Windows程序设计-位图和位块传输
位块传输(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结构的bitmapGetObject (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
BEGINPOPUP "&Size"BEGINMENUITEM "&Big", IDM_BIG, CHECKEDMENUITEM "&Small", IDM_SMALLEND
END
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
BEGINMENUITEM "&New", IDM_FILE_NEWMENUITEM "&Open...", IDM_FILE_OPENMENUITEM "&Save", IDM_FILE_SAVEMENUITEM "Save &As...", IDM_FILE_SAVE_AS
ENDMENUEDIT 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_CLEAR
END/////////////////////////////////////////////////////////////////////////////
//
// 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 charactercxChar = 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 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, SRCCOPY) ;// Clean upDeleteDC (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 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) ;}
}
非矩形位图图像
遮罩
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 DCshdcMemImag = CreateCompatibleDC (hdc) ;SelectObject (hdcMemImag, hBitmapImag) ;hdcMemMask = CreateCompatibleDC (hdc) ;SelectObject (hdcMemMask, hBitmapMask) ;// Center imagex = (cxClient - cxBitmap) / 2 ;y = (cyClient - cyBitmap) / 2 ;// Do the bitblts// 屏蔽掉椭圆:D & ~S (反色来源,然后AND目标)BitBlt (hdc, x, y, cxBitmap, cyBitmap, hdcMemMask, 0, 0, 0x220326) ;// 绘制位图 ORBitBlt (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
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_DELETEEND
END/////////////////////////////////////////////////////////////////////////////
//
// Accelerator
//BLOWUP 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, NOINVERT
END#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)) ;}elseMessageBeep (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-ordinationptBeg.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_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, &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环境下32位汇编语言程序设计(典藏版)(含CD光盘1张)
Windows环境下32位汇编语言程序设计(典藏版)(含CD光盘1张)(畅销10年,经典再现!) 罗云彬 著 ISBN 978-7-121-20759-4 2013年7月出版 定价:99.00元 75 ...
- 琢石成器――windows环境下32位汇编语言程序设计(第三版)笔记
琢石成器――windows环境下32位汇编语言程序设计(第三版)笔记 2011年12月20日 基础篇 第1章 背景知识 1 1.1 Win32的软硬件平台 1.1.1 80x86系列处理器简史 1.1 ...
- Windows环境下32位汇编语言程序设计(典藏版)
<Windows环境下32位汇编语言程序设计(典藏版) > 基本信息 作者: 罗云彬 出版社:电子工业出版社 ISBN:9787121207594 上架时间:2013-7-8 出版日期:2 ...
- 点阵图、矢量图、像素图、位图图像、位元块传输
点阵图 目录 概述 点阵图与矢量图 概述 一般来说点阵图和位图是一个概念.它是由n多的像素组成的. & 它的概念主要是相对于区别矢量图而言的.点阵图和矢量图是现代计算机平面图形的两大概念 ...
- Windows环境下32位汇编语言程序设计 相关资料
Windows环境下32位汇编语言程序设计.pdf:https://474b.com/file/15153148-465076702 <Windows环境下32位汇编语言程序设计>随书光盘 ...
- 简单的Windows程序设计
目录 1 创建图形界面应用 2 VC++数据类型 3 UNICODE字符集 4 MFC对话框应用程序 5 Windows 控件 6 消息驱动与消息映射 7 使用控件变量访问控制控件 8 用户自定义消息 ...
- Windows程序设计-剪贴板
数据格式 内存配置 将文字传送到剪贴簿 从剪贴簿上取得文字 剪贴板的简单使用 延迟提出 自定义数据格式 剪贴板浏览器 Windows剪贴板允许把数据从一个程序传送到另一个程序中.它的原理相对而言比较简 ...
- Windows的位图alpha混合技术
摘 要:本文介绍了在Windows环境下对位图的图像alpha混合技术,提供了alpha混合函数的实现方法,并对Windows API提供的alpha混合函数的使用进行了介绍. 关键词:Windows ...
- [渝粤教育] 中国地质大学 Windows程序设计 复习题 (2)
<Windows程序设计>模拟题 一单选题 1.所有的Windows应用程序都是由()驱动的. A.事件 B.消息 C.命令 D.菜单 2.一般应用程序不会派生自己的()类. A.主框架 ...
- 《Windows 程序设计(第3版)》——6.7 【实例】窗口查看器
本节书摘来自异步社区<Windows 程序设计(第3版)>一书中的第6章,第6.7节,作者:王艳平 , 张铮著,更多章节内容可以访问云栖社区"异步社区"公众号查看 6. ...
最新文章
- app怎么嵌套vue页面_PHP抖音点赞APP【开发】HTML5
- C语言实现Winsocket网络传输数据时乱码问题
- java常规普氏分析法_人脸对齐:Procrustes analysis 普氏分析
- PHPer 面试指南-扩展阅读资源整理
- 【转】Tcl/Tk 漫谈
- 计算机编程告白,程序员的520,五个表白代码,一看就会
- Hibernate拦截器字段加密解密
- 音频文件格式解析与编解码
- 数据恢复基础和进阶教程(二)
- sms 验证码 接收
- leejianjun的博客 PHP生成word并可下载
- 金字塔图表 html,Highcharts 柱形图(柱状图及条形图)之 金字塔图 演示
- 绁炵粡缃戠粶鏁版嵁鏍煎紡,鏂囨湰绁炵粡缃戠粶
- 由歌词引发的模式思考之上篇(FactoryMethod模式)
- 磁盘(含优盘识别)读写速度测试
- 2022年超声波雷达行业研究报告
- Sublime Text 2 - 性感无比的代码编辑器!(推荐阅读)
- 每天听一本书,日精日进
- 【酷柚易汛进销存开源版讲解】什么是核销单
- matlab中nnt,基于MATLAB的边坡稳定性评价方法
热门文章
- uniapp 运行到手机或模拟器
- Ubuntu18.04 谷歌浏览器安装商店助手
- 前台服务java.lang.SecurityException: Permission Denial: startForeground
- Python数据可视化大屏最全教程(全)
- 梦幻西游三维版获取服务器信息,梦幻西游三维版服务器等级提升
- 《SEM长尾搜索营销策略解密》一一2.1 起因:核心词成本过高
- 硬件设计1:常用元器件的选型理论依据
- 3GPP TS 29244-g30 中英文对照 | 7.3 Message Types
- Android APP安全测试
- CytusII 剧情梳理