我需要以编程方式调整一个大于屏幕分辨率或桌面大小的窗口的大小&最好也是手动的。
由于MS-Windows XP/Vista不允许窗口大小大于屏幕,有谁有任何想法来解决这个限制吗?
我试着在笔记本电脑上做平移效果,给我更多的工作空间。一款LCD尺寸较小的老式笔记本电脑确实有这样的功能。
看看这个:http://www.experts-exchange.com/OS/Microsoft_Operating_Systems/Windows/98/Q_21832063.html
发布于 2011-11-09 11:27:40
如果您想要调整一个不属于您的窗口的大小(并且不使用任何类型的挂钩),您可以使用设置了SWP_NOSENDCHANGING (0x0400)标志的Windows:
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_GETMINMAXINFO限制的WM_WINDOWPOSCHANGING消息。窗口的任何其他大小调整都将导致限制将窗口捕捉回桌面限制大小,因为将发送消息并强制执行窗口大小。
窗口调整程序(C#)
下面是一个小的示例程序,它将记事本的大小调整为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);
}
}
}限制和注意事项
这种方法通常是有效的,但有许多限制可能会阻止调整窗口大小或以任何有用的方式调整窗口大小。
安全性
从Windows Vista开始,Microsoft已经实现了增强窗口消息的安全性。可执行文件只能与处于或低于其自身安全上下文的窗口进行交互。例如,要调整“计算机管理”窗口的大小(总是以提升的方式运行),此程序也必须以提升的方式运行。
修复了窗口和布局逻辑
窗口大小可以由程序被动地或主动地强制执行。具有强制大小的窗口被动地设置初始大小,并且简单地不向用户展示调整窗口大小的能力(例如,没有大小夹点控制)。这些窗口通常可以通过发送消息来调整大小,但由于缺乏布局逻辑,不会显示除附加的空客户端区以外的任何内容。
具有活动强制的窗口通过捕获窗口消息(如WM_SIZE )或以更复杂的布局逻辑来监视大小。这些窗口可以接受消息,但会在它们自己的代码中限制或限制最终大小。
在这两种情况下,固定大小的Windows通常缺乏任何布局逻辑来利用较大的大小,因此,即使您可以强制使用,调整它们的大小也不会带来任何好处。
WPF
WPF中的Window类有一个处理发送到WPF窗口的窗口消息的HwndSource。私有方法LayoutFilterMessage捕获WM_SYSCOMMAND、WM_SIZING、WM_WINDOWPOSCHANGING和WM_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),并且不考虑WM_WINDOWPOSCHANGING消息。
如果它是您自己的应用程序,并且您在Windows Forms窗口中宿主WPF (通过ElementHost),您可以调整窗口的大小,并且WPF内容将遵循大于桌面的Windows Form窗口。
其他框架
其他框架,如GTK和Qt,可能会强制执行大小行为和限制,也可能不会强制执行这些限制,并且可能有各种可能的变通方法来克服这些限制。任何给定的程序都可以忽略、重写或绕过窗口消息,并且框架可以在整个应用程序类中强制执行它,例如使用上面的WPF。
有关SetWindowPos接口的更多信息:
HwndSource的Process_WM_SIZE方法的参考源
http://referencesource.microsoft.com/#PresentationCore/Core/CSharp/System/Windows/Interop/HwndSource.cs,da4aa32ad121c1b9,references
发布于 2011-01-25 22:32:16
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;
}发布于 2016-04-07 14:02:13
您可以在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;应用程序可以使用此消息覆盖窗口的默认最大化大小和位置,或其默认的最小或最大跟踪大小。
https://stackoverflow.com/questions/445893
复制相似问题