扫一扫
分享文章到微信
扫一扫
关注官方公众号
至顶头条
作者:张中庆 来源:vckbase 2007年10月16日
关键字:
virtual void StartTracking(int ht); virtual CWnd* GetActivePane(int* pRow = NULL, int* pCol = NULL); virtual void SetActivePane( int row, int col, CWnd* pWnd = NULL ); virtual BOOL OnCommand(WPARAM wParam, LPARAM lParam); virtual BOOL OnNotify( WPARAM wParam, LPARAM lParam, LRESULT* pResult ); virtual BOOL OnWndMsg( UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pResult );具体实现如下,实现中我将给出原有代码的主要部分以及修改后的代码以作对比。
enum HitTestValue { noHit = 0,//表示没有选中任何对象 vSplitterBox = 1, hSplitterBox = 2, bothSplitterBox = 3, vSplitterBar1 = 101,//代表各个方向的水平分割条 vSplitterBar15 = 115, hSplitterBar1 = 201,//代表垂直方向的各个分割条 hSplitterBar15 = 215, splitterIntersection1 = 301,//代表各个交叉点 splitterIntersection225 = 525 };这样我们就可以在对话框中使用CxSplitterWnd类了。
CWnd* CxSplitterWnd::GetActivePane(int* pRow, int* pCol) { ASSERT_VALID(this); //获得当前的获得焦点的窗口 //下面注释粗体的是原有的代码的主要部分。 // CWnd* pView = NULL; //CFrameWnd* pFrameWnd = GetParentFrame(); //ASSERT_VALID(pFrameWnd); //pView = pFrameWnd->GetActiveView(); //if (pView == NULL) // pView = GetFocus(); CWnd* pView = GetFocus(); if (pView != NULL && !IsChildPane(pView, pRow, pCol)) pView = NULL; return pView; } void CxSplitterWnd::SetActivePane( int row, int col, CWnd* pWnd) { CWnd* pPane = pWnd == NULL ? GetPane(row, col) : pWnd; //下面加注释粗体的是原有代码的主要部分。 //FrameWnd* pFrameWnd = GetParentFrame(); //ASSERT_VALID(pFrameWnd); //pFrameWnd->SetActiveView((CView*)pPane); pPane->SetFocus();//修改后的语句 } void CxSplitterWnd::StartTracking(int ht) { ASSERT_VALID(this); if (ht == noHit) return; // GetHitRect will restrict ''''m_rectLimit'''' as appropriate GetInsideRect(m_rectLimit); if (ht >= splitterIntersection1 && ht <= splitterIntersection225) { // split two directions (two tracking rectangles) int row = (ht - splitterIntersection1) / 15; int col = (ht - splitterIntersection1) % 15; GetHitRect(row + vSplitterBar1, m_rectTracker); int yTrackOffset = m_ptTrackOffset.y; m_bTracking2 = TRUE; GetHitRect(col + hSplitterBar1, m_rectTracker2); m_ptTrackOffset.y = yTrackOffset; } else if (ht == bothSplitterBox) { // hit on splitter boxes (for keyboard) GetHitRect(vSplitterBox, m_rectTracker); int yTrackOffset = m_ptTrackOffset.y; m_bTracking2 = TRUE; GetHitRect(hSplitterBox, m_rectTracker2); m_ptTrackOffset.y = yTrackOffset; // center it m_rectTracker.OffsetRect(0, m_rectLimit.Height()/2); m_rectTracker2.OffsetRect(m_rectLimit.Width()/2, 0); } else { // only hit one bar GetHitRect(ht, m_rectTracker); } //下面加注释的将从程序中删去。 //CView* pView = (CView*)GetActivePane(); //if (pView != NULL && pView->IsKindOf(RUNTIME_CLASS(CView))) //{ // ASSERT_VALID(pView); // CFrameWnd* pFrameWnd = GetParentFrame(); //ASSERT_VALID(pFrameWnd); //pView->OnActivateFrame(WA_INACTIVE, pFrameWnd); // } // steal focus and capture SetCapture(); SetFocus(); // make sure no updates are pending RedrawWindow(NULL, NULL, RDW_ALLCHILDREN | RDW_UPDATENOW); // set tracking state and appropriate cursor m_bTracking = TRUE; OnInvertTracker(m_rectTracker); if (m_bTracking2) OnInvertTracker(m_rectTracker2); m_htTrack = ht; SetSplitCursor(ht); } BOOL CxSplitterWnd::OnCommand(WPARAM wParam, LPARAM lParam) { if (CWnd::OnCommand(wParam, lParam)) return TRUE; //下面粗体的是原程序的语句 //return GetParentFrame()->SendMessage(WM_COMMAND, wParam, lParam); return GetParent()->SendMessage(WM_COMMAND, wParam, lParam); } BOOL CxSplitterWnd::OnNotify( WPARAM wParam, LPARAM lParam, LRESULT* pResult ) { if (CWnd::OnNotify(wParam, lParam, pResult)) return TRUE; //下面粗体的是源程序的语句 //*pResult = GetParentFrame()->SendMessage(WM_NOTIFY, wParam, lParam); *pResult = GetParent()->SendMessage(WM_NOTIFY, wParam, lParam); return TRUE; } BOOL CxSplitterWnd::OnWndMsg(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pResult) { // The code line below is necessary if using CxSplitterWnd in a regular dll // AFX_MANAGE_STATE(AfxGetStaticModuleState()); return CWnd::OnWndMsg(message, wParam, lParam, pResult); }
void CXXSplitterWnd::OnLButtonDown(UINT nFlags,CPoint point)其余的处理方法类似。
{ CWnd::OnLButtonDown(nFlags,point); }
void CSplitterWndEx::OnDrawSplitter(CDC *pDC, ESplitType nType, const CRect &rectArg) { if(pDC==NULL) { RedrawWindow(rectArg,NULL,RDW_INVALIDATE|RDW_NOCHILDREN); return; } ASSERT_VALID(pDC); CRect rc=rectArg; switch(nType) { case splitBorder: //重画分割窗口边界,使之为红色 pDC->Draw3dRect(rc,RGB(255,0,0),RGB(255,0,0)); rc.InflateRect(-CX_BORDER,-CY_BORDER); pDC->Draw3dRect(rc,RGB(255,0,0),RGB(255,0,0)); return; case splitBox: pDC->Draw3dRect(rc,RGB(0,0,0),RGB(0,0,0)); rc.InflateRect(-CX_BORDER,-CY_BORDER); pDC->Draw3dRect(rc,RGB(0,0,0),RGB(0,0,0)); rc.InflateRect(-CX_BORDER,-CY_BORDER); pDC->FillSolidRect(rc,RGB(0,0,0)); pDC->Draw3dRect(rc,RGB(0,0,0),RGB(0,0,0)); return; case splitBar: //重画分割条,使之为绿色 pDC->FillSolidRect(rc,RGB(255,255,255)); rc.InflateRect(-5,-5); pDC->Draw3dRect(rc,RGB(255,0,0),RGB(255,0,0)); return; default: ASSERT(FALSE); } pDC->FillSolidRect(rc,RGB(0,0,255)); } void CSplitterWndEx::OnInvertTracker(CRect &rect) { ASSERT_VALID(this); ASSERT(!rect.IsRectEmpty()); ASSERT((GetStyle()&WS_CLIPCHILDREN)==0); CRect rc=rect; rc.InflateRect(2,2); CDC* pDC=GetDC(); CBrush* pBrush=CDC::GetHalftoneBrush(); HBRUSH hOldBrush=NULL; if(pBrush!=NULL) hOldBrush=(HBRUSH)SelectObject(pDC->m_hDC,pBrush->m_hObject); pDC->PatBlt(rc.left,rc.top,rc.Width(),rc.Height(),BLACKNESS); if(hOldBrush!=NULL) SelectObject(pDC->m_hDC,hOldBrush); ReleaseDC(pDC); }同样我们只要继承CSplitterWnd中的其余的一些虚拟方法就可以生成具有自己个性的分割窗口了。
如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。