Created
April 7, 2012 04:09
-
-
Save shinaisan/2324979 to your computer and use it in GitHub Desktop.
Win32 sample program of bitmap waving effect
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// To compile (using VC): | |
// cl main.c /link gdi32.lib user32.lib kernel32.lib | |
#include <tchar.h> | |
#include <math.h> | |
#include <windows.h> | |
TCHAR *szWindowClass =_T("Window Class Name"); | |
#define PI 3.14159265 | |
typedef struct tag_DibStruct { | |
HBITMAP hDib; | |
HGDIOBJ hOldGdiObj; | |
HDC hDc; | |
int width; | |
int height; | |
void *buffer; | |
size_t bufferSize; | |
} DIBSTRUCT; | |
DIBSTRUCT g_dib; | |
/* Load a bitmap file into g_dib. */ | |
BOOL MyLoadBitmap(LPCTSTR szFileName) { | |
HBITMAP hBmp = NULL; | |
BITMAP bitmap; | |
BITMAPINFO bmi; | |
HDC hDesktopDc = NULL; | |
HDC hTempDc = NULL; | |
HGDIOBJ hOldObj = NULL; | |
BOOL bResult = TRUE; | |
/* Load a bitmap file and get a bitmap object. */ | |
hBmp = (HBITMAP)LoadImage(NULL, szFileName, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE); | |
if (hBmp == NULL) { | |
return (FALSE); | |
} | |
GetObject(hBmp, sizeof(bitmap), &bitmap); | |
/* Get the desktop DC. */ | |
hDesktopDc = GetDC(GetDesktopWindow()); | |
/* Create a temporary DC for the loaded bitmap. */ | |
hTempDc = CreateCompatibleDC(hDesktopDc); | |
hOldObj = SelectObject(hTempDc, hBmp); | |
/* Create 32-bit DIB with the same size as the loaded bitmap. */ | |
memset(&g_dib, 0, sizeof(g_dib)); | |
g_dib.width = bitmap.bmWidth; | |
g_dib.height = bitmap.bmHeight; | |
memset(&bmi, 0, sizeof(bmi)); | |
bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); | |
bmi.bmiHeader.biWidth = g_dib.width; | |
bmi.bmiHeader.biHeight = - g_dib.height; | |
bmi.bmiHeader.biPlanes = 1; | |
bmi.bmiHeader.biBitCount = 32; | |
bmi.bmiHeader.biCompression = BI_RGB; | |
g_dib.hDib = CreateDIBSection(hDesktopDc, &bmi, DIB_RGB_COLORS, (void **)&g_dib.buffer, 0, 0); | |
if (g_dib.buffer == NULL) { | |
bResult = FALSE; | |
goto Exit; | |
} | |
g_dib.bufferSize = g_dib.width * g_dib.height * 4; | |
g_dib.hDc = CreateCompatibleDC(hDesktopDc); | |
g_dib.hOldGdiObj = SelectObject(g_dib.hDc, g_dib.hDib); | |
BitBlt(g_dib.hDc, 0, 0, g_dib.width, g_dib.height, hTempDc, 0, 0, SRCCOPY); | |
Exit: | |
SelectObject(hTempDc, hOldObj); | |
DeleteDC(hTempDc); | |
DeleteObject(hBmp); | |
ReleaseDC(GetDesktopWindow(), hDesktopDc); | |
return (bResult); | |
} | |
COLORREF *GetPixelPtr(void *src, int x, int y, int w) { | |
return (((COLORREF *)src) + (w * y) + x); | |
} | |
void Wave() { | |
void *tmpBuffer = NULL; | |
int i, j, w, h, x, y, dx, dy; | |
int cx, cy; | |
cx = 30; | |
cy = 30; | |
tmpBuffer = malloc(g_dib.bufferSize); | |
if (tmpBuffer == NULL) { | |
return; | |
} | |
memcpy(tmpBuffer, g_dib.buffer, g_dib.bufferSize); | |
w = g_dib.width; | |
h = g_dib.height; | |
for (j = 0; j < h; j++) { | |
for (i = 0; i < w; i++) { | |
dx = cx * cos((double)j / h * PI * 3); | |
dy = cy * sin((double)i / w * PI * 3); | |
x = i + dx; | |
y = j + dy; | |
if (x < 0) x += w; | |
if (y < 0) y += h; | |
if (x >= w) x -= w; | |
if (y >= h) y -= h; | |
*GetPixelPtr(g_dib.buffer, i, j, w) = | |
*GetPixelPtr(tmpBuffer, x, y, w); | |
} | |
} | |
free(tmpBuffer); | |
} | |
LRESULT CALLBACK MyWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { | |
HDC hWndDc = NULL; | |
PAINTSTRUCT paint; | |
switch (msg) { | |
case WM_PAINT: | |
hWndDc = BeginPaint(hWnd, &paint); | |
BitBlt(hWndDc, 0, 0, g_dib.width, g_dib.height, g_dib.hDc, 0, 0, SRCCOPY); | |
EndPaint(hWnd, &paint); | |
break; | |
case WM_DESTROY: | |
SelectObject(g_dib.hDc, g_dib.hOldGdiObj); | |
DeleteDC(g_dib.hDc); | |
DeleteObject(g_dib.hDib); | |
PostQuitMessage(0); | |
break; | |
default: | |
return (DefWindowProc(hWnd, msg, wParam, lParam)); | |
} | |
return (0L); | |
} | |
ATOM MyRegisterClass(HINSTANCE hInstance) { | |
WNDCLASSEX wcex; | |
memset(&wcex, 0, sizeof(wcex)); | |
wcex.cbSize = sizeof(wcex); | |
wcex.style = CS_HREDRAW | CS_VREDRAW; | |
wcex.lpfnWndProc = (WNDPROC)MyWndProc; | |
wcex.cbClsExtra = 0; | |
wcex.cbWndExtra = 0; | |
wcex.hInstance = hInstance; | |
wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_APPLICATION)); | |
wcex.hCursor = LoadCursor(NULL, IDC_ARROW); | |
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); | |
wcex.lpszMenuName = NULL; | |
wcex.lpszClassName = szWindowClass; | |
return (RegisterClassEx(&wcex)); | |
} | |
int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPreInst, | |
LPTSTR lpszCmdLine, int nCmdShow) | |
{ | |
HWND hWnd; | |
MSG msg; | |
if (!MyRegisterClass(hInstance)) { | |
return FALSE; | |
} | |
MyLoadBitmap("test.bmp"); | |
Wave(); | |
hWnd = CreateWindow(szWindowClass, _T("Test"), WS_OVERLAPPEDWINDOW, | |
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, | |
hInstance, NULL); | |
if (!hWnd) { | |
return (FALSE); | |
} | |
ShowWindow(hWnd, nCmdShow); | |
UpdateWindow(hWnd); | |
while (GetMessage(&msg, NULL, 0, 0)) { | |
TranslateMessage(&msg); | |
DispatchMessage(&msg); | |
} | |
return (msg.wParam); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment