将窗口部分移出屏幕顶部 [英] Move a window partially off the top of the screen

查看:21
本文介绍了将窗口部分移出屏幕顶部的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm trying move a window partially off the top of the screen. However, Windows' default behavior will pop it back down after I'm done moving it. Yes, I understand why this particular functionality exists; however, I still don't want it for my window. Then I notice that I can use SetWindowPos to set a window partially off the top of the screen, and it won't pops back down. For example SetWindowPos(...., -100, -100, ....) will set my window above the screen 100 pixels, and it will stay there.

所以,我想使用 SetWindowPos 来移动,而不是正常移动我的窗口(比如发送 SendMessage(hwnd, WM_SYSCOMMAND, SC_MOVE | 0x0002, 0);.我的想法是处理 WM_MOUSEMOVE 并检查鼠标左键是否按下.如果鼠标左键按下,我调用 SetWindowPos 并对当前鼠标位置进行一些数学运算,上一个鼠标位置,并通过 SetWindowPos 传递.

So, instead of moving my window normally (like sending SendMessage(hwnd, WM_SYSCOMMAND, SC_MOVE | 0x0002, 0);, I want to use SetWindowPos to move. My idea is to handle WM_MOUSEMOVE and check the left mouse button is down. If the left mouse button is down, I call SetWindowPos with some math done to current mouse position, previous mouse positions, and pass it through SetWindowPos.

到目前为止我有它的工作,但不是很好.首先,如果鼠标快速移动,它根本不起作用.其次,当鼠标缓慢移动时,窗口会随着移动而抖动.

So far I have it working but not very well. First, if the mouse is move fast, it won't work at all. Second, when the mouse moves slowly, the window would shakes as it moves.

这是我的 WinProc:

Here is my 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 将窗口向下移动的位置,但我仍然不知道我需要做什么.我知道它可以完成,因为我已经在其他应用程序中看到它完成了.

Further inspecting windows messages, I see exactly where Windows moves the window back down but I still don't know what I need to do. I know it can be done, because I have seen it done in other apps.

<--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>

推荐答案

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

This works for me (designed using your captured window messages):

    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;

这篇关于将窗口部分移出屏幕顶部的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆