使窗口移动时具有停靠吸附功能

 

使窗口移动时具有停靠吸附功能


 

示例代码下载:窗口移动停靠.zip (请不要直接使用迅雷下载)

注:VC6下编译通过

 


一.前言:

封装了一个类,可以很简单的使窗口移动时具有自动吸附停靠在屏幕边缘或自定窗口边缘的功能。

 


二.使用方法:

 

0.添加MoveWnd.h 和 MoveWnd.cpp 到你的工程

 

1.左键按下时(OnNcLButtonDown)调用 

 

 1.左键按下时调用: PrepareMoveWnd的第二个参数是想停靠的目标窗口
 void CMyDlg::OnLButtonDown(UINT nFlags, CPoint point)
 {
  CMoveWnd::PrepareMoveWnd(m_hWnd,::GetParent(m_hWnd));
  CDialog::OnLButtonDown(nFlags, point);
 }

   如果在标题栏按下,则:
 void CMyDlg::OnNcLButtonDown(UINT nHitTest, CPoint point)
 {
  if(nHitTest == HTCAPTION)
  {
   CMoveWnd::PrepareMoveWnd(m_hWnd,::GetParent(m_hWnd));
   return;
  }
  CDialog::OnNcLButtonDown(nHitTest, point);
 } 

 

 

2.左键弹起时调用 CMoveWnd::IsMovedWnd() 判断是否移动了窗口

 

void CMyDlg::OnLButtonUp(UINT nFlags, CPoint point)
{
 if (CMoveWnd::IsMovedWnd()) //判断是否移动了窗口
 {
  trace("has mvoe");
 }
 else
  trace("no move");

 CDialog::OnLButtonUp(nFlags, point);
}

 

3.鼠标移动时:

 

 void CMyDlg::OnMouseMove(UINT nFlags, CPoint point)
 {
  if( CMoveWnd::m_IsCapture && nFlags&MK_LBUTTON) 
   CMoveWnd::IsMovingWnd(m_hWnd);
  
  CDialog::OnMouseMove(nFlags, point);
 }

4.可以自己设置Docking的距离  #define AUTO_DOCK_WIDTH 10  

 

 


二.CMoveWnd代码

 

MoveWnd.h

 

#ifndef _MOVE_WND_H_
#define _MOVE_WND_H_


/****************************************************************************
1.左键按下时调用: PrepareMoveWnd的第二个参数是想停靠的目标窗口
 void CMyDlg::OnLButtonDown(UINT nFlags, CPoint point)
 {
  CMoveWnd::PrepareMoveWnd(m_hWnd,::GetParent(m_hWnd));
  CDialog::OnLButtonDown(nFlags, point);
 }

   如果在标题栏按下,则:
 void CMyDlg::OnNcLButtonDown(UINT nHitTest, CPoint point)
 {
  if(nHitTest == HTCAPTION)
  {
   CMoveWnd::PrepareMoveWnd(m_hWnd,::GetParent(m_hWnd));
   return;
  }
  CDialog::OnNcLButtonDown(nHitTest, point);
 } 

 
2.左键弹起时调用 CMoveWnd::IsMovedWnd() 判断是否移动了窗口
 void CMyDlg::OnLButtonUp(UINT nFlags, CPoint point)
 {
  if (CMoveWnd::IsMovedWnd()) //判断是否移动了窗口
  {
   trace("has mvoe");
  }
  else
   trace("no move");

  CDialog::OnLButtonUp(nFlags, point);
 }


3.鼠标移动时判断
 void CMyDlg::OnMouseMove(UINT nFlags, CPoint point)
 {
  if( CMoveWnd::m_IsCapture && nFlags&MK_LBUTTON) 
   CMoveWnd::IsMovingWnd(m_hWnd);
  
  CDialog::OnMouseMove(nFlags, point);
 }
 
4.可以设置Docking的距离
 #define AUTO_DOCK_WIDTH 20 
 
希望对你有帮助!阿弥陀佛!
****************************************************************************/


#include <Windows.h>

//自动靠屏幕的距离
#define AUTO_DOCK_WIDTH 10    

class CMoveWnd 
{
public:
 static bool  m_IsCapture;
 
 static bool  m_IsDockedWnd;

 static void  PrepareMoveWnd(HWND m_hWnd,HWND TargetWnd);
 static bool  IsMovedWnd();
 static void  IsMovingWnd(HWND m_hWnd);
private:
 static POINT m_MouseOffsetFromRectLeftTop;
 static RECT  m_TargetRect;
 static POINT m_MouseDownPoint;

};

#endif //#define _MOVE_WND_H_

 

MoveWnd.cpp

 

#include "StdAfx.h"  //如果编译出错,请去掉这一行
#include "MoveWnd.h"

RECT CMoveWnd::m_TargetRect={-100,-100,-100,-100};
bool CMoveWnd::m_IsDockedWnd=false;
POINT CMoveWnd::m_MouseOffsetFromRectLeftTop={-1000,0};
POINT CMoveWnd::m_MouseDownPoint={-10,0};
bool CMoveWnd::m_IsCapture=false;


void CMoveWnd::PrepareMoveWnd(HWND m_hWnd,HWND TargetWnd)
{
 ::SetCapture(m_hWnd);
 m_IsCapture=true;

 ::GetCursorPos(&m_MouseDownPoint);

 RECT rect;    
 ::GetWindowRect(m_hWnd,&rect);
 
 //获取鼠标相对于Rect左上角的偏移量m_MouseOffsetFromRectLeftTop
 m_MouseOffsetFromRectLeftTop.x=m_MouseDownPoint.x-rect.left;
 m_MouseOffsetFromRectLeftTop.y=m_MouseDownPoint.y-rect.top;

 //保存要停靠的目标窗口Rect
 ::GetWindowRect(TargetWnd,&m_TargetRect);
}


bool CMoveWnd::IsMovedWnd()
{
 ::ReleaseCapture();
 m_IsCapture=false;

 //判断是否移动了窗口
 POINT point;
 ::GetCursorPos(&point);
 return (point.x==m_MouseDownPoint.x && point.y==m_MouseDownPoint.y) ? false : true;
}

void CMoveWnd::IsMovingWnd(HWND m_hWnd)
{
 //移动窗口,停泊效果

 //get cursor point
 POINT point;
 ::GetCursorPos(&point);
 
 //count the new position (当前鼠标位置-移动窗口前保存的鼠标偏移量=新的窗口位置)
 int x_pos_new=point.x-m_MouseOffsetFromRectLeftTop.x;
 int y_pos_new=point.y-m_MouseOffsetFromRectLeftTop.y;
 
 //用于后面和x_pos_new y_pos_new 对比从而判断是否停靠了
 int TempX=x_pos_new;
 int TempY=y_pos_new;
 
 //get window rectangle
 RECT rect; 
 ::GetWindowRect(m_hWnd,&rect);
 
 //停靠在目标窗口的右边
 if (abs(m_TargetRect.right-x_pos_new)<AUTO_DOCK_WIDTH)
  x_pos_new=m_TargetRect.right;

 //停靠在目标窗口的下边
 if (abs(m_TargetRect.bottom-y_pos_new)<AUTO_DOCK_WIDTH)
  y_pos_new=m_TargetRect.bottom;
  m_IsDockedWnd=true;

 //停靠在目标窗口的左边
 if (abs( (x_pos_new+rect.right-rect.left) -m_TargetRect.left)<AUTO_DOCK_WIDTH)
  x_pos_new=m_TargetRect.left-(rect.right-rect.left);
  m_IsDockedWnd=true;

 //停靠在目标窗口的上边
 if (abs( (y_pos_new+rect.bottom-rect.top) -m_TargetRect.top)<AUTO_DOCK_WIDTH)
  y_pos_new=m_TargetRect.top-(rect.bottom-rect.top);
  m_IsDockedWnd=true;

 //判断是否停靠了
 if (x_pos_new!=TempX || y_pos_new!=TempY)
  m_IsDockedWnd=true;
 else
 {
  m_IsDockedWnd=false;

  //获得屏幕的高和宽
  int cxScreen=GetSystemMetrics(SM_CXSCREEN); 
  int cyScreen=GetSystemMetrics(SM_CYSCREEN);
  //如果靠近屏幕,则进行贴边处理
  if ( abs(x_pos_new)<AUTO_DOCK_WIDTH) x_pos_new=0;
  if ( abs(y_pos_new)<AUTO_DOCK_WIDTH) y_pos_new=0;
  if ( abs(x_pos_new+rect.right-rect.left-cxScreen)<AUTO_DOCK_WIDTH) x_pos_new=cxScreen-(rect.right-rect.left);
  if ( abs(y_pos_new+rect.bottom-rect.top-cyScreen)<AUTO_DOCK_WIDTH) y_pos_new=cyScreen-(rect.bottom-rect.top);
 }

 
 ::SetCursor(::LoadCursor(NULL,IDC_SIZEALL)); 
 ::SetWindowPos(m_hWnd,HWND_TOPMOST,x_pos_new,y_pos_new,0,0,SWP_NOSIZE);
}

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值