Chapter 8 divide and conquer with Splitters

Source: Internet
Author: User

 

Divide and conquer with Splitters

 

The multi-SDI and MDI we introduced earlier use multiple views to display application data in a single application. another popular method is to split a window into one or more subwindows using a split string. the csplitterimpl and csplitter1_wimpl classes of wtl provide support for split windows. the core of the wtl split window is the csplitterimpl class, which provides all the magic functions required, such as creating a split window and adjusting the Panel sizes on both sides of the split bar. the csplitterimpl class is used as the base class and must be derived from it. in addition, the derived class of the csplitterimpl class must also be derived from the csf-wimpl class (or derived from the cmessagemap class with a message processing interface ). although the csplitterimpl class has its own message ing, it must be linked to the csplitterimpl class through chain_msg_map or other message ing chains in its derived class to capture and process messages.
 
// Atlsplit. h

Template <class T, bool t_bvertical = true>
Class csplitterimpl
{...

Begin_msg_map (thisclass)
Message_handler (wm_create, oncreate)
Message_handler (wm_paint, onpaint)
Message_handler (wm_printclient, onpaint)
If (isinteractive ())
{
Message_handler (wm_setcursor, onsetcursor)
Message_handler (wm_mousemove, onmousemove)
Message_handler (wm_lbuttondown, onlbuttondown)
Message_handler (wm_lbuttonup, onlbuttonup)
Message_handler (wm_lbuttondblclk,
Onlbuttondoubleclick)
}
Message_handler (wm_setfocus, onsetfocus)
Message_handler (wm_mouseactivate, onmouseactivate)
Message_handler (wm_settingchange, onsettingchange)
End_msg_map ()
...
...
};

The following code separates the SDI framework window we created earlier into a split window with two HTML views.
Class cmainframe:
Public cframeworkwimpl <cmainframe>,
Public csplitterimpl <cmainframe, true>
{
Public:
Declare_wnd_class_ex (null, cs_dblclks, color_window)

Typedef cframeworkwimpl <cmainframe> winbaseclass;
Typedef csplitterimpl <cmainframe, true> splitbaseclass;
Begin_msg_map (cmainframe)
...
Message_handler (wm_create, oncreate)
Message_handler (wm_erasebkgnd, onerasebackground)
Message_handler (wm_size, onsize)
Chain_msg_map (splitbaseclass)
End_msg_map ()
//...
PRIVATE: // The two panes within the Splitter
Chtmlview m_viewleft;
Chtmlview m_viewright;

...
};

Two view classes have been created in the wm_create message ing function. Because our framework window class cmainframe is the derived class of csplitterimpl, the member function csplitterimpl is called directly :: setsplitterpanes sets two view classes as two panels of the split window. finally, call csplitterimpl: setsplitterpos to set the split position. The split position determines the size of the two panels.

Lresult cmainframe: oncreate (uint, wparam, lparam, bool & bhandled)
{
...

// First the 2 Views (PANES)
M_viewleft.create (m_hwnd, rcdefault,
_ T ("http://www.sellsbrothers.com/tools"), ws_child |
Ws_visible | ws_clipsiblings,
Ws_ex_staticedge );
M_viewright.create (m_hwnd, rcdefault,
_ T ("http://www.sellsbrothers.com/comfun"), ws_child |
Ws_visible | ws_clipsiblings | ws_vscroll | ws_clipchildren,
Ws_ex_staticedge );

// Link the panes to the Splitter
Setsplitterpanes (m_viewleft, m_viewright );

// Set the initial positions
Rect RC; getclientrect (& rc );
Setsplitterpos (RC. Right-RC. Left)/4 );

Bhandled = false;
Return 0;
}

 

When the user adjusts the window size, the wm_size message ing function needs to calculate the size of the available customer zone and subtract the region occupied by the compound bar control (rebar), and then call csplitterimpl: setsplitterrect to reset the split bar position. note that this is not required when the window is minimized. In fact, nothing is done. of course, this message still needs to be processed by default, so bhandled = false is set.
Lresult cmainframe: onsize (uint, wparam, lparam, bool & bhandled)
{
If (wparam! = Size_minimized)
{
Rect RC; getclientrect (& rc );
Rect rcbar;: getclientrect (m_hwndtoolbar, & rcbar );
RC. Top = rcbar. bottom;
Setsplitterrect (& rc );
}

Bhandled = false;
Return 1;
}

 

Finally, in order to avoid window flickering when the window is dragged, cmainframe processes the wm_erasebkgnd message and only returns a non-zero value, so the message processing ends here, ignore the default processing of defwindowproc, because the processing of wm_erasebkgnd messages by defwindowproc is to refresh the background to be updated with the background paint of the window class, which will cause the screen to flash.
Note: In the definition of message ing macro, if a message defines message ing and bhandled = false is set in the message ing function, the virtual message processing function virtual bool processwindowmessage () returns false; otherwise, the system returns true. If no message ing is defined for a message, the virtual message processing function returns false, the window processing process will look for other processing methods in the message ing chain. therefore, the bhandled variable determines the return value of the virtual message processing function virtual bool processwindowmessage (), and the return value of this function determines whether to further process the message in the message ing chain, the Return Value of the message ing function is returned as a parameter of the virtual message processing function.

Lresult cmainframe: onerasebackground (uint, wparam, lparam, bool &)
{
Return 1;
}

 

Figure11a demonstrates the above csplitterimpl usage, that is, the customer needs to be divided into two panel window classes only need to be derived from the csplitterimpl class.

Figure 11A: csplitterimpl in the inheritance scenario

 

If you derive from the csplitterimpl class, you must process the wm_erasebkgnd and wm_size messages. It is very painful to do the same thing every time. fortunately, wtl adds another abstraction layer. The csplitterjavaswimpl class is provided between the csplitterimpl and the derived window class to process the two messages. at the same time, the csplitterreceivwimpl class reflects the notification message to the parent window for processing, and links unprocessed common messages to csplitterimpl for processing.
// Atlsplit. h
Template <class T, bool t_bvertical = true, class tbase = cwindow, class twintraits = ccontrolwintraits>
Class atl_no_vtable csplitter=wimpl:
Public cwindowimpl <t, tbase, twintraits>,
Public csplitterimpl <csplitter1_wimpl <t,
T_bvertical, tbase, twintraits>,
T_bvertical>
{
Public:
Declare_wnd_class_ex (null, cs_dblclks, color_window)

Typedef csplitter1_wimpl <t, t_bvertical, tbase, twintraits> thisclass;
Typedef csplitterimpl <
Csplitterwimpl <t, t_bvertical, tbase, twintraits>,
T_bvertical> baseclass;

Begin_msg_map (thisclass)
Message_handler (wm_erasebkgnd, onerasebackground)
Message_handler (wm_size, onsize)
Chain_msg_map (baseclass)
Forward_notifications ()
End_msg_map ()

Lresult onerasebackground (uint, wparam, lparam, bool &) {return 1 ;}
Lresult onsize (uint, wparam, lparam, bool & bhandled)
{
If (wparam! = Size_minimized)
Setsplitterrect ();
Bhandled = false;
Return 1;
}
};

 

You can use the wtl split window to separate the customer area in the vertical and horizontal directions to form a nested grid-like multi-view window. in the example program included in this book, nestedsplitters shows the creation of nested split windows. (See Figure 11b)

Figure 11b: nestedsplitters Sample Application

 

If you want to use the split window control in combination instead of inheriting from the split window class, the csplitterwindow and chorsplitterwindow provided by wtl can meet your requirements. the following example shows how to use the csplitterwindow class in the window class COM control. This example is generated using the atl com Appwizard of the old version: for more information, see books on ATL and component object models)
Class atl_no_vtable cfoocontrol:

Public ccomobjectrootex <ccomsinglethreadmodel>,
Public ccomcontrol <cfoocontrol> ,...
{
Cfoocontrol ()
{
M_bwindowonly = true;
}

Begin_msg_map (cfoocontrol)
Message_handler (wm_create, oncreate)
Chain_msg_map (ccomcontrol <cfoocontrol>)
Default_reflection_handler ()
End_msg_map ()

// Message handlers and other usual suspects

PRIVATE:
Csplitterwindow m_splitter;
Chtmlview m_leftview;
Chtmlview m_rightview;
};

Lresult cfoocontrol: oncreate (uint, wparam, lparam, bool &)
{
Atlaxwininit ();

// Create the left and right views
M_leftview.create (m_hwnd, rcdefault, _ T ("http://www.microsoft.com"), ws_child | ws_visible |
Ws_clipsiblings | ws_clipchildren, ws_ex_staticedge );

M_rightview.create (m_hwnd, rcdefault, _ T ("http://www.microsoft.com"), ws_child | ws_visible |
Ws_clipsiblings | ws_clipchildren, ws_ex_staticedge );
Rect; getclientrect (& rect );

// Create the splitter object
M_splitter.create (m_hwnd, rect, null, ws_child | ws_visible | ws_clipsiblings | ws_clipchildren );

M_splitter.setsplitterpanes (m_leftview, m_rightview );
M_splitter.setsplitterpos (rect. Right-rect. Left)/4 );

Return 0l;
}

Finally, the wtl split window class can dynamically switch different views in one panel. You only need to call the csplitterimpl: setsplitterpane () member function and pass a different view window handle. you can set the data member variable m_cxymin and call csplitterimpl: setsplitterpos () to limit the minimum size and fixed position of the split panel.

 

GDI wrappers

To be continued...






Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.