1 // Released to the Public Domain by Doug Lyons on April 16th, 2024.
2
3 #include <windows.h>
4 #include <stdio.h>
5
6 WCHAR szWindowClass[] = L"testclass";
7
8 static LRESULT CALLBACK
WndProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)9 WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
10 {
11 static HBITMAP hBmp;
12 HANDLE handle;
13 CHAR buffer[32];
14
15 switch (message)
16 {
17 case WM_CREATE:
18 {
19 handle = LoadLibraryExW(L"image.dll", NULL, LOAD_LIBRARY_AS_DATAFILE);
20 sprintf(buffer, "%p", handle);
21 MessageBoxA(NULL, buffer, "handle", 0);
22 hBmp = (HBITMAP)LoadImage(handle, MAKEINTRESOURCE(130), IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR);
23 sprintf(buffer, "%p", hBmp);
24 MessageBoxA(NULL, buffer, "Bmp", 0);
25 sprintf(buffer, "%ld", GetLastError());
26 MessageBoxA(NULL, buffer, "LastError", 0);
27 break;
28 }
29
30 case WM_PAINT:
31 {
32 PAINTSTRUCT ps;
33 HDC hdc, hdcMem;
34 BITMAP bitmap;
35 BITMAPINFO bmi;
36 hdc = BeginPaint(hWnd, &ps);
37 HGLOBAL hMem;
38 LPVOID lpBits;
39
40 hdcMem = CreateCompatibleDC(hdc);
41 SelectObject(hdcMem, hBmp);
42 GetObject(hBmp, sizeof(BITMAP), &bitmap);
43
44 memset(&bmi, 0, sizeof(bmi));
45 bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
46 bmi.bmiHeader.biWidth = bitmap.bmWidth;
47 bmi.bmiHeader.biHeight = bitmap.bmHeight;
48 bmi.bmiHeader.biPlanes = bitmap.bmPlanes;
49 bmi.bmiHeader.biBitCount = bitmap.bmBitsPixel;
50 bmi.bmiHeader.biCompression = BI_RGB;
51 bmi.bmiHeader.biSizeImage = 0;
52
53 hMem = GlobalAlloc(GMEM_MOVEABLE, ((bitmap.bmWidth *
54 bmi.bmiHeader.biBitCount + 31) / 32) * 4 * bitmap.bmHeight);
55 lpBits = GlobalLock(hMem);
56 GetDIBits(hdc, hBmp, 0, bitmap.bmHeight, lpBits, &bmi, DIB_RGB_COLORS);
57
58 // increasing the multiplier makes the image larger
59 StretchDIBits(hdc, 0, 0, bitmap.bmWidth * 3, bitmap.bmHeight * 3, 0, 0,
60 bitmap.bmWidth, bitmap.bmHeight,lpBits, &bmi, DIB_RGB_COLORS, SRCCOPY);
61 GlobalUnlock(hMem);
62 GlobalFree(hMem);
63
64 DeleteDC(hdcMem);
65
66 EndPaint(hWnd, &ps);
67 break;
68 }
69
70 case WM_DESTROY:
71 PostQuitMessage(0);
72 break;
73 default:
74 return DefWindowProc(hWnd, message, wParam, lParam);
75 }
76 return 0;
77 }
78
79
80 static ATOM
MyRegisterClass(HINSTANCE hInstance)81 MyRegisterClass(HINSTANCE hInstance)
82 {
83 WNDCLASSEX wcex;
84
85 wcex.cbSize = sizeof(WNDCLASSEX);
86
87 wcex.style = CS_HREDRAW | CS_VREDRAW;
88 wcex.lpfnWndProc = WndProc;
89 wcex.cbClsExtra = 0;
90 wcex.cbWndExtra = 0;
91 wcex.hInstance = hInstance;
92 wcex.hIcon = NULL;
93 wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
94 wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
95 wcex.lpszMenuName = NULL;
96 wcex.lpszClassName = szWindowClass;
97 wcex.hIconSm = NULL;
98
99 return RegisterClassEx(&wcex);
100 }
101
102
103 static BOOL
InitInstance(HINSTANCE hInstance,int nCmdShow)104 InitInstance(HINSTANCE hInstance, int nCmdShow)
105 {
106 HWND hWnd;
107
108 hWnd = CreateWindowEx(0,
109 szWindowClass,
110 L"Bmp test",
111 WS_OVERLAPPEDWINDOW,
112 CW_USEDEFAULT,
113 CW_USEDEFAULT,
114 300,
115 120,
116 NULL,
117 NULL,
118 hInstance,
119 NULL);
120
121 if (!hWnd)
122 return FALSE;
123
124 ShowWindow(hWnd, nCmdShow);
125 UpdateWindow(hWnd);
126
127 return TRUE;
128 }
129
130 int WINAPI
wWinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPTSTR lpCmdLine,int nCmdShow)131 wWinMain(HINSTANCE hInstance,
132 HINSTANCE hPrevInstance,
133 LPTSTR lpCmdLine,
134 int nCmdShow)
135 {
136 MSG msg;
137
138 MyRegisterClass(hInstance);
139
140 if (!InitInstance(hInstance, nCmdShow))
141 return FALSE;
142
143 while (GetMessage(&msg, NULL, 0, 0))
144 {
145 TranslateMessage(&msg);
146 DispatchMessage(&msg);
147 }
148
149 return (int)msg.wParam;
150 }
151