WinAPI integration module example

Below you can find source code of a winapi_integration example that showcases usage of the libbase integration module for WinAPI. This example is located in the /examples/winapi_integration/ directory in the repository and - if enabled - will be built along the libbase library itself (on Windows).

CMakeLists.txt
 1add_executable(winapi_integration_example WIN32 "")
 2
 3target_compile_options(winapi_integration_example
 4  PRIVATE
 5    ${LIBBASE_COMPILE_FLAGS}
 6)
 7
 8target_link_libraries(winapi_integration_example
 9  PRIVATE
10    libbase
11    libbase_win
12)
13
14target_sources(winapi_integration_example
15  PRIVATE
16    main.cc
17)
main.cc
 1#ifndef UNICODE
 2#define UNICODE
 3#endif
 4
 5#include <thread>
 6
 7#include "base/message_loop/win/win_message_loop_attachment.h"
 8#include "base/platform/windows.h"
 9#include "base/threading/thread_pool.h"
10
11LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
12
13void SetWindowTitle(HWND hWnd, const wchar_t* title) {
14  SetWindowText(hWnd, title);
15}
16
17int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, PWSTR, int nCmdShow) {
18  // Setup libbase attachment to main Window thread's message loop
19  auto loopAttachment = base::win::WinMessageLoopAttachment::TryCreate();
20  if (!loopAttachment) {
21    return 0;
22  }
23
24  // Register the window class.
25  const wchar_t CLASS_NAME[] = L"Window Class";
26  WNDCLASS wc = {};
27  wc.lpfnWndProc = &WindowProc;
28  wc.hInstance = hInstance;
29  wc.lpszClassName = CLASS_NAME;
30  RegisterClass(&wc);
31
32  // Adjust window size to account for borders and title bar
33  RECT rect = {0, 0, 800, 600};
34  AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW, FALSE);
35
36  HWND hwnd =
37      CreateWindowEx(0, CLASS_NAME, L"Default title", WS_OVERLAPPEDWINDOW,
38                     CW_USEDEFAULT, CW_USEDEFAULT, rect.right - rect.left,
39                     rect.bottom - rect.top, NULL, NULL, hInstance, NULL);
40  if (hwnd == NULL) {
41    return 0;
42  }
43
44  ShowWindow(hwnd, nCmdShow);
45
46  // Some example testing
47  loopAttachment->TaskRunner()->PostTask(
48      FROM_HERE, base::BindOnce(&SetWindowTitle, hwnd,
49                                L"Changed window title from post-task"));
50  loopAttachment->TaskRunner()->PostDelayedTask(
51      FROM_HERE,
52      base::BindOnce(&SetWindowTitle, hwnd, L"Delayed task executed as well!"),
53      base::Seconds(3));
54
55  base::ThreadPool threadPool{4};
56  threadPool.Start();
57  threadPool.GetTaskRunner()->PostTaskAndReplyWithResult(
58      FROM_HERE, base::BindOnce([]() -> const wchar_t* {
59        std::this_thread::sleep_for(std::chrono::seconds(5));
60        return L"Greetings from thread pool!";
61      }),
62      base::BindOnce(&SetWindowTitle, hwnd));
63
64  // Run the message loop.
65  MSG msg = {};
66  while (GetMessage(&msg, NULL, 0, 0) > 0) {
67    TranslateMessage(&msg);
68    DispatchMessage(&msg);
69  }
70
71  return 0;
72}
73
74LRESULT CALLBACK WindowProc(HWND hwnd,
75                            UINT uMsg,
76                            WPARAM wParam,
77                            LPARAM lParam) {
78  switch (uMsg) {
79    case WM_DESTROY:
80      PostQuitMessage(0);
81      return 0;
82
83    case WM_CLOSE:
84      DestroyWindow(hwnd);
85      return 0;
86
87    case WM_PAINT: {
88      PAINTSTRUCT ps;
89      HDC hdc = BeginPaint(hwnd, &ps);
90      FillRect(hdc, &ps.rcPaint, (HBRUSH)(COLOR_WINDOW + 1));
91      EndPaint(hwnd, &ps);
92      return 0;
93    }
94  }
95
96  return DefWindowProc(hwnd, uMsg, wParam, lParam);
97}