duilib中设置不激活窗口后移动无法立即跟随的bug
2014-08-01 10:58
405 查看
LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_LBUTTONDOWN: { OnMouseLButtonDown(wParam, lParam); break; } case WM_LBUTTONUP: { OnMouseLButtonUp(wParam, lParam); break; } case WM_MOUSEMOVE: { OnMouseLDownMove(wParam, lParam); break; } case WM_NCMOUSEMOVE: { OnMouseNcLDownMove(wParam, lParam); break; } case WM_NCLBUTTONUP: { OnMouseNcLButtonUp(wParam, lParam); break; } case WM_NCLBUTTONDOWN: { OnMouseNcLButtonDown(wParam, lParam); break; } } return __super::HandleMessage(uMsg, wParam, lParam); } void OnMouseNcLButtonDown(WPARAM wParam, LPARAM lParam) { POINT point; point.x = (short)LOWORD( lParam); point.y = (short)HIWORD( lParam); ClientToScreen(m_hWnd, &point); m_ptPrev = point; } void OnMouseNcLButtonUp(WPARAM wParam, LPARAM lParam) { POINT ptIn; ptIn.x = (short)LOWORD( lParam); ptIn.y = (short)HIWORD( lParam); POINT pt = ptIn; ClientToScreen(m_hWnd, &pt); RECT rectWnd, rcWorkArea; SIZE sz; GetWindowRect(m_hWnd, &rectWnd); OffsetRect(&rectWnd, m_ptPrev.x - m_ptMouseDown.x, m_ptPrev.y - m_ptMouseDown.y); OffsetRect(&rectWnd, pt.x - m_ptPrev.x, pt.y - m_ptPrev.y); ::SystemParametersInfo(SPI_GETWORKAREA, 0, &rcWorkArea, FALSE); sz.cx = rectWnd.right - rectWnd.left; sz.cy = rectWnd.bottom - rectWnd.top; if (rectWnd.left + sz.cx > rcWorkArea.right) { rectWnd.left = rcWorkArea.right - sz.cx; } else if(rectWnd.left < 0) { rectWnd.left = 0; } if(rectWnd.top < 0) { rectWnd.top = 0; } else if(rectWnd.top + sz.cy > rcWorkArea.bottom ) { rectWnd.top = rcWorkArea.bottom - sz.cy; } m_ptPrev.x = m_ptPrev.y = m_ptMouseDown.x = m_ptMouseDown.y = -1; GetWindowRect(m_hWnd, &rectWnd); } void OnMouseLButtonDown(WPARAM wParam, LPARAM lParam) { m_bMouseState = LNCDOWN; // 按下标题栏时拖放 ::SendMessage(m_hWnd, WM_NCLBUTTONDOWN, wParam, lParam); } void OnMouseLButtonUp(WPARAM wParam, LPARAM lParam) { POINT ptIn, pt; pt.x = ptIn.x = (short)LOWORD(lParam); pt.y = ptIn.y = (short)HIWORD(lParam); HRGN hRgn = CreateRectRgn(0, 0, 0, 0); GetWindowRgn(m_hWnd, hRgn); ClientToScreen(m_hWnd, &pt); if (!PtInRegion(hRgn, ptIn.x, ptIn.y) && (m_bMouseState == NOEVENT)) //释放鼠标捕捉 { ::SendMessage(m_hWnd, WM_MOUSELEAVE, 0, 0); } DeleteObject(hRgn); if ((m_bMouseState == LNCDOWN) || (m_bMouseState == NOEVENT)) { ::SendMessage(m_hWnd, WM_NCMOUSEMOVE, wParam, lParam); } } void OnMouseLDownMove(WPARAM wParam, LPARAM lParam) { POINT ptIn, pt; pt.x = ptIn.x = (short)LOWORD(lParam); pt.y = ptIn.y = (short)HIWORD(lParam); HRGN hRgn = CreateRectRgn(0, 0, 0, 0); GetWindowRgn(m_hWnd, hRgn); ClientToScreen(m_hWnd, &pt); if (!PtInRegion(hRgn, ptIn.x, ptIn.y) && (m_bMouseState == NOEVENT)) //释放鼠标捕捉 { ::SendMessage(m_hWnd, WM_MOUSELEAVE, 0, 0); } DeleteObject(hRgn); if ((m_bMouseState == LNCDOWN) || (m_bMouseState == NOEVENT)) { ::SendMessage(m_hWnd, WM_NCMOUSEMOVE, wParam, lParam); } } void OnMouseNcLDownMove(WPARAM wParam, LPARAM lParam) { UINT nFlags = (UINT)wParam; POINT point; point.x = (short)LOWORD( lParam); point.y = (short)HIWORD( lParam); if (nFlags & MK_LBUTTON) { RECT rectWnd; POINT pt = point; GetWindowRect(m_hWnd, &rectWnd); ClientToScreen(m_hWnd, &pt); OffsetRect(&rectWnd, pt.x - m_ptPrev.x , pt.y - m_ptPrev.y); m_ptPrev = pt; int nWidth = rectWnd.right - rectWnd.left; int nHeight = rectWnd.bottom - rectWnd.top; RECT rcWorkArea; ::SystemParametersInfo(SPI_GETWORKAREA, 0, &rcWorkArea, FALSE); if(rectWnd.left < rcWorkArea.left) { rectWnd.left = rcWorkArea.left; } else if (rectWnd.left + nWidth > rcWorkArea.right) { rectWnd.left = rcWorkArea.right - nWidth; } if (rectWnd.top < rcWorkArea.top) { rectWnd.top = rcWorkArea.top; } else if (rectWnd.top + nHeight > rcWorkArea.bottom) { rectWnd.top = rcWorkArea.bottom - nHeight; } ::MoveWindow(m_hWnd, rectWnd.left, rectWnd.top, nWidth, nHeight, TRUE); } }
private:enum MOUSESTATE{NOEVENT, LNCDOWN, LCLIENTDOWN, LSIZEDOWN};MOUSESTATE m_bMouseState; //记录鼠标状态POINT m_ptMouseDown; //记录鼠标按下时的位置POINT m_ptPrev; //记录鼠标前一次的位置
相关文章推荐
- duilib 修复Text控件无法设置宽度的bug,增加自动加算宽度的属性
- C#设置winform窗口无法移动
- duilib 修复Text控件无法设置宽度的bug,增加自动加算宽度的属性
- 【bug】对象激活前无法通过调用脚本函数设置变量
- 修复duilib CEditUI控件和CWebBrowserUI控件中按Tab键无法切换焦点的bug
- WIN32进阶必备:跟随鼠标移动的子窗口
- 博客园个性化设置:如何让【推荐】【反对】层跟随滚动条移动
- select对象无法设置innerHTML属性【微软BUG】
- XPS Viewer 无法设置权限账户 - 无法激活此计算机上的任何权限管理账户
- duilib List控件,横向滚动时列表项不移动或者移动错位的bug的修复
- Ubuntu窗口被系统状态栏遮挡,无法移动
- duilib中CTextUI控件设置文字时不刷新显示的bug
- win7系统中设置禁用/停止任务栏窗口自动移动方法图文教程介绍
- 无窗口激活ActiveX控件的bug
- duilib WindowImplBase BUG修复 --- 按一次ESC键, 关闭多个窗口
- Qt 技巧:去除对话框边框 + 设置窗口可移动和透明
- 关于select下拉框最后一项鼠标经过不能变色及设置宽度后下拉框无法滚动的bug?
- XP定时关机 && 浏览器新打开页面无法首次激活 && 关闭移动硬盘自动播放 && IE8从新选项卡打开链接 && XP虚拟机无法烧录软件
- JSObject的一个bug: 无法正确弹出html窗口
- <UI>设置某个控件在某个时候跟随某个scrollView的偏移量而移动