Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 128 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
128
Dung lượng
542,1 KB
Nội dung
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 */ HMENU CreateMyMenu (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) (LONG) hBitmap) ; } hBitmap = StretchBitmap (LoadBitmap (hInstance, TEXT ("BitmapFont"))) ; AppendMenu (hMenu, MF_BITMAP | MF_POPUP, (int) hMenuPopup, (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 = HIWORD (GetDialogBaseUnits ()) ; // Create 2 memory DCs compatible with the display This document is created with the unregistered version of CHM2PDF Pilot Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com hdc = CreateIC (TEXT ("DISPLAY"), NULL, NULL, NULL) ; hdcMem1 = CreateCompatibleDC (hdc) ; hdcMem2 = CreateCompatibleDC (hdc) ; DeleteDC (hdc) ; // Get the dimensions of the bitmap to be stretched GetObject (hBitmap1, sizeof (BITMAP), (PTSTR) &bm1) ; // Scale these dimensions based on the system font size bm2 = 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 size hBitmap2 = CreateBitmapIndirect (&bm2) ; // Select the bitmaps in the memory DCs and do a StretchBlt SelectObject (hdcMem1, hBitmap1) ; SelectObject (hdcMem2, hBitmap2) ; StretchBlt (hdcMem2, 0, 0, bm2.bmWidth, bm2.bmHeight, hdcMem1, 0, 0, bm1.bmWidth, bm1.bmHeight, SRCCOPY) ; // Clean up DeleteDC (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 hFont ; SIZE size ; TEXTMETRIC tm ; 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])) ; This document is created with the unregistered version of CHM2PDF Pilot Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com 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 menu hMenu = GetSystemMenu (hwnd, FALSE); GetMenuItemInfo (hMenu, IDM_HELP, FALSE, &mii) ; DeleteObject ((HBITMAP) mii.dwTypeData) ; // Delete top-level menu bitmaps hMenu = GetMenu (hwnd) ; for (i = 0 ; i < 3 ; i++) { GetMenuItemInfo (hMenu, i, TRUE, &mii) ; DeleteObject ((HBITMAP) mii.dwTypeData) ; } // Delete bitmap items on Font menu hMenu = mii.hSubMenu ;; for (i = 0 ; i < 3 ; i++) { GetMenuItemInfo (hMenu, i, TRUE, &mii) ; DeleteObject ((HBITMAP) mii.dwTypeData) ; } } This document is created with the unregistered version of CHM2PDF Pilot Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com GRAFMENU.RC (excerpts) //Microsoft Developer Studio generated resource script. #include "resource.h" #include "afxres.h" ///////////////////////////////////////////////////////////////////////////// // Menu MENUFILE MENU DISCARDABLE BEGIN MENUITEM "&New", IDM_FILE_NEW MENUITEM "&Open ", IDM_FILE_OPEN MENUITEM "&Save", IDM_FILE_SAVE MENUITEM "Save &As ", IDM_FILE_SAVE_AS END MENUEDIT MENU DISCARDABLE BEGIN MENUITEM "&Undo", IDM_EDIT_UNDO MENUITEM SEPARATOR MENUITEM "Cu&t", IDM_EDIT_CUT MENUITEM "&Copy", IDM_EDIT_COPY MENUITEM "&Paste", IDM_EDIT_PASTE MENUITEM "De&lete", IDM_EDIT_CLEAR END ///////////////////////////////////////////////////////////////////////////// // Bitmap BITMAPFONT BITMAP DISCARDABLE "Fontlabl.bmp" BITMAPHELP BITMAP DISCARDABLE "Bighelp.bmp" BITMAPEDIT BITMAP DISCARDABLE "Editlabl.bmp" BITMAPFILE BITMAP DISCARDABLE "Filelabl.bmp" This document is created with the unregistered version of CHM2PDF Pilot Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com RESOURCE.H (excerpts // Microsoft Developer Studio generated include file. // 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 40013 EDITLABL.BMP FILELABL.BMP FONTLABL.BMP This document is created with the unregistered version of CHM2PDF Pilot Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com BIGHELP.BMP To insert a bitmap into a menu, you use AppendMenu or InsertMenu. The bitmap can come from one of two places. You can create a bitmap in Visual C++ Developer Studio, include the bitmap file in your resource script, and within the program use LoadBitmap to load the bitmap resource into memory. You then call AppendMenu or InsertMenu to attach it to the menu. There's a problem with this approach, however. The bitmap might not be suitable for all types of video resolutions and aspect ratios; you probably want to stretch the loaded bitmap to account for this. Alternatively, you can create the bitmap right in the program, select it into a memory device context, draw on it, and then attach it to the menu. The GetBitmapFont function in GRAFMENU takes a parameter of 0, 1, or 2 and returns a handle to a bitmap. This bitmap contains the string "Courier New," "Arial," or "Times New Roman" in the appropriate font and about twice the size of the normal system font. Let's see how GetBitmapFont does it. (The code that follows is not the same as that in the GRAFMENU.C file. For purposes of clarity, I've replaced references to the szFaceName array with the values appropriate for the Arial font.) The first steps are to determine the size of the system font by using the TEXTMETRIC structure and to create a memory device context compatible with the screen: hdc = CreateIC (TEXT ("DISPLAY"), NULL, NULL, NULL) ; GetTextMetrics (hdc, &tm) ; hdcMem = CreateCompatibleDC (hdc) ; The CreateFont function creates a logical font that is twice the height of the system font and has a facename of "Arial": hFont = CreateFont (2 * tm.tmHeight, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, TEXT ("Arial")) ; This font is selected in the memory device context and the default font handle is saved: This document is created with the unregistered version of CHM2PDF Pilot Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com hFont = (HFONT) SelectObject (hdcMem, hFont) ; Now when we write some text to the memory device context, Windows will use the TrueType Arial font selected into the device context. But this memory device context initially has a one-pixel monochrome device surface. We have to create a bitmap large enough for the text we want to display on it. You can obtain the dimensions of the text through GetTextExtentPoint32 and create a bitmap based on these dimensions with CreateBitmap: GetTextExtentPoint32 (hdcMem, TEXT ("Arial"), 5, &size) ; hBitmap = CreateBitmap (size.cx, size.cy, 1, 1, NULL) ; SelectObject (hdcMem, hBitmap) ; This device context now has a monochrome display surface exactly the size of the text. Now all we have to do is write the text to it: TextOut (hdcMem, 0, 0, TEXT ("Arial"), 5) ; We're finished, except for cleaning up. To do so, we select the system font (with handle hFont) back into the device context by using SelectObject, and we delete the previous font handle that SelectObject returns, which is the handle to the Arial font: DeleteObject (SelectObject (hdcMem, hFont)) ; Now we can also delete the two device contexts: DeleteDC (hdcMem) ; DeleteDC (hdc) ; We're left with a bitmap that has the text "Arial" in an Arial font. The memory device context also comes to the rescue when we need to scale fonts to a different display resolution or aspect ratio. I created the four bitmaps used in GRAFMENU to be the correct size for a display that has a system font height of 8 pixels and width of 4 pixels. For other system font dimensions, the bitmap has to be stretched. This is done in GRAFMENU's StretchBitmap function. The first step is to get the device context for the screen, obtain the text metrics for the system font, and create two memory device contexts: hdc = CreateIC (TEXT ("DISPLAY"), NULL, NULL, NULL) ; GetTextMetrics (hdc, &tm) ; hdcMem1 = CreateCompatibleDC (hdc) ; hdcMem2 = CreateCompatibleDC (hdc) ; DeleteDC (hdc) ; This document is created with the unregistered version of CHM2PDF Pilot Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com The bitmap handle passed to the function is hBitmap1. The program can obtain the dimensions of this bitmap using GetObject: GetObject (hBitmap1, sizeof (BITMAP), (PSTR) &bm1) ; This copies the dimensions into a structure bm1 of type BITMAP. The structure bm2 is set equal to bm1, and then certain fields are modified based on the system font dimensions: bm2 = bm1 ; bm2.bmWidth = (tm.tmAveCharWidth * bm2.bmWidth) / 4 ; bm2.bmHeight = (tm.tmHeight * bm2.bmHeight) / 8 ; bm2.bmWidthBytes = ((bm2.bmWidth + 15) / 16) * 2 ; Next a new bitmap with handle hBitmap2 can be created that is based on the altered dimensions: hBitmap2 = CreateBitmapIndirect (&bm2) ; You can then select these two bitmaps into the two memory device contexts: SelectObject (hdcMem1, hBitmap1) ; SelectObject (hdcMem2, hBitmap2) ; We want to copy the first bitmap to the second bitmap and stretch it in the process. This involves the StretchBlt call: StretchBlt (hdcMem2, 0, 0, bm2.bmWidth, bm2.bmHeight, hdcMem1, 0, 0, bm1.bmWidth, bm1.bmHeight, SRCCOPY) ; Now the second bitmap has the properly scaled bitmap. We'll use that one in the menu. As you can see below, cleanup is simple. DeleteDC (hdcMem1) ; DeleteDC (hdcMem2) ; DeleteObject (hBitmap1) ; The CreateMyMenu function in GRAFMENU uses the StretchBitmap and GetBitmapFont functions when constructing the menu. GRAFMENU has two menus already defined in the resource script. These will become popups for the File and Edit options. The function begins by obtaining a handle to an empty menu: hMenu = CreateMenu () ; The popup menu for File (containing the four options New, Open, Save, and Save As) is loaded from the resource script: This document is created with the unregistered version of CHM2PDF Pilot Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com hMenuPopup = LoadMenu (hInstance, TEXT ("MenuFile")) ; The bitmap containing the word "FILE" is also loaded from the resource script and stretched using StretchBitmap: hBitmapFile = StretchBitmap (LoadBitmap (hInstance, TEXT ("BitmapFile"))) ; The bitmap handle and popup menu handle become arguments to the AppendMenu call: AppendMenu (hMenu, MF_BITMAP MF_POPUP, hMenuPopup, (PTSTR) (LONG) hBitmapFile) ; The same procedure is followed for the Edit menu: hMenuPopup = LoadMenu (hInstance, TEXT ("MenuEdit")) ; hBitmapEdit = StretchBitmap (LoadBitmap (hInstance, TEXT ("BitmapEdit"))) ; AppendMenu (hMenu, MF_BITMAP MF_POPUP, hMenuPopup, (PTSTR) (LONG) hBitmapEdit) ; The popup menu for the three fonts is constructed from calls to the GetBitmapFont function: hMenuPopup = CreateMenu () ; for (i = 0 ; i < 3 ; i++) { hBitmapPopFont [i] = GetBitmapFont (i) ; AppendMenu (hMenuPopup, MF_BITMAP, IDM_FONT_COUR + i, (PTSTR) (LONG) hMenuPopupFont [i]) ; } The popup is then added to the menu: hBitmapFont = StretchBitmap (LoadBitmap (hInstance, "BitmapFont")) ; AppendMenu (hMenu, MF_BITMAP MF_POPUP, hMenuPopup, (PTSTR) (LONG) hBitmapFont) ; The window menu is now complete, and WndProc makes it the window's menu by a call to SetMenu. GRAFMENU also alters the system menu in the AddHelpToSys function. The function first obtains a handle to the system menu: hMenu = GetSystemMenu (hwnd, FALSE) ; This loads the "Help" bitmap and stretches it to an appropriate size: hBitmapHelp = StretchBitmap (LoadBitmap (hInstance, TEXT ("BitmapHelp"))) ; This adds a separator bar and the stretched bitmap to the system menu: This document is created with the unregistered version of CHM2PDF Pilot Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com AppendMenu (hMenu, MF_SEPARATOR, 0, NULL) ; AppendMenu (hMenu, MF_BITMAP, IDM_HELP, (PTSTR)(LONG) hBitmapHelp) ; GRAFMENU devotes a whole function to cleaning up and deleting all the bitmaps before the program terminates. A couple of miscellaneous notes on using bitmap in menus now follow. In a top-level menu, Windows adjusts the menu bar height to accommodate the tallest bitmap. Other bitmaps (or character strings) are aligned at the top of the menu bar. The size of the menu bar obtained from GetSystemMetrics with the SM_CYMENU constant is no longer valid after you put bitmaps in a top-level menu. As you can see from playing with GRAFMENU, you can use check marks with bitmapped menu items in popups, but the check mark is of normal size. If that bothers you, you can create a customized check mark and use SetMenuItemBitmaps. Another approach to using nontext (or text in a font other than the system font) on a menu is the "owner-draw" menu. The keyboard interface to menus is another problem. When the menu contains text, Windows automatically adds a keyboard interface. You can select a menu item using the Alt key in combination with a letter of the character string. But once you put a bitmap in a menu, you've eliminated that keyboard interface. Even if the bitmap says something, Windows doesn't know about it. This is where the WM_MENUCHAR message comes in handy. Windows sends a WM_MENUCHAR message to your window procedure when you press Alt with a character key that does not correspond to a menu item. GRAFMENU would need to intercept WM_MENUCHAR messages and check the value of wParam (the ASCII character of the pressed key). If this corresponds to a menu item, it would have to return a double word to Windows, where the high word is set to 2 and the low word is set to the index of the menu item we want associated with that key. Windows does the rest. Nonrectangular Bitmap Images Bitmaps are always rectangular, but they needn't be displayed like that. For example, suppose you have a rectangular bitmap image that you want to be displayed as an ellipse. At first, this sounds simple. You just load the image into Visual C++ Developer Studio or the Windows Paint program (or a more expensive application) and you start drawing around the outside of the image with a white pen. You're left with an elliptical image with everything outside the ellipse painted white. This will work but only when you display the bitmap on a white background. If you display it on any other color background, you'll have an elliptical image on top of a white rectangle on top of a colored background. That's no good. There's a very common technique to solve problems like this. The technique involves a "mask" bitmap and some raster operations. A mask is a monochrome bitmap of the same dimensions as the rectangular bitmap image you want to display. Each mask pixel corresponds with a pixel of the bitmap image. The mask pixels are 1 (white) wherever the original bitmap pixel is to be displayed, and 0 (black) wherever you want to preserve the destination background. (Or the mask bitmap can be opposite this, with some corresponding changes to the raster operations you use.) Let's see how this works in real life in the BITMASK program shown in Figure 14-17. Figure 14-17. The BITMASK program. This document is created with the unregistered version of CHM2PDF Pilot Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com [...]... version of CHM 2PDF Pilot I find BLOWUP to be very useful for examining the multitude of little bitmaps and pictures that are scattered Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com throughout Windows and its applications This document is created with the unregistered version of CHM 2PDF Pilot Simpo PDF Merge Chapter 15 and Split Unregistered Version - http://www.simpopdf.com The... because you're running in a 16- color or 2 56- color video mode With the 16- color mode, there's not much you can do to improve things, but an application running in a 2 56- color mode can alter the color palette to display shades of gray You'll find out how in Chapter 16 Some Simple Animation Because the display of small bitmaps is quite fast, you can use bitmaps in combination with the Windows timer for some... } Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com EndPaint (hwnd, &ps) ; return 0 ; case WM_DESTROY: if (hBitmap) DeleteObject (hBitmap) ; PostQuitMessage (0) ; return 0 ; } return DefWindowProc (hwnd, message, wParam, lParam) ; } This document is created with the unregistered version of CHM 2PDF Pilot Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com... by the Windows API If you have a DIB in memory, you can supply pointers to that DIB as arguments to several functions that let you display the DIB or convert it into a DDB This document is created with the unregistered version of CHM 2PDF Pilot Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com The DIB File Format Interestingly enough, the DIB format did not originate in Windows. .. OS/2 to include a Windows- like graphical user interface, known as the Presentation Manager (PM) The Presentation Manager included the Graphics Programming Interface (GPI), which defined the bitmap format That OS/2 bitmap format was then used in Windows 3.0 (released in 1990), where it came to be known as the DIB Windows 3.0 also included a variation of the original DIB format that under Windows has come... that under Windows has come to be the standard Additional enhancements were defined in Windows 95 (and Windows NT 4.0) and Windows 98 (and Windows NT 5.0), as I'll discuss in this chapter The DIB is best examined first as a file format DIB files have the filename extension BMP or, more rarely, DIB Bitmap images used by Windows applications (for example, on the surfaces of buttons) are created as DIB files... version of CHM 2PDF Pilot BITMAPCOREINFO, * PBITMAPCOREINFO ; Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com This structure combines the information header with the color table Although the number of RGBTRIPLE structures is seemingly equal to 1 in this structure, you'll never find just one RGBTRIPLE in a DIB file The size of the color table is always 2, 16, or 2 56 RGBTRIPLE structures,...This document is created with the unregistered version of CHM 2PDF Pilot Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com BITMASK.C /* BITMASK.C Bitmap Masking Demonstration (c) Charles Petzold, 1998 -*/ #include LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ; int WINAPI WinMain (HINSTANCE... context Figure 14-19 The BOUNCE program This document is created with the unregistered version of CHM 2PDF Pilot Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com BOUNCE.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... 14-20 The SCRAMBLE program This document is created with the unregistered version of CHM 2PDF Pilot SCRAMBLE.C /* -Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com SCRAMBLE.C Scramble (and Unscramble) Screen (c) Charles Petzold, 1998 */ #include #define NUM 300 LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ; int . CHM 2PDF Pilot Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com hFont = (HFONT) SelectObject (hdcMem, hFont) ; Now when we write some text to the memory device context, Windows. of CHM 2PDF Pilot Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com BITMASK.C /* BITMASK.C Bitmap Masking Demonstration (c) Charles Petzold, 1998 */ #include < ;windows. h> LRESULT. hdcMemMask, 0, 0, 0x2203 26) ; This document is created with the unregistered version of CHM 2PDF Pilot Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com This uses a raster