创建大于桌面的窗口(显示分辨率)

时间:2009-01-15 07:04:31

标签: windows resize window desktop

我需要调整大小超过屏幕分辨率或桌面大小的窗口,以编程方式&最好还是手动。

由于MS-Windows XP / Vista不允许窗口大于屏幕,是否有任何想法可以解决此限制?

我试图在笔记本电脑上制作泛音效果,为我提供更多工作空间。具有较小LCD尺寸的旧笔记本电脑确实具有这样的功能。

看到这个: http://www.experts-exchange.com/OS/Microsoft_Operating_Systems/Windows/98/Q_21832063.html

9 个答案:

答案 0 :(得分:12)

如果您想要调整您不拥有的窗口的大小(并且不使用任何类型的挂钩),您可以使用Windows SetWindowPos API并设置SWP_NOSENDCHANGING(0x0400)标志:

BOOL WINAPI SetWindowPos(
__in      HWND hWnd,
__in_opt  HWND hWndInsertAfter,
__in      int X,
__in      int Y,
__in      int cx,
__in      int cy,
__in      UINT uFlags // ** SWP_NOSENDCHANGING must be passed here **
);

这将阻止发送WM_WINDOWPOSCHANGING消息,这是触发WM_GETMINMAXINFO限制的消息。窗口的任何其他大小调整都会导致限制将窗口捕捉回桌面限制大小,因为将发送消息并强制执行窗口大小。

Window Resizer(C#)

以下是一个微小的示例程序,它将记事本调整为6000x6000(将字符串“Untitled - Notepad”更改为要调整大小的窗口的标题,或从命令行args获取窗口名称和所需大小)

namespace Example
{
 class Program
 {
  [DllImport("USER32.DLL")]
  public static extern IntPtr FindWindow(String className, String windowName);

  [DllImport("USER32.DLL", SetLastError = true)]
  public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int left, int top, int width, int height, uint flags);

  static void Main(string[] args)
  {
   var TOP = new IntPtr(0);
   uint SHOWWINDOW = 0x0040, NOCOPYBITS = 0x0100, NOSENDCHANGING = 0x0400;
   var hwnd = FindWindow(null, "Untitled - Notepad");
   SetWindowPos(hwnd, TOP, 0, 0, 6000, 6000, NOCOPYBITS | NOSENDCHANGING | SHOWWINDOW);
  }
 }
}

限制和警告

这种方法通常具有功能性,但有许多限制可能会阻止窗口调整大小或以任何有用的方式调整大小。

安全

从Windows Vista开始,Microsoft已经实现了围绕窗口消息的增强安全性。可执行文件只能与其自身安全上下文之下或之下的窗口进行交互。例如,要调整“计算机管理”窗口(始终运行升高)的大小,此程序也必须升级。

修复了Windows和布局逻辑

窗口大小可能由程序强制被动主动强制执行。具有强制执行的大小的窗口被动地设置初始大小并且简单地暴露用户无法调整窗口大小的能力(例如,没有大小的抓握控制)。这些窗口通常可以通过发送消息来调整大小,但缺少布局逻辑,显示其他任何其他空客户区。

具有活动强制执行的Windows通过捕获诸如WM_SIZE之类的Windows消息或更复杂的布局逻辑来监视大小。这些窗口可以接受消息,但会限制或限制自己代码中的最终大小。

在任何一种情况下,具有固定大小的Windows通常缺少任何布局逻辑以利用更大的尺寸,因此,即使您可以强制它,调整它们也不会带来任何好处。

WPF

WPF中的Window类有一个HwndSource来处理发送到WPF窗口的窗口消息。私有方法LayoutFilterMessage捕获WM_SYSCOMMANDWM_SIZINGWM_WINDOWPOSCHANGINGWM_SIZE消息。在这种情况下,WM_SIZE消息由私有Process_WM_SIZE处理,实际上绕过NOSENDCHANGING标志并改变WPF客户区的RenderSize。这是使旧版Win32消息适应WPF事件的整个过程的一部分。

净效果是调整了Win32 主机窗口的大小(除非SizeToContent设置为SizeToContent.WidthAndHeight),但WPF 渲染区域被锁定到桌面区域,好像没有设置NOSENDCHANGING标志。当针对WPF应用程序运行上述代码示例时,您可以从任务栏或Windows-Tab切换器中的窗口预览中看到Aero Peek中的6000x6000窗口,但您还可以看到被剪切为的WPF内容和布局逻辑桌面区域。这样,WPF窗口就像主动强制执行的窗口,但不是强制执行特定大小,而是强制执行特定的最大值(对于RenderArea)并且不考虑{ {1}}消息。

如果它是您的拥有应用,并且您在 Windows窗体窗口(通过WM_WINDOWPOSCHANGING)内托管WPF,则可以调整窗口和WPF内容的大小将尊重大于桌面的Windows窗体窗口。

其他框架

其他框架(如GTK和Qt)可能会也可能不会强制执行大小行为和限制,并且可能有各种可行的方法来克服这些限制。任何给定的程序都可以忽略,重写或绕过窗口消息,框架可以在整个应用程序类中强制执行它,例如上面的WPF。

有关SetWindowPos API的更多信息:

ElementHost的{​​{1}}方法的参考来源:

http://referencesource.microsoft.com/#PresentationCore/Core/CSharp/System/Windows/Interop/HwndSource.cs,da4aa32ad121c1b9,references

答案 1 :(得分:2)

C#中的这段代码可以满足您的要求。窗口比桌面宽。

 protected override void WndProc(ref Message m) {
        if (m.ToString().Contains("GETMINMAXINFO")) {
            //Hent data
            MINMAXINFO obj = (MINMAXINFO)Marshal.PtrToStructure(m.LParam, typeof(MINMAXINFO));
            //Endre
            if (obj.ptMaxSize.X > 0) {
                obj.ptMaxSize.X = 60000;
                obj.ptMaxSize.Y = 60000;
                obj.ptMaxTrackSize.X = 60000;
                obj.ptMaxTrackSize.Y = 60000;
                //Oppdater
                Marshal.StructureToPtr(obj, m.LParam, true);
            }
        }
        if (m.ToString().Contains("WINDOWPOSCHANGING")) {
            //Hent data
            WINDOWPOS obj = (WINDOWPOS)Marshal.PtrToStructure(m.LParam, typeof(WINDOWPOS));
            //Endre
            if (obj.cx > 0) {
                obj.cx = 8000;
                //Oppdater
                Marshal.StructureToPtr(obj, m.LParam, true);
            }
        }
        //Debug.WriteLine(m.ToString());
        base.WndProc(ref m);
    }











    [StructLayout(LayoutKind.Sequential)]
    internal struct WINDOWPOS {
        internal IntPtr hwnd;
        internal IntPtr hWndInsertAfter;
        internal int x;
        internal int y;
        internal int cx;
        internal int cy;
        internal uint flags;
    }

    [StructLayout(LayoutKind.Sequential)]
    internal struct MINMAXINFO {
        internal POINT ptReserverd;
        internal POINT ptMaxSize;
        internal POINT ptMaxPosition;
        internal POINT ptMinTrackSize;
        internal POINT ptMaxTrackSize;
    }
    [StructLayout(LayoutKind.Sequential)]
    internal struct POINT {
        internal int X;
        internal int Y;
    }

答案 2 :(得分:2)

您可以在WinProc();

中执行类似以下代码的操作
case WM_GETMINMAXINFO:
    {
        LPMINMAXINFO lpmmi = (LPMINMAXINFO)lParam; 
        GetWindowRect(GetDesktopWindow(), &actualDesktop);
        lpmmi->ptMaxTrackSize.x = 3000;// set the value that you really need.
        lpmmi->ptMaxTrackSize.y = 3000;// set the value that you really need.
    }
    break;

应用程序可以使用此消息覆盖窗口的默认最大化大小和位置,或其默认的最小或最大跟踪大小。

答案 3 :(得分:1)

如果您的视频卡可以连接多个屏幕,则另一种解决方法是将系统设置为使用彼此相邻的两个屏幕。然后,您可以将窗口大小调整为两个屏幕的大小。

答案 4 :(得分:1)

仅列出推荐的屏幕分辨率。有关其他设置,请点击Advanced标签上的Settings按钮,点击Adapter tab,然后点击List all Modes。选择所需的分辨率,颜色级别和刷新率。

我刚刚做到了,在这里你可以在最后一点找到答案。

http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/display_change_screen_resolution.mspx?mfr=true

答案 5 :(得分:0)

对于需要更加屏幕友好的MSDN视图或任何其他网站(如StackOverflow)使用屏幕空间不佳的特定情况,我建议将自定义样式表应用于页面,使用工具如IE7Pro(IE),Greasemonkey(Firefox),Stylish(Fireox)或Opera内置的样式表选择器。

答案 6 :(得分:0)

好吧,我确实尝试过使用击键来移动,调整窗口大小。但是系统会在我的XP中自动将窗口移回桌面的可见区域。 我也尝试过SetWindowPos API,没有任何帮助。 最好的机会是编写视频驱动程序,但可能需要更多学习。 360桌面声称您可以水平扩展桌面。 但实际上它只是在虚拟更广阔的空间中平移当前桌面。内部的任何窗口仍然具有不大于屏幕分辨率的大小限制。

视频驱动程序设置屏幕分辨率(是的,必须兼容lcd / crt屏幕功能),Windows确实将窗口大小限制为此阈值。 我只是想在用户空间API中解决。

答案 7 :(得分:0)

窗口大小似乎取决于桌面大小,而不是屏幕分辨率;但桌面符合分辨率。诀窍可能是更改桌面大小或从那里开始。

前段时间,名为Robert Bresner(his website)的开发人员制作了一款名为sDesk(downloadable from here)的产品,该产品将Windows扩展到屏幕分辨率之外。

  

什么是SDesk? SDesk不是   多桌面程序。这是一个程序   这会创建一个单一的巨型桌面   超出可见区域   显示器。只有一部分   根据定义,SDesk一次可见   通过Windows桌面设置。

original homepage of the SDesk software is archived here互联网上没有当前页面(我可以找到)但是这个存档版本是通过 Way Back Machine 访问的,它可以缓存很多互联网。

SDesk产品是免费软件。但是没有包含源代码。您可以访问他的联系页面(也可以在存档版本中找到),询问是否有可用的来源或可以为您的研究获得。

答案 8 :(得分:0)

我需要将一部分窗口推离屏幕顶部,最终我可以使用以下AutoHotKey脚本来做到这一点:

SetTitleMatchMode, 2
WinTitle := "Visual Studio Code"

; --- WinMove version

; WinMove, %WinTitle%, , 0, -64, 1280, 1504

; -- DLL version

WinGet, id, , %WinTitle%
Result := DllCall("SetWindowPos", "uint", id, "uint", HWND_TOP, "Int", 0, "Int", -64, "Int", 1280, "Int", 1504, "UInt", 0x400)

(我想通过完全隐藏程序本身无法配置的标题栏和选项卡部分来最大化VSCode的编辑器区域。)