Win32 learning notes
Author: Jiang Xuezhe (netsail0@163.net)
Textbook: Windows Program Design (Fifth Edition) Peking University Press [United States] Charles Petzold Co., Ltd. ¥: 160
Environment: Windows2000 PRO Internet Explorer 6.0 DirectX8.1 Visual C 6.0
Tint Jiang Computer Program Group (http://chulsoft.xiloo.com) Copyright, reprint, please explain the source ----------------------- ------------------------------------------- [Chapter 4 Output Text - 1】
Our website has a forum. 60 pieces of one year. Very cheap? Very cool! The problem is that is very popular. But that's okay. everything will become better. I have been hit very much today. Maybe our website has water. The actual number of visits may not be one tenth. It turned out to be more than 23,000 me ~~~
Learning notes are the way I have learned. I explained myself. If I can explain it very well, I will explain this chapter. So I have written a lot of long and long. It's still long thanks to the book.
Chapter 4 Some mistakes let me find it, are I am very cattle? as follows:
★ Note 1 ★ Figure 4-3 on page 76 is wrong. However, on page 121, there is another picture, that picture is correct. ★ Note ★ Page 92: Ninth line begins, books in the book, SB_thumbPosition, SB_THUMBPSITION, SB_THUMBTRACK is a message, saying what SB_THUMBTRACK message, SB_thumbPosition message, etc. Conceptual problem.
The fourth chapter is much more important, it is also important. So the study of the fourth chapter has a big difficulty in me. I need a long time to complete. The article may be very long, so I am divided into two paragraphs. Like the previous three chapters, in the fourth chapter, you will encounter a lot of terms that don't understand. This is something that there is no way. Look at it a few times.
In the previous chapter we saw a simple Windows program hellowin. It shows a line of text in the center of the client zone. The client area is part of the entire application in the title bar, window border, and menu bar, toolbar, status bar, and scroll bar. That is to say that the client area is part of the window to write and transfer information from the program. Hellowin's client area is the white part.
The program in the MS-DOS environment is single-threaded. That is to say, only one program can be run. The situation of the Windows era is complex. Our program must share a screen with other programs. Moreover, the user can control the program's display mode, maximize, minimize, and so on. And most of the program windows can change the window size at will. This is very convenient for end users, but for programmers is a headache. These seemingly simple features are complex.
When the user changed the window size, when a window is blocked by another window, when the content in the window needs to be updated, all this requires our programmer to solve. We don't know how big is the user's display, and it is 14 inches or 19 inches. I don't know which resolution of the user's display is 800 * 600 or 1024 * 768. Our procedures should be flexibly handled.
Of course, if you think these are too trouble, I still have a way. That is ......... Your program can be designed to a fixed size window. Just like a calculator program, users cannot change the size of the program window. This will solve this. However, as a strong young man in the 21st century, how can we use such low energy?
This chapter tells the way the program shows information in the customer area. However, it is more complicated than the display method described in the previous chapter.
Windows provides a powerful graphics device interface (GDI) function for display graphics. But now Chapter 4, so only introduce the display of simple text lines in this chapter. The problem involved in this chapter is applicable to all Windows programming. This chapter discusses the design foundation of the program-independent programming. The program in the Windows environment uses the functionality provided by the system to obtain information about the program running environment.
WINDOWS can open a lot of windows at the same time, sometimes a part of a window is overwritten by another window. In fact, there is also a WPS similar to the Niki R, R Xin OS as an example. When the user selects a drop-down menu, the menu may overwrite a portion of the client area. At this time, the program saves the part that is overwritten by the menu. After the drop-down menu disappears, move the saved part. Windows processing method is not the case. Windows does not save the covered part. When Windows will require the program to refresh the covered part, it is re-draw. Because Windows retains all the information needed to regenerate the window.
The WPS under DOS is also a graphical interface, but the interface of the WPS is unable to recover. If the program does not save the covered part, then wait until the drop-down menu disappears, the place that is originally covered will not be left. It is equivalent to wipe it out.
And it is different under Windows. Windows has retained all information about the window in advance. So even if the window on the screen is covered by other windows, it can still be recovered.
Windows is a messaging system. It notifies the program through the message. When the window process receives a WM_PAINT message from Windows, the window is re-drawn.
Most Windows programs are called to call the function updateWindow () during initialization before entering the message loop. Windows uses this opportunity to send the first WM_PAINT message to the window process. This message notification window process must be drawn. Since then the window process should be ready to process other WM_PAINT messages at any time. If necessary, even reopen the entire customer area.
The window process will receive a WM_PAINT message when one of the following events occur.
◆ When the user moves the window or the display window, the previously hidden section is re-visible ◆ User change window size - If the window style has a CS_HREDRAW CS_VREDRAW bit setting ◆ Use scrollwindow () or scrolldc () Scroll part of the customer area ◆ Using InvalIdateRect ) Or invalidatergn () explicitly generates a WM_PAINT message.
In the case of the Windows, Windows may send a WM_PAINT message.
◆ Windows erase the dialog box or message box that covers some windows. ◆ The menu pulls out and is released ◆ Display Tool Tips
In some cases, Windows always saves the display area it override and then restores it. These situations are:
◆ Mouse spectrote crossing the customer area ◆ Icon dragging the customer area
The window process is ready to update the entire customer area after receiving the WM_PAINT message. Sometimes the window process only needs to update a smaller area. The most common is the rectangular area in the customer area. This is the case when the dialog covers some of the customer's area. The erase dialog is required to be redrawn just a rectangular area that is previously covered by the dialog.
This area is called "invalid area" or "update area". Windows will send a WM_PAINT message after the invalid area in the client area. The window will only receive a WM_PAINT message when a part of a part of the client area is invalid.
Windows Saves a "Draw Information Structure" for each window, which contains the minimum rectangle of the invalid area and other information. This rectangle is called "invalid rectangle", sometimes referred to as "invalid area". If another area in the client area is also invalid before the window process is handled, Windows calculates a new invalid area surrounded by two areas and places this change in the drawing information structure. Windows does not place multiple WM_PAINT messages in the message queue.
The function of invalidateect () is to make the part rectangle in the client area becomes invalid. We can use this function to enable some partial client zone to be invalid. The window procedure can get the coordinates of the invalid rectangle when the WM_PAINT message is received. These coordinates can be obtained at any time by calling getUpdateect (). The window procedure becomes effective after the WM_Paint message is called after calling BeginPaint (). The program can also call validateect () to make any rectangular area within the customer zone to be valid. If you call this function, all WM_PAINT messages in the current message queue will be deleted.
To draw on the window customer area, you can use the Windows Graphics Device Interface (GDI) function. Windows provides several GDI functions to output text strings to the window client area. The Hellowin program for the previous chapter is DrawText (). But the most common text output function is current (). The format of this function is as follows:
TextOut (HDC, X, Y, PSText, Ilength);
TextOut () writes a string to the window of the window. The PSText parameter is a pointer to the string, and ILngth is the length of the string. The x and y parameters define the start position of the string in the client area. The HDC parameter is "Device Description Table Handle", which is an important part of GDI. In fact, each GDI function needs to use this handle as the first parameter of the function.
In the third chapter, I simply introduced the handle. The handle is a value and is represented by hexadecimal. The handle represents an object. Device Description The form handle represents a device object. The device description of the GDI function represents a window object. With this handle programmer, you can draw in the customer district.
The device description table is actually the data structure saved inside the GDI. Device Description Table is related to a particular display device. The device descriptor is always related to a particular window on the display for a video display. Do you understand?
Some values in the device description table are graphical properties. These attributes define some special contents for some GDI drawing function. For example, for TextOut (), the properties of the device description table determine how the text's color, the background color, Textout () X coordinates and Y coordinates mapped to the window of the client area, and the fonts used when the text is displayed.
You must first get the device description table base handle when the program needs to draw. Fill the internal device description table structure with the default attribute value after the handle is obtained. We can call various GDI functions to change these default values. You can also use other GDI functions to get the current value of these properties.
It must release the device descriptor handle after the program draws in the customer area. The handle is no longer valid after being released, and it cannot be used again. The program must obtain and release the handle during processing a single message. In addition to calling createdc () created, the program cannot save other device description table sorts between the two messages.
Windows applications typically use two ways to obtain device description table scribes. The first method is employed when the WM_PAINT message is used. This approach involves BeginPaint () and endpaint (). These two functions require the address of the window handle and the PAINTSTRUCT structure to be parameters.
The window process first calls beginpaint () when processing the WM_PAINT message. Beginpaint () is generally erased with the background of the invalid area when preparing to draw. The value returned by this function is the device description table handle. This return value is usually stored in a variable of the HDC structure. The HDC data type is defined as a 32-bit unsigned integer.
The program can then use the GDI function that requires the device to describe the table handle. Call EndPaint () can release the device description table handle.
The form of the general processing of the WM_Paint message is as follows:
Case WM_Paint: HDC = Beginpaint (HWND, & PS); [Use GDI Function] Endpaint (HWND, & PS); RETURN 0;
BeginPaint () and endpaint () must be called when processing the WM_PAINT message. If the window procedure does not process the WM_PAINT message, you must pass the WM_PAINT message to DefWindowProc (). This function calls beginpaint () and endpaint () session. It only makes the invalid area effective. Case WM_Paint: BeginPaint (HWND, & PS); Endpaint (HWND, & PS); Return 0;
However, the following method is wrong.
Case WM_Paint: Return 0;
Windows sends a WM_PAINT message is due to part of the client area becomes invalid. If you do not call BeginPaint () or ValidateRect (), the invalid area will never be effective. Since this, Windows has continued to send WM_PAINT messages.
Windows saves a "Draw Information" PaintStructure for each window.
Typedef struct tagpaintstruct {hdc hdc; bool feed; bool frestore; bool fincupdate; byte rgbreserved [32];
The program calls beginpaint () when Windows populates the various fields of the structure. The user program uses only the first three fields, and the other fields are used inside the Windows. If the window of the window has a background brush, beginpaint () returns the background of the invalid area before erasing before the brush. There is a background brush in the window classes in the Hellowin program:
WNDCLASS.HBRBACKGROUND = (Hbrush) getStockObject (White_brush);
In most cases, Frase is marked as false, which means BeGinPaint () has erased the background of invalid rectangles. Want to define some background erase during the window, you can handle the WM_ERASEBKGN message. BeginPaint () returns the WM_ERASEBKGN message when the feed is marked as True.
If the program invaises the orthopedics in the customer area by calling invalidateect (), the last parameter of the function specifies whether to erase the background. If this parameter is false, Windows will not erase the background and set to true in the FraSe field of the PaintStruct structure after calling Beginpaint ().
The PAINTSTRUCT structure of the RCPAINT domain is the structure of the Rect type. In the third chapter we have seen the Rect structure define a rectangle, its four domains are left, top, right, bottom. Rcpain defines the boundaries of invalid rectangles. These values are in units of pixels and relative to the upper left corner of the client area.
The RCPAINT rectangle in the PaintStruct structure is not only an invalid rectangle, but it is still a "cut" rectangle. It means that Windows limits the drawing operation within the cut rectangle. If the invalid rectangular area is not a rectangle, Windows limits the drawing operation in this area.
Want to draw an invalid rectangular diagram when dealing with the WM_PAINT message, you can use the following call before calling beginpaint ():
InvalidateRect (HWND, NULL, TRUE);
This function makes the entire customer zone into invalid and erases the background. If the last parameter is false, the background is not erased, and the original Dongdong will remain in place.
Usually this is the most convenient method of the entire customer area without considering the RCPAINT structure when the Windows program receives the WM_PAINT message. For example, if a circle is included in the display output of the client area, only a part of the circle falls into an invalid rectangle, which is only the invalid part of the circle is not meaningful. We need to draw a whole circle.
Windows does not draw any part of the RCPaint rectangle when using the device descriptor descriptor descriptor returned from BeginPaint (). In the Hellowin program in Chapter 3, we don't care about the invalid rectangle when handling the WM_PAINT message. If the text display area happens to be in the invalid area, it is displayed by DrawText () to the center of the customer area. The program will check if it is necessary to call DrawText () to output a string to the display. However, this test process takes time. Programmers who care for program performance and speed hopes to use invalid rectangular ranges during processing WM_PAINT messages to avoid unnecessary GDI calls. This is especially important if you need to access disk files such as bitmaps when drawing. We will find it very useful to draw some parts of the client area during processing non-WM_PAINT messages. Or we need to use the device to describe the table scribe handle for other purposes.
Want to get the device description table handle of the window client area, you can call getDC () to get the handle, and call ReleaseDC () after use.
HDC = Getdc (HWND); [Use GDI function] ReleaseDC (HWND, HDC);
Like beginpaint () and endpaint (), the getDC () and releasedc () functions must be used. If getDC () is called when a message is processed, ReleaseDC () must be called before exiting the window process.
Getdc () returned by the device description table handle and the device description of the device descriptor returned by BeginPaint (). GetDC () The device description table has a clipping area containing the entire client area. That is to say, any part of the customer area can be drawn, not just limitations of invalid rectangles. Getdc () does not make any invalid zone to be valid. If you need to make the entire customer area valid, you can call
ValidateERECT (HWND, NULL);
Getdc () and released can typically be called to react to keyboard messages (such as in word handles) or mouse messages (such as in the drawing program). The program can immediately update the client according to the user's keyboard or mouse input, without considering the use of WM_PAINT messages for the invalid area of the window.
A function similar to getDC () is getWindowDC (). GETDC () Returns the device descriptor handle used to write to the window client area, and the device descriptor descriptor descriptor descriptor in the window is written in the title bar of the window.
TextOut () is the most commonly used GDI function for displaying text. We need to know this function. The syntax is:
TextOut (HDC, X, Y, PSText, Ilength);
The first parameter is the device description table. Device Description The attribute of the table handle controls the feature of the text string being displayed. For example, an attribute in the device description table specifies the color of the text, the default color is black. The default device description table also defines a white text background. The program uses this background color to fill the rectangular space around characters when you output text to the display. This rectangular space is referred to as "character box".
This text background color is not the same as the background of defined window classes. The background of the window class is a brush, which is a solid color or non-solid color consisting of a brush, and Windows is used to erase the client area, which is not part of the device description table structure. When defining a window class structure, most Windows applications use WHITE_BRUSH to make the same color as the default text in the device description table. The background of the character and the background of the client area is two yards.
The PSText parameter is a pointer to the string, which is displayed in the customer area. Ilength is the number of characters in a string. No ASCII control characters can be included in the string, such as Enter, Wrap, Table, Q.. Windows displays these control characters as solid blocks. The string is the end tag with "/ 0", but TextOut () does not detect the function of the end flag of the string. So ILEngth parameters need to indicate the length of the string.
X and Y define the start position of the string in the client area, X is horizontal position, Y is a vertical position. The upper left corner of the first character in the string is located at the coordinate point (x, y). In the default device description, the original point (x, y all 0 points) is the upper left corner of the client area. If X and Y are set to 0 in TextOut (), the string is output from the upper left corner of the client area. Coordening to the function is often referred to as "logical coordinates". For details on logical coordinates, we will explain in Chapter 5. Now just remember that Windows has a variety of different "mapping methods" that control the logical coordinates to convert the physical pixel coordinates of the display. The mapping method is defined in the device description table. The default mapping method is mm_text, defined in the Wingdi.h header file. Logical coordinates and physical coordinates in mm_text mapping mode. The value of x is incremented from left to right, and the value of Y is incremented from topward (Fig. 4-2).
The mm_text coordinate system is the same as the coordinate system used in the PaintSTRUCT structure. This brings us a lot of convenience. But other mapping methods are not this.
The device description table also defines a cut zone. Device descriptions from getDC () Description The default clipping area is the entire client area. The device description from BeginPaint () Description The default clipping area of the table is invalid. This can be seen that the cut zone and invalid area are two completely different two concepts. Windows does not display strings anywhere outside the clipping area. If a character is part of the clipping area, Windows will only display the contents of the part of the clipping zone.
The device description table also defines the font used when calling TextOut () display text. The default font is "system font", or the identifier in the header file is system_font. The system font is Windows to display the default font of the text string in the title bar, menu, and dialog box.
The system font is equipped with equivalent font, which means that all characters have the same width, very similar to the type of typewriter. However, the system font starts from Windows 3.0 becomes a wide font, which means that different characters have different sizes. For example, "W" is better than "I". Broaden font is better than equivalent. However, this shift makes many original program code no longer applies. Thereby requests to learn some new technologies that use fonts.
The system font is a "dot matrix font", which means that characters are defined as pixel blocks. The character size of the system font depends on the size of the video display. The system font is designed to at least display 25 rows, 80 column texts on the display.
If you want to use textOut () to display multi-line text, you must determine the character size of the font. You can position the display coordinates of the next line according to the height of the characters. And locate the display position of the next character based on the width of the character.
The character height and the average width of the system font depends on the pixel size of the video display. The minimum display size required for Windows is 640 * 480, but many users prefer the display mode of 800 * 600 or 1024 * 768. For these larger display sizes Windows allows users to choose different sizes of system fonts.
The program can call GetSystemMetrics () to determine information about the size of the user interface component. Call GetTextMetrics () determine the font size. This function returns the preparation of the currently selected font information in the table, so it requires a device to describe the table scribe. Windows pays font information to the TextMetric structure. This structure is defined in Wingdi.h, there are 20 domains, we only use the top 7:
typedef struct tagTEXTMETRIC {LONG tmHeight; LONG tmAscent; LONG tmDescent; LONG tmInternalLeading; LONG tmExternalLeading; LONG tmAveCharWidth; LONG tmMaxCharWidth; [omitted in other domains ...]} TEXTMETRIC, * PTEXTMETRIC;
The units of these field values depends on the selected device description table mapping mode. In the default device description table, the mapping method is mm_text, so the size of the value is in pixels.
To use GetTextMetrics (), you need to define the TEXTMETRIC structure of the TextMetric structure:
TextMetric TM;
You need to determine the text size first get the device description table handle, and then call GetTextMetrics ():
HDC = Getdc (HWND); GetTextMetrics (HDC, & TM); ReleaseDC (HWND, HDC);
★ I will emphasize that Figure 4-3 of page 76 in the book is wrong. However, on page 121, there is another picture, that picture is correct.
The TextMetric structure provides a rich information about the fonts selected in the current device description table. The longitudinal dimension of the font is determined only by five values, and the four values are shown in the figure. This figure is correct
The most important value is TemHeight, which is equal to TMASCENT TMDESCENT. These two values indicate the maximum longitudinal height of the baseline characters. The term "leading" refers to a space inserted between two lines of text. The interior of the TextMetric structure is included in TMASCENT, which is often places where the stress symbols appear. The TMInternalLleading field can be set to 0, in which case the hemp is shortened slightly in this case to accommodate the stress symbol.
The TextMetriC structure also includes a field TMExternalLleading that is not included in the TemHeight value. It is a font designer suggested that the size of the space between the rows and rows. TMEXTERNALLEADING is 0 in the system font, so it is not displayed in the figure. Figure 4-3 is an exact system font using Windows in 640 * 480 resolution.
The TextMetric structure contains two fields that describe the character width, namely TmaveCharWidth (lowercase letters weighted average width) and TMMaxCharWidth (width of the widest character in the font). Two values for equal wide fonts are equal.
The sample programs of this chapter also require another character width, namely uppercase letters average width. This can be calculated by TmaveCharwidth by 150%.
It must be recognized that the size of the system font depends on the resolution of the video display running in Windows. In some cases, depending on the size of the system font selected by the user. Windows offers a graphical interface that is unrelated to the device, but there are still many things that require programmers to solve.
Since the size of the system font does not change during a Windows dialog, we only need to call a GetTextMetrics during the program run. It is best to do this when the WM_CREATE message is processed during the window. The WM_CREATE message is the first message received by the window process. When CREATEWINDOW () is called in WinMain (), Window sends a WM_CREATE message to the window process.
Want to display a few lines of text in the customer area, this requires the first character width and height. We can define two variables within the window to save the average character width (CxChar) and the character height (Cychar):
Static int cxchar, cychar;
The prefix C of the variable name represents "count", here, the number of pixels, combined with X and Y, respectively, and high respectively. These variables are defined as Static because they should be effective when handling other messages during the window. If the variable is defined outside the function, it is not necessary to define it as static.
Below is a WM_CREATE code for getting the character width and height of the system font:
Case WM_CREATE: HDC = GetDC (HWND);
GetTextMetrics (HDC, & TM); cxchar = tm.tmavecharWidth; cychar = tm.tmheight tm.externalleading;
ReleaseDC (HWND, HDC); RETURN 0;
Note that the TMEXTERNALLEADING field is included when calculating CYCHAR, although the field is 0 in the system font, but because it makes the text more readable, it should also be included in. A line of text will be displayed every cychar pixel along the window. We often need to display the formatted numbers and simple strings to the screen. But we can't use Printf () to do this. But you can use sprintf () and Windows version of sprintf () -> WSPrintf (). These functions are similar to Printf (), just put the formatted string into the string. The string can then be output to the display with textout (). It is very convenient that the value returned from sprintf () and wsprintf () is the length of the string. We can pass this value to TextOut () as the ILEngth parameter. The following code shows a typical combination of WSPrintf () and TextOut ():
INT ILENGTH; TCHAR SZBUFFER [40]; [省 此] ionth = wsprintf (Szbuffer, Text ("The Sum of% I and% I IB), IA, IB, IA IB;
Textout (HDC, X, Y, Szbuffer, Ilength);
Now we seem to have all the knowledge required to display multi-line text on the screen. We know how to get a device description table handle during the WM_PAINT message, how to use textOut (), and how to arrange the word distance according to the size of the character, the rest is to show a meaningful stuff.
In Chapter 3, we know that information obtained from Windows getSystemMetrics () is very meaningful. This function returns the size information of different graphics components in Windows. Such as icons, cursors, title bar, and scroll bars. They differ depending on display of the adapter and drivers. GetSystemMetrics () is an important function that completes the graphic output that is not related to the device in the program.
This function requires a parameter. This parameter determines what kind of information obtained. For example, when this parameter is SM_CXSCREEN:
GetSystemMetrics (SM_CXSCREEN);
This function returns to the width of the display, and the unit is pixel. For example, my current display resolution is 1024 * 768. So the statement above the statement will be 1024. and:
GetSystemMetrics (SM_CYSCREEN);
The returned is the height of the screen, and the unit is pixel. I returned here is 768.
These parameter options that are prefixed in SM are defined in the Windows header file. GetSystemMetrics () return type is integer. Let us write a program that shows some information that can be obtained from the getSystemMetrics () call, and the display format is occupied by each message. A header file has been established in the book, and a structural array is defined in the header file. The structural arrays contain all parameter options all of the getSystemMetrics ().
I can finally see the program. This program is relatively simple. Just preparing for the later proceedings. The fourth chapter has three programs.
Winmain () section and the third chapter of Hellowin have no difference. So we go directly to WndProc ().
WndProc () in the program in the SYSMETS1.C program process three messages. The processing method of the WM_DESTROY message is the same as the Hellown in Chapter 3.
The WM_CREATE message is the first message received by the window process. Windows generates this message when CREATEWINDOW () creates a window. In dealing with the WM_CREATE message, the program calls getDC () gets the device descriptor table of the window, and calls GetTextMetrics () to get information about the default system font. The program saves the average character width in CXCHAR and saves the height of the character in Cychar.
The program also saves the average width of the uppercase letter in the static variable CXCAPS. If it is a wider font, CXCAPS is equal to CXCHAR. If it is a wide font, CXCAPS is set to CXChar multiplied by 150%. TmpitchandFamily domain in the TextMetric structure. If it is a wide font, the domain is valued, if it is a wider font, the domain value is 0. The role of this field calculates CXCAPS: CXCAPS = (TM.TMPITCHANDFAMILY & 1? 3: 2) * cxcha / 2;
The program displays multi-line text to the client area during processing WM_PAINT messages. The window procedure first calls beginpaint () Get the device description table handle, and then loops all the rows of the Sysmetrics structure defined in the program with a FOR statement. Three column text is displayed by three textOut (). For each column, the third parameter of TextOut () is set to:
CYCHAR * I
This parameter indicates the pixel point position in the upper left corner of the string to the upper left corner of the client area.
The first TextOut () statement shows the uppercase identifier in the first column. The second parameter of TextOut () is 0, so the display position of the first column is the left edge of the client area. The content of the text is from the SZLabel field of the Sysmetrics structure. The Windows function lstrlen () is used in the program to calculate the length of the string.
The second TextOut () statement shows a description of the system size value. Unfortunately, we don't understand. These descriptions are stored in the SZDESC field of the Sysmetrics structure. In this case, the second parameter of TextOut () is set to:
22 * CXCAPS
The longest uppercase identifier shown in the first column has 20 characters, so the second column must begin at the beginning of the first column text to the right 20 * CXCAPS. I use 22, so there is some gap between the first column and the second column since the first column.
Article 3 TextOut () statements displays a value from getSystemMetrics (). Note that the third column display mode is right alignment, and the string display position specified in Textout () is also the coordinates in the upper right corner of the text, which is different from the first two columns. A number of third columns displayed. The display location specified in TextOut () is the coordinates of the number of digital upper right corners. SetTextAlign () can change the alignment of the text.
SetTextAlign (HDC, TA_RIGHT | TA_TOP);
The second parameter of the third TextOut () is set to:
(22 * cxcaps) (40 * cxchar)
The other setTextAlign () after TextOut () will be aligned to normal left alignment to perform the next loop.
There is a problem that there is a difficult problem in the sysmets1 program. If there is no big display, we will not see the bottom few lines. If the user deliberately tested a small customer area, we can't even see two columns behind.
The program did not consider such a problem. Our program does not even know the size of the client area. It just starts the text from the top of the window. It doesn't matter if the user can see the following. This is very unsatisfactory. To solve this problem, our first task is to let the program know the size of the customer area, stand it know how many columns can be displayed in the customer area.
Users who have used the Windows program should be clear, and the size of the window is very large. We can change the size of the window as you want. In Chapter 3 we use getClientRect () to get the size of the client area. With this function is nothing wrong, it is not efficient to call it frequently. Determining the amount of window customer area is a better way to process the WM_SIZE message during the window. Whenever the window changes the size of Windows to the window process to send a WM_SIZE message. The low sixteen of the LPARAM domain of the WM_SIZE message contains the customer area width information, and the heights of the 16th part contain the customer area height. To save these sizes, you need to define two static variables during the window:
Static int CxClient, Cyclient;
The fourth domain of the MSG structure LPARAM, and the fourth parameter of WndProc () is a 32-bit integer. The lower 16 bits of the LPARAM domain in WM_SIZE contain the width of the client area, and the height 16 bits contain the height of the client area. These sizes must be saved to two static variables: Case WM_SIZE: CXClient = Loword (LPARAM); // Cyclient = HiWord (LPARAM); // Customer RETURN 0; //
Word is 16-bit unsigned integers. The definition of Loword and Hiword in WINDEF.H is as follows:
#define loword ((Word)) # Define HiWord ((Word) ((DWORD) >> 16) & 0xfff))
So Loword (LPARAM) is equal to Word (LPARAM). Because Word is 16-bit, and LPARAM is 32-bit, the LParam high 16 bit is lost after the strong type conversion. Leave only 16 bits, that is, the width of the customer area.
DWORD is unsigned long, 32 bits. After the right movement of 16 bits, the lower 16-bit part was lost, the original height 16 was lowered, and 16 bits were sixteen 0. Then stand with 0xffff (ie 111111111111111), and the result is nothing. Then, the 32-bit LPARAM is then stronger, so since it has obtained the height of the client area.
If you don't understand the Loword and Hiword macro, you don't know if your C language is not good, please try the C language foundation.
WM_SIZE messages in many Windows programs will inevitably follow a WM_PAINT message. Specify the window style when defining the window class:
CS_HREDRAW | CS_VREDRAW
This type tells Windows If the level of the client area or changes in the vertical size, the customer area is forced.
The total number of texts that can be displayed in the client area with the following formula:
Cyclient / cychar
The approximate number of lowercase characters that can be displayed in the horizontal direction of the customer area is:
CxClient / cychar
People who have a little mathematical knowledge know that the divisor cannot be zero. If CXCHAR and CYCHAR are determined during the processing of the WM_CREATE message, you don't have to worry about the case where 0 is removed in these two computing formulas.
If the size of the customer area is not enough to accommodate all the content, then the size of the window client area is only to provide users with the first step in moving text in the customer area. Users who have used other Windows programs should be very clear, in which case we need "scroll bar".
The scroll bar is one of the best features in the graphical user interface, which is easy to use and provides good visual feedback. You can use the scroll bar to display any stuff, whether it is text, graphics, form, database record, image, or web page, as long as the space required is exceeded by the space available, you can use the scroll bar.
The scroll bar has both vertical directions and there is also a horizontal direction. The user can use the mouse to click on the arrow between the scroll bar or between the arrows, and the "scroll box" is moved in the scroll bar simulated the approximate position of the displayed information across the entire document. The user can also drag the scroll box to a specific location with a mouse.
Sometimes the programmer is difficult to understand the scroll strip concept, because the programmer's view is different from the user's view. The user scroll down is a slight part of the document, but the program is actually moving up with respect to the display window. Windows documents and header file identifiers are user-based. Up rolling means moving toward the beginning of the document, it means to move to the tail of the document.
It is easy to include horizontal or vertical scroll bars in the application. Programmakers only need to include window style identifiers WS_VSCROLL (vertical scroll) and WS_HSCROLL (horizontal scroll) in the third parameter of CREATEWINDOW (). The customer area does not include the space occupied by the scroll bar. The width of the vertical scroll bar and the height of the horizontal scroll bar is constant. If you need these values, you can use getSystemMetrics () to get it.
Windows is responsible for processing all mouse operations of the scroll bar, but the scroll bar does not have an automatic keyboard interface. If you want to use the cursor to complete the scroll function, you must write this aspect of this area by the programmer.
Each scroll bar has a related range and location. When the rolling frame is in the top or left side of the scroll bar, the position of the rolling box is the minimum value. The position of the rolling box is the maximum range in the bottom or right side of the scroll bar.
By default, the roller is between 0 and 100. But it is easy to change the range to more convenient for the number of procedures:
SetscrollRange (HWND, IBAR, IMIN, IMAX, BREDRAW);
The parameter IBAR is SB_VERT or SB_HORZ, IMIN and IMAX are the minimum and maximum values, respectively. If you want Windows to scroll through the scroll bar according to the new range, set BREDRAW to True. If you call setScrollRange (), you should set BREDRAW to false to avoid too much redraw.
The position of the scroll bar is always discrete integer value. For example, the rolling strips range from 0 - 4 have 5 rolling frame positions.
We can use SetScrollPos () to set up new scroll layers in the scroll bar range:
Setscrollpos (HWND, IBAR, IPOS, BREDRAW);
Parameter IPOS is a new location, which must be within IMIN to IMAX. Windows also provides GetScrollRange () and GetScrollPos () to get the current range and location of the scroll bar.
The programmer and Windows are responsible for maintaining the scroll bar and updating the rolling box when using scroll bars. Below is the processing of Windows to scroll bar:
◆ Handle all scroll bar mouse events ◆ When the user is in the scroll bar, it provides a "reverse video" flashing ◆ When the user drags the scroll box in the scroll strip, the scroll box is to include the scroll bar window. Window process sends scroll bar information
The following is the work that the programmer should be completed:
◆ Initialize the scope and position of the roller ◆ Processing the scroll bar message for the window process ◆ Update the position of the scroll box in the scroll bar ◆ Change the content of the client to respond to changes to the scroll bar
Everything as described above is clearer when you look at the code.
When you click the scroll bar or drag the scroll box with the mouse, Windows sends a WM_VScroll message message message and WM_HSCROLL message to the window process. Each mouse action on the scroll bar generates at least two messages, one when the mouse button is pressed, and the other is released when the mouse button is released.
Like all messages, WM_VSCROLL and WM_HSCROLL have WPARAM and LPARAM message parameters. For scroll bars that are created from part of the window, we can ignore LPARAM, which is only used as a scroll bar created as a sub-window.
The WPARAM message parameter is divided into a low word and a high word. The low word is a value that indicates a mouse to the operation of the scroll bar. This value is called "Notification Code". The value of the notification code is defined by the identifier at the beginning of the SB. The following is the notification code defined in Winuser.h:
#define SB_LINEUP 0 # define SB_LINELEFT 0 # define SB_LINEDOWN 1 # define SB_LINERIGHT 1 # defint SB_PAGEUP 2 # define SB_PAGELEFT 2 # define SB_PAGEDOWN 3 # define SB_PAGERIGHT 3 # define SB_THUMBPOSITION 4 # define SB_THUMBTRACK 5 # define SB_TOP 6 # define SB_LEFT 6 # define SB_BOTTOM 7 # Define SB_Right 7 # define SB_ENDSCROLL 8 contains Left, and Right's identifier for horizontal scroll bars, contains UP, DOWN, TOP, and BOTTOM identifiers for vertical scroll bars. The mouse is shown in different regions of the scroll bar, as shown in Figure 4-7, as shown in Figure 4-7.
When the cursor of the mouse is placed on the scroll box and hold the mouse button, we can move the scroll box. This creates a scroll bar message with SB_THUMBTRACK and SB_THUMBPSITION notification code.
When the low word of WPARAM is SB_THUMBTRACK, the high word is the current location when the user is dragging the scroll box. When the low word of WPARAM is sb_thumbposition, the high word is the final position of the user release the scroll box after the mouse button. The high level of the WPARAM is ignored for other scroll strips.
In order to give the user feedback, Windows will move the scroll box when we drag the scroll box with the mouse. At the same time, our program will receive the SB_THUMBTRACK notification code. However, if the SB_THUMBTRACK or SB_THUMBPSITION notification code is not processed by calling setscrollpos (), the scroll box will quickly jump back to the original position.
One thing to figure out. Even if we change the position of the scroll box with setscrollpos (), the content of the client area will not automatically change with the scroll bar. The programmer must change the content of the customer area.
The program can handle SB_THUMBTRACK or SB_THUMBPOSITION, but generally processes both. If you process SB_THUMBTRACK, the programmer needs to move the customer area when the user drags the scroll box. If you handle SB_thumbPosition, you only need to move the customer area content when the user stops dragging the scroll box. Handle SB_thumbTrack is better.
Winuser.h header also includes SB_TOP, SB_BOTTOM, SB_LEFT, SB_RIGHT notification code, pointing that the scroll bar has been moved to its minimum or maximum. However, these notification codes will never receive for the scroll bars created as part of the application window.
It is also effective to use 32-bit values for scrolling strips range, although this is not common. However, the high level of WPARAM is just 16 bits, which cannot appropriately indicate the location of the SB_THUMBTRACK and SB_THUMBPSITION operations. In this case, getScrollInfo () is required to obtain information.