1 参考仿QQ悬挂窗口的实现 作者: 郑瑜。 在调试基础上,对悬挂功能[Docking]进行封装处理。非常方便实际编程中的直接调用。再次感谢郑瑜,通过他的文章而产生的灵感。
2 按钮,用CButtonST实现 参考www.codeproject.com , 详细参考:
CButtonST v3.9 (MFC Flat buttons)
By Davide Calabro
方便应用程序使用:
代码思想:
1 添加WM_MOUSE的全局钩子[dll]
2 通过对mouse当前坐标、Wnd的ClientRect判断,进行不同的slide
利用SetWindowPo, sleep(30)模拟动态悬挂效果。
核心代码:
- void Docking::TranslateMessage()
- {
- //减少常变量析构; 加快程序效率
- static const int Span = 5; //对此单位元素就进行Docking
- POINT pt;
- CRect rcWindow;
- ::GetCursorPos(&pt);
- m_Wnd->GetWindowRect(&rcWindow);
- //如果pt在窗体中, 直接返回
- if ((rcWindow.PtInRect(pt) && rcWindow.Width() > SpanValue)
- && (rcWindow.PtInRect(pt) && rcWindow.Height() > SpanValue))
- return ;
- if (rcWindow.Width() > Span && rcWindow.left < Span)//Left -> Hide
- {
- SliderWindow(LEFT, false);
- }
- else if(rcWindow.Width() < Span && pt.x < SpanValue + 1 &&
- (pt.y > rcWindow.top && pt.y < rcWindow.bottom) ) //Left -> Show
- {
- SliderWindow(LEFT, true);
- }
- else if(rcWindow.Width() > Span && rcWindow.right > this->ScreeWidth - Span && pt.x < ScreeWidth - Span)//Right -> Hide
- {
- SliderWindow(RIGHT, false);
- }
- else if(rcWindow.Width() < Span && pt.x >= ScreeWidth - Span &&
- (pt.y > rcWindow.top && pt.y < rcWindow.bottom)) //Right -> Show
- {
- SliderWindow(RIGHT, true);
- }
- else if(rcWindow.Height() > SpanValue && rcWindow.top < Span)//Top -> Hide
- {
- SliderWindow(TOP, false);
- }
- else if(rcWindow.Height() < SpanValue + 1 && pt.y < Span
- && (pt.x > rcWindow.left && pt.x < rcWindow.right))//Top -> Show
- {
- SliderWindow(TOP, true);
- }
- else if(rcWindow.Height() > 0 && rcWindow.bottom > ScreeHeigth - Span)//Bottom -> Hide
- {
- SliderWindow(BOTTOM, false);
- }
- else if(rcWindow.Height() < 1 && pt.y > ScreeHeigth - Span
- && (pt.x > rcWindow.left && pt.x < rcWindow.right))//Bottom -> Show
- {
- SliderWindow(BOTTOM, true);
- }
- }
- void Docking::SliderWindow(int nPos, bool bShow)
- {
- //提高效率
- if (m_oldDockingState.first == nPos && m_oldDockingState.second == bShow)
- return;
- m_oldDockingState.first = nPos;
- m_oldDockingState.second = bShow;
- CRect rc;
- m_Wnd->GetWindowRect(rc);
- if (!bShow) //Docking前,先记录一下原始大小
- {
- m_ClientRect.left = rc.left;
- m_ClientRect.right = rc.right;
- m_ClientRect.top = rc.top;
- m_ClientRect.bottom = rc.bottom;
- }
- switch(nPos)
- {
- case LEFT:
- {
- long W = m_ClientRect.Width();
- long step = W / 10;
- if(bShow)
- {
- for(int i=0; i<=10; i++)
- {
- m_Wnd->SetWindowPos(&CWnd::wndTopMost, 0, rc.top, i*step, rc.Height(), SWP_SHOWWINDOW);
- Sleep(30);
- }
- }
- else
- {
- for(int i=0; i<=10; i++)
- {
- m_Wnd->SetWindowPos(&CWnd::wndTopMost, 0, rc.top, W-step*i , rc.Height(), SWP_SHOWWINDOW);
- Sleep(30);
- }
- m_Wnd->SetWindowPos(&CWnd::wndTopMost, 0, rc.top, SpanValue , rc.Height(), SWP_SHOWWINDOW);
- }
- }
- break;
- case RIGHT:
- {
- long W = m_ClientRect.Width();
- long step = W / 10;
- if(bShow)
- {
- for(int i=0; i<=10; i++)
- {
- m_Wnd->SetWindowPos(&CWnd::wndTopMost, rc.left - i * step, rc.top, i*step, rc.Height(), SWP_SHOWWINDOW);
- Sleep(30);
- }
- }
- else
- {
- for(int i=0; i<=10; i++)
- {
- m_Wnd->SetWindowPos(&CWnd::wndTopMost, rc.left + i * step, rc.top, W-step*i, rc.Height(), SWP_SHOWWINDOW);
- Sleep(30);
- }
- m_Wnd->SetWindowPos(&CWnd::wndTopMost, ScreeWidth - SpanValue, rc.top, SpanValue, rc.Height(), SWP_SHOWWINDOW);
- }
- }
- break;
- case TOP:
- {
- int H = m_ClientRect.Height();
- int step = H / 10;
- if (bShow)
- {
- for(int i = 0; i <= 10; i++)
- {
- m_Wnd->SetWindowPos(&CWnd::wndTopMost, rc.left, 0, rc.Width(), i * step, SWP_SHOWWINDOW);
- Sleep(30);
- }
- }
- else
- {
- for(int i = 0; i <= 10; i++)
- {
- m_Wnd->SetWindowPos(&CWnd::wndTopMost, rc.left, 0, rc.Width(), H- i*step, SWP_SHOWWINDOW);
- Sleep(30);
- }
- m_Wnd->SetWindowPos(&CWnd::wndTopMost, rc.left, 0, rc.Width(), SpanValue, SWP_SHOWWINDOW);
- }
- }
- break;
- case BOTTOM:
- {
- int H = m_ClientRect.Height();
- int step = H / 10;
- if (bShow)
- {
- for(int i = 0; i <= 10; i++)
- {
- m_Wnd->SetWindowPos(&CWnd::wndTopMost, rc.left, rc.top - step*i, rc.Width(), i * step, SWP_SHOWWINDOW);
- Sleep(30);
- }
- }
- else
- {
- for(int i = 0; i <= 10; i++)
- {
- m_Wnd->SetWindowPos(&CWnd::wndTopMost, rc.left, rc.top + step*i, rc.Width(), H- i*step, SWP_SHOWWINDOW);
- Sleep(30);
- }
- }
- }
- break;
- default:
- break;
- }
- }
运行效果: