#include <Windows.h>
#define APP_NAME L"Mandelbrot"
#define WND_SIZE 512
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
void OnCreate(HWND hWnd);
void OnDestroy();
void OnPaint(HWND hWnd);
HDC hMemDC = NULL;
HBITMAP hBmp = NULL;
HBITMAP hBmpOld = NULL;
int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE, _In_ LPWSTR, _In_ int nCmdShow)
{
// ウィンドウクラスの登録
WNDCLASSEX wc = { sizeof WNDCLASSEX };
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WndProc;
wc.hInstance = hInstance;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = HBRUSH(COLOR_WINDOW + 1);
wc.lpszClassName = APP_NAME;
if (RegisterClassEx(&wc) == 0) {
return 0;
}
// ウィンドウの作成
HWND hWnd = CreateWindow(
APP_NAME, APP_NAME,
WS_OVERLAPPEDWINDOW & ~WS_MAXIMIZEBOX & ~WS_THICKFRAME,
CW_USEDEFAULT, 0,
CW_USEDEFAULT, 0,
NULL, NULL, hInstance, NULL);
if (hWnd == NULL) {
return 0;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
// メッセージループ
MSG msg;
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg) {
case WM_PAINT:
OnPaint(hWnd);
break;
case WM_CREATE:
OnCreate(hWnd);
break;
case WM_DESTROY:
OnDestroy();
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
return 0;
}
void OnCreate(HWND hWnd)
{
RECT rcw, rcc;
GetWindowRect(hWnd, &rcw);
GetClientRect(hWnd, &rcc);
int cx = WND_SIZE + (rcw.right - rcw.left) - rcc.right;
int cy = WND_SIZE + (rcw.bottom - rcw.top) - rcc.bottom;
SetWindowPos(hWnd, NULL, 0, 0, cx, cy, SWP_NOZORDER | SWP_NOMOVE);
BITMAPINFOHEADER bmih = { sizeof BITMAPINFOHEADER };
bmih.biWidth = WND_SIZE;
bmih.biHeight = WND_SIZE;
bmih.biPlanes = 1;
bmih.biBitCount = 32;
bmih.biCompression = BI_RGB;
LPDWORD pixel;
hBmp = CreateDIBSection(NULL, (BITMAPINFO*)& bmih, DIB_RGB_COLORS, (LPVOID*)& pixel, NULL, 0);
if (!hBmp) return;
HDC hdc = GetDC(hWnd);
hMemDC = CreateCompatibleDC(hdc);
// hBmp = CreateCompatibleBitmap(hdc, WND_SIZE, WND_SIZE);
hBmpOld = (HBITMAP)SelectObject(hMemDC, hBmp);
for (int y = 0; y < WND_SIZE; y++) {
double b = ((double)y / WND_SIZE - .5) * 4;
for (int x = 0; x < WND_SIZE; x++) {
double a = ((double)x / WND_SIZE - .5) * 4;
double u = a, v = b, uu, vv;
for (int i = 1; i < 256; i++) {
uu = u * u;
vv = v * v;
if (uu + vv > 4) {
int c = i & 0xff;
*pixel = (c << 8) | c;
// SetPixel(hMemDC, x, y, RGB(0, i, i));
break;
}
v = 2 * u * v + b;
u = uu - vv + a;
}
pixel++;
}
}
ReleaseDC(hWnd, hdc);
}
void OnDestroy()
{
SelectObject(hMemDC, hBmpOld);
DeleteObject(hBmp);
DeleteDC(hMemDC);
}
void OnPaint(HWND hWnd)
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &ps);
BitBlt(hdc, 0, 0, WND_SIZE, WND_SIZE, hMemDC, 0, 0, SRCCOPY);
EndPaint(hWnd, &ps);
}