位块传输(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程序设计-位图和位块传输相关推荐

  1. Windows环境下32位汇编语言程序设计(典藏版)(含CD光盘1张)

    Windows环境下32位汇编语言程序设计(典藏版)(含CD光盘1张)(畅销10年,经典再现!) 罗云彬 著 ISBN 978-7-121-20759-4 2013年7月出版 定价:99.00元 75 ...

  2. 琢石成器――windows环境下32位汇编语言程序设计(第三版)笔记

    琢石成器――windows环境下32位汇编语言程序设计(第三版)笔记 2011年12月20日 基础篇 第1章 背景知识 1 1.1 Win32的软硬件平台 1.1.1 80x86系列处理器简史 1.1 ...

  3. Windows环境下32位汇编语言程序设计(典藏版)

    <Windows环境下32位汇编语言程序设计(典藏版) > 基本信息 作者: 罗云彬 出版社:电子工业出版社 ISBN:9787121207594 上架时间:2013-7-8 出版日期:2 ...

  4. 点阵图、矢量图、像素图、位图图像、位元块传输

    点阵图 目录 概述 点阵图与矢量图 概述 一般来说点阵图和位图是一个概念.它是由n多的像素组成的. &amp 它的概念主要是相对于区别矢量图而言的.点阵图和矢量图是现代计算机平面图形的两大概念 ...

  5. Windows环境下32位汇编语言程序设计 相关资料

    Windows环境下32位汇编语言程序设计.pdf:https://474b.com/file/15153148-465076702 <Windows环境下32位汇编语言程序设计>随书光盘 ...

  6. 简单的Windows程序设计

    目录 1 创建图形界面应用 2 VC++数据类型 3 UNICODE字符集 4 MFC对话框应用程序 5 Windows 控件 6 消息驱动与消息映射 7 使用控件变量访问控制控件 8 用户自定义消息 ...

  7. Windows程序设计-剪贴板

    数据格式 内存配置 将文字传送到剪贴簿 从剪贴簿上取得文字 剪贴板的简单使用 延迟提出 自定义数据格式 剪贴板浏览器 Windows剪贴板允许把数据从一个程序传送到另一个程序中.它的原理相对而言比较简 ...

  8. Windows的位图alpha混合技术

    摘 要:本文介绍了在Windows环境下对位图的图像alpha混合技术,提供了alpha混合函数的实现方法,并对Windows API提供的alpha混合函数的使用进行了介绍. 关键词:Windows ...

  9. [渝粤教育] 中国地质大学 Windows程序设计 复习题 (2)

    <Windows程序设计>模拟题 一单选题 1.所有的Windows应用程序都是由()驱动的. A.事件 B.消息 C.命令 D.菜单 2.一般应用程序不会派生自己的()类. A.主框架 ...

  10. 《Windows 程序设计(第3版)》——6.7 【实例】窗口查看器

    本节书摘来自异步社区<Windows 程序设计(第3版)>一书中的第6章,第6.7节,作者:王艳平 , 张铮著,更多章节内容可以访问云栖社区"异步社区"公众号查看 6. ...

最新文章

  1. app怎么嵌套vue页面_PHP抖音点赞APP【开发】HTML5
  2. C语言实现Winsocket网络传输数据时乱码问题
  3. java常规普氏分析法_人脸对齐:Procrustes analysis 普氏分析
  4. PHPer 面试指南-扩展阅读资源整理
  5. 【转】Tcl/Tk 漫谈
  6. 计算机编程告白,程序员的520,五个表白代码,一看就会
  7. Hibernate拦截器字段加密解密
  8. 音频文件格式解析与编解码
  9. 数据恢复基础和进阶教程(二)
  10. sms 验证码 接收
  11. leejianjun的博客 PHP生成word并可下载
  12. 金字塔图表 html,Highcharts 柱形图(柱状图及条形图)之 金字塔图 演示
  13. 绁炵粡缃戠粶鏁版嵁鏍煎紡,鏂囨湰绁炵粡缃戠粶
  14. 由歌词引发的模式思考之上篇(FactoryMethod模式)
  15. 磁盘(含优盘识别)读写速度测试
  16. 2022年超声波雷达行业研究报告
  17. Sublime Text 2 - 性感无比的代码编辑器!(推荐阅读)
  18. 每天听一本书,日精日进
  19. 【酷柚易汛进销存开源版讲解】什么是核销单
  20. matlab中nnt,基于MATLAB的边坡稳定性评价方法

热门文章

  1. uniapp 运行到手机或模拟器
  2. Ubuntu18.04 谷歌浏览器安装商店助手
  3. 前台服务java.lang.SecurityException: Permission Denial: startForeground
  4. Python数据可视化大屏最全教程(全)
  5. 梦幻西游三维版获取服务器信息,梦幻西游三维版服务器等级提升
  6. 《SEM长尾搜索营销策略解密》一一2.1 起因:核心词成本过高
  7. 硬件设计1:常用元器件的选型理论依据
  8. 3GPP TS 29244-g30 中英文对照 | 7.3 Message Types
  9. Android APP安全测试
  10. CytusII 剧情梳理