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

@ -12,9 +12,18 @@ list(APPEND platform_INCLUDES
ui_interfaces/x11/XcbTextInterface.cpp
ui_interfaces/x11/XcbKeyboard.cpp
ui_interfaces/x11/GlxInterface.cpp)
list(APPEND platform_LIBS
X11 X11-xcb xcb )
X11 X11-xcb xcb )
else()
list(APPEND platform_INCLUDES
ui_interfaces/win32/Win32UIInterface.h
ui_interfaces/win32/Win32UIInterface.cpp
ui_interfaces/win32/Win32WindowInterface.h
ui_interfaces/win32/Win32WindowInterface.cpp
ui_interfaces/win32/Win32Window.h
ui_interfaces/win32/Win32Window.cpp
)
endif()
list(APPEND windows_LIB_INCLUDES
@ -29,6 +38,8 @@ target_include_directories(windows PUBLIC
"${CMAKE_CURRENT_SOURCE_DIR}"
"${CMAKE_CURRENT_SOURCE_DIR}/managers"
"${CMAKE_CURRENT_SOURCE_DIR}/ui_interfaces/x11"
"${CMAKE_CURRENT_SOURCE_DIR}/ui_interfaces/win32"
"${PROJECT_SOURCE_DIR}/src/core"
"${PROJECT_SOURCE_DIR}/src/geometry"
"${PROJECT_SOURCE_DIR}/src/graphics"
"${PROJECT_SOURCE_DIR}/src/ui_elements"

View file

@ -1,5 +1,7 @@
#include "DesktopManager.h"
#include "FileLogger.h"
DesktopManager::DesktopManager()
: mScreens(),
mWindowManager(WindowManager::Create()),
@ -28,6 +30,7 @@ void DesktopManager::ClearEvents()
void DesktopManager::OnKeyboardEvent(const KeyboardEvent* event)
{
MLOG_INFO("Got key event: " << event->GetKeyString());
GetWindowManager()->OnKeyboardEvent(event);
}
@ -97,14 +100,14 @@ void DesktopManager::SetKeyboard(KeyboardUPtr keyboard)
mKeyboard = std::move(keyboard);
}
void DesktopManager::SetMainApp(AbstractDesktopAppPtr mainApp)
void DesktopManager::SetMainApp(std::shared_ptr<AbstractApp> mainApp)
{
mMainApplication = mainApp;
}
AbstractDesktopAppPtr DesktopManager::GetMainApp()
AbstractApp* DesktopManager::GetMainApp()
{
return mMainApplication;
return mMainApplication.get();
}
void DesktopManager::AddScreen(ScreenPtr screen)

View file

@ -10,7 +10,7 @@
#include "MouseEvent.h"
#include "WindowManager.h"
#include "UiEvent.h"
#include "AbstractDesktopApp.h"
#include "AbstractApp.h"
#include "EventManager.h"
class DesktopManager
@ -25,9 +25,9 @@ public:
void SetWindowManager(WindowManagerUPtr windowManager);
void SetMainApp(AbstractDesktopAppPtr mainApp);
void SetMainApp(std::shared_ptr<AbstractApp> mainApp);
AbstractDesktopAppPtr GetMainApp();
AbstractApp* GetMainApp();
WindowManager* GetWindowManager() const;
@ -58,7 +58,7 @@ private:
WindowManagerUPtr mWindowManager;
KeyboardUPtr mKeyboard;
EventManagerUPtr mEventManager;
AbstractDesktopAppPtr mMainApplication;
std::shared_ptr<AbstractApp> mMainApplication;
bool mModified;
};

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>;