禁用对ShowWindow函数调用的窗口反应

问题描述:

我有一个具有禁用调整大小功能(WindowStyle = None,ResizeMode = CanMinimize)的WPF窗口。禁用对ShowWindow函数调用的窗口反应

它工作正常,除了一种情况。如果某个应用程序(即AutoHotKey)使用SW_MAXIMIZE选项在我的窗口上调用了WIN API API函数ShowWindow,那么我的窗口重新定位到(0,0)在桌面上的坐标不变,并且用户无法将其移动到屏幕上。

如何禁用此行为?我希望窗口在我的窗口上忽略此调用。

我已经尝试过对WM_WINDOWPOSCHANGING事件作出反应,但是这只能在用户最小化窗口之前起作用。在最小化和恢复之后,它重新定位到(0,0)坐标。

private IntPtr ProcessMessage(IntPtr windowHandle, int msg, IntPtr wideParam, IntPtr leftParam, ref bool handled) 
{ 
    Msg windowsMessage = (Msg)msg; 
    switch (windowsMessage) 
    { 
     case Msg.WM_WINDOWPOSCHANGING: 
      { 
       WindowPos windowPos = (WindowPos)Marshal.PtrToStructure(leftParam, typeof(WindowPos)); 

       if (IsNoClientAction(windowPos) && !IsMinimizing(windowPos) && window.WindowState == WindowState.Normal) 
       { 
        windowPos.Flags = SetWindowPosFlags.SWP_NOSIZE | SetWindowPosFlags.SWP_NOMOVE; 
        handled = true; 
        Marshal.StructureToPtr(windowPos, leftParam, true); 
       } 

       break; 
      } 
    } 

    return IntPtr.Zero; 
} 

private static bool IsNoClientAction(WindowPos windowPos) 
{ 
    return (windowPos.Flags & SetWindowPosFlags.SWP_NOCLIENTSIZE) != 0 || (windowPos.Flags & SetWindowPosFlags.SWP_NOCLIENTMOVE) != 0; 
} 

private static bool IsMinimizing(WindowPos windowPos) 
{ 
    return windowPos.Left == -32000 && windowPos.Top == -32000; 
} 

我已经分析了什么user32.dll对窗口做了什么,并找出了基于此的解决方案。在发送任何消息到Wndproc之前,它会更新GWL_STYLE窗口的标志,使其能够使用WS_MAXIMIZE。由于这个原因,窗口状态变得破坏,进一步的行为几乎不能通过处理窗口消息来处理。

要与SW_MAXIMIZE选项我设置该标志回ShowWindow禁用窗口的反应,当WM_WINDOWPOSCHANGING处理:

private IntPtr ProcessMessage(IntPtr windowHandle, int msg, IntPtr wideParam, IntPtr leftParam, ref bool handled) 
{ 
    Msg windowsMessage = (Msg)msg; 
    switch (windowsMessage) 
    { 
     case Msg.WM_WINDOWPOSCHANGING: 
      { 
       WindowPos windowPos = (WindowPos)Marshal.PtrToStructure(leftParam, typeof(WindowPos)); 

       if (IsNoClientAction(windowPos)) 
       { 
        WindowStyles styles = (WindowStyles)WindowsAPI.GetWindowLongPtr(windowHandle, GWL.GWL_STYLE); 
        if ((styles & WindowStyles.WS_MAXIMIZE) != 0) 
        { 
         windowPos.Flags |= SetWindowPosFlags.SWP_NOSIZE | SetWindowPosFlags.SWP_NOMOVE; 
         WindowsAPI.SetWindowLongPtr(new HandleRef(this, windowHandle), GWL.GWL_STYLE, (IntPtr)(long)(styles^WindowStyles.WS_MAXIMIZE)); 
         handled = true; 
         Marshal.StructureToPtr(windowPos, leftParam, true); 
        } 
       } 

       break; 
      } 
    } 

    return IntPtr.Zero; 
} 

private static bool IsNoClientAction(WindowPos windowPos) 
{ 
    return (windowPos.Flags & SetWindowPosFlags.SWP_NOCLIENTSIZE) != 0 || (windowPos.Flags & SetWindowPosFlags.SWP_NOCLIENTMOVE) != 0; 
}