|
|
-[尕硴] |
|
超级版主
|
UID: 71
来自:
精华: 130
积分: 14003
帖子: 12909
注册: 2007-10-22 17:59:00
状态:
离线
威望: 444.00
金钱: 3355.00 元
|
|
|
|
|
| VisualC++设计超强仿QQ自动伸缩窗口(2) |
|
然后在构造函数初始化成员变量: m_isSizeChanged = FALSE; m_isSetTimer = FALSE;m_hsFinished = TRUE; m_hiding = FALSE;m_oldWndHeight = MINCY; m_taskBarHeight = 30; m_edgeHeight = 0; m_edgeWidth=0; m_hideMode = HM_NONE; |
完成了一些初始的工作,那么就开始进入关键的函数实现了。首先是在OnCreate做些窗口的初始化和获得一些系统信息。 代码一 int CQQHideWndDlg::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CDialog::OnCreate(lpCreateStruct) == -1) return -1; // TODO: Add your specialized creation code here //获得任务栏高度 CWnd* p; p = this->FindWindow("Shell_TrayWnd",NULL); if(p != NULL) { CRect tRect; p->GetWindowRect(tRect); m_taskBarHeight = tRect.Height(); } //修改风格使得他不在任务栏显示 ModifyStyleEx(WS_EX_APPWINDOW, WS_EX_TOOLWINDOW); //去掉关闭按键(如果想画3个按键的话) //ModifyStyle(WS_SYSMENU,NULL); //获得边缘高度和宽度 m_edgeHeight = GetSystemMetrics(SM_CYEDGE); m_edgeWidth = GetSystemMetrics(SM_CXFRAME); return 0; }
|
接着如何知道鼠标进入或移出窗口呢?在前面我已经证明了WM_MOUSEMOVE和WM_MOUSELEAVE不符合我们的要求,于是我用了WM_ NCHITTEST这个消息,你可以看到我在这个消息响应函数中用了两个SetTimer,一个用于检测鼠标是否离开,一个用于伸缩过程,不管你喜欢不喜欢,要达到第7点和第11点,这个是必须的,考虑的效率问题,在不需要的时候关闭这些Timer就好了。 代码二 UINT CQQHideWndDlg::OnNcHitTest(CPoint point) { // TODO: Add your message handler code here and/or call default CString str; str.Format("Mouse (%d,%d)",point.x,point.y); GetDlgItem(IDC_CURSOR)->SetWindowText(str); if(m_hideMode != HM_NONE && !m_isSetTimer && //防止鼠标超出屏幕右边时向右边收缩造成闪烁 point.x < GetSystemMetrics(SM_CXSCREEN) + INFALTE) { //鼠标进入时,如果是从收缩状态到显示状态则开启Timer SetTimer(1,CM_ELAPSE,NULL); m_isSetTimer = TRUE; m_hsFinished = FALSE; m_hiding = FALSE; SetTimer(2,HS_ELAPSE,NULL); //开启显示过程 } return CDialog::OnNcHitTest(point); }
|
然后在OnTimer中, 代码三 void CQQHideWndDlg::OnTimer(UINT nIDEvent) { // TODO: Add your message handler code here and/or call default if(nIDEvent == 1 ) { POINT curPos; GetCursorPos(&curPos); CString str; str.Format("Timer On(%d,%d)",curPos.x,curPos.y); GetDlgItem(IDC_TIMER)->SetWindowText(str); CRect tRect; //获取此时窗口大小 GetWindowRect(tRect); //膨胀tRect,以达到鼠标离开窗口边沿一定距离才触发事件 tRect.InflateRect(INFALTE,INFALTE); if(!tRect.PtInRect(curPos)) //如果鼠标离开了这个区域 { KillTimer(1); //关闭检测鼠标Timer m_isSetTimer = FALSE; GetDlgItem(IDC_TIMER)->SetWindowText("Timer Off"); m_hsFinished = FALSE; m_hiding = TRUE; SetTimer(2,HS_ELAPSE,NULL); //开启收缩过程 } } if(nIDEvent == 2) { if(m_hsFinished) //如果收缩或显示过程完毕则关闭Timer KillTimer(2); else m_hiding ? DoHide() : DoShow(); } CDialog::OnTimer(nIDEvent); }
|
暂时不管OnTimer中的DoHide(); DoShow(); 先来看看核心的函数之一的 FixMoving,该函数在OnMoving中被调用,FixMoving通过检测鼠标位置和窗口位置来决定窗口的收缩模式,并修正粘附边界时窗口的位置,从而达到像移动QQ时出现的效果。
|
|
|
|