14.4.7 在位图上绘图
(1)在内存设备环境中绘图(与真实DC不同的是,内存DC的显示表面是个位图)
(2)GetTextExtentPoint32函数:用于确定文本字符串的像素大小。(此大小就是与视频显示兼容的位图的尺寸)。
参数 |
说明 |
hdc |
设备环境句柄 |
lpString |
文本字符串,如szText |
cbString |
文本字符串中字符的个数。如lstrlen(szText) |
lpSize |
指向一个结构体,用来存放结果 |
(3)当显示器的颜色深度和大小改变时,windows会自动改变内存设备环境的彩色分辩率。也就是内存设备环境与视频设备环境仍然会保持兼容。所以在WM_DISPLAYCHANGE消息中不用去关心这个问题。
【HelloBit程序】
效果图
/*------------------------------------------------------------ HELLOBIT.C -- Bitmap Demostration (c) Charles Petzold, 1998 ------------------------------------------------------------*/ #include <windows.h> #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; WNDCLASSEX wndclass; wndclass.style = CS_HREDRAW | CS_VREDRAW; wndclass.cbSize = sizeof(WNDCLASSEX); wndclass.lpfnWndProc = WndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = hInstance; wndclass.hIcon = LoadIcon(hInstance, szAppName); wndclass.hIconSm = LoadIcon(hInstance, szAppName); wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); wndclass.lpszMenuName = szAppName; wndclass.lpszClassName = szAppName; if (!RegisterClassEx(&wndclass)) { MessageBox(NULL, TEXT("This program requires Windows NT!"), szAppName, MB_ICONERROR); return 0; } hwnd = CreateWindow(szAppName, // window class name TEXT("HelloBit"), // window caption WS_OVERLAPPEDWINDOW, // window style CW_USEDEFAULT, // initial x position CW_USEDEFAULT, // initial y position CW_USEDEFAULT, // initial x size CW_USEDEFAULT, // initial y size NULL, // parent window handle NULL, // window menu handle hInstance, // program instance handle NULL); // creation parameters 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) { HDC hdc; static HDC hdcMem; PAINTSTRUCT ps; static int cxBitmap, cyBitmap, cxClient, cyClient, iSize = IDM_BIG; static HBITMAP hBitmap; static TCHAR* szText = TEXT("Hello,World!"); SIZE size; HMENU hMenu; switch (message) { case WM_CREATE: hdc = GetDC(hwnd); hdcMem = CreateCompatibleDC(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_COMMAND: hMenu = GetMenu(hwnd); switch (LOWORD(wParam)) //菜单ID { 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_SIZE: cxClient = LOWORD(lParam); cyClient = HIWORD(lParam); 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 (int y = 0; y < cyClient; y += cyBitmap) for (int x = 0; x < cxClient; x += cxBitmap) { BitBlt(hdc, x, y, cxBitmap, cyBitmap, hdcMem, 0, 0, SRCCOPY); } break; } EndPaint(hwnd, &ps); return 0; case WM_DESTROY: DeleteDC(hdcMem); DeleteObject(hBitmap); PostQuitMessage(0); return 0; } return DefWindowProc(hwnd, message, wParam, lParam); }
//resource.h
//{{NO_DEPENDENCIES}} // Microsoft Developer Studio generated include file. // Used by HelloBit.rc // #define IDM_BIG 40001 #define IDM_SMALL 40002 // Next default values for new objects // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 102 #define _APS_NEXT_COMMAND_VALUE 40003 #define _APS_NEXT_CONTROL_VALUE 1000 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif
//HelloBit.rc
//Microsoft Developer Studio generated resource script. // #include "resource.h" #define APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// // // Generated from the TEXTINCLUDE 2 resource. // #include "afxres.h" ///////////////////////////////////////////////////////////////////////////// #undef APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// // English (U.S.) resources #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) #ifdef _WIN32 LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US #pragma code_page(1252) #endif //_WIN32 #ifdef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // TEXTINCLUDE // 1 TEXTINCLUDE DISCARDABLE BEGIN "resource.h " END 2 TEXTINCLUDE DISCARDABLE BEGIN "#include ""afxres.h"" " "