#include "Win32Window.h" #include "Win32WindowInterface.h" #include "DirectXInterface.h" #include "Win32DxWindowInterface.h" #include "FileLogger.h" #include "StringUtils.h" #include "Widget.h" #include "DrawingContext.h" #include "DirectXPainter.h" #include "KeyboardEvent.h" #include "DesktopManager.h" #include LRESULT CALLBACK FreeWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); Win32Window::Win32Window(mt::Window* window, DirectXInterface* dxInterface) : IPlatformWindow(window) { if (dxInterface) { mDxInterface = std::make_unique(window, dxInterface); dynamic_cast(window->getDrawingContent()->getPainter())->setDxInterface(dxInterface); } } std::unique_ptr Win32Window::Create(mt::Window* window, DirectXInterface* dxInterface) { return std::make_unique(window, dxInterface); } 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(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 "Notes TK", // 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); } void Win32Window::onPaintMessage() { mDesktopManager->onUiEvent(PaintEvent::Create()); mWindow->doPaint(nullptr); } 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(); 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)); return 0; } case WM_PAINT: { onPaintMessage(); return 0; } case WM_SIZE: { auto width = LOWORD(lParam); auto height = HIWORD(lParam); MLOG_INFO("WM_SIZE: " << width << " | " << height); mWindow->setSize(width, height, false); if (wParam == SIZE_MINIMIZED) { mWindow->setDisplayState(WindowState::Display::MINIMIZED); } else if (wParam == SIZE_MAXIMIZED) { mWindow->setDisplayState(WindowState::Display::MAXIMIZED); mWindow->onResize(); } else if (wParam == SIZE_RESTORED) { if (mWindow->getDisplayState() == WindowState::Display::MINIMIZED) { mWindow->setDisplayState(WindowState::Display::NORMAL); mWindow->onResize(); } else if (mWindow->getDisplayState() == WindowState::Display::MAXIMIZED) { mWindow->setDisplayState(WindowState::Display::NORMAL); mWindow->onResize(); } else if (!mWindow->getIsSizingOnGoing()) { mWindow->onResize(); } } return 0; } case WM_ENTERSIZEMOVE: { MLOG_INFO("WM_ENTERSIZEMOVE"); mWindow->setIsSizingOnGoing(true); return 0; } case WM_EXITSIZEMOVE: { MLOG_INFO("WM_EXITSIZEMOVE"); mWindow->setIsSizingOnGoing(false); mWindow->onResize(); return 0; } } 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); } void Win32Window::beforePaint(mt::Screen* screen) { if (mDxInterface) { mDxInterface->initialize(); } } void Win32Window::afterPaint(mt::Screen* screen) { if (mDxInterface) { mDxInterface->onRender(); } else { 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); } } void Win32Window::onResize(unsigned width, unsigned height) { if (mDxInterface) { mDxInterface->onResize(); } }