// win-window.cpp #define _CRT_SECURE_NO_WARNINGS 1 #include #include #include "../window.h" #define WIN32_LEAN_AND_MEAN #define NOMINMAX #include #undef WIN32_LEAN_AND_MEAN #undef NOMINMAX #ifdef _MSC_VER #pragma warning(disable: 4996) #endif #include namespace renderer_test { class WinWindow : public Window { public: virtual SlangResult initialize(int width, int height) SLANG_OVERRIDE; virtual void show() SLANG_OVERRIDE; virtual void* getHandle() const SLANG_OVERRIDE { return m_hwnd; } virtual SlangResult runLoop(WindowListener* listener) SLANG_OVERRIDE; virtual ~WinWindow(); static LRESULT CALLBACK windowProc(HWND windowHandle, UINT message, WPARAM wParam, LPARAM lParam); protected: HINSTANCE m_hinst = nullptr; HWND m_hwnd = nullptr; }; // // We use a bare-minimum window procedure to get things up and running. // /* static */LRESULT CALLBACK WinWindow::windowProc(HWND windowHandle, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_CLOSE: PostQuitMessage(0); return 0; } return DefWindowProcW(windowHandle, message, wParam, lParam); } static ATOM _getWindowClassAtom(HINSTANCE hinst) { static ATOM s_windowClassAtom; if (s_windowClassAtom) { return s_windowClassAtom; } WNDCLASSEXW windowClassDesc; windowClassDesc.cbSize = sizeof(windowClassDesc); windowClassDesc.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW; windowClassDesc.lpfnWndProc = &WinWindow::windowProc; windowClassDesc.cbClsExtra = 0; windowClassDesc.cbWndExtra = 0; windowClassDesc.hInstance = hinst; windowClassDesc.hIcon = 0; windowClassDesc.hCursor = 0; windowClassDesc.hbrBackground = 0; windowClassDesc.lpszMenuName = 0; windowClassDesc.lpszClassName = L"SlangRenderTest"; windowClassDesc.hIconSm = 0; s_windowClassAtom = RegisterClassExW(&windowClassDesc); return s_windowClassAtom; } SlangResult WinWindow::initialize(int widthIn, int heightIn) { // Do initial window-creation stuff here, rather than in the renderer-specific files m_hinst = GetModuleHandleA(0); // First we register a window class. ATOM windowClassAtom = _getWindowClassAtom(m_hinst); if (!windowClassAtom) { fprintf(stderr, "error: failed to register window class\n"); return SLANG_FAIL; } // Next, we create a window using that window class. // We will create a borderless window since our screen-capture logic in GL // seems to get thrown off by having to deal with a window frame. DWORD windowStyle = WS_POPUP; DWORD windowExtendedStyle = 0; RECT windowRect = { 0, 0, widthIn, heightIn }; AdjustWindowRectEx(&windowRect, windowStyle, /*hasMenu=*/false, windowExtendedStyle); { auto width = windowRect.right - windowRect.left; auto height = windowRect.bottom - windowRect.top; LPWSTR windowName = L"Slang Render Test"; m_hwnd = CreateWindowExW( windowExtendedStyle, (LPWSTR)windowClassAtom, windowName, windowStyle, 0, 0, // x, y width, height, NULL, // parent NULL, // menu m_hinst, NULL); } if (!m_hwnd) { fprintf(stderr, "error: failed to create window\n"); return SLANG_FAIL; } return SLANG_OK; } void WinWindow::show() { // Once initialization is all complete, we show the window... int showCommand = SW_SHOW; ShowWindow(m_hwnd, showCommand); } SlangResult WinWindow::runLoop(WindowListener* listener) { // ... and enter the event loop: while (!m_isQuitting) { MSG message; int result = PeekMessageW(&message, NULL, 0, 0, PM_REMOVE); if (result != 0) { if (message.message == WM_QUIT) { m_quitValue = (int)message.wParam; return SLANG_OK; } TranslateMessage(&message); DispatchMessageW(&message); } else { if (listener) { SLANG_RETURN_ON_FAIL(listener->update(this)); } } } return SLANG_OK; } WinWindow::~WinWindow() { if (m_hwnd) { DestroyWindow(m_hwnd); } } Window* createWinWindow() { return new WinWindow; } } // namespace renderer_test