I have been very excited since I received this classic masterpiece "window Program Design" at on May 23, March 2. This book gives me the feeling that I want to "C ++ primer plus", or better, both of them share a common feature that allows you to eliminate basic blind spots and lift your doubts from the past. Everything starts and ends.
After 10 days, I only saw Chapter 10. Ah, it was a little slow, but because I didn't read books, I basically put all the programs that appeared in the book, in the form of self-understanding and independent writing. I feel that it is okay. I think it is difficult to understand that many of them have been removed before. For example, getsystemmetrics (although it is a basic function, however, I used to see this function. It seems that this function has a lot to do with the system, so I am afraid !), There are many things such as function window views, free transformation of the ing mode, and sub-Window Creation. This also proves the immortality of the Bible, so that you will feel a clear knowledge system after learning it. Although the content is large, it is not messy. It's not too messy, as long as it's because of Windows itself, not the reason described in this book. We all know Windows functions, message definitions, and notifications. If they all look at them, you can watch them for a few months.
Having paved the way for so many topics to enter this blog, it is the key point of self-summarization.
I summarized the key points in the order of chapters:
Chapter 1: getting started
- A Brief History of windows. In 1981, PC started to appear. At that time, the dominant operating system was MS-dos. Microsoft announced windows in 1983. (Before that, Apple released Lisa, proposing different ideas from the character interface. Apple released the Macintosh in 1984 to become the standard for graphic interfaces .) Windows was released in. Windows was released in, and the OS/2 operating system was released with IBM in the same period. Windows was launched in. At the same time, windows was separated from IBM. Microsoft no longer participated in OS/2, but focused on its own windows. Window3.1 was released on July 1, 1992, and 6-December 7, 1993. Then we are familiar with window95 and window98. And now windows
2000, windows2002, XP, Vista, window7, etc.
- Function of dynamic link library. Previously, all the APIS we used were connected to our program in the form of Dynamic Link Libraries. We were not able to blame the program for debugging. In the output box, N has been loaded with xxx. dll. The C-language functions we use, such as strlen (), are equivalent to adding code to your program, and the program itself will become larger. The import/export function is used to load DLL preparation information. This is because the import/export function itself feels that it records the corresponding DLL address and the address in the DLL, the program can add the information to the program only through Lib in the connection phase, and then the program does not need lib during actual running, because the information has been loaded into the program. This explains why we used to write ogre, the speech engine needs DLL, Lib, and header files (the header file is a method to conveniently call the DLL function, the dll contains a detailed description, which calls the DLL function as an "implicit connection" by using the header file ").
- We often see that Lp is actually a legacy of Windows 16. At that time, segment address addressing was adopted. Physical addresses include segment addresses and intra-segment addresses. Long pointers can be used for addressing different segments, while NP, or near pointers, can be used for addressing within the same segment. However, 32-bit Windows operating systems have long ignored this. LP and NP are the same, just to be compatible with previous versions of programs. You will often see this system definition: struct point {} * Ppoint, * lppoint, * nppoint; this proves that lp, NP, and P are the same.
- Naming method: Hungarian naming method. That is to say, the first or first few characters of all variables indicate that the type is smaller, and each word or its abbreviated first character is capitalized. For example: int ilen; hwnd hwnddlg; there are also some non-typed lowercase letters with special significance, such as: int cbwndextra; where CB, C is the abbreviation of count, the number. B is the abbreviation of byte, which means byte. Therefore, cbwndextra is the number of bytes reserved for the window, such a variable. The significance of this variable will be known in the future.
- MessageBox already has many forms. There is only one "OK" button, there are "OK" and "cancel" buttons, there are "Ignore", "retry", "cancel" three buttons, what are the four buttons. You can also specify the icon that appears in the message box. Information prompts, errors, and inquiries.
The first one says a lot! It seems that this book is just like this, so you can know a lot and even summarize a lot. See the next chapter.
Chapter 2: Unicode
- This is basically the source of Unicode. In the past, there were only a few American characters and they needed to use them. Later I thought that Europe would have to expand the characters and then expand to the east. The computer used Asia and finally the Americans were dumpfounded, the first method is the dubyte character set (DBCS ). However, this character set is very strange. Some characters are one byte, while others are two bytes. This makes programming difficult, because to determine the pointer position (in the first character), you cannot simply subtract from the first character address to get the offset, because some characters are in the same byte. Then the Unicode Character Set appears. It is indeed unique because it represents a character in two bytes, so there will be no ambiguity. But it is a waste of space. (Then the emergence of UTF-8, UTF-16, utf-32 and other Unicode solutions, window with UTF-16 ). A clear concept is that "wide character" is a method that indicates that multiple bytes are used to represent a character. Therefore, Unicode is a wide character. The wide character cannot be Unicode.
- Because the characters are used in different bytes, a wide character version must be added to all functions involved in the character. This is what we often see in strlen, corresponding to wcslen (this is a C function, windows has different macro definitions to facilitate compilation of different codes ). In the future, all constant strings will be added with text (""), which can be compiled using the Unicode encoding scheme or the ASCII encoding scheme.
- Sprintf and fprintf are used to format the strings and files. In addition, vsprintf is used to help implement functions that output non-quantitative variables. No. The C language also uses macro definition, while the window also uses macro definition, so that the program can use the same function name in Unicode and ASCII, without worrying about whether it is a wide character version or not. Because the compiler helps you decide.
It seems that the second chapter is a little less. Hey. Write down one tomorrow.
Today is the summary of March 13.
Chapter 3 window and message
- Here, I would like to recall that this is the basis, but the process of creating a window for the first time is thrilling and scary. You need to know, it is really scary for beginners to use a 10-parameter wndclass struct and createwindow with 11 parameters. But fortunately, these are all gone.
- In wndclass, you should pay attention to the usage of system resources, such as getstockobject, loadicon (null, idi_application), loadcursor (null, idc_arrow), and idi_application, idc_arrow is the macro definition of makeintresource to convert the numeric ID into a string pointer. However, this string pointer is not used in essence, but if the character pointer has a high value of 0, loadicon and other functions will know that the 16th bits are resource IDs.
- The first parameter of createwindow is the window class name, not the window class object. When it comes to the window class, it may be necessary to create the window into two parts. I think there are two reasons: 1. The first is to use the window class multiple times, that is to say, the values of some window class variables in many windows are the same, and the same is true. Therefore, the window class can be separated to facilitate subsequent window creation. 2. Both of them perform their respective duties. The window class is mainly related to some properties, but it is not the window itself, while createwindow is something that focuses entirely on the appearance and attributes of the window. In addition, the createwindow function itself will send the wm_create message, indicating that the message is sent as Asynchronous. In fact, it is synchronous. It calls back wndproc in the createwindow function and then goes back to complete createwindow after the call is complete. So remember that all the words used to send messages are synchronous function calls. If the message is delivered, it means that the message is sent to the Message Queue asynchronously.
- In addition, an important point in createwindow is that if it is created as a subwindow, The hmenu parameter is used as the subwindow ID, which is required.
- When createwindow is finished, it is showwindow. It is responsible for different jobs. createwindow creates basic window data in memory, while showwindow displays abstract windows to the screen. This function sends the wm_size message. I will send it. You know how to synchronize the callback window process.
- Updatewindow sends wm_paint, you know. However, you must note that the wm_paint message is repainted Based on the invalid region. Why is it determined by the HDC returned by beginpaint, because the HDC crops the invalid area, and the so-called cropping means only re-painting the cropped area, do not redraw in this area. Therefore, if you do not have an invalid region, it is useless to send an updatewindow. In addition, wm_paint has a lot to note. Wait for the summary in the wm_pant message.
- During the window process, we use the case statement to intercept the messages we are concerned about, but we should know whether the messages we intercept have been processed by default. If there is a default process, after the break is processed in the case block, if you know that the system does not handle it by default, you can directly return it.
- Wm_paint message. You must note that the beginpaint message must be written in this Statement. Remember to write the following wm_timer message. In the wm_create message, settimer is entered, but wm_timer messages are not received, it turns out that wm_paint didn't write code, but I want to check the wm_timer effect first. However, because wm_paint does not contain beginpaint, beginpaint clears invalid areas. You may not understand it. The key is how wm_paint is cleared in the message queue? Do not think that the wm_paint you are processing will be gone. If it is wrong, it will clear all wm_paint messages in the message queue. Continue to talk about the bug. Because wm_paint does not have beginpaint, wm_paint cannot be cleared and will repeat the wm_paint processing process. Therefore, wm_timer has no chance to process the message, because wm_timer is also a queue message. A queue message is a message that needs to pass through the message queue. Each program has a message queue. Messages that pass through the Message Queue can be a sequence of messages, that is, they comply with "first come, then arrive" and "priority ".
- The getmessage function retrieves messages from the message queue. If yes, extract the message and hand it over to translatemessage. If it is a Keyboard Message, translatemessage determines whether the Keyboard Message generates a character message. If it generates a character message, translatemessage adds a character message to the message queue, which serves only (so far ). Dispatchmessage refers to the process of sending messages to the corresponding window.
- By the way, the hinstanceprev in the winmain function is always 0. Why is it used in the previous program? It is reserved for compatibility and always set to 0, this will make the original program logic correct. Ah, we know something about compatibility. In the past, we always heard that Windows is highly compatible with books or other people, and we couldn't understand what compatibility is. Ah, we can also understand a little compatibility. Haha.
Ah, but I still wrote a lot about it. However, there are very few mistakes compared with those in the book. I don't know how many mistakes I typed. Hey.
Today is July March 21, and I haven't written it for eight days, because I saw a lot of new things last week, but some programs were relatively large and I didn't write it if I was tired. I also had a good rest, continue to work hard today!
Chapter 4: text output
- The wm_paint message may appear in several cases. Window Size changes (this requires the cs_hredraw and cs_vredraw types of Windows). The window is blocked and invalidaterect is used to indicate invalid rectangles. Some Windows functions such as scrollwindow and scrolldc make the window image scroll, some invalid regions are generated. You don't need to worry too much about others. Some windows will save, some will not. In short, Do not care too much, generally do not affect your program.
- The above mentioned invalid rectangle means that the rectangle specified by the invalidaterect function is invalid rectangle. This function will send the wm_paint message, the window handle obtained by using the beginpaint function will only be re-painted on the invalid rectangle (of course, it is the image in the invalid rectangle ). Alternatively, you can use getupdaterect to obtain an invalid rectangle or an update rectangle ".
- This chapter is the first chapter related to graphics. When it comes to GDI, you have to say a word that puzzles and fears all new users who are new to it. That is the device context. What is the device context? The context is often used in Chinese textbooks, but how does the device talk about it? This may be nothing to do with computers. I understand it as follows: First of all, I want to talk about devices. The devices mentioned here are a little abstract. Do not blindly think about the display devices. They do have something to do with them, however, using another perspective can help us understand programming. A complete description of the device is bitter. Let's talk about it! In this case, if you know what the customer zone is, you can better understand the device. Because we usually paint in the customer area, although we can also paint in the whole window, it is not a formal practice. Why can we paint in the customer area separately, and painting is like painting on an independent device? I mentioned the device because when we paint in the customer area, if the coordinates are displayed in the customer zone, they are not displayed. If our coordinates go out of the customer zone and affect other windows, I don't think anyone would like. You can see that the customer zone is like a separate display screen with a complete painting system. Therefore, we can build a customer zone as a device. Windows are also devices. The screen is also a device. Does it feel like these devices have many overlapping areas. However, if you get the handle of these device environments, painting above is equivalent to painting on an independent device. When talking about the device environment handle, let's talk about the device environment. You know a bit about the device. What is the device environment? I asked you if you want to write the words you want to write in the customer zone using textout! Yes, but I want to ask you, what is the font color and type of the words you write. If you draw a line directly, the line is a dotted line or a solid line. You do not need to use the prefix settings. The device has the default settings. In my opinion, this is the device environment and the current status of the device. What about the device environment handle? A handle is a value, which can be used to reference the desired object, while Windows kernel objects are all handled by the handle. For the time being, don't worry about kernel objects. A simple understanding is a very important windows object. The device environment handle allows us to get a lot of information about the device environment. I have written enough.
- List several methods to get the device environment handle: beginpaint is used for wm_paint messages because it is customized for wm_paint. It contains a lot of important information, such as invalid rectangle. Getdc is used to obtain various device handles, but does not contain any re-painting information. Createdc is used to create environment handles and printer handles for screen devices. Createic is the handle used to obtain information but cannot be painted.
- In terms of text output, it seems to me that there are basically two functions in display, one is the classic textout function, and the other is the format output function drawtext. However, if the output is neat, you need to get some specific font information, such as the fonts you want to use to output in the customer area, the height and width of these fonts directly affect your output. Therefore, if you output a general font, you will get the information you want to use in the wm_create message. Then we can use it later, but we can explain in advance that we can handle the same width font, that is, system_fixed_font, or set fixed_pitch when using logfont for pitch, in this way, the same width font can also be obtained. Because the processing of non-width fonts is really troublesome, we need to do a lot of meticulous work in the layout and layout.
- When talking about fonts, You should know some basic information about the computer's Font Processing. You can use the gettextmetrics function to obtain these basic information and save the results in textmetric variables. Among them, there are tmheight, tmavecharwidth, tmexternalleading, tminternalleading, tmascent, and tmdescent. Tmascent ranges from the font baseline to the highest possible font (including some tone symbols on top of common characters), while tmdescent is the baseline to the lowest possible font. The baseline is just like writing G on the letter paper. We will download the bending hook of G to the bottom of the horizontal line and unmount the O of G to the top of the horizontal line, which is the baseline I just mentioned. Tminternalleading is the tone symbol (if any) on a common character ). Tmexternalleading is a line spacing instead of a font. Basically, we can think that, of course, there is a more beautiful layout on the basis of tmexternalleading, which has achieved the best visual effect. Tmavecharwidth is the average character width. Why is the average character used for non-equal width fonts? The same width is the width of each character. Tmheight is the sum of tmascent and tmdescent. The most important thing for us is tmheight, tmexternalleading, and tmavecharwidth. Because tmheight + tmexternalleading is the height occupied by a row of fonts. Tmavecharwidth is the font width.
- If fonts are used, we need to explain the details. The font, pen, and painter will all involve the background color and background mode. Do not mix this with the window background. The window background is used to refresh invalid areas. The background color and background mode of the font are used to write the font on the background color when the font is output at the specified position. After the background mode is changed, the font is "pasted" to the desired position. Of course, the background color and background mode are in harmony with other default settings of the system in the default mode. You can change it through setbkcolor and setbkmode. You can check the specific function usage by yourself.
- The scroll bar basically uses setscrollinfo. For example, setscrollrange and setscrollpos can be replaced by setscrollinfo. In addition, setscrollinfo provides more convenience. For example, to scroll through the settings of the last page, you should not put the last row of the file on the top of the last page, but at the bottom of the last page. Put it at the bottom, you need to calculate it yourself, and setscrollinfo helps you calculate it.
- Scrollwindow is often used in the scroll bar. Because of its high efficiency, the screen will not become very stuck. However, scrollwindow is one of the few functions that do not use device handles. Therefore, this is because it does not belong to the GDI module. In the scroll bar, you should judge whether the scroll bar has reached the top or reached the bottom to avoid unnecessary re-painting.
Wow, it's so tired. Well, it's hard for you to write books! After writing the paper, I didn't check it. Who gave it a draft?
Today, in March 23, chapter 5 is about to begin. You need to know how important this is and how powerful it is for cainiao like ours. But the content is really a lot important!
Chapter 5: Drawing Basics
- First, we should know that Windows uses the GDI module to make our drawing completely independent from hardware. So that the drawing operation can be transplanted. Of course, the image output type is the same as the device, because the vector device cannot use many grating operations, so that the grating operation function cannot be used on the vector device.
- The functions used to obtain system information should know: getsystemmetrics, getdevicecaps, gettextmetrics;
- It should be clear that the resolution sometimes refers to the number of pixels used by the total length (width or height) of the device. The authors of this book tend to use the number of pixels per measurement unit as the resolution, while the pixel scale is used to represent the total length of the device. Represents the physical size of the total length of a device by measuring the size or scale. Horzsize is different from horzres. One is the measurement unit and the other is the pixel unit. And the former is not necessarily right from the system. The author does not recommend that you use physical dimensions to do things.
- If we want to change the environment of our device and then return to the original state in a certain operation, the savedc and restoredc are essential and often use the stack form. Savedc (HDC); restoredc (HDC,-1);-1 indicates that it is returned to the previous state.
- Statistics on various functions: setpixel and getpixel. Line: movetoex, lineto, polyline, polylineto, polypolyline, arc, polybezr, polybezierto. Fill type: rectangle, ellipse, Chord, pie, polygon, and polypolygon)
- Paint Brush, brush all kinds of styles should be understood. These objects are also in the background color and background mode.
- In addition, raster operation is an important drop-down operation. Grating operation. Through setrop2, 2 represents the two elements, that is, the relationship between the two objects, such as the paint brush color and the target color. The clever setrop2 can greatly improve the plotting efficiency of our program, without setting any invalid areas, which may be used to reproduce the background. So we should take a good look!
- You need to know a little basic knowledge. In fact, we use the current image brush (8*8 Bitmap) to repeat and paste the background. The current paint brush can be changed without SelectObject. It is the data in your window class and setclasslong is used for modification. Speaking of setclasslong, we need to know the other three Super functions, getclasslong, setwindowlong, and getwindowlong.
- Ing mode, which is very important. I think it is the soul of painting. If you do not understand the ing or are not clear about it, it is hard to understand the convenient operations built on the ing. There is a device coordinate ing wm_text. All other provisions are metric ing, that is, involving physical units. This is used to facilitate the creation of device-independent information. For example, if you want to create a 30mm-width, 30mm-high image, you don't need to calculate how many pixels the 30mm-height image has on your computer. You just need to replace it with wm_lometric or something else. The ing between Y and Y is the opposite of that of device coordinate. However, it is best to use wm_isotropic and wm_anisotropic, which makes our ing coordinates extremely flexible. You can set the number of pixels that 1 represents, or the unit that you think is useful to your program, such as a character height. Wm_isotropic is the same property, and wm_anisotropic is the same property. However, wm_ansiotropic does not have to be wide, and the unit of height must be different. It only shows that wm_ansiotropic can be competent for different units of width and height. Wm_isotropic makes the unit of width and height the same, even if you use different width and height values, because Windows will check your value, instead, we try our best to convert it into a ing mode with the same unit of width and height.
- In the ing mode, you have to mention the window, the view, and the origin. Do not care too much about the window. We should remember more about its meaning in the drawing, which is better. Window, as long as you think it has something to do with the window, it is generally only the logical coordinates and represents the current logical ing mode. In this case, the logic ing mode should be like this, but it makes me better understand, because I understand that the logical ing mode is your own, or you have not set the current default ing mode, which may be the device coordinate ing. The viewport is the device coordinate. Because the view does not change. Therefore, you need to modify the origin using a multi-view. Speaking of the origin, we need to know how Windows converts the logical coordinates you have written to the device coordinates, and you will know why there are windows, sdks, and origin points. Take a look at the following formula:[CPP]View
Plaincopy
- Xviewport = (XWindow-xw.worg) * xviewext/xwinext + xvieworg
- Yviewport = (ywindow-ywindow worg) * yviewext/ywinext + yvieworg
,XWindow-xw.worg is used to calculate the logical coordinate displacement difference (Point-to-origin), and xviewext/xwinext is used to obtain the length of the device coordinate of a logical coordinate, then the two are multiplied to obtain the device coordinate displacement difference, and then the real coordinates on the device are obtained by adding xvieworg.. Don't think it is troublesome. This is very necessary. Without this formula, the plot will become monotonous and complex. These ing modes are designed to facilitate scaling and layout. No, they believe that you are printing, and it will be painful to typeset somewhere. Through the formula, we can see that the origin has a window origin and a view origin, which are the reference points corresponding to the points in the window and the view. We can change the origin of one of them to achieve our ing coordinate system origin. Place the device origin point in the square direction (regardless of width or height). The ing Coordinate System Origin point will offset the corresponding displacement in this direction. Moving the origin of the logical coordinate system to the positive direction of the logical coordinate system will move the ing coordinate system to the opposite direction. In the formula, the origin of the logical coordinate system is reduced, and the origin of the device coordinate system is added. The ing coordinate system I mentioned is your logical coordinate system.
- Do not use Chinese to think about the window range or the window range. When you see the formula above, you will know that the two of them do not have much to do with the range, as long as they have a relationship with their proportions. Several common wm_isotropic setting methods use the same thing to set the window range and the window range. In this way, you can get your desired proportion. For example, you want to set your own logical coordinates to 1 feet logical units. So you should write:[CPP]View
Plaincopy
- Setwindowextex (HDC, 3, 3, null );
- Setviewportextex (HDC, getdevicescap (HDC, logpixelsx), getdevicescaps (HDC, logpixelsy), null );
- Getdevicescap (HDC, logpixelsx) is the number of pixels that are 1 inch.
In this way, because the window range and the window range are set with reference to 1 inch, Windows will help you implement it. Your 3 logical units correspond to 1 inch, which is actually the number of workers calculated by windows, but the number of shards is exactly equal to 1 inch.
- In addition, we will introduce useful invertrect and invertrgn. This is a function for reversing the regional pigment. Black to white. There are many problems related to rectangles, such as offsetrect, setrect, insectrect, inflaterect, uniorect, and ptinrect.
- A region is a very important GDI object. Just a few coordinate data without a rectangle. A region is a GDI object first, so it is a resource. Therefore, all regions must be deleted after they are created. We can create a variety of areas, rectangular, and elliptical areas, and then perform operations on the complex areas of the rectangle, the ellipse, and other areas. Areas can be used for drawing. Regional operation functions: combinergn (hdestrgn, hsrcrgn1, hsrcrgn2, icombine) perform operations in different regions using different methods. However, note that hdestrgn in this function is only used to undertake the results. This handle must have a valid region before it can be used. Otherwise, an error may occur. Crop the area and select the area into the device environment so that the device can be repainted only within the area after the cropping. So that you can plot a complex image by shielding the area.