【问题标题】:Move a window partially off the top of the screen将窗口部分移出屏幕顶部
【发布时间】:2011-07-11 01:58:54
【问题描述】:

我正在尝试将窗口部分移出屏幕顶部。但是,Windows 的默认行为会在我完成移动后将其弹出。是的,我理解为什么存在这个特定的功能;但是,我仍然不希望它用于我的窗口。然后我注意到我可以使用SetWindowPos 将窗口部分设置在屏幕顶部之外,并且它不会弹回。例如SetWindowPos(...., -100, -100, ....) 会将我的窗口设置在屏幕上方 100 像素处,并且它会停留在那里。

所以,不是正常移动我的窗口(比如发送SendMessage(hwnd, WM_SYSCOMMAND, SC_MOVE | 0x0002, 0);,我想使用SetWindowPos来移动。我的想法是处理WM_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;
}

这里是完整代码http://pastebin.com/9A8iV5GW

进一步检查 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>

【问题讨论】:

    标签: windows winapi


    【解决方案1】:

    这对我有用(使用您捕获的窗口消息设计):

        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;
    

    【讨论】:

    • 谢谢您,先生!完美运行!
    猜你喜欢
    • 1970-01-01
    • 2013-06-16
    • 2016-08-09
    • 1970-01-01
    • 1970-01-01
    • 2015-04-30
    • 1970-01-01
    • 1970-01-01
    • 2013-02-14
    相关资源
    最近更新 更多