it seems csplitterwnd is designed to be used in document/view-based applications only.
but by overriding some virtual methods in a derived class, you can make splitter windows based on csplitterwnd be used in dialog based application, activex-controls using mfc:
all virtual methods that call getparentframe() in its implementation have to be overridden.
i have done this by using existing code except
- that i replaced the call to getparentframe() by a call to getparent().
- all references or pointers to cframewnd were changed to references or pointers to cwnd.
i derived a class cxsplitterwnd from the class csplitterwnd and proceeded as stated above.
then i used this class in a dialog based application in the same way as any other cwnd derived class.
for example:
but by overriding some virtual methods in a derived class, you can make splitter windows based on csplitterwnd be used in dialog based application, activex-controls using mfc:
all virtual methods that call getparentframe() in its implementation have to be overridden.
i have done this by using existing code except
- that i replaced the call to getparentframe() by a call to getparent().
- all references or pointers to cframewnd were changed to references or pointers to cwnd.
i derived a class cxsplitterwnd from the class csplitterwnd and proceeded as stated above.
then i used this class in a dialog based application in the same way as any other cwnd derived class.
for example:
class csampledialog : public cdialog { ... cxsplitterwnd m_wndsplitter; .... } bool csampledlg::oninitdialog() { ... // todo: add extra initialization here m_wndsplitter.createstatic(this, 1, 2); m_wndsplitter.createview(0,0,runtime_class(csampleview), csize(50,0), null); m_wndsplitter.createview(0,1,runtime_class(csampleview), csize(0,0), null); crect rect = ...; m_wndsplitter.movewindow(&rect); ... }
the sample attached is a dialog based application and demonstrates the use of cxsplitterwnd. it does
nothing useful.
this is the new class declaration:
// splitwnd.h : implementation 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: //{{afx_msg(cxsplitterwnd) // note - the classwizard will add and remove member functions here. //}}afx_msg declare_message_map() };
and here the implementation file:
// splitwnd.cpp : implementation file // #include "stdafx.h" #include "splitwnd.h" #ifdef _debug #define new debug_new #undef this_file static 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 add and remove mapping macros here. //}}afx_msg_map end_message_map() cwnd* cxsplitterwnd::getactivepane(int* prow, 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::setactivepane( int row, 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 gethitrect(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; oninverttracker(m_recttracker); if (m_btracking2) oninverttracker(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 (cwnd::onnotify(wparam, 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(afxgetstaticmodulestate()); return cwnd::onwndmsg(message, wparam, lparam, presult);}