Extract file menu binding and Win32 splash helper
This commit is contained in:
124
src/platform_windows/windows_splash.cpp
Normal file
124
src/platform_windows/windows_splash.cpp
Normal file
@@ -0,0 +1,124 @@
|
||||
#include "pch.h"
|
||||
#include "platform_windows/windows_splash.h"
|
||||
|
||||
#include "app.h"
|
||||
#include "image.h"
|
||||
#include "log.h"
|
||||
#include "version.h"
|
||||
|
||||
#include "../resource.h"
|
||||
|
||||
#include <chrono>
|
||||
#include <shellscalingapi.h>
|
||||
#include <string>
|
||||
#include <stop_token>
|
||||
|
||||
extern HRESULT(*GetDpiForMonitor_fn)(HMONITOR hmonitor, MONITOR_DPI_TYPE dpiType, UINT* dpiX, UINT* dpiY);
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr UINT kSplashCloseMessage = WM_USER + 1;
|
||||
|
||||
HBITMAP image_to_hbitmap(const Image& img)
|
||||
{
|
||||
BITMAPINFOHEADER bmih;
|
||||
memset(&bmih, 0, sizeof(BITMAPINFOHEADER));
|
||||
bmih.biWidth = img.width;
|
||||
bmih.biHeight = img.height;
|
||||
bmih.biBitCount = 32;
|
||||
bmih.biCompression = BI_RGB;
|
||||
bmih.biSize = sizeof(BITMAPINFOHEADER);
|
||||
bmih.biPlanes = 1;
|
||||
BITMAPINFO* bmi = (BITMAPINFO*)&bmih;
|
||||
return CreateDIBitmap(GetDC(NULL), &bmih, CBM_INIT, img.data(), bmi, DIB_RGB_COLORS);
|
||||
}
|
||||
|
||||
LRESULT CALLBACK splash_proc(HWND hWndDlg, UINT Msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
switch (Msg)
|
||||
{
|
||||
case WM_INITDIALOG:
|
||||
{
|
||||
auto monitor = MonitorFromWindow(0, MONITOR_DEFAULTTOPRIMARY);
|
||||
auto x = unsigned{ 96 };
|
||||
auto y = unsigned{ 96 };
|
||||
if (GetDpiForMonitor_fn)
|
||||
GetDpiForMonitor_fn(monitor, MDT_EFFECTIVE_DPI, &x, &y);
|
||||
float z = (float)x / 96.f;
|
||||
|
||||
static char base_path[MAX_PATH];
|
||||
GetCurrentDirectoryA(MAX_PATH, base_path);
|
||||
std::string path = std::string(base_path) + "\\data\\splash.jpg";
|
||||
Image img;
|
||||
img.load_file(path);
|
||||
img.flip();
|
||||
auto hbitmap = image_to_hbitmap(img.resize(512 * z, 200 * z));
|
||||
SendMessage(GetDlgItem(hWndDlg, IDC_STATIC_IMAGE), STM_SETIMAGE, (WPARAM)IMAGE_BITMAP, (LPARAM)hbitmap);
|
||||
SetDlgItemText(hWndDlg, IDC_STATIC_VERSION, g_version_number_w);
|
||||
|
||||
RECT r;
|
||||
GetClientRect(hWndDlg, &r);
|
||||
MoveWindow(GetDlgItem(hWndDlg, IDC_STATIC_IMAGE), 0, 0, 512 * z, 200 * z, TRUE);
|
||||
SetWindowPos(hWndDlg, HWND_TOP, 0, 0, 512 * z, 200 * z, SWP_NOMOVE);
|
||||
|
||||
HWND hWndVersion = GetDlgItem(hWndDlg, IDC_STATIC_VERSION);
|
||||
RECT rv;
|
||||
GetClientRect(hWndVersion, &rv);
|
||||
MoveWindow(hWndVersion, 0, 200 * z - (rv.bottom - rv.top), r.right - r.left, rv.bottom - rv.top, TRUE);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
case kSplashCloseMessage:
|
||||
PostQuitMessage(0);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return DefWindowProc(hWndDlg, Msg, wParam, lParam);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace pp::platform::windows {
|
||||
|
||||
SplashScreen::SplashScreen(HINSTANCE hInst)
|
||||
: hInst_(hInst)
|
||||
, thread_([this](std::stop_token) { thread_main(); })
|
||||
{
|
||||
}
|
||||
|
||||
SplashScreen::~SplashScreen()
|
||||
{
|
||||
dismiss();
|
||||
}
|
||||
|
||||
void SplashScreen::dismiss()
|
||||
{
|
||||
if (HWND dialog = dialog_.load(std::memory_order_acquire))
|
||||
SendMessage(dialog, kSplashCloseMessage, 0, 0);
|
||||
if (thread_.joinable())
|
||||
thread_.join();
|
||||
}
|
||||
|
||||
void SplashScreen::thread_main()
|
||||
{
|
||||
BT_SetTerminate();
|
||||
HWND dialog = CreateDialog(hInst_, MAKEINTRESOURCE(IDD_SPLASH), NULL, reinterpret_cast<DLGPROC>(splash_proc));
|
||||
dialog_.store(dialog, std::memory_order_release);
|
||||
if (!dialog)
|
||||
return;
|
||||
|
||||
MSG msg;
|
||||
while (GetMessage(&msg, 0, 0, 0) > 0)
|
||||
{
|
||||
if (IsDialogMessage(dialog, &msg))
|
||||
{
|
||||
DispatchMessage(&msg);
|
||||
TranslateMessage(&msg);
|
||||
}
|
||||
}
|
||||
|
||||
if (HWND dialog = dialog_.exchange(nullptr))
|
||||
DestroyWindow(dialog);
|
||||
}
|
||||
|
||||
}
|
||||
30
src/platform_windows/windows_splash.h
Normal file
30
src/platform_windows/windows_splash.h
Normal file
@@ -0,0 +1,30 @@
|
||||
#pragma once
|
||||
|
||||
#include <windows.h>
|
||||
#include <atomic>
|
||||
#include <thread>
|
||||
|
||||
namespace pp::platform::windows {
|
||||
|
||||
class SplashScreen final
|
||||
{
|
||||
public:
|
||||
explicit SplashScreen(HINSTANCE hInst);
|
||||
~SplashScreen();
|
||||
|
||||
SplashScreen(const SplashScreen&) = delete;
|
||||
SplashScreen& operator=(const SplashScreen&) = delete;
|
||||
SplashScreen(SplashScreen&&) = delete;
|
||||
SplashScreen& operator=(SplashScreen&&) = delete;
|
||||
|
||||
void dismiss();
|
||||
|
||||
private:
|
||||
void thread_main();
|
||||
|
||||
HINSTANCE hInst_{};
|
||||
std::atomic<HWND> dialog_{};
|
||||
std::jthread thread_;
|
||||
};
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user