Add window support for Windows.

This commit is contained in:
jamgroga 2021-10-31 13:04:48 +00:00
parent 5d32592126
commit c05b7b6315
27 changed files with 783 additions and 95 deletions

View file

@ -0,0 +1,40 @@
#include "Win32UIInterface.h"
#include <Windows.h>
Win32UIInterface::Win32UIInterface()
: mWindowInterface(std::make_unique<Win32WindowInterface>())
{
}
void Win32UIInterface::Initialize(DesktopManager* desktopManager)
{
}
void Win32UIInterface::Loop(DesktopManager* desktopManager)
{
// Run the message loop.
MSG msg = { };
while (::GetMessage(&msg, NULL, 0, 0))
{
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
}
void Win32UIInterface::ShutDown()
{
}
void Win32UIInterface::ShowWindow(mt::Window* window)
{
mWindowInterface->Show(window);
}
void Win32UIInterface::AddWindow(mt::Window* window, DesktopManager* desktopManager)
{
mWindowInterface->Add(window, desktopManager);
}

View file

@ -0,0 +1,29 @@
#pragma once
#include "Window.h"
#include "Win32WindowInterface.h"
class DesktopManager;
class Win32UIInterface
{
public:
Win32UIInterface();
~Win32UIInterface() = default;
void Initialize(DesktopManager* desktopManager);
void Loop(DesktopManager* desktopManager);
void ShutDown();
void ShowWindow(mt::Window* window);
void AddWindow(mt::Window* window, DesktopManager* desktopManager);
private:
Win32WindowInterfacePtr mWindowInterface;
};

View file

@ -0,0 +1,139 @@
#include "Win32Window.h"
#include "Win32WindowInterface.h"
#include <WinUser.h>
#include "FileLogger.h"
#include "StringUtils.h"
#include "ui_events\KeyboardEvent.h"
#include "DesktopManager.h"
LRESULT CALLBACK FreeWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
Win32Window::Win32Window()
{
}
std::unique_ptr<Win32Window> Win32Window::Create()
{
return std::make_unique<Win32Window>();
}
HWND Win32Window::GetHandle() const
{
return mHandle;
}
void Win32Window::CreateNative(Win32ApplicationContext* context, DesktopManager* desktopManager)
{
mDesktopManager = desktopManager;
const char CLASS_NAME[] = "Sample Window Class";
auto hInstance = reinterpret_cast<HINSTANCE>(context->hInstance);
WNDCLASS wc = { };
wc.lpfnWndProc = FreeWindowProc;
wc.hInstance = hInstance;
wc.lpszClassName = CLASS_NAME;
RegisterClass(&wc);
MLOG_INFO("Request window create");
mHandle = CreateWindowEx(
0, // Optional window styles.
CLASS_NAME, // Window class
"Media Tool", // Window text
WS_OVERLAPPEDWINDOW, // Window style
// Size and position
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
nullptr, // Parent window
nullptr, // Menu
hInstance, // Instance handle
this // Additional application data
);
if (mHandle == nullptr)
{
LPVOID lpMsgBuf;
auto dw = ::GetLastError();
::FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
nullptr, dw,MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&lpMsgBuf, 0, NULL);
MLOG_INFO("Request window failed: " << dw);
LocalFree(lpMsgBuf);
}
MLOG_INFO("Request window create got handle: " << "0x" << mHandle);
}
LRESULT CALLBACK Win32Window::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_DESTROY:
{
PostQuitMessage(0);
return 0;
}
case WM_CHAR:
{
auto key_event = std::make_unique<KeyboardEvent>();
key_event->SetAction(KeyboardEvent::Action::Pressed);
auto keyChar = (wchar_t)wParam;
key_event->SetKeyString(StringUtils::convert(std::wstring(1, keyChar)));
mDesktopManager->OnUiEvent(std::move(key_event));
}
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(mHandle, &ps);
FillRect(hdc, &ps.rcPaint, (HBRUSH)(COLOR_WINDOW + 1));
auto text = L"Hello World";
auto val = DrawText(hdc, (LPCSTR)(&text[0]), -1, &ps.rcPaint, 0);
EndPaint(mHandle, &ps);
}
}
return DefWindowProc(mHandle, message, wParam, lParam);
}
static LRESULT CALLBACK FreeWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
Win32Window* window;
if (uMsg == WM_NCCREATE)
{
CREATESTRUCT* cs = (CREATESTRUCT*)lParam;
window = (Win32Window*)cs->lpCreateParams;
SetLastError(0);
if (::SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)window) == 0)
{
if (GetLastError() != 0)
return FALSE;
}
}
else
{
window = (Win32Window*)GetWindowLongPtr(hwnd, GWLP_USERDATA);
}
if (window)
{
window->SetHandle(hwnd);
return window->WindowProc(uMsg, wParam, lParam);
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}

View file

@ -0,0 +1,42 @@
#pragma once
#include "IPlatformWindow.h"
#include <Windows.h>
class Win32ApplicationContext;
class DesktopManager;
class Win32Window : public IPlatformWindow
{
public:
Win32Window();
virtual ~Win32Window() = default;
static std::unique_ptr<Win32Window> Create();
LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);
HWND GetHandle() const;
void SetHandle(HWND handle)
{
mHandle = handle;
}
int GetCmdShow() const
{
return mCmdShow;
}
void SetCmdShow(int cmdShow)
{
mCmdShow = cmdShow;
}
void CreateNative(Win32ApplicationContext* context, DesktopManager* desktopManager);
private:
HWND mHandle{ 0 };
int mCmdShow{ 0 };
DesktopManager* mDesktopManager;
};

View file

@ -0,0 +1,32 @@
#include "Win32WindowInterface.h"
#include "Win32Window.h"
#include <Windows.h>
#include "DesktopManager.h"
#include "FileLogger.h"
Win32WindowInterface::Win32WindowInterface()
{
}
void Win32WindowInterface::Show(mt::Window* window)
{
auto platformWindow = dynamic_cast<Win32Window*>(window->GetPlatformWindow());
MLOG_INFO("Showing platform window: " << platformWindow->GetHandle());
::ShowWindow(platformWindow->GetHandle(), platformWindow->GetCmdShow());
}
void Win32WindowInterface::Add(mt::Window* window, DesktopManager* desktopManager)
{
auto context = dynamic_cast<Win32ApplicationContext*>(desktopManager->GetMainApp()->GetApplicationContext());
auto win32_window = Win32Window::Create();
win32_window->CreateNative(context, desktopManager);
win32_window->SetCmdShow(context->nCmdShow);
window->SetPlatformWindow(std::move(win32_window));
}

View file

@ -0,0 +1,29 @@
#pragma once
#include "Window.h"
#include "AbstractApp.h"
#include <Windows.h>
#include <memory>
class DesktopManager;
class Win32ApplicationContext : public IApplicationContext
{
public:
void* hInstance{ nullptr };
int nCmdShow{ 0 };
};
class Win32WindowInterface
{
public:
Win32WindowInterface();
void Add(mt::Window* window, DesktopManager* desktopManager);
void Show(mt::Window* window);
};
using Win32WindowInterfacePtr = std::unique_ptr<Win32WindowInterface>;