The younger brother's first post, the level is not high, I hope not to lose things. Oh.
Everyone knows that you can use CSPLitterWnd on a cframewnd to make a split window (huh, the way, the split window can be a big feature of the MFC program. Previous (Delphi did not add this support), you only have to see the split window It is almost certain that it is MFC. (Haha, of course, some people do one with SDK, have this kind of idle guy? Oh, it seems to be too nonsense.).
However, in the real situation is, sometimes we have to make a splitterwnd effect on a general CWnd. How to do? SplitterWnd can only be used for CFrameWnd (like the CView class, MS) The reason why this limit is because TMD shit ms puts all the places where you want to take the Parent window in SplitterWnd. But in fact, it does not use any characteristics of CFrameWnd. So what should we do? It seems that it is very obvious. That's going to turn the source code of the SplitterWnd of MS, change all the places where PARENT. Ah !!! No, this is also called the shit OOP? It should be an overloaded one of our own .
head File:
// splitwnd.h: importation file // class cxsplitterwnd: public csplitterwnd {// construction public: cxsplitterwnd () {}; virtual ~ cxsplitterwnd () {};
// Operations public: // Overrides // ClassWizard generated virtual function overrides // {AFX_VIRTUAL (CXSPLITTERWND) //}} AFX_VIRTUAL
// Implementation public: // These are the methods to be overridden 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) ;
// generated message map functions protected: /// Note - The classwizard will address ///}} AFX_MSG DECLARE_MESSAGE_MAP ()};
There is also a document:
// splitWnd.cpp: importation file // #include "stdafx.h" #include "splitwnd.h"
#ifdef _debug # define new debug_new # undef this_filestatic char this_file [] = __file __; # ENDIF
// HitTest return values (values and spacing between values is important) // Had to adopt this because it has module scope enum HitTestValue {noHit = 0, vSplitterBox = 1, hSplitterBox = 2, bothSplitterBox = 3, // just for keyboard vSplitterBar1 = 101, vsplitterbar15 = 115, hsplitterbar1 = 201, hsplitterbar15 = 215, splitterintersection1 = 301, splitterintersection225 = 525}; /// cxsplitterwnd
Begin_Message_Map (cxsplitterwnd, csplitterWnd) // {AFX_MSG_MAP (cxsplitterWnd) // Note - The classwizard will address ////}} AFX_MSG_MAPEND_MESSAGE_MAP ()
CWnd * cxsplitterWnd :: getActivePane (int * pcol) {assert_valid (this); cWnd * pView = getFocus (); // make sure the pane is a child PANE of the splitter if (pView! = Null&&! Ischildpane (PView, Prow, Pcol) PView = null; Return PView;}
Void cxsplitterWnd :: Set, int COL, CWND * PWND {// set the focus to the PANE CWND * PPANE = PWND == NULL? GetPane (Row, Col): PWND; 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 getHit Rect (ht, m_rectTracker);} // 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; OnNinvertTracker; if (m_btracking2) OnNinvertTracker (m_recttracker2); m_httrack = ht; setsplitcursor (ht);}
/// CSplitterWnd command routing BOOL CxSplitterWnd :: OnCommand (WPARAM wParam, LPARAM lParam) {if (CWnd :: OnCommand (wParam, lParam)) return TRUE; // route commands to the splitter to the parent frame window return GetParent () -> SendMessage (wm_command, wparam, lparam);
BOOL CxSplitterWnd :: OnNotify (WPARAM wParam, LPARAM lParam, LRESULT * pResult) {if (wParam CWnd :: OnNotify (, lParam, pResult)) return TRUE; // route commands to the splitter to the parent frame window * 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 (AFXGETSTAICMODULESTATE ()); Return CWnd :: OnWndmsg (Message, WPARAM, LPARAM, PRESULT);
Give this file to your project, you can use cxsplitterwnd.