WTL architecture (3)

zhaozj2021-02-16  42

WTL architecture

view

The view window looks very simple:

class CMyView: public CWindowImpl {public: DECLARE_WND_CLASS (NULL) BOOL PreTranslateMessage (MSG * pMsg) {pMsg; return FALSE;} BEGIN_MSG_MAP (CMyView) MESSAGE_HANDLER (WM_PAINT, OnPaint) END_MSG_MAP () LRESULT OnPaint (UINT, WPARAM, LPARAM , Bool &) {CPAINTDC DC (M_HWND); // Todo: Add Your Drawing Code Here Return 0;}}; The above is a view class of an SDI program. The view class of multi-threaded SDI and MDI is essentially like this. But they don't have a PretranslateMessage () method. The SDI program uses this function to catch the message before the framework class processing message. PretranslateMessage () The implementation in the SDI's frame class is to forward the message to the view class. Here display The view doesn't actually do something. You should add code that draws the document content in the onpaint () function. If you need to support your input, such as click on the mouse, you should join the corresponding message processing function to the class and In the mapping. You can see that this window is inherited from cwindowimpl <>, if you want it to be based on a Win32 control, you should inherit a WTL class defined in an atlctrls.h file. If you want to CWindowIMPL > The class is plus the scroll bar, then you should change the base class to cscrollwindowimpl <>, while putting the message chain to it:

class CMyView: public CScrollWindowImpl {public: typedef CScrollWindowImpl parent; BEGIN_MSG_MAP (CMyView) CHAIN_MSG_MAP (parent) END_MSG_MAP () void DoPaint (CDCHandle dc) {}}; base class guarantees window includes a scroll bar, and provides a rolling The default processing of the message. The view class no longer has a WM_Paint process function because it has been processed by CScrollWindowImpl <>. According to the position of the scroll bar, the CSCROLLWINDOWIMPL <> draws the corresponding part of the view. Reveared, in your class To implement DopAint (), here you need to draw a whole view. If you want to specify the range, size, or starting point of the scrolling, you need to add the function that processes the WM_CREATE message, put these initialization code inside. As I first mentioned When it comes, the frame window changes the size of the view window to make the portion of the client area not covered by the status bar and the toolbar. In most cases, it is enough. But when you want one What should I do when Windows Explorer? Windows Explorer's window contains a Tree View and a List view, there is a split bar between the two. WTL's solution is simple: use the splitter window! For this purpose You need to change the frame window, let it create an instance of the splitter window as its view. For example, there is a data member in your frame class: ctreeWindow m_view; ctreeviewctrl m_tree; clistviewctrl m_list; you can create one in oncreate () splitter window: // get the frame client rect, so that we set the splitter initial size // and we can get the splitter bar in the centreRECT rect; GetClientRect (& rect); m_hWndClient = m_view.Create (m_hWnd, rect, NULL, WS_CHILD | WS_VISIBLE); M_TREE.CRE ate (m_view, rcDefault, NULL, WS_CHILD | WS_VISIBLE | TVS_HASBUTTONS | TVS_HASLINES | TVS_LINESATROOT, WS_EX_CLIENTEDGE); m_list.Create (m_view, rcDefault, NULL, WS_CHILD | WS_VISIBLE | LVS_REPORT, WS_EX_CLIENTEDGE); m_view.SetSplitterPanes (m_tree, m_list); m_view .Setsplitterpos ();

The splitter window is like a view, the frame window as its parent window. In this code, I passed the actual size of the frame window client area to the splitter window. I can use RCDefault here, because once the frame window creates completion The frame window will forward the WM_SIZE message to splitter. Such splitter can change its own size to fill the frame. However, when I am ready to use a parameter-free setSplitterpos (), the split bar is set to the window midline, there is a problem. The splitter window uses its size to determine the center of the center, because rcdefault tells the window its size is 0 (therefore the center line is also 0), which means that the split strip will appear in Z left edge, hide the left window. Create Once the splitter window, you need to create the window you want to split. They will be created as the sub-window for the Splitter window. Finally, you will be added to the SPLitter window via setsplitterpanes () and determine the splice strip. The location. TheUI Update menu item can be set to be valid or invalid, you can take the check mark or like a Radio button, in a set of menu items, only one can be CHECK. In addition, the menu item can also with icon and Text. All of these states can be changed according to a value in the program at runtime. The toolbar can see some degree of easy-to-see menu because their buttons can be individually, or as a group Part of the part is set effective or invalid, pushing. UI Update mechanism allows you to specify which UI Element can change at runtime. WTL uses the following Update mapping to implement this feature: Begin_UPDATE_UI_MAP (CMAINFRAME ) UPDATE_ELEMENT (ID_FILE_SAVERESULTS, UPDUI_MENUPOPUP | UPDUI_TOOLBAR) UPDATE_ELEMENT (ID_VIEW_TOOLBAR, UPDUI_MENUPOPUP) UPDATE_ELEMENT (ID_VIEW_STATUS_BAR, UPDUI_MENUPOPUP) END_UPDATE_UI_MAP () this example points out three menu items have a state needs to display at runtime, one, ID_FILE_SAVERESULTS, as well as a tool The strip button is associated with it. WTL saves this information by establishing an array. To this end, you need to complete two works:

The first is the status of the UI component. If it is a menu item, you can use uieNable () enable the menu item, uisetcheck () set the check mark, uiSettext () change the text of the menu. If it is the toolbar button, then you use uienable. Enable the button, uisetcheck () or uiSetradio () decision button is put into or launched. The following code is selected according to whether there is text, to enable the CUT menu item and the toolbar button: BOOL bselected = getSelected (); uieNable (Id_edit_cut, bselected); You can put this code into the corresponding processing function (such as a menu item depending on the action of another menu item, put it into the latter's processing function), or put onIdle () Method, by checking a certain type variable to determine the status of the component. Second, it is to determine if each UI component is updated, and for this, you need to call a certain method of CupdateUi <> to add the UI component to the list. Main menu Has been automatically added, but other menus and all the toolbars must be joined manually by calling uiaddmenubar () and uiaddtoolbar (). At other, there is also a bunch of things to pay attention. First, use UiupDateToolbar after setting the toolbar. ) So that the tool strip status is updated. For menus, you don't need this, because the submenu is dynamically generated .uiupdateMenubar () method also exists, but its role is to restore the menu to the initial state, if you change some The text of the item, the result of calling UiupdateMenubar () may not be what you expect (because the text of the menu item will become old). Although there is still a method uiTradio (), but there is no one menu item or toolbar The button is as a Radio button group (that is, there is one and only one selected) mechanism. If you want to get this effect, you must encode yourself, but it is not difficult. (Untrained)

转载请注明原文地址:https://www.9cbs.com/read-27302.html

New Post(0)