-Wince programming (3rd edition)-1.6 hello3

Source: Internet
Author: User
Tags drawtext

Hello3
There are enough reviews. It's time to build a complete windows application-hello3. Although the entire program file of hello3 and all the examples in the book can be found in the attached book CD, I still suggest that for the initial examples, instead of simply loading project files from CD, you should manually enter the entire example. Through this slightly boring work, you will experience the differences in the development process and program nuances between the standard Win32 program and the Windows CE program. Listing 1-3 shows all the source code of hello3.

Listing 1-3: Program hello3
Hello3.cpp
// ================================================ ======================================
// Hello3-a simple application for Windows CE
//
// Written for the book programming Windows CE
// Copyright (c) 2003 Douglas boling
// ================================================ ======================================
# Include <windows. h> // For all that Windows stuff

Lresult callback mainwndproc (hwnd, uint, wparam, lparam );

// ================================================ ======================================
// Program entry point
//
Int winapi winmain (hinstance, hinstance hprevinstance,
Lpwstr lpcmdline, int ncmdshow ){
Wndclass WC;
Hwnd;
MSG;

// Register Application main window class.
WC. Style = 0; // window style
WC. lpfnwndproc = mainwndproc; // callback function
WC. cbclsextra = 0; // extra class data
WC. cbwndextra = 0; // extra window data
WC. hinstance = hinstance; // owner handle
WC. hicon = NULL, // application icon
WC. hcursor = loadcursor (null, idc_arrow); // default cursor
WC. hbrbackground = (hbrush) getstockobject (white_brush );
WC. lpszmenuname = NULL; // menu name
WC. lpszclassname = text ("myclass"); // window class name

If (registerclass (& WC) = 0) Return-1;

// Create main window.
Hwnd = createmediawex (ws_ex_nodrag, // ex style flags
Text ("myclass"), // window class
Text ("hello"), // window title
// Style flags
Ws_visible | ws_caption | ws_sysmenu,
Cw_usedefault, // X position
Cw_usedefault, // y position
Cw_usedefault, // initial width
Cw_usedefault, // initial height
Null, // parent
Null, // menu, must be null
Hinstance, // application instance
Null); // pointer to create
// Parameters
If (! Iswindow (hwnd) Return-2; // fail code if not created.

// Standard show and update CILS
Showwindow (hwnd, ncmdshow );
Updatewindow (hwnd );

// Application message loop
While (getmessage (& MSG, null, 0, 0 )){
Translatemessage (& MSG );
Dispatchmessage (& MSG );
}
// Instance cleanup
Return msg. wparam;
}
// ================================================ ======================================
// Mainwndproc-callback function for application window
//
Lresult callback mainwndproc (hwnd, uint wmsg, wparam,
Lparam ){
Paintstruct pS;
Rect;
HDC;

Switch (wmsg ){
Case wm_paint:
// Get the size of the client rectangle
Getclientrect (hwnd, & rect );

HDC = beginpaint (hwnd, & PS );
Drawtext (HDC, text ("Hello Windows CE! "),-1, & rect,
Dt_center | dt_vcenter | dt_singleline );

Endpaint (hwnd, & PS );
Return 0;

Case wm_destroy:
Postquitmessage (0 );
Break;
}
Return defwindowproc (hwnd, wmsg, wparam, lparam );
}

Hello3 shows all aspects of Windows programs, from the registration window class to the creation window and window process. Like the first two examples, hello3 has the same entry point-winmain. However, because hello3 creates its own window, it must register a window class for the main window, create a window, and provide a message loop to process messages for the window.

Registration window class
In winmain, hello3 registers window classes for the main window. Registering a window class simply fills in some large structures that describe the window class and calls the registerclass function. The registerclass and wndclass structures are defined as follows:

Atom registerclass (const wndclass * lpwndclass );

Typedef struct _ wndclass {
Uint style;
Wndproc lpfnwndproc;
Int cbclsextra;
Int cbwndextra;
Handle hinstance;
Hicon;
Hcursor;
Hbrush hbrbackground;
Lpctstr lpszmenuname;
Lpctstr lpszclassname;
} Wndclass;

The value assigned to each field of the wndclass structure is the behavior of all instances in the hello3 main window. The style field sets the class style for the window. In Windows CE, the class style is limited:
Cs_globalclass indicates that the class is global. This flag is provided only for compatibility, because all window classes in Windows CE are process-level global classes.
Cs_hredraw tells the system to force the redraw window if the window size has changed horizontally.
Cs_vredraw tells the system to force the redraw window if the vertical size of the window is changed.
Cs_noclose: if the [close] button appears on the title bar, it becomes invalid.
Cs_parentdc allows the window to use the device environment variable of the parent window
Cs_dblclks allows [double-click] notification (double-click twice in Windows CE) to be passed to the parent window

Lpfnwndproc allocates the address of the window process. Because the domain is defined as a pointer to the window process, the declaration of the process must be defined in the source code before the domain is set. Otherwise, the row is warned during the compiler type check.

Cbclsexra allows programmers to add extra space for the class structure to store class-specific data that only applications know. Cbwndextra is easier to use. This domain adds space for the Windows internal structure, which maintains the status of each instance in the window. A large amount of data is not stored in the window structure itself. The application should store a pointer to the specific structure of the application, which contains the data of each instance in the window. In Windows CE, The cbclsextra and cbwndextra fields must be multiples of 4 bytes.

The hinstance domain is set as the instance handle of the program, which specifies the process that owns the window. Hicon domain is set as the handle of the default window icon, but this field is not supported in Windows CE, so this field should be set to null. (In Windows CE, the icon of the class is set after the first window of the class is created. For hello3, no icons are provided, and unlike other Windows versions, there are no predefined icons in Windows CE for loading .)

Unless the application is designed for a Windows CE system with a mouse, the hcursor field should be set to null. Fortunately, if the system does not support the cursor, calling the loadcursor (idc_arrow) function will return null.

The hbrbackground field specifies how Windows CE draws a background. Windows uses the specified brush (a small pre-defined pixel array) in this field to draw a window background. Windows CE provides many predefined brushes that you can use to load. If the hbrbackground field is null, the window must process the wm_erasebkgnd message and redraw the window background.

The lpszmenuname field must be set to null because Windows CE does not directly support windows with menus. In Windows CE, menus are provided by the command toolbar, command band, or menu bar Control created in the main window.

Lpszclassname is a programmer-defined string used to specify the class name for Windows. Hello3 uses "myclass" as the class name.

After the entire wndclass class is filled, the registerclass function is called and the pointer pointing to the wndclass structure is used as the unique parameter. If the function succeeds, the value of a flag window class is returned. If the function fails, 0 is returned.

Create window
Once the window class is successfully registered, you can create the main window. All windows programmers will learn how to call the createwindow and createmediawex functions in their windows programming career. The createmediawex prototype is as follows:
Hwnd createmediawex (DWORD dwexstyle, lpctstr lpclassname,
Lptstr lpwindowname, DWORD dwstyle,
Int X, int y, int nwidth, int nheight,
Hwnd hwndparent, hmenu,
Hinstance, lpvoid lpparam );

Although the number of parameters is daunting, once you understand these parameters, you will find them logical. The third parameter is the identifier of the extended style. Windows CE supports the following extended styles:
Ws_ex_topmost window top
Ws_ex_javaswedge window has a raised border
Ws_ex_clientedge window has a concave border
Ws_ex_staticedge static window with 3D appearance
Ws_ex_overlappedwindow is a combination of ws_ex_javaswedge and ws_ex_clientedge.
Ws_ex_captionokbutton has an OK button on the title bar.
Ws_ex_contexthelp HELP button on the title bar
When ws_ex_noactivate is clicked, the window does not become an activity window.
Ws_ex_noanimation when the window is created, the top-level window does not display a rectangle, and there are no buttons on the task bar.
Ws_ex_nodrag prevents window Movement

The dwexstyle parameter is the only difference between createmediawex and createwindow. In fact, if you read the createwindow statement in the Windows CE header file, you will find that createwindow simply sets dwexstyle to 0 and calls createdomainwex.

The first parameter is the name of the window class used to instantiate the window. In hello3, the class name is myclass, that is, the name of the Class Registered with registerclass.

3rd parameters are used as window text. In other versions of Windows, it is used as the text in the title bar of the standard window. In H/PC, there are few title bars in the main window. This text is only used on the task bar button. In the Pocket PC, this text appears in the navigation bar on the top of the display screen. The text macro is used to ensure that the string can be converted to Unicode in Windows CE.

The style icon specifies the initial style of the window. Style labels are common styles used for all related windows in the system, and also for the style of specific classes, such as the style of the button class or the list box class. In this case, we need to specify the ws_visible flag to indicate that the window is visible during creation. Experienced Win32 programmers should check the createwindow documentation because many Windows style labels are not supported by Windows CE.

The following four Parameters specify the initial position and size of the window. Because most applications in wimdows CE are full screen Windows, the cw_usedefault flag is used as the default value for each size and location domain. In the current version of Windows CE, the default window is created, and its size overwrites the entire screen. Be sure not to consider any special sizes for Windows CE devices, because different implementations have different screen sizes.

The next field is the handle of the parent window. Because it is a top-level window, the parent window field is set to null. The menu field is also set to null because Windows CE does not support top-level window menus.

The hinstance parameter is the instance handle passed to the program. When a window is created, the instance handle is stored at the beginning of the program. The final parameter is a pointer that is used to pass data to the window when calling createwindow during the wm_create message. In this example, no additional data needs to be transferred, so this parameter is set to null.

If the window is successfully created, createwindow returns the handle of the newly created window. If an error occurs during function call, 0 is returned. After passing the -- if statement of the error check statement, the window handle is used in the following two statements (showwindow and updatewindow ). The showwindow function modifies the window status so that it is consistent with the status in the ncmdshow parameter passed to winmain. The updatewindow function forces windows to send the wm_paint message to the created window.

Message Loop
After the main window is created, winmain enters the message loop, which is the heart of every Windows application. The message loop of hello3 is defined as follows:
While (getmessage (& MSG, null, 0, 0 )){
Translatemessage (& MSG );
Dispatchmessage (& MSG );
}

This cycle is simple: Call the getmessage function to obtain the next message from the application message queue. If no message is available, the call enters the waiting period, blocking the application thread until the message is available. When a message is available, this function returns the message data contained in the MSG structure. The MSG structure itself contains several domains, some are used to identify messages, some provide specific message parameters, and some are used to identify the last screen position touched by a pen before a message is sent. This location information is different from the standard Win32 message location data. In XP, the returned location is the current mouse position rather than the last click (or tapped, in Windows CE.

Translatemessage converts appropriate keyboard information into character information. (Other information filters, such as isdialogmsg, will be discussed later .) Dispatchmessage then tells windows to send the message to the appropriate window of the application.

The process of obtaining, transforming, and distributing messages continues until getmessage receives the wm_quit message, which causes getmessage to return 0, which is different from other messages. As can be seen from the while clause, if getmessage returns 0, the loop ends.

After a message loop is terminated, the program does nothing except cleaning and exiting. In hello3, the program simply returns from winmain. The return value of winmain is the return code of the program. Traditionally, the wparam parameter value of the last message wm_quit contains a return value. In response to the application's call to postquitmessage, The wm_quit message is sent out, and the wparam parameter value of wm_quit is filled.

Window Process
Messages sent or submitted (by sending or post) to the main hello3 window are sent to mainwndproc. Like all window procedures, the mainwndproc prototype is as follows:
Lresult callback mainwndproc (hwnd, uint wmsg, wparam,
Lparam );

The Return Value Type lresult is actually the long type (in windows, long is a 32-bit value). It is written in this form to provide an intermediate level between the source code and the machine. Although you can easily determine the true types of variables used in Windows programming from the inclusion files, it may cause problems when you try to convert code across platforms. Although understanding the size of variable types is useful for computing memory usage, there is no good reason to use them (in fact there are many reasons not to use them) the type definition provided in the windows. h file.

The callback type indicates that this function is the external entry point of EXE, which is required for Windows to directly call this process. In the desktop system, callback points out that the parameters are pushed to the program stack in the Pascal-like style from right to left, which is the opposite of the Standard C language. The use of the PASCAL Language stack framework for external entry points can be traced back to the very early windows development period. The use of a fixed size Pascal stack means that the stack is cleared by the called process, rather than left to the caller for cleanup. This method can effectively reduce the size of windows and its ancillary programs, so Microsoft developers in the Early Days think this is a good way. In Windows CE, the application uses the C stack framework for all functions, regardless of whether it is an external call.

The first parameter passed to the window process is the window handle. This handle is useful when you need to define a specific window instance. The wmsg parameter indicates the message sent to the window. This is not the MSG structure used in the winmain message loop, but an unsigned integer that contains the message value. The remaining two parameters, wparam and lparam, are used to pass the data related to the specific message to the window process. Their names come from the Win16 era. At that time, wparam was a 16-bit value while lparam was a 32-bit value. Like other Win32 operating systems, both of them are 32-bit in Windows CE.

Like the traditional Window Process, the window process of hello3 parses the wmsg Message ID through a switch statement. The switch statement contains two case statements, one for parsing the wm_paint message and the other for parsing the wm_destroy message. This window process is a window process that can be simplified to the nearest step.

Wm_paint
Draw a window and process the wm_paint message, which is one of the most important functions in any windows program. The appearance of the window is completed when the program processes the wm_paint message. Windows does not provide any help for processing this message except to draw the Default background with the brush you specify when registering the window class. The following figure shows how to process the wm_paint message in hello3:
Case wm_paint:
// Get the size of the client rectangle
Getclientrect (hwnd, & rect );

HDC = beginpaint (hwnd, & PS );
Drawtext (HDC, text ("Hello Windows CE! "),-1, & rect,
Dt_center | dt_vcenter | dt_singleline );

Endpaint (hwnd, & PS );
Return 0;
Before drawing a window, the program must determine the window size. In Windows, a standard window is divided into two areas: Non-customer and customer. The window title bar and the changeable border usually occupy the non-customer area of the window, which is drawn by windows. The customer area is located in the internal area of the window and is drawn by the application. The application uses the getclientrect function to determine the size and location of the customer zone. This function returns a rect structure that contains the coordinates in the upper left corner and lower right corner to describe the rectangle boundary of the customer area. The benefit of dividing into customer areas and non-customer areas is that the application does not have to draw those window standard elements, such as the title bar.

Other versions of Windows provide a series of wm_ncxxx messages that allow your applications to draw non-customer zones. In Windows CE, there are few title bars in a window. Because there are few non-customer zones, Windows CE does not send non-client messages to the window process.

All the painting tasks executed in the wm_paint message must be surrounded by the beginpaint and endpaint functions. The beginpaint function returns the device environment handle HDC. The device environment is a logical representation of physical display devices (such as video monitors or printers. Windows programs never directly modify the display hardware. On the contrary, Windows isolates programs from specific hardware in a device environment.

Beginpaint fills in a paintstruct structure with the following structure:
Typedef struct tagpaintstruct {
HDC;
Bool ferase;
Rect rcpaint;
Bool frestore;
Bool fincupdate;
Byte rgbreserved [32];
} Paintstruct;

HDC is the handle returned by the beginpaint function. Ferase indicates whether the window background needs to be re-painted during the window process. Rcpaint is a rect structure that defines the customer area to be repainted. Hello3 ignores this field and assumes that in each wm_paint message, the entire customer zone window needs to be re-painted. This field is useful when performance is a problem to consider, because sometimes you only need to redraw some windows. Windows will block this even if the program attempts to redraw areas outside the rcpaint rectangle. Other fields of this structure, such as frestore, fincupdate, and rgbreserved, are used in windows and can be ignored by applications.

The only drawing operation in hello3 is to draw a line of text in the window. Hello3 calls the drawtext function to complete the painting. I will describe the details of drawtext in Chapter 2nd. If you take a look at this function, it is easy to understand that this call draws a line of string "Hello Windows CE" in the window ". After drawtext is returned, call endpaint to notify the windows program that the window update has been completed.

The endpaint call also makes other areas of the undrawn window valid. Windows maintains an Invalid Window area (that is, the area to be re-painted) List and a valid area (that is, the updated area) list. No matter what you have painted in the window, calling beginpaint and endpaint in pairs will notify windows that you will handle the invalid area of the window. In fact, you must call beginpaint and endpaint, or use other methods to make the window invalid region valid. Otherwise, Windows will continuously send the wm_paint message to the window until the invalid region becomes valid.

Wm_destroy
Another message processed in hello3 is wm_destroy. The message is sent when the window is about to be destroyed. Because the window is the main application window, the application will terminate when the window is destroyed. The code that processes the wm_destroy message calls the postquitmessage message to trigger this action. The postquitmessage function puts the wm_quit message into the message queue. The parameter of this function is the value of the return code, which is placed in the wparam parameter of the wm_quit message and returned to the application.

As described above, the message loop will exit when wm_quit is displayed. Winmain then calls terminstance. In hello3, this function does nothing but returns. Winmain then returns and terminates the program.

Hello3 is a typical Windows program. This programming style sometimes becomes Petzold-style Windows programming, in order to respect Charles Petzold, the Windows Programming master. Charles's programming Microsoft Windows is currently version 5th, and is still the best book to learn windows programming.

I prefer a slightly different design for my windows program. In a sense, this is a way to componentialize windows program functions, which makes it easier to copy part of the program to another program. In the final example in this chapter, I will introduce this programming style and introduce some additional features required by Windows CE applications.

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.