Rastrové operace ve WinAPI

Trolled GDI

main.c
#include <windows.h>
#include <stdio.h>
#include <string.h>
 
// globální proměnné
 
HINSTANCE hInst;
 
// funkční protopypy.
int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int);
LRESULT CALLBACK MainWndProc(HWND, UINT, WPARAM, LPARAM);
 
void onPaint(HWND hWnd);
 
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
	MSG msg;
	BOOL bRet;
	WNDCLASS wcx;	// třída okna
	HWND hWnd;
	hInst = hInstance;
 
	// naplnění atributů třídy tvořeného okna
	wcx.style = CS_HREDRAW | CS_VREDRAW;
	wcx.lpfnWndProc = (WNDPROC) MainWndProc;
	wcx.cbClsExtra = 0;
	wcx.cbWndExtra = 0;
	wcx.hInstance = hInstance;
	wcx.hIcon = LoadIcon(NULL, IDI_APPLICATION);
	wcx.hCursor = LoadCursor(NULL, IDC_ARROW);
	wcx.hbrBackground = GetStockObject(WHITE_BRUSH);
	wcx.lpszMenuName =  (LPCSTR) "MainMenu";
	wcx.lpszClassName = (LPCSTR) "MainWClass";
 
	// registrace třídy okna
 
	if (!RegisterClass(&wcx)) {
		return FALSE;
	}
 
	// vytvoření okna dané třídy
 
	hWnd = CreateWindow(
		"MainWClass",	// třída okna
		"MUL 2 - WinAPI",	// titulek
		WS_OVERLAPPEDWINDOW,
		50,	// pozice a rozměry okna
		100,
		500,
		500,
		(HWND) NULL,	// bez vlastníka
		(HMENU) NULL,
		hInstance,
		(LPVOID) NULL);
	if (!hWnd) {
		return FALSE;
	}
 
	// prvotní vykreslení obsahu okna
 
	ShowWindow(hWnd, nCmdShow);
	UpdateWindow(hWnd);
 
	// smyčka zpráv
 
	while ((bRet = GetMessage( &msg, NULL, 0, 0 )) != 0) {
		if (bRet == -1) {
			// zpracování případné chyby ignorujeme - konec
		} else {
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
	}
	return (int) msg.wParam;
}	//WinMain
 
 
LRESULT CALLBACK MainWndProc(
	HWND hWnd,	// handle okna
	UINT uMsg,	// identifikátor zprávy
	WPARAM wParam,	// první parametr zprávy
	LPARAM lParam)	// druhý parametr
{
	switch (uMsg) {
		case WM_CREATE:
			// vytvoření okna
			return 0;
		case WM_SIZE:
			// změna velikosti okna
			return 0;
		case WM_DESTROY:
			// zrušení okna
			PostQuitMessage(0);
			return 0;
		case WM_PAINT:
			// vykreslení obsahu okna
			onPaint(hWnd);
			return 0;
		//
		// stejným způsobem lze ošetřit další typy zpráv
		//
		default:
			return DefWindowProc(hWnd, uMsg, wParam, lParam);
	}
}	//MainWndProc
 
void onPaint(HWND hWnd) {
	// vykreslení obsahu okna...
	PAINTSTRUCT ps;
	HDC hDC;
 
	RECT rect;
	HPEN hPen;
	HPEN hOldPen;
	GetClientRect(hWnd, &rect);	// získání rozměrů klientské části okna
	hDC = BeginPaint(hWnd, &ps);	// získání DC
 
	for (ssize_t y = 0; y < rect.bottom; y++) {
		unsigned char green = (255.0 / rect.bottom) * y;
		unsigned char blue = 255 - green;
		hPen = CreatePen(PS_SOLID, 0, RGB(0, green, blue));	// vytvoření nového pera
		hOldPen = SelectObject(hDC, hPen);//nastavení pera
		MoveToEx(hDC, 0, y, NULL);	//nastavení "kurzoru"
		LineTo(hDC, rect.right, y);	//vykreslení čáry
		SelectObject(hDC, hOldPen);	//opětovné nastavení původního pera
		DeleteObject(hPen);	//uvolnění prostředků
	}
 
	BITMAP bitmap;
	HDC hdcBitmap;
	HDC hMemoryDC;
	HBITMAP hMemBmp;
	hMemoryDC = CreateCompatibleDC(hDC);	//vytvoření memory DC
	hMemBmp = CreateCompatibleBitmap(hDC, 500, 500);	//vytvoření bitmapy
	SelectObject(hMemoryDC, hMemBmp);	//nastavení bitmapy pro daný DC
	HBITMAP hBitmap = NULL;
	hBitmap = (HBITMAP)LoadImage(GetModuleHandle(NULL), "trollface.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
	if (hBitmap == NULL) {
		MessageBox(NULL, "Could not load image.", "Error", MB_OK | MB_ICONEXCLAMATION);
	}
	hdcBitmap = CreateCompatibleDC(hDC);
	GetObject(hBitmap, sizeof(bitmap), &bitmap);	//získání informací o grafickém objektu
	SelectObject(hdcBitmap, hBitmap);
	BitBlt(hDC, rect.right / 2 - bitmap.bmWidth / 2, rect.bottom / 2 - bitmap.bmHeight / 2, bitmap.bmWidth, bitmap.bmHeight, hdcBitmap, 0, 0, SRCAND);
	DeleteDC(hdcBitmap);
 
	EndPaint(hWnd, &ps);
}