--- /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;
+ }