Wtl learning notes -- (4) Basic wtl Interface Class

Source: Internet
Author: User

I. Overall wtl impression

Wtl classes can be roughly divided into several types:

1. Implementation of the main frame window-Cframeworkwimpl, cmdiframeworkwimpl

2. Control encapsulation-cbutton, clistviewctrl GDI

3. Object encapsulation-CDC, cmenu

4. Some special interface features-csplitterwindow, cupdateui, cdialogresize, and ccustomdraw

5. Practical Tool class and macro-cstring, crect, begin_msg_map_ex

Ii. Start to write the wtl Program

It does not matter if you do not use the wtl application to generate a wizard (I will introduce the usage of this wizard later). The Code STRUCTURE OF THE wtl program is similar to that of the Atl program, the sample code used in this chapter is different from the example in the first chapter. It is mainly used to show the features of wtl and has no practical value.

In this section, we will add code based on the code generated by wtl to generate a new program. The client area of the main window of the program shows the current time. The stdafx. H code is as follows:

# Define strict <br/> # define win32_lean_and_mean <br/> # DEFINE _ wtl_use_cstring </P> <p> # include <atlbase. h> // basic ATL class <br/> # include <atlapp. h> // basic wtl class <br/> extern cappmodule _ module; // The ccommodule version derived from wtl <br/> # include <atlwin. h> // ATL window class <br/> # include <atlframe. h> // wtl main framework window class <br/> # include <atlmisc. h> // wtl utility class, such as cstring <br/> # include <atlcrack. h> // message macro enhanced by wtl

Atlapp. H is the first header file in your project. This file defines message processing classes and cappmodule. cappmodule is a class derived from ccommodule. If you want to use the cstring class, you need to manually define the _ wtl_use_cstring label, because the cstring class is in atlmisc. h, and many are included in atlmisc. all header files before H will use cstring. After _ wtl_use_cstring is defined, atlapp. h will declare the cstring class forward, and other header files will know the existence of the cstring class, so as to prevent the compiler from making a fuss.

Next, define the framework window. Our SDI window is derived from cframeworkwimpl. when defining the window class, use declare_frame_wnd_class to replace the previously used declare_wnd_class. In mywindow. H, the start part of the window definition is as follows:

Class cmywindow: Public cframeworkwimpl <cmywindow> <br/>{< br/> Public: <br/> declare_frame_wnd_class (_ T ("first wtl window"), idr_mainframe ); begin_msg_map (cmywindow) chain_msg_map (cframeworkwimpl <cmywindow>) end_msg_map ()};

Declare_frame_wnd_class has two parameters: window class name (class name can be null, ATL will generate a class name for you) and resource ID. When creating a window, wtl uses this ID to load the icon, menu and acceleration key table. We also need to Chain messages into the window like messages in cframeworkwimpl (for example, wm_size and wm_destroy messages.

Now let's take a look at the winmain () function. It is almost the same as the winmain () function in the example code in the first part, but the code for creating a window is slightly different.

// Main. CPP: <br/> # include "stdafx. H "<br/> # include" mywindow. H "</P> <p> cappmodule _ module; </P> <p> int apientry winmain (hinstance, hinstance hprevinstance, <br/> lpstr lpcmdline, int ncmdshow) <br/>{< br/> _ module. init (null, hinstance); </P> <p> cmywindow wndmain; <br/> MSG; </P> <p> // create the main window <br/> If (null = wndmain. createex () <br/> return 1; // window creation failed </P> <p> // show the window <br/> wndmain. showwindow (ncmdshow); <br/> wndmain. updatewindow (); </P> <p> // standard Win32 message loop <br/> while (getmessage (& MSG, null, 0, 0)> 0) <br/>{< br/> translatemessage (& MSG); <br/> dispatchmessage (& MSG); <br/>}</P> <p> _ module. term (); <br/> return MSG. wparam; <br/>}

The parameters of the createex () function in cframeworkwimpl use common default values, so we do not need to specify any parameters. As described earlier, cframeworkwimpl processes resource loading. You only need to use idr_mainframe as the ID to define your resource, menu and acceleration key table), you can also directly use the example code in this chapter.

If you run the program now, you will see the main framework window, in fact it does not do anything. We need to manually add some message processing, so now is the best time to introduce the message ing macro of wtl.

Iii. Enhancement of message ing by wtl

Restoring wparam and lparam data transmitted by Win32 APIs through messages is troublesome and error-prone. Unfortunately, ATL does not provide us with more help, we still need to restore the data from the message, except for the wm_command and wm_notify messages. However, the emergence of wtl has saved all of this!

The extended message ing macro of wtl is defined in atlcrack. h. (This name comes from the "message decryptor", which is similar to Windows X. h macros use the same term.) First, change begin_msg_map to begin_msg_map_ex, and generate the code for "decrypting" The message with _ ex.

Class cmywindow: Public cframeworkwimpl <cmywindow> <br/>{< br/> Public: <br/> begin_msg_map_ex (cmywindow) <br/> chain_msg_map (cframeworkwimpl <cmywindow>) <br/> end_msg_map () <br/> };

For our clock program, we need to process the wm_create message to set the timer. The message processing of wtl uses MSG _ as the prefix, followed by the message name, for example, msg_wm_create. These macros only represent the name of the message Response Processing. Now we can add a response to the wm_create message:

Class cmywindow: Public cframeworkwimpl <cmywindow> <br/>{< br/> Public: <br/> begin_msg_map_ex (cmywindow) <br/> msg_wm_create (oncreate) <br/> chain_msg_map (cframeworkwimpl <cmywindow>) <br/> end_msg_map () </P> <p> // oncreate (...)? <Br/> };

The message Response Processing of wtl looks a bit like MFC. Each processing function has a different prototype based on different message passing parameters. Because we do not have a wizard to automatically add a message response, we need to find the correct message processing function by ourselves. Fortunately, VC can help us, move the mouse cursor to the text of the "msg_wm_create" macro and press the F12 key to come to the definition code of this macro. If this function is used for the first time, VC will require that all files be compiled to create a browse Info database. After this database is created, VC will open atlcrack. h. Locate the code to the definition position of msg_wm_create:

# Define msg_wm_create (func)/<br/> If (umsg = wm_create)/<br/>{/ <br/> setmsghandled (true ); /<br/> lresult = (lresult) func (lpcreatestruct) lparam);/<br/> If (ismsghandled ()/<br/> return true; /<br/>}

The line marked as red is very important, that is, calling the actual message response function here, which tells us that the message response function hasLPCREATESTRUCTType parameter. The return value type is lresult. Note that there is no bhandled parameter used by the ATL macro,SetMsgHandled()The function replaces this parameter. I will give a brief introduction to this parameter.

Now add the oncreate () response function for our window class:

Class cmywindow: Public cframeworkwimpl <cmywindow> <br/>{< br/> Public: <br/> begin_msg_map_ex (cmywindow) <br/> msg_wm_create (oncreate) <br/> chain_msg_map (cframeworkwimpl <cmywindow>) <br/> end_msg_map () </P> <p> lresult oncreate (lpcreatestruct lpcs) <br/>{< br/> settimer (1, 1000); <br/> setmsghandled (false); <br/> return 0; <br/>}< br/> };

Cframeworkwimpl is derived directly from the cwindow class, so it inherits all cwindow class methods, such as settimer (). This makes the call to the window api a bit like the code of the MFC, but the MFC uses the cwnd class to wrap these Apis.

We use the settimer () function to create a timer that is triggered every second (1000 milliseconds. Because we need cframeworkwimpl to process the wm_create message, we call setmsghandled (false) to link the message to the base class through the chain_msg_map macro. This call replaces the bhandled parameter used by the ATL macro. (Even if the cframeworkwimpl class does not need to process the wm_create message, it is a good habit to call setmsghandled (false) to let the message flow into the base class, in this way, we do not always need to remember which message requires the base class to process those messages without the base class processing, which is similar to the code generated by the Class Wizard of VC, the start or end of the message processing function of most Derived classes call the message processing function of the base class)

In order to be able to stop the timer, we also need to respond to the wm_destroy message. The process of adding a message response is the same as that before. The definition of the msg_wm_destroy macro is as follows:

# Define msg_wm_destroy (func)/<br/> If (umsg = wm_destroy)/<br/>{/ <br/> setmsghandled (true ); /<br/> func ();/<br/> lresult = 0;/<br/> If (ismsghandled ()/<br/> return true; /<br/>}

The ondestroy () function has no parameters and no return value. cframeworkwimpl also needs to process the wm_destroy message, so it also needs to call setmsghandled (false ):

Class cmywindow: Public cframeworkwimpl <cmywindow> <br/>{< br/> Public: <br/> begin_msg_map_ex (cmywindow) <br/> msg_wm_create (oncreate) <br/> msg_wm_destroy (ondestroy) <br/> chain_msg_map (cframeworkwimpl <cmywindow>) <br/> end_msg_map () </P> <p> void ondestroy () <br/>{< br/> killtimer (1); <br/> setmsghandled (false); <br/>}< br/> };

Next is the processing function that responds to the wm_timer message. It is called every second. You should know how to use the F12 key, so I will directly give the Response Function Code:

Class cmywindow: Public cframeworkwimpl <cmywindow> <br/>{< br/> Public: <br/> begin_msg_map_ex (cmywindow) <br/> msg_wm_create (oncreate) <br/> msg_wm_destroy (ondestroy) <br/> msg_wm_timer (ontimer) <br/> chain_msg_map (cframeworkwimpl <cmywindow>) <br/> end_msg_map () </P> <p> void ontimer (uint utimerid, timerproc ptimerproc) <br/>{< br/> if (1! = Utimerid) <br/> setmsghandled (false); <br/> else <br/> redrawwindow (); <br/>}< br/> };

This response function only redraws the client area of the window when each timer is triggered. Finally, we need to respond to the wm_erasebkgnd message and display the current time in the upper left corner of the window customer area.

Class cmywindow: Public cframeworkwimpl <cmywindow> <br/>{< br/> Public: <br/> begin_msg_map_ex (cmywindow) <br/> msg_wm_create (oncreate) <br/> msg_wm_destroy (ondestroy) <br/> msg_wm_timer (ontimer) <br/> Merge (onerasebkgnd) <br/> chain_msg_map (cframeworkwimpl <cmywindow>) <br/> end_msg_map () </P> <p> lresult onerasebkgnd (HDC) <br/>{< br/> cdchandle DC (HDC ); <br/> crect RC; <br/> systemtime st; <br/> cstring stime; </P> <p> // get our window's client area. <br/> getclientrect (RC); </P> <p> // build the string to show in the window. <br/> getlocaltime (& St); <br/> stime. format (_ T ("the time is % d: % 02d: % 02d"), St. whour, St. wminute, St. wsecond); </P> <p> // set up the DC and draw the text. <br/> DC. savedc (); <br/> DC. setbkcolor (RGB (255,153, 0); <br/> DC. settextcolor (RGB (0, 0); <br/> DC. exttextout (0, 0, eto_opaque, RC, stime, stime. getlength (), null); </P> <p> // restore the DC. <br/> DC. restoredc (-1); <br/> return 1; // We erased the background (exttextout did it) <br/>}< br/> };

This message processing function not only uses the crect and cstring classes, but also uses a GDI packaging class cdchandle. For the cstring class, I want to say that it is equivalent to the cstring class of MFC. I will introduce these packaging classes in later articles, now you only need to know That cdchandle is a simple encapsulation of HDC. The usage method is similar to the CDC class of MFC, only when the cdchandle instance exceeds the scope, it will not destroy the device context it operates on.

Iv. Program Running Effect

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.