Windows 将窗口部分移出屏幕顶部

Windows 将窗口部分移出屏幕顶部,windows,winapi,Windows,Winapi,我正试着把一个窗口从屏幕顶部移开一部分。但是,Windows的默认行为会在我移动完它后将其弹出。是的,我理解为什么存在这种特殊功能;然而,我还是不想把它放在我的窗户上。然后我注意到,我可以使用SetWindowPos将窗口部分设置为离开屏幕顶部,并且不会弹出。例如,SetWindowPos(…..,-100,-100,…)会将我的窗口设置在屏幕100像素以上,并保持在那里 因此,不是正常地移动我的窗口(比如发送SendMessage(hwnd,WM_SYSCOMMAND,SC_MOVE | 0x

我正试着把一个窗口从屏幕顶部移开一部分。但是,Windows的默认行为会在我移动完它后将其弹出。是的,我理解为什么存在这种特殊功能;然而,我还是不想把它放在我的窗户上。然后我注意到,我可以使用
SetWindowPos
将窗口部分设置为离开屏幕顶部,并且不会弹出。例如,
SetWindowPos(…..,-100,-100,…)
会将我的窗口设置在屏幕100像素以上,并保持在那里

因此,不是正常地移动我的窗口(比如发送
SendMessage(hwnd,WM_SYSCOMMAND,SC_MOVE | 0x0002,0)
,我想使用
SetWindowPos
移动。我的想法是处理
WM\u MOUSEMOVE
并检查鼠标左键是否按下。如果鼠标左键按下,我调用
SetWindowPos
,对当前鼠标位置、以前的鼠标位置进行一些计算,然后将其传递给
SetWindowPos

到目前为止,我已经知道了它的工作原理,但不是很好。首先,如果鼠标移动快,它根本不会工作。其次,当鼠标缓慢移动时,窗口会随着移动而抖动

这是我的WinProc:

LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    static int lastMouseX = 0; 
    static int lastMouseY = 0; 
    switch (message)         /* handle the messages */
    {
    case WM_LBUTTONDOWN:
        lastMouseX = LOWORD(lParam); 
        lastMouseY = HIWORD(lParam); 
        break;
    //case WM_NCMOUSEMOVE: 
    case WM_MOUSEMOVE: 
        if(wParam == MK_LBUTTON)
        {
            int currentMouseX = LOWORD(lParam); 
            int currentMouseY = HIWORD(lParam); 
            int deltaX = currentMouseX - lastMouseX; 
            int deltaY = currentMouseY - lastMouseY; 
            RECT prc; 
            GetWindowRect(hwnd, &prc);
            SetWindowPos(hwnd, NULL, prc.left + deltaX, prc.top + deltaY, 0, 0, SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE);
            lastMouseX = currentMouseX; 
            lastMouseY = currentMouseY;
        }
        break; 
    case WM_DESTROY:
        PostQuitMessage (0);    /* send a WM_QUIT to the message queue */
        break;

    default:           /* for messages that we don't deal with */
        return DefWindowProc (hwnd, message, wParam, lParam);
    }

    return 0;
}
这是完整的代码

进一步检查windows消息,我看到了windows将窗口向下移动的确切位置,但我仍然不知道我需要做什么。我知道这是可以做到的,因为我在其他应用程序中看到过

<--I stop moving here with WM_LBUTTONUP -->  
<windowMessage id="514" name="WM_LBUTTONUP">
  <wParam>0x00000000</wParam>
  <lParam>0x0049009E</lParam>
  <returnValue>0x00000000</returnValue>
<-- And here is when windows moves it back down -->  
</windowMessage><windowMessage id="534" name="WM_MOVING">
  <wParam>0x00000009</wParam>
  <lParam>0x003FF220</lParam>
  <returnValue>0x00000000</returnValue>
</windowMessage><windowMessage id="70" name="WM_WINDOWPOSCHANGING">
  <wParam>0x00000000</wParam>
  <lParam>0x003FEF98</lParam>
  <returnValue>0x00000000</returnValue>
</windowMessage><windowMessage id="36" name="WM_GETMINMAXINFO">
  <wParam>0x00000000</wParam>
  <lParam>0x003FEC20</lParam>
  <returnValue>0x00000000</returnValue>
</windowMessage><windowMessage id="71" name="WM_WINDOWPOSCHANGED">
  <wParam>0x00000000</wParam>
  <lParam>0x003FEF98</lParam>
  <returnValue>0x00000000</returnValue>
</windowMessage><windowMessage id="533" name="WM_CAPTURECHANGED">
  <wParam>0x00000000</wParam>
  <lParam>0x00000000</lParam>
  <returnValue>0x00000000</returnValue>
</windowMessage><windowMessage id="70" name="WM_WINDOWPOSCHANGING">
  <wParam>0x00000000</wParam>
  <lParam>0x003FF210</lParam>
  <returnValue>0x00000000</returnValue>
</windowMessage><windowMessage id="562" name="WM_EXITSIZEMOVE">
  <wParam>0x00000000</wParam>
  <lParam>0x00000000</lParam>
  <returnValue>0x00000000</returnValue>
</windowMessage>

0x00000000
0x0049009E
0x00000000
0x00000009
0x003FF220
0x00000000
0x00000000
0x003FEF98
0x00000000
0x00000000
0x003FEC20
0x00000000
0x00000000
0x003FEF98
0x00000000
0x00000000
0x00000000
0x00000000
0x00000000
0x003FF210
0x00000000
0x00000000
0x00000000
0x00000000
这适用于我(使用捕获的窗口消息设计):

case WM\u ENTERSIZEMOVE:
in_movesize_loop=true;
禁止_movesize_loop=false;
打破
案例WM_EXITSIZEMOVE:
in_movesize_loop=false;
禁止_movesize_loop=false;
打破
案例WM_CAPTURECHANGED:
禁止\u movesize\u循环=在\u movesize\u循环中;
打破
案例WM_WINDOWPOSCHANGING:
if(禁止移动大小循环){
WINDOWPOS*wp=重新解释强制转换(LPRAM);
wp->flags |=SWP|u NOMOVE;
返回0;
}
打破
这适用于我(使用捕获的窗口消息设计):

case WM\u ENTERSIZEMOVE:
in_movesize_loop=true;
禁止_movesize_loop=false;
打破
案例WM_EXITSIZEMOVE:
in_movesize_loop=false;
禁止_movesize_loop=false;
打破
案例WM_CAPTURECHANGED:
禁止\u movesize\u循环=在\u movesize\u循环中;
打破
案例WM_WINDOWPOSCHANGING:
if(禁止移动大小循环){
WINDOWPOS*wp=重新解释强制转换(LPRAM);
wp->flags |=SWP|u NOMOVE;
返回0;
}
打破

谢谢,先生!非常好!谢谢,先生!非常好!
    case WM_ENTERSIZEMOVE:
        in_movesize_loop = true;
        inhibit_movesize_loop = false;
        break;

    case WM_EXITSIZEMOVE:
        in_movesize_loop = false;
        inhibit_movesize_loop = false;
        break;  

    case WM_CAPTURECHANGED:
        inhibit_movesize_loop = in_movesize_loop;
        break;  

    case WM_WINDOWPOSCHANGING:
        if (inhibit_movesize_loop) {
            WINDOWPOS* wp = reinterpret_cast<WINDOWPOS*>(lParam);
            wp->flags |= SWP_NOMOVE;
            return 0;
        }
        break;