Skip to content

Instantly share code, notes, and snippets.

@shinaisan
Created April 7, 2012 04:09
Show Gist options
  • Save shinaisan/2324979 to your computer and use it in GitHub Desktop.
Save shinaisan/2324979 to your computer and use it in GitHub Desktop.
Win32 sample program of bitmap waving effect
// 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