【问题标题】:Win32 prevent window "snap"Win32 防止窗口“啪”
【发布时间】:2013-10-29 14:31:33
【问题描述】:

如何为我的应用程序禁用 Windows 7 的快照功能(以编程方式)?或者有什么方法可以检测应用程序是否已被捕捉,并专门调用 API 函数来取消捕捉它?

调用 SetWindowPos() 或 ShowWindow() 不能正确解开它 *(SW_MAXIMIZE 可以)。调用 SetWindowPos() 实际上会在以后调用 SetWindowPos() 和 MoveWindow() 时导致奇怪的行为。同样的不一致不适用于最大化的窗口。

【问题讨论】:

  • 微软选择不公开 Aero Snap 的 API。
  • 是的,好像是这样。不幸的是,必须取消捕捉捕捉的窗口才能在 OpenGL 中全屏显示。我今天才发现这个错误。最大化窗口首先取消对齐。
  • @JonathanPotter 如果 Microsoft 不公开 API,我们应该为它找到一个 hack。 第一个可能的解决方案在我的回答中,但第二个解决方案没有临时修改窗口样式:为WM_SYSCOMMAND:SC_MOVEWM_SYSCOMMAND:SC_SIZE 编写自己的代码。第二种解决方案在未来和其他系统中的工作方式相同。

标签: winapi window-style window-position


【解决方案1】:

我找到了一种取消捕捉的方法,方法是使用 SW_MAXIMIZE 调用 ShowWindow()。这很奇怪,因为没有其他值与此调用取消对齐,即使窗口可以移开,它仍然锚定在屏幕的一侧。最大化它可以解决问题,然后我可以将窗口移动到需要的位置。

【讨论】:

    【解决方案2】:
    #define WM_RESTOREORIGINALSTYLE WM_USER+... /* your first free USER message */
    
    case WM_SYSCOMMAND:
    {
       if(wParam==(SC_MOVE|2)) wParam=SC_SIZE|9;
       if((wParam&0xFFE0)==SC_SIZE && (wParam&0x000F)) // handles MOVE and SIZE in one "if"
       {
          long int oldStyle=GetWindowLongW(hwnd,GWL_STYLE);
          PostMessageW(hwnd,WM_RESTOREORIGINALSTYLE,GWL_STYLE,oldStyle);
          SetWindowLongW(hwnd,GWL_STYLE,oldStyle &0xFEFEFFFF); // disable WS_MAXIMIZE and WS_MAXIMIZEBOX
          DefWindowProcW(hwnd,WM_SYSCOMMAND,wParam,lParam);
          return 0;
       }
       return DefWindowProcW(hwnd,WM_SYSCOMMAND,wParam,lParam);
    }
    case WM_RESTOREORIGINALSTYLE:
    {
       if((long int)wParam==GWL_STYLE)
          SetWindowLongW(hwnd,GWL_STYLE,lParam);
       return 0;
    }
    

    PostMessage 将在随后的消息循环中处理 - 这意味着在进入移动大小循环后尽快。 如果您使用自己的框架绘制方法,请不要忘记在WM_STYLECHANGED 消息上正确重绘您的框架,内部存储 oldStyle 在您的类中。 为什么它有效? Windows 在移动/大小操作开始时检查捕捉条件。如果 WS_MAXIMIZEWS_MAXIMIZEBOX 在启动时被禁用,则捕捉行为被禁用。

    SC_SIZE|9 等效于SC_MOVE|2,不会阻止重绘半秒。

    如果你不想在最大化的情况下启用拖动最大化的窗口,请检查系统菜单中SC_MOVE项的状态,如果已启用,直接在WM_SYSCOMMAND中返回0。

    已在 Windows 8.1 上验证。

    【讨论】:

    • 你真的不应该在你的代码中使用"magic numbers",它会让你更难理解发生了什么。 SC_MOVE|2 也称为 SC_DRAGMOVESC_SIZE|9 尚未命名。见this list0xFEFEFFFF可以写成~(WS_MAXIMIZE | WS_MAXIMIZEBOX)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-06
    • 2014-07-01
    • 2014-04-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多