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 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 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 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 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