plugins/consoles/rcons/server/win32/Window.cpp
changeset 0 7f656887cf89
--- /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;
+	}