Dot matrix map and bitblt

xiaoxiao2021-03-06  44

The dot matrix is ​​a two-dimensional bit array, which corresponds to the image of the image. When the image of the real world is scanned into a dot matrix, the image is split into a grid, and the image is used as a sampling unit. Each of the dot matrix is ​​referred to as the average color of an in-unit grid. Monochromatic dot array Each status requires only one element, gray or color dot mapping, multiple bodies. The dot matrix represents one of two ways to store image information in the Windows program. Another form of storing image information is Metafile, I will discuss in Chapter 18. MetaFile stores is a description of how the image is generated instead of a graphic representation of digitization.

I will discuss more in more detail later, and Microsoft Windows 3.0 defines a map called device-independent point mapping (DIB: device-independent bitmap). I will discuss DIB in the next chapter. This chapter mainly discusses GDI dot matrix maps, which is a dot matrix graphical data supported earlier than DIB. As explained in a large number of examples in this chapter, this graphic format that is supported earlier than the DIB dot mapping is still useful.

Dot matrix

Dot matrix and Metafile occupied a place in the computer graphics. The dot matrix map is often used to represent complex images from the real world, such as a number of photos or video images. MetAfile is more suitable for describing images generated by people or machines, such as architectural blueprints. Dot matrix and Metafile can be stored as a file to the magnetic sheet and can be transmitted between the Windows application via the scrapbook.

The difference between the dot matrix and MetaFile is the difference between the bit element mapping image and the vector image. The bit element maps the image discrete to process the output device; the vector image processes the output device with a Cartesian coordinate system, and its lines and fill items can be individually dragged. Most image output devices are now bitmaping devices, including video displays, dot matrix prints, laser printing machines and inkjet printing machines. The pen plotting machine is a vector output device.

There are two main disadvantages in the dot matrix. The first problem is to be affected by the dependence of the device. The most obvious is the dependence of the color, and the effect of displaying the color dot mapping on the monochrome device is always unsatisfactory. Another problem is that the dot matrix map often implies a specific display resolution and image aspect ratio. Although the dot matrix can be stretched and narrowed, such processing typically includes some rows and columns of replication or deleting the icon, which disrupts the size of the image. Metafile still keeps graphic appearance without damage after zooming.

The second disadvantage of the dot matrix is ​​to require a large storage space. For example, a complete 640 × 480 element, a 16-color video graphic array (VGA: video graphics array) screen is more than 150 kB of space; a 1024 × 768, and each set is The 24-bit color image requires a space greater than 2 MB. Metafile needs a space that is usually less than the dot mapping. The storage space of the dot matrix is ​​determined by the size of the image and the color thereof, while the storage space of Metafile is determined by the complexity of the image and the number of GDI instructions it contains.

However, the dot matrix is ​​superior to MetaFile is the speed. Copy the dot matrix to the video display is usually faster than the replication basic graphical file. In recent years, compression techniques allow compression points to compress the file size to enable it to efficiently transmit and widely used for Internet-page web pages over telephone lines.

Source of dot matrix

The dot matrix can be created manually, for example, the "small painter" program included with Windows 98. Some people prefer to use the bitmap drawing software or not using vector drawing software. They assume that the graph will be complex to expose to the fill area that cannot be used in line.

Dot matrix image can also be generated by computer program. Although most calculated generated images can be stored in vector graphics Metafile, high-definition screens or fragmented patterns often require a dot matrix.

Now, the dot matrix is ​​often used to describe images of the real world, and many hardware devices allow you to enter the image of the real world to the computer. Such hardware typically uses a charge coupling device (CCD: Charge-Coupled Device), which releases the charge in contact with the light. Sometimes these CCD units can be arranged in a group, a set corresponding to a CCD; saving only a line of CCD scanning images. In these computer CCD devices, the scanner is the oldest. It scans the surface scan along the surface of the paper (e.g., a photo) using a line CCD. The CCD generates charge according to the intensity of the light. Class ratio of digital converter (ADC: Analog-to-Digital Converters) converts the charge into a digital signal, then arrange a point line.

Carrying cameras also use CCD cell groups to capture images. Typically, these images are recorded on the video tape. However, these video outputs can also directly enter the image capture device, which converts the class than the video signal into a set of iconic values. These image captures can be used simultaneously with any compatible video signal, such as VCR, disc, DVD player, or cable television decoder.

Recently, the price of digital cameras has become a burden on household users. It looks like a normal camera. However, the digital camera does not use a film, and a set of CCDs intercepts the image, and the digital image is stored directly in the camera within the camera in the ADC. Typically, the interface between the digital camera and the computer is passed through the sequence.

Dot matrix size

The dot matrix is ​​rectangular, and there is a spatial size, the height and width of the image are in a state. For example, this grid can describe a small dot matrix: a width of 9 primubes, height is 6 primary, or more simply 9 × 6:

It is accustomed to the shorthand size of the dot matrix to give the width. The total number of dot matrix is ​​9 × 6 or 54. I will often use symbols CX and CY to represent the width and height of the point line. c represents counting, and CX and CY are the number of images along the X-axis (horizontal) and Y-axis (vertical).

We can describe the specific elements on the point array based on the X and Y coordinates. General (not all like this), when calculated in the grid, the dot matrix is ​​started at the upper left corner of the image. Thus, the primary corner of the lower right corner of this point is (8, 5). Since counting from 0, this value is smaller than the width and height of the image.

The spatial size of the dot matrix is ​​usually specified, but this is a controversial word. We said that our video shows a resolution of 640 × 480, but the resolution of the Lei Print Machine is only 300 inch per inch. I like the meaning of the resolution in the latter case as the number of each unit. The analysis of the dot matrix in this sense refers to the number of points in the distant map in a specific measurement unit. In any case, when I use the resolution of the word, the content defined should be clear.

The dot matrix is ​​rectangular, but the computer memory space is linear. Typically, but not all this) dot matrix is ​​stored in the memory by column and starts from the top of the primary set to the end of the column. (DIB is a major exception to this rule). Each column, the status starts from the leftmost status. This seems to be stored in several characters in several columns.

Color and dot matrix

In addition to the spatial size, the dot mapping also has color dimensions. Here, it refers to the number of bits required for each of the primers, and sometimes referred to as a color depth of the dot matrix, bit-count, or bit / key (BPP: BITS Per Pixel) )number. Each of the dot matrix map has the same number of color bit.

A dot matrix of 1 bits per status is called a bilevel, a bicolor or a monochrome dot matrix. Each status can be 0 or 1, 0 to represent black, 1 can represent white, but not always like this. For other colors, one lookup needs to have multiple bodies. Possible color values ​​are equal to 2-bit elevational values. 4 colors can be obtained with 2 bits, and 16 colors can be obtained with 4-bit elements, and the 8-bit element can obtain 256 colors, and the 16-bit element can obtain 65,536 colors, while the 24-bit element can obtain 16,777,216 colors. How to make the combination of color bits with the colors familiar with people, often encounter (and often disaster) when current processing dot mapping.

Actual equipment

The dot matrix can be classified according to the number of color bits; during the development of Windows, the color format of different dot matrix depends on the function of common video display cards. In fact, we can see the memory as a huge dot mapping - we can see from the display.

Windows 1.0 Most display cards are IBM's Color Image Adapter (CGA: Color Graphics Adapter) and monochrome graphics card (HGC: Hercules Graphics Card). HGC is a monochrome device, and CGA can only be used in monochrome graphics mode in Windows. Monochrome dot mapping is now also common (for example, the cursor of the mouse is generally monochrome), and the monochrome dot matrix has other uses other than displaying the image.

With the emergence of the enhanced graphics display card (EGA: Enhanced Graphics Adapter), Windows users start touching 16 colors of graphics. Each status requires 4 color bits. (In fact, EGA is more complicated than here, it also includes a 64 color palette, and the application can select any 16 colors, but Windows uses EGA only as simpler. The 16 colors used in EGA are black, white, two gray, high and low brightness red, green and blue (three original colors), cyan (blue and green combination). It is now considered that these 16 colors are the lowest color standard for Windows. Similarly, other 16-color dot mappings can also be displayed in Windows. Most icons are a 16-color dot matrix. Typically, simple cartoon images can also be made with these 16 colors.

Color coding in a 16-color point pattern is sometimes referred to as IRGB (high bright red blue: intersity-red-green-blue), and actually the 16 colors originated in IBM CGA text mode. The four IRGB color bits used in each of the primers are mapped to the Windows Hexagging RGB color shown in Table 14-1.

Table 14-1

IRGB RGB color color name 0000 00-00-00 dark blue 0010 00-80-00 dark green 0011 00-80-80 dark green 0100 80-00-00 dark red 0101 80-00-80 Dark @ 0110 80-80-00 Dark Yellow 0111 C0-C0-C0 Bright gray 1000 80-80-80 Dark Fruit 1001 00-00-FB 1010 00-FF-00 Green 1011 00-FF-FF Yellow 1100 FF- 00-00 Red 1101 FF-00-FF Magenta 1110 FF-FF-00 Yellow 1111 FF-FF-FF White

EGA's memory consists of four "color surface", that is, four-bit metaps that define each of the compacts are discontinuous in the memory. However, such an organization shows that the memory facilitates all the brightness bits, all the red bits are arranged together, and so on. This sounds like a device dependence, that is, Windows program writers don't need to know all details, but it should be more or less known. However, these color surfaces appear in some API calls, such as getDeviceCaps and CreateBitmap. Windows 98 and Microsoft Windows NT require VGA or higher graphics cards. This is the lowest standard for the currently recognized display card.

In 1987, IBM first published video image arrays (Video Graphics Array: VGA) and PS / 2 Series PC. It provides many different display modes, but the best image mode (Windows also uses one) is a horizontal display of 640 compacts, and 480 compartments are displayed vertically with 16 colors. To display 256 colors, the initial VGA must switch to 320 × 240 graphics mode, which is not suitable for Windows.

Generally, people have forgotten the color limit of the original VGA card, because other hardware manufacturers have developed "Super-VGA" display card, which includes more video memory, 256 colors and More than 640 × 480 mode. This is the current standard, and it is also a good thing, because of the image in the real world, 16 colors are too simple, some are not suitable.

The display card mode of 256 colors is displayed 8 bits per status. However, these 8-bit dollars do not have to match the actual colors. In fact, the display card provides a "Palette Lookup Table", which allows the software to specify the color value of the 8-bit element to match the actual color. In Windows, the application cannot directly access the torched disk comparison table. In fact, Windows stores 20 types in 256 colors, and the application can be booked in 236 colors through the "Windows Toner Manager". With regard to these content, I will introduce in Chapter 16. The palette manager allows the application to display the actual dot matrix on the 256-color display. 20 colors stored in Windows As shown in Table 14-2.

Table 14-2

IRGB RGB color color name 00000000 00-00-00 dark red 00000010 00-80-00 dark green 00000011 80-80-00 dark yellow 00000100 00-00-80 dark blue 00000101 80-00-80 Dark @ 暗 红 00 0000-00-00 80-80-80 Dark Fruit 1111001 FF-00-00 Red 11111010 00-FF-00 Green 11111011 FF-FF-00 Yellow 11111100 00 - FF Blue 1111101 FF-00-FF Magenta 11111110 00-FF-FF Youth 11111111 FF-FF-FF White

In recent years, True-Color displays are commonly used, and they use 16-bit or 24-bit dollars per status. Sometimes there is a 16-bit dollar per status, one of which is not used, while the other 15 yuan is mainly approximately red, green and blue. In this way, there is a 32-color order for each of the red, green and blue, which can be combined to reach 32,768 colors. More commonly, 6-bit yuan is used for green (most sensitive to this color), so you can get 65,536 colors. For non-technical PC users, they don't like to see numbers such as 32, 768 or 65, 536, so this video display card is usually called Hi-Color display card, which provides thousands colour. When you have a 24-bit element of each status, we have a total of 16,777,216 colors (or True Color, millions of colors), each of which uses 3-bit yuan group. This is very similar to future standards because it roughly represents the limits of human sensory and it is also very convenient.

When calling getDeviceCaps (see the devrapcaps in Chapter 5), you can use the BitsPixel and PlasoS constants to get the color unit of the display card, which shows shown in Table 14-3

Table 14-3

Bitspixel Planes Color 1 1 2 1 4 16 8 1 256 15 or 16 1 32,768 or 65 536 24 or 32 1 16 777 216

Recently, you should not touch the monochrome display, but even if you encounter, your application should not have problems.

Dot matrix support for GDI

Windows Graphics Device Interface (GDI: Graphics Device Interface "starts from version 1.0. However, until Windows 3.0, the only bit graph that supports GDI objects under Windows is used to use it in a point-of-one. These GDI dot matrix maps are monochrome, or with the actual image output device (eg, a video display) has the same color unit. For example, a dot matrix map compatible with 16-color VGA has four color surfaces. The problem is that these color dot mappings cannot be stored, or the image output devices different from color units (such as 86 colors can be generated), such as 86 colors per image).

Starting with Windows 3.0, a new dot matrix map format is defined, we call the device independent bitmap, or DIB. DIB includes its own palette, which shows a chamber bit corresponding to the RGB color. DIB can be displayed on any bitmap output device. The only problem here is that the color of the DIB usually converts the color actually exhibited by the device.

At the same time as DIB, Windows 3.0 also introduces the "Windows Toner Manager", which allows programs to customize colors from the 256 colors displayed. As we have seen in Chapter 16, the application usually uses the "Toner Disk Manager" when DIB is displayed.

Microsoft extends DIB definitions in Windows 95 (and Windows NT 4.0), and extensions again in Windows 98 (and Windows NT 5.0). These extensions add a so-called "image color manager (ICM: image color management) and allow DIB to more accurately specify the color required to be required. I will discuss ICM in Chapter 15.

Regardless of how important DIB is, in the processing point mapping, the early GDI dot matrix object still plays an important role. The best way to master the point of printing is to learn according to the time order of evolving development in various usages, starting with the concept of GDI dot matrix objects and bit blocks.

Position block transmission

I mentioned earlier, you can think of the entire video display as a big chart. The icon you see on the screen is described by the bit element stored in the memory display card. The rectangular area displayed by any video is also a dot matrix, which is the number of rows it contains.

Let's copy the image from the image from the video to another, start our travel in the world! This is a powerful Bitblt function.

Bitblt (read "Bit Blit") represents "Bit-block Transfer". The BLT originated from a combined language instruction that transmits the memory block on DEC PDP-10. The term "Bitblt" is used for the first time in the image is related to the SmallTalk system designed by Xerox Palo Alto Research Center (Parc). In SmallTalk, all graphics output operations use Bitblt. Crew writing sometimes uses BLT as verbs, for example: "THEN I WROTE Some Code to Blt the Happy Face to the Screen and Play A Wave File."

Bitblt is moving with a primitive, or (more specifically) is a bitmap map. You will see that the term "transfer" is the same as the Bitblt. This file actually executes primary gradation operations, and some interesting results can be generated.

Simple Bitblt

The Bitblt program shown in Equation 14-1 is copied to its display area for the functional table of the program system (located in the upper left corner of the program Windows) with a Bitblt function.

Program 14-1 bitbltbitbitblt.c / * ----------------------------------------- ----------------------------- Bitblt.c - Bitblt Demonstration (c) Charles Petzold, 1998 ------- -------------------------------------------------- ---------- * /

#include LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM); int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) {static TCHAR szAppName [] = TEXT ( "BitBlt"); HWND HWND; MSG msg; wndclass wndclass;

wndclass.style = CS_HREDRAW | CS_VREDRAW; wndclass.lpfnWndProc = WndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = hInstance; wndclass.hIcon = LoadIcon (NULL, IDI_INFORMATION); wndclass.hCursor = LoadCursor (NULL , IDC_ARROW); wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH); wndclass.lpszMenuName = NULL; wndclass.lpszClassName = szAppName;! if (RegisterClass (& wndclass)) {MessageBox (NULL, TEXT ( "This program requires Windows NT! "), szAppName, MB_ICONERROR); return 0;} hwnd = CreateWindow (szAppName, TEXT (" BitBlt Demo "), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL); ShowWindow (hwnd, iCmdShow ); UpdateWindow (HWND); While (GetMessage (& MSG, NULL, 0, 0)) {TranslateMessage (& MSG); DispatchMessage (& MSG);} return msg.wparam;}

LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {static int cxClient, cyClient, cxSource, cySource; HDC hdcClient, hdcWindow; int x, y; PAINTSTRUCT ps; switch (message) {case WM_CREATE: cxSource = GetSystemMetrics (SM_CXSIZEFRAME) GetSystemMetrics (SM_CXSIZE); cySource = GetSystemMetrics (SM_CYSIZEFRAME) GetSystemMetrics (SM_CYCAPTION); return 0; case WM_SIZE: cxClient = LOWORD (lParam); cyClient = HIWORD (lParam); return 0;

Case WM_Paint: hdcclient = beginpaint (hwnd, & ps); hdcwindow = getWindowdc (hwnd); for (y = 0; y

ReleaseDC (hwnd, hdcwindow); EndPaint (hwnd, & ps); return 0; case wm_destroy: postquitMessage (0); return 0;} return defWindowProc (hwnd, message, wparam, lparam);} But why only use a Bitblt? ? In fact, the Bitblt fills the display area with multiple copies illustrated by the system function table (in this case, the iDi_information icon in the information box), as shown in Figure 14-1.

Figure 14-1 Bitblt's screen display

The Bitblt function transmits a rectangular area in the contents of the "Source" to another device content called "Destination". The rectangular area of ​​the same size. The syntax of this franchise is as follows:

Bitblt (HDCDST, XDST, YDST, CX, CY, HDCSRC, XSRC, YSRC, DWROP); the contents of the destination device can be the same.

In the Bitblt program, the destination device content is the display area of ​​the window, and the device content code is obtained from the BeginPAint. The source device content is the entire window of the application, and this device content code is obtained from getWindowDC. Obviously, the contents of these two devices refer to the same actual device (video display). However, the coordinate origin of the two devices is different.

The XSRC and YSRC parameters indicate the coordinate position of the left upper left corner of the source image. In Bitblt, the two parameters are set to 0, indicating that the image from the source device content (that is, the entire window), the CX and CY parameters are the width and height of the image. BitBLT calculates these values ​​based on information obtained from the GetSytemmetrics.

The XDST and YDST parameters represent the coordinate position in the upper left corner of the copy image. In Bitblt, these two parameters are set to different values ​​for multiple times. For the first Bitblt call, the two parameters are set to 0, copy the image to the left upper corner position of the display area.

The last parameter of Bitblt is a bitmap mapping operating state. I will discuss this value shortly.

Note that Bitblt is transmitted from actual video to display memory transfers instead of other image transit from the system function table. If you move the Bitblt window to remove the screen, then adjust the size of the Bitblt window to make it heavy, then you will find a part of the Bitblt display area is part of the functional table. The Bitblt is no longer accessing the entire image.

In the Bitblt function, the contents of the destination device can be the same. You can rewrite the bitblt to make the WM_PAINT process execute the following:

Bitblt (HDCCLIENT, 0, 0, CXSource, Cysource, HDCWindow, 0, 0, Srcopy); for (y = 0; y 0 || y, cxsource, cysource, hdclient, 0, 0, srccopy);} This will produce the same effect as the Bitblt displayed in front, just display The upper left corner of the area is relatively blurred.

The maximum limit in Bitblt is that the contents of the two devices must be compatible. This means or one of them must be monochrome, or the number of bit elements having the same number of each of the two. All in all, you cannot use this method to copy certain graphics on the screen to the printer.

Stretch point

In the Bitblt function, the destination image is the same as the size of the source image, as the function is only two parameters to explain the width and height. If you want to stretch or compress the image size during replication, you can use the stretchblt file. The syntax of the StretchBLT function is as follows: stretchblt (HDCDST, XDST, YDST, CXDST, CYDST, HDCSRC, XSRC, YSRC, CXSRC, CYSRC, DWROP); this card adds two parameters. The current function contains the respective widths and heights of the purpose and source, respectively. The StretCH is displayed in the StretchBLT function, as shown in the formula 14-2.

Co-style 14-2 Stretchstretch.c / * ----------------------------------------- -------------------------------- Stretch.c - Stretchblt Demonstration (C) Charles Petzold, 1998 --- -------------------------------------------------- ----------------------- * /

#include LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM); int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) {static TCHAR szAppName [] = TEXT ( "Stretch"); HWND HWND; MSG msg; wndclass wndclass;

wndclass.style = CS_HREDRAW | CS_VREDRAW; wndclass.lpfnWndProc = WndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = hInstance; wndclass.hIcon = LoadIcon (NULL, IDI_INFORMATION); wndclass.hCursor = LoadCursor (NULL , IDC_ARROW); wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH); wndclass.lpszMenuName = NULL; wndclass.lpszClassName = szAppName;! if (RegisterClass (& wndclass)) {MessageBox (NULL, TEXT ( "This program requires Windows NT! "), szAppName, MB_ICONERROR); return 0;} hwnd = CreateWindow (szAppName, TEXT (" StretchBlt Demo "), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL); ShowWindow (hwnd, iCmdShow UpdateWindow (HWND);

While (GetMessage (& MSG, NULL, 0, 0)) {TranslateMessage (& MSG); DispatchMessage (& MSG);} return msg.wparam;}

LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {static int cxClient, cyClient, cxSource, cySource; HDC hdcClient, hdcWindow; PAINTSTRUCT ps; switch (message) {case WM_CREATE: cxSource = GetSystemMetrics (SM_CXSIZEFRAME) GetSystemMetrics; Cysource = GetSystemMetrics (SM_CysizeFrame) GetSystemMetrics; Return 0;

Case WM_SIZE: CXClient = loword (lparam); cyclient = HiWord (LPARAM); Return 0;

Case WM_Paint: hdcclient = beginpaint (hwnd, & ps); hdcwindow = getwindowdc (hwnd);

Stretchblt (HDCCLIENT, 0, 0, CXClient, Cyclient, HDCWindow, 0, 0, CxSource, Cysource, MergeCopy);

ReleaseDC (HWND, HDCWindow); EndPaint (HWND, & PS); Return 0;

Case WM_DESTROY: PostquitMessage (0); Return 0;} Return DEFWINDOWPROC (HWND, Message, WPARAM, LPARAM);} This program only calls the StretchBLT version once, but this purpose is filled with the system function table illustration. Area, as shown in Figure 14-2.

Figure 14-2 Screen of Stretch

All coordinates and sizes in Bitblt and StretchBLT functions are based on logical units. But when you define two different device content in the Bitblt function, the contents of these two devices have different mapping patterns, what will happen? If this happens, the result of call bitblt is not clear: CX and CY parameters are logical units, while they are also applied to the rectangular area in the content of the source device and the content of the destination device. All coordinates and dimensions must be converted to a device coordinate prior to actual bitmine. Because the CX and CY values ​​are used for the source and destination device content, this value must be converted to the device content yourself.

When the source and destination device contents, or when the contents of the two devices use the mm_text image mode, the rectangular size under the device unit is the same in the two device contents, and then the converted of the primary setting is performed by Windows. However, if the rectangular size under the unit unit is different in the contents of the two devices, Windows transfers this work to a more common STRETCHBLT function.

StretchBLT also allows horizontal or vertical flip images. If the CXSRC and CXDST tags (after converting into the device unit), then stretchblt creates a mirror: flip right left. In the StretCH program, you can do this by changing the XDST parameter to cxclient and change the CXDST parameter to -cxClient. If CysRC and Cydst are different, StretchBLT flips the image up and down. To test this in the StretCH program, you can change the YDST parameter to Cyclient and change the CYDST parameter to-cyclient.

StretChblt mode

Using StretchBLT will encounter some fundamental issues related to the size of the dot matrix size. When an extension is extended, the StretchBLT must copy the pattern row or column. If the magnification is not an integer multiple of the original map, then this operation will result in some distortion. If the destination rectangle is smaller than the source rectangle, the StretCHBLT must merge two rows (or columns) or multi-row (or column) to a row (or column) when narrowing the image. There are four ways to complete this operation, which selects one of the methods according to the device content extension mode properties. You can use the SetStRetchBltMode file to modify this property.

SetStretchBltMode (HDC, Imode); Imode can remove the column value:

BlackonWhite or Stretch_andscans (Contact) If two or more totsses are merged into one icon, then StretchBLT performs a logical AND operation of the icon. The result is that only all the original elements are white when it is white, and the actual significance is black in black. This applies to monochrome dot mapping in white background. WhiteonBLACK or Stretch_orscans If two or more totsses are merged into one icon, then the stretchblt performs a logical OR operation. This result is that only all of the original elements are black, which means that the color is determined by the white background. This applies to monochrome dot mapping in black backgrounds. Coloroncolor or Stretch_Deletescans CTRETCHBLT simply eliminates the pattern row or column without any logical combination. This is usually the best way to handle color dot mapping. Halftone or Stretch_HALFTONE Windows calculates the average color of the purpose based on the combined source colors. This will be used in combination with the half-tonal palette, and this procedure will be displayed in Chapter 16. Windows also includes GetStretchbltMode functions for obtaining current extension modes.

Bit mapping operation

Bitblt and Stretch have simply copied sources to the destination dot matrix, which may also be scaled during the process. This is the result of the last parameter of Bitblt and StretchBLT functions. Srccopy is only one of the 256 bitmaps in these functions that you can use in these functions. Let's take a differential experiment in the StretCH program, then researcically study the bitmap map operation.

Try to use NotsrcCopy instead of Srccopy. Like them, the bit element mapping operation transforms its colors when copying the point mapping. In the display area window, all color conversion: black turns into white, white turns black, blue turns yellow. Now try SRCINVERT, you will get the same effect. If Blackness is trying, just as its name, the entire display area will become black, while Whiteness makes it white.

Now try the following three narratives instead of STRETCHBLT calls:

SelectObject (HDCCLIENT, CREATEHATCHBRUSH (HS_Diagcross, RGB (0, 0, 0))); Stretchblt (HDCClient, 0, 0, CxClient, Cyclient, HDCWindow, 0, 0, CxSource, Cysource, MergeCopy);

DeleteObject (HDCCLIENT, GETSTOCKOBJECT (White_brush)); this time, you will see a diamond painting brush on the image, what is this?

I said earlier, Bitblt and StretchBLT functions are not simple bit block transmissions. This one is actually executed between the following three images.

Source source point mapping, stretching or compression (if necessary) to the dimension of the destination. Destination rectangle before the Bitblt or StretchBLT call. Pattern is selected in the destination device, level or vertically to the destination rectangle. The result is copied into the destination rectangle. The bitmap mode is similar to what we encountered in Chapter 5. The drawing mode uses the control item of the image object, such as a line to combine a purpose. We know that there are 16 drawing modes - that is, when 0 and 1 in the objects are drawn, the only result is the combination of 0 and 1 in the purpose of the purpose.

The bitmap operation using BitBLT and STRETCHBLT includes combining three objects, which will generate 256 bitmap operations. There are 256 ways to combine sources, destination dot mapping and patterns. There are 15 types of metadam maps have been named - some of these names are actually not clear clear to its meaning - they are defined in Wingdi.h, and the rest are values, listed in / platform SDK / GRAPHICS AND MULTIMEDIA SERVICES / GDI / Raster Operation Codes / Ternary Raster Operations.

15 ROP code with name is shown in Table 14-4.

Table 14-4

Pattern (P): 1 1 1 1 0 0 0 0 Source (s): 1 1 0 0 1 1 0 0

Purpose (D): 1 0 1 0 1 0 1 0 Balin operation ROP code name Results: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 ~ (s | d) 0x1100A6 NotSrcerase 0 0 1 1 0 0 1 1 ~ S 0x330008 NotSrcopy 0 1 0 0 0 0 0 0 SRCERase 0 1 0 1 0 1 0 1 ~ D 0x550009 Dstinvert 0 1 0 1 0 1 0 P ^ D 0x5a0049 Patinvert 0 1 1 0 0 1 1 0 s ^ D 0x660046 Srcinvert 1 0 0 0 0 0 0 0 S & D 0x8800C6 Srcand 1 0 1 1 0 1 1 ~ S | D 0xBB0226 MergePaint 1 1 0 0 0 0 0 0 P & S 0xC000CA MergeCopy 1 1 0 0 1 0 0 s 0xcc0020 SRCCopy 1 1 1 0 1 1 0 S | D 0xee0086 SrcPaint 1 1 1 0 0 0 0 p 0xF00021 PATCopy 1 1 1 1 0 1 1 P | ~ S | D 0xfb0a09 Patpaint 1 1 1 1 1 1 1 1 0xff0062 Whiteness

This form is very important for understanding and using bit yuan mapping operation, so we should take a time to study.

In this form, the value of the "ROP code" line will be passed to the last parameter of Bitblt or StretchBLT; the value in the "Name" line is defined in Wingdi.h. The low character group assistance device driver of the ROP code is mapped. The high character is between 0 and 255. This value is the same as the bit element of the pattern of the second column, which is the result of the bit element operation between the pattern, source, and the destination displayed on the top. "Bulin Computing" column is a combination of the pattern, source and purpose in the C syntax.

To start understanding this table, the easiest way is to assume that you are working with a monochrome system (1 bit per image) where 0 represents black, 1 represents white. The result of the Blackness operation is whether it is a source, destination, and pattern, all of which is zero, so the purpose will be displayed. Similarly, Whiteness always leads to a look at the purpose. Now assume that you use the bit yuan mapping to operate PATCopy. This causes the result bit element to be the same as the pattern, and ignores the source and the target point of the target. In other words, PATCopy simply copies the current pattern to the destination rectangle.

The PATPAINT bitmap operation contains a more complex operation. The result is the same as between the pattern, the purpose, and the source of the reverse. When the source point line is black (0), the result is always white (1); when the source is white (1), as long as the pattern or purpose is white, the result is white. In other words, only the source is white and the pattern and the purpose are black, the result is black.

Multiple bits are used each of the compacts when color display. BitBLT and StretchBLT functions provide bitmore operations for each color bit. For example, if the purpose is to be red, the SrcPaint bitmap is mapped to magenta. Note that the operation is actually performed in the bit element stored in the display card. The colors corresponding to these positions depends on the setting of the toner disc of the display card. Windows completed this, so that the bitmap mapping operation can meet the results you expected. However, if you modify the palette (I will discuss this chapter 16), the bitmap map will generate unpredictable results.

For applications with better bitmap operation, see the "Non-Ramp Over-Draw Image" section later in this chapter.

Pattern BLT

In addition to Bitblt and Stretchblt, Windows also includes a function called PATBLT (Pattern Block Transfer: Pattern Block Transfer "). This is the simplest in three "BLT" functions. Unlike Bitblt and StretchBLT, it only uses one destination device content. Patblt syntax is:

PATBLT (HDC, X, Y, CX, CY, DWROP); X, Y, CX and CY parameters are located in logical units. The logical point (x, y) specifies the upper left corner of the rectangle. The rectangular width is a CX unit, which is a CY unit. This is a rectangular area modified by Patblt. The logical operation of the PATBLT is determined by the DWROP parameter, which is the subset of the ROP code. The following table lists the 16-bit mapping operations for PATBLT support:

Table 14-5

Pattern (P): 1 1 0 0 Purpose (D): 1 0 1 0 Balf Forest Operation ROP Code Name Results: 0 0 0 0 0 0 0 0 1 ~ (P | D) 0x0500A9 0 0 1 0 ~ P & D 0x0a0329 0 0 1 1 ~ p 0x0f0001 0 1 0 0 P & ~ D 0x500325 0 1 0 1 ~ d 0x550009 Dstinvert 0 1 1 0 p ^ d 0x5a0049 Patinvert 0 1 1 1 ~ (p & d) 0x5f00e9 1 0 0 0 p & d 0xa000c9 1 0 0 1 ~ (p ^ d) 0xa50065 1 0 1 0 d 0xaa0029 1 0 1 1 ~ P | d 0xaf0229 1 1 0 0 p 0xf00021 PATCOPY 1 1 0 1 P | ~ d 0xf50225 1 1 1 0 p | d 0xfa0089 1 1 1 1 0xFF0062 Whiteness The following lists some more common uses. If you want to draw a black rectangle, you can call

PATBLT (HDC, X, Y, CX, CY, Blackness); to draw a white rectangle, please

PATBLT (HDC, X, Y, CX, CY, WHITENESS);

PATBLT (HDC, X, Y, CX, CY, DSTINVERT); used to change the color of the rectangle. If you choose White_brush in the current device content, then a function

PATBLT (HDC, X, Y, CX, Cy, Patinvert); also changes the rectangle.

You can call the FillRect letter again to fill a rectangular area with a brush:

FillRect (HDC, & Rect, Hbrush); FillRect function is the same as the following code:

Hbrush = SelectObject (HDC, Hbrush); Patblt (HDC, Rect.Lect, Rect, Rect.right - Rect.top, Rect.Bottom - Rect.top, Patcopy; SelectObject (HDC, Hbrush); actually, This program code is Windows to perform the action of the FillRect function. If you call

InvertRect (HDC, & Re); Windows converts it into a function:

PATBLT (HDC, Rect.Lect, Rect.top, Rect.Right - Rect.top, Rect.bottom - Rect.top, Dstinvert); when introducing the syntax of the PATBLT, I said, I've said that The upper left corner of the rectangle, and this rectangle width is the CX unit, the height is CY unit. This narrative is not completely correct. Bitblt, Patblt and StretchBLT are the most suitable GDI drawing figures that specify the logical corner coordinate based on the logical width and height of the logical width and height from one angle. All other GDI drawing functions for rectangular borders are required to specify the coordinates according to the coordinates of the upper left corner and the lower right corner. For MM_Text mapping mode, the PATBLT parameters described above are correct. However, it is incorrect for the mapping mode of the metric. If you use a CX and CY value, the points (x, y) will be the lower left corner of the rectangle. If the desired point (x, y) is the upper left corner of the rectangle, then the CY parameter must be set to the negative height of the rectangle.

If you want more accurate, modify the color of the color with PATBLT will obtain the logical width through the absolute value of the CX, and the logic height is obtained by the absolute value of CY. These two parameters can be negative. A rectangle is defined by the two corners given by logical points (x, y) and (x cx, y cy). The upper left corner of the rectangle usually belongs to the area modified by PATBLT. The range of rectangles is exceeded in the upper right corner. According to the mapping mode and the symbol of the CX, the CY parameter, the point in the upper left corner of the rectangle is (x, y), (x, y cy), (x cx, y) or (x cx, y cy). If you set a mapping mode for mm_loenglish, and you want to use Patblt on a small square in the upper left corner of the display area, you can use

PATBLT (HDC, 0, 0, 100, -100, DWROP); or

PATBLT (HDC, 0, -100, 100, 100, DWROP); or

PATBLT (HDC, 100, 0, -100, -100, DWROP); or

PATBLT (HDC, 100, -100, -100, 100, DWROP); the easiest way to set the correct parameter to the PATBLT is to set the X and Y to the upper left corner of the rectangle. If the mapping mode definition is increased as the upward scroll display, use a negative CY parameter. If the mapping mode defines the X coordinate to the left (very useful), the negative CX parameter is required.

GDI dot matrix object

I have mentioned in front of this chapter that Windows supports GDI dot matrix objects from 1.0. Because the device is not related to the device, the GDI dot matrix object is sometimes referred to as a device-related point array, or DDB. I try not to collect the full text of Device-Dependent Bitmap because it looks similar to Device-Independent Bitmap. Abbreviation DDB will be better because we can easily distinguish it from DIB.

For program writers, existing dot matrix maps are more confusing from Windows 3.0. Many experienced Windows program writers cannot accurately understand the relationship between DIB and DDB. (I am afraid the WINDOWS 3.0 version of this book cannot clarify this issue). It is true that DIB and DDB are related to many aspects: DIB and DDB can be converted to each other (although some information will be lost in the conversion program). However, DIB and DDB are not replaced with each other and cannot simply select a method to represent the same visual information.

If we can assume that DIB will definitely replace DDB, it will be convenient. But the reality is not the case, DDB also plays a very important role in Windows, especially when you care about the performance performance.

Establish DDB

DDB is one of the graphical objects of the Windows graphics device (which also includes drawing pen, brush, font, Metafile, and toner). These graphics objects are stored inside the GDI module, referenced by the application software in a code number. You can store the DDB code in a hbitmap ("Handle To A Bitmap: Dot Mapping Code") variable, for example:

Hbitmap hbitmap; then get a code by calling DDB, for example: CreateBitmap. These functions are configured and initialize some memories in the GDI memory to store information about the dot matrix map, as well as information on the actual point-in-line chart. This memory cannot be accessed directly. The dot matrix is ​​not related to the content of the device. After using the point of use, it is necessary to clear this memory:

DeleteObject (hbitmap); If you execute, you use DDB, you can complete the above operation when you terminate. The CreateBitmap is as follows:

Hbitmap = CreateBitmap (CX, CY, CPLANES, CBITSPIXEL, BITS); the first two parameters are the width and height of the dot matrix (in the primary unit), the third parameter is the number of color surfaces, the fourth parameter is The number of bit elements per status, the fifth parameter is a indicator of a bit element array stored in a specific color format, and an image is stored in the array to initialize the DDB. If you don't want to initialize DDB with an existing image, you can set the last parameter to NULL. You can still set the contents of the DDB in the future.

When you use this one, Windows also allows you to create specific type GDI dot matrix objects you like. For example, suppose you want a bit of a map wide 7 primitives, high 9 numerals, 5 color bitmography, and each of the 1st dollars, you only need to perform the following:

Hbitmap = CreateBitmap (7, 9, 5, 3, null); At this time, Windows will give you a valid dot matrix code.

During this functions, Windows will save you through the information you passed to the function and configure the memory for the icon element. The rough calculation is this point of view of 7 × 9 × 5 × 3, which is 945-bit yuan, which requires more than the 118-bit tuple.

However, Windows is a dot mapping to configure the memory, and each line of ambiguity takes up many coherent bits.

iWidthbytes = 2 * ((CX * CBITSPIEL 15) / 16); or C programmaker is more inclined to write:

iWidthBytes = (CX * CBITSPIEL 15) & ~ 15) >> 3; Therefore, the memory configured for DDB is:

ibitmapBytes = cy * cplanes * iWidthbytes; in this case, iWidthbytes accounts for 4-bit group, and IBITMapBytes accounts for 180-bit groups.

Now, I know that a dot matrix has 5 color bitmas, what is the meaning of each image for 3 color? It's really a ghost, which can't even call it as an exercise job. Although you have configured some memory inside the GDI and make these memories have a certain structure, you can't do any useful thing.

In fact, you will call CreateBitmap with the parameters of the two types.

CPLANES and CBITSPIXEL are equal to 1 (represents monochrome dot mapping); or Cplanes and CBITSPixel are equal to values ​​for a particular device content, you can use the Planes and BitSpixel indexes to get from the getDeviceCaps. More realistic cases, you will only call createBitmap in the first case. For the second case, you can simplify the problem with CreateCompatibleBitmap:

Hbitmap = CreateCompatibleBitmap (HDC, CX, CX); This file has established a dot matrix map with the device, and the device content code of this device is given by the first parameter. CreateCompaTibleBitmap uses the device content code to get getDeviceCaps information, and then pass this information to createBitmap. In addition to the same memory tissue in addition to the actual device content, the DDB and the device content do not have other contacts.

The CreateDiscardableBitMap function is the same as the parameters of CreateCompaBitMap, and the function is functionally. In early Windows versions, CreateDiscardableBitmap created dot matrix can be cleared from the memory when the memory is reduced, and then re-buys a point-of-point map data. The third dot matrix is ​​created in the CreateBitMapIndirect:

Hbitmap CreateBitmapIndirect (& Bitmap); where Bitmap is the structure of the Bitmap. The Bitmap structure is defined as follows:

typedef struct _tagBITMAP {LONG bmType; // set to 0LONG bmWidth; // width in pixelsLONG bmHeight; // height in pixelsLONG bmWidthBytes; // width of row in bytesWORD bmPlanes; // number of color planesWORD bmBitsPixel; // number of bits Per PixellPvoid ​​Bmbits; // Pointer to Pixel Bits} Bitmap, * Pbitmap; You do not need to set the BMWidthbytes field when you call the createBitMapIndirect. Windows will calculate you, you can also set the BMBITS field to null, or set to the primitive diome site for initial dot mapping.

The BitMap structure is also used in the GetObject function, first defining a structure of a Bitmap type.

Bitmap Bitmap; and call the fifth as follows:

GetObject (Hbitmap, Sizeof (Bitmap), & Bitmap; Windows will populate the Bitmap structure with dot mapping information, but the BMBITS field is equal to NULL.

You finally call DeleteObject to clear all the points created within the program.

Dot matrix chamber

When you create a device-related GDI dot matrix object with CreateBitmap or CreateBitmapIndirect, you can specify an indicator to the dot matrix graphic. Or you can also let the dot matrix last. After establishing a dot mapping, Windows also provides two functions to obtain and set the icon.

To set a chamber bit, please call:

SetBitmapBits (Hbitmap, CBYTES, & BITS); GetBitmapBits Versions have the same syntax:

GetBitmapBits (HbitMap, CBytes, & Bits); in these two functions, Cbytes indicate the number of bit groups to be copied, and BITS is a minimum Cbytes size buffer.

The icon in the DDB is arranged from the top column. I have said before, the number of bit yuan groups per column is even. In addition, there is nothing to explain. If the point is monochrome, that is, it has 1 position element and each of the 1-bit yuan, each of the icons is not 1. The leftmost chamber per column is the bit element of the highest bit of the first bit element group. After we finish how to display monochrome DDB after this chapter, we will make a monochrome DDB.

For non-monochrome dot mapping, you should avoid the situation you need to know the meaning of the icon. For example, assume that Windows is executed on the VGA of 8-bit colors, you can call CreateCompATIBLEBITMAP. With GetDeviceCaps, you can determine that you are working with a device with a color bit or 8-bit dollar per status. A bit tuple stores a look. But what does the primary 0x37 mean? It is obvious to some colors, but what color is it?

The icint actually does not involve any fixed color, it is just a value. DDB has no color table. The key to the problem is what the color of the icon is made when the DDB is displayed on the screen. It is definitely a certain color, but what color is it? The displayed icon will be related to the RGB color represented by the 0x37 index value represented by the color palette on the display card. This is the device dependence you have encountered. However, don't just just because we don't know the meaning of the iconic value, it is assumed that non-monochrome DDB is useless. We will briefly look at their use. Next chapter, we will see how the setBitmapBits and getBitmapBits functions are more useful for setDibits and getDibits cards.

Therefore, the basic rules are like this: do not use createBitMap, createBitMapIndirect or setBitMapBits to set the color DDB bit elements, you can only use these functions to set the bit elevation of the monochrome DDB. (If you get a bit in the DDB in other identical formats during the call getBitMapBits, then these rules are exceptions.

Before you continue, let me discuss SetBitmapDimensionex and getBitmapDimensionex. These functions allow you to set (and get) the measurement dimensions of the dot matrix map (in 0.1 mm). These information is stored in GDI with the dot matrix resolution, but not for any operation. It is just a measurement dimension with DDB.

Memory device content

The next concept we must solve is the content of memory device. You need to process the GDI dot matrix object with the content of the memory device.

Typically, the device content refers to a special graphics output device (eg, a video display or a printer) and its device driver. The memory device content is only in the memory, it is not a real graphic output device, but it can be said to "compatible" with the specified real device.

To establish a memory device content, you must first have the device content code of the actual device. If you are HDC, you can build a memory device as so as follows:

HDCMEM = CREATECOMPALDC (HDC); Usually, a functional call is easier than this. If you set the parameters to null, Windows will create a memory device content that is compatible with the video display. Any memory device content established by the application is ultimately cleared by calling deletaDC.

The memory device content has the same display plane as the actual bitmap mapping device. However, the initial display plane is very small - monochrome, 1 grain wide, 1 grain high. The display plane is a single element alone.

Of course, you cannot do more work with a 1-bit display plane, so the next step is to expand the display plane. You can do this by selecting a GDI dot matrix object to the memory device content, for example:

SelectObject (HDCMEM, HBitmap); This card is the same as you bring a brush, brush, font, region, and color panel to select the device content. However, the content of the memory device is the only device content type that you can select in the point line. (If you need, you can also select other GDI objects to the memory device content.)

The selectobject will only work when the dot matrix selects the content of the memory device is monochrome, or when there is the same color organization as the memory device content. This is also a reason why the special DDB (eg, 5 positions, and 3 per numerals) is not used.

Now that the situation is this: after the SelectObject call, the DDB is the display plane of the memory device content. Each operation of processing the content of the actual device can be used for the content of the memory device. For example, if the plot in the memory device content is drawn with the GDI drawing, the image will draw on the dot matrix. This is very useful. The memory device content can also be called Bitblt as a source of content. This is a method of drawing a dot mapping on a display. If the content of the video device is used as the source, the contents of the memory device are used as the purpose, then the call bitblt can copy some of the contents on the screen to the dot matrix. We will see that these are possible. Load dot mapping resources

Another way to obtain the GDI dot matrix item code is to call the loadbitmap. Using this file, you don't have to worry about the dot mapping format. In the program, you only need to set up a dot mapping by resources, which is similar to the method of establishing an illustration or a mouse cursor. The syntax of the Loadbitmap is the same as Loadicon and LoadCursor:

HbitMap = loadingBitmap (Hinstance, Szbitmapname); if you want to load the system dot matrix, set the first parameter to NULL. These different dot matrix are a small part of the Windows visual interface (e.g., closed squares and check mark), and their identifier begins with the letter OBM. If the point array is associated with an integer identification, the second parameter can use the MakeintResource for the MakeintResource. All dot mappings loaded by Loadbitmap finally apply DeleteObject clearance.

If the point-of-picture resource is monochrome, the code from the LoadBitmap will point to a monochrome dot matrix object. If the point-of-picture resource is not monochrome, the code from LoadBitmap will point to a GDI dot matrix, which has the same color organization with the executable video display. Therefore, the dot matrix is ​​always compatible with the video display and always selects the contents of the memory device compatible with the video display. After using the loadbitmap call, you don't have to worry about any color conversion. In the next chapter, we know that the specific operation of loadbitmap.

The bricks1 shown in the formula 14-3 demonstrates the method of loading a small sheet of monochrome dot mapping resources. This picture is not like a brick, but when it is horizontal and vertical, it is similar to the brick wall.

Program 14-3 bricks1 bricks1.c / * ----------------------------------------- -------------------------------- BRICKS1.C - Loadbitmap Demonstration (C) Charles Petzold, 1998 --- -------------------------------------------------- ----------------------- * /

#include LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM); int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) {static TCHAR szAppName [] = TEXT ( "Bricks1"); HWND HWND; MSG msg; wndclass wndclass;

wndclass.style = CS_HREDRAW | CS_VREDRAW; wndclass.lpfnWndProc = WndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = hInstance; wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION); wndclass.hCursor = LoadCursor (NULL , IDC_ARROW); wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH); wndclass.lpszMenuName = NULL; wndclass.lpszClassName = szAppName;! if (RegisterClass (& wndclass)) {MessageBox (NULL, TEXT ( "This program requires Windows NT! "), szAppName, MB_ICONERROR); return 0;} hwnd = CreateWindow (szAppName, TEXT (" LoadBitmap Demo "), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL); ShowWindow (hwnd, iCmdShow UpdateWindow (HWND);

While (GetMessage (& MSG, NULL, 0, 0)) {TranslateMessage (& MSG); DispatchMessage (& MSG);} return msg.wparam;}

LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {static HBITMAP hBitmap; static int cxClient, cyClient, cxSource, cySource; BITMAP bitmap; HDC hdc, hdcMem; HINSTANCE hInstance; int x, y; PAINTSTRUCT ps; Switch (Message) {copy wm_create: hinstance = ((lpcreatestruct) lparam) -> Hinstance;

Hbitmap = loadingBitmap (Hinstance, Text ("bricks"));

GetObject (Hbitmap, Sizeof (Bitmap), & Bitmap

CXSource = Bitmap.bmwidth; cysource = bitmap.bmHeight;

Return 0;

Case WM_SIZE: CXClient = loword (lparam); cyclient = HiWord (LPARAM); Return 0;

Case WM_Paint: HDC = BeginPaint (HWND, & PS);

HDCMEM = CREATECOMPATIPLEDC (HDC); SELECTOBJECT (HDCMEM, HBitmap);

For (y = 0; y

/// BitmapBricks Bitmap Discardable "Bricks.bmp" bricks.bmp

When establishing a dot mapping in Visual C Developer Studio, it should refer to the height and width of the map, which is 8 stages, which is monochrome, name is "bricks". The Bricks1 program has loaded a dot matrix map during WM_CREATE message processing and use GetObject to determine the status of the dot mapping (so that the point array is not 8 graphic time "can continue to work). In the future, Bricks1 will delete this picture in the WM_DESTROY message.

During the WM_PAINT message processing, Bricks1 establishes a memory device content compatible with the display, and selects a dot matrix. Then, from the memory device content to the display area device content a series of Bitblt functions, then delete the contents of the memory device. Figure 14-3 shows the execution result of the program.

By the way, the bricks.bmp file established by developer studio is a device-independent point picture. You may want to create a colored bricks.bmp file within Developer Studio (you can choose your own colors), and ensure that everything works fine.

We see that DIB can be converted into a GDI dot matrix object compatible with the video display. We will see how this is operating in the next chapter.

Figure 14-3 Show of bricks1

Monochrome dot mapping format

If you are handling small block monochrome images, you don't have to build them as a resource. Unlike the color dot matrix object, the format of the monochrome is relatively simple, and almost all from the images you want to build. For example, suppose you want to create a dot matrix map shown in the figure:

You can write a series of bit yuan (0 represents black, 1 represents white), which correspond directly to the grid. Read these bitmines from left to right, you can configure a segment value value for each 8-bit yuan group. If the width of the point is not a multiple of 16, the zero is filled with zero on the right side of the bit ing group to obtain an even number of groups:

0 1 0 1 0 0 0 1 0 1 1 0 1 1 0 0 0 1 = 51 77 10 000 1 0 1 0 1 1 1 0 1 1 1 0 1 1 0 1 0 1 = 57 77 50 000 0 0 1 0 0 1 1 0 1 1 0 1 1 1 0 1 0 1 = 13 77 50 000 1 0 1 0 1 1 0 1 1 1 0 1 1 1 0 1 0 1 = 57 77 50 000 1 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 = 51 11 1000 The pot is 20, the scan line is 5, and the bit element set is 4. You can set the Bitmap structure of this point of this point in the following description: static bitmap bitmap = {0, 20, 5, 4, 1, 1}; and can store the bit in the Byte array:

Static byte bits [] = {0x51, 0x77, 0x10, 0x00, 0x57, 0x77, 0x50, 0x00, 0x13, 0x77, 0x77, 0x00, 0x00, 0x51, 0x11, 0x00, 0x51, 0x11, 0x10, 0x00}; with CreateBitmapIndirect) To create a point of view, you need the following two narratives:

BitMap.Bmbits = (PSTR) Bits; hbitmap = createBitmapIndirect (& Bitmap); another method is:

HbitMap = CreateBitMapindirect (& Bitmap); SetBitmapBits (Hbitmap, SizeOf Bits, Bits); You can also use a narrative to create a dot mapping:

Hbitmap = CreateBitmap (20, 5, 1, 1, bits); Bricks2 displayed in the program 14-4 utilizes this technology directly to create brick dot matrix, without using resources.

Co-style 14-4 bricks2bricks2.c / * --------------------------------------------------------------------------------------- -------------------------------- BRICKS2.C - CreateBitmap Demonstration (C) Charles Petzold, 1998 --- -------------------------------------------------- ---------------------- * /

#include LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM); int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) {static TCHAR szAppName [] = TEXT ( "Bricks2"); HWND HWND; MSG msg; wndclass wndclass;

wndclass.style = CS_HREDRAW | CS_VREDRAW; wndclass.lpfnWndProc = WndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = hInstance; wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION); wndclass.hCursor = LoadCursor (NULL , IDC_ARROW); wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH); wndclass.lpszMenuName = NULL; wndclass.lpszClassName = szAppName;! if (RegisterClass (& wndclass)) {MessageBox (NULL, TEXT ( "This program requires Windows NT! "), szAppName, MB_ICONERROR); return 0;} hwnd = CreateWindow (szAppName, TEXT (" CreateBitmap Demo "), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);

ShowWindow (hwnd, icmdshow); UpdateWindow (HWND);

While (GetMessage (& MSG, NULL, 0, 0)) {TranslateMessage (& MSG); DispatchMessage (& MSG);} return msg.wparam;}

Lresult Callback WndProc (HWND HWND, UINT MESSAGE, WPARAM WPARAM, LPARAM LPARAM) {Static Bitma Pbitmap = {0, 8, 8, 2, 1, 1}; Static Byte Bits [8] [2] = {0xFF, 0, 0x0c, 0, 0x0c, 0, 0x0c, 0, 0xc0, 0, 0xc0, 0}; static hbitmap hbitmap; static int CxClient, Cyclient, cxsource, cysource; hdc HDC, HDCMem; Int x , y; PAINTSTRUCT ps; switch (message) {case WM_CREATE: bitmap.bmBits = bits; hBitmap = CreateBitmapIndirect (& bitmap); cxSource = bitmap.bmWidth; cySource = bitmap.bmHeight; return 0;

Case WM_SIZE: CXClient = loword (lparam); cyclient = HiWord (LPARAM); Return 0;

Case WM_Paint: HDC = BeginPaint (HWND, & PS);

HDCMEM = CREATECOMPATIPLEDC (HDC); SELECTOBJECT (HDCMEM, HBitmap);

For (y = 0; y

Case WM_DESTROY: DeleteObject (HbitMap); PostquitMessage (0); Return 0;} Return DefWindowProc (HWND, Message, WPARAM, LPARAM);} You can try a similar article similar to color dot mapping. For example, if your video display is executed in 256 color mode, you can define each of the color bricks according to Table 14-2. However, this program code does not work when the program is executed in other display mode. The color dot mapping is handled in a manner that needs to use the DIB discussed in the next seal.

Painted brush

The last item of the Bricks series is Bricks3, as shown in the formula 14-5. At first glance, you may have this feeling: Where is the program code?

Co-style 14-5 bricks3bricks3.c / * ----------------------------------------- -------------------------------- Bricks3.c - createpatternbrush demonstration (c) Charles Petzold, 1998 ---- -------------------------------------------------- --------------------- * /

#include LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM); int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) {static TCHAR szAppName [] = TEXT ( "Bricks3"); Hbitmap hbitmap; hbrush hbrush; hwnd hwnd; msg; wndclass wndclass;

HBitmap = loadingBitmap (Hinstance, Text ("bricks")); hbrush = creagepatternbrush (hbitmap); deleteObject (hbitmap);

wndclass.style = CS_HREDRAW | CS_VREDRAW; wndclass.lpfnWndProc = WndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = hInstance; wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION); wndclass.hCursor = LoadCursor (NULL , IDC_ARROW); wndclass.hbrBackground = hBrush; wndclass.lpszMenuName = NULL; wndclass.lpszClassName = szAppName; (! RegisterClass (& wndclass) if) {MessageBox ( "! This program requires Windows NT" NULL, TEXT (), szAppName, MB_ICONERROR ); return 0;} hwnd = CreateWindow (szAppName, TEXT ( "CreatePatternBrush Demo"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL); ShowWindow (hwnd, iCmdShow); UpdateWindow (hwnd) ;

While (GetMessage (& MSG, NULL, 0, 0)) {TranslateMessage (& MSG); DispatchMessage (& MSG);

DeleteObject (Hbrush); Return Msg.wParam;}

LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {switch (message) {case WM_DESTROY: PostQuitMessage (0); return 0;} return DefWindowProc (hwnd, message, wParam, lParam);} BRICKS3.RC (Excerpt) // Microsoft Developer Studio Generated Resource Script. # Include "resource.h" #include "afxres.h"

/// BitmapBricks Bitmap Discardable "bricks.bmp" This program uses the same bricks.bmp file with Bricks1, and the window looks the same.

As you can see, there is no more content in the window message processing program. Bricks3 actually uses brick patterns as a window category background, which is defined in the HBRBackground field of the WNDCLASS structure.

You may now guess the GDI painting brush is a small drawings, usually 8 chambers. If you set the LBStyle field of the Logbrush structure to BS_Pattern, then call createPatternbrush or createbrushindirect, you can create a painting brush outside of the dot mapping. This image is at least 8 compacts of each wide. If it is big, Windows 98 will use only the top left corner of the dot matrix as a painting. Windows NT is not subject to this limit, which uses the entire dot mapping.

Keep in mind that the paintings and dot matrix are GDI objects, and you should delete you before you terminate you create a brush and dot matrix. If you establish a painted brush based on a point of view, Windows will replicate the dot matrix to the area drawn by the copy point. After calling createPatternbrush (or createbrushIcture, you can immediately delete the dot mapping without affecting the brush. Similarly, you can also delete the painting brush without affecting the original point of your choice. Note that Bricks3 deletes the dot matrix after the creation of the painted brush, and deletes the painting before the program termination. Draw a picture

When drawing in the window, we have used the dot mapping as a plot source. This requires the first to select the dot matrix to the memory device, and call Bitblt or StretchBLT. You can also use the memory device content code as the first parameter in the GDI card of all actual calls. The operation of the memory device content is the same as that of the actual device, unless the display plane is a dot matrix.

The Hellobit shown in the formula 14-6 showed this technology. The program displays strings "Hello, World!" On a small pattern, and then execute Bitblt or StretchBLT from the dot matrix to program display area.

Code 14-6 HellobitHellobit.c / * --------------------------------------- ------------------------------ Hellobit.c - Bitmap Demonstration (c) Charles Petzold, 1998 ------ -------------------------------------------------- ----------------- * /

#include #include "resource.h"

LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM); int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) {static TCHAR szAppName [] = TEXT ( "HelloBit"); HWND hwnd; MSG msg; WNDCLASS WNDCLASS;

wndclass.style = CS_HREDRAW | CS_VREDRAW; wndclass.lpfnWndProc = WndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = hInstance; wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION); wndclass.hCursor = LoadCursor (NULL , IDC_ARROW); wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH); wndclass.lpszMenuName = szAppName; wndclass.lpszClassName = szAppName;! if (RegisterClass (& wndclass)) {MessageBox (NULL, TEXT ( "This program requires Windows NT! "), szAppName, MB_ICONERROR); return 0;} hwnd = CreateWindow (szAppName, TEXT (" HelloBit "), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL); ShowWindow (hwnd, iCmdShow) UpdateWindow (HWND);

While (GetMessage (& MSG, NULL, 0, 0)) {TranslateMessage (& MSG); DispatchMessage (& MSG);} return msg.wparam;}

LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {static HBITMAP hBitmap; static HDC hdcMem; static int cxBitmap, cyBitmap, cxClient, cyClient, iSize = IDM_BIG; static TCHAR * szText = TEXT ( "Hello, world ! "); HDC HDC; HMENU HMENU; INT X, Y; PAINTSTRUCT PS; SIZE SIZE; SWITCH (Message) {Case WM_CREATE: HDC = Getdc (HWND); HDCMEM = CreateCompAMPLEDC (HDC);

GettextExtentPoint32 (HDC, Sztext, Lstrlen (Sztext), & size); cxbitmap = size.cx; cybitmap = size.cy; hbitmap = createcompatiblebitMap (HDC, CXBitmap, cybitmap);

ReleaseDC (HWND, HDC);

SelectObject (HDCMEM, HBitmap); Textout (HDCMEM, 0, 0, Sztext, Lstrlen (Sztext)); Return 0;

Case WM_SIZE: CXClient = loword (lparam); cyclient = HiWord (LPARAM); Return 0;

case WM_COMMAND: hMenu = GetMenu (hwnd); switch (LOWORD (wParam)) {case IDM_BIG: case IDM_SMALL: CheckMenuItem (hMenu, iSize, MF_UNCHECKED); iSize = LOWORD (wParam); CheckMenuItem (hMenu, iSize, MF_CHECKED); InvalidateRect (hwnd, null, true); break;} return 0;

Case WM_Paint: HDC = BeginPaint (HWND, & PS);

Switch (isize) {Case IDM_BIG: Stretchblt (HDC, 0, 0, CxClient, Cyclient, HDCMEM, 0, 0, CXBitmap, Cybitmap, Srccopy); Break;

CASE IDM_SMALL: FOR (Y = 0; Y

Endpaint (hwnd, & ps); Return 0;

case WM_DESTROY: DeleteDC (hdcMem); DeleteObject (hBitmap); PostQuitMessage (0); return 0;} return DefWindowProc (hwnd, message, wParam, lParam);} HELLOBIT.RC (excerpt) // Microsoft Developer Studio generated resource script. #include "resource.h" #include "afxres.h"

/// MenuHELLOBIT MENU DISCARDABLE BEGINPOPUP "& Size" BEGINMENUITEM "& Big", IDM_BIG, CHECKEDMENUITEM "& Small", IDM_SMALLENDENDRESOURCE.H (excerpt) // Microsoft Developer Studio generated include file.// Used by HelloBit.rc

#define idm_big 40001 # define IDM_SMALL 40002 starts from the call gettextExtentPoint32 determines the status of the string begins. These dimensions will be a dot matrix size with a compatible with video. When this point is selected into the memory device content (also compatible with the video display), then call Textout displays the text on the dot matrix. The memory device content is retained during program execution. During the processing of WM_DESTROY information, Hellobit deletes the contents of the dot matrix and the memory device.

One of the Hellobit is allowed to display the size of the point mapping, or the actual size of the horizontal and vertical direction in the display area, or the size of the display area size, as shown in Figures 14-4. Just as you see, this is not a good way to show large-size characters! It is just a small font to enlarge and have a sawtooth line generated when zoomed.

Figure 14-4 Sound of Hellobit Shows

You may want to know a program, such as Hellobit, whether you need to handle WM_DISPLAYCHANGE messages. As long as the user (or other application) modifies the video display size or color depth, the application receives this message. The change in color depth can cause the content of the memory device to be incompatible. But this does not happen, because when the display mode is modified, Windows automatically modifies the color resolution of the contents of the memory device. The dot mapping of the content of the memory device is still maintained, but it will not cause any problems. Shadow point line

The technology of the memory device content drawing (that is, a dot matrix) is the key to the "Shadow Bitmap". This image contains all the content displayed in the window display area. Thus, the processing of the WM_PAINT message is simplified to a simple Bitblt.

Shadow point lines are most useful in painting programs. The Sketch program shown in the formula 14-7 is not a perfect painting program, but it is a beginning.

Co-style 14-7 Sketchsketch.c / * --------------------------------------- -------------------------------- Sketch.c - Shadow Bitmap Demonstration (C) Charles Petzold, 1998 --- -------------------------------------------------- ---------------------- * /

#include LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM); int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) {static TCHAR szAppName [] = TEXT ( "Sketch"); HWND HWND; MSG msg; wndclass wndclass;

wndclass.style = CS_HREDRAW | CS_VREDRAW; wndclass.lpfnWndProc = WndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = hInstance; wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION); wndclass.hCursor = LoadCursor (NULL , IDC_ARROW); wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH); wndclass.lpszMenuName = NULL; wndclass.lpszClassName = szAppName;! if (RegisterClass (& wndclass)) {MessageBox (NULL, TEXT ( "This program requires Windows NT! "), szAppName, MB_ICONERROR); return 0;} hwnd = CreateWindow (szAppName, TEXT (" Sketch "), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);

IF (hwnd == null) {MessageBox (NULL, TEXT ("Not Enough Memory to Create Bitmap!"), SZAPPNAME, MB_ICONERROR); RETURN 0;} showwindow (hwnd, icmdshow); UpdateWindow (hwnd);

While (GetMessage (& MSG, NULL, 0, 0)) {TranslateMessage (& MSG); DispatchMessage (& MSG);} return msg.wparam;}

Void getLargestDisplayMode (int * pcxbitmap, int * pcybitmap) {devmode devmode; int imodenum = 0;

* pcxbitmap = * pcybitmap = 0;

ZeroMemory (& devmode, sizeof (DEVMODE)); devmode.dmSize = sizeof (DEVMODE); while (EnumDisplaySettings (NULL, iModeNum , & devmode)) {* pcxBitmap = max (* pcxBitmap, (int) devmode.dmPelsWidth); * pcyBitmap = max (* pcyBitmap, (int) devmode.dmPelsHeight);}} LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {static BOOL fLeftButtonDown, fRightButtonDown; static HBITMAP hBitmap; static HDC hdcMem; static int cxBitmap, Cybitmap, CxClient, Cyclient, XMouse, YMouse; HDC HDC; PAINTSTRUCT PS; Switch (Message) {CASE WM_CREATE: GetLargestDisplayMode (& CXBitmap, & cybitmap);

HDC = getDC (hwnd); hbitmap = createcompatiblebitMap (HDC, CXBitmap, cybitmap); hdcmem = createcompatibledc (HDC); ReleaseDC (HWND, HDC);

IF (! hbitmap) // no memory for bitmap {deletedc (hdcmem); return -1;}

SelectObject (HDCMEM, HBitmap); Patblt (HDCMEM, 0, 0, CXBitmap, Cybitmap, Whiteness); Return 0;

Case WM_SIZE: CXClient = loword (lparam); cyclient = HiWord (LPARAM); Return 0;

Case WM_LBUTTONDOWN: IF (! FRIGHTBUTTONDOWN) SetCapture (hwnd);

XMouse = loword (lparam); yMouse = HiWord (LPARAM); FleftButtondown = true; return 0;

case WM_LBUTTONUP: if (fLeftButtonDown) SetCapture (NULL); fLeftButtonDown = FALSE; return 0; case WM_RBUTTONDOWN: (! fLeftButtonDown) if SetCapture (hwnd); xMouse = LOWORD (lParam); yMouse = HIWORD (lParam); fRightButtonDown = TRUE; RETURN 0; casser (FrightButtondown) setcapture (null); FRIGHTBUTTONDOWN = FALSE; RETURN 0; CASE WM_MOUSEMOVE: IF (! Fleftbuttondown &&! FrightButtondown) Return 0;

HDC = Getdc (hwnd);

SelectObject (HDC, GetStockObject (FleftButtondown? Black_pen: white_pen);

SelectObject (HDCMEM, getStockObject (FleftButtondown® Black_pen: White_pen));

MoveToex (HDC, XMouse, YMouse, NULL); MoveToex (HDCMEM, XMOUSE, YMOUSE, NULL);

XMouse = (Short) Loword (LPARAM); YMOUSE = (Short) HiWord (LPARAM);

LINETO (HDC, XMouse, YMouse); LINETO (HDCMEM, XMOUSE, YMOUSE);

ReleaseDC (HWND, HDC); RETURN 0;

Case WM_Paint: HDC = Beginpaint (HWND, & PS); Bitblt (HDC, 0, 0, CxClient, Cyclient, HDCMEM, 0, 0, SRCCopy);

Endpaint (hwnd, & ps); Return 0;

Case WM_DESTROY: DeleteDc (HDCMEM); deleteObject (hbitmap); postquitmessage (0); return 0;} return defWindowProc (hwnd, message, wparam, lparam);} To view line in Sketch, please press the left button and Drag the mouse. To wipe out something (more exactly, painting white line), press the right mouse button and drag the mouse. To empty the entire window, please ... end the program, then reload, everything comes from the head. Figure 14-5 The Sketch program is shown in the SKETCH program, which expresses the early advertisements of the Frequency Fruit Company's McKin Tower.

Figure 14-5 Sketon screen display

How big should this shadow point? In this system, it should be large to the entire display area that can contain maximizes the window. This problem is easy to calculate according to GetSystemMetrics information, but if the user modifies the display settings, then display the size of the window, what happens when the maximum time is maximized? The Sketch program solves this issue with the help of the EnumdisplaySettings. This file uses the DEVMODE structure to pass all valid video display mode information. When you call this fifth, you should set the second parameter of EnumDisPlaySettings to 0, and each time you call this value. EnumdisPlaySettings is completed when false.

At the same time, Sketch will create a shadow point pattern, which is more than four times higher than the surface of the current video display mode, and requires millions of memory memories. Because of this, Sketch will check if the point line is established. If it is not established, then -1 is transmitted from WM_CREATE to indicate an error. During the WM_MOUSEMOVE message processing, the SKETCH intercepts the slice when the mouse left button or right is pressed and the memory device content and the display area device content are passed. If the line mode is more complicated, you may want to do in a single function, the program will call twice-once the video device content is drawn on the content of the memory device.

Here is an interesting experiment: so that the Sketch window is smaller than the full screen size. As the left button of the mole, drag the mouse to the lower right corner of the window. Because Sketch intercepts the mouse, it continues to receive and process the WM_MOUSEMOVE message. Now expand the window, you will see the shadow point map containing the content you draw outside the Sketch window.

Use a dot mapping in the function table

You can also display options on the function table with a dot mapping. Don't think about those pictures if you Lenneuse's pictures of the file clips, scrapbooks, and resource recovery cylinders. You should consider that the function table shows how big the drawing program is used, and it is imagined using different fonts and font size, line width, shadow pattern, and color in the menu.

GrafMenU is an example of displaying a graphic function table option. The top layer function of this program is shown in Figure 14-6. The zoomed letter from a monochrome dot mapping file of 40 × 16 primitives, which is established in Visual C Developer Studio. Select "Font" from the function table to pop up three options - "Courier New", "Arial" and "Times New Roman". They are standard Windows TrueType fonts, and each of them is displayed in its related font, as shown in Figure 14-7. These dot mappings are established in the program in the program.

Figure 14-6 Graft function table

Figure 14-7 The "Font" function table popped up from Grafmenu

Finally, when you pull the system menu, you will get some "assistance" information, expressed the new user's online help item (see Figure 14-8) with "Help". The monochrome dot matrix of this 64 × 64 set is established in Developer Studio.

Figure 14-8 GrafMenu program system function table

Grafmenu program, including a dot matrix, which is established in four developer studio, as shown in the formula 14-8.

Co-style 14-8 grafmenugrafmenu.c / * ----------------------------------------- ----------------------------------- Grafmenu.c - Demonstrates Bitmap Menu Items (C) Charles Petzold, 1998 ------------------------------------- ---------------------------- * /

#include #include "resource.h"

LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM); void AddHelpToSys (HINSTANCE, HWND); HMENU CreateMyMenu (HINSTANCE); HBITMAP StretchBitmap (HBITMAP); HBITMAP GetBitmapFont (int); void DeleteAllBitmaps (HWND); TCHAR szAppName [] = TEXT ( "GrafMenu"); int WINAPI WinMain (hINSTANCE hInstance, hINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) {HWND hwnd; MSG msg; WNDCLASS wndclass; wndclass.style = CS_HREDRAW | CS_VREDRAW; wndclass.lpfnWndProc = WndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = hInstance; wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION); wndclass.hCursor = LoadCursor (NULL, IDC_ARROW); wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH); wndclass .lpszMenuName = NULL; wndclass.lpszClassName = szAppName; (! RegisterClass (& wndclass)) if {MessageBox (NULL, TEXT ( "This program requires Windows NT!"), szAppName, MB_ICONERROR); return 0;} hwnd = CreateWindow (szAppName , Text ("Bitmap Menu DemonStration), WS_OVERLAPPEDWINDOW, CW_USED FAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL); ShowWindow (hwnd, iCmdShow); UpdateWindow (hwnd); while (GetMessage (& msg, NULL, 0, 0)) {TranslateMessage (& msg); DispatchMessage ( & msg);} return msg.wpaham;}

LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam) {HMENU hMenu; static int iCurrentFont = IDM_FONT_COUR; switch (iMsg) {case WM_CREATE: AddHelpToSys (((LPCREATESTRUCT) lParam) -> hInstance, hwnd); hMenu = CreateMyMenu (((LPCREATESTRUCT) lParam) -> hInstance); SetMenu (hwnd, hMenu); CheckMenuItem (hMenu, iCurrentFont, MF_CHECKED); return 0; case WM_SYSCOMMAND: switch (LOWORD (wParam)) {case IDM_HELP: MessageBox (hwnd , TEXT ( "Help not yet implemented!"), szAppName, MB_OK | MB_ICONEXCLAMATION); return 0;} break; case WM_COMMAND: switch (LOWORD (wParam)) {case IDM_FILE_NEW: case IDM_FILE_OPEN: case IDM_FILE_SAVE: case IDM_FILE_SAVE_AS: case IDM_EDIT_UNDO : case IDM_EDIT_CUT: case IDM_EDIT_COPY: case IDM_EDIT_PASTE: case IDM_EDIT_CLEAR: MessageBeep (0); return 0; case IDM_FONT_COUR: case IDM_FONT_ARIAL: case IDM_FONT_TIMES: hMenu = GetMenu (hwnd); CheckMenuItem (hMenu, iCurrentFont, MF_UNCHECKED); iCurrentFont = LOWORD ( WPARAM; Checkmenuitem (HMENU, ICURRENTFONT, MF_CHECKED); RETURN 0;} Break; Case WM_DESTROY: DELETEALLBITMAPS (HWND); PostquitMessage (0); Return 0;} Return DEFWINDOWPROC (HWND, IMSG, WPARAM, LPARAM);} / * ---------------- -------------------------------------------------- -------- Addhelptosys: Adds Bitmap Help Item to System Menu --------------------------------- --------------------------------------- * /

Void AddHelptosys (Hinstance Hinstance, HWND HWND) {Hbitmap Hbitmap; HMENU HMENU

hMenu = GetSystemMenu (hwnd, FALSE); hBitmap = StretchBitmap (LoadBitmap (hInstance, TEXT ( "BitmapHelp"))); AppendMenu (hMenu, MF_SEPARATOR, 0, NULL); AppendMenu (hMenu, MF_BITMAP, IDM_HELP, (PTSTR) (LONG ) hbitmap;

/ * ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ------------------------ CreateMymenu: Assembles Menu from Components -------------------- -------------------------------------------------- ---- * / Hinstance Hinstance {Hbitmap HbitMap; HMENU HMENU, HMENUPOPUP; INT I;

hMenu = CreateMenu (); hMenuPopup = LoadMenu (hInstance, TEXT ( "MenuFile")); hBitmap = StretchBitmap (LoadBitmap (hInstance, TEXT ( "BitmapFile"))); AppendMenu (hMenu, MF_BITMAP | MF_POPUP, (int) hMenuPopup, (PTSTR) (LONG) hBitmap); hMenuPopup = LoadMenu (hInstance, TEXT ( "MenuEdit")); hBitmap = StretchBitmap (LoadBitmap (hInstance, TEXT ( "BitmapEdit"))); AppendMenu (hMenu, MF_BITMAP | MF_POPUP, (int HMenupopup, (PTSTR) (long) hbitmap; hMenupopup = CreateMenu (); for (i = 0; i <3; i ) {hbitmap = getBitmapFont (i); appendmenu (HMenupopup, mf_bitmap, idm_font_cour i, (PTSTR HBitmap);

Hbitmap = stretchbitmap (Hinstance, Text ("BitmapFont")))); appendmenu (HMENU, MF_BITMAP | MF_POPUP, (INT) HMENUPUPUP, (PTSTR) (long) hbitmap; Return HMenu;

/ * ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ------------------------- Stretchbitmap: Scales Bitmap to Display Resolution ------------------ -------------------------------------------------- ------- * /

Hbitmap stretchbitmap (hbitmap hbitmap1) {Bitmap BM1, BM2; HBitmap HbitMap2; HDC HDC, HDCMEM1, HDCMEM2; INT CXCHAR, CYCHAR

// Get The Width and Height of a System Font Character

CXCHAR = loword (getDialogbaseunits ()); cychar = half (getDialogbaseunits ());

// Create 2 memory DCs compatible with the displayhdc = CreateIC (TEXT ( "DISPLAY"), NULL, NULL, NULL); hdcMem1 = CreateCompatibleDC (hdc); hdcMem2 = CreateCompatibleDC (hdc); DeleteDC (hdc); // Get the dimensions of the bitmap to be stretchedGetObject (hBitmap1, sizeof (BITMAP), (PTSTR) & bm1); // Scale these dimensions based on the system font sizebm2 = bm1; bm2.bmWidth = (cxChar * bm2.bmWidth) / 4; bm2 .BmHeight = (cychar * bm2.bmheight) / 8; bm2.bmwidthbytes = ((BM2.BMWIDTH 15) / 16) * 2;

// Create a new bitmap of larger sizehBitmap2 = CreateBitmapIndirect (& bm2); // Select the bitmaps in the memory DCs and do a StretchBltSelectObject (hdcMem1, hBitmap1); SelectObject (hdcMem2, hBitmap2); StretchBlt (hdcMem2, 0, 0, bm2 .BmWidth, BM2.Bmheight, HDCMEM1, 0, 0, Bm1.bmwidth, bm1.bmheight, srcopy; // clean updositedc (HDCMEM1); deleteDc (hdcmem2); deleteObject (hbitmap1); return hbitmap2;}

/ * ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------- GetBitmapFont: Creates Bitmaps with font names -------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------- ----------- * /

HbitMap getBitmapFont (INT i) {static tchar * SZFACENAME [3] = {Text ("Courier New"), Text ("Arial"), Text ("Times New Roman")}; hbitmap hbitmap; HDC HDC, HDCMEM; HFONT HDC = Createic (Text ("Display"), NULL, NULL, NULL); GetTextMetrics (HDC, & TM); hdcmem = createcompatibledc (HDC); HFONT = CREATEFONT (2 * tm.tmheight, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, szfacename [I]);

HFONT = (HFONT) SelectObject (HDCMEM, HFONT); GettextExtentPoint32 (HDCMEM, SZFACENAME [I], Lstrlen (Szfacename [i]), & size); hbitmap = createBitmap (size.cx, size.cy, 1, 1, null) SelectObject (HDCMEM, HBitmap); Textout (HDCMEM, 0, 0, SZFACENAME [I], Lstrlen (Szfacename [i])); deleteObject (SELECTOBJECT (HDCMEM, HFONT)); deletedc (HDCMEM); deletedc (HDC); Return hbitmap;} / * ------------------------------------------------------------------------------------------------------- ------------------------------ DELETEALLBITMAPS: DELETES All The Bitmaps in the menu ---------- -------------------------------------------------- ------------- * /

void DeleteAllBitmaps (HWND hwnd) {HMENU hMenu; int i; MENUITEMINFO mii = {sizeof (MENUITEMINFO), MIIM_SUBMENU | MIIM_TYPE}; // Delete Help bitmap on system menuhMenu = GetSystemMenu (hwnd, FALSE); GetMenuItemInfo (hMenu, IDM_HELP, FALSE , & mii); deleteObject (hbitmap) mii.dwtypedata);

// delete top-level menu bitmapshmenu = getMenu (hwnd); for (i = 0; i <3; i ) {GetMenuItemInfo (HMENU, I, True, & Mii); deleteObject ((hbitmap) mii.dwtypedata;}

// delete bitmap items on font menuhMenu = mii.hsubmenu ;; for (i = 0; i <3; i ) {GetMenuiteminfo (HMENU, I, True, & Mii); deleteObject (hbitmap) mii.dwtypedata);}} Grafmenu.rc (excerpt) // Microsoft Developer Studio generated resource script. # Include "resource.h" #include "afxres.h"

/// MenuMENUFILE MENU DISCARDABLE BEGINMENUITEM "& New", IDM_FILE_NEWMENUITEM "& Open ...", IDM_FILE_OPENMENUITEM "& Save", IDM_FILE_SAVEMENUITEM "Save & As ...", IDM_FILE_SAVE_ASENDMENUEDIT MENU DISCARDABLE BEGINMENUITEM "& Undo", IDM_EDIT_UNDOMENUITEM SEPARATORMENUITEM "Cu & t", IDM_EDIT_CUTMENUITEM "& Copy ", IDM_EDIT_COPYMENUITEM" & Paste ", IDM_EDIT_PASTEMENUITEM" De & lete ", IDM_EDIT_CLEAREND /// BitmapBITMAPFONT BITMAP DISCARDABLE" Fontlabl.bmp "BITMAPHELP BITMAP DISCARDABLE" Bighelp.bmp "BITMAPEDIT BITMAP DISCARDABLE" Editlabl.bmp "bITMAPFILE BITMAP DISCARDABLE" Filelabl.bmp "RESOURCE. H (excerpt) // Microsoft developer studio generated include file.// buy/ used by grafmenu.rc

#define IDM_FONT_COUR 101 # define IDM_FONT_ARIAL 102 # define IDM_FONT_TIMES 103 # define IDM_HELP 104 # define IDM_EDIT_UNDO 40005 # define IDM_EDIT_CUT 40006 # define IDM_EDIT_COPY 40007 # define IDM_EDIT_PASTE 40008 # define IDM_EDIT_CLEAR 40009 # define IDM_FILE_NEW 40010 # define IDM_FILE_OPEN 40011 # define IDM_FILE_SAVE 40012 # define IDM_FILE_SAVE_AS 40013EditLabl.bmp

Filelabl.bmp

Fontlabl.bmp

Bighelp.bmp

To insert a dot mapping into the menu, you can use the appendmenu or insertmenu. Dot matrix map has two sources: can establish a point map in Visual C Developer Studio, including the dot matrix map file in the resource script, and load the dot matrix resource into the memory when using LoadBitmap, then calls Appendmenu or INSERTMENU is attached to the metrics to the menu. However, there are some problems with this method: the dot matrix is ​​not suitable for all dislocations and aspect ratios; sometimes you need to scale the light-loaded dot matrix to resolve this issue. Another method is to establish a dot mapping inside the program, and select it into the content of the memory device, draw it, and then attach to the menu.

The parameters of the getBitmapFont function in Grafmenu are 0, 1 or 2, and back a bit of the map code. This picture contains the string "Courier New", "Arial" or "Times New Roman", and the font is twice as each corresponding, the size is twice the normal system font. Let us see how getBitmapFont is doing. (The following code code is somewhat different from the grafmenu.c file. For the sake of clarity, I use the "Arial" font corresponding to the reference SZFACename array.) The first step is to use the TextMetric structure to determine the size of the current system font, And build a memory device content with the current screen:

HDC = Createic (Text ("Display"), NULL, NULL, NULL); GetTextMetrics (HDC, & TM); HDCMEM = CREATECOMPALEDC (HDC); CreateFont Versatics established a logical font, the font is the system font Double, and the logical name is "Arial":

HFONT = CREATEFONT (2 * tm.tmheight, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, TEXT ("Arial")); Select this from the memory device content Font, then store the internal font code:

HFONT = (HFONT) SelectObject (HDCMEM, HFONT); Now, when we write some text to the contents of the memory device, Windows uses the TrueType Arial font of the optional device content.

However, the content of this memory device initially has only one single graphic monochrome device plane. We must establish a large enough dot matrix to accommodate the text we have to display. With the GettextExtentPoint32 function, you can get the size of the text, and createBitmap can be created according to these dimensions:

GetTextExtentPoint32 (HDCMEM, Text ("Arial"), 5, & size); hbitmap = createBitmap (size.cx, size.cy, 1, 1, null); selectObject (hdcmem, hbitmap); now this device content is a monochrome The display plane is also a strict text size. What we have to do now is to write text:

Textout (HDCMEM, 0, 0, Text ("Arial"), 5); In addition to clearance, all work is completed. To clear, we can use SelectObject to re-select the system font (with code HFONT), then delete the first font code recorded by SelectObject, which is the Arial Font code:

DeleteObject (SelectObject (HDCMEM, HFONT)); now you can delete two devices:

DELETEDC (HDCMEM); DELETEDC (HDC); this, we get a dot mapping, which has a string "Arial" of Arial font on the point.

When we need to zoom fonts to accommodate different display resolution or aspect ratio, the memory device content can also solve the problem. In the Grafmenu program, I built four dot matrix maps only for system font high 8 o'clock, width 4 status display. For other size system fonts, only the dot mapping is scaled. This feature is done in the Stretchbitmap in Grafmenu.

The first step is to obtain the displayed device content, then obtain the text specification of the system font, then build two memory device content:

HDC = Createic (Text ("Display"), NULL, NULL, NULL); GetTextMetrics (HDC, & TM); HDCMEM1 = CreateCompatibleDC (HDC); HDCMEM2 = CreateCompALPLEDC (HDC); Deletedc (HDC); Pixably passed The array code is HBitmap1. The program can get the size of a point of the picture with GetObject:

GetObject (HbitMap1, SizeOf (Bitmap), (PSTR) & BM1); This action is copied to the structure BM1 of the Bitmap type. Structure BM2 is equal to the structure BM1, then modify certain fields according to the system font size:

BM2 = BM1; BM2.BMWidth = (TM.TMAVECHARWIDTH * BM2.BMWIDTH) / 4; BM2.BmHeight = (TM.TMHEIGHT * BM2.BMHEIGHT) / 8; bm2.bmwidthbytes = ((Bm2.bmwidth 15) / 16 ) * 2; the next dot matrix has code HBitmap2, which can be established according to the dynamic size:

Hbitmap2 = CreateBitMapIndirect (& BM2); then select these two dot mapping in the contents of the two memory devices:

SelectObject (HDCMEM1, HBitmap1); SelectObject (HDCMEM2, HBitmap2); we want to copy the first dot matrix to the second dot matrix map and stretch in this program. This includes a StretchBLT call:

Stretchblt (HDCMEM2, 0, 0, BM2.BMWIDTH, BM2.BMHEIGHT, HDCMEM1, 0, 0, BM1.BMWIDTH, BM1.BMHEIGHT, SRCCPY); Now the second picture is properly scaled, we can use it to function Table. The remaining clear work is very simple:

Deletedc (HDCMEM1); DeleteDc (HDCMEM2); DeleteObject (HbitMap1); When the function is built, the CreateMyMenu in GrafMenu calls StretchbitMap and getBitmapFont. GrafMenu defines two menu in the resource file, and the two menu pops up when selecting "File" and "Edit" option. The code starts to get an air function table first:

HMENU = CREATEMENU (); from the resource file to load "File" full-time menu (including four options: "New", "Open", "Save" and "Save AS"):

HMenupopup = loadingMenu (Hinstance, Text ("Menufile")); from the resource file also loaded a dot matrix map with "File", and stretched with Stretchbitmap:

HbitMapFile = stretchbitMap (LoadBitmap (Hinstance, Text ("BitmapFile"))))))))); Dot matrix code and sudden functional tables are all parameters of the AppendMenu call:

Appendmenu (HMENU, MF_BITMAP | MF_POPUP, HMENUPOPUP, (PTSTR) HbitMapFile; "Edit" function table is as follows:

hMenuPopup = LoadMenu (hInstance, TEXT ( "MenuEdit")); hBitmapEdit = StretchBitmap (LoadBitmap (hInstance, TEXT ( "BitmapEdit"))); AppendMenu (hMenu, MF_BITMAP | MF_POPUP, hMenuPopup, (PTSTR) (LONG) hBitmapEdit); Call GetBitmapFont Verstries can construct these three different fonts of the sudden functional table: hMenupopup = creteMenu (); for (i = 0; i <3; i ) {hbitmappopfont [i] = getBitmapFont (i); appendmenu (HMenupopup, MF_bitmap, idm_font_cour i, (ptstr) (long) HMenupupupFont [i]);} then adds the sudden function table to the menu:

Hbitmapfont = stretchbitmap (Hinstance, "BitmapFont"); appendmenu (HMENU, MF_BITMAP | MF_POPUP, HMENUPOPUP, (PTSTR) (long) hbitmapfont; WNDPROC passes the call setmenu to complete the establishment of the window function table.

GrafMenu also changed the system menu in the AddHelptosys function. This form first gets a system function table code:

HMENU = GetSystemMenu (hwnd, false); this will load "Help" dot matrix map and stretch it to the appropriate size:

HbitMaphelp = stretchbitMap (LoadBitmap (Hinstance, Text ("Bitmaphelp"))))))))))))))))))))))))))))))

Appendmenu (HMENU, MF_SEPARATOR, 0, NULL); appendmenu (HMENU, MF_BITMAP, IDM_HELP, (PTSTR) (long) hbitmaphelp); GrafMenu calls a plurality before exiting to clear and delete all point lines.

Below is some precautions for using a dot mapping in the menu.

In the top-level menu, Windows adjusts the height of the functional table column to accommodate the highest dot matrix. Other dot matrix (or strings) are aligned based on the top end of the functional table column. If a dot matrix is ​​used in the top-level function table, the functional table column semanties obtained from GetSystemMetrics using constant SM_CYMENU will no longer be effective.

You can see during GrafMenu: In an Exaxial Function Table, you can use a tick mark with a point-of-point graph function, but check the mark is normal size. If you are not satisfied, you can create a custom tick mark and use SetMenuItemBitmaps.

Another way to use non-text (or using non-system font) in the functional table is the "owner draw" menu.

The keyboard interface of the function table is another problem. When the function table contains text, Windows automatically adds a keyboard interface. To select a functional entry, you can use a combination of alpha and a letter from a string. Once the dot matrix is ​​placed in the function table, the keyboard interface is deleted. Even if the point-in-picture is expressed, Windows does not know.

We can currently use WM_MenuChar messages. Windows will send a WM_MenuChar message to your window message processing when you press the ALT and a key key key key key that does not match the function item. GrafMenu needs to intercept the WM_MenuChar message and check the value of WPARAM (ie the button's ASCII code). If this value corresponds to a functional entry, the double word group is back to Windows: where the high character is 2, the low character group is the function table entry index value associated with the key. The rest is then processed by Windows. Non-rectangular dot mapping image

The dot matrix is ​​a rectangle, but it is not necessary to display a rectangle. For example, assume you have a rectangular point mapping image, but you want to display it into an elliptical.

First, this sounds very simple. Simply load images into Visual C Developer Studio or Windows's "Draw" program (or more expensive application), then draw images around the image with a white brush. At this time, an elliptical image will be obtained, and the ellipse is made on white. Only when the background color is white when the background is white, this is displayed correctly. If you display on other background colors, you will find that there is a white rectangle between the elliptical image and the background. This effect is not good.

There is a very common technology to solve such problems. This technique includes a "Mask" dot mapping and some bitmap operations. Mask is a monochrome point, which is the same as the rectangular dot mapping image you want to display. Each mask of the pattern corresponds to a primitive of the image image. The mask is 1 (white), corresponding to the point line pattern display; it is 0 (black), then the background color is displayed. (Or the mask dot mapping is reversed here, which has some corresponding changes depending on the bitmap operation you use.)

Let's take a look at how the Bitmask program does this technology. As shown in the formula 14-9.

Program 14-9 bitmaskbitmask.c / * ------------------------------------------- --------------------------------- Bitmask.c - Bitmap Masking Demonstration (c) Charles Petzold, 1998- -------------------------------------------------- ------------------------- * /

#include LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM); int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) {static TCHAR szAppName [] = TEXT ( "BitMask"); HWND HWND; MSG msg; wndclass wndclass;

wndclass.style = CS_HREDRAW | CS_VREDRAW; wndclass.lpfnWndProc = WndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = hInstance; wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION); wndclass.hCursor = LoadCursor (NULL , IDC_ARROW); wndclass.hbrBackground = (HBRUSH) GetStockObject (LTGRAY_BRUSH); wndclass.lpszMenuName = NULL; wndclass.lpszClassName = szAppName;! if (RegisterClass (& wndclass)) {MessageBox (NULL, TEXT ( "This program requires Windows NT! "), szAppName, MB_ICONERROR); return 0;} hwnd = CreateWindow (szAppName, TEXT (" Bitmap Masking Demo "), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL); ShowWindow (hwnd, ICMDSHOW); UpdateWindow (HWND);

While (GetMessage (& MSG, NULL, 0, 0)) {TranslateMessage (& MSG); DispatchMessage (& MSG);} return msg.wparam;}

LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {static HBITMAP hBitmapImag, hBitmapMask; static HINSTANCE hInstance; static int cxClient, cyClient, cxBitmap, cyBitmap; BITMAP bitmap; HDC hdc, hdcMemImag, hdcMemMask; int x, y; PAINTSTRUCT ps; switch (message) {case WM_CREATE: hInstance = ((LPCREATESTRUCT) lParam) -> hInstance; // Load the original image and get its sizehBitmapImag = LoadBitmap (hInstance, TEXT ( "Matthew")); GetObject ( Hbitmapimag, sizeof (bitmap), & Bitmap; cxbitmap = bitmap.bmwidth; cybitmap = bitmap.bmheight;

// Select the original image into a memory DChdcMemImag = CreateCompatibleDC (NULL); SelectObject (hdcMemImag, hBitmapImag); // Create the monochrome mask bitmap and memory DChBitmapMask = CreateBitmap (cxBitmap, cyBitmap, 1, 1, NULL); hdcMemMask = CreateCompatibleDC (NULL); SelectObject (hdcMemMask, hBitmapMask); // Color the mask bitmap black with a white ellipseSelectObject (hdcMemMask, GetStockObject (BLACK_BRUSH)); Rectangle (hdcMemMask, 0, 0, cxBitmap, cyBitmap); SelectObject (hdcMemMask, GetStockObject ( White_brush)); Ellipse (HDCMemmask, 0, 0, CXBitmap, Cybitmap);

// Mask The Original ImageBitblt (HDCMEMAG, 0, 0, CXBitmap, Cybitmap, HDCMemmask, 0, 0, Srcand); deletedc (HDCMEMIMAG); deletedc (hdcmemmask); returnograph;

Case WM_SIZE: CXClient = loword (lparam); cyclient = HiWord (LPARAM); Return 0;

Case WM_Paint: HDC = BeginPaint (HWND, & PS);

// Select Bitmaps Into Memory DCS

HDCMEMIMAG = CreateCompatibleDC (HDC); SelectObject (HDCMEMIMAG, HBITMAPIMAG);

HDCMEMMASK = CreateCompatibleDC (HDC); SelectObject (HDCMEMMASK, HBitmapmask);

// center image

X = (CxClient - cxbitmap) / 2; y = (cyclient - cybitmap) / 2; // do the bitblts

Bitblt (HDC, X, Y, CXbitmap, Cybitmap, HDCMemmask, 0, 0, 0x220326); Bitblt (HDC, X, Y, CXbitmap, Cybitmap, HDCMEMAG, 0, 0, SRCPAINT);

Delededc (HDCMEMIMAG); deletedc (HDCMemmask); EndPaint (HWND, & PS); Return 0;

case WM_DESTROY: DeleteObject (hBitmapImag); DeleteObject (hBitmapMask); PostQuitMessage (0); return 0;} return DefWindowProc (hwnd, message, wParam, lParam);} BITMASK.RC // Microsoft Developer Studio generated resource script # include ". Resource.h "#include" afxres.h "

/// bitmapmatthew bitmap discardable "matthew.bmp" The matthew.bmp file in the resource file is a black and white photo, a width of 200 odds, a high 320 primer, 8 bits per status. However, additional Bitmask is only because the content of this file is all anything. Note that Bitmask sets the window background to bright gray. This ensures that we can correctly mask the dot mapping, not just to apply it white.

Let's take a look at the WM_CREATE handler: Bitmask uses the LoadBitMap function to get the original image of the original image in the hbitmapiMAG variable. Use the getObject letter to obtain the width height of the point pattern. Then select the dot matrix code to the memory device content of the code-hdcmemimag.

The next monochrome dot mapping of the program is the same as the original chart, and the code is stored in Hbitmapmask and is selected in the memory device content of the code to HDCMEMASK. In the memory device content, the GDI is used, and the mask point is applied to a black background and a white ellipse:

SelectObject (hdcMemMask, GetStockObject (BLACK_BRUSH)); Rectangle (hdcMemMask, 0, 0, cxBitmap, cyBitmap); SelectObject (hdcMemMask, GetStockObject (WHITE_BRUSH)); Ellipse (hdcMemMask, 0, 0, cxBitmap, cyBitmap); because it is a Monochrome dot matrix, the bits of the black area are 0, while the bit in the white area is 1.

Then Bitblt Call will change the original image by pressing this mask:

Bitblt (HDCMEMIMAG, 0, 0, CXBitmap, Cybitmap, HDCMemmask, 0, 0, srcand); Srcand bitmap is performed between the source bit element (mask point) and the destination element (original image) Dollar and operation. As long as the mask point is white, it will show the purpose; as long as the mask is black, the purpose is also black. A black surrounded elliptical region is formed in the original image.

Let's take a look at the WM_PAINT handler. This procedure simultaneously changes the image dot matrix map and mask point lines in the content of the memory device. Two Bitblt calls completed this magic, and the first time to perform a Bitblt of the mask point on the window:

Bitblt (HDC, X, Y, CXbitmap, Cybitmap, HDCMemmask, 0, 0, 0x220326); a bitmap operation without a name is used here. The logical operator is D & ~ S. Recall source - ie mask point array - is a white (bit value 1) ellipse surrounded by black (bit value 0). The bit mapping operation first will reflect the source, which is changed to the black ellipse surrounded by white. The bit is then operated between this converted source and the purpose (ie, on the window). When the purpose and bit value 1 "AND" remain unchanged; when the bit value is 0 "AND", the purpose will become black. Therefore, the Bitblt operation will draw a black ellipse on the window.

The second Bitblt call is drawn in the window:

Bitblt (HDC, X, Y, CXbitmap, Cybitmap, HDCMEMAG, 0, 0, SrcPaint); bit element mapping operations perform bit yuan "OR" operation between the source and destination. Since the outer surface of the source point line is black, the purpose is not changed; in the ellipse area, the purpose is black, so the image is inoperable. The execution results are shown in Figure 14-9.

Precautions:

Sometimes you need a very complex mask - for example, erase the entire background of the original image. You will need to manually establish it in the drawing program and store it into a file. Figure 14-9 BitMask screen display

If you are writing similar applications for Windows NT, you can use a Maskblt function similar to the Maskbit program, but only less functions. Windows NT also includes another Voices similar to Bitblt, and Windows 98 does not support the form. This file is PLGBLT ("Parallel Si'an Move: Parallelogram BLT"). This group can rotate or inclined the image image of the image.

Finally, if you execute a Bitmask program on your machine, you will only see black, white and two gray shadows because the display mode you perform is 16 colors or 256 colors. For 16-color mode, the display effect cannot be improved, but the color plate can be changed in 256 color mode to display the grayscale. You will learn how to set a palette in Chapter 16.

Simple animation

Small dot matrix shows very fast, so you can use the dot matrix and Windows timer to complete some basic animations.

Now start this playball program.

BOUNCE, as shown in the formula 14-10, generated a small ball that bounced in the window display area. The program uses the timer to control the travel speed of the ball. The ball itself is a dot matrix map, the program first establishes a small ball by establishing a point of view, selecting the content of the memory device, and then calls some simple GDI functions. The program uses Bitblt from a memory device content to the display.

Program 14-10 Bouncebounce.c / * ----------------------------------------- --------------------------------- Bounce.c - bouncing ball program (c) Charles Petzold, 1998- -------------------------------------------------- ------------------------- * /

#include #define id_timer 1

LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM); int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) {static TCHAR szAppName [] = TEXT ( "Bounce"); HWND hwnd; MSG msg; WNDCLASS WNDCLASS;

wndclass.style = CS_HREDRAW | CS_VREDRAW; wndclass.lpfnWndProc = WndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = hInstance; wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION); wndclass.hCursor = LoadCursor (NULL , IDC_ARROW); wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH); wndclass.lpszMenuName = NULL; wndclass.lpszClassName = szAppName;! if (RegisterClass (& wndclass)) {MessageBox (NULL, TEXT ( "This program requires Windows NT! "), szAppName, MB_ICONERROR); return 0;} hwnd = CreateWindow (szAppName, TEXT (" Bouncing Ball "), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL); ShowWindow (hwnd, iCmdShow ); UpdateWindow (HWND); While (GetMessage (& MSG, NULL, 0, 0)) {TranslateMessage (& MSG); DispatchMessage (& MSG);} return msg.wparam;}

LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam) {static HBITMAP hBitmap; static int cxClient, cyClient, xCenter, yCenter, cxTotal, cyTotal, cxRadius, cyRadius, cxMove, cyMove, xPixel, yPixel; HBRUSH hBrush; HDC hdc, hdcMem; int iScale; switch (iMsg) {case WM_CREATE: hdc = GetDC (hwnd); xPixel = GetDeviceCaps (hdc, ASPECTX); yPixel = GetDeviceCaps (hdc, ASPECTY); ReleaseDC (hwnd, hdc); SetTimer ( HWND, ID_TIMER, 50, NULL; RETURN 0; CASE WM_SIZE: XCenter = (cxclient = loword (lparam)) / 2; Ycenter = (Cyclient = HiWord (LPARAM)) / 2; iscale = min (cxclient * xpixel, cyclient * Ypixel) / 16; cxradius = iscale / xpixel; cyradius = Iscale / Ypixel; cxmove = max (1, cxradius / 2); cymove = max (1, cyradius / 2); cxtotal = 2 * (cxradius cxmove); cyTotal = 2 * (cyRadius cyMove); if (hBitmap) DeleteObject (hBitmap); hdc = GetDC (hwnd); hdcMem = CreateCompatibleDC (hdc); hBitmap = CreateCompatibleBitmap (hdc, cxTotal, cyTotal); ReleaseDC (hwnd, hdc) ; SelectObject (HDCM EM, HBitmap; Rectangle (HDCMEM, -1, -1, CXTOTAL 1, Cytotal 1); Hbrush = CreateHatchbrush (HS_Diagcross, 0L); SelectObject (HDCMEM, HBRUSH); SetBkcolor (HDCMEM, RGB (255, 0, 255); Ellipse (HDCMEM, CXMOVE, CYMOVE, CXTOTAL - CXMOVE, CYTOTAL - CYMOVE); DeleteDc (HDCMEM); deleteObject (Hbrush); Return 0; Case WM_TIMER: IF (! Hbitmap) Break; HDC = Getdc (hwnd) HDCMEM = CreateCompatibleDC (HDC); SelectObject (HDCMEM, HBitMap); Bitblt (HDC, Xcenter - CXTOTAL / 2, YCENTER - Cytotal / 2, CXTOTAL, CYTOTAL, HDCMEM, 0, 0, SRCCOPY); ReleaseDC (HWND, HDC) DELETEDC (HDCMEM); Xcenter = Cxmove; Ycenter = Cymove; IF ((Xcenter CXRADIUS>

= cxclient) || (xMETER - CXRADIUS <= 0))) cxmove = -cxmove; if ((Ycenter cyradius> = cyclient) || (Ycenter - cyradius <= 0)) cymove = -Cymove; return 0; Case WM_DESTROY : if (hbitmap) deleteObject (hbitmap); killtimer (hwnd, id_timer); postquitMessage (0); return 0;} return defWindowProc (HWND, IMSG, WPARAM, LPARAM);} Bounce is heavy every time a WM_SIZE message is received Painted a small ball. This requires a memory device that is compatible with the video display: HDCMEM = CREATECOMPALEDC (HDC); the diameter of the ball is set to 1 sixteenth of the shorter in the window display area or the width. However, the dot matrix map of the program is larger than the small ball: from the point of the point-in-point map, the distance of the four sides is 1.5 times the spherical radius:

Hbitmap = createcompatiblebitmap (HDC, cxtotal, cytotal); After selecting a dot matrix into the content of the memory device, the entire dot mapping background is set on white:

Rectangle (HDCMEM, -1, -1, XTOTAL 1, YTOTAL 1); those unfixed coordinates make the rectangular border colored outside the dot mapping. A brush of a diagonal opening selects the content of the memory device, and draws the tap in the center of the dot matrix:

Ellipse (HDCMEM, XMOVE, YMOVE, XTOTAL - XMOVE, YTOTAL - YMOVE); When the ball moves, the blank of the ball boundary will effectively delete the pocal image at the previous moment. In another location, you will be able to use SRCCOPY ROP code in a Bitblt call:

Bitblt (HDC, Xceternal - CXTOTAL / 2, YCENTER - CYTOTAL / 2, CXTOTAL, CYTOTAL, HDCMEM, 0, 0, SRCCOPY); Bounce program is only the easiest way to move images on the display. In general, this method is not satisfactory. If you are interested in animation, then other ROP code (such as srcinvert) should also be studied in addition to executing or operating between sources and destinations. Other animation technologies include a Windows palette (and an AtematePalette function) and createDibSECTION cards. For more advanced animations, you have to give up GDI and use the DirectX interface.

Dot map outside the window

Scramble, as shown in the formula 14-11, written very rough, I can't display this program, but it demonstrates some interesting technologies, and in the program that swaps the two Bitblt operations that display the rectangular content, with the memory The device content is used as a temporary storage space.

Cheng-style 14-11 scramblescRamble.c / * ----------------------------------------- ---------------------------------- Scramble.c - scramble (and unscramble) Screen (c) Charles Petzold 1998 ------------------------------------------------ ----------------------------- * /

#include

#define Num 300

LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM); int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) {static int iKeep [NUM] [4]; HDC hdcScr, hdcMem; int cx, cy; Hbitmap hbitmap; hwnd hwnd; INT I, J, X1, Y1, X2, Y2;

if (LockWindowUpdate (hwnd = GetDesktopWindow ())) {hdcScr = GetDCEx (hwnd, NULL, DCX_CACHE | DCX_LOCKWINDOWUPDATE); hdcMem = CreateCompatibleDC (hdcScr); cx = GetSystemMetrics (SM_CXSCREEN) / 10; cy = GetSystemMetrics (SM_CYSCREEN) / 10; Hbitmap = CreateCompaPLEBITMAP (HDCSCR, CX, CY); SelectObject (HDCMEM, HBitmap); SRAND (INT) getcurrentTime ()); for (i = 0; i <2; i ) for (j = 0; J

The scramble then determines the size of the full screen and divides the long and width to 10, respectively. The program uses this size (name is CX and CY) to create a dot matrix map and select the point of the memory to the memory device.

Using the C language RAND function, scramble calculates four random values ​​(two seat points) as multiplexes of CX and CY. The program exchanges the content displayed in two rectangular blocks through three call bitblt functions. The first time the rectangle starting from the first seat point is copied to the content of the memory device. The second Bitblt copies the rectangle starting from the second branch to the first point starting. The third time the rectangle in the memory device content is copied to the region where the second seat punctuation begins. This program will effectively exchange the contents of two rectangles on the display. Scramble performs 300 exchanges, and the screen display is definitely a mess. But don't worry, because scramble remembers how to make it like this, then it will restore the original desktop display (the picture before locking the screen before exiting)!

You can also copy a dot matrix to another point. For example, assume that you want to create a dot matrix, which contains only graphics in the upper left corner of another dot mapping. If the original image is codenamed hbitmap, you can copy its size to a Bitmap-type structure:

GetObject (Hbitmap, Sizeof (Bitmap), & BM); then established an uninitialized new point of view, the size of this point is 1/4 of the original picture:

HBitmap2 = CreateBitmap (BM.BMWIDTH / 2, BM.BMHEIGHT / 2, BM.BMPLANES, BM.BMBITSPIXEL, NULL); now establish two memory device content, and select the original point of the picture and the new dot mapping These two memory devices content:

HDCMEM1 = CREATECOMPATIBLEDC (HDC); HDCMEM2 = CREATECOMPATIBLEDC (HDC);

SelectObject (HDCMEM1, HBitmap); SelectObject (HDCMEM2, HBitmap2); Finally, copy the upper left corner of the first dot matrix to the second:

Bitblt (HDCMEM2, 0, 0, BM.BMWIDTH / 2, BM.BMHEIGHT / 2, HDCMEM1, 0, 0, SRCCOPY); the remaining only clear work:

Deletedc (HDCMEM1); deleteObject (hbitmap); Blowup.c program, as shown in Figure 14-21, also displayed with a window update lock to display a captured rectangle outside of the program window. This program allows the user to select the rectangular area on the screen, and then Blowup copies the contents of the area to the dot matrix. During the WM_PAINT message processing, the dot matrix is ​​copied to the program display area, and stretches or compresses when necessary. (See No. 14-12.)

Co-style 14-12 blowupblowup.c / * ----------------------------------------- --------------------------------- Blowup.c - Video Magnifier Program (c) Charles Petzold, 1998 - -------------------------------------------------- ------------------------ * /

#include #include // for abs Definition # include "resource.h" LRESULT CALLBACK WNDPROC (HWND, UINT, WPARAM, LPARAM);

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) {static TCHAR szAppName [] = TEXT ( "Blowup"); HACCEL hAccel; HWND hwnd; MSG msg; WNDCLASS wndclass; wndclass.style = CS_HREDRAW | CS_VREDRAW; wndclass.lpfnWndProc = WndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = hInstance; wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION); wndclass.hCursor = LoadCursor (NULL, IDC_ARROW); wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH); wndclass.lpszMenuName = szAppName; wndclass.lpszClassName = szAppName; (! RegisterClass (& wndclass)) if {MessageBox ( "! This program requires Windows NT" NULL, TEXT (), szAppName, MB_ICONERROR); return 0;} hwnd = CreateWindow (szAppName, TEXT ( "Blow-Up Mouse Demo"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);

ShowWindow (hwnd, icmdshow); UpdateWindow (HWND);

hAccel = LoadAccelerators (hInstance, szAppName); while (GetMessage (& msg, NULL, 0, 0)) {if {TranslateMessage (& msg) (TranslateAccelerator (hwnd, hAccel, & msg)!); DispatchMessage (& msg);}} return msg .wpaham;

void InvertBlock (HWND hwndScr, HWND hwnd, POINT ptBeg, POINT ptEnd) {HDC hdc; hdc = GetDCEx (hwndScr, NULL, DCX_CACHE | DCX_LOCKWINDOWUPDATE); ClientToScreen (hwnd, & ptBeg); ClientToScreen (hwnd, & ptEnd); PatBlt (hdc, PTBEG.X, PTBeg.y, Ptend.x - ptbeg.x, ptend.y - ptbeg.y, dstinvert); ReleaseDC (HWNDSCR, HDC);}

Hbitmap copybitmap (hbitmap hbitmapsrc) {bitmap bitmap; hbitmap hbitmapdst; HDC HDCSRC, HDCDST;

GetObject (Hbitmapsrc, Sizeof (Bitmap), & Bitmap; hbitmapdst = createbitmapindirect (& Bitmap); hdcsrc = createcompatibledc (null); hdcdst = createcompatibleDC (null);

SelectObject (HDCSRC, HBitmapsrc); SelectObject (HDCDST, HBitmapdst);

Bitblt (HDCDST, 0, 0, Bitmap.bmwidth, Bitmap.Bmheight, HDCSRC, 0, 0, Srcopy); deletedc (HDCSRC); deletedc (hdcdst);

Return hbitmapdst;

LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {static BOOL bCapturing, bBlocking; static HBITMAP hBitmap; static HWND hwndScr; static POINT ptBeg, ptEnd; BITMAP bm; HBITMAP hBitmapClip; HDC hdc, hdcMem; int iEnable ; PAINTSTRUCT PS; RECT D;

switch (message) {case WM_LBUTTONDOWN: if {if (LockWindowUpdate (hwndScr = GetDesktopWindow ())) {bCapturing = TRUE; SetCapture (hwnd); SetCursor (LoadCursor (NULL, IDC_CROSS));} elseMessageBeep (0) (bCapturing!) } return 0;

Case WM_RBUTTONDOWN: IF (BCAPTURING) {BBLOCKING = true; ptbeg.x = loword (lparam); pTBeg.y = HiWord (LPARAM); Ptend = PTBEG; InvertBlock (hwndscr, hwnd, ptbeg, ptend);} return 0;

case WM_MOUSEMOVE: if (bBlocking) {InvertBlock (hwndScr, hwnd, ptBeg, ptEnd); ptEnd.x = LOWORD (lParam); ptEnd.y = HIWORD (lParam); InvertBlock (hwndScr, hwnd, ptBeg, ptEnd);} return 0;

Case WM_LButtonUp: Case WM_RButtonup: IF (BBLOCKING) {InvertBlock (HWNDSCR, HWND, PTBEG, PTEND); Ptend.x = Loword (LPARAM); ptend.y = HiWord (LPARAM);

IF (hbitmap) {deleteObject (hbitmap); hbitmap = null;}

HDC = GETDC (HWND); hdcmem = creteCompatibleDC (HBitmap = CreateCompablebitMap (HDC, ABS (Ptend.x - ptbeg.x), ABS (Ptend.y - ptbeg.y));

SelectObject (HDCMEM, HBitmap);

Stretchblt (HDCMEM, 0, 0, ABS (Ptend.x - ptbeg.x), ABS (Ptend.y - ptbeg.y), HDC, PTBeg.x, PTBeg.y, Ptend.x - PTBeg.x, Ptend. y - ptBeg.y, SRCCOPY); DeleteDC (hdcMem); ReleaseDC (hwnd, hdc); InvalidateRect (hwnd, NULL, TRUE);} if (bBlocking || bCapturing) {bBlocking = bCapturing = FALSE; SetCursor (LoadCursor (NULL , Idc_arrow); ReleaseCapture (); LockWindowUpdate (NULL);} return 0; Case WM_INITMENUPOPUP: INABLE = IsclipboardFormatavailable (cf_bitmap)? Mf_enabled: mf_grayed;

EnableMenuItem ((HMENU) WPARAM, IDM_EDIT_PASTE, IENABLE;

INABLE = hbitmap? mf_enabled: mf_grayed;

EnableMenuItem ((HMENU) WPARAM, IDM_EDIT_CUT, IENABLE); EnableMenuItem ((HMENU) WPARAM, IDM_EDIT_COPY, IENABLE); EnableMenuItem ((HMENU) WPARAM, IDM_EDIT_DELETE, IENABLE; RETURN 0;

case WM_COMMAND: switch (LOWORD (wParam)) {case IDM_EDIT_CUT: case IDM_EDIT_COPY: if (hBitmap) {hBitmapClip = CopyBitmap (hBitmap); OpenClipboard (hwnd); EmptyClipboard (); SetClipboardData (CF_BITMAP, hBitmapClip);} if (LOWORD ( wParam) == IDM_EDIT_COPY) return 0; // fall through for IDM_EDIT_CUTcase IDM_EDIT_DELETE: if (hBitmap) {DeleteObject (hBitmap); hBitmap = NULL;} InvalidateRect (hwnd, NULL, TRUE); return 0;

Case IDM_EDit_paste: if (hbitmap) {deleteObject (hbitmap); hbitmap = null;} OpenClipboard (hwnd); hbitmapclip = getClipboardData (cf_bitmap);

IF (hbitmapclip) hbitmap = copybitmap (hbitmapclip);

Closeclipboard (); InvalIdateRect (hwnd, null, true); return 0;} Break; Case WM_Paint: HDC = BeginPaint (hwnd, & ps);

IF (hbitmap) {getClientRect (hwnd, & review);

hdcMem = CreateCompatibleDC (hdc); SelectObject (hdcMem, hBitmap); GetObject (hBitmap, sizeof (BITMAP), (PSTR) & bm); SetStretchBltMode (hdc, COLORONCOLOR); StretchBlt (hdc, 0, 0, rect.right, rect. Bottom, HDCMEM, 0, 0, BM.BMWIDTH, BM.BMHEIGHT, SRCCOPY;

DELETEDC (HDCMEM); Endpaint (HWND, & PS); RETURN 0;

Case WM_DESTROY: IF (HbitMap) deleteObject (HbitMap);

PostQuitMessage (0); return 0;} return DefWindowProc (hwnd, message, wParam, lParam);} BLOWUP.RC (excerpt) // Microsoft Developer Studio generated resource script # include "resource.h" #include "afxres.h. "

/// MenuBLOWUP MENU DISCARDABLE BEGINPOPUP "& Edit" BEGINMENUITEM "Cu & t / tCtrl X", IDM_EDIT_CUTMENUITEM "& Copy / tCtrl C", IDM_EDIT_COPYMENUITEM "& Paste / tCtrl V", IDM_EDIT_PASTEMENUITEM "De & lete / tDelete", IDM_EDIT_DELETEENDEND

/// AcceleratorBLOWUP ACCELERATORS DISCARDABLE BEGIN "C", IDM_EDIT_COPY, VIRTKEY, CONTROL, NOINVERT "V", IDM_EDIT_PASTE, VIRTKEY, CONTROL, NOINVERTVK_DELETE, IDM_EDIT_DELETE, VIRTKEY, NOINVERT "X", IDM_EDIT_CUT, VIRTKEY, CONTROL, NOINVERTENDRESOURCE.H (excerpt ) // Microsoft developer studio generated incrude file.// buy by bulowup.rc

#define IDM_EDIT_CUT 40001 # define idm_edit_copy 40002 # define idm_edit_paste 40003 # define idm_edit_delete 40004

Figure 14-10 A sample displayed by the flowup

Due to the limitations of the mouse interception, it will be stronger when using Blowup, and it needs to be gradually adapted. Below is a method of using this sentence:

The left button is pressed in the Blowup display area, and the mouse indicator will become " " font. Continue to press and hold the left button to move the mouse to any other location on the screen. The position of the mouse cursor is the upper left corner of the rectangular area you want to circle. Continue to press and hold the left button, press the right mouse button, then drag the mouse to the lower right corner of the rectangular area you want to circle. Release the left button and right click. (Release the left, right-click order.) The mouse cursor returns to an arrow shape, then the rectangular area of ​​your circle has been copied to the display area of ​​the blowup, and appropriate compression or stretching changes.

If you choose from the upper right corner to the lower left corner, the blowup will display the image of the rectangular area. If you choose from the left to the upper right corner, the Blowup will display an upside down image. If you choose from the upper right corner to the upper left corner, the program will synthesize both effects. The Blowup also contains copying the dot matrix to the scrapbook, and copies the dot matrix map in the scrapbook to the process of processing. Blowup processes WM_InitMenupup messages to enable or disable different options in the "Edit" feature, and process these functional entries via WM_Command messages. You should be more familiar with the structure of these program code because they are in essence of the processing of replication and paste text items in Chapter 12.

However, for dot matrix, the scrapbook item is not an overall code but is a point of illustration. When you use CF_bitmap, the getClipboardData is sent back to an HBitmap object and a SETCLIPBOARDDATA card receives an HBitmap object. If you want to transfer a dot mapping to the scrapbook and want to keep the copy to use the supplies itself, you must copy the point map. Similarly, if you paste a picture from the scrapbook, you should make a copy. The copybitmap in Blowup is to complete this operation by obtaining the BitMap structure of the existing point graph and uses this structure in the CreateBitMapIndirect card. (Variable names of tail code SRC and DST represent "Source" and "Purpose".) The two dot matrix maps are selected into the memory device content, and copy bitblt contents by calling Bitblt. (Another method of copying the bit, you can configure a memory by point the pattern size, then call GetBitMapBits for source point mapping, call setBitmapBits for the purpose of the target.)

I found that Blowup is very useful for checking a large number of small dots and pictures in Windows and their applications.

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

New Post(0)