windows 创建大于桌面的窗口(显示分辨率)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/445893/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Create Window larger than desktop (display resolution)
提问by Maxx Daymon
I need to resize a window larger than screen resolution or size of desktop, programmatically & preferably also manually.
我需要以编程方式调整大于屏幕分辨率或桌面大小的窗口大小,最好也手动调整。
Since MS-Windows XP/Vista disallows a window size larger than screen, does anybody have any ideas to work around this limitation?
由于 MS-Windows XP/Vista 不允许窗口大小大于屏幕,是否有人有任何想法来解决此限制?
I trying to make pan effect on a laptop to give me more space to work. An older laptop with a smaller LCD size did have such a feature.
我试图在笔记本电脑上制作平移效果,以便给我更多的工作空间。LCD 尺寸较小的旧笔记本电脑确实具有这样的功能。
See this: http://www.experts-exchange.com/OS/Microsoft_Operating_Systems/Windows/98/Q_21832063.html
请参阅:http: //www.experts-exchange.com/OS/Microsoft_Operating_Systems/Windows/98/Q_21832063.html
回答by Maxx Daymon
If you would like to resize a window that you do not own (and without using any kind of hook), you can use the Windows SetWindowPos API with the SWP_NOSENDCHANGING (0x0400) flag set:
如果您想调整不属于您的窗口的大小(并且不使用任何类型的挂钩),您可以使用设置了 SWP_NOSENDCHANGING (0x0400) 标志的 Windows SetWindowPos API:
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 **
);
This will prevent the WM_WINDOWPOSCHANGING message from being sent which is what triggers the WM_GETMINMAXINFO restriction. Any other sizing of the window will cause the restriction to snap the window back to desktop restricted sizes, as the message will be sent and the window size enforced.
这将阻止发送 WM_WINDOWPOSCHANGING 消息,这是触发 WM_GETMINMAXINFO 限制的原因。窗口的任何其他大小都将导致限制将窗口捕捉回桌面限制大小,因为将发送消息并强制执行窗口大小。
Window Resizer (C#)
窗口调整器 (C#)
The following is a tiny example program that will resize Notepad to 6000x6000 (change the string "Untitled - Notepad" to the title of the window you want to resize, or take the window name and desired size from the command line args)
下面是一个将 Notepad 大小调整为 6000x6000 的小示例程序(将字符串“Untitled - Notepad”更改为要调整大小的窗口的标题,或从命令行参数中获取窗口名称和所需大小)
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);
}
}
}
Limitations and caveats
限制和注意事项
This approach is generally functional, but there are a number of limitations that might prevent a window from being resized, or resized in any useful manner.
这种方法通常是有效的,但有许多限制可能会阻止调整窗口大小或以任何有用的方式调整大小。
Security
安全
Starting with Windows Vista, Microsoft has implemented increasing security around window messages. An executable can only interact with windows at or below its own security context. For example, to resize the "Computer Management" window (which always runs elevated), this program would have to run elevated as well.
从 Windows Vista 开始,Microsoft 已针对窗口消息实施了更高的安全性。可执行文件只能与处于或低于其自身安全上下文的窗口进行交互。例如,要调整“计算机管理”窗口的大小(始终以提升的方式运行),该程序也必须以提升的方式运行。
Fixed Windows and layout logic
固定窗口和布局逻辑
Window sizes might be enforced passivelyor activelyby a program. A window with a size enforced passively sets the initial size and simply exposes no ability for the user to resize the window (e.g., no size grip control). These windows can usually be resized by sending a message as described but, lacking layout logic, will notshow anything other that additional empty client area.
窗口大小可能由程序被动或主动强制执行。具有强制大小的窗口被动地设置初始大小并且简单地向用户展示没有调整窗口大小的能力(例如,没有大小控制控制)。这些窗口通常可以通过发送所描述的消息来调整大小,但由于缺乏布局逻辑,除了额外的空白客户区外,不会显示任何其他内容。
Windows with activeenforcement monitor the size, either by catching the windows messages such as WM_SIZE, or in more sophisticated layout logic. These windows may acceptthe message, but will restrict or limit the final size in their own code.
具有主动强制执行功能的窗口通过捕获诸如 WM_SIZE 之类的窗口消息或更复杂的布局逻辑来监视大小。这些窗口可能会接受消息,但会在自己的代码中限制或限制最终大小。
In either case, Windows with fixed sizes generally lack any layout logic to take advantage of larger sizes so, even if you canforce it, resizing them confers no benefits.
在任何一种情况下,具有固定尺寸的 Windows 通常缺乏任何布局逻辑来利用更大的尺寸,因此,即使您可以强制它,调整它们的大小也没有任何好处。
WPF
WPF
The Window
class in WPF has an HwndSource
that handles window messages sent to the WPF window. The private method LayoutFilterMessage
catches the WM_SYSCOMMAND
, WM_SIZING
, WM_WINDOWPOSCHANGING
, and WM_SIZE
messages. In this case, the WM_SIZE
message is then handled by the private Process_WM_SIZE
which, in effect, bypasses the NOSENDCHANGING
flag and alters the RenderSize
of the WPF client area. This is part of an overall process of adapting legacy Win32 messages to WPF events.
Window
WPF 中的类有一个HwndSource
处理发送到 WPF 窗口的窗口消息。私有方法LayoutFilterMessage
捕获WM_SYSCOMMAND
,WM_SIZING
,WM_WINDOWPOSCHANGING
,和WM_SIZE
消息。在这种情况下,WM_SIZE
消息随后由私有处理,私有Process_WM_SIZE
实际上绕过NOSENDCHANGING
标志并更改RenderSize
WPF 客户区的 。这是将旧版 Win32 消息适应 WPF 事件的整个过程的一部分。
The net effect is that the Win32 hostwindow is resized (unless SizeToContent is set to SizeToContent.WidthAndHeight), but the WPF render areais locked to the desktop area, as if the NOSENDCHANGING flag weren't set. When the above code sample is run against a WPF app, you can see the 6000x6000 window in Aero Peek from the task bar or the window preview in the Windows-Tab switcher, but you can also see the WPF content and layout logic being clipped to the desktop area. In this way, the WPF window is like the actively enforced window but, rather than enforcing a specific size, enforces a specific maximum(for RenderArea) and does not consider the WM_WINDOWPOSCHANGING
message.
最终效果是调整了 Win32主机窗口的大小(除非将 SizeToContent 设置为 SizeToContent.WidthAndHeight),但 WPF呈现区域被锁定到桌面区域,就好像未设置 NOSENDCHANGING 标志一样。当上面的代码示例针对 WPF 应用程序运行时,您可以从任务栏或 Windows-Tab 切换器中的窗口预览中看到 Aero Peek 中的 6000x6000 窗口,但您也可以看到 WPF 内容和布局逻辑被剪切到桌面区域。这样,WPF 窗口就像主动强制执行的窗口,但不是强制执行特定的 size,而是强制执行特定的最大值(对于 RenderArea)并且不考虑WM_WINDOWPOSCHANGING
消息。
If it is your ownapp and you host the WPF within a Windows Formswindow (via ElementHost
) you can resize the window and the WPF content will respect the larger-than-desktop Windows Form window.
如果它是您自己的应用程序并且您在Windows 窗体窗口中托管 WPF (通过ElementHost
),您可以调整窗口大小,WPF 内容将遵循大于桌面的 Windows 窗体窗口。
Other frameworks
其他框架
Other frameworks such as GTK and Qt may or may not enforce size behavior and limits, and may have various workarounds possible to overcome those limits. Any given program may ignore, rewrite, or bypass a window message and a framework can enforce it across an entire class of application such as with WPF above.
其他框架(例如 GTK 和 Qt)可能会也可能不会强制执行大小行为和限制,并且可能有各种可能的解决方法来克服这些限制。任何给定的程序都可以忽略、重写或绕过窗口消息,并且框架可以在整个应用程序类中强制执行它,例如上面的 WPF。
More about the SetWindowPos API:
有关 SetWindowPos API 的更多信息:
Reference Source for Process_WM_SIZE
method of HwndSource
:
Process_WM_SIZE
方法的参考来源HwndSource
:
回答by user6170414
You can do something like the following code in your WinProc();
您可以在 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;
An application can use this message to override the window's default maximized size and position, or its default minimum or maximum tracking size.
应用程序可以使用此消息来覆盖窗口的默认最大化大小和位置,或其默认的最小或最大跟踪大小。
回答by Wolf5
This code in C# does what you ask. The window is way wider than the desktop.
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;
}
回答by vasile
Only the recommended screen resolutions are listed. For additional settings, click the Advanced
button on the Settings
tab, click the Adapter tab
, and then click List all Modes
. Select the resolution, color level, and refresh rate you want.
仅列出了推荐的屏幕分辨率。如需其他设置,请单击选项卡Advanced
上的Settings
按钮,单击Adapter tab
,然后单击List all Modes
。选择所需的分辨率、颜色级别和刷新率。
I've just did it, here you can find the answer in the last point.
我刚刚做了,在这里你可以找到最后一点的答案。
回答by Rafelb
If you have a video card with the possibility to connect more than one screen, another workaround is to setup your system as if it is using two screens next to eachother. Then you can resize your windows to the size of the two screens together.
如果您的显卡可以连接多个屏幕,另一种解决方法是将系统设置为使用两个相邻的屏幕。然后,您可以将窗口大小调整为两个屏幕的大小。
回答by John K
The window size seems to be dependent on Desktop size, not screen resolution; however the Desktop conforms to resolution. The trick might be to change the Desktop size or start from there.
窗口大小似乎取决于桌面大小,而不是屏幕分辨率;但是桌面符合分辨率。诀窍可能是更改桌面大小或从那里开始。
A while back, a developer named Robert Bresner (his website) made a product called sDesk (downloadable from here) which expanded Windows beyond the screen resolution.
不久前,一位名叫 Robert Bresner(他的网站)的开发人员制作了一款名为 sDesk(可从此处下载)的产品,该产品将 Windows 扩展到了屏幕分辨率之外。
What is SDesk?SDesk is not a multi-desktop program. It is a program that creates a single, giant desktop that extends beyond the visible region of the monitor. Only a portion of the SDesk is visible at a time, as defined by the Windows desktop settings.
什么是 SDesk?SDesk 不是多桌面程序。它是一个程序,可以创建一个超出显示器可见区域的单个巨型桌面。根据 Windows 桌面设置的定义,一次只能看到一部分 SDesk。
The original homepage of the SDesk software is archived hereThere's no current page on the Internet (that I could find) but this archived version is accessed through the Way Back Machinewhich caches a lot of the Internet.
SDesk 软件的原始主页存档在这里。 Internet 上没有当前页面(我可以找到)但此存档版本是通过缓存大量 Internet的Way Back Machine访问的。
The SDesk product is freeware. No source code was included though. You might visit his contact page (also available in the archived version) to ask if the source is available or can be acquired for your research.
SDesk 产品是免费软件。虽然没有包含源代码。您可以访问他的联系页面(也可以在存档版本中找到),询问是否有可用的资源或可以为您的研究获取资源。
回答by Sparr
For the specific case of needing a more screen-friendly view of the MSDN, or on any other site (like StackOverflow) that makes poor use of screen real estate, I would suggest applying a custom stylesheet to the page, using a tool like IE7Pro (IE), Greasemonkey (Firefox), Stylish (Fireox), or the built in stylesheet picker in Opera.
对于需要更友好的 MSDN 屏幕视图的特定情况,或在任何其他网站(如 StackOverflow)上使用屏幕空间不佳的特定情况,我建议使用 IE7Pro 之类的工具将自定义样式表应用于页面(IE)、Greasemonkey (Firefox)、Stylish (Fireox) 或 Opera 中内置的样式表选择器。
回答by Sparr
ok, I did try use keystrokes to move, resize windows. But system will automatically move windows back to visible region of desktop in my XP. I also tried SetWindowPos API, and no helps. The best chance will be to write a Video driver, but it may need more study. The 360 desktop claims you can expand desktop horizontally. But actually it just pan the current desktop in a virtual wider space. Any windows inside still have the size limitation of no larger than your screen resolution.
好的,我确实尝试使用击键来移动、调整窗口大小。但是系统会自动将窗口移回我的 XP 中的桌面可见区域。我也试过 SetWindowPos API,但没有帮助。最好的机会是编写一个视频驱动程序,但它可能需要更多的研究。360 桌面声称您可以水平扩展桌面。但实际上它只是在虚拟更广阔的空间中平移当前桌面。里面的任何窗口仍然有不大于屏幕分辨率的大小限制。
Video driver set the screen resolution(yes, have to compatibile to lcd/crt screen capability), and Windows did limit window-size by this thresholds. I just want to work around in user space API.
视频驱动程序设置屏幕分辨率(是的,必须兼容 lcd/crt 屏幕功能),Windows 确实通过此阈值限制了窗口大小。我只想在用户空间 API 中解决。
回答by Isti115
I needed to push part of a window off the top of the screen and I was fnally able to do it using this AutoHotKey script:
我需要将窗口的一部分从屏幕顶部推出,我最终能够使用这个 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)
(I wanted to maximize the editor area of VSCode by completely hiding the title bar and the tabs section, that are not configurable in the program itself.)
(我想通过完全隐藏在程序本身中不可配置的标题栏和选项卡部分来最大化 VSCode 的编辑器区域。)