制作一个客户端,选择duilib+cef+mfc为客户端界面。父窗口为一个对话框,子窗口为duilib的窗口(Mainframe)。当主界面把mfc的对话框盖住时,发现窗口移动不了(无标题窗口)。为了移动主窗口,记录的解决方法:
- 第一个解决方法(失败)
...
if (uMsg == WM_LBUTTONUP)
{
POINT point = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
::ReleaseCapture();
::SendMessage(::GetParent(this->GetHWND()),WM_SYSCOMMAND,SC_DRAGMOVE,0);
return 0;
}
...
这段代码实现了点击窗口任意位置,窗口移动的目的,但是窗口的所有消息都被丢弃了(return 0)。不能采用这个方法。需要监控鼠标移动+鼠标点击的事件。
* 第二个方法(ok)
if (uMsg == WM_MOUSEMOVE)
{
if (::GetAsyncKeyState(VK_LBUTTON) != 0 && m_bStartMove)
{
POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
int dx = pt.x - m_StartPt.x;
int dy = pt.y - m_StartPt.y;
RECT curRect;
::GetWindowRect(m_hWnd, &curRect);
int cx = curRect.left + dx;
int cy = curRect.top + dy;
int w = curRect.right - curRect.left;
int h = curRect.bottom - curRect.top;
SetWindowPos(::GetParent(this->GetHWND()), NULL, cx, cy, w, h, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
}
}
else if (uMsg == WM_LBUTTONDOWN)
{
POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
m_bStartMove = TRUE;
m_StartPt = pt;
}
else if (uMsg == WM_LBUTTONUP)
{
m_bStartMove = FALSE;
}
不需要任何返回。完整代码如下:
LRESULT MainFrame::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
{
LRESULT lRes = 0;
if (uMsg == WM_MOUSEMOVE)
{
if (::GetAsyncKeyState(VK_LBUTTON) != 0 && m_bStartMove)
{
POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
int dx = pt.x - m_StartPt.x;
int dy = pt.y - m_StartPt.y;
RECT curRect;
::GetWindowRect(m_hWnd, &curRect);
int cx = curRect.left + dx;
int cy = curRect.top + dy;
int w = curRect.right - curRect.left;
int h = curRect.bottom - curRect.top;
SetWindowPos(::GetParent(this->GetHWND()), NULL, cx, cy, w, h, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
}
}
else if (uMsg == WM_LBUTTONDOWN)
{
POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
m_bStartMove = TRUE;
m_StartPt = pt;
}
else if (uMsg == WM_LBUTTONUP)
{
m_bStartMove = FALSE;
}
if( uMsg == WM_CREATE )
{
CPaintManagerUI::SetInstance(AfxGetInstanceHandle());//加载XML的时候,需要使用该句柄去定位EXE的路径,才能加载XML的路径
CPaintManagerUI::SetResourcePath(CPaintManagerUI::GetInstancePath() + _T("skin"));//定位图片等资源的位置
m_pm.Init(m_hWnd);
CDialogBuilder builder;
CControlUI *pRoot = builder.Create(_T("ui.xml"), (UINT)0, NULL, &m_pm); //加载的XML文件的名称
ASSERT(pRoot && "Failed to parse XML");
m_pm.AttachDialog(pRoot);
m_pm.AddNotifier(this);
return 0;
}
else if( uMsg == WM_DESTROY )
{
::PostQuitMessage(0);
}
if( m_pm.MessageHandler(uMsg, wParam, lParam, lRes) ) return lRes;
return CWindowWnd::HandleMessage(uMsg, wParam, lParam);
}
大功告成!