|
最近,在开发飞鸽传书C/S版的即时通讯软件时,需要解决消息对话框中窗口拆分问题,一时间,一头雾水,无从入手。后来还是一步一步解决了这问题,现在就和大家说说我的解决方案。水平有限,请多指教。转载请注明出处:http://www.freeeim.com/ 在网上,许多文章的窗口拆分实现方法是使用 CSplitWnd 类,的确,他可以解决许多功能,但是当你要自定义一些功能,或自绘窗口时,他的局限性就全部暴露出来了。废话太多了,就说我的方法吧: 我使用 CDialog 通过处理鼠标事件来处理窗口拆分,实现方法比较难说清楚,代码最好说明问题。 1.文件:csplitdlg.h class CSplitDlg : public CDialog { // Construction public: void SetTowWindow(CWnd *pWnd1, CWnd *pWnd2, DWORD dwLeftMin); BOOL m_bTracking; CBrush m_brBk1; CBrush m_brBk2; CBrush m_brBk3; BOOL m_bCaptured; CPoint m_ptDown; CWnd *m_wndTop; DWORD m_nLeftMin; CWnd *m_wndBottom; CSplitDlg(CWnd* pParent = NULL); // standard constructor // Dialog Data //{{AFX_DATA(CSplitDlg) enum { IDD = IDD_DIALOG4 }; // NOTE: the ClassWizard will add data members here //}}AFX_DATA // Overrides // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CSplitDlg) protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support //}}AFX_VIRTUAL // Implementation protected: // Generated message map functions //{{AFX_MSG(CSplitDlg) afx_msg void OnMouseMove(UINT nFlags, CPoint point); afx_msg LRESULT OnMouseLeave(WPARAM wparam, LPARAM lparam); afx_msg void OnMouseHover(WPARAM wparam, LPARAM lparam) ; afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor); afx_msg void OnLButtonDown(UINT nFlags, CPoint point); afx_msg void OnLButtonUp(UINT nFlags, CPoint point); virtual BOOL OnInitDialog(); //}}AFX_MSG DECLARE_MESSAGE_MAP() }; ********************************************************************************************************************** 2.文件 csplitdlg.cpp #include "stdafx.h" #include "SplitDlg.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CSplitDlg dialog CSplitDlg::CSplitDlg(CWnd* pParent /*=NULL*/) : CDialog(CSplitDlg::IDD, pParent) { //{{AFX_DATA_INIT(CSplitDlg) // NOTE: the ClassWizard will add member initialization here //}}AFX_DATA_INIT } void CSplitDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CSplitDlg) // NOTE: the ClassWizard will add DDX and DDV calls here //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CSplitDlg, CDialog) //{{AFX_MSG_MAP(CSplitDlg) ON_WM_MOUSEMOVE() ON_MESSAGE(WM_MOUSELEAVE, OnMouseLeave) ON_MESSAGE(WM_MOUSEHOVER, OnMouseHover) ON_WM_CTLCOLOR() ON_WM_LBUTTONDOWN() ON_WM_LBUTTONUP() //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CSplitDlg message handlers void CSplitDlg::OnMouseMove(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default SetCursor(LoadCursor(NULL, IDC_SIZENS)); GetParent()->ScreenToClient(&point); CPoint apt = point; ClientToScreen(&apt); if (!m_bTracking) { TRACKMOUSEEVENT tme; tme.cbSize = sizeof(tme); tme.hwndTrack = m_hWnd; tme.dwFlags = TME_LEAVE|TME_HOVER; tme.dwHoverTime = 1; m_bTracking = _TrackMouseEvent(&tme); } else { if (m_bCaptured) { // 中间分解线 CRect rc; GetWindowRect(&rc); GetParent()->ScreenToClient(&rc); // 左侧窗口 CRect rtTop; m_wndTop->GetWindowRect(&rtTop); GetParent()->ScreenToClient(&rtTop); // 右侧窗口 CRect rtBottom; m_wndBottom->GetWindowRect(&rtBottom); GetParent()->ScreenToClient(&rtBottom); CRect rtParent; GetParent()->GetWindowRect(&rtParent); GetParent()->ScreenToClient(&rtParent); int nHalf = rtParent.Width()/2; apt.y -= m_ptDown.y; if (apt.y < (int)m_nLeftMin) { rtTop.bottom = m_nLeftMin; rtBottom.top = rc.Height() + m_nLeftMin; m_wndTop->MoveWindow(rtTop); m_wndBottom->MoveWindow(rtBottom); MoveWindow(rtTop.left, m_nLeftMin, rc.Width(), rc.Height()); // CString str; // str.Format("apt.y < (int)m_nLeftMin %d, %d", apt.y, m_ptDown.y); // GetParent()->SetWindowText(str); } else if (rtParent.bottom-apt.y-42 < 38) { rtTop.bottom = rtParent.bottom-42-rc.Height()-38; rtBottom.top =rtParent.bottom-42-38; m_wndTop->MoveWindow(rtTop); m_wndBottom->MoveWindow(rtBottom); MoveWindow(rc.left, rtTop.bottom, rc.Width(), rc.Height()); // CString str; // str.Format("rtParent.bottom-apt.y-42 < 38"); // GetParent()->SetWindowText(str); } else { rtTop.bottom = apt.y; rtBottom.top = apt.y + rc.Height(); m_wndTop->MoveWindow(rtTop); m_wndBottom->MoveWindow(rtBottom); MoveWindow(rc.left, apt.y, rc.Width(), rc.Height()); // CString str; // str.Format("y:%d, %d, %d, %d, %d, %d, %d", apt.y, rtParent.right, rtParent.bottom, // rtBottom.Width(), rtBottom.Height(), // rtBottom.right, rtBottom.bottom); // GetParent()->SetWindowText(str); } } } CDialog::OnMouseMove(nFlags, point); } void CSplitDlg::OnMouseHover(WPARAM wparam, LPARAM lparam) { // TODO: Add your message handler code here and/or call default // SetDlgItemText(IDC_STATIC, "hover"); RedrawWindow(); } LRESULT CSplitDlg::OnMouseLeave(WPARAM wparam, LPARAM lparam) { // SetDlgItemText(IDC_STATIC, "leave"); m_bTracking = FALSE; RedrawWindow(); return 0; } HBRUSH CSplitDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) { HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor); // TODO: Change any attributes of the DC here switch(nCtlColor) { case CTLCOLOR_DLG: if (m_bTracking) { if (m_bCaptured) return (HBRUSH)m_brBk2.GetSafeHandle(); else return (HBRUSH)m_brBk3.GetSafeHandle(); } else return (HBRUSH)m_brBk1.GetSafeHandle(); } // TODO: Return a different brush if the default is not desired return hbr; } /* UINT CAaaaaaaaaDlg::OnNcHitTest(CPoint point) { UINT nResult = CDialog::OnNcHitTest(point); return nResult == HTCLIENT ? HTCAPTION : nResult; } */ void CSplitDlg::OnLButtonDown(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default SetCursor(LoadCursor(NULL, IDC_SIZENS)); // SetCursor(LoadCursor(NULL, IDC_SIZEWE)); if(!m_bCaptured) { m_bCaptured=true; RedrawWindow(); SetCapture(); m_ptDown.x = point.x; m_ptDown.y = point.y; // CRect rt; // GetWindowRect(&rt); // GetParent()->ScreenToClient(&rt); // m_ptDown=rt.TopLeft(); } // CDialog::OnLButtonDown(nFlags, point); } void CSplitDlg::OnLButtonUp(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default SetCursor(LoadCursor(NULL, IDC_SIZEWE)); if(m_bCaptured) { m_bCaptured=false; RedrawWindow(); ReleaseCapture(); } // CDialog::OnLButtonUp(nFlags, point); } BOOL CSplitDlg::OnInitDialog() { CDialog::OnInitDialog(); // TODO: Add extra initialization here m_brBk1.CreateSolidBrush(RGB(236, 243, 246)); m_brBk2.CreateSolidBrush(RGB(200, 200, 200)); m_brBk3.CreateSolidBrush(RGB(100, 100, 100)); m_bCaptured = FALSE; m_bTracking = FALSE; return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE } void CSplitDlg::SetTowWindow(CWnd *pWnd1, CWnd *pWnd2, DWORD dwLeftMin) { m_wndTop = pWnd1; m_wndBottom = pWnd2; m_nLeftMin = dwLeftMin; } 转载请注明出处:http://www.freeeim.com/
|