216 lines
6.7 KiB
C++
216 lines
6.7 KiB
C++
/**
|
|
******************************************************************************
|
|
* Xenia : Xbox 360 Emulator Research Project *
|
|
******************************************************************************
|
|
* Copyright 2014 Ben Vanik. All rights reserved. *
|
|
* Released under the BSD license - see LICENSE in the root for more details. *
|
|
******************************************************************************
|
|
*/
|
|
|
|
#include "xenia/ui/win32/win32_window.h"
|
|
|
|
#include <dwmapi.h>
|
|
#include <tpcshrd.h>
|
|
#include <windowsx.h>
|
|
|
|
#include "xenia/base/logging.h"
|
|
|
|
namespace xe {
|
|
namespace ui {
|
|
namespace win32 {
|
|
|
|
Win32Window::Win32Window(const std::wstring& title)
|
|
: Window(title), closing_(false) {
|
|
menu_ = nullptr;
|
|
}
|
|
|
|
Win32Window::~Win32Window() {}
|
|
|
|
bool Win32Window::Initialize() {
|
|
Create();
|
|
return true;
|
|
}
|
|
|
|
bool Win32Window::Create() {
|
|
HINSTANCE hInstance = GetModuleHandle(nullptr);
|
|
|
|
WNDCLASSEX wcex;
|
|
wcex.cbSize = sizeof(WNDCLASSEX);
|
|
wcex.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
|
|
wcex.lpfnWndProc = Win32Control::WndProcThunk;
|
|
wcex.cbClsExtra = 0;
|
|
wcex.cbWndExtra = 0;
|
|
wcex.hInstance = hInstance;
|
|
wcex.hIcon = nullptr; // LoadIcon(hInstance, (LPCTSTR)IDI_TUTORIAL1);
|
|
wcex.hIconSm = nullptr; // LoadIcon(hInstance, (LPCTSTR)IDI_TUTORIAL1);
|
|
wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);
|
|
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
|
|
wcex.lpszMenuName = nullptr;
|
|
wcex.lpszClassName = L"XeniaWindowClass";
|
|
if (!RegisterClassEx(&wcex)) {
|
|
XELOGE("RegisterClassEx failed");
|
|
return false;
|
|
}
|
|
|
|
// Setup initial size.
|
|
DWORD window_style = WS_OVERLAPPEDWINDOW;
|
|
DWORD window_ex_style = WS_EX_APPWINDOW | WS_EX_CONTROLPARENT;
|
|
RECT rc = {0, 0, width_, height_};
|
|
AdjustWindowRect(&rc, WS_OVERLAPPEDWINDOW, FALSE);
|
|
|
|
// Create window.
|
|
hwnd_ = CreateWindowEx(window_ex_style, L"XeniaWindowClass", title_.c_str(),
|
|
window_style, rc.left, rc.top, rc.right - rc.left,
|
|
rc.bottom - rc.top, nullptr, nullptr, hInstance, this);
|
|
if (!hwnd_) {
|
|
XELOGE("CreateWindow failed");
|
|
return false;
|
|
}
|
|
|
|
// Disable flicks.
|
|
ATOM atom = GlobalAddAtom(L"MicrosoftTabletPenServiceProperty");
|
|
const DWORD_PTR dwHwndTabletProperty =
|
|
TABLET_DISABLE_PRESSANDHOLD | // disables press and hold (right-click)
|
|
// gesture
|
|
TABLET_DISABLE_PENTAPFEEDBACK | // disables UI feedback on pen up (waves)
|
|
TABLET_DISABLE_PENBARRELFEEDBACK | // disables UI feedback on pen button
|
|
// down (circle)
|
|
TABLET_DISABLE_FLICKS | // disables pen flicks (back, forward, drag down,
|
|
// drag up)
|
|
TABLET_DISABLE_TOUCHSWITCH | TABLET_DISABLE_SMOOTHSCROLLING |
|
|
TABLET_DISABLE_TOUCHUIFORCEON | TABLET_ENABLE_MULTITOUCHDATA;
|
|
SetProp(hwnd_, L"MicrosoftTabletPenServiceProperty",
|
|
reinterpret_cast<HANDLE>(dwHwndTabletProperty));
|
|
GlobalDeleteAtom(atom);
|
|
|
|
// Enable DWM elevation.
|
|
EnableMMCSS();
|
|
|
|
ShowWindow(hwnd_, SW_SHOWNORMAL);
|
|
UpdateWindow(hwnd_);
|
|
|
|
return 0;
|
|
}
|
|
|
|
void Win32Window::EnableMMCSS() {
|
|
HMODULE hLibrary = LoadLibrary(L"DWMAPI.DLL");
|
|
if (!hLibrary) {
|
|
return;
|
|
}
|
|
|
|
typedef HRESULT(__stdcall * PDwmEnableMMCSS)(BOOL);
|
|
PDwmEnableMMCSS pDwmEnableMMCSS =
|
|
(PDwmEnableMMCSS)GetProcAddress(hLibrary, "DwmEnableMMCSS");
|
|
if (pDwmEnableMMCSS) {
|
|
pDwmEnableMMCSS(TRUE);
|
|
}
|
|
|
|
typedef HRESULT(__stdcall * PDwmSetPresentParameters)(
|
|
HWND, DWM_PRESENT_PARAMETERS*);
|
|
PDwmSetPresentParameters pDwmSetPresentParameters =
|
|
(PDwmSetPresentParameters)GetProcAddress(hLibrary,
|
|
"DwmSetPresentParameters");
|
|
if (pDwmSetPresentParameters) {
|
|
DWM_PRESENT_PARAMETERS pp;
|
|
std::memset(&pp, 0, sizeof(DWM_PRESENT_PARAMETERS));
|
|
pp.cbSize = sizeof(DWM_PRESENT_PARAMETERS);
|
|
pp.fQueue = FALSE;
|
|
pp.cBuffer = 2;
|
|
pp.fUseSourceRate = FALSE;
|
|
pp.cRefreshesPerFrame = 1;
|
|
pp.eSampling = DWM_SOURCE_FRAME_SAMPLING_POINT;
|
|
pDwmSetPresentParameters(hwnd_, &pp);
|
|
}
|
|
|
|
FreeLibrary(hLibrary);
|
|
}
|
|
|
|
bool Win32Window::set_title(const std::wstring& title) {
|
|
if (!Window::set_title(title)) {
|
|
return false;
|
|
}
|
|
SetWindowText(hwnd_, title.c_str());
|
|
return true;
|
|
}
|
|
|
|
void Win32Window::Resize(int32_t width, int32_t height) {
|
|
RECT rc = {0, 0, width, height};
|
|
bool has_menu = menu_ ? true : false;
|
|
AdjustWindowRect(&rc, WS_OVERLAPPEDWINDOW, has_menu);
|
|
if (true) {
|
|
rc.right += 100 - rc.left;
|
|
rc.left = 100;
|
|
rc.bottom += 100 - rc.top;
|
|
rc.top = 100;
|
|
}
|
|
Window::Resize(rc.left, rc.top, rc.right, rc.bottom);
|
|
}
|
|
|
|
void Win32Window::Resize(int32_t left, int32_t top, int32_t right,
|
|
int32_t bottom) {
|
|
RECT rc = {left, top, right, bottom};
|
|
bool has_menu = menu_ ? true : false;
|
|
AdjustWindowRect(&rc, WS_OVERLAPPEDWINDOW, has_menu);
|
|
Window::Resize(rc.left, rc.top, rc.right, rc.bottom);
|
|
}
|
|
|
|
void Win32Window::ResizeToFill(int32_t pad_left, int32_t pad_top,
|
|
int32_t pad_right, int32_t pad_bottom) {
|
|
// TODO(benvanik): fullscreen.
|
|
}
|
|
|
|
void Win32Window::OnClose() {
|
|
if (!closing_ && hwnd_) {
|
|
closing_ = true;
|
|
CloseWindow(hwnd_);
|
|
}
|
|
}
|
|
|
|
void Win32Window::OnSetMenu(MenuItem* menu) {
|
|
Win32MenuItem* win_menu = reinterpret_cast<Win32MenuItem*>(menu);
|
|
if (win_menu) {
|
|
::SetMenu(hwnd_, win_menu->handle());
|
|
}
|
|
}
|
|
|
|
LRESULT Win32Window::WndProc(HWND hWnd, UINT message, WPARAM wParam,
|
|
LPARAM lParam) {
|
|
switch (message) {
|
|
case WM_ACTIVATEAPP:
|
|
if (wParam) {
|
|
// Made active.
|
|
OnShow();
|
|
} else {
|
|
// Made inactive.
|
|
OnHide();
|
|
}
|
|
break;
|
|
case WM_CLOSE:
|
|
closing_ = true;
|
|
Close();
|
|
break;
|
|
|
|
case WM_TABLET_QUERYSYSTEMGESTURESTATUS:
|
|
return TABLET_DISABLE_PRESSANDHOLD | // disables press and hold
|
|
// (right-click) gesture
|
|
TABLET_DISABLE_PENTAPFEEDBACK | // disables UI feedback on pen up
|
|
// (waves)
|
|
TABLET_DISABLE_PENBARRELFEEDBACK | // disables UI feedback on pen
|
|
// button down (circle)
|
|
TABLET_DISABLE_FLICKS | // disables pen flicks (back, forward,
|
|
// drag down, drag up)
|
|
TABLET_DISABLE_TOUCHSWITCH | TABLET_DISABLE_SMOOTHSCROLLING |
|
|
TABLET_DISABLE_TOUCHUIFORCEON | TABLET_ENABLE_MULTITOUCHDATA;
|
|
|
|
case WM_COMMAND: {
|
|
OnCommand(LOWORD(wParam));
|
|
} break;
|
|
}
|
|
|
|
return Win32Control::WndProc(hWnd, message, wParam, lParam);
|
|
}
|
|
|
|
} // namespace win32
|
|
} // namespace ui
|
|
} // namespace xe
|