Win32 prevent window “snap”

扶醉桌前 提交于 2021-01-28 07:43:26

问题


How can I disable the snap feature of Windows 7 for my application (progmatically)? Or is there any way to detect if the application has been snapped, and specifically call an API function to unsnap it?

Calling SetWindowPos() or ShowWindow() does not unsnap it correctly *(SW_MAXIMIZE does). Calling SetWindowPos() actually causes strange behavior in future calls to SetWindowPos() and MoveWindow(). The same inconsistencies do not apply to a window that is maximized.


回答1:


I figured out a way to unsnap, by calling ShowWindow() with SW_MAXIMIZE. This is odd since no other values unsnap with this call, even though the window can be moved away, it is still anchored to the side of the screen. Maximizing it fixes the problem, whereafter I can move the window where it needs to be.




回答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;
}

The PostMessage will be processed in subsequent message loop - it means ASAP after entering into move-size loop. If you use own drawing method of frame, please do not forget to redraw your frame correctly on WM_STYLECHANGED message, internally store oldStyle in your class. Why it works? Windows check snap condition at start of move/size action. If WS_MAXIMIZE and WS_MAXIMIZEBOX are disabled at start, the snap behaviour is disabled.

The SC_SIZE|9 is equivalent of SC_MOVE|2 without blocking redrawing for half a second.

If you don't want to enable dragging maximized windows if they are fully maximized, check state of SC_MOVE item in system menu and if it is enabled, directly return 0 in WM_SYSCOMMAND.

Verified on Windows 8.1.



来源:https://stackoverflow.com/questions/19661126/win32-prevent-window-snap

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!