怎么实现子对话框在主对话框内的边界吸附,现在吸附边屏幕的边界已经实现了,但是我想再主对话框内实现吸附怎么办?
而且子对话框不能拖拽出主对话框的范围内。

解决方案 »

  1.   

    在子对话框中响应WM_MOVE,用GetParent()拿到父窗口指针,利用父窗口指针调用GetWindowRect获得窗口的位置,然后做出判断,再做相应的处理就成了@!
      

  2.   

    參考:
    http://hi.baidu.com/qiujiejia/blog/item/9bdb4fef77839406fdfa3ca3.html
      

  3.   

    可以给我个别的地址吗,我百度空间我进不去,或者发我邮箱里[email protected]  谢谢啦
      

  4.   

    一.前言:封装了一个类,可以很简单的使窗口移动时具有自动吸附停靠在屏幕边缘或自定窗口边缘的功能。--------------------------------------------------------------------------------二.使用方法:
    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);
      

  5.   

    关于范围控制可以参考这篇博客
    关于吸附就是只要子窗口设成Child风格子窗口就会随主窗口一起移动
    http://blog.csdn.net/xianglitian/article/details/6023656