Files
pcsx2/plugins/LilyPad/WindowsMessaging.cpp
T
Jake.Stine 1ea29b0e62 Lilypad: Implemented full support for child-window GS viewports (fixes windows messaging being broken from the prev rev).
DevNotes: The main change here was to turn WndProcEater into a class and create multiple instances of it, so that it could manage the WndProcs for multiple windows concurrently.  The "frame" (top-level window) gets a WndProc that sets title and handles screensaver/alt-enter hacks.  The "viewport" (provided by PCSX2) gets the usual keyboard input handler WndProc.  Config buttons also have their own WndProc that avoid fuzzy logic conflicts with the other two.

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@2277 96395faa-99c1-11dd-bbfe-3dabce05a288
2009-11-30 20:52:09 +00:00

175 lines
4.5 KiB
C++

#include "Global.h"
#include "InputManager.h"
#include "WindowsMessaging.h"
#include "VKey.h"
#include "DeviceEnumerator.h"
#include "WndProcEater.h"
#include "WindowsKeyboard.h"
#include "WindowsMouse.h"
ExtraWndProcResult WindowsMessagingWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *output);
class WindowsMessagingKeyboard;
class WindowsMessagingMouse;
static WindowsMessagingKeyboard *wmk = 0;
static WindowsMessagingMouse *wmm = 0;
class WindowsMessagingKeyboard : public WindowsKeyboard {
public:
WindowsMessagingKeyboard() : WindowsKeyboard(WM, L"WM Keyboard") {
}
int Activate(InitInfo *initInfo) {
// Redundant. Should match the next line.
// Deactivate();
if (wmk) wmk->Deactivate();
hWndProc = initInfo->hWndProc;
if (!wmm)
hWndProc->Eat(WindowsMessagingWndProc, EATPROC_NO_UPDATE_WHILE_UPDATING_DEVICES);
wmk = this;
InitState();
active = 1;
return 1;
}
void Deactivate() {
if (active) {
if (!wmm)
hWndProc->ReleaseExtraProc(WindowsMessagingWndProc);
wmk = 0;
active = 0;
FreeState();
}
}
void CheckKey(int vkey) {
UpdateKey(vkey, 1&(((unsigned short)GetAsyncKeyState(vkey))>>15));
}
};
class WindowsMessagingMouse : public WindowsMouse {
public:
WindowsMessagingMouse() : WindowsMouse(WM, 1, L"WM Mouse") {
}
int Activate(InitInfo *initInfo) {
// Redundant. Should match the next line.
// Deactivate();
if (wmm) wmm->Deactivate();
hWndProc = initInfo->hWndProc;
if (!wmk)
hWndProc->Eat(WindowsMessagingWndProc, EATPROC_NO_UPDATE_WHILE_UPDATING_DEVICES);
GetMouseCapture(hWndProc->hWndEaten);
active = 1;
wmm = this;
AllocState();
return 1;
}
void Deactivate() {
if (active) {
if (!wmk)
hWndProc->ReleaseExtraProc(WindowsMessagingWndProc);
ReleaseMouseCapture();
wmm = 0;
active = 0;
FreeState();
}
}
};
ExtraWndProcResult WindowsMessagingWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *output) {
if (wmk) {
if (uMsg == WM_KEYDOWN || uMsg == WM_SYSKEYDOWN || uMsg == WM_KEYUP || uMsg == WM_SYSKEYUP) {
if (wParam == VK_SHIFT) {
wmk->CheckKey(VK_RSHIFT);
wmk->CheckKey(VK_LSHIFT);
}
else if (wParam == VK_CONTROL) {
wmk->CheckKey(VK_RCONTROL);
wmk->CheckKey(VK_LCONTROL);
}
else if (wParam == VK_MENU) {
wmk->CheckKey(VK_RMENU);
wmk->CheckKey(VK_LMENU);
}
else
wmk->UpdateKey(wParam, (uMsg == WM_KEYDOWN || uMsg == WM_SYSKEYDOWN));
return NO_WND_PROC;
}
// Needed to prevent default handling of keys in some situations.
else if (uMsg == WM_CHAR || uMsg == WM_UNICHAR) {
return NO_WND_PROC;
}
else if (uMsg == WM_ACTIVATE) {
// Not really needed, but doesn't hurt.
memset(wmk->physicalControlState, 0, sizeof(int) * wmk->numPhysicalControls);
}
}
if (wmm) {
if (uMsg == WM_MOUSEMOVE) {
POINT p;
GetCursorPos(&p);
// Need check to prevent cursor movement cascade.
if (p.x != wmm->center.x || p.y != wmm->center.y) {
wmm->UpdateAxis(0, p.x - wmm->center.x);
wmm->UpdateAxis(1, p.y - wmm->center.y);
SetCursorPos(wmm->center.x, wmm->center.y);
}
return NO_WND_PROC;
}
else if (uMsg == WM_LBUTTONDOWN || uMsg == WM_LBUTTONUP) {
wmm->UpdateButton(0, uMsg == WM_LBUTTONDOWN);
return NO_WND_PROC;
}
else if (uMsg == WM_RBUTTONDOWN || uMsg == WM_RBUTTONUP) {
wmm->UpdateButton(1, uMsg == WM_RBUTTONDOWN);
return NO_WND_PROC;
}
else if (uMsg == WM_MBUTTONDOWN || uMsg == WM_MBUTTONUP) {
wmm->UpdateButton(2, uMsg == WM_MBUTTONDOWN);
return NO_WND_PROC;
}
else if (uMsg == WM_XBUTTONDOWN || uMsg == WM_XBUTTONUP) {
wmm->UpdateButton(3+((wParam>>16) == XBUTTON2), uMsg == WM_XBUTTONDOWN);
return NO_WND_PROC;
}
else if (uMsg == WM_MOUSEWHEEL) {
wmm->UpdateAxis(2, ((int)wParam>>16)/WHEEL_DELTA);
return NO_WND_PROC;
}
else if (uMsg == WM_MOUSEHWHEEL) {
wmm->UpdateAxis(3, ((int)wParam>>16)/WHEEL_DELTA);
return NO_WND_PROC;
}
else if (uMsg == WM_SIZE && wmm->active) {
WindowsMouse::WindowResized(hWnd);
}
// Taken care of elsewhere. When binding, killing focus means stop reading input.
// When running PCSX2, I release all mouse and keyboard input elsewhere.
/*else if (uMsg == WM_KILLFOCUS) {
wmm->Deactivate();
}//*/
}
return CONTINUE_BLISSFULLY;
}
void EnumWindowsMessagingDevices() {
dm->AddDevice(new WindowsMessagingKeyboard());
dm->AddDevice(new WindowsMessagingMouse());
}