Implemented RObjectIx-based memoryaccess APIs.
Upshot is that objinfo now works again on platforms that define FSHELL_NO_DOBJECTIX_SUPPORT.
// 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;
}