位图和位块传输(6)画框与会移动的小球
2012-08-10 21:03 java线程例子 阅读(175) 评论(0) 编辑 收藏 举报由一个很常用的技巧,这个方法使用"掩码"位图和一些光栅操作,掩码是一个单色位图,它的大小和你要显示的矩形位图大小相同。每个掩码像素对应要显示的位图上的一个像素,要显示出来的像素对应的掩码像素为白色(1)
下面来看看这个例子(来自Windows程序设计第五版圣经)
#include<windows.h> #include"resource.h" LRESULT CALLBACK WindowProc( HWND hwnd, // handle to window UINT uMsg, // message identifier WPARAM wParam, // first message parameter LPARAM lParam // second message parameter ); int WINAPI WinMain( HINSTANCE hInstance, // handle to current instance HINSTANCE hPrevInstance, // handle to previous instance LPSTR lpCmdLine, // command line int nCmdShow // show state ) { static TCHAR szAppName[]=TEXT("leidemingzi"); HWND hwnd; MSG msg; WNDCLASS wndclass; wndclass.cbClsExtra=0; wndclass.cbWndExtra=0; wndclass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH); wndclass.hCursor=LoadCursor(NULL,IDC_ARROW); wndclass.hIcon=LoadIcon(NULL,IDI_ERROR); wndclass.hInstance=hInstance; wndclass.lpfnWndProc=WindowProc; wndclass.lpszClassName=szAppName; wndclass.lpszMenuName=NULL; wndclass.style=CS_HREDRAW|CS_VREDRAW; if(!RegisterClass(&wndclass)) { MessageBox(NULL,TEXT("the program require the windows nt"),TEXT("tips"),MB_ICONERROR); return 0; } hwnd=CreateWindow( szAppName, // registered class name TEXT("this is title"), // window name WS_OVERLAPPEDWINDOW, // window style CW_USEDEFAULT, // horizontal position of window CW_USEDEFAULT, // vertical position of window CW_USEDEFAULT, // window width CW_USEDEFAULT, // window height NULL, // handle to parent or owner window NULL, // menu handle or child identifier hInstance, // handle to application instance NULL // window-creation data ); ShowWindow(hwnd,nCmdShow); UpdateWindow(hwnd); while(GetMessage(&msg,NULL,0,0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam; } LRESULT CALLBACK WindowProc( HWND hwnd, // handle to window UINT uMsg, // message identifier WPARAM wParam, // first message parameter LPARAM lParam // second message parameter ) { 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 (uMsg) { case WM_CREATE: hInstance = ((LPCREATESTRUCT) lParam)->hInstance ; // Load the original image and get its size hBitmapImag = LoadBitmap (hInstance, MAKEINTRESOURCE(BITMAPID)) ; 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 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 BitBlt (hdcMemImag, 0, 0, cxBitmap, cyBitmap, hdcMemMask, 0, 0, SRCAND) ; DeleteDC (hdcMemImag) ; DeleteDC (hdcMemMask) ; return 0 ; case WM_SIZE: cxClient = LOWORD (lParam) ; cyClient = HIWORD (lParam) ; return 0 ; case WM_PAINT: hdc = BeginPaint (hwnd, &ps) ; // Select bitmaps into memory DCs hdcMemImag = CreateCompatibleDC (hdc) ; SelectObject (hdcMemImag, hBitmapImag) ; hdcMemMask = CreateCompatibleDC (hdc) ; SelectObject (hdcMemMask, hBitmapMask) ; // Center image x = (cxClient - cxBitmap) / 2 ; y = (cyClient - cyBitmap) / 2 ; // Do the bitblts BitBlt (hdc, x, y, cxBitmap, cyBitmap, hdcMemMask, 0, 0, 0x220326) ; BitBlt (hdc, x, y, cxBitmap, cyBitmap, hdcMemImag, 0, 0, SRCPAINT) ; DeleteDC (hdcMemImag) ; DeleteDC (hdcMemMask) ; EndPaint (hwnd, &ps) ; return 0 ; case WM_DESTROY: DeleteObject (hBitmapImag) ; DeleteObject (hBitmapMask) ; PostQuitMessage (0) ; return 0 ; } return DefWindowProc (hwnd, uMsg, wParam, lParam) ; }
下面是会移动的小球
#include <windows.h> #define ID_TIMER 1 LRESULT 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) ; 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) ; }
闪屏:
#include <windows.h> #define NUM 300 LRESULT 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 ; if (LockWindowUpdate (hwnd = GetDesktopWindow ())) { hdcScr = GetDCEx (hwnd, NULL, DCX_CACHE | DCX_LOCKWINDOWUPDATE) ; hdcMem = CreateCompatibleDC (hdcScr) ; 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 ; }
自个试验去
因为慢着学习别的东西,没有太多时间来写自己的理解,匆忙写点笔记。