diff -r 000000000000 -r 7f656887cf89 plugins/consoles/rcons/server/win32/Window.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugins/consoles/rcons/server/win32/Window.cpp Wed Jun 23 15:52:26 2010 +0100 @@ -0,0 +1,546 @@ +// Window.cpp +// +// Copyright (c) 2010 Accenture. All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Accenture - Initial contribution +// + +#include "Misc.h" +#include "stdafx.h" +#include "console_host.h" +#include "Window.h" + +#ifdef _DEBUG +#undef THIS_FILE +static char THIS_FILE[]=__FILE__; +#endif + +const DWORD KWindowStyle = (WS_OVERLAPPEDWINDOW | WS_HSCROLL | WS_VSCROLL);// & ~WS_THICKFRAME; +CWindow* CWindow::sFirst = NULL; +CWindow* CWindow::sLast = NULL; +MWindowMessageHandler* CWindow::sFirstMessageHandler = NULL; +MWindowMessageHandler* CWindow::sLastMessageHandler = NULL; + + +// From e32keys.h +enum TKeyCode + { + EKeyNull=0x0000, + EKeyBell=0x0007, + EKeyBackspace=0x0008, + EKeyTab=0x0009, + EKeyLineFeed=0x000a, + EKeyVerticalTab=0x000b, + EKeyFormFeed=0x000c, + EKeyEnter=0x000d, + EKeyEscape=0x001b, + EKeySpace=0x0020, + EKeyDelete=0x007f, + EKeyPrintScreen=0xf800, + EKeyPause, + EKeyHome, + EKeyEnd, + EKeyPageUp, + EKeyPageDown, + EKeyInsert, + EKeyLeftArrow, + EKeyRightArrow, + EKeyUpArrow, + EKeyDownArrow, + EKeyLeftShift, + EKeyRightShift, + EKeyLeftAlt, + EKeyRightAlt, + EKeyLeftCtrl, + EKeyRightCtrl, + EKeyLeftFunc, + EKeyRightFunc, + EKeyCapsLock, + EKeyNumLock, + EKeyScrollLock, + EKeyF1, + EKeyF2, + EKeyF3, + EKeyF4, + EKeyF5, + EKeyF6, + EKeyF7, + EKeyF8, + EKeyF9, + EKeyF10, + EKeyF11, + EKeyF12, + EKeyF13, + EKeyF14, + EKeyF15, + EKeyF16, + EKeyF17, + EKeyF18, + EKeyF19, + EKeyF20, + EKeyF21, + EKeyF22, + EKeyF23, + EKeyF24, + EKeyOff, + EKeyIncContrast, + EKeyDecContrast, + EKeyBacklightOn, + EKeyBacklightOff, + EKeyBacklightToggle, + EKeySliderDown, + EKeySliderUp, + EKeyMenu, + EKeyDictaphonePlay, + EKeyDictaphoneStop, + EKeyDictaphoneRecord, + EKeyHelp, + EKeyDial, + EKeyScreenDimension0, + EKeyScreenDimension1, + EKeyScreenDimension2, + EKeyScreenDimension3, + EKeyIncVolume, + EKeyDecVolume, + EKeyDevice0, + EKeyDevice1, + EKeyDevice2, + EKeyDevice3, + EKeyDevice4, + EKeyDevice5, + EKeyDevice6, + EKeyDevice7, + EKeyDevice8, + EKeyDevice9, + EKeyDeviceA, + EKeyDeviceB, + EKeyDeviceC, + EKeyDeviceD, + EKeyDeviceE, + EKeyDeviceF, + EKeyApplication0, + EKeyApplication1, + EKeyApplication2, + EKeyApplication3, + EKeyApplication4, + EKeyApplication5, + EKeyApplication6, + EKeyApplication7, + EKeyApplication8, + EKeyApplication9, + EKeyApplicationA, + EKeyApplicationB, + EKeyApplicationC, + EKeyApplicationD, + EKeyApplicationE, + EKeyApplicationF, + EKeyYes, + EKeyNo, + EKeyIncBrightness, + EKeyDecBrightness + }; + +enum TEventModifier + { + EModifierAutorepeatable=0x00000001, /**< Key event can auto-repeat.*/ + EModifierKeypad=0x00000002, /**< The key that generated the event was on the numeric keypad, on the emulator.*/ + EModifierLeftAlt=0x00000004, /**< Left Alt key.*/ + EModifierRightAlt=0x00000008, /**< Right Alt key.*/ + EModifierAlt=0x00000010, /**< Single Alt key.*/ + EModifierLeftCtrl=0x00000020, /**< Left Control (Ctrl) key.*/ + EModifierRightCtrl=0x00000040, /**< Right Control (Ctrl) key.*/ + EModifierCtrl=0x00000080, /**< Single Control (Ctrl) key.*/ + EModifierLeftShift=0x00000100, /**< Left Shift key.*/ + EModifierRightShift=0x00000200, /**< Right Shift key.*/ + EModifierShift=0x00000400, /**< Single Shift key.*/ + EModifierLeftFunc=0x00000800, /**< Left Fn key.*/ + EModifierRightFunc=0x00001000, /**< Right Fn key.*/ + EModifierFunc=0x00002000, /**< Single Fn key.*/ + EModifierCapsLock=0x00004000, /**< Caps lock key.*/ + EModifierNumLock=0x00008000, /**< Num lock key.*/ + EModifierScrollLock=0x00010000, /**< Scroll lock key.*/ + EModifierKeyUp=0x00020000, /**< Key up event.*/ + EModifierSpecial=0x00040000, /**< The keycode is a non-standard keyboard character that has been generated in a special keyboard mode, for example accented vowels.*/ + EModifierDoubleClick=0x00080000, /**< Double click.*/ + EModifierPureKeycode=0x00100000, /**< The key code in the key event is not changed. E.g.an alphabetic key is not changed by the Caps Lock or Shift key being pressed.*/ + EModifierKeyboardExtend=0x00200000, /**< The "Keyboard extend" generated modifier. */ + EModifierCancelRotation=0x00000000, /**< No Keyboard rotation is in effect. */ + EModifierRotateBy90=0x00400000, /**< Keyboard rotation through 90 degrees clockwise is in effect. */ + EModifierRotateBy180=0x00800000, /**< Keyboard rotation through 180 degrees clockwise is in effect. */ + EModifierRotateBy270=0x01000000, /**< Keyboard rotation through 270 degrees clockwise is in effect. */ + EModifierPointer3DButton1=0x02000000,/**< 3D pointer device specific modifier (button 1). */ + EModifierPointer3DButton2=0x04000000,/**< 3D pointer device specific modifier (button 2). */ + EModifierPointer3DButton3=0x08000000,/**< 3D pointer device specific modifier (button 3). */ + EAllModifiers=0x0fffffff /**< A combination of all event modifiers.*/ + }; + + +MWindowMessageHandler::MWindowMessageHandler() : iNext(NULL), iPrevious(NULL) + { + } + +CWindow::~CWindow() + { + if (sLast == this) + { + ASSERT(iNext == NULL); + sLast = iPrevious; + } + if (sFirst == this) + { + sFirst = iNext; + } + if (iPrevious) + { + iPrevious->iNext = iNext; + } + if (iNext) + { + iNext->iPrevious = iPrevious; + } + } + +void CWindow::AddMessageHandler(MWindowMessageHandler& aHandler) + { + if (sFirstMessageHandler == NULL) + { + ASSERT(sLastMessageHandler == NULL); + sFirstMessageHandler = &aHandler; + sLastMessageHandler = &aHandler; + } + else + { + sLastMessageHandler->iNext = &aHandler; + aHandler.iPrevious = sLastMessageHandler; + sLastMessageHandler = &aHandler; + } + } + +void CWindow::RemoveMessageHandler(MWindowMessageHandler& aHandler) + { + if (sLastMessageHandler == &aHandler) + { + ASSERT(aHandler.iNext == NULL); + sLastMessageHandler = aHandler.iPrevious; + } + if (sFirstMessageHandler == &aHandler) + { + sFirstMessageHandler = aHandler.iNext; + } + if (aHandler.iPrevious) + { + aHandler.iPrevious->iNext = aHandler.iNext; + } + if (aHandler.iNext) + { + aHandler.iNext->iPrevious = aHandler.iPrevious; + } + } + +HWND CWindow::Handle() const + { + return iHandle; + } + +void CWindow::SetTitle(LPCTSTR aTitle) + { + SetWindowText(iHandle, aTitle); + } + +void CWindow::GetTitle(LPTSTR aTitle, int aMaxLength) const + { + GetWindowText(iHandle, aTitle, aMaxLength); + } + +CWindow::CWindow() : iNext(NULL), iPrevious(NULL), iObserver(NULL) + { + if (sFirst == NULL) + { + ASSERT(sLast == NULL); + sFirst = this; + sLast = this; + } + else + { + sLast->iNext = this; + iPrevious = sLast; + sLast = this; + } + } + +void CWindow::Construct(HINSTANCE aAppHandle, LPCTSTR aWindowClass, LPCTSTR aTitle, int aPoxX, int aPosY, int aWidth, int aHeight, MWindowObserver* aObserver) + { + iAppHandle = aAppHandle; + iObserver = aObserver; + + RECT windowRect = {0, 0, aWidth, aHeight}; + AdjustWindowRect(&windowRect, KWindowStyle, TRUE); + windowRect.right += GetSystemMetrics(SM_CYVSCROLL); + iHandle = CreateWindow(aWindowClass, aTitle, KWindowStyle, aPoxX, aPosY, windowRect.right-windowRect.left, windowRect.bottom-windowRect.top, NULL, NULL, aAppHandle, NULL); + if (iHandle == 0) + { + throw KExceptionWindowConstructFailed; + } + ShowWindow(iHandle, SW_SHOWNORMAL); + if (UpdateWindow(iHandle) == 0) + { + throw KExceptionWindowConstructFailed; + } + } + +void CWindow::Redraw() + { + InvalidateRect(iHandle, NULL, TRUE); + } + +void CWindow::Draw() const + { + } + +LRESULT CWindow::HandleChar(TCHAR, UINT) + { + return 0; + } + +LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) + { + switch (message) + { + case WM_INITDIALOG: + return TRUE; + case WM_COMMAND: + if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) + { + EndDialog(hDlg, LOWORD(wParam)); + return TRUE; + } + break; + } + return FALSE; + } + +LRESULT CWindow::HandleCommand(UINT aMessage, WPARAM aWParam, LPARAM aLParam) + { + int wmId = LOWORD(aWParam); + int wmEvent = HIWORD(aWParam); + switch (wmId) + { + case ID_ABOUT: + DialogBox(iAppHandle, (LPCTSTR)IDD_ABOUTBOX, iHandle, (DLGPROC)About); + break; + case IDM_EXIT: + DestroyWindow(iHandle); + break; + default: + if (iObserver) + { + return iObserver->HandleWindowCommand(aMessage, aWParam, aLParam); + } + return DefWindowProc(iHandle, aMessage, aWParam, aLParam); + } + return 0; + } + +LRESULT CWindow::HandleFocusChange(bool aFocused) + { + return 0; + } + +void CWindow::HandleScrollEvent(UINT aMessage, WPARAM aWParam) + { + } + +void CWindow::HandleSizeChanged(int aWidth, int aHeight) + { + } + +void CWindow::HandleMouseEvent(UINT aMessage, WPARAM aWParam, LPARAM aLParam) + { + } + +void CWindow::HandleMenuPopUp(HMENU aMenu) + { + } + +LRESULT CALLBACK CWindow::HandleMessage(HWND aHandle, UINT aMessage, WPARAM aWParam, LPARAM aLParam) + { + CWindow* window = Instance(aHandle); + + if (window) + { + MWindowMessageHandler* messageHandler = sFirstMessageHandler; + while (messageHandler) + { + if (messageHandler->HandleWindowMessage(aMessage, aWParam, aLParam) == 0) + { + return 0; + } + messageHandler = messageHandler->iNext; + } + } + + switch (aMessage) + { + case WM_SETFOCUS: + if (window) + { + window->HandleFocusChange(TRUE); + } + break; + case WM_KILLFOCUS: + if (window) + { + window->HandleFocusChange(FALSE); + } + break; + case WM_COMMAND: + if (window) + { + return window->HandleCommand(aMessage, aWParam, aLParam); + } + break; + case WM_KEYDOWN: + case WM_SYSKEYDOWN: + if (window) + { + UINT modifiers = EModifierAutorepeatable; + if (aMessage == WM_SYSKEYDOWN) + { + modifiers |= (EModifierLeftAlt | EModifierAlt | EModifierLeftFunc | EModifierFunc); + } + switch (aWParam) + { + case VK_LEFT: return window->HandleChar(EKeyLeftArrow, modifiers); + case VK_UP: return window->HandleChar(EKeyUpArrow, modifiers); + case VK_RIGHT: return window->HandleChar(EKeyRightArrow, modifiers); + case VK_DOWN: return window->HandleChar(EKeyDownArrow, modifiers); + case VK_HOME: return window->HandleChar(EKeyHome, modifiers); + case VK_END: return window->HandleChar(EKeyEnd, modifiers); + case VK_PRIOR: return window->HandleChar(EKeyPageUp, modifiers); + case VK_NEXT: return window->HandleChar(EKeyPageDown, modifiers); + case VK_PAUSE: return window->HandleChar(EKeyPause, modifiers); + case VK_PRINT: return window->HandleChar(EKeyPrintScreen, modifiers); + case VK_INSERT: return window->HandleChar(EKeyInsert, modifiers); + case VK_DELETE: return window->HandleChar(EKeyDelete, modifiers); + case VK_CAPITAL: return window->HandleChar(EKeyCapsLock, modifiers); + case VK_NUMLOCK: return window->HandleChar(EKeyNumLock, modifiers); + case VK_SCROLL: return window->HandleChar(EKeyScrollLock, modifiers); + case VK_F1: return window->HandleChar(EKeyF1, modifiers); + case VK_F2: return window->HandleChar(EKeyF2, modifiers); + case VK_F3: return window->HandleChar(EKeyF3, modifiers); + case VK_F4: return window->HandleChar(EKeyF4, modifiers); + case VK_F5: return window->HandleChar(EKeyF5, modifiers); + case VK_F6: return window->HandleChar(EKeyF6, modifiers); + case VK_F7: return window->HandleChar(EKeyF7, modifiers); + case VK_F8: return window->HandleChar(EKeyF8, modifiers); + case VK_F9: return window->HandleChar(EKeyF9, modifiers); + case VK_F10: return window->HandleChar(EKeyF10, modifiers); + case VK_F11: return window->HandleChar(EKeyF11, modifiers); + case VK_F12: return window->HandleChar(EKeyF12, modifiers); + case VK_F13: return window->HandleChar(EKeyF13, modifiers); + case VK_F14: return window->HandleChar(EKeyF14, modifiers); + case VK_F15: return window->HandleChar(EKeyF15, modifiers); + case VK_F16: return window->HandleChar(EKeyF16, modifiers); + case VK_F17: return window->HandleChar(EKeyF17, modifiers); + case VK_F18: return window->HandleChar(EKeyF18, modifiers); + case VK_F19: return window->HandleChar(EKeyF19, modifiers); + case VK_F20: return window->HandleChar(EKeyF20, modifiers); + case VK_F21: return window->HandleChar(EKeyF21, modifiers); + case VK_F22: return window->HandleChar(EKeyF22, modifiers); + case VK_F23: return window->HandleChar(EKeyF23, modifiers); + case VK_F24: return window->HandleChar(EKeyF24, modifiers); + default: return 0; + } + } + break; + case WM_CHAR: + case WM_SYSCHAR: + if (window) + { + UINT modifiers = EModifierAutorepeatable; + if (aMessage == WM_SYSCHAR) + { + modifiers |= (EModifierLeftAlt | EModifierAlt | EModifierLeftFunc | EModifierFunc); + } + return window->HandleChar(TCHAR(aWParam), modifiers); + } + break; + case WM_SIZE: + if (window) + { + window->HandleSizeChanged(LOWORD(aLParam), HIWORD(aLParam)); + } + break; + case WM_HSCROLL: + case WM_VSCROLL: + if (window) + { + window->HandleScrollEvent(aMessage, aWParam); + } + break; + case 0x020A: // WM_MOUSEWHEEL + if (window) + { + window->HandleScrollEvent(WM_VSCROLL, (short)HIWORD(aWParam) > 0 ? SB_LINEUP : SB_LINEDOWN); + } + break; + case WM_PAINT: + if (window) + { + window->Draw(); + } + break; + case WM_LBUTTONDOWN: + case WM_LBUTTONDBLCLK: + case WM_MOUSEMOVE: + case WM_LBUTTONUP: + if (window) + { + window->HandleMouseEvent(aMessage, aWParam, aLParam); + } + break; + case WM_INITMENUPOPUP: + if (window) + { + window->HandleMenuPopUp((HMENU)aWParam); + } + break; + case WM_DESTROY: + if (window && window->iObserver) + { + window->iObserver->HandleWindowClosure(*window); + } + break; + default: + return DefWindowProc(aHandle, aMessage, aWParam, aLParam); + } + return 0; + } + +CWindow* CWindow::Instance(HWND aHandle) + { + CWindow* window = sFirst; + bool found(0); + while (window && !found) + { + if (window->iHandle == aHandle) + { + found = 1; + } + else + { + window = window->iNext; + } + } + + if (found) + { + return window; + } + return NULL; + }