英文:
How can I find out if a user is trying to maximize a window before it happens with subclassing?
问题
我正在尝试捕获一个子类化的窗体中的消息,并从中创建一个新的事件,以便在发生之前检查一些事情,然后根据需要取消消息。
我想知道用户是否试图最大化窗体,然后根据全局变量将消息传递给基类。
public class APIConstants
{
public const uint SWP_NOSIZE = 0x0001;
}
public class APIs
{
[DllImport("kernel32", CharSet = CharSet.Auto)]
public static extern void CopyMemory(WINDOWPOS pDst, IntPtr pSrc, int ByteLen);
}
public class Structures
{
[StructLayout(LayoutKind.Sequential)]
public struct WINDOWPOS
{
public IntPtr hwnd;
public IntPtr hwndInsertAfter;
public int x;
public int y;
public int cx;
public int cy;
public uint flags;
}
}
protected override void WndProc(ref Message m)
{
WinMsgs msg = new WinMsgs(m.Msg);
switch (msg.Message)
{
case WinMsgs.WinMessages.WM_WINDOWPOSCHANGING:
Structures.WINDOWPOS wPos = new Structures.WINDOWPOS();
APIs.CopyMemory(wPos, m.LParam, Marshal.SizeOf(wPos));
if ((wPos.flags & APIConstants.SWP_NOSIZE) != 0)
{
Debug.WriteLine("NOSIZE");
}
break;
}
}
在上述代码中,您正在尝试捕获窗体消息以查看是否包含 SWP_NOSIZE 标志。但您提到似乎在填充 CopyMemory 中的 wPos 结构时未获取到正确的数据。
您的代码看起来大致正确,但问题可能出在 CopyMemory 方法的使用上,确保 m.LParam 指向正确的内存位置,并且 wPos 结构的定义与消息的参数匹配。
您可以尝试添加一些调试输出,以查看获取的数据是否正确。如果问题仍然存在,可能需要检查窗体的子类化和消息处理是否正确配置。
英文:
I'm trying to catch a message in a subclassed form and make a new event from it so I can check things before it happens and then cancel the message if needed.
I want to know if the user is trying to maximize the form, then based on a global variable, pass along the message to the base.
public class APIConstants
{
public const uint SWP_NOSIZE = 0x0001;
}
public class APIs
{
[DllImport("kernel32", CharSet = CharSet.Auto)]
public static extern void CopyMemory(WINDOWPOS pDst, IntPtr pSrc, int ByteLen);
}
public class Structures
{
[StructLayout(LayoutKind.Sequential)]
public struct WINDOWPOS
{
public IntPtr hwnd;
public IntPtr hwndInsertAfter;
public int x;
public int y;
public int cx;
public int cy;
public uint flags;
}
}
How I'm currently subclassing the form...
protected override void WndProc(ref Message m)
{
WinMsgs msg = new WinMsgs(m.Msg);
switch (msg.Message)
{
case WinMsgs.WinMessages.WM_WINDOWPOSCHANGING:
Structures.WINDOWPOS wPos = new Structures.WINDOWPOS();
APIs.CopyMemory(wPos, m.LParam, Marshal.SizeOf(wPos));
if ((wPos.flags & APIConstants.SWP_NOSIZE) != 0)
{
Debug.WriteLine("NOSIZE");
}
break;
}
}
Reading around I thought the key was to just look if the flags passed with the message included SWP_NOSIZE. My form has a FormBorderStyle of FixedSingle
(not sure if that affects the results or not). But for some reason it doesn't feel like I'm getting any good data in the wPos
structure I fill with CopyMemory.
What am I doing wrong?
答案1
得分: 2
检查窗口的消息WM_SYSCOMMAND。
当用户从窗口菜单(以前称为系统菜单或控制菜单)中选择命令或选择最大化按钮、最小化按钮、还原按钮或关闭按钮时,窗口会收到此消息。
然后检查WParam属性,看它是否等于SC_MAXIMIZE,以确定是否发出了最大化窗口请求。
protected override void WndProc(ref Message m)
{
const Int32 WM_SYSCOMMAND = 0x112;
const Int32 SC_MAXIMIZE = 0xF030;
if (m.Msg == WM_SYSCOMMAND && m.WParam.ToInt32() == SC_MAXIMIZE)
{
// 在最大化之前执行需要的操作
}
base.WndProc(ref m); // 让基类处理消息
}
英文:
Check for the Window's message WM_SYSCOMMAND.
> A window receives this message when the user chooses a command from the Window menu (formerly known as the system or control menu) or when the user chooses the maximize button, minimize button, restore button, or close button.
Then check the WParam property to see if it is equal to SC_MAXIMIZE to determine if a maximize window request has been issued.
protected override void WndProc(ref Message m)
{
const Int32 WM_SYSCOMMAND = 0x112;
const Int32 SC_MAXIMIZE = 0xF030;
if (m.Msg == WM_SYSCOMMAND && m.WParam.ToInt32() == SC_MAXIMIZE)
{
// do what you need to before maximizing
}
base.WndProc(ref m); // let the base class process the message
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论