src/ngfx/porting/windows/WWindow.cpp
Functions
|
Name |
LRESULT |
windowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) |
Defines
Functions Documentation
function windowProc
LRESULT windowProc(
HWND hWnd,
UINT message,
WPARAM wParam,
LPARAM lParam
)
Macro Documentation
define WINDOW_CLASS_NAME
#define WINDOW_CLASS_NAME L"WWindow"
Source code
/*
* Copyright 2020 GoPro Inc.
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#include "ngfx/porting/windows/WWindow.h"
#include "ngfx/core/DebugUtil.h"
#include "ngfx/core/StringUtil.h"
#include <windowsx.h>
using namespace ngfx;
#define WINDOW_CLASS_NAME L"WWindow"
WWindow::Monitor WWindow::getPrimaryMonitor() {
DWORD adapterIndex, displayIndex;
DISPLAY_DEVICEW adapter, display;
// get primary adapter
for (adapterIndex = 0;; adapterIndex++) {
ZeroMemory(&adapter, sizeof(adapter));
adapter.cb = sizeof(adapter);
if (!EnumDisplayDevicesW(NULL, adapterIndex, &adapter, 0))
break;
if (!(adapter.StateFlags & DISPLAY_DEVICE_ACTIVE))
continue;
if (adapter.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE)
break;
}
// get primary display
for (displayIndex = 0;; displayIndex++) {
ZeroMemory(&display, sizeof(display));
display.cb = sizeof(display);
if (!EnumDisplayDevicesW(adapter.DeviceName, displayIndex, &display, 0))
break;
if (display.StateFlags & DISPLAY_DEVICE_ACTIVE)
break;
}
return {adapter, display};
}
WWindow::VideoMode WWindow::getVideoMode(const Monitor &monitor) {
DEVMODEW dm;
ZeroMemory(&dm, sizeof(dm));
dm.dmSize = sizeof(dm);
EnumDisplaySettingsW(monitor.adapter.DeviceName, ENUM_CURRENT_SETTINGS, &dm);
return {int(dm.dmPelsWidth), int(dm.dmPelsHeight)};
}
LRESULT windowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
WWindow *thiz =
reinterpret_cast<WWindow *>(GetWindowLongPtr(hWnd, GWLP_USERDATA));
switch (message) {
case WM_CREATE: {
LPCREATESTRUCT pCreateStruct = reinterpret_cast<LPCREATESTRUCT>(lParam);
SetWindowLongPtr(hWnd, GWLP_USERDATA,
reinterpret_cast<LONG_PTR>(pCreateStruct->lpCreateParams));
return 0;
}
case WM_KEYDOWN: {
if (thiz->onKey)
thiz->onKey(KeyCode(wParam), PRESS);
return 0;
}
case WM_KEYUP: {
if (thiz->onKey)
thiz->onKey(KeyCode(wParam), RELEASE);
return 0;
}
case WM_MOUSEWHEEL: {
if (thiz->onScroll)
thiz->onScroll(0.0, GET_WHEEL_DELTA_WPARAM(wParam) / double(WHEEL_DELTA));
return 0;
}
case WM_LBUTTONDOWN: {
if (thiz->onMouseButton)
thiz->onMouseButton(MOUSE_BUTTON_LEFT, InputAction(PRESS));
return 0;
}
case WM_MBUTTONDOWN: {
if (thiz->onMouseButton)
thiz->onMouseButton(MOUSE_BUTTON_MIDDLE, InputAction(PRESS));
return 0;
}
case WM_RBUTTONDOWN: {
if (thiz->onMouseButton)
thiz->onMouseButton(MOUSE_BUTTON_RIGHT, InputAction(PRESS));
return 0;
}
case WM_LBUTTONUP: {
if (thiz->onMouseButton)
thiz->onMouseButton(MOUSE_BUTTON_LEFT, InputAction(RELEASE));
return 0;
}
case WM_MBUTTONUP: {
if (thiz->onMouseButton)
thiz->onMouseButton(MOUSE_BUTTON_MIDDLE, InputAction(RELEASE));
return 0;
}
case WM_RBUTTONUP: {
if (thiz->onMouseButton)
thiz->onMouseButton(MOUSE_BUTTON_RIGHT, InputAction(RELEASE));
return 0;
}
case WM_MOUSEMOVE: {
if (thiz->onCursorPos)
thiz->onCursorPos(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
return 0;
}
case WM_PAINT: {
thiz->onUpdate();
thiz->onPaint();
return 0;
}
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hWnd, message, wParam, lParam);
}
void WWindow::registerWindowClass() {
WNDCLASSEXW wc = {};
wc.cbSize = sizeof(wc);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = (WNDPROC)windowProc;
wc.hInstance = GetModuleHandleW(NULL);
wc.hCursor = LoadCursorW(NULL, IDC_ARROW);
wc.lpszClassName = WINDOW_CLASS_NAME;
wc.hIcon = HICON(LoadImageW(NULL, IDI_APPLICATION, IMAGE_ICON, 0, 0,
LR_DEFAULTSIZE | LR_SHARED));
if (!RegisterClassExW(&wc))
NGFX_ERR("");
}
void WWindow::createWindow(int w, int h, const char *title) {
const wchar_t *wTitle = StringUtil::toWString(title).c_str();
auto &hWnd = d3dSurface.v;
RECT rect = {0, 0, w, h};
DWORD style = WS_POPUP; // WS_OVERLAPPED_WINDOW;
AdjustWindowRect(&rect, style, FALSE);
hWnd = CreateWindow(WINDOW_CLASS_NAME, wTitle, style, 0, 0,
rect.right - rect.left, rect.bottom - rect.top, nullptr,
nullptr, GetModuleHandleW(NULL), this);
assert(hWnd);
ShowWindow(hWnd, SW_SHOWNA);
}
void WWindow::getFramebufferSize(int *w, int *h) {
RECT area;
auto &hWnd = d3dSurface.v;
GetClientRect(hWnd, &area);
if (w)
*w = area.right;
if (h)
*h = area.bottom;
}
void WWindow::create(GraphicsContext *graphicsContext, const char *title,
std::function<void(Window *thiz)> onWindowCreated, int w,
int h) {
this->w = w;
this->h = h;
auto monitor = getPrimaryMonitor();
auto videoMode = getVideoMode(monitor);
if (w == Window::DISPLAY_WIDTH)
w = videoMode.width;
if (h == Window::DISPLAY_HEIGHT)
h = videoMode.height;
registerWindowClass();
createWindow(w, h, title);
getFramebufferSize(&w, &h);
this->w = w;
this->h = h;
d3dSurface.w = w;
d3dSurface.h = h;
surface = &d3dSurface;
onWindowCreated(this);
}
bool WWindow::shouldClose() { return (msg.message == WM_QUIT); }
void WWindow::pollEvents() {
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
WWindow::~WWindow() {}
void WWindow::destroySurface() {}
Window *Window::create(GraphicsContext *graphicsContext, const char *title,
std::function<void(Window *thiz)> onWindowCreated, int w,
int h) {
auto window = new WWindow();
window->create(graphicsContext, title, onWindowCreated, w, h);
return window;
}
Updated on 3 April 2021 at 20:21:52 PDT