编写可托拽改变大小的对话框

    技术2022-05-11  79

    编写可托拽改变大小的对话框 声明:本文不得转载,如需程序代码可给我发信索取。 Email: wubinghao1981@163.com   我个人认为由于对话框改变大小后需要该对话框包含的所有子窗口进行重新排列,所有在MFC类中没有一个可托拽的对话框类。我编写了一个可托拽的对话框基类 CDragDialog,如果需要编写可托拽的对话框,可以继承该基类。 1.        位图资源的添加 将“标识鼠标拖拽有效区的位图”作为位图添加到资源,其ID为:“ IDB_BITMAP_DRAGBLOCK2.        CDragDialog 类的定义 class CDragDialog : public CDialog {     DECLARE_DYNAMIC(CDragDialog)   public :     CDragDialog(UINT nIDTemplate, CWnd* pParent = NULL);   // standard constructor     virtual ~CDragDialog();   protected :     virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support       DECLARE_MESSAGE_MAP() public :     virtual BOOL OnInitDialog();     afx_msg void OnMouseMove(UINT nFlags, CPoint point);     afx_msg void OnLButtonDown(UINT nFlags, CPoint point);     afx_msg void OnLButtonUp(UINT nFlags, CPoint point);     void SetMinSize(const CSize &size) { m_szMinSize = size; }     bool GetTitleRect(CRect &rect) const;     afx_msg void OnPaint();     virtual void ReSizeContrals(void) { }     afx_msg void OnSize(UINT nType, int cx, int cy); protected :     void ReSetDragBlock();     void ReSizeDialog(const CPoint &point);     void PaintDragBlock(CPaintDC &dc);     CBitmap m_btDragBlock;     CRect m_rcDragBlock;     HCURSOR m_hcurDrag;     HCURSOR m_hcurArrow;     bool m_bDrag;     CPoint m_ptLast;     CSize m_szMinSize; }; 3.        CDragDialog 的成员函数的定义 IMPLEMENT_DYNAMIC (CDragDialog, CDialog) CDragDialog ::CDragDialog(UINT nIDTemplate, CWnd* pParent /*=NULL*/) : CDialog(nIDTemplate, pParent), m_rcDragBlock(0,0,0,0), m_szMinSize(100,40) , m_bDrag(false), m_ptLast(0,0) {     m_btDragBlock.LoadBitmap(IDB_BITMAP_DRAGBLOCK);     CWinApp*   pApp   =   ::AfxGetApp();     m_hcurArrow = pApp->LoadStandardCursor(IDC_ARROW);     m_hcurDrag = pApp->LoadStandardCursor(IDC_SIZENWSE); }   CDragDialog ::~CDragDialog() { }   void CDragDialog::DoDataExchange(CDataExchange* pDX) {     CDialog::DoDataExchange(pDX); }     BEGIN_MESSAGE_MAP (CDragDialog, CDialog)     ON_WM_MOUSEMOVE()     ON_WM_LBUTTONDOWN()     ON_WM_LBUTTONUP()     ON_WM_PAINT()     ON_WM_SIZE() END_MESSAGE_MAP ()     // CDragDialog message handlers   BOOL CDragDialog::OnInitDialog() {     CDialog::OnInitDialog();       // TODO: Add extra initialization here     CRect rect;     GetClientRect(&rect);       //»ٌµأ؟ح»§اّ´َذ،     BITMAP bitmap;     m_btDragBlock.GetBitmap(&bitmap);     m_rcDragBlock.left = rect.right - bitmap.bmWidth;     m_rcDragBlock.top = rect.bottom - bitmap.bmHeight;     m_rcDragBlock.right = rect.right;     m_rcDragBlock.bottom = rect.bottom;       ReSizeContrals();       return TRUE// return TRUE unless you set the focus to a control     // EXCEPTION: OCX Property Pages should return FALSE }   void CDragDialog::ReSetDragBlock() {     CRect rect(0,0,0,0);     GetClientRect(&rect);     BITMAP bitmap;     m_btDragBlock.GetBitmap(&bitmap);     m_rcDragBlock.left = rect.right - bitmap.bmWidth;     m_rcDragBlock.top = rect.bottom - bitmap.bmHeight;     m_rcDragBlock.right = rect.right;     m_rcDragBlock.bottom = rect.bottom; }   void CDragDialog::PaintDragBlock(CPaintDC &dc) {     CDC dcMemory;     dcMemory.CreateCompatibleDC(&dc);     CBitmap* pOldBitmap = dcMemory.SelectObject(&m_btDragBlock);       dc.BitBlt(m_rcDragBlock.left, m_rcDragBlock.top, m_rcDragBlock.Width(),m_rcDragBlock.Height(),         &dcMemory,0, 0, SRCCOPY);       dcMemory.SelectObject(pOldBitmap); }   bool CDragDialog::GetTitleRect(CRect &rect) const {     if (!::IsWindow(this->m_hWnd))     {         return false;     }       CRect rcWindow(0,0,0,0);     GetWindowRect(&rcWindow);     CRect rcClient(0,0,0,0);     GetClientRect(rcClient);     rect = rcWindow;     rect.bottom = rcWindow.bottom - rcClient.Height();     return true; }   void CDragDialog::ReSizeDialog(const CPoint &point) {     if (!m_bDrag)         return;       CRect rcWindow(0,0,0,0);     GetWindowRect(&rcWindow);     CRect rcTitle(0,0,0,0);     GetTitleRect(rcTitle);     int nTitleHeight = rcTitle.Height();     if (point.x < m_szMinSize.cx && point.y < m_szMinSize.cy - nTitleHeight)     {         SetWindowPos(&CWnd::wndTopMost, 0, 0, m_szMinSize.cx, m_szMinSize.cy, SWP_NOMOVE | SWP_NOZORDER | SWP_SHOWWINDOW | SWP_NOOWNERZORDER);     }     else if (point.x < m_szMinSize.cx)     {         SetWindowPos(&CWnd::wndTopMost, 0, 0, m_szMinSize.cx, rcWindow.Height() + (point.y - m_ptLast.y), SWP_NOMOVE | SWP_NOZORDER | SWP_SHOWWINDOW | SWP_NOOWNERZORDER);     }     else if (point.y < m_szMinSize.cy - nTitleHeight)     {         SetWindowPos(&CWnd::wndTopMost, 0, 0, rcWindow.Width() + (point.x - m_ptLast.x), m_szMinSize.cy, SWP_NOMOVE | SWP_NOZORDER | SWP_SHOWWINDOW | SWP_NOOWNERZORDER);     }     else     {         SetWindowPos(&CWnd::wndTopMost, 0, 0, rcWindow.Width() + (point.x - m_ptLast.x), rcWindow.Height() + (point.y - m_ptLast.y), SWP_NOMOVE | SWP_NOZORDER | SWP_SHOWWINDOW | SWP_NOOWNERZORDER);     }     if (NULL != GetParent())     {         //GetParent()->InvalidateRect(rcWindow);         GetParent()->Invalidate();     } }   void CDragDialog::OnMouseMove(UINT nFlags, CPoint point) {     // TODO: Add your message handler code here and/or call default     if (m_bDrag)     {         ::SetCursor(m_hcurDrag);         ReSizeDialog(point);         m_ptLast = point;         Invalidate();         ReSetDragBlock();     }     else if (m_rcDragBlock.PtInRect(point))     {         ::SetCursor(m_hcurDrag);     }     else     {         ::SetCursor(m_hcurArrow);     }       CDialog::OnMouseMove(nFlags, point); }   void CDragDialog::OnLButtonDown(UINT nFlags, CPoint point) {     // TODO: Add your message handler code here and/or call default     if (m_rcDragBlock.PtInRect(point))     {         m_bDrag = true;         ::SetCursor(m_hcurDrag);         SetCapture();         m_ptLast = point;     }       CDialog::OnLButtonDown(nFlags, point); }   void CDragDialog::OnLButtonUp(UINT nFlags, CPoint point) {     // TODO: Add your message handler code here and/or call default     if (m_bDrag)     {         m_bDrag = false;         ::SetCursor(m_hcurArrow);         ReleaseCapture();         m_ptLast = CPoint(0,0);     }       CDialog::OnLButtonUp(nFlags, point); }     void CDragDialog::OnSize(UINT nType, int cx, int cy) {     CDialog::OnSize(nType, cx, cy);       // TODO: Add your message handler code here     ReSizeContrals(); }   4.        派生类所做的工作 派生类需要做的工作为: 1) 重定义基类的 ReSizeContrals虚函数,函数内容为重新排列对话框中的控件(可用 SetWindowPosMoveWindow函数)。 2) 在派生类的 OnPaint函数中调用 PaintDragBlock函数。 PaintDragBlock函数的作用是在对话框的右下角画出“标识鼠标拖拽有效区的位图”。 5.        我所写的派生类的定义 class CDrugDlgDlg : public CDragDialog { public :     CDrugDlgDlg(CWnd* pParent = NULL); // ±ê×¼¹¹شى؛¯ت‎       enum { IDD = IDD_DRUGDLG_DIALOG };       protected:     virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV ض§³ض     protected :     HICON m_hIcon;       virtual BOOL OnInitDialog();     afx_msg void OnSysCommand(UINT nID, LPARAM lParam);     afx_msg void OnPaint();     afx_msg HCURSOR OnQueryDragIcon();     DECLARE_MESSAGE_MAP() private :     CButton m_ctlOK;     CButton m_ctlCancle; public :     virtual void ReSizeContrals(void); }; 6.        我所写的派生类的成员函数定义 我建立的工程是基于对话框的,如果工程是单文档或多问档派生类成员函数的定义会略有不同。 CDrugDlgDlg ::CDrugDlgDlg(CWnd* pParent /*=NULL*/)     : CDragDialog(CDrugDlgDlg::IDD, pParent) {     m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); }   void CDrugDlgDlg::DoDataExchange(CDataExchange* pDX) {     CDialog::DoDataExchange(pDX);     DDX_Control(pDX, IDOK, m_ctlOK);     DDX_Control(pDX, IDCANCEL, m_ctlCancle); }   BEGIN_MESSAGE_MAP (CDrugDlgDlg, CDragDialog)     ON_WM_SYSCOMMAND()     ON_WM_PAINT()     ON_WM_QUERYDRAGICON()     //}}AFX_MSG_MAP END_MESSAGE_MAP ()     BOOL CDrugDlgDlg::OnInitDialog() {     CDragDialog::OnInitDialog();         ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);     ASSERT(IDM_ABOUTBOX < 0xF000);       CMenu* pSysMenu = GetSystemMenu(FALSE);     if (pSysMenu != NULL)     {         CString strAboutMenu;         strAboutMenu.LoadString(IDS_ABOUTBOX);         if (!strAboutMenu.IsEmpty())         {             pSysMenu->AppendMenu(MF_SEPARATOR);             pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);         }     }       SetIcon(m_hIcon, TRUE);             SetIcon(m_hIcon, FALSE);              return TRUE }   void CDrugDlgDlg::OnSysCommand(UINT nID, LPARAM lParam) {     if ((nID & 0xFFF0) == IDM_ABOUTBOX)     {         CAboutDlg dlgAbout;         dlgAbout.DoModal();     }     else     {         CDragDialog::OnSysCommand(nID, lParam);     } }   void CDrugDlgDlg::OnPaint() {     if (IsIconic())     {         CPaintDC dc(this);         PaintDragBlock(dc);           SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);           int cxIcon = GetSystemMetrics(SM_CXICON);         int cyIcon = GetSystemMetrics(SM_CYICON);         CRect rect;         GetClientRect(&rect);         int x = (rect.Width() - cxIcon + 1) / 2;         int y = (rect.Height() - cyIcon + 1) / 2;           dc.DrawIcon(x, y, m_hIcon);     }     else     {         CDragDialog::OnPaint();     } }   HCURSOR CDrugDlgDlg::OnQueryDragIcon() {     return static_cast<HCURSOR>(m_hIcon); }   void CDragDialog::OnPaint() {     CPaintDC dc(this); // device context for painting     // TODO: Add your message handler code here     // Do not call CDialog::OnPaint() for painting messages     PaintDragBlock(dc); }   void CDrugDlgDlg::ReSizeContrals(void) {     if (::IsWindow(this->m_hWnd))     {         CRect rect(0,0,0,0);         GetClientRect(&rect);         if (::IsWindow(m_ctlOK.m_hWnd) && ::IsWindow(m_ctlCancle.m_hWnd))         {             m_ctlOK.SetWindowPos(&CWnd::wndTop,15,15,rect.Width()-30,(int)(rect.Height()/2)-15,SWP_NOZORDER);             m_ctlCancle.SetWindowPos(&CWnd::wndTop,15,(int)(rect.Height()/2),rect.Width()-30,(int)(rect.Height()/2)-15,SWP_NOZORDER);         }     } }    

    最新回复(0)