Windows程序设计-位图和位块传输
来源:互联网 发布:telnet登录端口 编辑:程序博客网 时间:2024/06/04 19:27
位块传输(BitBlt)
bitblt(bit block transfer)
BITBLT.C
/*--------------------------------------- BITBLT.C -- BitBlt Demonstration (c) Charles Petzold, 1998 ---------------------------------------*/#include <windows.h>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_CXSMICON) ; 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 < cyClient ; y += cySource) for (x = 0 ; x < cxClient ; x += cxSource) { // 位块传输 BitBlt (hdcClient, x, y, cxSource, cySource, hdcWindow, 0, 0, SRCCOPY) ; } ReleaseDC (hwnd, hdcWindow) ; EndPaint (hwnd, &ps) ; return 0 ; case WM_DESTROY: PostQuitMessage (0) ; return 0 ; } return DefWindowProc (hwnd, message, wParam, lParam) ;}
拉伸位图(StretchBlt)
/*---------------------------------------- STRETCH.C -- StretchBlt Demonstration (c) Charles Petzold, 1998 ----------------------------------------*/#include <windows.h>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 (SM_CXSMICON) ; 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) ; 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) ;}
光栅(位映像)操作
BitBlt和StretchBlt函数不是简单的位块传输。此函数实际在下面三种图像间执行位操作:
- Source 来源位图,拉伸或压缩(如果有必要)到目的矩形的尺寸。
- 目标(Destination)在BitBlt或StretchBlt调用之前的目的矩形。
- 图案(Pattern)在目标设备内容中选择的目前画刷,水平或垂直地不断重复复制到目的矩形范围内。
图案Blt(PatBlt)
Pattern block transfer 图案块传输
PatBlt (hdc, x, y, cx, cy, dwROP);
x、y、cx和cy参数字于逻辑单位。逻辑点(x,y)指定了矩形的左上角。矩形宽为cx单位,高为cy单位。这是PatBlt修改的矩形区域。PatBlt在画刷与目的设备内容上执行的逻辑操作由dwROP参数决定,此参数是ROP代码的子集-也就是说,您可以只使用那些不包括来源目的设备内容的ROP代码。
GDI位图对象
GDI位图对象有时也称为设备相关位图,或者DDB(device-dependent bitmap)。
不 要 用 CreateBitmap 、 CreateBitmapIndirect 或SetBitmapBits来设定彩色DDB的位,您只能安全地使用这些函数来设定单色DDB的位。
LoadBitmap
/*---------------------------------------- BRICKS1.C -- LoadBitmap Demonstration (c) Charles Petzold, 1998 ----------------------------------------*/#include <windows.h>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) { case WM_CREATE: hInstance = ((LPCREATESTRUCT) lParam)->hInstance ; // 加载位图 hBitmap = LoadBitmap (hInstance, TEXT ("Bricks")) ; // 获取对象信息,并填满BITMAP结构的bitmap 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 = CreateCompatibleDC (hdc) ; // 把位图选入内存设备内容 SelectObject (hdcMem, hBitmap) ; for (y = 0 ; y < cyClient ; y += cySource) for (x = 0 ; x < cxClient ; x += cxSource) { BitBlt (hdc, x, y, cxSource, cySource, hdcMem, 0, 0, SRCCOPY) ; } // 删除内存设备内容 DeleteDC (hdcMem) ; EndPaint (hwnd, &ps) ; return 0 ; case WM_DESTROY: DeleteObject (hBitmap) ; PostQuitMessage (0) ; return 0 ; } return DefWindowProc (hwnd, message, wParam, lParam) ;}
单色位图格式
未使用资源
/*----------------------------------------- BRICKS2.C -- CreateBitmap Demonstration (c) Charles Petzold, 1998 -----------------------------------------*/#include <windows.h>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 BITMAP bitmap = { 0, 8, 8, 2, 1, 1 } ; static BYTE bits [8][2] = { 0xFF, 0, 0x0C, 0, 0x0C, 0, 0x0C, 0, 0xFF, 0, 0xC0, 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 = CreateCompatibleDC (hdc) ; SelectObject (hdcMem, hBitmap) ; for (y = 0 ; y < cyClient ; y += cySource) for (x = 0 ; x < cxClient ; x += cxSource) { BitBlt (hdc, x, y, cxSource, cySource, hdcMem, 0, 0, SRCCOPY) ; } DeleteDC (hdcMem) ; EndPaint (hwnd, &ps) ; return 0 ; case WM_DESTROY: DeleteObject (hBitmap) ; PostQuitMessage (0) ; return 0 ; } return DefWindowProc (hwnd, message, wParam, lParam) ;}
窗口类画刷
/*----------------------------------------------- BRICKS3.C -- CreatePatternBrush Demonstration (c) Charles Petzold, 1998 -----------------------------------------------*/#include <windows.h>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 msg ; WNDCLASS wndclass ; hBitmap = LoadBitmap (hInstance, TEXT ("Bricks")) ; hBrush = CreatePatternBrush (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 ; if (!RegisterClass (&wndclass)) { MessageBox (NULL, TEXT ("This program requires Windows NT!"), 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) ;}
绘制画刷
HelloBit.rc
///////////////////////////////////////////////////////////////////////////////// Menu//HELLOBIT MENU DISCARDABLE BEGIN POPUP "&Size" BEGIN MENUITEM "&Big", IDM_BIG, CHECKED MENUITEM "&Small", IDM_SMALL ENDEND
RESOURCE.H
#define IDM_BIG 40001#define IDM_SMALL 40002
HelloBit.c
/*----------------------------------------- HELLOBIT.C -- Bitmap Demonstration (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 ; 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 = 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_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 < cyClient ; y += cyBitmap) for (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) ;}
阴影位图
/*----------------------------------------- SKETCH.C -- Shadow Bitmap Demonstration (c) Charles Petzold, 1998 -----------------------------------------*/#include <windows.h>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) ; // EnumDisplaySettings使用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: if (!fLeftButtonDown) SetCapture (hwnd) ; xMouse = LOWORD (lParam) ; yMouse = HIWORD (lParam) ; fRightButtonDown = TRUE ; return 0 ; case WM_RBUTTONUP: if (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) ;}
在菜单中使用位图
在顶层菜单中,Windows调整菜单列的高度以适应最高的位图。其它位图(或字符串)是根据菜单列的顶端对齐的。如果在顶层菜单中使用了位图,那么从使用常数SM_CYMENU的GetSystemMetrics得到的菜单列大小将不再有效。
执行GRAFMENU期间可以看到:在弹出式菜单中,您可使用带有位图菜单项的勾选标记,但勾选标记是正常尺寸。如果不满意,您可以建立一个自订的勾选标记,并使用SetMenuItemBitmaps。
在菜单中使用非文字(或者使用非系统字体的文字)的另一种方法是「拥有者绘制」菜单。
菜单的键盘接口是另一个问题。当菜单含有文字时,Windows会自动添加键盘接口。要选择一个菜单项,可以使用Alt与字符串中的一个字母的组合键。而一旦在菜单中放置了位图,就删除了键盘接口。即使位图表达了一定的含义,但Windows并不知道。
目前我们可以使用WM_MENUCHAR消息。 当您按下Alt和与菜单项不相符的一个字符键的组合键时,Windows将向您的窗口消息处理程序发送一个WM_MENUCHAR消息。
GRAFMENU需要截取WM_MENUCHAR消息并检查wParam的值(即按键的ASCII码)。
如果这个值对应一个菜单项,那么向Windows传回双字组:其中高字组为2,低字组是与该键相关的菜单项索引值。然后由Windows处理余下的事。
在顶层菜单中,Windows调整菜单列的高度以适应最高的位图。其它位图(或字符串)是根据
菜单列的顶端对齐的。如果在顶层菜单中使用了位图,那么从使用常数SM_CYMENU的
GetSystemMetrics得到的菜单列大小将不再有效。
执行GRAFMENU期间可以看到:在弹出式菜单中,您可使用带有位图菜单项的勾选标记,
但勾选标记是正常尺寸。如果不满意,您可以建立一个自订的勾选标记,并使用
SetMenuItemBitmaps。
在菜单中使用非文字(或者使用非系统字体的文字)的另一种方法是「拥有者绘制」菜单。
菜单的键盘接口是另一个问题。当菜单含有文字时,Windows会自动添加键盘接口。要选
择一个菜单项,可以使用Alt与字符串中的一个字母的组合键。而一旦在菜单中放置了位图,
就删除了键盘接口。即使位图表达了一定的含义,但Windows并不知道。
目前我们可以使用WM_MENUCHAR消息。 当您按下Alt和与菜单项不相符的一个字符键的
组合键时,Windows将向您的窗口消息处理程序发送一个WM_MENUCHAR消息。
GRAFMENU需要截取WM_MENUCHAR消息并检查wParam的值(即按键的ASCII码)。
如果这个值对应一个菜单项,那么向Windows传回双字组:其中高字组为2,低字组是与该键相关的菜单项索引值。然后由Windows处理余下的事。
GrafMenu.rc
///////////////////////////////////////////////////////////////////////////////// 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_ASENDMENUEDIT 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_CLEAREND///////////////////////////////////////////////////////////////////////////////// Bitmap//BITMAPFONT BITMAP DISCARDABLE "Fontlabl.bmp"BITMAPHELP BITMAP DISCARDABLE "Bighelp.bmp"BITMAPEDIT BITMAP DISCARDABLE "Editlabl.bmp"BITMAPFILE BITMAP DISCARDABLE "Filelabl.bmp"#endif // English (U.S.) resources/////////////////////////////////////////////////////////////////////////////
RESOURCE.H
#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
GrafMenu.c
/*---------------------------------------------- GRAFMENU.C -- Demonstrates Bitmap Menu Items (c) Charles Petzold, 1998 ----------------------------------------------*/#include <windows.h>#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 ; if (!RegisterClass (&wndclass)) { MessageBox (NULL, TEXT ("This program requires Windows NT!"), szAppName, MB_ICONERROR) ; return 0 ; } hwnd = CreateWindow (szAppName, TEXT ("Bitmap Menu Demonstration"), 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){ 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 ----------------------------------------------*/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 // 获得显示器设备内容 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])) ; // 收尾清除工作 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) ; }}
非矩形位图图像
遮罩
BitMask.rc
///////////////////////////////////////////////////////////////////////////////// Bitmap//MATTHEW BITMAP DISCARDABLE "matthew.bmp"
BitMask.c
/*------------------------------------------- BITMASK.C -- Bitmap Masking Demonstration (c) Charles Petzold, 1998 -------------------------------------------*/#include <windows.h>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 size // 获取原始图像句柄 hBitmapImag = LoadBitmap (hInstance, TEXT ("Matthew")) ; // 获取图像宽高 GetObject (hBitmapImag, sizeof (BITMAP), &bitmap) ; cxBitmap = bitmap.bmWidth ; cyBitmap = bitmap.bmHeight ; // Select the original image into a memory DC // 选入内存设备内容 hdcMemImag = CreateCompatibleDC (NULL) ; SelectObject (hdcMemImag, hBitmapImag) ; // Create the monochrome mask bitmap and memory DC // 创建与原图一样大的遮罩 hBitmapMask = CreateBitmap (cxBitmap, cyBitmap, 1, 1, NULL) ; hdcMemMask = CreateCompatibleDC (NULL) ; // 选入内存设备内容 SelectObject (hdcMemMask, hBitmapMask) ; // Color the mask bitmap black with a white ellipse // 在遮罩上换一个黑色0矩形和白色1椭圆 SelectObject (hdcMemMask, GetStockObject (BLACK_BRUSH)) ; Rectangle (hdcMemMask, 0, 0, cxBitmap, cyBitmap) ; SelectObject (hdcMemMask, GetStockObject (WHITE_BRUSH)) ; Ellipse (hdcMemMask, 0, 0, cxBitmap, cyBitmap) ; // Mask the original image // 用MaskBlt更方便 Win98不支持 // 用遮罩屏蔽原图像 AND操作 BitBlt (hdcMemImag, 0, 0, cxBitmap, cyBitmap, hdcMemMask, 0, 0, SRCAND) ; DeleteDC (hdcMemImag) ; DeleteDC (hdcMemMask) ; return 0 ; 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 // 屏蔽掉椭圆:D & ~S (反色来源,然后AND目标) BitBlt (hdc, x, y, cxBitmap, cyBitmap, hdcMemMask, 0, 0, 0x220326) ; // 绘制位图 OR BitBlt (hdc, x, y, cxBitmap, cyBitmap, hdcMemImag, 0, 0, SRCPAINT) ; DeleteDC (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) ;}
简单的动画
高级动画选DirectX,就不要用GDI了。
/*--------------------------------------- BOUNCE.C -- Bouncing Ball Program (c) Charles Petzold, 1998 ---------------------------------------*/#include <windows.h>#define ID_TIMER 1LRESULT 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 (hdcMem, 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) ; // 使用ROP代码为SRCCOPY,来重画小球 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) || (xCenter - 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) ;}
窗口外的位图
在窗口产生矩形位图
/*------------------------------------------------ SCRAMBLE.C -- Scramble (and Unscramble) Screen (c) Charles Petzold, 1998 ------------------------------------------------*/#include <windows.h>#define NUM 300LRESULT 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 ; // LockWindowUpdate暂停其他程序更新屏幕 if (LockWindowUpdate (hwnd = GetDesktopWindow ())) { // 带DCX_LOCKWINDOWUPDATE,获得整个屏幕的设备内容 hdcScr = GetDCEx (hwnd, NULL, DCX_CACHE | DCX_LOCKWINDOWUPDATE) ; hdcMem = CreateCompatibleDC (hdcScr) ; // 使用长宽为1/10的屏幕大小来建立位图 cx = GetSystemMetrics (SM_CXSCREEN) / 10 ; cy = GetSystemMetrics (SM_CYSCREEN) / 10 ; hBitmap = CreateCompatibleBitmap (hdcScr, cx, cy) ; SelectObject (hdcMem, hBitmap) ; // 产生两个随机坐标 srand ((int) GetCurrentTime ()) ; for (i = 0 ; i < 2 ; i++) for (j = 0 ; j < NUM ; j++) { if (i == 0) { iKeep [j] [0] = x1 = cx * (rand () % 10) ; iKeep [j] [1] = y1 = cy * (rand () % 10) ; iKeep [j] [2] = x2 = cx * (rand () % 10) ; iKeep [j] [3] = y2 = cy * (rand () % 10) ; } else { x1 = iKeep [NUM - 1 - j] [0] ; y1 = iKeep [NUM - 1 - j] [1] ; x2 = iKeep [NUM - 1 - j] [2] ; y2 = iKeep [NUM - 1 - j] [3] ; } // 交换显示器上两个矩形中的内容: // 将从第一个坐标点开始的矩形复制到内存设备内容 BitBlt (hdcMem, 0, 0, cx, cy, hdcScr, x1, y1, SRCCOPY) ; // 将从第二坐标点开始的矩形复制到第一点开始的位置 BitBlt (hdcScr, x1, y1, cx, cy, hdcScr, x2, y2, SRCCOPY) ; // 将内存设备内容中的矩形复制到第二个坐标点开始的区域 BitBlt (hdcScr, x2, y2, cx, cy, hdcMem, 0, 0, SRCCOPY) ; Sleep (10) ; } DeleteDC (hdcMem) ; ReleaseDC (hwnd, hdcScr) ; DeleteObject (hBitmap) ; LockWindowUpdate (NULL) ; } return FALSE ;}
截屏
Blowup.rc
//////////////////////////////////////////////////////////////////////////////// Menu//BLOWUP MENU DISCARDABLE BEGIN POPUP "&Edit" BEGIN MENUITEM "Cu&t\tCtrl+X", IDM_EDIT_CUT MENUITEM "&Copy\tCtrl+C", IDM_EDIT_COPY MENUITEM "&Paste\tCtrl+V", IDM_EDIT_PASTE MENUITEM "De&lete\tDelete", IDM_EDIT_DELETE ENDEND///////////////////////////////////////////////////////////////////////////////// Accelerator//BLOWUP ACCELERATORS DISCARDABLE BEGIN "C", IDM_EDIT_COPY, VIRTKEY, CONTROL, NOINVERT "V", IDM_EDIT_PASTE, VIRTKEY, CONTROL, NOINVERT VK_DELETE, IDM_EDIT_DELETE, VIRTKEY, NOINVERT "X", IDM_EDIT_CUT, VIRTKEY, CONTROL, NOINVERTEND#endif
RESOURCE.H
#define IDM_EDIT_CUT 40001#define IDM_EDIT_COPY 40002#define IDM_EDIT_PASTE 40003#define IDM_EDIT_DELETE 40004
Blowup.c
/*--------------------------------------- BLOWUP.C -- Video Magnifier Program (c) Charles Petzold, 1998 ---------------------------------------*/#include <windows.h>#include <windowsx.h> //Added by translator#include <stdlib.h> // 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 ; if (!RegisterClass (&wndclass)) { MessageBox (NULL, TEXT ("This program requires Windows NT!"), 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 (!TranslateAccelerator (hwnd, hAccel, &msg)) { TranslateMessage (&msg) ; DispatchMessage (&msg) ; } } return msg.wParam ;}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, SRCCOPY) ; 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 rect ; switch (message) { case WM_LBUTTONDOWN: if (!bCapturing) { if (LockWindowUpdate (hwndScr = GetDesktopWindow ())) { bCapturing = TRUE ; SetCapture (hwnd) ; SetCursor (LoadCursor (NULL, IDC_CROSS)) ; } else MessageBeep (0) ; } return 0 ; case WM_RBUTTONDOWN: if (bCapturing) { bBlocking = TRUE ; //ptBeg.x = LOWORD (lParam) ; //wrong code //ptBeg.y = HIWORD (lParam) ; ptBeg.x = GET_X_LPARAM(lParam) ; //added by translator: should use GET_X_LPARAM/GET_Y_LPARAM to retreive the co-ordination ptBeg.y = GET_Y_LPARAM(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) ; ptEnd.x = GET_X_LPARAM(lParam) ; ptEnd.y = GET_Y_LPARAM(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) ; ptEnd.x = GET_X_LPARAM(lParam) ; ptEnd.y = GET_Y_LPARAM(lParam) ; if (hBitmap) { DeleteObject (hBitmap) ; hBitmap = NULL ; } hdc = GetDC (hwnd) ; hdcMem = CreateCompatibleDC (hdc) ; hBitmap = CreateCompatibleBitmap (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: iEnable = IsClipboardFormatAvailable (CF_BITMAP) ? MF_ENABLED : MF_GRAYED ; EnableMenuItem ((HMENU) wParam, IDM_EDIT_PASTE, iEnable) ; iEnable = 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_CUT case 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, &rect) ; 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) ;}
- Windows程序设计-位图和位块传输
- 《Windows程序设计》之位块传输
- 位图和位块传输(3)之加载位图资源
- 第十四章 位图和Bitblt(位块传输)
- 位图和位块传输(1)BitBlt与PatBlt
- 位图和位块传输(5)之画图程序
- 第 14 章 位图和位块传输
- 位图和位块传输(4)位图画刷与画画
- 位图和位块传输(2)压缩拉伸之StretchBlt函数
- 位图和位块传输(6)画框与会移动的小球
- windows程序设计:位图和bitblt
- 14.3 位块传输
- windows 程序设计 位图
- 《Windows程序设计》之位图操作
- MFC Windows程序设计--位图,区域
- Windows程序设计-设备无关位图
- Windows程序设计:位图的显示
- 位图和像素位
- Dubbo与Zookeeper、SpringMVC整合和使用(负载均衡、容错)
- spark中map和flatmap之间的区别
- 愿世界没有技术面全是Hr面
- 编程笔记
- 字符串作为数组下标
- Windows程序设计-位图和位块传输
- int main (int argc ,char *argv[])
- android studio中如何设置注释模板---项目开发规范
- 关于double计算精度丢失解决办法
- Axure8.0汉化包+注册码
- C#设计模式—单例模式
- win10JAVA环境变量的配置及解决输入javac提示不是内部命令
- leetcode 226. Invert Binary Tree 反转二叉树 + DFS深度优先搜索
- Apache Spark 2.2.0 中文文档