37上位机VC MFC让程序窗口具有磁性效果
37上位机VC MFC让程序窗口具有磁性效果
功能展示
千千静听,很老的音乐播放软件,我们在使用时会发再它的很小窗口可以连在一起,拖动起来彼此间有磁性效果,主程序具有很大的灵活性,那么这种磁性效果是怎么实现的呢?我们当前例程就实现了这功能,效果如图
要点提示 窗口的磁性效果主要用到了两个函数,MapWindowPoints()和MoveWindow();MapWindowPoints函数实现将某个窗口的区域坐标转换为另一窗口的区域坐标,语法如下: void MapWindowPoints( CWnd* pwndTo, LPRECT lpRect ) pwndTo:转换后的区域坐标窗口, lpRect 要转换的区域对象; 实现功能 1.新建基于对话框的应用程序 2.插入一个对话框资源建立与关联一对话框类CChildDlg;在主对话框中添加变量CChildDlg m_ChildDlg; intm_Width; //窗口宽int m_Height;//窗口高BOOLm_bCreate;//窗口是否已创建BOOL m_bStick; //=两窗口是否粘住CPoint m_Point; //窗口左上角位置;在构造函数中初始化两变量m_bCreate = FALSE;m_bStick = FALSE;在OnInitDialog()中初始化变量m_ChildDlg.Create(IDD_DIALOG1,this);m_ChildDlg.ShowWindow(SW_SHOW); CRect Rect; GetWindowRect(Rect);MapWindowPoints(this,Rect); m_Width = Rect.Width(); m_Height = Rect.Height(); m_Point.x = Rect.left;m_Point.y = Rect.top; m_bCreate = TRUE;
窗口的背景可以选择性加载进行美化程序 3.在OnNcLButtonDown()中对m_bStick进行附值 - <div style="text-align: center;"><span style="line-height: 1.5;">void CGkbc8Dlg::OnNcLButtonDown(UINT nHitTest, CPoint point) </span></div>{
- // 判断两窗口是否粘合,是则在Onmove函数进一步处理
- CRect Rect,cRect;
- GetWindowRect(Rect);
- MapWindowPoints(this,Rect);
- m_ChildDlg.GetWindowRect(cRect);
- if(Rect.left-cRect.right == 0)
- {
- m_bStick = TRUE;
- }
- else if(cRect.left-Rect.right == 0)
- {
- m_bStick = TRUE;
- }
- else if(cRect.top-Rect.bottom == 0)
- {
- m_bStick = TRUE;
- }
- else if(Rect.top-cRect.bottom == 0)
- {
- m_bStick = TRUE;
- }
- else
- m_bStick = FALSE;
- CDialog::OnNcLButtonDown(nHitTest, point);
- }
复制代码4.在OnMove()实现磁性效果 - void CGkbc8Dlg::OnMove(int x, int y)
- {
- CDialog::OnMove(x, y);
-
- if(m_bCreate == TRUE)
- {
- CRect Rect,cRect;
- GetWindowRect(Rect);
- MapWindowPoints(this,Rect);
-
- m_ChildDlg.GetWindowRect(cRect);
- if(Rect.left-cRect.right<20 && Rect.left-cRect.right>0 && (
- Rect.top>cRect.top-m_Height && Rect.bottom<cRect.bottom+m_Height))
- Rect.left = cRect.right;
- else if(cRect.left-Rect.right<20 && cRect.left-Rect.right>0 && (
- Rect.top>cRect.top-m_Height && Rect.bottom<cRect.bottom+m_Height))
- Rect.left = cRect.left - m_Width;
- else if(cRect.top-Rect.bottom<20 && cRect.top-Rect.bottom>0 && (
- Rect.left>cRect.left-m_Width && Rect.right<cRect.right+m_Width))
- Rect.top = cRect.top - m_Height;
- else if(Rect.top-cRect.bottom<20 && Rect.top-cRect.bottom>0 && (
- Rect.left>cRect.left-m_Width && Rect.right<cRect.right+m_Width))
- Rect.top = cRect.bottom;
- MoveWindow(Rect.left,Rect.top,m_Width,m_Height);
- if(m_bStick)
- {
- m_ChildDlg.MoveWindow(cRect.left+(Rect.left-m_Point.x),
- cRect.top+(Rect.top-m_Point.y),cRect.Width(),cRect.Height());
- }
- m_Point.x = Rect.left;
- m_Point.y = Rect.top;
- }
- }
复制代码5.以上仅实现父窗口对子窗口的磁性效果,如果要实现子窗口也具有磁性效果,还得对子对话框类进行简单处理。在子对话框CChildDlg中添加变量int m_Width;
int m_Height;BOOL m_bCreate; 在构造函数中初始化m_bCreate=FALSE;在OnInitDialog()中初始化Crect rect; GetWindowRect(rect);m_Width =rect.Width();m_Height = rect.Height();m_bCreate = TRUE;
6.在OnMove()里实现子窗口的磁性效果 - void CChildDlg::OnMove(int x, int y)
- {
- CDialog::OnMove(x, y);
-
- // TODO: Add your message handler code here
- if(m_bCreate == TRUE)
- {
- CRect Rect,cRect;
- GetWindowRect(cRect);
- this->GetParent()->GetWindowRect(Rect);
- if(cRect.left-Rect.right<20 && cRect.left-Rect.right>0 && (
- cRect.top>Rect.top-m_Height && cRect.bottom<Rect.bottom+m_Height))
- cRect.left = Rect.right;
- else if(Rect.left-cRect.right<20 && Rect.left-cRect.right>0 && (
- cRect.top>Rect.top-m_Height && cRect.bottom<Rect.bottom+m_Height))
- cRect.left = Rect.left - m_Width;
- else if(Rect.top-cRect.bottom<20 && Rect.top-cRect.bottom>0 && (
- cRect.left>Rect.left-m_Width && cRect.right<Rect.right+m_Width))
- cRect.top = Rect.top - m_Height;
- else if(cRect.top-Rect.bottom<20 && cRect.top-Rect.bottom>0 && (
- cRect.left>Rect.left-m_Width && cRect.right<Rect.right+m_Width))
- cRect.top = Rect.bottom;
- MoveWindow(cRect.left,cRect.top,m_Width,m_Height);
- }
- }
复制代码下面我们来实现磁性窗口的过程演示 源码及视频下载 (仅在电脑可见)
|