ATL window (2)

zhaozj2021-02-17  63

WTL window

(ATL window Part 2) Translation: Sun Kai

-------------------------------------------------- -------------

This article is written by Andrew WhiteChapel.

-------------------------------------------------- -------------

Download code 12K

introduction

In my first article, I explained the ATL window class. The article brought a problem about the problem of reception GUI support from MFC to ATL. The result of this debate produces Microsoft Windows Template Library (WTL). I will bring you a WTL-based framework-view application through a very simple step, let you write your own feelings from the MFC to ATL.

WTL is an extension of ATL, which is also developed by ATL team, which is included in the development platform SDK package issued in Microsoft in January 2000 (you can also download from Microsoft Website), although Microsoft has not formally supported. WTL extends the ATL window class by providing a lightweight framework for writing Win32 applications and controlled, some special views, GDI objects, and practical classes.

The WTL package consists of 750KB window class library header files, three examples and a Visual Studio WTL AppWizard. Of course, it still relies on the 1MB size ATL file.

To install WTL, you have to do the following:

Copy the contents of the WTL directory to your specified location.

Add the WTL / INCLUDE directory to the list of header files (Include Directories) of the VC .

Copy file AppWiz / Atlapp60.AWX to the Custom Custom App Wizard (Custom App Wizard) directory,% vcdir% / common / msdev98 / template,% VCDIR% is the directory specified when VC is installed.

WTL Design Features - Incidentally, with respect to the advantages of MFC - including:

Template, therefore has a small amount of code. For example, a simple "Hello World" SDI application, WTL-based program is only 24kB, while the MFC static connection result is 440kb, the result of the MFC dynamic connection is 24KB 1MB.

There is no too much correlation and can be directly mixed freely with the SDK code.

Not forced to use specific application models, especially relative to the MFC application framework.

WTL classes include:

Standard control (edit box, list box, button, etc.)

Public control (including list view, tree view, progress bar, fine tune button)

IE control (Rebar, flat scroll bar, calendar, etc.)

Command strip, menu, and update UI class

Public dialog

Properties list and page classes

Frame window, MDI frame and sub-frame, partition, rolling window

Equipment environment (DC) and GDI object classes (pen, brush, bitmap, etc.)

Printer and its information and equipment mode

Practical tools: including CPoint, CRECT, CSIZE, and CSTRING classes

WTL AppWizard allows you to generate SDI, MDI, multi-threaded SDI, and dialog-based applications. Multi-threaded SDI app is like IE or Windows Explorer (my computer), it looks like a plurality of instances that are started, essentially they are multiple views of the same process. These views can be ordinary CWindowIMPL-based windows, or form, list boxes, edit boxes, list views, tree views, enrich text editing boxes or HTML controls. You can make your app have rebar, such as Windows CEs, toolbars or status bars. Your application can contain ActiveX control, or even a COM server. Hello WTL

In this exercise, we will create a WTL-based "Hello World" application.

Create a new WTL AppWizard application. Try HelloWorld. In the first step dialog in WTL AppWizard, accept all default options, click the next step button. In the Second Step dialog, all default options are retained (including toolbar, rebar, command bar, status bar, and view window), click the completion button. It is now compiled to run the program. You will see a very ordinary Win32 application, which has standard frames and views, menus, toolbars, status bars, and about dialogs. File | EXIT, View | Toolbar, View | Statusbar, and Help | The About Menu item / Toolbar Button can work, although other can't. Moreover, some menu items in the menu have the corresponding toolbar buttons icon:

Now analyze the code. First, you should notice that there is a standard ATL CCOMMODULE global variable in the _twinmain function, which performs initialization and termination functions. Analysis_twinmain function, you will find that other work it does is just to initialize the public control (by calling the InitCommonControlsex function) and calls the global function RUN (Processing Message loop). The Run function creates the main frame window and the CMessageloop object, call the ShowWindow function of the main frame window, and then call the cMessageloop :: Run function. The CMessageloop :: Run function is essentially turning GetMessage and DispatchMessage functions.

Then let us see the CMAINFRAME class generated by AppWizard. Its parent class defines in wtl / atlframe.h or wtl / atlapp.h. The main functions come from the CFrameWindowImpl class.

CupdateUI is connected via UPDATE_UI_MAP macros and eventually reaching the ONViewToolbar and ONVIEWSTATUSBAR functions in our derived CMAINFRAME. The operations do what we expect ShowWindow and SetCheck.

Deported in the CMessageFilter and CidleHandler classes mean that the CMAINFRAME class must implement a message filter. This message filter is used to clear some messages that do not have to be processed before dispatch messages (for example, change the way the user hit the user is processed). When there is no message in the message queue, the idle processing function is called.

The derived view class and the CCOMANDBARCTRL object are embedded in the frame window class as a member variable.

Class CMAINFRAME: PUBLIC CFRAMEWINDOWIMPL ,

Public CUPDATEUI ,

Public cMessageFilter, // message filtering

Public CIDLEHANDLER // Idle Processing

{

PUBLIC:

Declare_frame_wnd_class (null, idr_mainframe) // Define Frame Window Category CHELLOWORLDVIEW M_VIEW;

CCommandbarctrl m_cmdbar;

Begin_msg_map (cmainframe) // message mapping

Message_handler (WM_CREATE, ONCREATE)

Command_id_handler (ID_APP_EXIT, ONFILEEXIT)

Command_id_handler (id_file_new, onfilenew)

Command_id_handler (id_view_toolbar, onviewtoolbar)

Command_id_handler (id_view_status_bar, onviousstatusbar)

Command_id_handler (ID_APP_ABOUT, ONAPPABOUT)

CHAIN_MSG_MAP (CUPDATEUI )

CHAIN_MSG_MAP (CFrameWindowImpl )

END_MSG_MAP ()

Begin_UPDATE_UI_MAP (CMAINFRAME) // Update for Menu and Toolbar

UPDATE_ELEMENT (ID_View_toolbar, UPDUI_MENUPOPUP)

UPDATE_ELEMENT (ID_View_status_bar, updui_menupopup)

END_UPDATE_UI_MAP ()

}

The only most important function in the frame window class is oncreate. It initializes the CCOMANDBARCTRL object and associates with the menu, loads a list of commands (icons on the menu). In fact, the ccomandbarctrl class converts the menu description in the resource file to the toolbar element, which can easily associate the same command ID and icon for the menu item and the toolbar buttons. Then, the frame window continues to create a toolbar, a retractable (Rebar), and status bar. Then the initialization view. The final step is to join the Message Filter and Idle Handler to the application object of the CCommodule class. Message filtering is such a technology. In your program, the TRANSLATE / DISPATCHMESSAGE function processes it before the TRANSLATE / DISPATCHMESSAGE function processes it before the GetMessage function processes the message.

LRESULT OnCreate (uint / * umsg * /, wparam / * wparam * /,

LPARAM / * LPARAM * /, BOOL & / * BHANDLED * /

{

HWnd hwndcmdbar = m_cmdbar.create (m_hwnd,

RcDefault,

NULL,

ATL_SIMPLE_CMDBAR_PANE_STYLE);

m_cmdbar.attachmenu (GetMenu ());

m_cmdbar.loadImages; IDR_MAINFRAME;

SetMenu (NULL); // Delete an old-fashioned menu

HWND HWNDTOOLBAR = CREATESIMPLETOOLBARCTRL (m_hwnd,

IDR_MAINFRAME,

False,

ATL_SIMPLE_TOOLBAR_PANE_STYLE);

CreateSimpleRebar (ATL_SIMPLE_REBAR_NOBORDER_STYLE);

AddsImpleRebarband (HWndcmdbar);

AdsimpleRebarband (HWndToolbar, Null, True);

CreateSimpleStatusbar ();

m_hWndClient = m_view.create (m_hwnd, rcdefault, null,

WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, WS_EX_CLIENTEDGE

UIADDTOOLBAR (HWNDTOOLBAR);

UisetCheck (id_view_toolbar, 1);

UisetCheck (id_view_status_bar, 1);

CMessageLoop * plop = _Module.getMessageloop ();

PLOOP-> AddMessageFilter (this);

PLOOP-> AddIdleHandler (this);

Return 0;

}

The view class is derived from the CWINDOWIMPL class, the application wizard generates a message processor - for WM_Paint - with Todo Note:

Class Cheloworldview: Public CWindowImpl

{

PUBLIC:

Declare_Wnd_Class (NULL)

Bool PretranslateMessage (MSG * PMSG)

{

PMSG;

Return False;

}

Begin_msg_map (chelloworldview)

Message_handler (wm_paint, onpaint)

END_MSG_MAP ()

LResult onpaint (uint / * umsg * /, wparam / * wparam * /,

LPARAM / * LPARAM * /, BOOL & / * BHANDLED * /

{

CPAINTDC DC (M_HWND);

// Todo: Add Your Drawing Code Here

Return 0;

}

}

Here, make a small change. Join the TextOut function to the onpaint function to enter the "Hello World" string to compile it.

Compare this WTL version of the program with the previous chapter (the first part of the ATL window). Our easily comes from the wizard to do some annoying work. But don't forget all of these help us are free - framework view, beautiful menu, about dialogs, toolbar, and status bars, including display / hiding features, and update user interface processing. Similarly, comparing with the MFC's equivalent - MFC Application Guide gives you menus, toolbars, statustes, and regarding dialogs, but is it easy to add the tool strip button icon into the menu in the MFC? Moreover, compare the size of the executable file, especially the release.

In my article, I want to follow the ATL Scribble application in the last chapter.

Ok, if you click the right mouse button in the class view (ClassView), select "Add Windows Message Handler", then select the WM_LBUTTONDOWN handler, will generate the following code:

LRESULT ONLBUTTONDOWN (UINT UMSG,

WPARAM WPARAM,

LParam LPARAM,

Bool & bhandled)

{

Return 0;

}

The message mapping entries are as follows:

Message_handler (WM_LButtondown, ONLBUTTONDOWN)

Since we use ATL, the wizard no longer provides the macro of the CRACKED Messages used by the MFC. "Please stop" I heard you said, "Your article doesn't mean that WTL provides us with a message classification description macro?" Yes, WTL provides macros similar to MFC, in the AtlCrack.h file. If you look at the source code, you will see the macro corresponding to the Windows message. What you have to do is to use the appropriate macros and implement the message processing functions of the same format. Also, do you want to use begin_msg_map_ex instead of begin_msg_map macro. It provides a re-get current message and the specified message is processed for the CRACKED HANDLERS. This is because the classification description message processing function does not have the last Boole parameter of the ATL processing function. Therefore, Begin_MSG_MAP_EX macros defines an additional function setMessageHandledLED to complete this. For example, the macro in response to the WM_LBUTTONDOWN message is as follows: #define msg_wm_lbuttondown (func) /

IF (UMSG == WM_LButtondown) /

{/

SetmsgHandled (TRUE); /

Func ((uint) WPARAM, CPOINT (GET_X_LPARAM (LPARAM), /

GET_Y_LPARAM (LPARAM)))))))); /

LRESULT = 0; /

IF (ismsghand ()) /

Return True; /

}

Note that CPOINT is used here, so it is to include ATLMISC.H.

So, in your HelloWorldView.h file, you will join #include "atlmisc.h" and "atlcrack.h". Turn your view to the message map of your view to an EX version and add the following classification message macro and handler. Remember, if you want to use GDI objects like CPEN, add #include "atlgdi.h" to the file. Define two CPOINT objects m_startpoint, m_endpoint to the view, and initialize (-1, -1) in the constructor.

BEGIN_MSG_MAP_EX (ChelloworldView)

MSG_WM_LBUTTONDOWN (ONLBUTTONDOWN)

MSG_WM_LBUTTONUP (ONLBUTTONUP)

MSG_WM_MOUSEMOVE (ONMOUSEMOVE)

END_MSG_MAP ()

LRESULT ONLBUTTONDOWN (uint flags, cpoint point)

{

M_StartPoint = POINT;

Return 0;

}

LResult ONLBUTTONUP (Uint Flags, CPoint Point)

{

m_startpoint.x = m_startpoint.y = -1;

Return 0;

}

LResult OnMousemove (uint flags, cpoint point)

{

M_ENDPOINT = POINT;

CclientDC DC (this-> m_hwnd);

CPEN NP;

Np.createpen (ps_solid, 2, rgb (255, 0, 0));

HPEN OP = Dc.selectpen (np.m_hpen);

IF (m_startpoint.x! = -1)

{

Dc.moveto (m_startpoint.x, m_startpoint.y, null);

Dc.LineTo (M_ENDPOINT.X, M_ENDPOINT.Y);

m_startpoint.x = m_endpoint.x;

m_startpoint.y = m_endpoint.y;}

Dc.selectpen (OP);

Return 0;

}

In order to change the color and brush, like the above article (Part 1 of the ATL window), we join a simple menu / tool strip support. Add a new menu, "Color" has three menu items "Red", "Green", "Blue". At the same time, the corresponding tool strip button is also added and confident that their IDs are consistent. Writing a command processing function for the value of the value variable of the ColorRef type in the view. Add these command processing functions message mapping entries to begen_msg_map_ex / end_msg_map.

Command_id_handler_ex (id_color_red, oncolorred)

COMMAND_ID_HANDLER_EX (id_color_green, oncolorgreen)

Command_id_handler_ex (id_color_blue, oncolorblue)

LResult Oncolorred (uint, int, hwnd)

{

m_color = RGB (255, 0, 0);

Return 0;

}

LResult Oncolorgreen (uint, int, hwnd)

{

m_color = rgb (0,255,0);

Return 0;

}

Lresult OncolorBlue (uint, int, hwnd)

{

m_color = rgb (0,0,255);

Return 0;

}

If you run the program at this time, you will find that these new items on the menu and toolbar can be used, but there is no result, the message generated by the original menu is not passed to the view class. why? Oh, the command message originates from the framework class, so the message generated by the menu (toolbar) will only be passed to the framework class. ATL / WTL uses a message routing policy different from the MFC to pass the message from a class to another class, you must add the following macro to the message map of the frame class (see Part 1 of the ATL window).

CHAIN_MSG_MAP_MEMBER (M_VIEW)

Some things are different from MFC, although you have seen these extensions from ATL. What is important and beautiful? Serious developers don't have to be too small to support. On the other hand, the beautiful menu (Cool Menu) is very beautiful, but it really deserves from MFC to change? Yes, WTL can be said to be ATL , ATL is an important COM-based development tool. Is this a full reason to use it? After all, WTL is not officially supported by Microsoft.

What support do you need for WTL? Microsoft uses WTL's early versions for a few years, because the software developed with it is very efficient, and Microsoft ATL / WTL team and the vast majority of ATL / WTL communities are committed to continuing to support WTL.

ATL / WTL will not replace MFC soon, but many projects require faster production efficiency, faster running efficiency, less consumption, plus easy support for COM, ATL / WTL instead of MFC. I have been using MFC for 10 years, but how attractive ATL / WTL combination is. If we retain our investment in old technology is a standard, we may still use COBOL. What we did has been accepted by everyone, what do you think of?

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

New Post(0)