plugins/consoles/rcons/server/win32/Window.cpp
changeset 0 7f656887cf89
equal deleted inserted replaced
-1:000000000000 0:7f656887cf89
       
     1 // Window.cpp
       
     2 // 
       
     3 // Copyright (c) 2010 Accenture. All rights reserved.
       
     4 // This component and the accompanying materials are made available
       
     5 // under the terms of the "Eclipse Public License v1.0"
       
     6 // which accompanies this distribution, and is available
       
     7 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 // 
       
     9 // Initial Contributors:
       
    10 // Accenture - Initial contribution
       
    11 //
       
    12 
       
    13 #include "Misc.h"
       
    14 #include "stdafx.h"
       
    15 #include "console_host.h"
       
    16 #include "Window.h"
       
    17 
       
    18 #ifdef _DEBUG
       
    19 #undef THIS_FILE
       
    20 static char THIS_FILE[]=__FILE__;
       
    21 #endif
       
    22 
       
    23 const DWORD KWindowStyle = (WS_OVERLAPPEDWINDOW | WS_HSCROLL | WS_VSCROLL);// & ~WS_THICKFRAME;
       
    24 CWindow* CWindow::sFirst = NULL;
       
    25 CWindow* CWindow::sLast = NULL;
       
    26 MWindowMessageHandler* CWindow::sFirstMessageHandler = NULL;
       
    27 MWindowMessageHandler* CWindow::sLastMessageHandler = NULL;
       
    28 
       
    29 
       
    30 // From e32keys.h
       
    31 enum TKeyCode
       
    32 	{
       
    33 	EKeyNull=0x0000,
       
    34 	EKeyBell=0x0007,
       
    35 	EKeyBackspace=0x0008,
       
    36 	EKeyTab=0x0009,
       
    37 	EKeyLineFeed=0x000a,
       
    38 	EKeyVerticalTab=0x000b,
       
    39 	EKeyFormFeed=0x000c,
       
    40 	EKeyEnter=0x000d,
       
    41 	EKeyEscape=0x001b,
       
    42 	EKeySpace=0x0020,
       
    43 	EKeyDelete=0x007f,
       
    44 	EKeyPrintScreen=0xf800,
       
    45 	EKeyPause,
       
    46 	EKeyHome,
       
    47 	EKeyEnd,
       
    48 	EKeyPageUp,
       
    49 	EKeyPageDown,
       
    50 	EKeyInsert,
       
    51 	EKeyLeftArrow,
       
    52 	EKeyRightArrow,
       
    53 	EKeyUpArrow,
       
    54 	EKeyDownArrow,
       
    55 	EKeyLeftShift,
       
    56 	EKeyRightShift,
       
    57 	EKeyLeftAlt,
       
    58 	EKeyRightAlt,
       
    59 	EKeyLeftCtrl,
       
    60 	EKeyRightCtrl,
       
    61 	EKeyLeftFunc,
       
    62 	EKeyRightFunc,
       
    63 	EKeyCapsLock,
       
    64 	EKeyNumLock,
       
    65 	EKeyScrollLock,
       
    66 	EKeyF1,
       
    67 	EKeyF2,
       
    68 	EKeyF3,
       
    69 	EKeyF4,
       
    70 	EKeyF5,
       
    71 	EKeyF6,
       
    72 	EKeyF7,
       
    73 	EKeyF8,
       
    74 	EKeyF9,
       
    75 	EKeyF10,
       
    76 	EKeyF11,
       
    77 	EKeyF12,
       
    78 	EKeyF13,
       
    79 	EKeyF14,
       
    80 	EKeyF15,
       
    81 	EKeyF16,
       
    82 	EKeyF17,
       
    83 	EKeyF18,
       
    84 	EKeyF19,
       
    85 	EKeyF20,
       
    86 	EKeyF21,
       
    87 	EKeyF22,
       
    88 	EKeyF23,
       
    89 	EKeyF24,
       
    90     EKeyOff,
       
    91     EKeyIncContrast,
       
    92     EKeyDecContrast,
       
    93     EKeyBacklightOn,
       
    94     EKeyBacklightOff,
       
    95     EKeyBacklightToggle,
       
    96     EKeySliderDown,
       
    97     EKeySliderUp,
       
    98     EKeyMenu,
       
    99     EKeyDictaphonePlay,
       
   100     EKeyDictaphoneStop,
       
   101     EKeyDictaphoneRecord,
       
   102     EKeyHelp,
       
   103     EKeyDial,
       
   104 	EKeyScreenDimension0,
       
   105 	EKeyScreenDimension1,
       
   106 	EKeyScreenDimension2,
       
   107 	EKeyScreenDimension3,
       
   108 	EKeyIncVolume,
       
   109 	EKeyDecVolume,
       
   110 	EKeyDevice0,
       
   111 	EKeyDevice1,
       
   112 	EKeyDevice2,
       
   113 	EKeyDevice3,
       
   114 	EKeyDevice4,
       
   115 	EKeyDevice5,
       
   116 	EKeyDevice6,
       
   117 	EKeyDevice7,
       
   118 	EKeyDevice8,
       
   119 	EKeyDevice9,
       
   120 	EKeyDeviceA,
       
   121 	EKeyDeviceB,
       
   122 	EKeyDeviceC,
       
   123 	EKeyDeviceD,
       
   124 	EKeyDeviceE,
       
   125 	EKeyDeviceF,
       
   126 	EKeyApplication0,
       
   127 	EKeyApplication1,
       
   128 	EKeyApplication2,
       
   129 	EKeyApplication3,
       
   130 	EKeyApplication4,
       
   131 	EKeyApplication5,
       
   132 	EKeyApplication6,
       
   133 	EKeyApplication7,
       
   134 	EKeyApplication8,
       
   135 	EKeyApplication9,
       
   136 	EKeyApplicationA,
       
   137 	EKeyApplicationB,
       
   138 	EKeyApplicationC,
       
   139 	EKeyApplicationD,
       
   140 	EKeyApplicationE,
       
   141 	EKeyApplicationF,
       
   142 	EKeyYes,
       
   143 	EKeyNo,
       
   144 	EKeyIncBrightness,
       
   145 	EKeyDecBrightness
       
   146 	};
       
   147 
       
   148 enum TEventModifier
       
   149 	{
       
   150 	EModifierAutorepeatable=0x00000001, /**< Key event can auto-repeat.*/
       
   151 	EModifierKeypad=0x00000002,         /**< The key that generated the event was on the numeric keypad, on the emulator.*/
       
   152 	EModifierLeftAlt=0x00000004,        /**< Left Alt key.*/
       
   153 	EModifierRightAlt=0x00000008,       /**< Right Alt key.*/
       
   154 	EModifierAlt=0x00000010,            /**< Single Alt key.*/
       
   155 	EModifierLeftCtrl=0x00000020,       /**< Left Control (Ctrl) key.*/
       
   156 	EModifierRightCtrl=0x00000040,      /**< Right Control (Ctrl) key.*/
       
   157 	EModifierCtrl=0x00000080,           /**< Single Control (Ctrl) key.*/
       
   158 	EModifierLeftShift=0x00000100,      /**< Left Shift key.*/
       
   159 	EModifierRightShift=0x00000200,     /**< Right Shift key.*/
       
   160 	EModifierShift=0x00000400,          /**< Single Shift key.*/
       
   161 	EModifierLeftFunc=0x00000800,       /**< Left Fn key.*/
       
   162 	EModifierRightFunc=0x00001000,      /**< Right Fn key.*/
       
   163 	EModifierFunc=0x00002000,           /**< Single Fn key.*/
       
   164 	EModifierCapsLock=0x00004000,       /**< Caps lock key.*/
       
   165 	EModifierNumLock=0x00008000,        /**< Num lock key.*/
       
   166 	EModifierScrollLock=0x00010000,     /**< Scroll lock key.*/
       
   167 	EModifierKeyUp=0x00020000,          /**< Key up event.*/
       
   168 	EModifierSpecial=0x00040000,        /**< The keycode is a non-standard keyboard character that has been generated in a special keyboard mode, for example accented vowels.*/
       
   169 	EModifierDoubleClick=0x00080000,    /**< Double click.*/
       
   170 	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.*/
       
   171 	EModifierKeyboardExtend=0x00200000,	/**< The "Keyboard extend" generated modifier. */
       
   172 	EModifierCancelRotation=0x00000000, /**< No Keyboard rotation is in effect. */
       
   173 	EModifierRotateBy90=0x00400000,		/**< Keyboard rotation through 90 degrees clockwise is in effect. */
       
   174 	EModifierRotateBy180=0x00800000,	/**< Keyboard rotation through 180 degrees clockwise is in effect. */
       
   175 	EModifierRotateBy270=0x01000000,	/**< Keyboard rotation through 270 degrees clockwise is in effect. */
       
   176 	EModifierPointer3DButton1=0x02000000,/**< 3D pointer device specific modifier (button 1). */
       
   177 	EModifierPointer3DButton2=0x04000000,/**< 3D pointer device specific modifier (button 2). */
       
   178 	EModifierPointer3DButton3=0x08000000,/**< 3D pointer device specific modifier (button 3). */
       
   179 	EAllModifiers=0x0fffffff            /**< A combination of all event modifiers.*/
       
   180 	};
       
   181 
       
   182 
       
   183 MWindowMessageHandler::MWindowMessageHandler() : iNext(NULL), iPrevious(NULL)
       
   184 	{
       
   185 	}
       
   186 
       
   187 CWindow::~CWindow()
       
   188 	{
       
   189 	if (sLast == this)
       
   190 		{
       
   191 		ASSERT(iNext == NULL);
       
   192 		sLast = iPrevious;
       
   193 		}
       
   194 	if (sFirst == this)
       
   195 		{
       
   196 		sFirst = iNext;
       
   197 		}
       
   198 	if (iPrevious)
       
   199 		{
       
   200 		iPrevious->iNext = iNext;
       
   201 		}
       
   202 	if (iNext)
       
   203 		{
       
   204 		iNext->iPrevious = iPrevious;
       
   205 		}
       
   206 	}
       
   207 
       
   208 void CWindow::AddMessageHandler(MWindowMessageHandler& aHandler)
       
   209 	{
       
   210 	if (sFirstMessageHandler == NULL)
       
   211 		{
       
   212 		ASSERT(sLastMessageHandler == NULL);
       
   213 		sFirstMessageHandler = &aHandler;
       
   214 		sLastMessageHandler = &aHandler;
       
   215 		}
       
   216 	else
       
   217 		{
       
   218 		sLastMessageHandler->iNext = &aHandler;
       
   219 		aHandler.iPrevious = sLastMessageHandler;
       
   220 		sLastMessageHandler = &aHandler;
       
   221 		}
       
   222 	}
       
   223 
       
   224 void CWindow::RemoveMessageHandler(MWindowMessageHandler& aHandler)
       
   225 	{
       
   226 	if (sLastMessageHandler == &aHandler)
       
   227 		{
       
   228 		ASSERT(aHandler.iNext == NULL);
       
   229 		sLastMessageHandler = aHandler.iPrevious;
       
   230 		}
       
   231 	if (sFirstMessageHandler == &aHandler)
       
   232 		{
       
   233 		sFirstMessageHandler = aHandler.iNext;
       
   234 		}
       
   235 	if (aHandler.iPrevious)
       
   236 		{
       
   237 		aHandler.iPrevious->iNext = aHandler.iNext;
       
   238 		}
       
   239 	if (aHandler.iNext)
       
   240 		{
       
   241 		aHandler.iNext->iPrevious = aHandler.iPrevious;
       
   242 		}
       
   243 	}
       
   244 
       
   245 HWND CWindow::Handle() const
       
   246 	{
       
   247 	return iHandle;
       
   248 	}
       
   249 
       
   250 void CWindow::SetTitle(LPCTSTR aTitle)
       
   251 	{
       
   252 	SetWindowText(iHandle, aTitle);
       
   253 	}
       
   254 
       
   255 void CWindow::GetTitle(LPTSTR aTitle, int aMaxLength) const
       
   256 	{
       
   257 	GetWindowText(iHandle, aTitle, aMaxLength);
       
   258 	}
       
   259 
       
   260 CWindow::CWindow() : iNext(NULL), iPrevious(NULL), iObserver(NULL)
       
   261 	{
       
   262 	if (sFirst == NULL)
       
   263 		{
       
   264 		ASSERT(sLast == NULL);
       
   265 		sFirst = this;
       
   266 		sLast = this;
       
   267 		}
       
   268 	else
       
   269 		{
       
   270 		sLast->iNext = this;
       
   271 		iPrevious = sLast;
       
   272 		sLast = this;
       
   273 		}
       
   274 	}
       
   275 
       
   276 void CWindow::Construct(HINSTANCE aAppHandle, LPCTSTR aWindowClass, LPCTSTR aTitle, int aPoxX, int aPosY, int aWidth, int aHeight, MWindowObserver* aObserver)
       
   277 	{
       
   278 	iAppHandle = aAppHandle;
       
   279 	iObserver = aObserver;
       
   280 
       
   281 	RECT windowRect = {0, 0, aWidth, aHeight};
       
   282 	AdjustWindowRect(&windowRect, KWindowStyle, TRUE);
       
   283 	windowRect.right += GetSystemMetrics(SM_CYVSCROLL);
       
   284 	iHandle = CreateWindow(aWindowClass, aTitle, KWindowStyle, aPoxX, aPosY, windowRect.right-windowRect.left, windowRect.bottom-windowRect.top, NULL, NULL, aAppHandle, NULL);
       
   285 	if (iHandle == 0)
       
   286 		{
       
   287 		throw KExceptionWindowConstructFailed;
       
   288 		}
       
   289 	ShowWindow(iHandle, SW_SHOWNORMAL);
       
   290 	if (UpdateWindow(iHandle) == 0)
       
   291 		{
       
   292 		throw KExceptionWindowConstructFailed;
       
   293 		}
       
   294 	}
       
   295 
       
   296 void CWindow::Redraw()
       
   297 	{
       
   298 	InvalidateRect(iHandle, NULL, TRUE);
       
   299 	}
       
   300 
       
   301 void CWindow::Draw() const
       
   302 	{
       
   303 	}
       
   304 
       
   305 LRESULT CWindow::HandleChar(TCHAR, UINT)
       
   306 	{
       
   307 	return 0;
       
   308 	}
       
   309 
       
   310 LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
       
   311 	{
       
   312 	switch (message)
       
   313 		{
       
   314 		case WM_INITDIALOG:
       
   315 				return TRUE;
       
   316 		case WM_COMMAND:
       
   317 			if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) 
       
   318 				{
       
   319 				EndDialog(hDlg, LOWORD(wParam));
       
   320 				return TRUE;
       
   321 				}
       
   322 			break;
       
   323 		}
       
   324     return FALSE;
       
   325 	}
       
   326 
       
   327 LRESULT CWindow::HandleCommand(UINT aMessage, WPARAM aWParam, LPARAM aLParam)
       
   328 	{
       
   329 	int wmId = LOWORD(aWParam); 
       
   330 	int wmEvent = HIWORD(aWParam); 
       
   331 	switch (wmId)
       
   332 		{
       
   333 		case ID_ABOUT:
       
   334 			DialogBox(iAppHandle, (LPCTSTR)IDD_ABOUTBOX, iHandle, (DLGPROC)About);
       
   335 			break;
       
   336 		case IDM_EXIT:
       
   337 			DestroyWindow(iHandle);
       
   338 			break;
       
   339 		default:
       
   340 			if (iObserver)
       
   341 				{
       
   342 				return iObserver->HandleWindowCommand(aMessage, aWParam, aLParam);
       
   343 				}
       
   344 			return DefWindowProc(iHandle, aMessage, aWParam, aLParam);
       
   345 		}
       
   346 	return 0;
       
   347 	}
       
   348 
       
   349 LRESULT CWindow::HandleFocusChange(bool aFocused)
       
   350 	{
       
   351 	return 0;
       
   352 	}
       
   353 
       
   354 void CWindow::HandleScrollEvent(UINT aMessage, WPARAM aWParam)
       
   355 	{
       
   356 	}
       
   357 
       
   358 void CWindow::HandleSizeChanged(int aWidth, int aHeight)
       
   359 	{
       
   360 	}
       
   361 
       
   362 void CWindow::HandleMouseEvent(UINT aMessage, WPARAM aWParam, LPARAM aLParam)
       
   363 	{
       
   364 	}
       
   365 
       
   366 void CWindow::HandleMenuPopUp(HMENU aMenu)
       
   367 	{
       
   368 	}
       
   369 
       
   370 LRESULT CALLBACK CWindow::HandleMessage(HWND aHandle, UINT aMessage, WPARAM aWParam, LPARAM aLParam)
       
   371 	{
       
   372 	CWindow* window = Instance(aHandle);
       
   373 
       
   374 	if (window)
       
   375 		{
       
   376 		MWindowMessageHandler* messageHandler = sFirstMessageHandler;
       
   377 		while (messageHandler)
       
   378 			{
       
   379 			if (messageHandler->HandleWindowMessage(aMessage, aWParam, aLParam) == 0)
       
   380 				{
       
   381 				return 0;
       
   382 				}
       
   383 			messageHandler = messageHandler->iNext;
       
   384 			}
       
   385 		}
       
   386 
       
   387 	switch (aMessage) 
       
   388 		{
       
   389 		case WM_SETFOCUS:
       
   390 			if (window)
       
   391 				{
       
   392 				window->HandleFocusChange(TRUE);
       
   393 				}
       
   394 			break;
       
   395 		case WM_KILLFOCUS:
       
   396 			if (window)
       
   397 				{
       
   398 				window->HandleFocusChange(FALSE);
       
   399 				}
       
   400 			break;
       
   401 		case WM_COMMAND:
       
   402 			if (window)
       
   403 				{
       
   404 				return window->HandleCommand(aMessage, aWParam, aLParam);
       
   405 				}
       
   406 			break;
       
   407 		case WM_KEYDOWN:
       
   408 		case WM_SYSKEYDOWN:
       
   409 			if (window)
       
   410 				{
       
   411 				UINT modifiers = EModifierAutorepeatable;
       
   412 				if (aMessage == WM_SYSKEYDOWN)
       
   413 					{
       
   414 					modifiers |= (EModifierLeftAlt | EModifierAlt | EModifierLeftFunc | EModifierFunc);
       
   415 					}
       
   416 				switch (aWParam) 
       
   417 					{ 
       
   418 					case VK_LEFT:		return window->HandleChar(EKeyLeftArrow, modifiers);
       
   419 					case VK_UP:			return window->HandleChar(EKeyUpArrow, modifiers);
       
   420 					case VK_RIGHT:		return window->HandleChar(EKeyRightArrow, modifiers);
       
   421 					case VK_DOWN:		return window->HandleChar(EKeyDownArrow, modifiers);
       
   422 					case VK_HOME:		return window->HandleChar(EKeyHome, modifiers);
       
   423 					case VK_END:		return window->HandleChar(EKeyEnd, modifiers);
       
   424 					case VK_PRIOR:		return window->HandleChar(EKeyPageUp, modifiers);
       
   425 					case VK_NEXT:		return window->HandleChar(EKeyPageDown, modifiers);
       
   426 					case VK_PAUSE:		return window->HandleChar(EKeyPause, modifiers);
       
   427 					case VK_PRINT:		return window->HandleChar(EKeyPrintScreen, modifiers);
       
   428 					case VK_INSERT:		return window->HandleChar(EKeyInsert, modifiers);
       
   429 					case VK_DELETE:		return window->HandleChar(EKeyDelete, modifiers);
       
   430 					case VK_CAPITAL:	return window->HandleChar(EKeyCapsLock, modifiers);
       
   431 					case VK_NUMLOCK:	return window->HandleChar(EKeyNumLock, modifiers);
       
   432 					case VK_SCROLL:		return window->HandleChar(EKeyScrollLock, modifiers);
       
   433 					case VK_F1:			return window->HandleChar(EKeyF1, modifiers);
       
   434 					case VK_F2:			return window->HandleChar(EKeyF2, modifiers);
       
   435 					case VK_F3:			return window->HandleChar(EKeyF3, modifiers);
       
   436 					case VK_F4:			return window->HandleChar(EKeyF4, modifiers);
       
   437 					case VK_F5:			return window->HandleChar(EKeyF5, modifiers);
       
   438 					case VK_F6:			return window->HandleChar(EKeyF6, modifiers);
       
   439 					case VK_F7:			return window->HandleChar(EKeyF7, modifiers);
       
   440 					case VK_F8:			return window->HandleChar(EKeyF8, modifiers);
       
   441 					case VK_F9:			return window->HandleChar(EKeyF9, modifiers);
       
   442 					case VK_F10:		return window->HandleChar(EKeyF10, modifiers);
       
   443 					case VK_F11:		return window->HandleChar(EKeyF11, modifiers);
       
   444 					case VK_F12:		return window->HandleChar(EKeyF12, modifiers);
       
   445 					case VK_F13:		return window->HandleChar(EKeyF13, modifiers);
       
   446 					case VK_F14:		return window->HandleChar(EKeyF14, modifiers);
       
   447 					case VK_F15:		return window->HandleChar(EKeyF15, modifiers);
       
   448 					case VK_F16:		return window->HandleChar(EKeyF16, modifiers);
       
   449 					case VK_F17:		return window->HandleChar(EKeyF17, modifiers);
       
   450 					case VK_F18:		return window->HandleChar(EKeyF18, modifiers);
       
   451 					case VK_F19:		return window->HandleChar(EKeyF19, modifiers);
       
   452 					case VK_F20:		return window->HandleChar(EKeyF20, modifiers);
       
   453 					case VK_F21:		return window->HandleChar(EKeyF21, modifiers);
       
   454 					case VK_F22:		return window->HandleChar(EKeyF22, modifiers);
       
   455 					case VK_F23:		return window->HandleChar(EKeyF23, modifiers);
       
   456 					case VK_F24:		return window->HandleChar(EKeyF24, modifiers);
       
   457 					default:			return 0;
       
   458 					}
       
   459 				}
       
   460 			break;
       
   461 		case WM_CHAR:
       
   462 		case WM_SYSCHAR:
       
   463 			if (window)
       
   464 				{
       
   465 				UINT modifiers = EModifierAutorepeatable;
       
   466 				if (aMessage == WM_SYSCHAR)
       
   467 					{
       
   468 					modifiers |= (EModifierLeftAlt | EModifierAlt | EModifierLeftFunc | EModifierFunc);
       
   469 					}
       
   470 				return window->HandleChar(TCHAR(aWParam), modifiers);
       
   471 				}
       
   472 			break;
       
   473 		case WM_SIZE:
       
   474 			if (window)
       
   475 				{
       
   476 				window->HandleSizeChanged(LOWORD(aLParam), HIWORD(aLParam));
       
   477 				}
       
   478 			break;
       
   479 		case WM_HSCROLL:
       
   480 		case WM_VSCROLL:
       
   481 			if (window)
       
   482 				{
       
   483 				window->HandleScrollEvent(aMessage, aWParam);
       
   484 				}
       
   485 			break;
       
   486 		case 0x020A: // WM_MOUSEWHEEL
       
   487 			if (window)
       
   488 				{
       
   489 				window->HandleScrollEvent(WM_VSCROLL, (short)HIWORD(aWParam) > 0 ? SB_LINEUP : SB_LINEDOWN);
       
   490 				}
       
   491 			break;
       
   492 		case WM_PAINT:
       
   493 			if (window)
       
   494 				{
       
   495 				window->Draw();
       
   496 				}
       
   497 			break;
       
   498 		case WM_LBUTTONDOWN:
       
   499 		case WM_LBUTTONDBLCLK:
       
   500 		case WM_MOUSEMOVE:
       
   501 		case WM_LBUTTONUP:
       
   502 			if (window)
       
   503 				{
       
   504 				window->HandleMouseEvent(aMessage, aWParam, aLParam);
       
   505 				}
       
   506 			break;
       
   507 		case WM_INITMENUPOPUP:
       
   508 			if (window)
       
   509 				{
       
   510 				window->HandleMenuPopUp((HMENU)aWParam);
       
   511 				}
       
   512 			break;
       
   513 		case WM_DESTROY:
       
   514 			if (window && window->iObserver)
       
   515 				{
       
   516 				window->iObserver->HandleWindowClosure(*window);
       
   517 				}
       
   518 			break;
       
   519 		default:
       
   520 			return DefWindowProc(aHandle, aMessage, aWParam, aLParam);
       
   521 		}
       
   522 	return 0;
       
   523 	}
       
   524 
       
   525 CWindow* CWindow::Instance(HWND aHandle)
       
   526 	{
       
   527 	CWindow* window = sFirst;
       
   528 	bool found(0);
       
   529 	while (window && !found)
       
   530 		{
       
   531 		if (window->iHandle == aHandle)
       
   532 			{
       
   533 			found = 1;
       
   534 			}
       
   535 		else
       
   536 			{
       
   537 			window = window->iNext;
       
   538 			}
       
   539 		}
       
   540 
       
   541 	if (found)
       
   542 		{
       
   543 		return window;
       
   544 		}
       
   545 	return NULL;
       
   546 	}