Win32 APIでウィンドウを表示して、CreateDIBSection
関数で作成したビットマップを描画するサンプルコードです。
CreateDIBSection
関数で作成したビットマップはppvBits
引数に与えた変数の内容をビットマップデータとして直接操作できます。ここでは赤と黒の横縞を描画しています。
std::span
を使用するためC++20以降対応です。
#include <memory> #include <span> #define STRICT #define NOMINMAX #include <Windows.h> static const auto MainWindowClassName = L"MainWindow"; static const auto MainWindowTitle = L"MainWindow"; LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); using unique_bitmap_handle = std::unique_ptr<std::remove_pointer_t<HBITMAP>, decltype(&DeleteObject)>; using unique_dc_handle = std::unique_ptr<std::remove_pointer_t<HDC>, decltype(&DeleteDC)>; unique_bitmap_handle make_unique_bitmap_handle(HBITMAP hbmp) noexcept; unique_dc_handle make_unique_dc_handle(HDC hdc) noexcept; int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, LPWSTR, int iCmdShow) { // メインウィンドウのウィンドウクラス登録 WNDCLASSEXW wcex{ sizeof(WNDCLASSEXW), CS_HREDRAW | CS_VREDRAW, WndProc, 0, 0, hInstance, nullptr, LoadCursor(nullptr, IDC_ARROW), reinterpret_cast<HBRUSH>(COLOR_WINDOW + 1), nullptr, MainWindowClassName }; if (!RegisterClassExW(&wcex)) { return GetLastError(); } // メインウィンドウの作成・表示 auto hwnd = CreateWindowExW( WS_EX_OVERLAPPEDWINDOW, MainWindowClassName, MainWindowTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, nullptr, nullptr, hInstance, nullptr); if (hwnd == nullptr) { return GetLastError(); } ShowWindow(hwnd, iCmdShow); UpdateWindow(hwnd); // メッセージループ MSG msg; int ret; while (ret = GetMessageW(&msg, nullptr, 0, 0)) { if (ret == -1) { break; } TranslateMessage(&msg); DispatchMessageW(&msg); } return msg.wParam; } LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_PAINT: { PAINTSTRUCT ps; auto hdc = BeginPaint(hwnd, &ps); const int width = 100; const int height = 100; const int width_bytes = width + (width % 4); BITMAPINFO bmi{ sizeof(BITMAPINFO), width, -height, 1, 32, BI_RGB }; LPVOID pbits = nullptr; auto hbmp = make_unique_bitmap_handle(CreateDIBSection( nullptr, &bmi, DIB_RGB_COLORS, &pbits, nullptr, 0)); auto pixels = std::span( reinterpret_cast<LPBYTE>(pbits), reinterpret_cast<LPBYTE>(pbits) + width_bytes * height * 4); // 赤と黒の横縞 // 赤を指定しない部分は自動的に黒 for (int h = 0; h < height; h += 2) { const int j = h * width_bytes; for (int w = 0; w < width; w++) { int i = (j + w) * 4; pixels[i + 2] = 0xff; // R pixels[i + 1] = 0x00; // G pixels[i + 0] = 0x00; // B } } auto hdc2 = make_unique_dc_handle(CreateCompatibleDC(hdc)); SelectObject(hdc2.get(), hbmp.get()); BitBlt(hdc, 0, 0, 100, 100, hdc2.get(), 0, 0, SRCCOPY); EndPaint(hwnd, &ps); } return TRUE; case WM_DESTROY: PostQuitMessage(0); return 0; } return DefWindowProcW(hwnd, uMsg, wParam, lParam); } unique_bitmap_handle make_unique_bitmap_handle(HBITMAP hbmp) noexcept { return unique_bitmap_handle(hbmp, &DeleteObject); } unique_dc_handle make_unique_dc_handle(HDC hdc) noexcept { return unique_dc_handle(hdc, &DeleteDC); }