Naohiro19

SetWindowSubclass/DefSubclassProc/RemoveWindowSubclassを使ったサンプルプログラム

Nov 16th, 2025
263
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.32 KB | Source Code | 0 0
  1.  
  2. ///
  3. /// インクルード
  4. ///
  5. #include <Windows.h>
  6. #include <string>
  7. #include <CommCtrl.h>
  8.  
  9. ///  
  10. /// ライブラリのリンク
  11. ///
  12. #pragma comment(lib, "comctl32.lib")
  13.  
  14. ///
  15. /// 定数
  16. ///
  17. const std::wstring WINDOW_CAPTION_NAME{ L"Sample Skeleton" };
  18. const std::wstring WINDOW_CLASS_NAME{ L"WINDOW PROGRAM" };
  19.  
  20. const int s_Window_Width{ 1280 };
  21. const int s_Window_Height{ 720 };
  22.  
  23. const DWORD dwStyle { WS_OVERLAPPEDWINDOW ^ WS_THICKFRAME };
  24. const DWORD dwExStyle{ WS_EX_OVERLAPPEDWINDOW };
  25.  
  26. const UINT_PTR uIdSubclassMainWindowId{ 10000 };
  27.  
  28. ///
  29. /// プロトタイプ宣言
  30. ///
  31. LRESULT CALLBACK MainWindowSubclassProc(HWND, UINT, WPARAM, LPARAM, UINT_PTR, DWORD_PTR);
  32.  
  33.  
  34. ///
  35. /// グローバル変数
  36. ///
  37. HINSTANCE g_hInstance = nullptr;    // インスタンスハンドル
  38. HWND      g_hMainWindow = nullptr;  // ウィンドウハンドル
  39. BOOL      g_fActive = FALSE;        // アクティブフラグ
  40.  
  41. ///
  42. /// WinMain()
  43. /// memo: Windows Programming において最初に呼ばれる関数
  44. ///
  45. int WINAPI
  46. WinMain(
  47.     HINSTANCE       hInst,              // 実行時のインスタンスハンドル
  48.     HINSTANCE       hPrevInst,          // Windows 95以降は常にNULL
  49.     LPSTR           lpszCmdLine,        // 実行時のコマンドライン
  50.     int             nCmdShow)           // 実行時のウィンドウの状態
  51. {
  52.     // インスタンスハンドルのコピー
  53.     g_hInstance = hInst;
  54.  
  55.     // ウィンドウクラスの設定
  56.     WNDCLASSEX wcex = {
  57.         sizeof(WNDCLASSEX),
  58.         CS_VREDRAW | CS_HREDRAW,
  59.         DefWindowProc,
  60.         0, 0,
  61.         static_cast<HINSTANCE>(GetModuleHandle(nullptr)),
  62.         LoadIcon(nullptr, IDI_APPLICATION),
  63.         LoadCursor(nullptr, IDC_ARROW),
  64.         static_cast<HBRUSH>(GetStockObject(WHITE_BRUSH)),
  65.         nullptr,
  66.         WINDOW_CLASS_NAME.c_str(),
  67.         nullptr,
  68.     };
  69.  
  70.     // ウィンドウクラスの登録
  71.     if (!RegisterClassEx(&wcex)) {
  72.         LPCTSTR lpMessage{ TEXT("ウィンドウクラスの登録に失敗") };
  73.         LPCTSTR lpTitle{ TEXT("RegisterClassEx()") };
  74.         UINT type = MB_OK;
  75.         MessageBox(nullptr, lpMessage, lpTitle, type);
  76.         return 0;
  77.     }
  78.  
  79.     HWND hwnd;
  80.     RECT window_rect, client_rect;
  81.    
  82.     RECT window_size = { 0, 0, s_Window_Width, s_Window_Height };
  83.     const auto& target_width = window_size.right - window_size.left;
  84.     const auto& target_height = window_size.bottom - window_size.top;
  85.  
  86.     // ウィンドウの作成
  87.     hwnd = CreateWindowEx(dwExStyle, WINDOW_CLASS_NAME.c_str(),
  88.         WINDOW_CAPTION_NAME.c_str(),
  89.         dwStyle, CW_USEDEFAULT, CW_USEDEFAULT,
  90.         target_width, target_height, nullptr, nullptr, g_hInstance, nullptr);
  91.     if (hwnd == nullptr) {
  92.         LPCTSTR lpMessage{ TEXT("ウィンドウの作成に失敗") };
  93.         LPCTSTR lpTitle{ TEXT("CreateWindowEx()") };
  94.         UINT type = MB_OK;
  95.         MessageBox(nullptr, lpMessage, lpTitle, type);
  96.         return 0;
  97.     }
  98.  
  99.     if (!GetWindowRect(hwnd, &window_rect)) {
  100.         LPCTSTR lpMessage{ TEXT("ウィンドウ全体のサイズの取得に失敗") };
  101.         LPCTSTR lpTitle{ TEXT("GetWindowRect()") };
  102.         UINT type = MB_OK;
  103.         MessageBox(nullptr, lpMessage, lpTitle, type);
  104.         return 0;
  105.     }
  106.  
  107.     if (!GetClientRect(hwnd, &client_rect)) {
  108.         LPCTSTR lpMessage{ TEXT("ウィンドウのクライアント領域のサイズの取得に失敗") };
  109.         LPCTSTR lpTitle{ TEXT("GetClientRect()") };
  110.         UINT type = MB_OK;
  111.         MessageBox(nullptr, lpMessage, lpTitle, type);
  112.         return 0;
  113.     }
  114.  
  115.     // フレームサイズの算出
  116.     const int frame_size_x = (window_rect.right - window_rect.left) - (client_rect.right - client_rect.left);
  117.     const int frame_size_y = (window_rect.bottom - window_rect.top) - (client_rect.bottom - client_rect.top);
  118.  
  119.     // リサイズ用のウィンドウサイズの算出
  120.     const int resize_width = frame_size_x + target_width;
  121.     const int resize_height = frame_size_y + target_height;
  122.  
  123.     SetWindowPos(hwnd, nullptr, CW_USEDEFAULT, CW_USEDEFAULT, resize_width, resize_height, SWP_NOMOVE);
  124.  
  125.     // ウィンドウハンドルのコピー
  126.     g_hMainWindow = hwnd;
  127.  
  128.     // ウィンドウハンドルとプロシージャーの関連付け
  129.     SetWindowSubclass(g_hMainWindow, MainWindowSubclassProc, uIdSubclassMainWindowId, 0);
  130.  
  131.     // ウィンドウの表示と描画の更新
  132.     ShowWindow(g_hMainWindow, nCmdShow);
  133.     UpdateWindow(g_hMainWindow);
  134.    
  135.  
  136.     // メッセージループ
  137.     MSG msg = {};
  138.     while (1) {
  139.         if (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE)) {
  140.             if (msg.message == WM_QUIT) {
  141.                 break;
  142.             }
  143.             TranslateMessage(&msg);
  144.             DispatchMessage(&msg);
  145.         } else {
  146.             // ウィンドウがアクティブな時だけ処理をする
  147.             if (g_fActive) {
  148.                 //
  149.             } else {
  150.                 WaitMessage();
  151.             }
  152.         }
  153.  
  154.     }
  155.    
  156.     // ウィンドウクラスの登録解除およびウィンドウハンドルとプロシージャーの関連付けを解除
  157.     UnregisterClass(WINDOW_CLASS_NAME.c_str(), g_hInstance);
  158.     RemoveWindowSubclass(g_hMainWindow, MainWindowSubclassProc, uIdSubclassMainWindowId);
  159.  
  160.     return static_cast<int>(msg.wParam);
  161.  
  162. }
  163.  
  164. ///
  165. /// MainWindowSubclassProc()
  166. /// memo: 発行されたウィンドウメッセージの処理を行う
  167. ///
  168. LRESULT CALLBACK MainWindowSubclassProc(
  169.             HWND            hWnd,           // メッセージが発行されたウィンドウハンドル
  170.             UINT            msg,            // 発行されたメッセージ
  171.             WPARAM          wParam,         // 発行されたメッセージの情報その1
  172.             LPARAM          lParam,         // 発行されたメッセージの情報その2
  173.             UINT_PTR        uIdSubclass,    // サブクラスID
  174.             DWORD_PTR       dwRefData)      // サブクラスの参照データ
  175. {
  176.     switch (msg) {
  177.     case WM_ACTIVATEAPP:
  178.         g_fActive = static_cast<BOOL>(wParam);
  179.         return 0;
  180.     case WM_KEYDOWN:
  181.         switch (LOWORD(wParam)) {
  182.         case VK_ESCAPE:
  183.             DestroyWindow(hWnd);
  184.             return 0;
  185.         }
  186.     case WM_DESTROY:
  187.         PostQuitMessage(0);
  188.         return 0;
  189.     }
  190.     return DefSubclassProc(hWnd, msg, wParam, lParam);
  191.  
  192. }
  193.  
Tags: C++ Win32API
Advertisement
Add Comment
Please, Sign In to add comment