示例#1
0
/*
 * DialogProc for OpenVPN username/password/challenge auth dialog windows
 */
INT_PTR CALLBACK
UserAuthDialogFunc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
    auth_param_t *param;
    WCHAR username[USER_PASS_LEN];
    WCHAR password[USER_PASS_LEN];

    switch (msg)
    {
    case WM_INITDIALOG:
        /* Set connection for this dialog and show it */
        param = (auth_param_t *) lParam;
        SetProp(hwndDlg, cfgProp, (HANDLE) param);
        if (param->challenge_str)
        {
            int wchars_num = MultiByteToWideChar(CP_UTF8, 0, param->challenge_str, -1, NULL, 0);
            LPWSTR wstr = (LPWSTR)malloc(sizeof(WCHAR) * wchars_num);
            HWND wnd_challenge = GetDlgItem(hwndDlg, ID_EDT_AUTH_CHALLENGE);

            MultiByteToWideChar(CP_UTF8, 0, param->challenge_str, -1, wstr, wchars_num);
            SetDlgItemTextW(hwndDlg, ID_TXT_AUTH_CHALLENGE, wstr);
            free(wstr);
            /* Set/Remove style ES_PASSWORD by SetWindowLong(GWL_STYLE) does nothing,
               send EM_SETPASSWORDCHAR just works. */
            if(param->challenge_echo)
                SendMessage(wnd_challenge, EM_SETPASSWORDCHAR, 0, 0);
        }
        if (RecallUsername(param->c->config_name, username))
            SetDlgItemTextW(hwndDlg, ID_EDT_AUTH_USER, username);
        if (RecallAuthPass(param->c->config_name, password))
        {
            SetDlgItemTextW(hwndDlg, ID_EDT_AUTH_PASS, password);
            SecureZeroMemory(password, sizeof(password));
        }
        if (param->c->flags & FLAG_SAVE_AUTH_PASS)
            Button_SetCheck(GetDlgItem (hwndDlg, ID_CHK_SAVE_PASS), BST_CHECKED);

        if (param->c->state == resuming)
            ForceForegroundWindow(hwndDlg);
        else
            SetForegroundWindow(hwndDlg);
        break;

    case WM_COMMAND:
        param = (auth_param_t *) GetProp(hwndDlg, cfgProp);
        switch (LOWORD(wParam))
        {
        case ID_EDT_AUTH_USER:
            if (HIWORD(wParam) == EN_UPDATE)
            {
                int len = Edit_GetTextLength((HWND) lParam);
                EnableWindow(GetDlgItem(hwndDlg, IDOK), (len ? TRUE : FALSE));
            }
            break;

        case ID_CHK_SAVE_PASS:
            param->c->flags ^= FLAG_SAVE_AUTH_PASS;
            if (param->c->flags & FLAG_SAVE_AUTH_PASS)
                Button_SetCheck(GetDlgItem (hwndDlg, ID_CHK_SAVE_PASS), BST_CHECKED);
            else
            {
                DeleteSavedAuthPass(param->c->config_name);
                Button_SetCheck(GetDlgItem (hwndDlg, ID_CHK_SAVE_PASS), BST_UNCHECKED);
            }
            break;

        case IDOK:
            if (GetDlgItemTextW(hwndDlg, ID_EDT_AUTH_USER, username, _countof(username)))
            {
                SaveUsername(param->c->config_name, username);
            }
            if ( param->c->flags & FLAG_SAVE_AUTH_PASS &&
                 GetDlgItemTextW(hwndDlg, ID_EDT_AUTH_PASS, password, _countof(password)) &&
                 wcslen(password) )
            {
                SaveAuthPass(param->c->config_name, password);
                SecureZeroMemory(password, sizeof(password));
            }
            ManagementCommandFromInput(param->c, "username \"Auth\" \"%s\"", hwndDlg, ID_EDT_AUTH_USER);
            if (param->challenge_str)
                ManagementCommandFromInputBase64(param->c, "password \"Auth\" \"SCRV1:%s:%s\"", hwndDlg, ID_EDT_AUTH_PASS, ID_EDT_AUTH_CHALLENGE);
            else
                ManagementCommandFromInput(param->c, "password \"Auth\" \"%s\"", hwndDlg, ID_EDT_AUTH_PASS);
            EndDialog(hwndDlg, LOWORD(wParam));
            return TRUE;

        case IDCANCEL:
            EndDialog(hwndDlg, LOWORD(wParam));
            StopOpenVPN(param->c);
            return TRUE;
        }
        break;

    case WM_CLOSE:
        EndDialog(hwndDlg, LOWORD(wParam));
        return TRUE;

    case WM_NCDESTROY:
        param = (auth_param_t *) GetProp(hwndDlg, cfgProp);
        if (param->challenge_str) free(param->challenge_str);
        free(param);
        RemoveProp(hwndDlg, cfgProp);
        break;
    }

    return FALSE;
}
示例#2
0
/*
 * Function CHyperLink::_HyperlinkProc
 *
 * Note: Processed messages are not passed back to the static control
 *       procedure. It does work fine but be aware that it could cause
 *       some problems if the static control is already subclassed.
 *       Consider the example where the static control would be already
 *       subclassed with the ToolTip control that needs to process mouse
 *       messages. In that situation, the ToolTip control would not work
 *       as expected.
 */
LRESULT CALLBACK CHyperLink::_HyperlinkProc(HWND hwnd, UINT message,
		                                   WPARAM wParam, LPARAM lParam)
{
	CHyperLink *pHyperLink = (CHyperLink *)GetProp(hwnd, PROP_OBJECT_PTR);

	switch (message)
	{
	case WM_MOUSEMOVE:
		{
			if ( pHyperLink->m_bOverControl )
			{
				// This is the most common case for static branch prediction
				// optimization
				RECT rect;
				GetClientRect(hwnd,&rect);

				POINT pt = { LOWORD(lParam), HIWORD(lParam) };

				if (!PTINRECT(&rect,pt))
				{
					ReleaseCapture();
				}
			}
			else
			{
				pHyperLink->m_bOverControl = TRUE;
				SendMessage(hwnd, WM_SETFONT,
					        (WPARAM)CHyperLink::g_UnderlineFont, FALSE);
				InvalidateRect(hwnd, NULL, FALSE);
				pHyperLink->OnSelect();
				SetCapture(hwnd);
			}
			return 0;
		}
	case WM_SETCURSOR:
		{
			SetCursor(CHyperLink::g_hLinkCursor);
			return TRUE;
		}
	case WM_CAPTURECHANGED:
		{
			pHyperLink->m_bOverControl = FALSE;
			pHyperLink->OnDeselect();
			SendMessage(hwnd, WM_SETFONT,
				        (WPARAM)pHyperLink->m_StdFont, FALSE);
			InvalidateRect(hwnd, NULL, FALSE);
			return 0;
		}
	case WM_KEYUP:
		{
			if( wParam != VK_SPACE )
			{
				break;
			}
		}
						// Fall through
	case WM_LBUTTONUP:
		{
			pHyperLink->Navigate();
			return 0;
		}
	case WM_SETFOCUS:	// Fall through
	case WM_KILLFOCUS:
		{
			if( message == WM_SETFOCUS )
			{
				pHyperLink->OnSelect();
			}
			else		// WM_KILLFOCUS
			{
				pHyperLink->OnDeselect();
			}
			CHyperLink::DrawFocusRect(hwnd);
			return 0;
		}
	case WM_DESTROY:
		{
			SetWindowLongPtr(hwnd, GWLP_WNDPROC,
				          (LONG) pHyperLink->m_pfnOrigCtlProc);

			SendMessage(hwnd, WM_SETFONT, (WPARAM) pHyperLink->m_StdFont, 0);

			if( --CHyperLink::g_counter <= 0 )
			{
				destroyGlobalResources();
			}

			RemoveProp(hwnd, PROP_OBJECT_PTR);
			break;
		}
	}

	return CallWindowProc(pHyperLink->m_pfnOrigCtlProc, hwnd, message,
		                  wParam, lParam);
}
示例#3
0
文件: VNCHooks.cpp 项目: tmbx/vnc
inline BOOL HookHandle(UINT MessageId, HWND hWnd, WPARAM wParam, LPARAM lParam)
{
	////////////////////////////////////////////////////////////////
	// *** HANDLE DEFERRED UPDATES ***

	// Is this a deferred-update message?
	if (MessageId == VNC_DEFERRED_UPDATE)
	{

		// NOTE : NEVER use the SendDeferred- routines to send updates
		//		from here, or you'll get an infinite loop....!

		// NB : The format of DEFERRED_UPDATE matches that of UpdateRectMessage,
		//		so just send the exact same message data to WinRFB:

		PostMessage(
			hVeneto,
			UpdateRectMessage,
			wParam,
			lParam
			);

		return FALSE;
	}

	// *** Could use WM_COPYDATA to send data to WinVNC

/*
	if (GetClassLong(hWnd, GCW_ATOM) == 32768)
	{
		_RPT4(_CRT_WARN, "DBG : popup menu message (hwnd=%d, msg=%d, l=%d, w=%d)\n",
		hWnd, MessageId, lParam, wParam);
	}
*/

	////////////////////////////////////////////////////////////////
	// *** UPDATE-TRIGGERING MESSAGES ***

	// Do something dependent upon message type
	switch (MessageId)
	{
		
		////////////////////////////////////////////////////////////////
		// Messages indicating only a border repaint.
	case WM_NCPAINT:
	case WM_NCACTIVATE:
		SendDeferredBorderRect(hWnd);
		break;

		////////////////////////////////////////////////////////////////
		// Messages indicating a client area repaint
	case WM_CHAR:
	case WM_KEYUP:							// Handle key-presses
		if (prf_use_KeyPress)
			SendDeferredWindowRect(hWnd);
		break;

	case WM_LBUTTONUP:						// Handle LMB clicks
		if (prf_use_LButtonUp)
			SendDeferredWindowRect(hWnd);
		break;

	case WM_MBUTTONUP:						// Handle MMB clicks
		if (prf_use_MButtonUp)
			SendDeferredWindowRect(hWnd);
		break;

	case WM_RBUTTONUP:						// Handle RMB clicks
		if (prf_use_RButtonUp)
			SendDeferredWindowRect(hWnd);
		break;

	case WM_TIMER:
		if (prf_use_Timer)
			SendDeferredWindowRect(hWnd);
		break;

	case WM_HSCROLL:
	case WM_VSCROLL:
		if (((int) LOWORD(wParam) == SB_THUMBTRACK) || ((int) LOWORD(wParam) == SB_ENDSCROLL))
			SendDeferredWindowRect(hWnd);
		break;

	case 485:  // HACK to handle popup menus
		{
			// Get the old popup menu selection value
			HANDLE prop = GetProp(hWnd, (LPCTSTR) MAKELONG(VNC_POPUPSELN_ATOM, 0));
			if (prop != (HANDLE) wParam)
			{
				// It did, so update the menu & the selection value
				SendDeferredWindowRect(hWnd);
				SetProp(hWnd,
					(LPCTSTR) MAKELONG(VNC_POPUPSELN_ATOM, 0),
					(HANDLE) wParam);
			}
		}
		break;

		////////////////////////////////////////////////////////////////
		// Messages indicating a full window update
	case WM_SYSCOLORCHANGE:
	case WM_PALETTECHANGED:
	case WM_SETTEXT:
	case WM_ENABLE:
	case BM_SETCHECK:
	case BM_SETSTATE:
	case EM_SETSEL:
	//case WM_MENUSELECT:
		SendDeferredWindowRect(hWnd);
		break;

		////////////////////////////////////////////////////////////////
		// Messages indicating that an area of the window needs updating
		// Uses GetUpdateRect to find out which
	case WM_PAINT:
		if (prf_use_GetUpdateRect)
		{
			HRGN region;
			region = CreateRectRgn(0, 0, 0, 0);

			// Get the affected region
			if (GetUpdateRgn(hWnd, region, FALSE) != ERROR)
			{
				int buffsize;
				UINT x;
				RGNDATA *buff;
				POINT TopLeft;

				// Get the top-left point of the client area
				TopLeft.x = 0;
				TopLeft.y = 0;
				if (!ClientToScreen(hWnd, &TopLeft))
					break;

				// Get the size of buffer required
				buffsize = GetRegionData(region, 0, 0);
				if (buffsize != 0)
				{
					buff = (RGNDATA *) new BYTE [buffsize];
					if (buff == NULL)
						break;

					// Now get the region data
					if(GetRegionData(region, buffsize, buff))
					{
						for (x=0; x<(buff->rdh.nCount); x++)
						{
							// Obtain the rectangles from the list
							RECT *urect = (RECT *) (((BYTE *) buff) + sizeof(RGNDATAHEADER) + (x * sizeof(RECT)));
							SendDeferredUpdateRect(
								hWnd,
								(SHORT) (TopLeft.x + urect->left),
								(SHORT) (TopLeft.y + urect->top),
								(SHORT) (TopLeft.x + urect->right),
								(SHORT) (TopLeft.y + urect->bottom)
								);
						}
					}

					delete [] buff;
				}
			}

			// Now free the region
			if (region != NULL)
				DeleteObject(region);
		}
		else
			SendDeferredWindowRect(hWnd);
		break;

		////////////////////////////////////////////////////////////////
		// Messages indicating full repaint of this and a different window
		// Send the new position of the window
	case WM_WINDOWPOSCHANGING:
		if (IsWindowVisible(hWnd))
			SendWindowRect(hWnd);
		break;

	case WM_WINDOWPOSCHANGED:
		if (IsWindowVisible(hWnd))
			SendDeferredWindowRect(hWnd);
		break;

		////////////////////////////////////////////////////////////////
		// WinRFB also wants to know about mouse movement
	case WM_NCMOUSEMOVE:
	case WM_MOUSEMOVE:
		// Inform WinRFB that the mouse has moved and pass it the current cursor handle
		PostMessage(
			hVeneto,
			MouseMoveMessage,
			(ULONG) GetCursor(),
			0
		);
		break;

		////////////////////////////////////////////////////////////////
		// VNCHOOKS PROPERTIES HANDLING WINDOWS
	case WM_DESTROY:
		RemoveProp(hWnd, (LPCTSTR) MAKEWORD(VNC_WINDOWPOS_ATOM, 0));
		RemoveProp(hWnd, (LPCTSTR) MAKEWORD(VNC_POPUPSELN_ATOM, 0));
		break;

	}

    return TRUE;
}
示例#4
0
static LRESULT CALLBACK DialogBoxSubclassProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
	int i;

	EnterCriticalSection(&csDlgBoxSubclass);
	for (i = 0; i<dlgBoxSubclassCount; i++)
		if (dlgBoxSubclass[i].hwndDlg == hwndDlg)
			break;
	if (i == dlgBoxSubclassCount) {
		LeaveCriticalSection(&csDlgBoxSubclass);
		return 0;
	}
	WNDPROC pfnWndProc = dlgBoxSubclass[i].pfnOldWndProc;
	DWORD flags = dlgBoxSubclass[i].flags;
	if (msg == WM_NCDESTROY) {
		struct DlgBoxSubclassData *buf;
		MoveMemory(dlgBoxSubclass + i, dlgBoxSubclass + i + 1, sizeof(struct DlgBoxSubclassData)*(dlgBoxSubclassCount - i - 1));
		dlgBoxSubclassCount--;
		buf = (struct DlgBoxSubclassData*)mir_realloc(dlgBoxSubclass, sizeof(struct DlgBoxSubclassData)*dlgBoxSubclassCount);
		if (buf != NULL)
			dlgBoxSubclass = buf;
		else if (!dlgBoxSubclassCount)
			dlgBoxSubclass = NULL;
	}
	LeaveCriticalSection(&csDlgBoxSubclass);

	switch (msg) {
	case WM_INITMENUPOPUP:
		if (flags&DBSDF_MINIMIZABLE || flags&DBSDF_MAXIMIZABLE) {
			HMENU hMenu = GetSystemMenu(hwndDlg, FALSE);
			if ((HMENU)wParam != hMenu)
				break;
			int isMin = IsIconic(hwndDlg);
			int isMax = IsZoomed(hwndDlg);
			EnableMenuItem(hMenu, SC_RESTORE, MF_BYCOMMAND | (isMin || isMax) ? MF_ENABLED : MF_GRAYED);
			EnableMenuItem(hMenu, SC_MINIMIZE, MF_BYCOMMAND | (flags&DBSDF_MINIMIZABLE && !isMin) ? MF_ENABLED : MF_GRAYED);
			EnableMenuItem(hMenu, SC_MAXIMIZE, MF_BYCOMMAND | (flags&DBSDF_MAXIMIZABLE && !isMax) ? MF_ENABLED : MF_GRAYED);
			EnableMenuItem(hMenu, SC_SIZE, MF_BYCOMMAND | (GetWindowLongPtr(hwndDlg, GWL_STYLE)&WS_THICKFRAME && !isMin && !isMax) ? MF_ENABLED : MF_GRAYED);
		}
		break;
	case WM_MOUSEMOVE: // TrackMouseEvent() would disturb too much
		if (!settingAutoTipDelay)
			break;
		if (cursorPos == lParam)
			break;
		cursorPos = lParam;
	case WM_LBUTTONDOWN:
	case WM_LBUTTONUP:
	case WM_MOUSEWHEEL:
		if (!settingAutoTipDelay)
			break;
		if (msg != WM_MOUSEMOVE && !idMouseMoveTimer)
			break;
		if (openedAutoTip && IsWindow(hwndHelpDlg))
			DestroyWindow(hwndHelpDlg);
		openedAutoTip = 0;
		hwndMouseMoveDlg = hwndDlg;
		if (hwndHelpDlg == NULL)
			idMouseMoveTimer = SetTimer(NULL, idMouseMoveTimer, settingAutoTipDelay, NoMouseMoveForDelayTimerProc);
		break;
	case WM_CAPTURECHANGED:
		if ((HWND)lParam == hwndDlg)
			break;
	case WM_SHOWWINDOW:
	case WM_WINDOWPOSCHANGING:
	case WM_MOVING:
	case WM_SIZING:
	case WM_CANCELMODE:
	case WM_CHILDACTIVATE:
	case WM_MOUSEACTIVATE:
	case WM_ACTIVATEAPP:
	case WM_ACTIVATE:
		if (idMouseMoveTimer)
			KillTimer(NULL, idMouseMoveTimer);
		idMouseMoveTimer = 0;
		break;
	case WM_SYSCOMMAND:
		if ((UINT)wParam == SC_CONTEXTHELP_DIALOG) { // alt. "What's this dialog?"
			if (idMouseMoveTimer)
				KillTimer(NULL, idMouseMoveTimer);
			idMouseMoveTimer = 0;
			if (hwndHelpDlg == NULL) {
				hwndHelpDlg = CreateDialog(hInst, MAKEINTRESOURCE(IDD_HELP), NULL, HelpDlgProc);
				if (hwndHelpDlg == NULL)
					break;
			}
			SendMessage(hwndHelpDlg, M_CHANGEHELPCONTROL, 0, (LPARAM)hwndDlg);
			return 0;
		}
		break;
	case WM_CONTEXTMENU:
		{
			POINT pt;
			struct FindChildAtPointData fcap;

			// workaround for badly coded plugins that do display a context menu
			// and pass the message to DefWindowProc afterwards (doing a "break;").
			if (GetTickCount() - GetMessageTime()>10)
				return 0;

			if (idMouseMoveTimer)
				KillTimer(NULL, idMouseMoveTimer);
			idMouseMoveTimer = 0;

			ZeroMemory(&fcap, sizeof(fcap));
			POINTSTOPOINT(pt, MAKEPOINTS(lParam));
			// ChildWindowFromPoint() messes up with group boxes
			fcap.hwnd = NULL;
			fcap.pt = pt;
			EnumChildWindows(hwndDlg, FindChildAtPointEnumProc, (LPARAM)&fcap);
			HWND hwndCtl = fcap.hwnd;
			if (hwndCtl == NULL) {
				ScreenToClient(hwndDlg, &pt);
				hwndCtl = ChildWindowFromPointEx(hwndDlg, pt, CWP_SKIPINVISIBLE);
				if (hwndCtl == NULL)
					break;
				POINTSTOPOINT(pt, MAKEPOINTS(lParam));
			}
			{
				LONG_PTR flags = (LONG_PTR)GetProp(hwndCtl, PROP_CONTEXTSTATE);
				if (flags&PROPF_MENUDISABLED)
					break;
				else if (!(flags&PROPF_MENUFORCED)) {
					int type = GetControlType(hwndCtl);
					// showing a context menu on these looks silly (multi components)
					if (type == CTLTYPE_TOOLBAR || type == CTLTYPE_LISTVIEW || type == CTLTYPE_TREEVIEW || type == CTLTYPE_STATUSBAR || type == CTLTYPE_CLC)
						break;
				}
			}
			if (IsRealChild(hwndDlg, hwndCtl)) {
				HMENU hMenu = CreatePopupMenu();
				AppendMenu(hMenu, MF_STRING, SC_CONTEXTHELP, (hwndCtl == hwndDlg) ? TranslateT("&What's this dialog?") : TranslateT("&What's this?"));
				if (TrackPopupMenuEx(hMenu, TPM_LEFTALIGN | TPM_TOPALIGN | TPM_HORPOSANIMATION | TPM_VERPOSANIMATION | TPM_RIGHTBUTTON | TPM_RETURNCMD | TPM_NONOTIFY, pt.x, pt.y, hwndDlg, NULL)) {
					if (hwndHelpDlg == NULL) {
						hwndHelpDlg = CreateDialog(hInst, MAKEINTRESOURCE(IDD_HELP), NULL, HelpDlgProc);
						if (hwndHelpDlg == NULL) {
							DestroyMenu(hMenu);
							break;
						}
					}
					SendMessage(hwndHelpDlg, M_CHANGEHELPCONTROL, 0, (LPARAM)hwndCtl);
				}
				DestroyMenu(hMenu);
			}
			return 0;
		}
	case WM_HELP:
		{
			HELPINFO *hi = (HELPINFO*)lParam;
			if (hi->iContextType != HELPINFO_WINDOW) break;
			// fix for SHBrowseForFolder() dialog, which sends unhandled help to parent
			if (!IsRealChild(hwndDlg, (HWND)hi->hItemHandle))
				break;

			if (idMouseMoveTimer)
				KillTimer(NULL, idMouseMoveTimer);
			idMouseMoveTimer = 0;

			if (!IsWindow(hwndHelpDlg)) {
				hwndHelpDlg = CreateDialog(hInst, MAKEINTRESOURCE(IDD_HELP), NULL, HelpDlgProc);
				if (hwndHelpDlg == NULL)
					break;
			}
			SendMessage(hwndHelpDlg, M_CHANGEHELPCONTROL, 0, (LPARAM)hi->hItemHandle);
			// we need to eat the next WM_LBUTTONDOWN (if invoked by mouse)
			if (GetKeyState(GetSystemMetrics(SM_SWAPBUTTON) ? VK_RBUTTON : VK_LBUTTON) & 0x8000 && hEatNextMouseHook == NULL)
				hEatNextMouseHook = SetWindowsHookEx(WH_MOUSE, EatNextMouseButtonUpHookProc, NULL, GetCurrentThreadId());
			return TRUE;
		}
	case WM_NCDESTROY:
		if (idMouseMoveTimer)
			KillTimer(NULL, idMouseMoveTimer);
		idMouseMoveTimer = 0;
		EnumChildWindows(hwndDlg, RemovePropForAllChildsEnumProc, (LPARAM)PROP_CONTEXTSTATE);
		{
			TCHAR text[64];
			mir_sntprintf(text, _countof(text), _T("unhooked window 0x%X for context help\n"), hwndDlg);
			OutputDebugString(text);
		}
		SetWindowLongPtr(hwndDlg, GWLP_WNDPROC, (LONG_PTR)pfnWndProc);
		break;
	}
	return CallWindowProc(pfnWndProc, hwndDlg, msg, wParam, lParam);
}
示例#5
0
LRESULT CALLBACK
winMWExtWMWindowProc (HWND hwnd, UINT message, 
			    WPARAM wParam, LPARAM lParam)
{
  WindowPtr		pWin = NULL;
  win32RootlessWindowPtr pRLWinPriv = NULL;
  ScreenPtr		pScreen = NULL;
  winPrivScreenPtr	pScreenPriv = NULL;
  winScreenInfo		*pScreenInfo = NULL;
  HWND			hwndScreen = NULL;
  POINT			ptMouse;
  static Bool		s_fTracking = FALSE;
  HDC			hdcUpdate;
  PAINTSTRUCT		ps;
  LPWINDOWPOS		pWinPos = NULL;
  RECT			rcClient;
  winWMMessageRec	wmMsg;
  Bool			fWMMsgInitialized = FALSE;

  /* Check if the Windows window property for our X window pointer is valid */
  if ((pRLWinPriv = (win32RootlessWindowPtr)GetProp (hwnd, WIN_WINDOW_PROP)) != NULL)
    {
      pWin = pRLWinPriv->pFrame->win;
      pScreen				= pWin->drawable.pScreen;
      if (pScreen) pScreenPriv		= winGetScreenPriv(pScreen);
      if (pScreenPriv) pScreenInfo	= pScreenPriv->pScreenInfo;
      if (pScreenPriv) hwndScreen	= pScreenPriv->hwndScreen;

      wmMsg.msg		= 0;
      wmMsg.hwndWindow	= hwnd;
      wmMsg.iWindow	= (Window)pWin->drawable.id;

      wmMsg.iX		= pRLWinPriv->pFrame->x;
      wmMsg.iY		= pRLWinPriv->pFrame->y;
      wmMsg.iWidth	= pRLWinPriv->pFrame->width;
      wmMsg.iHeight	= pRLWinPriv->pFrame->height;

      fWMMsgInitialized = TRUE;
#if CYGDEBUG
      winDebugWin32Message("winMWExtWMWindowProc", hwnd, message, wParam, lParam);

      winDebug ("\thWnd %08X\n", hwnd);
      winDebug ("\tpScreenPriv %08X\n", pScreenPriv);
      winDebug ("\tpScreenInfo %08X\n", pScreenInfo);
      winDebug ("\thwndScreen %08X\n", hwndScreen);
      winDebug ("winMWExtWMWindowProc (%08x) %08x %08x %08x\n",
	      pRLWinPriv, message, wParam, lParam);
#endif
    }
  /* Branch on message type */
  switch (message)
    {
    case WM_CREATE:
#if CYGMULTIWINDOW_DEBUG
      winDebug ("winMWExtWMWindowProc - WM_CREATE\n");
#endif
      /* */
      SetProp (hwnd,
	       WIN_WINDOW_PROP,
	       (HANDLE)((LPCREATESTRUCT) lParam)->lpCreateParams);
      return 0;

    case WM_CLOSE:
#if CYGMULTIWINDOW_DEBUG
      winDebug ("winMWExtWMWindowProc - WM_CLOSE %d\n", pRLWinPriv->fClose);
#endif
      /* Tell window-manager to close window */
      if (pRLWinPriv->fClose)
	{
	  DestroyWindow (hwnd);
	}
      else
	{
	  if (winIsInternalWMRunning(pScreenInfo))
	    {
	      /* Tell our Window Manager thread to kill the window */
	      wmMsg.msg = WM_WM_KILL;
	      if (fWMMsgInitialized)
		winSendMessageToWM (pScreenPriv->pWMInfo, &wmMsg);
	    }
	  winWindowsWMSendEvent(WindowsWMControllerNotify,
				WindowsWMControllerNotifyMask,
				1,
				WindowsWMCloseWindow,
				pWin->drawable.id,
				0, 0, 0, 0);
	}
      return 0;

    case WM_DESTROY:
#if CYGMULTIWINDOW_DEBUG
      winDebug ("winMWExtWMWindowProc - WM_DESTROY\n");
#endif
      /* Free the shaodw DC; which allows the bitmap to be freed */
      DeleteDC (pRLWinPriv->hdcShadow);
      pRLWinPriv->hdcShadow = NULL;
      
      /* Free the shadow bitmap */
      DeleteObject (pRLWinPriv->hbmpShadow);
      pRLWinPriv->hbmpShadow = NULL;
      
      /* Free the screen DC */
      ReleaseDC (pRLWinPriv->hWnd, pRLWinPriv->hdcScreen);
      pRLWinPriv->hdcScreen = NULL;

      /* Free shadow buffer info header */
      free (pRLWinPriv->pbmihShadow);
      pRLWinPriv->pbmihShadow = NULL;
      
      pRLWinPriv->fResized = FALSE;
      pRLWinPriv->pfb = NULL;
      free (pRLWinPriv);
      RemoveProp (hwnd, WIN_WINDOW_PROP);
      break;

    case WM_MOUSEMOVE:
#if CYGMULTIWINDOW_DEBUG && 0
      winDebug ("winMWExtWMWindowProc - WM_MOUSEMOVE\n");
#endif
      /* Unpack the client area mouse coordinates */
      ptMouse.x = GET_X_LPARAM(lParam);
      ptMouse.y = GET_Y_LPARAM(lParam);

      /* Translate the client area mouse coordinates to screen coordinates */
      ClientToScreen (hwnd, &ptMouse);

      /* Screen Coords from (-X, -Y) -> Root Window (0, 0) */
      ptMouse.x -= GetSystemMetrics (SM_XVIRTUALSCREEN);
      ptMouse.y -= GetSystemMetrics (SM_YVIRTUALSCREEN);

      /* We can't do anything without privates */
      if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput)
	break;

      /* Has the mouse pointer crossed screens? */
      if (pScreen != miPointerGetScreen(inputInfo.pointer))
	miPointerSetScreen (inputInfo.pointer, pScreenInfo->dwScreen,
			       ptMouse.x - pScreenInfo->dwXOffset,
			       ptMouse.y - pScreenInfo->dwYOffset);

      /* Are we tracking yet? */
      if (!s_fTracking)
	{
	  TRACKMOUSEEVENT		tme;
	  
	  /* Setup data structure */
	  ZeroMemory (&tme, sizeof (tme));
	  tme.cbSize = sizeof (tme);
	  tme.dwFlags = TME_LEAVE;
	  tme.hwndTrack = hwnd;

	  /* Call the tracking function */
	  if (!(*g_fpTrackMouseEvent) (&tme))
	    ErrorF ("winMWExtWMWindowProc - _TrackMouseEvent failed\n");

	  /* Flag that we are tracking now */
	  s_fTracking = TRUE;
	}
      
      /* Kill the timer used to poll mouse events */
      if (g_uipMousePollingTimerID != 0)
	{
	  KillTimer (pScreenPriv->hwndScreen, WIN_POLLING_MOUSE_TIMER_ID);
	  g_uipMousePollingTimerID = 0;
	}

      /* Deliver absolute cursor position to X Server */
      winEnqueueMotion(ptMouse.x - pScreenInfo->dwXOffset,
		       ptMouse.y - pScreenInfo->dwYOffset);

      return 0;
      
    case WM_NCMOUSEMOVE:
#if CYGMULTIWINDOW_DEBUG && 0
      winDebug ("winMWExtWMWindowProc - WM_NCMOUSEMOVE\n");
#endif
      /*
       * We break instead of returning 0 since we need to call
       * DefWindowProc to get the mouse cursor changes
       * and min/max/close button highlighting in Windows XP.
       * The Platform SDK says that you should return 0 if you
       * process this message, but it fails to mention that you
       * will give up any default functionality if you do return 0.
       */
      
      /* We can't do anything without privates */
      if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput)
	break;

      /*
       * Timer to poll mouse events.  This is needed to make
       * programs like xeyes follow the mouse properly.
       */
      if (g_uipMousePollingTimerID == 0)
	g_uipMousePollingTimerID = SetTimer (pScreenPriv->hwndScreen,
					     WIN_POLLING_MOUSE_TIMER_ID,
					     MOUSE_POLLING_INTERVAL,
					     NULL);
      break;

    case WM_MOUSELEAVE:
#if CYGMULTIWINDOW_DEBUG
      winDebug ("winMWExtWMWindowProc - WM_MOUSELEAVE\n");
#endif
      /* Mouse has left our client area */

      /* Flag that we are no longer tracking */
      s_fTracking = FALSE;

      /*
       * Timer to poll mouse events.  This is needed to make
       * programs like xeyes follow the mouse properly.
       */
      if (g_uipMousePollingTimerID == 0)
	g_uipMousePollingTimerID = SetTimer (pScreenPriv->hwndScreen,
					     WIN_POLLING_MOUSE_TIMER_ID,
					     MOUSE_POLLING_INTERVAL,
					     NULL);
      return 0;

    case WM_LBUTTONDBLCLK:
    case WM_LBUTTONDOWN:
#if CYGMULTIWINDOW_DEBUG
      winDebug ("winMWExtWMWindowProc - WM_LBUTTONDBLCLK\n");
#endif
      if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput)
	break;
      SetCapture (hwnd);
      return winMouseButtonsHandle (pScreen, ButtonPress, Button1, wParam);
      
    case WM_LBUTTONUP:
#if CYGMULTIWINDOW_DEBUG
      winDebug ("winMWExtWMWindowProc - WM_LBUTTONUP\n");
#endif
      if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput)
	break;
      ReleaseCapture ();
      return winMouseButtonsHandle (pScreen, ButtonRelease, Button1, wParam);

    case WM_MBUTTONDBLCLK:
    case WM_MBUTTONDOWN:
#if CYGMULTIWINDOW_DEBUG
      winDebug ("winMWExtWMWindowProc - WM_MBUTTONDBLCLK\n");
#endif
      if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput)
	break;
      SetCapture (hwnd);
      return winMouseButtonsHandle (pScreen, ButtonPress, Button2, wParam);
      
    case WM_MBUTTONUP:
#if CYGMULTIWINDOW_DEBUG
      winDebug ("winMWExtWMWindowProc - WM_MBUTTONUP\n");
#endif
      if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput)
	break;
      ReleaseCapture ();
      return winMouseButtonsHandle (pScreen, ButtonRelease, Button2, wParam);
      
    case WM_RBUTTONDBLCLK:
    case WM_RBUTTONDOWN:
#if CYGMULTIWINDOW_DEBUG
      winDebug ("winMWExtWMWindowProc - WM_RBUTTONDBLCLK\n");
#endif
      if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput)
	break;
      SetCapture (hwnd);
      return winMouseButtonsHandle (pScreen, ButtonPress, Button3, wParam);
      
    case WM_RBUTTONUP:
#if CYGMULTIWINDOW_DEBUG
      winDebug ("winMWExtWMWindowProc - WM_RBUTTONUP\n");
#endif
      if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput)
	break;
      ReleaseCapture ();
      return winMouseButtonsHandle (pScreen, ButtonRelease, Button3, wParam);

    case WM_XBUTTONDBLCLK:
    case WM_XBUTTONDOWN:
      if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput)
	break;
      SetCapture (hwnd);
      return winMouseButtonsHandle (pScreen, ButtonPress, HIWORD(wParam) + 5, wParam);
    case WM_XBUTTONUP:
      if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput)
	break;
      ReleaseCapture ();
      return winMouseButtonsHandle (pScreen, ButtonRelease, HIWORD(wParam) + 5, wParam);

    case WM_MOUSEWHEEL:
#if CYGMULTIWINDOW_DEBUG
      winDebug ("winMWExtWMWindowProc - WM_MOUSEWHEEL\n");
#endif
      
      /* Pass the message to the root window */
      SendMessage (hwndScreen, message, wParam, lParam);
      return 0;

    case WM_MOUSEACTIVATE:
#if CYGMULTIWINDOW_DEBUG
      winDebug ("winMWExtWMWindowProc - WM_MOUSEACTIVATE\n");
#endif
#if 1
      /* Check if this window needs to be made active when clicked */
      if (winIsInternalWMRunning(pScreenInfo) && pWin->overrideRedirect)
	{
#if CYGMULTIWINDOW_DEBUG
	  winDebug ("winMWExtWMWindowProc - WM_MOUSEACTIVATE - "
		    "MA_NOACTIVATE\n");
#endif

	  /* */
	  return MA_NOACTIVATE;
	}
#endif
      if (!winIsInternalWMRunning(pScreenInfo) && !IsMouseActive (pWin))
	return MA_NOACTIVATE;

      break;

    case WM_KILLFOCUS:
      /* Pop any pressed keys since we are losing keyboard focus */
      winKeybdReleaseKeys ();
      return 0;

    case WM_SYSDEADCHAR:
    case WM_DEADCHAR:
      /*
       * NOTE: We do nothing with WM_*CHAR messages,
       * nor does the root window, so we can just toss these messages.
       */
      return 0;

    case WM_SYSKEYDOWN:
    case WM_KEYDOWN:
#if CYGMULTIWINDOW_DEBUG
      winDebug ("winMWExtWMWindowProc - WM_*KEYDOWN\n");
#endif

      /*
       * Don't pass Alt-F4 key combo to root window,
       * let Windows translate to WM_CLOSE and close this top-level window.
       *
       * NOTE: We purposely don't check the fUseWinKillKey setting because
       * it should only apply to the key handling for the root window,
       * not for top-level window-manager windows.
       *
       * ALSO NOTE: We do pass Ctrl-Alt-Backspace to the root window
       * because that is a key combo that no X app should be expecting to
       * receive, since it has historically been used to shutdown the X server.
       * Passing Ctrl-Alt-Backspace to the root window preserves that
       * behavior, assuming that -unixkill has been passed as a parameter.
       */
      if (wParam == VK_F4 && (GetKeyState (VK_MENU) & 0x8000))
	  break;

      /* Pass the message to the root window */
      SendMessage (hwndScreen, message, wParam, lParam);
      return 0;

    case WM_SYSKEYUP:
    case WM_KEYUP:

#if CYGMULTIWINDOW_DEBUG
      winDebug ("winMWExtWMWindowProc - WM_*KEYUP\n");
#endif

      /* Pass the message to the root window */
      SendMessage (hwndScreen, message, wParam, lParam);
      return 0;

    case WM_HOTKEY:
#if CYGMULTIWINDOW_DEBUG
      winDebug ("winMWExtWMWindowProc - WM_HOTKEY\n");
#endif

      /* Pass the message to the root window */
      SendMessage (hwndScreen, message, wParam, lParam);
      return 0;

    case WM_ERASEBKGND:
#if CYGDEBUG
      winDebug ("winMWExtWMWindowProc - WM_ERASEBKGND\n");
#endif
      /*
       * Pretend that we did erase the background but we don't care,
       * since we repaint the entire region anyhow
       * This avoids some flickering when resizing.
       */
      return TRUE;

    case WM_PAINT:
    
      /* BeginPaint gives us an hdc that clips to the invalidated region */
      hdcUpdate = BeginPaint (hwnd, &ps);

      /* Try to copy from the shadow buffer */
      if (!BitBlt (hdcUpdate,
		   ps.rcPaint.left, ps.rcPaint.top,
		   ps.rcPaint.right - ps.rcPaint.left,
		   ps.rcPaint.bottom - ps.rcPaint.top,
		   pRLWinPriv->hdcShadow,
		   ps.rcPaint.left, ps.rcPaint.top,
		   SRCCOPY))
	{
	  LPVOID lpMsgBuf;
	  
	  /* Display a fancy error message */
	  FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | 
			 FORMAT_MESSAGE_FROM_SYSTEM | 
			 FORMAT_MESSAGE_IGNORE_INSERTS,
			 NULL,
			 GetLastError (),
			 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
			 (LPTSTR) &lpMsgBuf,
			 0, NULL);

	  ErrorF ("winMWExtWMWindowProc - BitBlt failed: %s\n",
		  (LPSTR)lpMsgBuf);
	  LocalFree (lpMsgBuf);
	}

      /* EndPaint frees the DC */
      EndPaint (hwnd, &ps);
      break;

    case WM_ACTIVATE:
#if CYGMULTIWINDOW_DEBUG
      winDebug ("winMWExtWMWindowProc - WM_ACTIVATE\n");
#endif
      if (LOWORD(wParam) != WA_INACTIVE)
	{
	  if (winIsInternalWMRunning(pScreenInfo))
	    {
#if 0
	      /* Raise the window to the top in Z order */
	      wmMsg.msg = WM_WM_RAISE;
	      if (fWMMsgInitialized)
		winSendMessageToWM (pScreenPriv->pWMInfo, &wmMsg);
#endif
	      /* Tell our Window Manager thread to activate the window */
	      wmMsg.msg = WM_WM_ACTIVATE;
	      if (fWMMsgInitialized)
		if (!pWin || !pWin->overrideRedirect) /* for OOo menus */
		  winSendMessageToWM (pScreenPriv->pWMInfo, &wmMsg);
	    }
	  winWindowsWMSendEvent(WindowsWMControllerNotify,
				WindowsWMControllerNotifyMask,
				1,
				WindowsWMActivateWindow,
				pWin->drawable.id,
				0, 0,
				0, 0);
	}
      return 0;

#if 1
    case WM_WINDOWPOSCHANGING:
      pWinPos = (LPWINDOWPOS)lParam;
      if (!(pWinPos->flags & SWP_NOZORDER))
	{
	  if (pRLWinPriv->fRestackingNow || pScreenPriv->fRestacking)
	    {
#if CYGMULTIWINDOW_DEBUG
	      winDebug ("Win %08x is now restacking.\n", (unsigned int)pRLWinPriv);
#endif
	      break;
	    }

	  if (winIsInternalWMRunning(pScreenInfo) || IsRaiseOnClick (pWin))
	    {
#if CYGMULTIWINDOW_DEBUG
	      winDebug ("Win %08x has WINDOWSWM_RAISE_ON_CLICK.\n", (unsigned int)pRLWinPriv);
#endif
	      break;
	    }

#if CYGMULTIWINDOW_DEBUG
	  winDebug ("Win %08x forbid to change z order (%08x).\n",
		    (unsigned int)pRLWinPriv, (unsigned int)pWinPos->hwndInsertAfter);
#endif
	  pWinPos->flags |= SWP_NOZORDER;
	}
      break;
#endif

    case WM_MOVE:
#if CYGMULTIWINDOW_DEBUG
      winDebug ("winMWExtWMWindowProc - WM_MOVE - %d ms\n",
		(unsigned int)GetTickCount ());
#endif
      if (g_fNoConfigureWindow) break;
#if 0
      /* Bail if Windows window is not actually moving */
      if (pRLWinPriv->dwX == (short) LOWORD(lParam)
	  && pRLWinPriv->dwY == (short) HIWORD(lParam))
	break;

      /* Also bail if we're maximizing, we'll do the whole thing in WM_SIZE */
      {
	WINDOWPLACEMENT windPlace;
	windPlace.length = sizeof (WINDOWPLACEMENT);

	/* Get current window placement */
	GetWindowPlacement (hwnd, &windPlace);

	/* Bail if maximizing */
	if (windPlace.showCmd == SW_MAXIMIZE
	    || windPlace.showCmd == SW_SHOWMAXIMIZED)
	  break;
      }
#endif

#if CYGMULTIWINDOW_DEBUG
      winDebug ("\t(%d, %d)\n", (short) LOWORD(lParam), (short) HIWORD(lParam));
#endif
      if (!pRLWinPriv->fMovingOrSizing)
	{
	  if (winIsInternalWMRunning(pScreenInfo))
	    winAdjustXWindow (pWin, hwnd);

	  winMWExtWMMoveXWindow (pWin,
				 (LOWORD(lParam) - wBorderWidth (pWin)
				  - GetSystemMetrics (SM_XVIRTUALSCREEN)),
				 (HIWORD(lParam) - wBorderWidth (pWin)
				  - GetSystemMetrics (SM_YVIRTUALSCREEN)));
	}
      return 0;

    case WM_SHOWWINDOW:
#if CYGMULTIWINDOW_DEBUG || TRUE
      winDebug ("winMWExtWMWindowProc - WM_SHOWWINDOW - %d ms\n",
		(unsigned int)GetTickCount ());
#endif
      /* Bail out if the window is being hidden */
      if (!wParam)
	return 0;

      if (!pScreenInfo->fInternalWM)//XXXX
	return 0;

      winMWExtWMUpdateWindowDecoration (pRLWinPriv, pScreenInfo);

      if (winIsInternalWMRunning(pScreenInfo))
	{
#if CYGMULTIWINDOW_DEBUG || TRUE
	  winDebug ("\tMapWindow\n");
#endif
	  /* Tell X to map the window */
	   MapWindow (pWin, wClient(pWin));

	  if (!pRLWinPriv->pFrame->win->overrideRedirect)
	    /* Bring the Windows window to the foreground */
	    SetForegroundWindow (hwnd);

	  /* Setup the Window Manager message */
	  wmMsg.msg = WM_WM_MAP;
	  wmMsg.iWidth = pRLWinPriv->pFrame->width;
	  wmMsg.iHeight = pRLWinPriv->pFrame->height;

	  /* Tell our Window Manager thread to map the window */
	  if (fWMMsgInitialized)
	    winSendMessageToWM (pScreenPriv->pWMInfo, &wmMsg);
	}
      break;

    case WM_SIZING:
      /* Need to legalize the size according to WM_NORMAL_HINTS */
      /* for applications like xterm */
      return ValidateSizing (hwnd, pWin, wParam, lParam);

    case WM_WINDOWPOSCHANGED:
      {
	pWinPos = (LPWINDOWPOS) lParam;
#if CYGMULTIWINDOW_DEBUG
        winDebug("winMWExtWMWindowProc - WM_WINDOWPOSCHANGED\n");
	winDebug("\tflags: %s%s%s%s%s%s%s%s%s%s%s%s\n",
	(pWinPos->flags & SWP_DRAWFRAME)?"SWP_DRAWFRAME ":"",
	(pWinPos->flags & SWP_FRAMECHANGED)?"SWP_FRAMECHANGED ":"",
	(pWinPos->flags & SWP_HIDEWINDOW)?"SWP_HIDEWINDOW ":"",
	(pWinPos->flags & SWP_NOACTIVATE)?"SWP_NOACTIVATE ":"",
	(pWinPos->flags & SWP_NOCOPYBITS)?"SWP_NOCOPYBITS ":"",
	(pWinPos->flags & SWP_NOMOVE)?"SWP_NOMOVE ":"",
	(pWinPos->flags & SWP_NOOWNERZORDER)?"SWP_NOOWNERZORDER ":"",
	(pWinPos->flags & SWP_NOSIZE)?"SWP_NOSIZE ":"",
	(pWinPos->flags & SWP_NOREDRAW)?"SWP_NOREDRAW ":"",
	(pWinPos->flags & SWP_NOSENDCHANGING)?"SWP_NOSENDCHANGING ":"",
	(pWinPos->flags & SWP_NOZORDER)?"SWP_NOZORDER ":"",
	(pWinPos->flags & SWP_SHOWWINDOW)?"SWP_SHOWWINDOW ":"");
	winDebug("\tno_configure: %s\n", (g_fNoConfigureWindow?"Yes":"No"));
	winDebug("\textend: (%d, %d, %d, %d)\n",
            pWinPos->x, pWinPos->y, pWinPos->cx, pWinPos->cy);

#endif
	if (pWinPos->flags & SWP_HIDEWINDOW) break;

	/* Reorder if window z order was changed */
	if ((pScreenPriv != NULL)
	    && !(pWinPos->flags & SWP_NOZORDER)
	    && !(pWinPos->flags & SWP_SHOWWINDOW)
	    && winIsInternalWMRunning(pScreenInfo))
	  {
#if CYGMULTIWINDOW_DEBUG
	    winDebug ("\twindow z order was changed\n");
#endif
	    if (pWinPos->hwndInsertAfter == HWND_TOP
		||pWinPos->hwndInsertAfter == HWND_TOPMOST
		||pWinPos->hwndInsertAfter == HWND_NOTOPMOST)
	      {
#if CYGMULTIWINDOW_DEBUG
		winDebug ("\traise to top\n");
#endif
		/* Raise the window to the top in Z order */
		wmMsg.msg = WM_WM_RAISE;
		if (fWMMsgInitialized)
		  winSendMessageToWM (pScreenPriv->pWMInfo, &wmMsg);
	      }
#if 1
	    else if (pWinPos->hwndInsertAfter == HWND_BOTTOM)
	      {
	      }
	    else
	      {
		/* Check if this window is top of X windows. */
		HWND hWndAbove = NULL;
		DWORD dwCurrentProcessID = GetCurrentProcessId ();
		DWORD dwWindowProcessID = 0;

		for (hWndAbove = pWinPos->hwndInsertAfter;
		     hWndAbove != NULL;
		     hWndAbove = GetNextWindow (hWndAbove, GW_HWNDPREV))
		  {
		    /* Ignore other XWin process's window */
		    GetWindowThreadProcessId (hWndAbove, &dwWindowProcessID);

		    if ((dwWindowProcessID == dwCurrentProcessID)
			&& GetProp (hWndAbove, WIN_WINDOW_PROP)
			&& !IsWindowVisible (hWndAbove)
			&& !IsIconic (hWndAbove) ) /* ignore minimized windows */
		      break;
		  }
		/* If this is top of X windows in Windows stack,
		   raise it in X stack. */
		if (hWndAbove == NULL)
		  {
#if CYGMULTIWINDOW_DEBUG
		    winDebug ("\traise to top\n");
#endif
		    /* Raise the window to the top in Z order */
		    wmMsg.msg = WM_WM_RAISE;
		    if (fWMMsgInitialized)
		      winSendMessageToWM (pScreenPriv->pWMInfo, &wmMsg);
		  }
	      }
#endif
	  }

	if (!(pWinPos->flags & SWP_NOSIZE)) {
	  if (IsIconic(hwnd)){
#if CYGMULTIWINDOW_DEBUG
	    winDebug ("\tIconic -> MINIMIZED\n");
#endif
	    if (winIsInternalWMRunning(pScreenInfo))
	      {
	      /* Raise the window to the top in Z order */
		wmMsg.msg = WM_WM_LOWER;
		if (fWMMsgInitialized)
		  winSendMessageToWM (pScreenPriv->pWMInfo, &wmMsg);
	      }
	    winWindowsWMSendEvent(WindowsWMControllerNotify,
				  WindowsWMControllerNotifyMask,
				  1,
				  WindowsWMMinimizeWindow,
				  pWin->drawable.id,
				  0, 0, 0, 0);
	  } else if (IsZoomed(hwnd)){
#if CYGMULTIWINDOW_DEBUG
	    winDebug ("\tZoomed -> MAXIMIZED\n");
#endif
	    winWindowsWMSendEvent(WindowsWMControllerNotify,
				  WindowsWMControllerNotifyMask,
				  1,
				  WindowsWMMaximizeWindow,
				  pWin->drawable.id,
				  0, 0, 0, 0);
	  } else {
#if CYGMULTIWINDOW_DEBUG
	    winDebug ("\tnone -> RESTORED\n");
#endif
	    winWindowsWMSendEvent(WindowsWMControllerNotify,
				  WindowsWMControllerNotifyMask,
				  1,
				  WindowsWMRestoreWindow,
				  pWin->drawable.id,
				  0, 0, 0, 0);
	  }
	}
	if (!g_fNoConfigureWindow ) {

	  if (!pRLWinPriv->fMovingOrSizing
	      /*&& (pWinPos->flags & SWP_SHOWWINDOW)*/) {
	    GetClientRect (hwnd, &rcClient);
	    MapWindowPoints (hwnd, HWND_DESKTOP, (LPPOINT)&rcClient, 2);

	    if (!(pWinPos->flags & SWP_NOMOVE)
		&&!(pWinPos->flags & SWP_NOSIZE)) {
#if CYGMULTIWINDOW_DEBUG
	      winDebug ("\tmove & resize\n");
#endif
	      if (winIsInternalWMRunning(pScreenInfo))
                winAdjustXWindow (pWin, hwnd);

	      winMWExtWMMoveResizeXWindow (pWin,
					   rcClient.left - wBorderWidth (pWin)
					   - GetSystemMetrics (SM_XVIRTUALSCREEN),
					   rcClient.top - wBorderWidth (pWin)
					   - GetSystemMetrics (SM_YVIRTUALSCREEN),
					   rcClient.right - rcClient.left
					   - wBorderWidth (pWin)*2,
					   rcClient.bottom - rcClient.top
					   - wBorderWidth (pWin)*2);
	    } else if (!(pWinPos->flags & SWP_NOMOVE)) {
#if CYGMULTIWINDOW_DEBUG
	      winDebug ("\tmove\n");
#endif
	      if (winIsInternalWMRunning(pScreenInfo))
                winAdjustXWindow (pWin, hwnd);

	      winMWExtWMMoveResizeXWindow (pWin,
					   rcClient.left - wBorderWidth (pWin)
					   - GetSystemMetrics (SM_XVIRTUALSCREEN),
					   rcClient.top - wBorderWidth (pWin)
					   - GetSystemMetrics (SM_YVIRTUALSCREEN),
					   rcClient.right - rcClient.left
					   - wBorderWidth (pWin)*2,
					   rcClient.bottom - rcClient.top
					   - wBorderWidth (pWin)*2);
	    } else if (!(pWinPos->flags & SWP_NOMOVE)) {
#if CYGMULTIWINDOW_DEBUG
	      winDebug ("\tmove\n");
#endif
	      if (winIsInternalWMRunning(pScreenInfo))
                winAdjustXWindow (pWin, hwnd); 

	      winMWExtWMMoveXWindow (pWin,
				     rcClient.left - wBorderWidth (pWin)
				     - GetSystemMetrics (SM_XVIRTUALSCREEN),
				     rcClient.top - wBorderWidth (pWin)
				     - GetSystemMetrics (SM_YVIRTUALSCREEN));
	    } else if (!(pWinPos->flags & SWP_NOSIZE)) {
#if CYGMULTIWINDOW_DEBUG
	      winDebug ("\tresize\n");
#endif
	      if (winIsInternalWMRunning(pScreenInfo))
                winAdjustXWindow (pWin, hwnd); 

	      winMWExtWMResizeXWindow (pWin,
				       rcClient.right - rcClient.left
				       - wBorderWidth (pWin)*2,
				       rcClient.bottom - rcClient.top
				       - wBorderWidth (pWin)*2);
	    }
	  }
	}
      }
#if CYGMULTIWINDOW_DEBUG
      winDebug ("winMWExtWMWindowProc - WM_WINDOWPOSCHANGED - done.\n");
#endif
      return 0;

    case WM_SIZE:
      /* see dix/window.c */
      /* FIXME: Maximize/Restore? */
#if CYGMULTIWINDOW_DEBUG
      winDebug ("winMWExtWMWindowProc - WM_SIZE - %d ms\n",
		(unsigned int)GetTickCount ());
#endif
#if CYGMULTIWINDOW_DEBUG
      winDebug ("\t(%d, %d) %d\n", (short) LOWORD(lParam), (short) HIWORD(lParam), g_fNoConfigureWindow);
#endif
      if (g_fNoConfigureWindow) break;

      /* Branch on type of resizing occurring */
      switch (wParam)
	{
	case SIZE_MINIMIZED:
#if CYGMULTIWINDOW_DEBUG
	  winDebug ("\tSIZE_MINIMIZED\n");
#endif
	  if (winIsInternalWMRunning(pScreenInfo))
	    {
	      /* Raise the window to the top in Z order */
	      wmMsg.msg = WM_WM_LOWER;
	      if (fWMMsgInitialized)
		winSendMessageToWM (pScreenPriv->pWMInfo, &wmMsg);
	    }
	  winWindowsWMSendEvent(WindowsWMControllerNotify,
				WindowsWMControllerNotifyMask,
				1,
				WindowsWMMinimizeWindow,
				pWin->drawable.id,
				0, 0,
				LOWORD(lParam), HIWORD(lParam));
	  break;

	case SIZE_RESTORED:
#if CYGMULTIWINDOW_DEBUG
	  winDebug ("\tSIZE_RESTORED\n");
#endif
	  winWindowsWMSendEvent(WindowsWMControllerNotify,
				WindowsWMControllerNotifyMask,
				1,
				WindowsWMRestoreWindow,
				pWin->drawable.id,
				0, 0,
				LOWORD(lParam), HIWORD(lParam));
	  break;

	case SIZE_MAXIMIZED:
#if CYGMULTIWINDOW_DEBUG
	  winDebug ("\tSIZE_MAXIMIZED\n");
#endif
	  winWindowsWMSendEvent(WindowsWMControllerNotify,
				WindowsWMControllerNotifyMask,
				1,
				WindowsWMMaximizeWindow,
				pWin->drawable.id,
				0, 0,
				LOWORD(lParam), HIWORD(lParam));
	  break;
	}

      /* Perform the resize and notify the X client */
      if (!pRLWinPriv->fMovingOrSizing)
	{
	  if (winIsInternalWMRunning(pScreenInfo))
            winAdjustXWindow (pWin, hwnd);

	  winMWExtWMResizeXWindow (pWin,
				   (short) LOWORD(lParam)
				   - wBorderWidth (pWin)*2,
				   (short) HIWORD(lParam)
				   - wBorderWidth (pWin)*2);
	}
      break;

    case WM_ACTIVATEAPP:
#if CYGMULTIWINDOW_DEBUG
      winDebug ("winMWExtWMWindowProc - WM_ACTIVATEAPP - %d ms\n",
		(unsigned int)GetTickCount ());
#endif
      if (wParam)
	{
	  if (winIsInternalWMRunning(pScreenInfo))
	    {
	    }
	  else
	    {
	    }
	  winWindowsWMSendEvent(WindowsWMActivationNotify,
				WindowsWMActivationNotifyMask,
				1,
				WindowsWMIsActive,
				pWin->drawable.id,
				0, 0,
				0, 0);
	}
      else
	{
	  winWindowsWMSendEvent(WindowsWMActivationNotify,
				WindowsWMActivationNotifyMask,
				1,
				WindowsWMIsInactive,
				pWin->drawable.id,
				0, 0,
				0, 0);
	}
      break;

    case WM_SETCURSOR:
      if (LOWORD(lParam) == HTCLIENT)
	{
	  if (!g_fSoftwareCursor) SetCursor (pScreenPriv->cursor.handle);
	  return TRUE;
	}
      break;

    case WM_ENTERSIZEMOVE:
#if CYGMULTIWINDOW_DEBUG
      winDebug ("winMWExtWMWindowProc - WM_ENTERSIZEMOVE - %d ms\n",
		(unsigned int)GetTickCount ());
#endif
      pRLWinPriv->fMovingOrSizing = TRUE;
      break;

    case WM_EXITSIZEMOVE:
#if CYGMULTIWINDOW_DEBUG
      winDebug ("winMWExtWMWindowProc - WM_EXITSIZEMOVE - %d ms\n",
		(unsigned int)GetTickCount ());
#endif
      pRLWinPriv->fMovingOrSizing = FALSE;

      GetClientRect (hwnd, &rcClient);

      MapWindowPoints (hwnd, HWND_DESKTOP, (LPPOINT)&rcClient, 2);

      if (winIsInternalWMRunning(pScreenInfo))
        winAdjustXWindow (pWin, hwnd); 

      winMWExtWMMoveResizeXWindow (pWin,
				   rcClient.left - wBorderWidth (pWin)
				   - GetSystemMetrics (SM_XVIRTUALSCREEN),
				   rcClient.top - wBorderWidth (pWin)
				   - GetSystemMetrics (SM_YVIRTUALSCREEN),
				   rcClient.right - rcClient.left
				   - wBorderWidth (pWin)*2,
				   rcClient.bottom - rcClient.top
				   - wBorderWidth (pWin)*2);
      break;

    case WM_MANAGE:
      ErrorF ("winMWExtWMWindowProc - WM_MANAGE\n");
      break;

    case WM_UNMANAGE:
      ErrorF ("winMWExtWMWindowProc - WM_UNMANAGE\n");
      break;

    default:
      break;
    }

  return DefWindowProc (hwnd, message, wParam, lParam);
}
示例#6
0
文件: winwndproc.c 项目: aosm/X11
LRESULT CALLBACK
winWindowProc (HWND hwnd, UINT message, 
	       WPARAM wParam, LPARAM lParam)
{
  static winPrivScreenPtr	s_pScreenPriv = NULL;
  static winScreenInfo		*s_pScreenInfo = NULL;
  static ScreenPtr		s_pScreen = NULL;
  static HWND			s_hwndLastPrivates = NULL;
  static HINSTANCE		s_hInstance;
  static Bool			s_fTracking = FALSE;
  static unsigned long		s_ulServerGeneration = 0;
  int				iScanCode;
  int				i;

  /* Watch for server regeneration */
  if (g_ulServerGeneration != s_ulServerGeneration)
    {
      /* Store new server generation */
      s_ulServerGeneration = g_ulServerGeneration;
    }

  /* Only retrieve new privates pointers if window handle is null or changed */
  if ((s_pScreenPriv == NULL || hwnd != s_hwndLastPrivates)
      && (s_pScreenPriv = GetProp (hwnd, WIN_SCR_PROP)) != NULL)
    {
#if CYGDEBUG
      ErrorF ("winWindowProc - Setting privates handle\n");
#endif
      s_pScreenInfo = s_pScreenPriv->pScreenInfo;
      s_pScreen = s_pScreenInfo->pScreen;
      s_hwndLastPrivates = hwnd;
    }
  else if (s_pScreenPriv == NULL)
    {
      /* For safety, handle case that should never happen */
      s_pScreenInfo = NULL;
      s_pScreen = NULL;
      s_hwndLastPrivates = NULL;
    }

  /* Branch on message type */
  switch (message)
    {
    case WM_TRAYICON:
      return winHandleIconMessage (hwnd, message, wParam, lParam,
				   s_pScreenPriv);

    case WM_CREATE:
#if CYGDEBUG
      ErrorF ("winWindowProc - WM_CREATE\n");
#endif
      
      /*
       * Add a property to our display window that references
       * this screens' privates.
       *
       * This allows the window procedure to refer to the
       * appropriate window DC and shadow DC for the window that
       * it is processing.  We use this to repaint exposed
       * areas of our display window.
       */
      s_pScreenPriv = ((LPCREATESTRUCT) lParam)->lpCreateParams;
      s_hInstance = ((LPCREATESTRUCT) lParam)->hInstance;
      s_pScreenInfo = s_pScreenPriv->pScreenInfo;
      s_pScreen = s_pScreenInfo->pScreen;
      s_hwndLastPrivates = hwnd;
      SetProp (hwnd, WIN_SCR_PROP, s_pScreenPriv);

      /* Store the mode key states so restore doesn't try to restore them */
      winStoreModeKeyStates (s_pScreen);

      /* Setup tray icon */
      if (!s_pScreenInfo->fNoTrayIcon)
	{
	  /*
	   * NOTE: The WM_CREATE message is processed before CreateWindowEx
	   * returns, so s_pScreenPriv->hwndScreen is invalid at this point.
	   * We go ahead and copy our hwnd parameter over top of the screen
	   * privates hwndScreen so that we have a valid value for
	   * that member.  Otherwise, the tray icon will disappear
	   * the first time you move the mouse over top of it.
	   */
	  
	  s_pScreenPriv->hwndScreen = hwnd;

	  winInitNotifyIcon (s_pScreenPriv);
	}
      return 0;

    case WM_DISPLAYCHANGE:
      /* We cannot handle a display mode change during initialization */
      if (s_pScreenInfo == NULL)
	FatalError ("winWindowProc - WM_DISPLAYCHANGE - The display "
		    "mode changed while we were intializing.  This is "
		    "very bad and unexpected.  Exiting.\n");

      /*
       * We do not care about display changes with
       * fullscreen DirectDraw engines, because those engines set
       * their own mode when they become active.
       */
      if (s_pScreenInfo->fFullScreen
	  && (s_pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DD
	      || s_pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DDNL
	      || s_pScreenInfo->dwEngine == WIN_SERVER_PRIMARY_DD))
	{
	  /* 
	   * Store the new display dimensions and depth.
	   * We do this here for future compatibility in case we
	   * ever allow switching from fullscreen to windowed mode.
	   */
	  s_pScreenPriv->dwLastWindowsWidth = GetSystemMetrics (SM_CXSCREEN);
	  s_pScreenPriv->dwLastWindowsHeight = GetSystemMetrics (SM_CYSCREEN);
	  s_pScreenPriv->dwLastWindowsBitsPixel
	    = GetDeviceCaps (s_pScreenPriv->hdcScreen, BITSPIXEL);	  
	  break;
	}
      
      ErrorF ("winWindowProc - WM_DISPLAYCHANGE - orig bpp: %d, last bpp: %d, "
	      "new bpp: %d\n",
	      s_pScreenInfo->dwBPP,
	      s_pScreenPriv->dwLastWindowsBitsPixel,
	      wParam);

      ErrorF ("winWindowProc - WM_DISPLAYCHANGE - new width: %d "
	      "new height: %d\n",
	      LOWORD (lParam), HIWORD (lParam));

      /*
       * TrueColor --> TrueColor depth changes are disruptive for:
       *	Windowed:
       *		Shadow DirectDraw
       *		Shadow DirectDraw Non-Locking
       *		Primary DirectDraw
       *
       * TrueColor --> TrueColor depth changes are non-optimal for:
       *	Windowed:
       *		Shadow GDI
       *
       *	FullScreen:
       *		Shadow GDI
       *
       * TrueColor --> PseudoColor or vice versa are disruptive for:
       *	Windowed:
       *		Shadow DirectDraw
       *		Shadow DirectDraw Non-Locking
       *		Primary DirectDraw
       *		Shadow GDI
       */

      /*
       * Check for a disruptive change in depth.
       * We can only display a message for a disruptive depth change,
       * we cannot do anything to correct the situation.
       */
      if ((s_pScreenInfo->dwBPP != wParam)
	  && (s_pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DD
	      || s_pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DDNL
	      || s_pScreenInfo->dwEngine == WIN_SERVER_PRIMARY_DD))
	{
	  /* Cannot display the visual until the depth is restored */
	  ErrorF ("winWindowProc - Disruptive change in depth\n");

	  /* Display Exit dialog */
	  winDisplayDepthChangeDialog (s_pScreenPriv);

	  /* Flag that we have an invalid screen depth */
	  s_pScreenPriv->fBadDepth = TRUE;

	  /* Minimize the display window */
	  ShowWindow (hwnd, SW_MINIMIZE);
	}
      else
	{
	  /* Flag that we have a valid screen depth */
	  s_pScreenPriv->fBadDepth = FALSE;
	}
      
      /*
       * Check for a change in display dimensions.
       * We can simply recreate the same-sized primary surface when
       * the display dimensions change.
       */
      if (s_pScreenPriv->dwLastWindowsWidth != LOWORD (lParam)
	  || s_pScreenPriv->dwLastWindowsHeight != HIWORD (lParam))
	{
	  /*
	   * NOTE: The non-DirectDraw engines set the ReleasePrimarySurface
	   * and CreatePrimarySurface function pointers to point
	   * to the no operation function, NoopDDA.  This allows us
	   * to blindly call these functions, even if they are not
	   * relevant to the current engine (e.g., Shadow GDI).
	   */

#if CYGDEBUG
	  ErrorF ("winWindowProc - WM_DISPLAYCHANGE - Dimensions changed\n");
#endif
	  
	  /* Release the old primary surface */
	  (*s_pScreenPriv->pwinReleasePrimarySurface) (s_pScreen);

#if CYGDEBUG
	  ErrorF ("winWindowProc - WM_DISPLAYCHANGE - Released "
		  "primary surface\n");
#endif

	  /* Create the new primary surface */
	  (*s_pScreenPriv->pwinCreatePrimarySurface) (s_pScreen);

#if CYGDEBUG
	  ErrorF ("winWindowProc - WM_DISPLAYCHANGE - Recreated "
		  "primary surface\n");
#endif
	}
      else
	{
#if CYGDEBUG
	  ErrorF ("winWindowProc - WM_DISPLAYCHANGE - Dimensions did not "
		  "change\n");
#endif
	}

      /* Store the new display dimensions and depth */
      s_pScreenPriv->dwLastWindowsWidth = GetSystemMetrics (SM_CXSCREEN);
      s_pScreenPriv->dwLastWindowsHeight = GetSystemMetrics (SM_CYSCREEN);
      s_pScreenPriv->dwLastWindowsBitsPixel
	= GetDeviceCaps (s_pScreenPriv->hdcScreen, BITSPIXEL);
      break;

    case WM_SIZE:
      {
	SCROLLINFO		si;
	RECT			rcWindow;
	int			iWidth, iHeight;

#if CYGDEBUG
	ErrorF ("winWindowProc - WM_SIZE\n");
#endif

	/* Break if we do not use scrollbars */
	if (!s_pScreenInfo->fScrollbars
	    || !s_pScreenInfo->fDecoration
	    || s_pScreenInfo->fRootless
	    || s_pScreenInfo->fMultiWindow
	    || s_pScreenInfo->fFullScreen)
	  break;

	/* No need to resize if we get minimized */
	if (wParam == SIZE_MINIMIZED)
	  return 0;

	/*
	 * Get the size of the whole window, including client area,
	 * scrollbars, and non-client area decorations (caption, borders).
	 * We do this because we need to check if the client area
	 * without scrollbars is large enough to display the whole visual.
	 * The new client area size passed by lParam already subtracts
	 * the size of the scrollbars if they are currently displayed.
	 * So checking is LOWORD(lParam) == visual_width and
	 * HIWORD(lParam) == visual_height will never tell us to hide
	 * the scrollbars because the client area would always be too small.
	 * GetClientRect returns the same sizes given by lParam, so we
	 * cannot use GetClientRect either.
	 */
	GetWindowRect (hwnd, &rcWindow);
	iWidth = rcWindow.right - rcWindow.left;
	iHeight = rcWindow.bottom - rcWindow.top;

	ErrorF ("winWindowProc - WM_SIZE - window w: %d h: %d, "
		"new client area w: %d h: %d\n",
		iWidth, iHeight, LOWORD (lParam), HIWORD (lParam));

	/* Subtract the frame size from the window size. */
	iWidth -= 2 * GetSystemMetrics (SM_CXSIZEFRAME);
	iHeight -= (2 * GetSystemMetrics (SM_CYSIZEFRAME)
		    + GetSystemMetrics (SM_CYCAPTION));

	/*
	 * Update scrollbar page sizes.
	 * NOTE: If page size == range, then the scrollbar is
	 * automatically hidden.
	 */

	/* Is the naked client area large enough to show the whole visual? */
	if (iWidth < s_pScreenInfo->dwWidth
	    || iHeight < s_pScreenInfo->dwHeight)
	  {
	    /* Client area too small to display visual, use scrollbars */
	    iWidth -= GetSystemMetrics (SM_CXVSCROLL);
	    iHeight -= GetSystemMetrics (SM_CYHSCROLL);
	  }
	
	/* Set the horizontal scrollbar page size */
	si.cbSize = sizeof (si);
	si.fMask = SIF_PAGE | SIF_RANGE;
	si.nMin = 0;
	si.nMax = s_pScreenInfo->dwWidth - 1;
	si.nPage = iWidth;
	SetScrollInfo (hwnd, SB_HORZ, &si, TRUE);
	
	/* Set the vertical scrollbar page size */
	si.cbSize = sizeof (si);
	si.fMask = SIF_PAGE | SIF_RANGE;
	si.nMin = 0;
	si.nMax = s_pScreenInfo->dwHeight - 1;
	si.nPage = iHeight;
	SetScrollInfo (hwnd, SB_VERT, &si, TRUE);

	/*
	 * NOTE: Scrollbars may have moved if they were at the 
	 * far right/bottom, so we query their current position.
	 */
	
	/* Get the horizontal scrollbar position and set the offset */
	si.cbSize = sizeof (si);
	si.fMask = SIF_POS;
	GetScrollInfo (hwnd, SB_HORZ, &si);
	s_pScreenInfo->dwXOffset = -si.nPos;
	
	/* Get the vertical scrollbar position and set the offset */
	si.cbSize = sizeof (si);
	si.fMask = SIF_POS;
	GetScrollInfo (hwnd, SB_VERT, &si);
	s_pScreenInfo->dwYOffset = -si.nPos;
      }
      return 0;

    case WM_VSCROLL:
      {
	SCROLLINFO		si;
	int			iVertPos;

#if CYGDEBUG
	ErrorF ("winWindowProc - WM_VSCROLL\n");
#endif
      
	/* Get vertical scroll bar info */
	si.cbSize = sizeof (si);
	si.fMask = SIF_ALL;
	GetScrollInfo (hwnd, SB_VERT, &si);

	/* Save the vertical position for comparison later */
	iVertPos = si.nPos;

	/*
	 * Don't forget:
	 * moving the scrollbar to the DOWN, scroll the content UP
	 */
	switch (LOWORD(wParam))
	  {
	  case SB_TOP:
	    si.nPos = si.nMin;
	    break;
	  
	  case SB_BOTTOM:
	    si.nPos = si.nMax - si.nPage + 1;
	    break;

	  case SB_LINEUP:
	    si.nPos -= 1;
	    break;
	  
	  case SB_LINEDOWN:
	    si.nPos += 1;
	    break;
	  
	  case SB_PAGEUP:
	    si.nPos -= si.nPage;
	    break;
	  
	  case SB_PAGEDOWN:
	    si.nPos += si.nPage;
	    break;

	  case SB_THUMBTRACK:
	    si.nPos = si.nTrackPos;
	    break;

	  default:
	    break;
	  }

	/*
	 * We retrieve the position after setting it,
	 * because Windows may adjust it.
	 */
	si.fMask = SIF_POS;
	SetScrollInfo (hwnd, SB_VERT, &si, TRUE);
	GetScrollInfo (hwnd, SB_VERT, &si);
      
	/* Scroll the window if the position has changed */
	if (si.nPos != iVertPos)
	  {
	    /* Save the new offset for bit block transfers, etc. */
	    s_pScreenInfo->dwYOffset = -si.nPos;

	    /* Change displayed region in the window */
	    ScrollWindowEx (hwnd,
			    0,
			    iVertPos - si.nPos,
			    NULL,
			    NULL,
			    NULL,
			    NULL,
			    SW_INVALIDATE);
	  
	    /* Redraw the window contents */
	    UpdateWindow (hwnd);
	  }
      }
      return 0;

    case WM_HSCROLL:
      {
	SCROLLINFO		si;
	int			iHorzPos;

#if CYGDEBUG
	ErrorF ("winWindowProc - WM_HSCROLL\n");
#endif
      
	/* Get horizontal scroll bar info */
	si.cbSize = sizeof (si);
	si.fMask = SIF_ALL;
	GetScrollInfo (hwnd, SB_HORZ, &si);

	/* Save the horizontal position for comparison later */
	iHorzPos = si.nPos;

	/*
	 * Don't forget:
	 * moving the scrollbar to the RIGHT, scroll the content LEFT
	 */
	switch (LOWORD(wParam))
	  {
	  case SB_LEFT:
	    si.nPos = si.nMin;
	    break;
	  
	  case SB_RIGHT:
	    si.nPos = si.nMax - si.nPage + 1;
	    break;

	  case SB_LINELEFT:
	    si.nPos -= 1;
	    break;
	  
	  case SB_LINERIGHT:
	    si.nPos += 1;
	    break;
	  
	  case SB_PAGELEFT:
	    si.nPos -= si.nPage;
	    break;
	  
	  case SB_PAGERIGHT:
	    si.nPos += si.nPage;
	    break;

	  case SB_THUMBTRACK:
	    si.nPos = si.nTrackPos;
	    break;

	  default:
	    break;
	  }

	/*
	 * We retrieve the position after setting it,
	 * because Windows may adjust it.
	 */
	si.fMask = SIF_POS;
	SetScrollInfo (hwnd, SB_HORZ, &si, TRUE);
	GetScrollInfo (hwnd, SB_HORZ, &si);
      
	/* Scroll the window if the position has changed */
	if (si.nPos != iHorzPos)
	  {
	    /* Save the new offset for bit block transfers, etc. */
	    s_pScreenInfo->dwXOffset = -si.nPos;

	    /* Change displayed region in the window */
	    ScrollWindowEx (hwnd,
			    iHorzPos - si.nPos,
			    0,
			    NULL,
			    NULL,
			    NULL,
			    NULL,
			    SW_INVALIDATE);
	  
	    /* Redraw the window contents */
	    UpdateWindow (hwnd);
	  }
      }
      return 0;

    case WM_GETMINMAXINFO:
      {
	MINMAXINFO		*pMinMaxInfo = (MINMAXINFO *) lParam;
	int			iCaptionHeight;
	int			iBorderHeight, iBorderWidth;

#if CYGDEBUG	
	ErrorF ("winWindowProc - WM_GETMINMAXINFO - pScreenInfo: %08x\n",
		s_pScreenInfo);
#endif

	/* Can't do anything without screen info */
	if (s_pScreenInfo == NULL
	    || !s_pScreenInfo->fScrollbars
	    || s_pScreenInfo->fFullScreen
	    || !s_pScreenInfo->fDecoration
	    || s_pScreenInfo->fRootless
	    || s_pScreenInfo->fMultiWindow)
	  break;

	/*
	 * Here we can override the maximum tracking size, which
	 * is the largest size that can be assigned to our window
	 * via the sizing border.
	 */

	/*
	 * FIXME: Do we only need to do this once, since our visual size
	 * does not change?  Does Windows store this value statically
	 * once we have set it once?
	 */

	/* Get the border and caption sizes */
	iCaptionHeight = GetSystemMetrics (SM_CYCAPTION);
	iBorderWidth = 2 * GetSystemMetrics (SM_CXSIZEFRAME);
	iBorderHeight = 2 * GetSystemMetrics (SM_CYSIZEFRAME);
	
	/* Allow the full visual to be displayed */
	pMinMaxInfo->ptMaxTrackSize.x
	  = s_pScreenInfo->dwWidth + iBorderWidth;
	pMinMaxInfo->ptMaxTrackSize.y
	  = s_pScreenInfo->dwHeight + iBorderHeight + iCaptionHeight;
      }
      return 0;

    case WM_ERASEBKGND:
#if CYGDEBUG
      ErrorF ("winWindowProc - WM_ERASEBKGND\n");
#endif
      /*
       * Pretend that we did erase the background but we don't care,
       * the application uses the full window estate. This avoids some
       * flickering when resizing.
       */
      return TRUE;

    case WM_PAINT:
#if CYGDEBUG
      ErrorF ("winWindowProc - WM_PAINT\n");
#endif
      /* Only paint if we have privates and the server is enabled */
      if (s_pScreenPriv == NULL
	  || !s_pScreenPriv->fEnabled
	  || (s_pScreenInfo->fFullScreen && !s_pScreenPriv->fActive)
	  || s_pScreenPriv->fBadDepth)
	{
	  /* We don't want to paint */
	  break;
	}

      /* Break out here if we don't have a valid paint routine */
      if (s_pScreenPriv->pwinBltExposedRegions == NULL)
	break;
      
      /* Call the engine dependent repainter */
      (*s_pScreenPriv->pwinBltExposedRegions) (s_pScreen);
      return 0;

    case WM_PALETTECHANGED:
      {
#if CYGDEBUG
	ErrorF ("winWindowProc - WM_PALETTECHANGED\n");
#endif
	/*
	 * Don't process if we don't have privates or a colormap,
	 * or if we have an invalid depth.
	 */
	if (s_pScreenPriv == NULL
	    || s_pScreenPriv->pcmapInstalled == NULL
	    || s_pScreenPriv->fBadDepth)
	  break;

	/* Return if we caused the palette to change */
	if ((HWND) wParam == hwnd)
	  {
	    /* Redraw the screen */
	    (*s_pScreenPriv->pwinRedrawScreen) (s_pScreen);
	    return 0;
	  }
	
	/* Reinstall the windows palette */
	(*s_pScreenPriv->pwinRealizeInstalledPalette) (s_pScreen);
	
	/* Redraw the screen */
	(*s_pScreenPriv->pwinRedrawScreen) (s_pScreen);
	return 0;
      }

    case WM_MOUSEMOVE:
      /* We can't do anything without privates */
      if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
	break;

      /* Has the mouse pointer crossed screens? */
      if (s_pScreen != miPointerCurrentScreen ())
	miPointerSetNewScreen (s_pScreenInfo->dwScreen,
			       GET_X_LPARAM(lParam)-s_pScreenInfo->dwXOffset,
			       GET_Y_LPARAM(lParam)-s_pScreenInfo->dwYOffset);

      /* Are we tracking yet? */
      if (!s_fTracking)
	{
	  TRACKMOUSEEVENT		tme;
	  
	  /* Setup data structure */
	  ZeroMemory (&tme, sizeof (tme));
	  tme.cbSize = sizeof (tme);
	  tme.dwFlags = TME_LEAVE;
	  tme.hwndTrack = hwnd;

	  /* Call the tracking function */
	  if (!(*g_fpTrackMouseEvent) (&tme))
	    ErrorF ("winWindowProc - _TrackMouseEvent failed\n");

	  /* Flag that we are tracking now */
	  s_fTracking = TRUE;
	}

      /* Hide or show the Windows mouse cursor */
      if (g_fCursor && (s_pScreenPriv->fActive || s_pScreenInfo->fLessPointer))
	{
	  /* Hide Windows cursor */
	  g_fCursor = FALSE;
	  ShowCursor (FALSE);
	}
      else if (!g_fCursor && !s_pScreenPriv->fActive
	       && !s_pScreenInfo->fLessPointer)
	{
	  /* Show Windows cursor */
	  g_fCursor = TRUE;
	  ShowCursor (TRUE);
	}
      
      /* Deliver absolute cursor position to X Server */
      miPointerAbsoluteCursor (GET_X_LPARAM(lParam)-s_pScreenInfo->dwXOffset,
			       GET_Y_LPARAM(lParam)-s_pScreenInfo->dwYOffset,
			       g_c32LastInputEventTime = GetTickCount ());
      return 0;

    case WM_NCMOUSEMOVE:
      /*
       * We break instead of returning 0 since we need to call
       * DefWindowProc to get the mouse cursor changes
       * and min/max/close button highlighting in Windows XP.
       * The Platform SDK says that you should return 0 if you
       * process this message, but it fails to mention that you
       * will give up any default functionality if you do return 0.
       */
      
      /* We can't do anything without privates */
      if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
	break;
      
      /* Non-client mouse movement, show Windows cursor */
      if (!g_fCursor)
	{
	  g_fCursor = TRUE;
	  ShowCursor (TRUE);
	}
      break;

    case WM_MOUSELEAVE:
      /* Mouse has left our client area */

      /* Flag that we are no longer tracking */
      s_fTracking = FALSE;

      /* Show the mouse cursor, if necessary */
      if (!g_fCursor)
	{
	  g_fCursor = TRUE;
	  ShowCursor (TRUE);
	}
      return 0;

    case WM_LBUTTONDBLCLK:
    case WM_LBUTTONDOWN:
      if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
	break;
      if (s_pScreenInfo->fRootless) SetCapture (hwnd);
      return winMouseButtonsHandle (s_pScreen, ButtonPress, Button1, wParam);
      
    case WM_LBUTTONUP:
      if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
	break;
      if (s_pScreenInfo->fRootless) ReleaseCapture ();
      return winMouseButtonsHandle (s_pScreen, ButtonRelease, Button1, wParam);

    case WM_MBUTTONDBLCLK:
    case WM_MBUTTONDOWN:
      if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
	break;
      if (s_pScreenInfo->fRootless) SetCapture (hwnd);
      return winMouseButtonsHandle (s_pScreen, ButtonPress, Button2, wParam);
      
    case WM_MBUTTONUP:
      if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
	break;
      if (s_pScreenInfo->fRootless) ReleaseCapture ();
      return winMouseButtonsHandle (s_pScreen, ButtonRelease, Button2, wParam);
      
    case WM_RBUTTONDBLCLK:
    case WM_RBUTTONDOWN:
      if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
	break;
      if (s_pScreenInfo->fRootless) SetCapture (hwnd);
      return winMouseButtonsHandle (s_pScreen, ButtonPress, Button3, wParam);
      
    case WM_RBUTTONUP:
      if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
	break;
      if (s_pScreenInfo->fRootless) ReleaseCapture ();
      return winMouseButtonsHandle (s_pScreen, ButtonRelease, Button3, wParam);

    case WM_TIMER:
      if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
	break;

      /* Branch on the timer id */
      switch (wParam)
	{
	case WIN_E3B_TIMER_ID:
	  /* Send delayed button press */
	  winMouseButtonsSendEvent (ButtonPress,
				    s_pScreenPriv->iE3BCachedPress);

	  /* Kill this timer */
	  KillTimer (s_pScreenPriv->hwndScreen, WIN_E3B_TIMER_ID);

	  /* Clear screen privates flags */
	  s_pScreenPriv->iE3BCachedPress = 0;
	  break;

	case WIN_POLLING_MOUSE_TIMER_ID:
	  {
	    POINT		point;
	    
	    /* Get the current position of the mouse cursor */
	    GetCursorPos (&point);
	    
	    /* Map from screen (-X, -Y) to root (0, 0) */
	    point.x -= GetSystemMetrics (SM_XVIRTUALSCREEN);
	    point.y -= GetSystemMetrics (SM_YVIRTUALSCREEN);
	    
	    /* Deliver absolute cursor position to X Server */
	    miPointerAbsoluteCursor (point.x, point.y,
				     g_c32LastInputEventTime = GetTickCount());
	  }
	}
      return 0;

    case WM_CTLCOLORSCROLLBAR:
      FatalError ("winWindowProc - WM_CTLCOLORSCROLLBAR - We are not "
		  "supposed to get this message.  Exiting.\n");
      return 0;

    case WM_MOUSEWHEEL:
      if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
	break;
#if CYGDEBUG
      ErrorF ("winWindowProc - WM_MOUSEWHEEL\n");
#endif
      winMouseWheel (s_pScreen, GET_WHEEL_DELTA_WPARAM(wParam));
      break;

    case WM_SETFOCUS:
      if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
	break;

      /* Restore the state of all mode keys */
      winRestoreModeKeyStates (s_pScreen);
      return 0;

    case WM_KILLFOCUS:
      if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
	break;

      /* Store the state of all mode keys */
      winStoreModeKeyStates (s_pScreen);

      /* Release any pressed keys */
      winKeybdReleaseKeys ();
      return 0;

#if WIN_NEW_KEYBOARD_SUPPORT
    case WM_SYSKEYDOWN:
    case WM_KEYDOWN:
    case WM_SYSKEYUP:
    case WM_KEYUP:
      if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
	break;

      /* Don't process keys if we are not active */
      if (!s_pScreenPriv->fActive)
	return 0;

      winProcessKeyEvent ((DWORD)wParam, (DWORD) lParam);
      return 0;

    case WM_DEADCHAR:
    case WM_SYSDEADCHAR:
      return 0;

#else /* WIN_NEW_KEYBOARD_SUPPORT */
    case WM_SYSKEYDOWN:
    case WM_KEYDOWN:
      if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
	break;

      /*
       * FIXME: Catching Alt-F4 like this is really terrible.  This should
       * be generalized to handle other Windows keyboard signals.  Actually,
       * the list keys to catch and the actions to perform when caught should
       * be configurable; that way user's can customize the keys that they
       * need to have passed through to their window manager or apps, or they
       * can remap certain actions to new key codes that do not conflict
       * with the X apps that they are using.  Yeah, that'll take awhile.
       */
      if ((s_pScreenInfo->fUseWinKillKey && wParam == VK_F4
	   && (GetKeyState (VK_MENU) & 0x8000))
	  || (s_pScreenInfo->fUseUnixKillKey && wParam == VK_BACK
	      && (GetKeyState (VK_MENU) & 0x8000)
	      && (GetKeyState (VK_CONTROL) & 0x8000)))
	{
	  /*
	   * Better leave this message here, just in case some unsuspecting
	   * user enters Alt + F4 and is surprised when the application
	   * quits.
	   */
	  ErrorF ("winWindowProc - WM_*KEYDOWN - Closekey hit, quitting\n");
	  
	  /* Display Exit dialog */
	  winDisplayExitDialog (s_pScreenPriv);
	  return 0;
	}
      
      /*
       * Don't do anything for the Windows keys, as focus will soon
       * be returned to Windows.  We may be able to trap the Windows keys,
       * but we should determine if that is desirable before doing so.
       */
      if (wParam == VK_LWIN || wParam == VK_RWIN)
	break;

      /* Discard fake Ctrl_L presses that precede AltGR on non-US keyboards */
      if (winIsFakeCtrl_L (message, wParam, lParam))
	return 0;
      
      /* Send the key event(s) */
      winTranslateKey (wParam, lParam, &iScanCode);
      for (i = 0; i < LOWORD(lParam); ++i)
	winSendKeyEvent (iScanCode, TRUE);
      return 0;

    case WM_SYSKEYUP:
    case WM_KEYUP:
      if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
	break;

      /*
       * Don't do anything for the Windows keys, as focus will soon
       * be returned to Windows.  We may be able to trap the Windows keys,
       * but we should determine if that is desirable before doing so.
       */
      if (wParam == VK_LWIN || wParam == VK_RWIN)
	break;

      /* Ignore the fake Ctrl_L that follows an AltGr release */
      if (winIsFakeCtrl_L (message, wParam, lParam))
	return 0;

      /* Enqueue a keyup event */
      winTranslateKey (wParam, lParam, &iScanCode);
      winSendKeyEvent (iScanCode, FALSE);
      return 0;
#endif /* WIN_NEW_KEYBOARD_SUPPORT */

    case WM_HOTKEY:
      if (s_pScreenPriv == NULL)
	break;

      /* Call the engine-specific hot key handler */
      (*s_pScreenPriv->pwinHotKeyAltTab) (s_pScreen);
      return 0;

    case WM_ACTIVATE:
      if (s_pScreenPriv == NULL
	  || s_pScreenInfo->fIgnoreInput)
	break;

      /* TODO: Override display of window when we have a bad depth */
      if (LOWORD(wParam) != WA_INACTIVE && s_pScreenPriv->fBadDepth)
	{
	  ErrorF ("winWindowProc - WM_ACTIVATE - Bad depth, trying "
		  "to override window activation\n");

	  /* Minimize the window */
	  ShowWindow (hwnd, SW_MINIMIZE);

	  /* Display dialog box */
	  if (g_hDlgDepthChange != NULL)
	    {
	      /* Make the existing dialog box active */
	      SetActiveWindow (g_hDlgDepthChange);
	    }
	  else
	    {
	      /* TODO: Recreate the dialog box and bring to the top */
	      ShowWindow (g_hDlgDepthChange, SW_SHOWDEFAULT);
	    }

	  /* Don't do any other processing of this message */
	  return 0;
	}

#if CYGDEBUG
      ErrorF ("winWindowProc - WM_ACTIVATE\n");
#endif

      /*
       * Focus is being changed to another window.
       * The other window may or may not belong to
       * our process.
       */

      /* Clear any lingering wheel delta */
      s_pScreenPriv->iDeltaZ = 0;

      /* Reshow the Windows mouse cursor if we are being deactivated */
      if (LOWORD(wParam) == WA_INACTIVE
	  && !g_fCursor)
	{
	  /* Show Windows cursor */
	  g_fCursor = TRUE;
	  ShowCursor (TRUE);
	}
      return 0;

    case WM_ACTIVATEAPP:
      if (s_pScreenPriv == NULL
	  || s_pScreenInfo->fIgnoreInput)
	break;

#if CYGDEBUG
      ErrorF ("winWindowProc - WM_ACTIVATEAPP\n");
#endif

      /* Activate or deactivate */
      s_pScreenPriv->fActive = wParam;

      /* Reshow the Windows mouse cursor if we are being deactivated */
      if (!s_pScreenPriv->fActive
	  && !g_fCursor)
	{
	  /* Show Windows cursor */
	  g_fCursor = TRUE;
	  ShowCursor (TRUE);
	}

      /* Call engine specific screen activation/deactivation function */
      (*s_pScreenPriv->pwinActivateApp) (s_pScreen);
      return 0;

    case WM_COMMAND:
      switch (LOWORD (wParam))
	{
	case ID_APP_EXIT:
	  /* Display Exit dialog */
	  winDisplayExitDialog (s_pScreenPriv);
	  return 0;

	case ID_APP_HIDE_ROOT:
	  ShowWindow (s_pScreenPriv->hwndScreen, SW_HIDE);
	  s_pScreenPriv->fRootWindowShown = FALSE;
	  return 0;

	case ID_APP_SHOW_ROOT:
	  ShowWindow (s_pScreenPriv->hwndScreen, SW_SHOW);
	  s_pScreenPriv->fRootWindowShown = TRUE;
	  return 0;

	default:
	  /* It's probably one of the custom menus... */
	  return HandleCustomWM_COMMAND (0, LOWORD (wParam));
	  
	}
      break;

    case WM_GIVEUP:
       /* Tell X that we are giving up */
      winDeinitClipboard ();
      winDeinitMultiWindowWM ();
      GiveUp (0);
      return 0;

    case WM_CLOSE:
      /* Display Exit dialog */
      winDisplayExitDialog (s_pScreenPriv);
      return 0;
    }

  return DefWindowProc (hwnd, message, wParam, lParam);
}
示例#7
0
文件: config.cpp 项目: songhtdo/vespa
Config::Config(const char* config_name, Juniper & juniper) :
    _docsumparams(),
    _matcherparams(),
    _sumconf(NULL),
    _config_name(config_name),
    _juniper(juniper)
{
    std::string separators = "";
    separators += UNIT_SEPARATOR;
    separators += GROUP_SEPARATOR;

    const char* high_on  = GetProp("dynsum.highlight_on", "<b>");
    const char* high_off = GetProp("dynsum.highlight_off", "</b>");
    const char* contsym  = GetProp("dynsum.continuation", "...");
    const char* fallback = GetProp("dynsum.fallback", "none");
    size_t summarylength = atoi(GetProp("dynsum.length", "256"));
    size_t sum_minlength = atoi(GetProp("dynsum.min_length", "128"));
    size_t stem_min      = atoi(GetProp("stem.min_length", "5"));
    size_t stem_extend   = atoi(GetProp("stem.max_extend", "3"));
    size_t surround_max  = atoi(GetProp("dynsum.surround_max", "128"));
    size_t max_matches   = atoi(GetProp("dynsum.max_matches", "3"));
    const char* escape_markup  = GetProp("dynsum.escape_markup", "auto");
    const char* preserve_white_space  = GetProp("dynsum.preserve_white_space", "off");
    size_t match_winsize = strtol(GetProp("matcher.winsize", "200"), NULL, 0);
    size_t max_match_candidates = atoi(GetProp("matcher.max_match_candidates", "1000"));
    const char* seps = GetProp("dynsum.separators", separators.c_str());
    const unsigned char* cons =
        reinterpret_cast<const unsigned char*>(GetProp("dynsum.connectors", separators.c_str()));
    double proximity_factor = vespalib::locale::c::strtod(GetProp("proximity.factor", "0.25"), NULL);
    // Silently convert to something sensible
    if (proximity_factor > 1E8 || proximity_factor < 0) proximity_factor = 0.25;

    _sumconf = CreateSummaryConfig(high_on, high_off, contsym, seps, cons,
				   StringToConfigFlag(escape_markup),
				   StringToConfigFlag(preserve_white_space));
    _docsumparams.SetEnabled(true)
        .SetLength(summarylength).SetMinLength(sum_minlength)
        .SetMaxMatches(max_matches)
        .SetSurroundMax(surround_max)
        .SetFallback(fallback);
    _matcherparams.SetWantGlobalRank(true)
        .SetStemMinLength(stem_min).SetStemMaxExtend(stem_extend)
        .SetMatchWindowSize(match_winsize)
        .SetMaxMatchCandidates(max_match_candidates)
        .SetWordFolder(& _juniper.getWordFolder())
        .SetProximityFactor(proximity_factor);
}
//=============================================================================
//
//  DirList_Fill()
//
//  Snapshots a directory and displays the items in the listview control
//
int DirList_Fill(HWND hwnd,LPCWSTR lpszDir,DWORD grfFlags,LPCWSTR lpszFileSpec,
                 BOOL bExcludeFilter,BOOL bNoFadeHidden,
                 int iSortFlags,BOOL fSortRev)
{

  WCHAR wszDir[MAX_PATH];

  LPSHELLFOLDER lpsfDesktop = NULL;
  LPSHELLFOLDER lpsf = NULL;

  LPITEMIDLIST  pidl = NULL;
  LPITEMIDLIST  pidlEntry = NULL;

  LPENUMIDLIST  lpe = NULL;

  LV_ITEM       lvi;
  LPLV_ITEMDATA lplvid;

  ULONG chParsed = 0;
  ULONG dwAttributes = 0;

  DL_FILTER dlf;
  SHFILEINFO shfi;

  LPDLDATA lpdl = (LPVOID)GetProp(hwnd,pDirListProp);

  // Initialize default icons
  SHGetFileInfo(L"Icon",FILE_ATTRIBUTE_DIRECTORY,&shfi,sizeof(SHFILEINFO),
    SHGFI_USEFILEATTRIBUTES | SHGFI_SMALLICON | SHGFI_SYSICONINDEX);
  lpdl->iDefIconFolder = shfi.iIcon;

  SHGetFileInfo(L"Icon",FILE_ATTRIBUTE_NORMAL,&shfi,sizeof(SHFILEINFO),
    SHGFI_USEFILEATTRIBUTES | SHGFI_SMALLICON | SHGFI_SYSICONINDEX);
  lpdl->iDefIconFile = shfi.iIcon;

  // First of all terminate running icon thread
  DirList_TerminateIconThread(hwnd);

  // A Directory is strongly required
  if (!lpszDir || !*lpszDir)
    return(-1);

  lstrcpy(lpdl->szPath,lpszDir);

  // Init ListView
  SendMessage(hwnd,WM_SETREDRAW,0,0);
  ListView_DeleteAllItems(hwnd);

  // Init Filter
  DirList_CreateFilter(&dlf,lpszFileSpec,bExcludeFilter);

  // Init lvi
  lvi.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM;
  lvi.iItem = 0;
  lvi.iSubItem = 0;
  lvi.pszText = LPSTR_TEXTCALLBACK;
  lvi.cchTextMax = MAX_PATH;
  lvi.iImage = I_IMAGECALLBACK;

  // Convert Directory to a UNICODE string
  /*MultiByteToWideChar(CP_ACP,
                      MB_PRECOMPOSED,
                      lpszDir,
                      -1,
                      wszDir,
                      MAX_PATH);*/
  lstrcpy(wszDir,lpszDir);


  // Get Desktop Folder
  if (NOERROR == SHGetDesktopFolder(&lpsfDesktop))
  {

    // Convert wszDir into a pidl
    if (NOERROR == lpsfDesktop->lpVtbl->ParseDisplayName(
                                          lpsfDesktop,
                                          hwnd,
                                          NULL,
                                          wszDir,
                                          &chParsed,
                                          &pidl,
                                          &dwAttributes))

    {

      // Bind pidl to IShellFolder
      if (NOERROR == lpsfDesktop->lpVtbl->BindToObject(
                                            lpsfDesktop,
                                            pidl,
                                            NULL,
                                            &IID_IShellFolder,
                                            &lpsf))

      {

        // Create an Enumeration object for lpsf
        if (NOERROR == lpsf->lpVtbl->EnumObjects(
                                        lpsf,
                                        hwnd,
                                        grfFlags,
                                        &lpe))

        {

          // Enumerate the contents of lpsf
          while (NOERROR == lpe->lpVtbl->Next(
                                            lpe,
                                            1,
                                            &pidlEntry,
                                            NULL))

          {

            // Add found item to the List
            // Check if it's part of the Filesystem
            dwAttributes = SFGAO_FILESYSTEM | SFGAO_FOLDER;

            lpsf->lpVtbl->GetAttributesOf(
                            lpsf,
                            1,
                            &pidlEntry,
                            &dwAttributes);

            if (dwAttributes & SFGAO_FILESYSTEM)
            {

              // Check if item matches specified filter
              if (DirList_MatchFilter(lpsf,pidlEntry,&dlf))
              {

                lplvid = CoTaskMemAlloc(sizeof(LV_ITEMDATA));

                lplvid->pidl = pidlEntry;
                lplvid->lpsf = lpsf;

                lpsf->lpVtbl->AddRef(lpsf);

                lvi.lParam = (LPARAM)lplvid;

                // Setup default Icon - Folder or File
                lvi.iImage = (dwAttributes & SFGAO_FOLDER) ?
                  lpdl->iDefIconFolder : lpdl->iDefIconFile;

                ListView_InsertItem(hwnd,&lvi);

                lvi.iItem++;

              }

            }

          } // IEnumIDList::Next()

          lpe->lpVtbl->Release(lpe);

        } // IShellFolder::EnumObjects()

      } // IShellFolder::BindToObject()

    } // IShellFolder::ParseDisplayName()

    lpsfDesktop->lpVtbl->Release(lpsfDesktop);

  } // SHGetDesktopFolder()

  if (lpdl->pidl)
    CoTaskMemFree(lpdl->pidl);

  if (lpdl->lpsf && lpdl->lpsf->lpVtbl)
    lpdl->lpsf->lpVtbl->Release(lpdl->lpsf);

  // Set lpdl
  lpdl->cbidl = IL_GetSize(pidl);
  lpdl->pidl = pidl;
  lpdl->lpsf = lpsf;
  lpdl->bNoFadeHidden = bNoFadeHidden;

  // Set column width to fit window
  ListView_SetColumnWidth(hwnd,0,LVSCW_AUTOSIZE_USEHEADER);

  // Sort before display is updated
  DirList_Sort(hwnd,iSortFlags,fSortRev);

  // Redraw Listview
  SendMessage(hwnd,WM_SETREDRAW,1,0);

  // Return number of items in the control
  return (ListView_GetItemCount(hwnd));

}
INT_PTR CALLBACK CRegisterTabs::TabProcGPR(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
    if (msg == WM_INITDIALOG)
    {
        SetProp(hDlg, "attached", (HANDLE)lParam);
        return TRUE;
    }

    // color textboxes
    if (msg == WM_CTLCOLOREDIT)
    {
        HDC hdc = (HDC)wParam;
        COLORREF colorBg = RGB(255, 255, 255);

        COLORREF colorRead = RGB(200, 200, 255);
        COLORREF colorWrite = RGB(255, 200, 200);
        COLORREF colorBoth = RGB(220, 170, 255);

        if (!m_bColorsEnabled || g_Reg == NULL || g_MMU == NULL)
        {
            return FALSE;
        }

        HWND hWnd = (HWND)lParam;
        WORD ctrlId = (WORD) ::GetWindowLong(hWnd, GWL_ID);

        COpInfo opInfo;
        g_MMU->LW_VAddr(g_Reg->m_PROGRAM_COUNTER, opInfo.m_OpCode.Hex);

        bool bOpReads = false;
        bool bOpWrites = false;

        if (ctrlId == IDC_LO_EDIT)
        {
            bOpReads = opInfo.ReadsLO();
            bOpWrites = !bOpReads && opInfo.WritesLO();
        }
        else if (ctrlId == IDC_HI_EDIT)
        {
            bOpReads = opInfo.ReadsHI();
            bOpWrites = !bOpReads && opInfo.WritesHI();
        }
        else
        {
            int nReg = GetCtrlRegNum(ctrlId, GPREditIds);

            if (nReg == -1)
            {
                return (LRESULT)GetStockObject(DC_BRUSH);
            }

            int nRegRead1, nRegRead2, nRegWrite;

            opInfo.ReadsGPR(&nRegRead1, &nRegRead2);
            opInfo.WritesGPR(&nRegWrite);

            bOpReads = (nReg == nRegRead1) || (nReg == nRegRead2);
            bOpWrites = (nReg == nRegWrite);
        }

        if (bOpReads && bOpWrites)
        {
            colorBg = colorBoth;
        }
        else if (bOpReads)
        {
            colorBg = colorRead;
        }
        else if (bOpWrites)
        {
            colorBg = colorWrite;
        }

        SetBkColor(hdc, colorBg);
        SetDCBrushColor(hdc, colorBg);
        return (LRESULT)GetStockObject(DC_BRUSH);
    }

    if (msg == WM_COMMAND && HIWORD(wParam) == EN_KILLFOCUS)
    {
        bool * attached = (bool *)GetProp(hDlg, "attached");
        if (attached != NULL && *attached)
        {
            RegisterChanged(hDlg, TabGPR, wParam);
        }

        return FALSE;
    }

    // right click labels
    if (msg == WM_CONTEXTMENU)
    {
        HWND hWnd = (HWND)wParam;
        WORD ctrlId = (WORD) ::GetWindowLong(hWnd, GWL_ID);

        CBreakpoints* breakpoints = m_Debugger->Breakpoints();

        if (ctrlId == IDC_HI_LBL)
        {
            breakpoints->ToggleHIWriteBP();
        }
        else if (ctrlId == IDC_LO_LBL)
        {
            breakpoints->ToggleLOWriteBP();
        }
        else
        {
            int nReg = GetCtrlRegNum(ctrlId, GPRLabelIds);

            if (nReg <= 0) // ignore R0
            {
                return FALSE;
            }

            breakpoints->ToggleGPRWriteBP(nReg);
        }

        ::InvalidateRect(hWnd, NULL, true);
        return FALSE;
    }

    // click labels
    if (msg == WM_COMMAND && HIWORD(wParam) == STN_CLICKED || HIWORD(wParam) == STN_DBLCLK)
    {
        HWND hWnd = (HWND)lParam;
        WORD ctrlId = LOWORD(wParam);

        CBreakpoints* breakpoints = m_Debugger->Breakpoints();

        if (ctrlId == IDC_HI_LBL)
        {
            breakpoints->ToggleHIReadBP();
        }
        else if (ctrlId == IDC_LO_LBL)
        {
            breakpoints->ToggleLOReadBP();
        }
        else
        {
            int nReg = GetCtrlRegNum(ctrlId, GPRLabelIds);

            if (nReg <= 0) // ignore R0
            {
                return FALSE;
            }

            breakpoints->ToggleGPRReadBP(nReg);
        }

        ::InvalidateRect(hWnd, NULL, true);
        return FALSE;
    }

    // color labels
    if (msg == WM_CTLCOLORSTATIC)
    {
        HWND hWnd = (HWND)lParam;
        WORD ctrlId = (WORD) ::GetWindowLong(hWnd, GWL_ID);
        

        HDC hdc = (HDC)wParam;

        COLORREF colorRead = RGB(200, 200, 255);
        COLORREF colorWrite = RGB(255, 200, 200);
        COLORREF colorBoth = RGB(220, 170, 255);

        CBreakpoints* breakpoints = m_Debugger->Breakpoints();
        
        bool haveRead, haveWrite;

        if (ctrlId == IDC_HI_LBL)
        {
            haveRead = breakpoints->HaveHIReadBP();
            haveWrite = breakpoints->HaveHIWriteBP();
        }
        else if (ctrlId == IDC_LO_LBL)
        {
            haveRead = breakpoints->HaveLOReadBP();
            haveWrite = breakpoints->HaveLOWriteBP();
        }
        else
        {
            int nReg = GetCtrlRegNum(ctrlId, GPRLabelIds);

            if (nReg == -1)
            {
                return FALSE;
            }

            haveRead = breakpoints->HaveGPRReadBP(nReg);
            haveWrite = breakpoints->HaveGPRWriteBP(nReg);
        }

        if (haveRead && haveWrite)
        {
            SetBkColor(hdc, colorBoth);
        }
        else if(haveRead)
        {
            SetBkColor(hdc, colorRead);
        }
        else if(haveWrite)
        {
            SetBkColor(hdc, colorWrite);
        }
        else
        {
            return FALSE;
        }

        return (LRESULT)GetStockObject(DC_BRUSH);
    }
    
    return FALSE;
}
示例#10
0
//---------------------------------------------------------------------------
LRESULT __stdcall NotifyInitWndProc(HWND Win,UINT Mess,WPARAM wPar,LPARAM lPar)
{
  switch (Mess){
#ifndef ONEGAME
    case WM_CREATE:
    {
      char *Text=new char[200];
      strcpy(Text,T("Please wait..."));
      SetProp(Win,"NotifyText",Text);
      break;
    }
    case WM_PAINT:
    {
      HDC DC;
      RECT rc;
      char *Text;
      SIZE sz;

      GetClientRect(Win,&rc);

      DC=GetDC(Win);

      SelectObject(DC,GetStockObject(DEFAULT_GUI_FONT));

      HBRUSH br=CreateSolidBrush(GetSysColor(COLOR_BTNFACE));
      FillRect(DC,&rc,br);
      DeleteObject(br);

      SetBkMode(DC,TRANSPARENT);

      Text=(char*)GetProp(Win,"NotifyText");

      GetTextExtentPoint32(DC,Text,strlen(Text),&sz);
      TextOut(DC,(rc.right-sz.cx)/2,(rc.bottom-sz.cy)/2,Text,strlen(Text));

      ReleaseDC(Win,DC);
      ValidateRect(Win,NULL);
      return 0;
    }
    case WM_USER:
      if (wPar==12345){
        char *Text=(char*)GetProp(Win,"NotifyText"),*NewText=(char*)lPar;
        delete[] Text;

        Text=new char[strlen(NewText)+1];
        strcpy(Text,NewText);
        SetProp(Win,"NotifyText",Text);

        InvalidateRect(Win,NULL,1);
      }
      break;
    case WM_DESTROY:
      delete[] (char*)GetProp(Win,"NotifyText");
      RemoveProp(Win,"NotifyText");
      break;
#else
    case WM_PAINT:
    {
      HDC DC=GetDC(Win);
      RECT rc;
      GetClientRect(Win,&rc);
      FillRect(DC,&rc,(HBRUSH)GetStockObject(BLACK_BRUSH));
      ReleaseDC(Win,DC);
      ValidateRect(Win,NULL);
      return 0;
    }
    case WM_SETCURSOR:
      SetCursor(NULL);
      return TRUE;
/*
    case WM_CREATE:
    {
      HBITMAP bmp=LoadBitmap(Inst,RCNUM(2));
      HDC SrcDC=GetDC(NULL);
      HDC dc=CreateCompatibleDC(SrcDC);
      ReleaseDC(NULL,SrcDC);
      SelectObject(dc,bmp);
      SetProp(Win,"BitmapDC",dc);
      SetProp(Win,"BitmapBMP",bmp);
      break;
    }
    case WM_PAINT:
    {
      HDC dc=GetDC(Win);
      BitBlt(dc,0,0,320,200,(HDC)GetProp(Win,"BitmapDC"),0,0,SRCCOPY);
      ReleaseDC(Win,dc);
      ValidateRect(Win,NULL);
      return 0;
    }
    case WM_NCLBUTTONDOWN:case WM_NCRBUTTONDOWN:case WM_NCMBUTTONDOWN:
    case WM_NCLBUTTONUP:case WM_NCRBUTTONUP:case WM_NCMBUTTONUP:
      return 0;
    case WM_DESTROY:
      DeleteDC((HDC)GetProp(Win,"BitmapDC"));
      DeleteObject(GetProp(Win,"BitmapBMP"));
      RemoveProp(Win,"BitmapDC");
      RemoveProp(Win,"BitmapBMP");
      break;
*/
#endif
  }
	return DefWindowProc(Win,Mess,wPar,lPar);
}
示例#11
0
static INT_PTR CALLBACK NetworkOutputDlgProc(
    _In_ HWND hwndDlg,
    _In_ UINT uMsg,
    _In_ WPARAM wParam,
    _In_ LPARAM lParam
    )
{
    PNETWORK_OUTPUT_CONTEXT context;

    if (uMsg == WM_INITDIALOG)
    {
        context = (PNETWORK_OUTPUT_CONTEXT)lParam;
        SetProp(hwndDlg, L"Context", (HANDLE)context);
    }
    else
    {
        context = (PNETWORK_OUTPUT_CONTEXT)GetProp(hwndDlg, L"Context");

        if (uMsg == WM_DESTROY)
        {
            PhSaveWindowPlacementToSetting(SETTING_NAME_TRACERT_WINDOW_POSITION, SETTING_NAME_TRACERT_WINDOW_SIZE, hwndDlg);
            PhDeleteLayoutManager(&context->LayoutManager);

            if (context->ProcessHandle)
            {
                // Terminate the child process.
                PhTerminateProcess(context->ProcessHandle, STATUS_SUCCESS);

                // Close the child process handle.
                NtClose(context->ProcessHandle);
            }

            // Close the pipe handle.
            if (context->PipeReadHandle)
                NtClose(context->PipeReadHandle);

            RemoveProp(hwndDlg, L"Context");
            PhFree(context);
        }
    }

    if (!context)
        return FALSE;

    switch (uMsg)
    {
    case WM_INITDIALOG:
        {
            PH_RECTANGLE windowRectangle;

            context->WindowHandle = hwndDlg;
            context->OutputHandle = GetDlgItem(hwndDlg, IDC_NETOUTPUTEDIT);

            PhInitializeLayoutManager(&context->LayoutManager, hwndDlg);
            PhAddLayoutItem(&context->LayoutManager, context->OutputHandle, NULL, PH_ANCHOR_ALL);
            PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDC_MORE_INFO), NULL, PH_ANCHOR_BOTTOM | PH_ANCHOR_LEFT);
            PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDOK), NULL, PH_ANCHOR_BOTTOM | PH_ANCHOR_RIGHT);

            windowRectangle.Position = PhGetIntegerPairSetting(SETTING_NAME_TRACERT_WINDOW_POSITION);
            windowRectangle.Size = PhGetIntegerPairSetting(SETTING_NAME_TRACERT_WINDOW_SIZE);

            if (MinimumSize.left == -1)
            {
                RECT rect;

                rect.left = 0;
                rect.top = 0;
                rect.right = 190;
                rect.bottom = 120;
                MapDialogRect(hwndDlg, &rect);
                MinimumSize = rect;
                MinimumSize.left = 0;
            }

            // Check for first-run default position.
            if (windowRectangle.Position.X == 0 || windowRectangle.Position.Y == 0)
            {
                PhCenterWindow(hwndDlg, GetParent(hwndDlg));
            }
            else
            {
                PhLoadWindowPlacementFromSetting(SETTING_NAME_TRACERT_WINDOW_POSITION, SETTING_NAME_TRACERT_WINDOW_SIZE, hwndDlg);
            }

            if (context->IpAddress.Type == PH_IPV4_NETWORK_TYPE)
            {
                RtlIpv4AddressToString(&context->IpAddress.InAddr, context->IpAddressString);
            }
            else
            {
                RtlIpv6AddressToString(&context->IpAddress.In6Addr, context->IpAddressString);
            }

            switch (context->Action)
            {
            case NETWORK_ACTION_TRACEROUTE:
                {
                    HANDLE dialogThread = INVALID_HANDLE_VALUE;

                    Static_SetText(context->WindowHandle,
                        PhaFormatString(L"Tracing route to %s...", context->IpAddressString)->Buffer
                        );

                    if (dialogThread = PhCreateThread(0, NetworkTracertThreadStart, (PVOID)context))
                        NtClose(dialogThread);
                }
                break;
            case NETWORK_ACTION_WHOIS:
                {
                    HANDLE dialogThread = INVALID_HANDLE_VALUE;

                    Static_SetText(context->WindowHandle,
                        PhaFormatString(L"Whois %s...", context->IpAddressString)->Buffer
                        );

                    ShowWindow(GetDlgItem(hwndDlg, IDC_MORE_INFO), SW_SHOW);

                    if (dialogThread = PhCreateThread(0, NetworkWhoisThreadStart, (PVOID)context))
                        NtClose(dialogThread);
                }
                break;
            }
        }
        break;
    case WM_COMMAND:
        {
            switch (LOWORD(wParam))
            {
            case IDCANCEL:
            case IDOK:
                PostQuitMessage(0);
                break;
            }
        }
        break;
    case WM_SIZE:
        PhLayoutManagerLayout(&context->LayoutManager);
        break;
    case WM_SIZING:
        PhResizingMinimumSize((PRECT)lParam, wParam, MinimumSize.right, MinimumSize.bottom);
        break;
    case WM_CTLCOLORDLG:
    case WM_CTLCOLORSTATIC:
        {
            HDC hDC = (HDC)wParam;
            HWND hwndChild = (HWND)lParam;

            // Check if old graph colors are enabled.
            if (!PhGetIntegerSetting(L"GraphColorMode"))
                break;

            // Set a transparent background for the control backcolor.
            SetBkMode(hDC, TRANSPARENT);

            // Check for our edit control and change the color.
            if (hwndChild == context->OutputHandle)
            {
                // Set text color as the Green PH graph text color.
                SetTextColor(hDC, RGB(124, 252, 0));

                // Set a black control backcolor.
                return (INT_PTR)GetStockBrush(BLACK_BRUSH);
            }
        }
        break;
    case WM_NOTIFY:
        {
            switch (((LPNMHDR)lParam)->code)
            {
            case NM_CLICK:
            case NM_RETURN:
                {
                    PNMLINK syslink = (PNMLINK)lParam;

                    if (syslink->hdr.idFrom == IDC_MORE_INFO)
                    {
                        PhShellExecute(
                            PhMainWndHandle,
                            PhaConcatStrings2(L"http://wq.apnic.net/apnic-bin/whois.pl?searchtext=", context->IpAddressString)->Buffer,
                            NULL
                            );
                    }
                }
                break;
            }
        }
        break;
    case NTM_RECEIVEDTRACE:
        {
            OEM_STRING inputString;
            UNICODE_STRING convertedString;
            PH_STRING_BUILDER receivedString;

            if (wParam != 0)
            {
                inputString.Buffer = (PCHAR)lParam;
                inputString.Length = (USHORT)wParam;

                if (NT_SUCCESS(RtlOemStringToUnicodeString(&convertedString, &inputString, TRUE)))
                {
                    PPH_STRING windowText = NULL;

                    PhInitializeStringBuilder(&receivedString, PAGE_SIZE);

                    // Get the current output text.
                    windowText = PhGetWindowText(context->OutputHandle);

                    // Append the current output text to the New string.
                    if (!PhIsNullOrEmptyString(windowText))
                        PhAppendStringBuilder(&receivedString, windowText);

                    PhAppendFormatStringBuilder(&receivedString, L"%s", convertedString.Buffer);

                    // Remove leading newlines.
                    if (receivedString.String->Length >= 2 * 2 &&
                        receivedString.String->Buffer[0] == '\r' &&
                        receivedString.String->Buffer[1] == '\n')
                    {
                        PhRemoveStringBuilder(&receivedString, 0, 2);
                    }

                    SetWindowText(context->OutputHandle, receivedString.String->Buffer);
                    SendMessage(
                        context->OutputHandle,
                        EM_SETSEL,
                        receivedString.String->Length / 2 - 1,
                        receivedString.String->Length / 2 - 1
                        );
                    SendMessage(context->OutputHandle, WM_VSCROLL, SB_BOTTOM, 0);

                    PhDereferenceObject(windowText);
                    PhDeleteStringBuilder(&receivedString);
                    RtlFreeUnicodeString(&convertedString);
                }
            }
        }
        break;
    case NTM_RECEIVEDWHOIS:
        {
            OEM_STRING inputString;
            UNICODE_STRING convertedString;
            PH_STRING_BUILDER receivedString;

            if (lParam != 0)
            {
                inputString.Buffer = (PCHAR)lParam;
                inputString.Length = (USHORT)wParam;

                if (NT_SUCCESS(RtlOemStringToUnicodeString(&convertedString, &inputString, TRUE)))
                {
                    USHORT i;

                    PhInitializeStringBuilder(&receivedString, PAGE_SIZE);

                    // Convert carriage returns.
                    for (i = 0; i < convertedString.Length; i++)
                    {
                        if (convertedString.Buffer[i] == '\n')
                        {
                            PhAppendStringBuilder(&receivedString, PhaCreateString(L"\r\n"));
                        }
                        else
                        {
                            PhAppendCharStringBuilder(&receivedString, convertedString.Buffer[i]);
                        }
                    }

                    // Remove leading newlines.
                    if (receivedString.String->Length >= 2 * 2 &&
                        receivedString.String->Buffer[0] == '\r' &&
                        receivedString.String->Buffer[1] == '\n')
                    {
                        PhRemoveStringBuilder(&receivedString, 0, 2);
                    }

                    SetWindowText(context->OutputHandle, receivedString.String->Buffer);
                    SendMessage(
                        context->OutputHandle,
                        EM_SETSEL,
                        receivedString.String->Length / 2 - 1,
                        receivedString.String->Length / 2 - 1
                        );
                    SendMessage(context->OutputHandle, WM_VSCROLL, SB_TOP, 0);

                    PhDeleteStringBuilder(&receivedString);
                    RtlFreeUnicodeString(&convertedString);
                }

                PhFree((PVOID)lParam);
            }
        }
        break;
    case NTM_RECEIVEDFINISH:
        {
            PPH_STRING windowText = PhGetWindowText(context->WindowHandle);

            if (windowText)
            {
                Static_SetText(
                    context->WindowHandle,
                    PhaFormatString(L"%s Finished.", windowText->Buffer)->Buffer
                    );
                PhDereferenceObject(windowText);
            }
        }
        break;
    }

    return FALSE;
}
示例#12
0
LONG GetControlPtr(HWND hWnd)
  {
  long rVal  = MAKELONG((UINT)GetProp(hWnd, LOPTR), (UINT)GetProp(hWnd, HIPTR));
  return rVal;
  }
示例#13
0
/*
 * DialogProc for OpenVPN status dialog windows
 */
INT_PTR CALLBACK
StatusDialogFunc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
    connection_t *c;

    switch (msg)
    {
    case WM_MANAGEMENT:
        /* Management interface related event */
        OnManagement(wParam, lParam);
        return TRUE;

    case WM_INITDIALOG:
        c = (connection_t *) lParam;

        /* Set window icon "disconnected" */
        SetStatusWinIcon(hwndDlg, ID_ICO_CONNECTING);

        /* Set connection for this dialog */
        SetProp(hwndDlg, cfgProp, (HANDLE) c);

        /* Create log window */
        HWND hLogWnd = CreateWindowEx(0, RICHEDIT_CLASS, NULL,
            WS_CHILD|WS_VISIBLE|WS_HSCROLL|WS_VSCROLL|ES_SUNKEN|ES_LEFT|
            ES_MULTILINE|ES_READONLY|ES_AUTOHSCROLL|ES_AUTOVSCROLL,
            20, 25, 350, 160, hwndDlg, (HMENU) ID_EDT_LOG, o.hInstance, NULL);
        if (!hLogWnd)
        {
            ShowLocalizedMsg(IDS_ERR_CREATE_EDIT_LOGWINDOW);
            return FALSE;
        }

        /* Set font and fontsize of the log window */
        CHARFORMAT cfm = {
            .cbSize = sizeof(CHARFORMAT),
            .dwMask = CFM_SIZE|CFM_FACE|CFM_BOLD,
            .szFaceName = _T("Microsoft Sans Serif"),
            .dwEffects = 0,
            .yHeight = 160
        };
        if (SendMessage(hLogWnd, EM_SETCHARFORMAT, SCF_DEFAULT, (LPARAM) &cfm) == 0)
            ShowLocalizedMsg(IDS_ERR_SET_SIZE);

        /* Set size and position of controls */
        RECT rect;
        GetClientRect(hwndDlg, &rect);
        MoveWindow(hLogWnd, 20, 25, rect.right - 40, rect.bottom - 70, TRUE);
        MoveWindow(GetDlgItem(hwndDlg, ID_TXT_STATUS), 20, 5, rect.right - 25, 15, TRUE);
        MoveWindow(GetDlgItem(hwndDlg, ID_DISCONNECT), 20, rect.bottom - 30, 110, 23, TRUE);
        MoveWindow(GetDlgItem(hwndDlg, ID_RESTART), 145, rect.bottom - 30, 110, 23, TRUE);
        MoveWindow(GetDlgItem(hwndDlg, ID_HIDE), rect.right - 130, rect.bottom - 30, 110, 23, TRUE);

        /* Set focus on the LogWindow so it scrolls automatically */
        SetFocus(hLogWnd);
        return FALSE;

    case WM_SIZE:
        MoveWindow(GetDlgItem(hwndDlg, ID_EDT_LOG), 20, 25, LOWORD(lParam) - 40, HIWORD(lParam) - 70, TRUE);
        MoveWindow(GetDlgItem(hwndDlg, ID_DISCONNECT), 20, HIWORD(lParam) - 30, 110, 23, TRUE);
        MoveWindow(GetDlgItem(hwndDlg, ID_RESTART), 145, HIWORD(lParam) - 30, 110, 23, TRUE);
        MoveWindow(GetDlgItem(hwndDlg, ID_HIDE), LOWORD(lParam) - 130, HIWORD(lParam) - 30, 110, 23, TRUE);
        MoveWindow(GetDlgItem(hwndDlg, ID_TXT_STATUS), 20, 5, LOWORD(lParam) - 25, 15, TRUE);
        InvalidateRect(hwndDlg, NULL, TRUE);
        return TRUE;

    case WM_COMMAND:
        c = (connection_t *) GetProp(hwndDlg, cfgProp);
        switch (LOWORD(wParam))
        {
        case ID_DISCONNECT:
            SetFocus(GetDlgItem(c->hwndStatus, ID_EDT_LOG));
            StopOpenVPN(c);
            return TRUE;

        case ID_HIDE:
            if (c->state != disconnected)
                ShowWindow(hwndDlg, SW_HIDE);
            else
                DestroyWindow(hwndDlg);
            return TRUE;

        case ID_RESTART:
            c->state = reconnecting;
            SetFocus(GetDlgItem(c->hwndStatus, ID_EDT_LOG));
            ManagementCommand(c, "signal SIGHUP", NULL, regular);
            return TRUE;
        }
        break;

    case WM_SHOWWINDOW:
        if (wParam == TRUE)
        {
            c = (connection_t *) GetProp(hwndDlg, cfgProp);
            if (c->hwndStatus)
                SetFocus(GetDlgItem(c->hwndStatus, ID_EDT_LOG));
        }
        return FALSE;

    case WM_CLOSE:
        c = (connection_t *) GetProp(hwndDlg, cfgProp);
        if (c->state != disconnected)
            ShowWindow(hwndDlg, SW_HIDE);
        else
            DestroyWindow(hwndDlg);
        return TRUE;

    case WM_NCDESTROY:
        RemoveProp(hwndDlg, cfgProp);
        break;

    case WM_DESTROY:
        PostQuitMessage(0);
        break;

    case WM_OVPN_STOP:
        c = (connection_t *) GetProp(hwndDlg, cfgProp);
        c->state = disconnecting;
        RunDisconnectScript(c, false);
        EnableWindow(GetDlgItem(c->hwndStatus, ID_DISCONNECT), FALSE);
        EnableWindow(GetDlgItem(c->hwndStatus, ID_RESTART), FALSE);
        SetMenuStatus(c, disconnecting);
        SetDlgItemText(c->hwndStatus, ID_TXT_STATUS, LoadLocalizedString(IDS_NFO_STATE_WAIT_TERM));
        SetEvent(c->exit_event);
        SetTimer(hwndDlg, IDT_STOP_TIMER, 3000, NULL);
        break;

    case WM_OVPN_SUSPEND:
        c = (connection_t *) GetProp(hwndDlg, cfgProp);
        c->state = suspending;
        EnableWindow(GetDlgItem(c->hwndStatus, ID_DISCONNECT), FALSE);
        EnableWindow(GetDlgItem(c->hwndStatus, ID_RESTART), FALSE);
        SetMenuStatus(c, disconnecting);
        SetDlgItemText(c->hwndStatus, ID_TXT_STATUS, LoadLocalizedString(IDS_NFO_STATE_WAIT_TERM));
        SetEvent(c->exit_event);
        SetTimer(hwndDlg, IDT_STOP_TIMER, 3000, NULL);
        break;

    case WM_TIMER:
        PrintDebug(L"WM_TIMER message with wParam = %lu", wParam);
        c = (connection_t *) GetProp(hwndDlg, cfgProp);
        if (wParam == IDT_STOP_TIMER)
        {
            /* openvpn failed to respond to stop signal -- terminate */
            TerminateOpenVPN(c);
            KillTimer (hwndDlg, IDT_STOP_TIMER);
        }
        break;
    }
    return FALSE;
}

/*
 * ThreadProc for OpenVPN status dialog windows
 */
static DWORD WINAPI
ThreadOpenVPNStatus(void *p)
{
    connection_t *c = p;
    TCHAR conn_name[200];
    MSG msg;
    HANDLE wait_event;

    CLEAR (msg);

    /* Cut of extention from config filename. */
    _tcsncpy(conn_name, c->config_file, _countof(conn_name));
    conn_name[_tcslen(conn_name) - _tcslen(o.ext_string) - 1] = _T('\0');

    c->state = (c->state == suspended ? resuming : connecting);

    /* Create and Show Status Dialog */
    c->hwndStatus = CreateLocalizedDialogParam(ID_DLG_STATUS, StatusDialogFunc, (LPARAM) c);
    if (!c->hwndStatus)
        return 1;

    CheckAndSetTrayIcon();
    SetMenuStatus(c, connecting);
    SetDlgItemText(c->hwndStatus, ID_TXT_STATUS, LoadLocalizedString(IDS_NFO_STATE_CONNECTING));
    SetWindowText(c->hwndStatus, LoadLocalizedString(IDS_NFO_CONNECTION_XXX, conn_name));

    if (!OpenManagement(c))
        PostMessage(c->hwndStatus, WM_CLOSE, 0, 0);

    /* Start the async read loop for service and set it as the wait event */
    if (c->iserv.hEvent)
    {
        HandleServiceIO (0, 0, (LPOVERLAPPED) &c->iserv);
        wait_event = c->iserv.hEvent;
    }
    else
        wait_event = c->hProcess;

    if (o.silent_connection == 0)
        ShowWindow(c->hwndStatus, SW_SHOW);

    /* Run the message loop for the status window */
    while (WM_QUIT != msg.message)
    {
        DWORD res;
        if (!PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
        {
            if ((res = MsgWaitForMultipleObjectsEx (1, &wait_event, INFINITE, QS_ALLINPUT,
                                         MWMO_ALERTABLE)) == WAIT_OBJECT_0)
            {
                if (wait_event == c->hProcess)
                    OnProcess (c, NULL);
                else if (wait_event == c->iserv.hEvent)
                    OnService (c, NULL);
            }
            continue;
        }

        if (IsDialogMessage(c->hwndStatus, &msg) == 0)
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }

    /* release handles etc.*/
    Cleanup (c);
    c->hwndStatus = NULL;
    return 0;
}
示例#14
0
/*
 * DialogProc for OpenVPN private key password dialog windows
 */
INT_PTR CALLBACK
PrivKeyPassDialogFunc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
    connection_t *c;
    WCHAR passphrase[KEY_PASS_LEN];

    switch (msg)
    {
    case WM_INITDIALOG:
        /* Set connection for this dialog and show it */
        c = (connection_t *) lParam;
        SetProp(hwndDlg, cfgProp, (HANDLE) c);
        if (RecallKeyPass(c->config_name, passphrase) && wcslen(passphrase))
        {
            /* Use the saved password and skip the dialog */
            SetDlgItemTextW(hwndDlg, ID_EDT_PASSPHRASE, passphrase);
            SecureZeroMemory(passphrase, sizeof(passphrase));
            ManagementCommandFromInput(c, "password \"Private Key\" \"%s\"", hwndDlg, ID_EDT_PASSPHRASE);
            EndDialog(hwndDlg, IDOK);
            return TRUE;
        }
        if (c->flags & FLAG_SAVE_KEY_PASS)
            Button_SetCheck (GetDlgItem (hwndDlg, ID_CHK_SAVE_PASS), BST_CHECKED);
        if (c->state == resuming)
            ForceForegroundWindow(hwndDlg);
        else
            SetForegroundWindow(hwndDlg);
        break;

    case WM_COMMAND:
        c = (connection_t *) GetProp(hwndDlg, cfgProp);
        switch (LOWORD(wParam))
        {
        case ID_CHK_SAVE_PASS:
            c->flags ^= FLAG_SAVE_KEY_PASS;
            if (c->flags & FLAG_SAVE_KEY_PASS)
                Button_SetCheck (GetDlgItem (hwndDlg, ID_CHK_SAVE_PASS), BST_CHECKED);
            else
            {
                Button_SetCheck (GetDlgItem (hwndDlg, ID_CHK_SAVE_PASS), BST_UNCHECKED);
                DeleteSavedKeyPass(c->config_name);
            }
            break;

        case IDOK:
            if ((c->flags & FLAG_SAVE_KEY_PASS) &&
                GetDlgItemTextW(hwndDlg, ID_EDT_PASSPHRASE, passphrase, _countof(passphrase)) &&
                wcslen(passphrase) > 0)
            {
                SaveKeyPass(c->config_name, passphrase);
                SecureZeroMemory(passphrase, sizeof(passphrase));
            }
            ManagementCommandFromInput(c, "password \"Private Key\" \"%s\"", hwndDlg, ID_EDT_PASSPHRASE);
            EndDialog(hwndDlg, LOWORD(wParam));
            return TRUE;

        case IDCANCEL:
            EndDialog(hwndDlg, LOWORD(wParam));
            StopOpenVPN (c);
            return TRUE;
        }
        break;

    case WM_CLOSE:
        EndDialog(hwndDlg, LOWORD(wParam));
        return TRUE;

    case WM_NCDESTROY:
        RemoveProp(hwndDlg, cfgProp);
        break;
  }
  return FALSE;
}
示例#15
0
LRESULT WINAPI _afxWndUltimate(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
	WndUltimate*pWindow=(WndUltimate*)GetProp(hWnd,__UMyProp__);
	return(pWindow->_Main(uMsg,wParam,lParam));
}
示例#16
0
BOOL CFileExplore::OnInitDialog() 
{
	CResizableDialog::OnInitDialog();

	//m_CheckHeader.Create(IDB_TRAYSTATUS_BITMAP,16,0,0xFF00FF);
	//m_FileList.GetHeaderCtrl()->SetImageList(&m_CheckHeader);
	m_SortHeader.SubclassWindow(m_FileList.GetHeaderCtrl()->GetSafeHwnd());

	m_iSortingMode	= GetOptionInt(IDS_OFSMESSENGER,IDS_FILEL,1);

	m_hSplitter = AfxGetApp()->LoadCursor(IDC_SPLITH);

	ShowSizeGrip(FALSE);
	
	//m_FileList.SetExtendedStyle (m_FileList.GetExtendedStyle ()|LVS_EX_FULLROWSELECT);

	m_FileList.SetImageList(CImageList::FromHandle(GetSystemImageList(TRUE)),LVSIL_SMALL);

	CString strSection = GetString(IDS_OFSMESSENGER);
	CString strEntry = GetString(IDS_COLUMN_WIDTH);

	m_FileList.InsertColumn(0,GetString(IDS_FILENAME_NAME),LVCFMT_LEFT,AfxGetApp()->GetProfileInt(strSection, strEntry+_T("30"), 150));
	m_FileList.InsertColumn(1,GetString(IDS_FILESIZE_NAME),LVCFMT_RIGHT,AfxGetApp()->GetProfileInt(strSection, strEntry+_T("33"), 80),3);
	m_FileList.InsertColumn(2,GetString(IDS_FILETYPE_NAME),LVCFMT_LEFT,AfxGetApp()->GetProfileInt(strSection, strEntry+_T("32"), 130),2);
	m_FileList.InsertColumn(3,GetString(IDS_FILEMODIFIED_NAME),LVCFMT_LEFT,AfxGetApp()->GetProfileInt(strSection, strEntry+_T("31"), 125),1);
	

	m_DirTree.SetImageList(CImageList::FromHandle(GetSystemImageList(TRUE)),TVSIL_NORMAL);

	//m_hRoot	=	CreateTreeItem(TVI_ROOT,GetString(IDS_MYDOCUMENTS));
	//LoadTreeByPath(m_hRoot,m_strStartFolder);
	//m_DirTree.Expand(m_hRoot,TVE_EXPAND);

/*	CString	strDefaultPath = GetDefaultPath();
	CString strPathAddon	=	GetStartFolder();
	while(!strDefaultPath.IsEmpty())
	{
		int Pos = strDefaultPath.Find(_T('\\'));
		if(Pos==-1)
		{
			strPathAddon += _T('\\')+strDefaultPath;
		}
		else
		{
			strPathAddon += _T('\\')+strDefaultPath.Left(Pos);
			strDefaultPath = strDefaultPath.Mid(Pos+1);
		}
		LoadTreeByPath(m_hRoot,m_strStartFolder);
	}*/

	AddAnchor(&m_DirTree,CSize(0,0),CSize(0,100));
	AddAnchor(&m_VSplitter,CSize(0,0),CSize(0,100));
	AddAnchor(&m_FileList,CSize(0,0),CSize(100,100));

	HANDLE hHanle1 = GetProp(m_FileList.GetSafeHwnd(),(LPCTSTR)(DWORD)0xC01C);
	
	m_OleFileListDropTarget.Register(&m_FileList);
	m_OleDirTreeDropTarget.Register(&m_DirTree);
	
	return TRUE;  // return TRUE unless you set the focus to a control
	              // EXCEPTION: OCX Property Pages should return FALSE
}
示例#17
0
LRESULT CALLBACK SubclassProc(
    HWND hWnd,
    UINT uMsg,
    WPARAM wParam,
    LPARAM lParam,
    UINT_PTR uIdSubclass,
    DWORD_PTR dwRefData
)
{
	switch(uMsg)
	{
	case WM_NCDESTROY:
		{
			UINT uId = (UINT) GetProp(hWnd, gszSubclassProp);
			if(uId != 0)
			{
				RemoveProp(hWnd, gszSubclassProp);
				RemoveWindowSubclass(hWnd, SubclassProc, guIdSubclass);
			}
		}
		break;

	case WM_PARENTNOTIFY:
		if(LOWORD(wParam) == WM_CREATE)
		{
			bool bSubclass = true;

			// We stop at "Internet Explorer_Server
			TCHAR szClassName[MAX_PATH];
			if ( GetClassName( hWnd, szClassName, ARRAYSIZE(szClassName) ) > 0 )
			{
				if ( _tcscmp(szClassName, _T("Internet Explorer_Server")) == 0 )
				{
					bSubclass = false;
				}
			}

			if(bSubclass)
			{
				HWND hWndChild = (HWND) lParam;
				UINT uId = (UINT) GetProp(hWndChild, gszSubclassProp);
				ATLASSERT(uId == 0);
				if(uId == 0)
				{
					AttachAll(hWndChild);
				}
			}
		}
		break;

	case WM_KEYDOWN:
	case WM_SYSKEYDOWN:
		{
			CWebBrowserCtrl* wb = WebBrowserFromHandle(hWnd);
			if(wb)
			{
				if( (uMsg == WM_KEYDOWN || uMsg == WM_SYSKEYDOWN) &&
					( HIBYTE(GetKeyState(VK_CONTROL)) || // Ctrl is pressed
					  HIBYTE(GetKeyState(VK_MENU)) || // Alt is pressed
					  ((wParam >= VK_F1) && (wParam <= VK_F24)) // Function-Keys is pressed
					)
				  )
				{
					// Redirect to browser
					::PostMessage( ::GetParent(::GetParent(::GetParent(::GetParent(wb->m_hWnd)))), uMsg, wParam, lParam );
				}
			}
		}
		break;
	}

	return DefSubclassProc(hWnd, uMsg, wParam, lParam);
}
示例#18
0
static INT_PTR CALLBACK PhpNetworkStackDlgProc(
    _In_ HWND hwndDlg,
    _In_ UINT uMsg,
    _In_ WPARAM wParam,
    _In_ LPARAM lParam
    )
{
    switch (uMsg)
    {
    case WM_INITDIALOG:
        {
            PNETWORK_STACK_CONTEXT networkStackContext;
            HWND lvHandle;
            PPH_LAYOUT_MANAGER layoutManager;
            PVOID address;
            ULONG i;

            PhCenterWindow(hwndDlg, GetParent(hwndDlg));

            networkStackContext = (PNETWORK_STACK_CONTEXT)lParam;
            SetProp(hwndDlg, PhMakeContextAtom(), (HANDLE)networkStackContext);

            lvHandle = GetDlgItem(hwndDlg, IDC_LIST);
            PhAddListViewColumn(lvHandle, 0, 0, 0, LVCFMT_LEFT, 350, L"Name");
            PhSetListViewStyle(lvHandle, FALSE, TRUE);
            PhSetControlTheme(lvHandle, L"explorer");

            networkStackContext->ListViewHandle = lvHandle;

            layoutManager = PhAllocate(sizeof(PH_LAYOUT_MANAGER));
            PhInitializeLayoutManager(layoutManager, hwndDlg);
            SetProp(hwndDlg, L"LayoutManager", (HANDLE)layoutManager);

            PhAddLayoutItem(layoutManager, lvHandle, NULL,
                PH_ANCHOR_ALL);
            PhAddLayoutItem(layoutManager, GetDlgItem(hwndDlg, IDOK),
                NULL, PH_ANCHOR_RIGHT | PH_ANCHOR_BOTTOM);

            if (MinimumSize.left == -1)
            {
                RECT rect;

                rect.left = 0;
                rect.top = 0;
                rect.right = 190;
                rect.bottom = 120;
                MapDialogRect(hwndDlg, &rect);
                MinimumSize = rect;
                MinimumSize.left = 0;
            }

            for (i = 0; i < PH_NETWORK_OWNER_INFO_SIZE; i++)
            {
                PPH_STRING name;

                address = *(PVOID *)&networkStackContext->NetworkItem->OwnerInfo[i];

                if ((ULONG_PTR)address < PAGE_SIZE) // stop at an invalid address
                    break;

                name = PhGetSymbolFromAddress(
                    networkStackContext->SymbolProvider,
                    (ULONG64)address,
                    NULL,
                    NULL,
                    NULL,
                    NULL
                    );
                PhAddListViewItem(lvHandle, MAXINT, name->Buffer, NULL);
                PhDereferenceObject(name);
            }
        }
        break;
    case WM_DESTROY:
        {
            PPH_LAYOUT_MANAGER layoutManager;
            PNETWORK_STACK_CONTEXT networkStackContext;

            layoutManager = (PPH_LAYOUT_MANAGER)GetProp(hwndDlg, L"LayoutManager");
            PhDeleteLayoutManager(layoutManager);
            PhFree(layoutManager);

            networkStackContext = (PNETWORK_STACK_CONTEXT)GetProp(hwndDlg, PhMakeContextAtom());

            RemoveProp(hwndDlg, PhMakeContextAtom());
            RemoveProp(hwndDlg, L"LayoutManager");
        }
        break;
    case WM_COMMAND:
        {
            INT id = LOWORD(wParam);

            switch (id)
            {
            case IDCANCEL: // Esc and X button to close
            case IDOK:
                EndDialog(hwndDlg, IDOK);
                break;
            }
        }
        break;
    case WM_SIZE:
        {
            PPH_LAYOUT_MANAGER layoutManager;

            layoutManager = (PPH_LAYOUT_MANAGER)GetProp(hwndDlg, L"LayoutManager");
            PhLayoutManagerLayout(layoutManager);
        }
        break;
    case WM_SIZING:
        {
            PhResizingMinimumSize((PRECT)lParam, wParam, MinimumSize.right, MinimumSize.bottom);
        }
        break;
    }

    return FALSE;
}
LRESULT CALLBACK LinkLabelMsgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	switch (message)
	{
	case WM_KILLFOCUS:
		::RedrawWindow(hwnd, 0, 0, RDW_INVALIDATE);
		break;

	case WM_SETFOCUS:
		{
			RECT rc;
			HDC dc = ::GetDC(hwnd);
			::GetClientRect(hwnd, &rc);
			::DrawFocusRect(dc, &rc);
			::ReleaseDC(hwnd, dc);
		}
		break;

	case WM_MOUSEMOVE:
		if (GetCapture() != hwnd)
		{
			SendMessage(hwnd, WM_SETFONT, (WPARAM)GetProp(hwnd, TEXT("Underline")), TRUE);
			SetCapture(hwnd);
		}
		else
		{
			RECT rc;
			GetWindowRect(hwnd, &rc);
			POINT p = { LOWORD(lParam), HIWORD(lParam) };
			ClientToScreen(hwnd, &p);
			if (!PtInRect(&rc, p)) ReleaseCapture();
		}
		break;

	case WM_CAPTURECHANGED:
		SendMessage(hwnd, WM_SETFONT, (WPARAM)GetProp(hwnd, TEXT("BaseFont")), TRUE);
		break;

	case WM_SETCURSOR:
		{
			HCURSOR hand = (HCURSOR)LoadImage(0, IDC_HAND, IMAGE_CURSOR, 0, 0, LR_SHARED);
			if (hand) SetCursor(hand);
			return TRUE;
		}
		break;

	case WM_KEYUP:
		if (wParam != VK_SPACE) break;

	case WM_LBUTTONUP:
		{
			WCHAR *wc = (WCHAR*)GetProp(hwnd, TEXT("Link"));
			if ( wc ) ShellExecute(0, 0, wc, 0, 0, SW_SHOWNORMAL);
		}
		break;

	case WM_DESTROY:
		{
			WCHAR *wc = (WCHAR*)GetProp(hwnd, TEXT("Link"));
			if (wc) delete [] wc;
			RemoveProp(hwnd, TEXT("Link"));
			RemoveProp(hwnd, TEXT("BaseFont"));
			HFONT underline = (HFONT)GetProp(hwnd, TEXT("Underline"));
			::DeleteObject(underline);
			RemoveProp(hwnd, TEXT("Underline"));
		}
		break;
	}

	WNDPROC base = (WNDPROC)GetProp( hwnd, TEXT("BaseWndProc"));
	return CallWindowProc(base, hwnd, message, wParam, lParam);
}
示例#20
0
LRESULT CALLBACK _HyperlinkProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	WNDPROC pfnOrigProc = (WNDPROC) GetProp(hwnd, PROP_ORIGINAL_PROC);

	switch (message)
	{
	case WM_DESTROY:
		{
			SetWindowLong(hwnd, GWL_WNDPROC, (LONG) pfnOrigProc);
			RemoveProp(hwnd, PROP_ORIGINAL_PROC);

			HFONT hOrigFont = (HFONT) GetProp(hwnd, PROP_ORIGINAL_FONT);
			SendMessage(hwnd, WM_SETFONT, (WPARAM) hOrigFont, 0);
			RemoveProp(hwnd, PROP_ORIGINAL_FONT);

			HFONT hFont = (HFONT) GetProp(hwnd, PROP_UNDERLINE_FONT);
			DeleteObject(hFont);
			RemoveProp(hwnd, PROP_UNDERLINE_FONT);

			RemoveProp(hwnd, PROP_STATIC_HYPERLINK);

			break;
		}
	case WM_MOUSEMOVE:
		{
			if (GetCapture() != hwnd)
			{
				HFONT hFont = (HFONT) GetProp(hwnd, PROP_UNDERLINE_FONT);
				SendMessage(hwnd, WM_SETFONT, (WPARAM) hFont, FALSE);
				InvalidateRect(hwnd, NULL, FALSE);
				SetCapture(hwnd);
			}
			else
			{
				RECT rect;
				GetWindowRect(hwnd, &rect);

				POINT pt = { LOWORD(lParam), HIWORD(lParam) };
				ClientToScreen(hwnd, &pt);

				if (!PtInRect(&rect, pt))
				{
					HFONT hFont = (HFONT) GetProp(hwnd, PROP_ORIGINAL_FONT);
					SendMessage(hwnd, WM_SETFONT, (WPARAM) hFont, FALSE);
					InvalidateRect(hwnd, NULL, FALSE);
					ReleaseCapture();
				}
			}
			break;
		}
	case WM_SETCURSOR:
		{
			// Since IDC_HAND is not available on all operating systems,
			// we will load the arrow cursor if IDC_HAND is not present.
			HCURSOR hCursor = LoadCursor(NULL, MAKEINTRESOURCE(IDC_HAND));
			if (NULL == hCursor)
			{
				hCursor = LoadCursor(NULL, MAKEINTRESOURCE(IDC_ARROW));
			}
			SetCursor(hCursor);
			return TRUE;
		}
	}

	return CallWindowProc(pfnOrigProc, hwnd, message, wParam, lParam);
}
示例#21
0
DWORD WINAPI listDirectoryToPanelWorker (void* args)
{
	BOOL isUpDirPresent;		// Флаг, обозначает то что переход на дирректорию выше найден
	LTPD* ltpd = (LTPD*) args;
	TCHAR str [FM_MAX_PATH];
	str [0] = L'\0';
	HIMAGELIST hIL = NULL;
		
	LVITEM lvI = {0};
	lvI.pszText = str;
	lvI.cchTextMax = sizeof(str) / sizeof (str[0]);
	
	// Очистить панель от своих данных
	lvI.mask = LVIF_PARAM; 
	BOOL rc = TRUE;
	while (rc)
	{
		rc = SendDlgItemMessage (ltpd->hDlg, ltpd->itemId, LVM_GETITEM, 0, (LPARAM)&lvI);
		if (rc)
		{
			if (lvI.lParam != NULL)
			{
				fmLocalFree ((HLOCAL)lvI.lParam);
			}
			lvI.lParam = NULL;
			++ lvI.iItem;
		}
	}
	
	lvI.mask = LVIF_TEXT | LVIF_IMAGE;
	
	lvI.iItem = 0;
	lvI.lParam = 0;
		
	SendDlgItemMessage (ltpd->hDlg, ltpd->itemId, LVM_DELETEALLITEMS, 0, 0);
	
	hIL = (HIMAGELIST) SendDlgItemMessage (ltpd->hDlg, ltpd->itemId, LVM_GETIMAGELIST, (WPARAM)LVSIL_SMALL, 0);
	if (hIL == NULL)
	{
		hIL = ImageList_Create (16, 16, ILC_COLORDDB, 255, 1);
		SendDlgItemMessage (ltpd->hDlg, ltpd->itemId, LVM_SETIMAGELIST, LVSIL_SMALL, (LPARAM) hIL);
	}
	else
	{
		ImageList_RemoveAll (hIL);
	}
	
	WIN32_FIND_DATA findData = {0};

	wsprintf (str, L"%s%s", ltpd->path, L"\\*");
	HANDLE hFFile = FindFirstFile (str, &findData);
	if (hFFile != INVALID_HANDLE_VALUE)
	{	
		isUpDirPresent = findData.cFileName[0] == L'.';
		isUpDirPresent &= findData.cFileName[1] == L'.';
		isUpDirPresent &= findData.cFileName[2] == L'\0';

		if (FM_AFTLV_OK == addFileToListView (ltpd->hDlg, &findData, ltpd->itemId, &lvI))
		{
			setFileIcon (ltpd->hDlg, ltpd->path, &findData, &lvI, hIL);
			lvI.mask = LVIF_IMAGE;
			SendDlgItemMessage (ltpd->hDlg, ltpd->itemId, LVM_SETITEM, 0, (LPARAM)&lvI); 
			// Перейти к следующей строке
			++ lvI.iItem;
		}
		while (FindNextFile (hFFile, &findData))
		{
			if (!isUpDirPresent)
			{
				if (lstrcmp (findData.cFileName, L"..") == 0)
				{
					isUpDirPresent = TRUE;
				}
			}
			if (FM_AFTLV_OK == addFileToListView (ltpd->hDlg, &findData, ltpd->itemId, &lvI))
			{	
				setFileIcon (ltpd->hDlg, ltpd->path, &findData, &lvI, hIL);
				lvI.mask = LVIF_IMAGE;
				SendDlgItemMessage (ltpd->hDlg, ltpd->itemId, LVM_SETITEM, 0, (LPARAM)&lvI); 
				++ lvI.iItem;
			}
		}
		FindClose (hFFile);
	}
	else // Возникла ошибка
	{
		// Показать List View
		wprintfd (L"Возникла ошибка при FindFirstFile('%s', ...)", str);
		SendMessage (ltpd->hDlg, FM_LIST_FINISHED, ltpd->itemId, (LPARAM)ltpd);
		return 1;
	}
		
	// Символ L".." не был найден, значит его надо вставить
	if (!isUpDirPresent) 
	{	
		// Имя файла L".." и соответствующая иконка
		HINSTANCE hInst = (HINSTANCE) GetWindowLong (ltpd->hDlg, GWL_HINSTANCE);
		HICON hIcon = LoadIcon (hInst, MAKEINTRESOURCE (IDI_ICON1));
		lvI.iItem = 0; // L".." всегда в первой строке
		lvI.iImage = ImageList_ReplaceIcon (hIL, lvI.iItem, hIcon);
		lvI.iSubItem = FM_COLUMN_NAME;	// Колонка названия файлов
		lvI.pszText = L"..";
		lvI.lParam = NULL;
		SendDlgItemMessage (ltpd->hDlg, ltpd->itemId, LVM_INSERTITEM, (WPARAM)0, (LPARAM)&lvI);
		DestroyIcon (hIcon);
	}
	
	
	// Сортировать панель
	FmPanelProps* props = (FmPanelProps*)GetProp (GetDlgItem(ltpd->hDlg, ltpd->itemId), L"Props");
	NMLISTVIEW nmlv = {0};
	nmlv.iSubItem = props->sortColumnIndex;

	lvI.mask = LVIF_IMAGE;
	DWORD cnt = SendDlgItemMessage(ltpd->hDlg, ltpd->itemId, LVM_GETITEMCOUNT, 0, 0);
	for (lvI.iItem = 0; lvI.iItem < cnt; ++ lvI.iItem)
	{
		SendDlgItemMessage (ltpd->hDlg, ltpd->itemId, LVM_GETITEM,0, (LPARAM) &lvI);
		wprintfd(L"item:%u image:%u", lvI.iItem, lvI.iImage);
	}
	SendMessage (ltpd->hDlg, FM_LIST_FINISHED, ltpd->itemId, (LPARAM)ltpd);
	return 0;
}
示例#22
0
static INT_PTR CALLBACK PhpThreadStackDlgProc(
    _In_ HWND hwndDlg,
    _In_ UINT uMsg,
    _In_ WPARAM wParam,
    _In_ LPARAM lParam
    )
{
    switch (uMsg)
    {
    case WM_INITDIALOG:
        {
            NTSTATUS status;
            PTHREAD_STACK_CONTEXT threadStackContext;
            PPH_STRING title;
            HWND lvHandle;
            PPH_LAYOUT_MANAGER layoutManager;

            threadStackContext = (PTHREAD_STACK_CONTEXT)lParam;
            SetProp(hwndDlg, PhMakeContextAtom(), (HANDLE)threadStackContext);

            title = PhFormatString(L"Stack - thread %u", (ULONG)threadStackContext->ThreadId);
            SetWindowText(hwndDlg, title->Buffer);
            PhDereferenceObject(title);

            lvHandle = GetDlgItem(hwndDlg, IDC_LIST);
            PhAddListViewColumn(lvHandle, 0, 0, 0, LVCFMT_LEFT, 30, L" ");
            PhAddListViewColumn(lvHandle, 1, 1, 1, LVCFMT_LEFT, 300, L"Name");
            PhSetListViewStyle(lvHandle, FALSE, TRUE);
            PhSetControlTheme(lvHandle, L"explorer");
            PhLoadListViewColumnsFromSetting(L"ThreadStackListViewColumns", lvHandle);

            threadStackContext->ListViewHandle = lvHandle;

            layoutManager = PhAllocate(sizeof(PH_LAYOUT_MANAGER));
            PhInitializeLayoutManager(layoutManager, hwndDlg);
            SetProp(hwndDlg, L"LayoutManager", (HANDLE)layoutManager);

            PhAddLayoutItem(layoutManager, lvHandle, NULL,
                PH_ANCHOR_ALL);
            PhAddLayoutItem(layoutManager, GetDlgItem(hwndDlg, IDC_COPY),
                NULL, PH_ANCHOR_RIGHT | PH_ANCHOR_BOTTOM);
            PhAddLayoutItem(layoutManager, GetDlgItem(hwndDlg, IDC_REFRESH),
                NULL, PH_ANCHOR_RIGHT | PH_ANCHOR_BOTTOM);
            PhAddLayoutItem(layoutManager, GetDlgItem(hwndDlg, IDOK),
                NULL, PH_ANCHOR_RIGHT | PH_ANCHOR_BOTTOM);

            if (MinimumSize.left == -1)
            {
                RECT rect;

                rect.left = 0;
                rect.top = 0;
                rect.right = 190;
                rect.bottom = 120;
                MapDialogRect(hwndDlg, &rect);
                MinimumSize = rect;
                MinimumSize.left = 0;
            }

            PhLoadWindowPlacementFromSetting(NULL, L"ThreadStackWindowSize", hwndDlg);
            PhCenterWindow(hwndDlg, GetParent(hwndDlg));

            if (PhPluginsEnabled)
            {
                PH_PLUGIN_THREAD_STACK_CONTROL control;

                control.Type = PluginThreadStackInitializing;
                control.UniqueKey = threadStackContext;
                control.u.Initializing.ProcessId = threadStackContext->ProcessId;
                control.u.Initializing.ThreadId = threadStackContext->ThreadId;
                control.u.Initializing.ThreadHandle = threadStackContext->ThreadHandle;
                control.u.Initializing.SymbolProvider = threadStackContext->SymbolProvider;
                control.u.Initializing.CustomWalk = FALSE;
                PhInvokeCallback(PhGetGeneralCallback(GeneralCallbackThreadStackControl), &control);

                threadStackContext->CustomWalk = control.u.Initializing.CustomWalk;
            }

            status = PhpRefreshThreadStack(hwndDlg, threadStackContext);

            if (status == STATUS_ABANDONED)
                EndDialog(hwndDlg, IDCANCEL);
            else if (!NT_SUCCESS(status))
                PhShowStatus(hwndDlg, L"Unable to load the stack", status, 0);
        }
        break;
    case WM_DESTROY:
        {
            PPH_LAYOUT_MANAGER layoutManager;
            PTHREAD_STACK_CONTEXT threadStackContext;
            ULONG i;

            layoutManager = (PPH_LAYOUT_MANAGER)GetProp(hwndDlg, L"LayoutManager");
            PhDeleteLayoutManager(layoutManager);
            PhFree(layoutManager);

            threadStackContext = (PTHREAD_STACK_CONTEXT)GetProp(hwndDlg, PhMakeContextAtom());

            if (PhPluginsEnabled)
            {
                PH_PLUGIN_THREAD_STACK_CONTROL control;

                control.Type = PluginThreadStackUninitializing;
                control.UniqueKey = threadStackContext;
                PhInvokeCallback(PhGetGeneralCallback(GeneralCallbackThreadStackControl), &control);
            }

            for (i = 0; i < threadStackContext->List->Count; i++)
                PhpFreeThreadStackItem(threadStackContext->List->Items[i]);

            PhSaveListViewColumnsToSetting(L"ThreadStackListViewColumns", GetDlgItem(hwndDlg, IDC_LIST));
            PhSaveWindowPlacementToSetting(NULL, L"ThreadStackWindowSize", hwndDlg);

            RemoveProp(hwndDlg, PhMakeContextAtom());
            RemoveProp(hwndDlg, L"LayoutManager");
        }
        break;
    case WM_COMMAND:
        {
            INT id = LOWORD(wParam);

            switch (id)
            {
            case IDCANCEL: // Esc and X button to close
            case IDOK:
                EndDialog(hwndDlg, IDOK);
                break;
            case IDC_REFRESH:
                {
                    NTSTATUS status;

                    if (!NT_SUCCESS(status = PhpRefreshThreadStack(
                        hwndDlg,
                        (PTHREAD_STACK_CONTEXT)GetProp(hwndDlg, PhMakeContextAtom())
                        )))
                    {
                        PhShowStatus(hwndDlg, L"Unable to load the stack", status, 0);
                    }
                }
                break;
            case IDC_COPY:
                {
                    HWND lvHandle;

                    lvHandle = GetDlgItem(hwndDlg, IDC_LIST);

                    if (ListView_GetSelectedCount(lvHandle) == 0)
                        PhSetStateAllListViewItems(lvHandle, LVIS_SELECTED, LVIS_SELECTED);

                    PhCopyListView(lvHandle);
                    SetFocus(lvHandle);
                }
                break;
            }
        }
        break;
    case WM_NOTIFY:
        {
            LPNMHDR header = (LPNMHDR)lParam;

            switch (header->code)
            {
            case LVN_GETINFOTIP:
                {
                    LPNMLVGETINFOTIP getInfoTip = (LPNMLVGETINFOTIP)header;
                    HWND lvHandle;
                    PTHREAD_STACK_CONTEXT threadStackContext;

                    lvHandle = GetDlgItem(hwndDlg, IDC_LIST);
                    threadStackContext = (PTHREAD_STACK_CONTEXT)GetProp(hwndDlg, PhMakeContextAtom());

                    if (header->hwndFrom == lvHandle)
                    {
                        PTHREAD_STACK_ITEM stackItem;
                        PPH_THREAD_STACK_FRAME stackFrame;

                        if (PhGetListViewItemParam(lvHandle, getInfoTip->iItem, &stackItem))
                        {
                            PH_STRING_BUILDER stringBuilder;
                            PPH_STRING fileName;
                            PH_SYMBOL_LINE_INFORMATION lineInfo;

                            stackFrame = &stackItem->StackFrame;
                            PhInitializeStringBuilder(&stringBuilder, 40);

                            // There are no params for kernel-mode stack traces.
                            if ((ULONG_PTR)stackFrame->PcAddress <= PhSystemBasicInformation.MaximumUserModeAddress)
                            {
                                PhAppendFormatStringBuilder(
                                    &stringBuilder,
                                    L"Parameters: 0x%Ix, 0x%Ix, 0x%Ix, 0x%Ix\n",
                                    stackFrame->Params[0],
                                    stackFrame->Params[1],
                                    stackFrame->Params[2],
                                    stackFrame->Params[3]
                                    );
                            }

                            if (PhGetLineFromAddress(
                                threadStackContext->SymbolProvider,
                                (ULONG64)stackFrame->PcAddress,
                                &fileName,
                                NULL,
                                &lineInfo
                                ))
                            {
                                PhAppendFormatStringBuilder(
                                    &stringBuilder,
                                    L"File: %s: line %u\n",
                                    fileName->Buffer,
                                    lineInfo.LineNumber
                                    );
                                PhDereferenceObject(fileName);
                            }

                            if (stringBuilder.String->Length != 0)
                                PhRemoveStringBuilder(&stringBuilder, stringBuilder.String->Length / 2 - 1, 1);

                            if (PhPluginsEnabled)
                            {
                                PH_PLUGIN_THREAD_STACK_CONTROL control;

                                control.Type = PluginThreadStackGetTooltip;
                                control.UniqueKey = threadStackContext;
                                control.u.GetTooltip.StackFrame = stackFrame;
                                control.u.GetTooltip.StringBuilder = &stringBuilder;
                                PhInvokeCallback(PhGetGeneralCallback(GeneralCallbackThreadStackControl), &control);
                            }

                            PhCopyListViewInfoTip(getInfoTip, &stringBuilder.String->sr);
                            PhDeleteStringBuilder(&stringBuilder);
                        }
                    }
                }
                break;
            }
        }
        break;
    case WM_SIZE:
        {
            PPH_LAYOUT_MANAGER layoutManager;

            layoutManager = (PPH_LAYOUT_MANAGER)GetProp(hwndDlg, L"LayoutManager");
            PhLayoutManagerLayout(layoutManager);
        }
        break;
    case WM_SIZING:
        {
            PhResizingMinimumSize((PRECT)lParam, wParam, MinimumSize.right, MinimumSize.bottom);
        }
        break;
    }

    return FALSE;
}
示例#23
0
static UINT_PTR CALLBACK
FileDialogHookProc(HWND hdlg, UINT uiMsg, WPARAM wParam, LPARAM lParam)
{
    JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);

    TRY;

    HWND parent = ::GetParent(hdlg);

    switch(uiMsg) {
        case WM_INITDIALOG: {
            OPENFILENAME *ofn = (OPENFILENAME *)lParam;
            jobject peer = (jobject)(ofn->lCustData);
            env->CallVoidMethod(peer, AwtFileDialog::setHWndMID,
                                (jlong)parent);
            ::SetProp(parent, ModalDialogPeerProp, reinterpret_cast<HANDLE>(peer));

            // fix for 4508670 - disable CS_SAVEBITS
            DWORD style = ::GetClassLong(hdlg,GCL_STYLE);
            ::SetClassLong(hdlg,GCL_STYLE,style & ~CS_SAVEBITS);

            // set appropriate icon for parentless dialogs
            jobject awtParent = env->GetObjectField(peer, AwtFileDialog::parentID);
            if (awtParent == NULL) {
                ::SendMessage(parent, WM_SETICON, (WPARAM)ICON_BIG,
                              (LPARAM)AwtToolkit::GetInstance().GetAwtIcon());
            } else {
                env->DeleteLocalRef(awtParent);
            }

            // subclass dialog's parent to receive additional messages
            WNDPROC lpfnWndProc = ComCtl32Util::GetInstance().SubclassHWND(parent,
                                                                           FileDialogWndProc);
            ::SetProp(parent, NativeDialogWndProcProp, reinterpret_cast<HANDLE>(lpfnWndProc));

            ::SetProp(parent, OpenFileNameProp, (void *)lParam);

            break;
        }
        case WM_DESTROY: {
            WNDPROC lpfnWndProc = (WNDPROC)(::GetProp(parent, NativeDialogWndProcProp));
            ComCtl32Util::GetInstance().UnsubclassHWND(parent,
                                                       FileDialogWndProc,
                                                       lpfnWndProc);
            ::RemoveProp(parent, ModalDialogPeerProp);
            ::RemoveProp(parent, NativeDialogWndProcProp);
            ::RemoveProp(parent, OpenFileNameProp);
            break;
        }
        case WM_NOTIFY: {
            OFNOTIFYEX *notifyEx = (OFNOTIFYEX *)lParam;
            if (notifyEx) {
                jobject peer = (jobject)(::GetProp(parent, ModalDialogPeerProp));
                if (notifyEx->hdr.code == CDN_INCLUDEITEM) {
                    LPITEMIDLIST pidl = (LPITEMIDLIST)notifyEx->pidl;
                    // Get the filename and directory
                    TCHAR szPath[MAX_PATH];
                    if (!::SHGetPathFromIDList(pidl, szPath)) {
                        return TRUE;
                    }
                    jstring strPath = JNU_NewStringPlatform(env, szPath);
                    // Call FilenameFilter.accept with path and filename
                    UINT uRes = (env->CallBooleanMethod(peer,
                        AwtFileDialog::checkFilenameFilterMID, strPath) == JNI_TRUE);
                    env->DeleteLocalRef(strPath);
                    return uRes;
                } else if (notifyEx->hdr.code == CDN_FILEOK) {
                    // This notification is sent when user selects some file and presses
                    // OK button; it is not sent when no file is selected. So it's time
                    // to unblock all the windows blocked by this dialog as it will
                    // be closed soon
                    env->CallVoidMethod(peer, AwtFileDialog::setHWndMID, (jlong)0);
                } else if (notifyEx->hdr.code == CDN_SELCHANGE) {
                    // reallocate the buffer if the buffer is too small
                    LPOPENFILENAME lpofn = (LPOPENFILENAME)GetProp(parent, OpenFileNameProp);

                    UINT nLength = CommDlg_OpenSave_GetSpec(parent, NULL, 0) +
                                   CommDlg_OpenSave_GetFolderPath(parent, NULL, 0);

                    if (lpofn->nMaxFile < nLength)
                    {
                        // allocate new buffer
                        LPTSTR newBuffer = new TCHAR[nLength];

                        if (newBuffer) {
                            memset(newBuffer, 0, nLength * sizeof(TCHAR));
                            LPTSTR oldBuffer = lpofn->lpstrFile;
                            lpofn->lpstrFile = newBuffer;
                            lpofn->nMaxFile = nLength;
                            // free the previously allocated buffer
                            if (oldBuffer) {
                                delete[] oldBuffer;
                            }

                        }
                    }
                }
            }
            break;
        }
    }

    return FALSE;

    CATCH_BAD_ALLOC_RET(TRUE);
}
示例#24
0
static INT_PTR CALLBACK PhpThreadStackProgressDlgProc(
    _In_ HWND hwndDlg,
    _In_ UINT uMsg,
    _In_ WPARAM wParam,
    _In_ LPARAM lParam
    )
{
    switch (uMsg)
    {
    case WM_INITDIALOG:
        {
            PTHREAD_STACK_CONTEXT threadStackContext;
            HANDLE threadHandle;

            threadStackContext = (PTHREAD_STACK_CONTEXT)lParam;
            SetProp(hwndDlg, PhMakeContextAtom(), (HANDLE)threadStackContext);
            threadStackContext->ProgressWindowHandle = hwndDlg;

            if (threadHandle = PhCreateThread(0, PhpRefreshThreadStackThreadStart, threadStackContext))
            {
                NtClose(threadHandle);
            }
            else
            {
                threadStackContext->WalkStatus = STATUS_UNSUCCESSFUL;
                EndDialog(hwndDlg, IDOK);
                break;
            }

            PhCenterWindow(hwndDlg, GetParent(hwndDlg));

            PhSetWindowStyle(GetDlgItem(hwndDlg, IDC_PROGRESS), PBS_MARQUEE, PBS_MARQUEE);
            SendMessage(GetDlgItem(hwndDlg, IDC_PROGRESS), PBM_SETMARQUEE, TRUE, 75);
            SetWindowText(hwndDlg, L"Loading stack...");
        }
        break;
    case WM_DESTROY:
        {
            RemoveProp(hwndDlg, PhMakeContextAtom());
        }
        break;
    case WM_COMMAND:
        {
            switch (LOWORD(wParam))
            {
            case IDCANCEL:
                {
                    PTHREAD_STACK_CONTEXT threadStackContext = (PTHREAD_STACK_CONTEXT)GetProp(hwndDlg, PhMakeContextAtom());

                    EnableWindow(GetDlgItem(hwndDlg, IDCANCEL), FALSE);
                    threadStackContext->StopWalk = TRUE;
                }
                break;
            }
        }
        break;
    case WM_PH_COMPLETED:
        {
            EndDialog(hwndDlg, IDOK);
        }
        break;
    case WM_PH_STATUS_UPDATE:
        {
            PTHREAD_STACK_CONTEXT threadStackContext = (PTHREAD_STACK_CONTEXT)GetProp(hwndDlg, PhMakeContextAtom());
            PPH_STRING message;

            PhAcquireQueuedLockExclusive(&threadStackContext->StatusLock);
            message = threadStackContext->StatusMessage;
            PhReferenceObject(message);
            PhReleaseQueuedLockExclusive(&threadStackContext->StatusLock);

            SetDlgItemText(hwndDlg, IDC_PROGRESSTEXT, message->Buffer);
            PhDereferenceObject(message);
        }
        break;
    }

    return 0;
}
示例#25
0
LRESULT CALLBACK  HelpWindowProc  ( HWND  	hwnd, 
				    uint  	message,
				    WPARAM	wparam,
				    LPARAM	lparam )
   {
	register THelp :: THotkeyType		Type ;
	WNDPROC					WindowProc ;
	HANDLE					WndProcProperty ;


	if  ( ! THelp :: TheHelpObject  ||
			! THelp :: TheHelpObject -> HelpTableCount )
		throw  xmsg ( string ( "HelpWindowProc a été appelée alors qu'il n'y a aucune aide disponible !!!" ) ) ;

	switch  ( message )
	   {

	// Messages qui sont peut-être des hotkeys
		case	WM_KEYDOWN :
		case	WM_CHAR :
			Type = THelp :: TheHelpObject -> IsHotkey ( hwnd, message, wparam, lparam ) ;
			
			if  ( Type  !=  THelp :: Unknown )
			   {
				THelp :: TheHelpObject -> ProcessHelpRequest ( THelp :: WindowHelp, 
						     Type,
						     hwnd, message, 
						     wparam, lparam ) ;
				return ( 0L ) ;
			    }
			break ;


	// C'est au MENUSELECT qu'on peut récupérer des infos sur l'élément de 
	// menu actuellement sélectionné.
	// Lorsque LOWORD ( lparam ) == 0xFFFF et HIWORD ( lparam ) est à zéro,
	// on est sur un menu popup dont le handle est donné par wparam
		case	WM_MENUSELECT :	
			if  ( LOWORD ( lparam )  !=  0xFFFF  &&  HIWORD ( lparam ) )
			   {
				THelp :: TheHelpObject -> LastSelectedMenuType    =  LOWORD ( lparam ) ;

				if  ( LOWORD ( lparam )  &  MF_POPUP )
				   {
					THelp :: TheHelpObject -> LastSelectedMenu = 0 ;
					THelp :: TheHelpObject -> LastSelectedMenuHandle =
							( HMENU ) wparam ;
				    }
				else
				   {
					THelp :: TheHelpObject -> LastSelectedMenu = wparam ;
					THelp :: TheHelpObject -> LastSelectedMenuHandle  =  
							( HMENU ) HIWORD ( lparam ) ;
				    }
			     }
			break ;
	      }


// Il s'agit maintenant d'appeler la bonne WindowProc. On récupère l'index de la
// première référence à cette fenêtre
	WndProcProperty = GetProp ( hwnd, WNDPROC_PROPERTY ) ;
	WindowProc = NULL ;

	if  ( WndProcProperty )
		WindowProc = THelp :: TheHelpObject ->
				HelpTable [ ( int ) WndProcProperty - 1 ]. WindowProc ;

	if  ( WindowProc  !=  NULL )
		return ( CallWindowProc ( WindowProc, hwnd, message, wparam, lparam ) ) ;
	else
		return ( 0L ) ;
     }
示例#26
0
LRESULT W_CALLBACK KappaRBGroupProc(HWND hWnd, UINT msg, 
				    WPARAM wParam, LPARAM lParam)
{
    ATOMID idWidget;
    static HBRUSH hBrBack;
    HWND hRBWnd;
    short i;
    HDC hDCx;

    switch (msg) {
      case WM_SETFOCUS:
          for (i = 1; i < 1000; ++i)
          {
              if ((hRBWnd = GetDlgItem(hWnd, i)) != NULL)
              {
                  if (IsDlgButtonChecked(hWnd, i))
                  {
                      SetFocus(hRBWnd);
                      break;
                  }
              }
              else
              {
				  /* if no button is checked, focus on the first one */ 
                  hRBWnd = GetDlgItem(hWnd, 1);
                  SetFocus(hRBWnd);
                  break;
              }
          }
          break;

      case WM_SIZE:
          if (wParam == SIZENORMAL)
          {
              idWidget = KpsGetWidgetFromWindow(hWnd);
              KpsSizeWidget(hWnd, LOWORD(lParam), HIWORD(lParam));
              AdjustCBGroup(hWnd, idWidget);
          }
          break;

      case IDG_RESET:
          DisplayRBGroup(hWnd);
          return TRUE;

      case WM_DESTROY:
          if (hBrBack)
          {
              DeleteObject(hBrBack);
              hBrBack = NULL;
          }
          break;

      case WM_PAINT:
          idWidget = KpsGetWidgetFromWindow(hWnd);
          hDCx = GetProp(hWnd, (LPSTR) "Context");

          /* If no children, return FALSE to allow drawing
             of the BITMAP. Otherwise, return TRUE for no bitmap
          */
          if (!GetWindow(hWnd, GW_CHILD))
              return (long) FALSE;
          else
              KpiDisplayTitle(hWnd, hDCx, idWidget);

          return (long) TRUE;

      case WM_COMMAND:
          switch (wParam) {
            case IDG_CLICKED:
                UpdateRBGroupValue(hWnd, LOWORD(lParam));
                break;

            default:
                break;
            }
      default:
          break;
      }

    return DefWindowProc(hWnd, msg, wParam, lParam);
}
示例#27
0
/*
	HotspotWP -- this is the WindowProc for the viewer pane.
		Answers the WM_CREATE and EWM_QUERYSIZE messages -- see
		comments next to the messages.
*/
LONG CALLBACK HotspotWP(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
	LPEWDATA lpew;
	LPCREATESTRUCT lpCreate;
	LPSTR szAviFile, szIniFile;

	switch (msg)
	{
	/* WM_CREATE -- filenames to use were handed in on the
		LPCREATESTRUCT, so we have to unpack them.  That's what
		all this string stuff does.  Once we have the filenames,
		we just hand them to hspPlayAVI, which handles all the
		subclassing and stuff for us.
	*/
	case WM_CREATE:
		lpCreate = (LPCREATESTRUCT)lParam;
		lpew = (LPEWDATA)lpCreate->lpCreateParams;

		szIniFile = lpew->szAuthorData;
		while (*szIniFile != ',') szIniFile++;
		*szIniFile = '\0';
		szIniFile++;
		szAviFile = lpew->szAuthorData;
		if ((*szAviFile == '\140') || *szAviFile == '\042' );
			szAviFile++; 
		if ((szIniFile[lstrlen(szIniFile)-1] == '\047') ||
		    (szIniFile[lstrlen(szIniFile)-1] == '\042') )
			szIniFile[lstrlen(szIniFile)-1] = '\0';
        hspPlayAVI(hwnd, szAviFile,szIniFile,NULL);
		//{
			//PMOVIEINFO pMovieInfo;
			//HANDLE hglb;
		    
			//hglb = GetProp(hwnd, (LPSTR)szMovieInfo);
			//if (hglb)
	        //{
		    	//pMovieInfo = (PMOVIEINFO)GlobalLock(hglb);
		 		//if (pMovieInfo && pMovieInfo->fMovieOpen) 
				//{
					//MCI_DGV_SETVIDEO_PARMS	dgv;
					//UINT					uDevice;
					//dgv.dwValue = (DWORD)NULL;//ICAVIDrawProc;
						////MakeProcInstance((FARPROC) ICAVIDrawProc,hInstApp);
					//dgv.dwItem = MCI_AVI_SETVIDEO_DRAW_PROCEDURE;
					//uDevice = pMovieInfo->wMCIDeviceID;
					//if (uDevice)
					//{
						//DWORD dw;
								
						//dw = mciSendCommand(uDevice,
						//MCI_SETVIDEO,
						//MCI_DGV_SETVIDEO_ITEM | MCI_DGV_SETVIDEO_VALUE,
						//(DWORD) (MCI_DGV_SETVIDEO_PARMS FAR *)&dgv);
						//OutputDebugString("set draw proc!\n");
						//if (dw != 0)
						//{
							//MessageBox(GetFocus(),
								//"The currently installed MCIAVI does not "
								//"support the MCI_AVI_SETVIDEO_DRAW_PROCEDURE "
								//"command during play.","MCI Problem",
								//MB_OK | MB_ICONHAND);
						//}
					//}
					//else
					//{
						//MessageBox(GetFocus(),"movie info has no device id",
							//"real bummer",MB_OK);
					//}
					//playMovie(pMovieInfo, 1);
				//}
				//else
				//{
					//OutputDebugString(
						//"no pMovieInfo && pMovieInfo->fMovieOpen\n");
				//}
			//}
			//else
			//{
				//OutputDebugString("NO WINDOW PROPERTY!!\n");
			//}
		//}
		return 0;
	/* EWM_QUERYSIZE -- the viewer wants to know the pane size.
		hspPlayAVI already glued a handle to the movieinfo structure
		onto this window with SetProp. So, we use GetProp to get the
		movieinfo, which has a deviceID we can then use to ask
		MCI for the size numbers.(with the MCI_WHERE) command.
	 */
	case EWM_QUERYSIZE:
		dbg("HotspotWP EWM_QUERYSIZE");
	{
		LPPOINT lpPoint = (LPPOINT) lParam;
		HANDLE hglb;
		PMOVIEINFO pMovieInfo;
		MCI_DGV_RECT_PARMS   mciRect;
    
		hglb = GetProp(hwnd, (LPSTR)szMovieInfo);
		if (!hglb)
        {
        	return FALSE;
        }
    	pMovieInfo = (PMOVIEINFO)GlobalLock(hglb);
 		if (!pMovieInfo->fMovieOpen) 
		{
			GlobalUnlock(hglb);
			return FALSE;
		}
		mciSendCommand(pMovieInfo->wMCIDeviceID, MCI_WHERE, 
                  (DWORD)(MCI_DGV_WHERE_SOURCE), 
                  (DWORD)(LPMCI_DGV_RECT_PARMS)&mciRect);
		lpPoint->x = mciRect.rc.right - mciRect.rc.left; 
		lpPoint->y = mciRect.rc.bottom - mciRect.rc.top; 
		GlobalUnlock(hglb);
		return TRUE;
	}
	/* now we just refuse a few viewer questions... */
	case EWM_ASKPALETTE:
		return NULL;
	case EWM_RENDER:
		return NULL;
	case EWM_COPY:
		return NULL;
	case EWM_PRINT:
		return FALSE;
	case WM_PARENTNOTIFY:
		OutputDebugString("WM_PARENTNOTIFY !!!!!\n");
		if (wParam == WM_LBUTTONDOWN)
		{
			OutputDebugString("WM_LBUTTONDOWN even !!!!!\n");
		}
		else
		{
			{char x[256]; wsprintf(x,"value %X\n",wParam);
				OutputDebugString(x);   }
			//if (wParam == 1)
			//{
				//PMOVIEINFO pMovieInfo;
				//HANDLE hglb;
		    
				//hglb = GetProp(hwnd, (LPSTR)szMovieInfo);
				//if (hglb)
		        //{
			    	//pMovieInfo = (PMOVIEINFO)GlobalLock(hglb);
			 		//if (pMovieInfo && pMovieInfo->fMovieOpen) 
					//{
						//MCI_DGV_SETVIDEO_PARMS	dgv;
						//UINT					uDevice;
						//dgv.dwValue = (DWORD)ICAVIDrawProc;
							////MakeProcInstance((FARPROC) ICAVIDrawProc,hInstApp);
						//dgv.dwItem = MCI_AVI_SETVIDEO_DRAW_PROCEDURE;
						//uDevice = pMovieInfo->wMCIDeviceID;
						//if (uDevice)
						//{
							//DWORD dw;
								
							//dw = mciSendCommand(uDevice,
							//MCI_SETVIDEO,
							//MCI_DGV_SETVIDEO_ITEM | MCI_DGV_SETVIDEO_VALUE,
							//(DWORD) (MCI_DGV_SETVIDEO_PARMS FAR *)&dgv);
							//OutputDebugString("set draw proc!\n");
							//if (dw != 0)
							//{
								//MessageBox(GetFocus(),
									//"The currently installed MCIAVI does not "
									//"support the MCI_AVI_SETVIDEO_DRAW_PROCEDURE "
									//"command during play.","MCI Problem",
									//MB_OK | MB_ICONHAND);
							//}
						//}
						//else
						//{
							//MessageBox(GetFocus(),"movie info has no device id",
								//"real bummer",MB_OK);
						//}
					//}
					//else
					//{
						//OutputDebugString(
							//"no pMovieInfo && pMovieInfo->fMovieOpen\n");
					//}
				//}
				//else
				//{
					//OutputDebugString("NO WINDOW PROPERTY!!\n");
				//}
			//}
			break;
		//case MCIWNDM_NOTIFYSIZE:
			//OutputDebugString("MCIWNDM_NOTIFYMEDIA\n");
			//if (hwndMCI == 0)
			//{
				//hwndMCI = (HWND) wParam;
			//}
			//GetWindowRect(hwndMCI, &rc);
			//AdjustWindowRect(&rc, GetWindowLong(hwnd, GWL_STYLE), TRUE);
			//SetWindowPos(hwnd, NULL, 0, 0, rc.right - rc.left,
				//rc.bottom - rc.top,
				//SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOMOVE);
			//break;
		}
		break;
	default:
		return DefWindowProc(hwnd, msg, wParam, lParam);
	}
	return FALSE;
}
示例#28
0
LRESULT DcxDivider::PostMessage( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL & bParsed ) {

	LRESULT lRes = 0L;
	switch( uMsg ) {

	case WM_NOTIFY : 
		{
			LPNMHDR hdr = (LPNMHDR) lParam;

			if (!hdr)
				break;

			if (IsWindow(hdr->hwndFrom)) {
				DcxControl *c_this = (DcxControl *) GetProp(hdr->hwndFrom,"dcx_cthis");
				if (c_this != NULL)
					lRes = c_this->ParentMessage(uMsg, wParam, lParam, bParsed);
			}
		}
		break;

	case WM_HSCROLL: 
	case WM_VSCROLL: 
	case WM_COMMAND:
		{
			if (IsWindow((HWND) lParam)) {
				DcxControl *c_this = (DcxControl *) GetProp((HWND) lParam,"dcx_cthis");
				if (c_this != NULL)
					lRes = c_this->ParentMessage(uMsg, wParam, lParam, bParsed);
			}
		}
		break;
	case WM_COMPAREITEM:
		{
			LPCOMPAREITEMSTRUCT idata = (LPCOMPAREITEMSTRUCT)lParam;
			if ((idata != NULL) && (IsWindow(idata->hwndItem))) {
				DcxControl *c_this = (DcxControl *) GetProp(idata->hwndItem,"dcx_cthis");
				if (c_this != NULL)
					lRes = c_this->ParentMessage(uMsg, wParam, lParam, bParsed);
			}
		}
		break;

	case WM_DELETEITEM:
		{
			DELETEITEMSTRUCT *idata = (DELETEITEMSTRUCT *)lParam;
			if ((idata != NULL) && (IsWindow(idata->hwndItem))) {
				DcxControl *c_this = (DcxControl *) GetProp(idata->hwndItem,"dcx_cthis");
				if (c_this != NULL)
					lRes = c_this->ParentMessage(uMsg, wParam, lParam, bParsed);
			}
		}
		break;

	case WM_MEASUREITEM:
		{
			HWND cHwnd = GetDlgItem(this->m_Hwnd, wParam);
			if (IsWindow(cHwnd)) {
				DcxControl *c_this = (DcxControl *) GetProp(cHwnd,"dcx_cthis");
				if (c_this != NULL)
					lRes = c_this->ParentMessage(uMsg, wParam, lParam, bParsed);
			}
		}
		break;

	case WM_DRAWITEM:
		{
			DRAWITEMSTRUCT *idata = (DRAWITEMSTRUCT *)lParam;
			if ((idata != NULL) && (IsWindow(idata->hwndItem))) {
				DcxControl *c_this = (DcxControl *) GetProp(idata->hwndItem,"dcx_cthis");
				if (c_this != NULL)
					lRes = c_this->ParentMessage(uMsg, wParam, lParam, bParsed);
			}
		}
		break;

	case WM_DESTROY:
		{
			delete this;
			bParsed = TRUE;
		}
		break;

	case DV_CHANGEPOS:
		{
			const int phase = (int) wParam;
			const LPPOINT pt = (LPPOINT) lParam;

			this->execAliasEx("%s,%d,%d,%d", (phase == DVNM_DRAG_START ? "dragbegin" : (phase == DVNM_DRAG_END ? "dragfinish" : "drag")), this->getUserID(), pt->x, pt->y);
		}
		break;

	default:
		lRes = this->CommonMessage( uMsg, wParam, lParam, bParsed);
		break;
	}

	return lRes;
}
示例#29
0
INT_PTR CALLBACK PhpRunAsDlgProc(
    _In_ HWND hwndDlg,
    _In_ UINT uMsg,
    _In_ WPARAM wParam,
    _In_ LPARAM lParam
    )
{
    PRUNAS_DIALOG_CONTEXT context;

    if (uMsg != WM_INITDIALOG)
    {
        context = (PRUNAS_DIALOG_CONTEXT)GetProp(hwndDlg, PhMakeContextAtom());
    }
    else
    {
        context = (PRUNAS_DIALOG_CONTEXT)lParam;
        SetProp(hwndDlg, PhMakeContextAtom(), (HANDLE)context);
    }

    if (!context)
        return FALSE;

    switch (uMsg)
    {
    case WM_INITDIALOG:
        {
            HWND typeComboBoxHandle = GetDlgItem(hwndDlg, IDC_TYPE);
            HWND userNameComboBoxHandle = GetDlgItem(hwndDlg, IDC_USERNAME);
            ULONG sessionId;

            PhCenterWindow(hwndDlg, GetParent(hwndDlg));

            if (SHAutoComplete_I)
            {
                SHAutoComplete_I(
                    GetDlgItem(hwndDlg, IDC_PROGRAM),
                    SHACF_AUTOAPPEND_FORCE_ON | SHACF_AUTOSUGGEST_FORCE_ON | SHACF_FILESYS_ONLY
                    );
            }

            ComboBox_AddString(typeComboBoxHandle, L"Batch");
            ComboBox_AddString(typeComboBoxHandle, L"Interactive");
            ComboBox_AddString(typeComboBoxHandle, L"Network");
            ComboBox_AddString(typeComboBoxHandle, L"New credentials");
            ComboBox_AddString(typeComboBoxHandle, L"Service");
            PhSelectComboBoxString(typeComboBoxHandle, L"Interactive", FALSE);

            ComboBox_AddString(userNameComboBoxHandle, L"NT AUTHORITY\\SYSTEM");
            ComboBox_AddString(userNameComboBoxHandle, L"NT AUTHORITY\\LOCAL SERVICE");
            ComboBox_AddString(userNameComboBoxHandle, L"NT AUTHORITY\\NETWORK SERVICE");

            PhpAddAccountsToComboBox(userNameComboBoxHandle);

            if (NT_SUCCESS(PhGetProcessSessionId(NtCurrentProcess(), &sessionId)))
                SetDlgItemInt(hwndDlg, IDC_SESSIONID, sessionId, FALSE);

            SetDlgItemText(hwndDlg, IDC_DESKTOP, L"WinSta0\\Default");
            SetDlgItemText(hwndDlg, IDC_PROGRAM, PhaGetStringSetting(L"RunAsProgram")->Buffer);

            if (!context->ProcessId)
            {
                SetDlgItemText(hwndDlg, IDC_USERNAME,
                    PH_AUTO_T(PH_STRING, PhGetStringSetting(L"RunAsUserName"))->Buffer);

                // Fire the user name changed event so we can fix the logon type.
                SendMessage(hwndDlg, WM_COMMAND, MAKEWPARAM(IDC_USERNAME, CBN_EDITCHANGE), 0);
            }
            else
            {
                HANDLE processHandle;
                HANDLE tokenHandle;
                PTOKEN_USER user;
                PPH_STRING userName;

                if (NT_SUCCESS(PhOpenProcess(
                    &processHandle,
                    ProcessQueryAccess,
                    context->ProcessId
                    )))
                {
                    if (NT_SUCCESS(PhOpenProcessToken(
                        processHandle,
                        TOKEN_QUERY,
                        &tokenHandle
                        )))
                    {
                        if (NT_SUCCESS(PhGetTokenUser(tokenHandle, &user)))
                        {
                            if (userName = PhGetSidFullName(user->User.Sid, TRUE, NULL))
                            {
                                SetDlgItemText(hwndDlg, IDC_USERNAME, userName->Buffer);
                                PhDereferenceObject(userName);
                            }

                            PhFree(user);
                        }

                        NtClose(tokenHandle);
                    }

                    NtClose(processHandle);
                }

                EnableWindow(GetDlgItem(hwndDlg, IDC_USERNAME), FALSE);
                EnableWindow(GetDlgItem(hwndDlg, IDC_PASSWORD), FALSE);
                EnableWindow(GetDlgItem(hwndDlg, IDC_TYPE), FALSE);
            }

            SendMessage(hwndDlg, WM_NEXTDLGCTL, (WPARAM)GetDlgItem(hwndDlg, IDC_PROGRAM), TRUE);
            Edit_SetSel(GetDlgItem(hwndDlg, IDC_PROGRAM), 0, -1);

            //if (!PhGetOwnTokenAttributes().Elevated)
            //    SendMessage(GetDlgItem(hwndDlg, IDOK), BCM_SETSHIELD, 0, TRUE);

            if (!WINDOWS_HAS_UAC)
                ShowWindow(GetDlgItem(hwndDlg, IDC_TOGGLEELEVATION), SW_HIDE);
        }
        break;
    case WM_DESTROY:
        {
            if (context->DesktopList)
                PhDereferenceObject(context->DesktopList);

            RemoveProp(hwndDlg, PhMakeContextAtom());
        }
        break;
    case WM_COMMAND:
        {
            switch (LOWORD(wParam))
            {
            case IDCANCEL:
                EndDialog(hwndDlg, IDCANCEL);
                break;
            case IDOK:
                {
                    NTSTATUS status;
                    PPH_STRING program;
                    PPH_STRING userName;
                    PPH_STRING password;
                    PPH_STRING logonTypeString;
                    ULONG logonType;
                    ULONG sessionId;
                    PPH_STRING desktopName;
                    BOOLEAN useLinkedToken;

                    program = PhaGetDlgItemText(hwndDlg, IDC_PROGRAM);
                    userName = PhaGetDlgItemText(hwndDlg, IDC_USERNAME);
                    logonTypeString = PhaGetDlgItemText(hwndDlg, IDC_TYPE);

                    // Fix up the user name if it doesn't have a domain.
                    if (PhFindCharInString(userName, 0, '\\') == -1)
                    {
                        PSID sid;
                        PPH_STRING newUserName;

                        if (NT_SUCCESS(PhLookupName(&userName->sr, &sid, NULL, NULL)))
                        {
                            if (newUserName = PH_AUTO(PhGetSidFullName(sid, TRUE, NULL)))
                                userName = newUserName;

                            PhFree(sid);
                        }
                    }

                    if (!IsServiceAccount(userName))
                        password = PhGetWindowText(GetDlgItem(hwndDlg, IDC_PASSWORD));
                    else
                        password = NULL;

                    sessionId = GetDlgItemInt(hwndDlg, IDC_SESSIONID, NULL, FALSE);
                    desktopName = PhaGetDlgItemText(hwndDlg, IDC_DESKTOP);

                    if (WINDOWS_HAS_UAC)
                        useLinkedToken = Button_GetCheck(GetDlgItem(hwndDlg, IDC_TOGGLEELEVATION)) == BST_CHECKED;
                    else
                        useLinkedToken = FALSE;

                    if (PhFindIntegerSiKeyValuePairs(
                        PhpLogonTypePairs,
                        sizeof(PhpLogonTypePairs),
                        logonTypeString->Buffer,
                        &logonType
                        ))
                    {
                        if (
                            logonType == LOGON32_LOGON_INTERACTIVE &&
                            !context->ProcessId &&
                            sessionId == NtCurrentPeb()->SessionId &&
                            !useLinkedToken
                            )
                        {
                            // We are eligible to load the user profile.
                            // This must be done here, not in the service, because
                            // we need to be in the target session.

                            PH_CREATE_PROCESS_AS_USER_INFO createInfo;
                            PPH_STRING domainPart;
                            PPH_STRING userPart;

                            PhpSplitUserName(userName->Buffer, &domainPart, &userPart);

                            memset(&createInfo, 0, sizeof(PH_CREATE_PROCESS_AS_USER_INFO));
                            createInfo.CommandLine = program->Buffer;
                            createInfo.UserName = userPart->Buffer;
                            createInfo.DomainName = domainPart->Buffer;
                            createInfo.Password = PhGetStringOrEmpty(password);

                            // Whenever we can, try not to set the desktop name; it breaks a lot of things.
                            // Note that on XP we must set it, otherwise the program doesn't display correctly.
                            if (WindowsVersion < WINDOWS_VISTA || (desktopName->Length != 0 && !PhEqualString2(desktopName, L"WinSta0\\Default", TRUE)))
                                createInfo.DesktopName = desktopName->Buffer;

                            PhSetDesktopWinStaAccess();

                            status = PhCreateProcessAsUser(
                                &createInfo,
                                PH_CREATE_PROCESS_WITH_PROFILE,
                                NULL,
                                NULL,
                                NULL
                                );

                            if (domainPart) PhDereferenceObject(domainPart);
                            if (userPart) PhDereferenceObject(userPart);
                        }
                        else
                        {
                            status = PhExecuteRunAsCommand2(
                                hwndDlg,
                                program->Buffer,
                                userName->Buffer,
                                PhGetStringOrEmpty(password),
                                logonType,
                                context->ProcessId,
                                sessionId,
                                desktopName->Buffer,
                                useLinkedToken
                                );
                        }
                    }
                    else
                    {
                        status = STATUS_INVALID_PARAMETER;
                    }

                    if (password)
                    {
                        RtlSecureZeroMemory(password->Buffer, password->Length);
                        PhDereferenceObject(password);
                    }

                    if (!NT_SUCCESS(status))
                    {
                        if (status != STATUS_CANCELLED)
                            PhShowStatus(hwndDlg, L"Unable to start the program", status, 0);
                    }
                    else if (status != STATUS_TIMEOUT)
                    {
                        PhSetStringSetting2(L"RunAsProgram", &program->sr);
                        PhSetStringSetting2(L"RunAsUserName", &userName->sr);
                        EndDialog(hwndDlg, IDOK);
                    }
                }
                break;
            case IDC_BROWSE:
                {
                    static PH_FILETYPE_FILTER filters[] =
                    {
                        { L"Programs (*.exe;*.pif;*.com;*.bat)", L"*.exe;*.pif;*.com;*.bat" },
                        { L"All files (*.*)", L"*.*" }
                    };
                    PVOID fileDialog;

                    fileDialog = PhCreateOpenFileDialog();
                    PhSetFileDialogFilter(fileDialog, filters, sizeof(filters) / sizeof(PH_FILETYPE_FILTER));
                    PhSetFileDialogFileName(fileDialog, PhaGetDlgItemText(hwndDlg, IDC_PROGRAM)->Buffer);

                    if (PhShowFileDialog(hwndDlg, fileDialog))
                    {
                        PPH_STRING fileName;

                        fileName = PhGetFileDialogFileName(fileDialog);
                        SetDlgItemText(hwndDlg, IDC_PROGRAM, fileName->Buffer);
                        PhDereferenceObject(fileName);
                    }

                    PhFreeFileDialog(fileDialog);
                }
                break;
            case IDC_USERNAME:
                {
                    PPH_STRING userName = NULL;

                    if (!context->ProcessId && HIWORD(wParam) == CBN_SELCHANGE)
                    {
                        userName = PH_AUTO(PhGetComboBoxString(GetDlgItem(hwndDlg, IDC_USERNAME), -1));
                    }
                    else if (!context->ProcessId && (
                        HIWORD(wParam) == CBN_EDITCHANGE ||
                        HIWORD(wParam) == CBN_CLOSEUP
                        ))
                    {
                        userName = PhaGetDlgItemText(hwndDlg, IDC_USERNAME);
                    }

                    if (userName)
                    {
                        if (IsServiceAccount(userName))
                        {
                            EnableWindow(GetDlgItem(hwndDlg, IDC_PASSWORD), FALSE);

                            // Hack for Windows XP
                            if (
                                PhEqualString2(userName, L"NT AUTHORITY\\SYSTEM", TRUE) &&
                                WindowsVersion <= WINDOWS_XP
                                )
                            {
                                PhSelectComboBoxString(GetDlgItem(hwndDlg, IDC_TYPE), L"New credentials", FALSE);
                            }
                            else
                            {
                                PhSelectComboBoxString(GetDlgItem(hwndDlg, IDC_TYPE), L"Service", FALSE);
                            }
                        }
                        else
                        {
                            EnableWindow(GetDlgItem(hwndDlg, IDC_PASSWORD), TRUE);
                            PhSelectComboBoxString(GetDlgItem(hwndDlg, IDC_TYPE), L"Interactive", FALSE);
                        }
                    }
                }
                break;
            case IDC_SESSIONS:
                {
                    PPH_EMENU sessionsMenu;
                    PSESSIONIDW sessions;
                    ULONG numberOfSessions;
                    ULONG i;
                    RECT buttonRect;
                    PPH_EMENU_ITEM selectedItem;

                    sessionsMenu = PhCreateEMenu();

                    if (WinStationEnumerateW(NULL, &sessions, &numberOfSessions))
                    {
                        for (i = 0; i < numberOfSessions; i++)
                        {
                            PPH_STRING menuString;
                            WINSTATIONINFORMATION winStationInfo;
                            ULONG returnLength;

                            if (!WinStationQueryInformationW(
                                NULL,
                                sessions[i].SessionId,
                                WinStationInformation,
                                &winStationInfo,
                                sizeof(WINSTATIONINFORMATION),
                                &returnLength
                                ))
                            {
                                winStationInfo.Domain[0] = 0;
                                winStationInfo.UserName[0] = 0;
                            }

                            if (
                                winStationInfo.UserName[0] != 0 &&
                                sessions[i].WinStationName[0] != 0
                                )
                            {
                                menuString = PhaFormatString(
                                    L"%u: %s (%s\\%s)",
                                    sessions[i].SessionId,
                                    sessions[i].WinStationName,
                                    winStationInfo.Domain,
                                    winStationInfo.UserName
                                    );
                            }
                            else if (winStationInfo.UserName[0] != 0)
                            {
                                menuString = PhaFormatString(
                                    L"%u: %s\\%s",
                                    sessions[i].SessionId,
                                    winStationInfo.Domain,
                                    winStationInfo.UserName
                                    );
                            }
                            else if (sessions[i].WinStationName[0] != 0)
                            {
                                menuString = PhaFormatString(
                                    L"%u: %s",
                                    sessions[i].SessionId,
                                    sessions[i].WinStationName
                                    );
                            }
                            else
                            {
                                menuString = PhaFormatString(L"%u", sessions[i].SessionId);
                            }

                            PhInsertEMenuItem(sessionsMenu,
                                PhCreateEMenuItem(0, 0, menuString->Buffer, NULL, UlongToPtr(sessions[i].SessionId)), -1);
                        }

                        WinStationFreeMemory(sessions);

                        GetWindowRect(GetDlgItem(hwndDlg, IDC_SESSIONS), &buttonRect);

                        selectedItem = PhShowEMenu(
                            sessionsMenu,
                            hwndDlg,
                            PH_EMENU_SHOW_LEFTRIGHT,
                            PH_ALIGN_LEFT | PH_ALIGN_TOP,
                            buttonRect.right,
                            buttonRect.top
                            );

                        if (selectedItem)
                        {
                            SetDlgItemInt(
                                hwndDlg,
                                IDC_SESSIONID,
                                PtrToUlong(selectedItem->Context),
                                FALSE
                                );
                        }

                        PhDestroyEMenu(sessionsMenu);
                    }
                }
                break;
            case IDC_DESKTOPS:
                {
                    PPH_EMENU desktopsMenu;
                    ULONG i;
                    RECT buttonRect;
                    PPH_EMENU_ITEM selectedItem;

                    desktopsMenu = PhCreateEMenu();

                    if (!context->DesktopList)
                        context->DesktopList = PhCreateList(10);

                    context->CurrentWinStaName = GetCurrentWinStaName();

                    EnumDesktops(GetProcessWindowStation(), EnumDesktopsCallback, (LPARAM)context);

                    for (i = 0; i < context->DesktopList->Count; i++)
                    {
                        PhInsertEMenuItem(
                            desktopsMenu,
                            PhCreateEMenuItem(0, 0, ((PPH_STRING)context->DesktopList->Items[i])->Buffer, NULL, NULL),
                            -1
                            );
                    }

                    GetWindowRect(GetDlgItem(hwndDlg, IDC_DESKTOPS), &buttonRect);

                    selectedItem = PhShowEMenu(
                        desktopsMenu,
                        hwndDlg,
                        PH_EMENU_SHOW_LEFTRIGHT,
                        PH_ALIGN_LEFT | PH_ALIGN_TOP,
                        buttonRect.right,
                        buttonRect.top
                        );

                    if (selectedItem)
                    {
                        SetDlgItemText(
                            hwndDlg,
                            IDC_DESKTOP,
                            selectedItem->Text
                            );
                    }

                    for (i = 0; i < context->DesktopList->Count; i++)
                        PhDereferenceObject(context->DesktopList->Items[i]);

                    PhClearList(context->DesktopList);
                    PhDereferenceObject(context->CurrentWinStaName);
                    PhDestroyEMenu(desktopsMenu);
                }
                break;
            }
        }
        break;
    }

    return FALSE;
}
LRESULT CALLBACK
winWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    static winPrivScreenPtr s_pScreenPriv = NULL;
    static winScreenInfo *s_pScreenInfo = NULL;
    static ScreenPtr s_pScreen = NULL;
    static HWND s_hwndLastPrivates = NULL;
    static HINSTANCE s_hInstance;
    static Bool s_fTracking = FALSE;
    static unsigned long s_ulServerGeneration = 0;
    static UINT s_uTaskbarRestart = 0;
    int iScanCode;
    int i;

#if CYGDEBUG
    winDebugWin32Message("winWindowProc", hwnd, message, wParam, lParam);
#endif

    /* Watch for server regeneration */
    if (g_ulServerGeneration != s_ulServerGeneration) {
        /* Store new server generation */
        s_ulServerGeneration = g_ulServerGeneration;
    }

    /* Only retrieve new privates pointers if window handle is null or changed */
    if ((s_pScreenPriv == NULL || hwnd != s_hwndLastPrivates)
        && (s_pScreenPriv = GetProp(hwnd, WIN_SCR_PROP)) != NULL) {
#if CYGDEBUG
        winDebug("winWindowProc - Setting privates handle\n");
#endif
        s_pScreenInfo = s_pScreenPriv->pScreenInfo;
        s_pScreen = s_pScreenInfo->pScreen;
        s_hwndLastPrivates = hwnd;
    }
    else if (s_pScreenPriv == NULL) {
        /* For safety, handle case that should never happen */
        s_pScreenInfo = NULL;
        s_pScreen = NULL;
        s_hwndLastPrivates = NULL;
    }

    /* Branch on message type */
    switch (message) {
    case WM_TRAYICON:
        return winHandleIconMessage(hwnd, message, wParam, lParam,
                                    s_pScreenPriv);

    case WM_CREATE:
#if CYGDEBUG
        winDebug("winWindowProc - WM_CREATE\n");
#endif

        /*
         * Add a property to our display window that references
         * this screens' privates.
         *
         * This allows the window procedure to refer to the
         * appropriate window DC and shadow DC for the window that
         * it is processing.  We use this to repaint exposed
         * areas of our display window.
         */
        s_pScreenPriv = ((LPCREATESTRUCT) lParam)->lpCreateParams;
        s_hInstance = ((LPCREATESTRUCT) lParam)->hInstance;
        s_pScreenInfo = s_pScreenPriv->pScreenInfo;
        s_pScreen = s_pScreenInfo->pScreen;
        s_hwndLastPrivates = hwnd;
        s_uTaskbarRestart = RegisterWindowMessage(TEXT("TaskbarCreated"));
        SetProp(hwnd, WIN_SCR_PROP, s_pScreenPriv);

        /* Setup tray icon */
        if (!s_pScreenInfo->fNoTrayIcon) {
            /*
             * NOTE: The WM_CREATE message is processed before CreateWindowEx
             * returns, so s_pScreenPriv->hwndScreen is invalid at this point.
             * We go ahead and copy our hwnd parameter over top of the screen
             * privates hwndScreen so that we have a valid value for
             * that member.  Otherwise, the tray icon will disappear
             * the first time you move the mouse over top of it.
             */

            s_pScreenPriv->hwndScreen = hwnd;

            winInitNotifyIcon(s_pScreenPriv);
        }
        return 0;

    case WM_DISPLAYCHANGE:
        /*
           WM_DISPLAYCHANGE seems to be sent when the monitor layout or
           any monitor's resolution or depth changes, but it's lParam and
           wParam always indicate the resolution and bpp for the primary
           monitor (so ignore that as we could be on any monitor...)
         */

        /* We cannot handle a display mode change during initialization */
        if (s_pScreenInfo == NULL)
            FatalError("winWindowProc - WM_DISPLAYCHANGE - The display "
                       "mode changed while we were intializing.  This is "
                       "very bad and unexpected.  Exiting.\n");

        /*
         * We do not care about display changes with
         * fullscreen DirectDraw engines, because those engines set
         * their own mode when they become active.
         */
        if (s_pScreenInfo->fFullScreen
            && (s_pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DD
                || s_pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DDNL
#ifdef XWIN_PRIMARYFB
                || s_pScreenInfo->dwEngine == WIN_SERVER_PRIMARY_DD
#endif
            )) {
            break;
        }

        ErrorF("winWindowProc - WM_DISPLAYCHANGE - new width: %d "
               "new height: %d new bpp: %d\n",
               LOWORD(lParam), HIWORD(lParam), wParam);

        /* 0 bpp has no defined meaning, ignore this message */
        if (wParam == 0)
            break;

        /*
         * Check for a disruptive change in depth.
         * We can only display a message for a disruptive depth change,
         * we cannot do anything to correct the situation.
         */
        /*
           XXX: maybe we need to check if GetSystemMetrics(SM_SAMEDISPLAYFORMAT)
           has changed as well...
         */
        if (s_pScreenInfo->dwBPP !=
            GetDeviceCaps(s_pScreenPriv->hdcScreen, BITSPIXEL)) {
            if ((s_pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DD ||
                 s_pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DDNL
#ifdef XWIN_PRIMARYFB
                 || s_pScreenInfo->dwEngine == WIN_SERVER_PRIMARY_DD
#endif
                )) {
                /* Cannot display the visual until the depth is restored */
                ErrorF("winWindowProc - Disruptive change in depth\n");

                /* Display depth change dialog */
                winDisplayDepthChangeDialog(s_pScreenPriv);

                /* Flag that we have an invalid screen depth */
                s_pScreenPriv->fBadDepth = TRUE;

                /* Minimize the display window */
                ShowWindow(hwnd, SW_MINIMIZE);
            }
            else {
                /* For GDI, performance may suffer until original depth is restored */
                ErrorF
                    ("winWindowProc - Performance may be non-optimal after change in depth\n");
            }
        }
        else {
            /* Flag that we have a valid screen depth */
            s_pScreenPriv->fBadDepth = FALSE;
        }

        /*
           If we could cheaply check if this WM_DISPLAYCHANGE change
           affects the monitor(s) which this X screen is displayed on
           then we should do so here.  For the moment, assume it does.
           (this is probably usually the case so that might be an
           overoptimization)
         */
        {
            /*
               In rootless modes which are monitor or virtual desktop size
               use RandR to resize the X screen
             */
            if ((!s_pScreenInfo->fUserGaveHeightAndWidth) &&
                (s_pScreenInfo->iResizeMode == resizeWithRandr) && (FALSE
#ifdef XWIN_MULTIWINDOWEXTWM
                                                                    ||
                                                                    s_pScreenInfo->
                                                                    fMWExtWM
#endif
                                                                    ||
                                                                    s_pScreenInfo->
                                                                    fRootless
#ifdef XWIN_MULTIWINDOW
                                                                    ||
                                                                    s_pScreenInfo->
                                                                    fMultiWindow
#endif
                )) {
                DWORD dwWidth, dwHeight;

                if (s_pScreenInfo->fMultipleMonitors) {
                    /* resize to new virtual desktop size */
                    dwWidth = GetSystemMetrics(SM_CXVIRTUALSCREEN);
                    dwHeight = GetSystemMetrics(SM_CYVIRTUALSCREEN);
                }
                else {
                    /* resize to new size of specified monitor */
                    struct GetMonitorInfoData data;

                    if (QueryMonitor(s_pScreenInfo->iMonitor, &data)) {
                        if (data.bMonitorSpecifiedExists == TRUE) {
                            dwWidth = data.monitorWidth;
                            dwHeight = data.monitorHeight;
                            /*
                               XXX: monitor may have changed position,
                               so we might need to update xinerama data
                             */
                        }
                        else {
                            ErrorF("Monitor number %d no longer exists!\n",
                                   s_pScreenInfo->iMonitor);
                        }
                    }
                }

                /*
                   XXX: probably a small bug here: we don't compute the work area
                   and allow for task bar

                   XXX: generally, we don't allow for the task bar being moved after
                   the server is started
                 */

                /* Set screen size to match new size, if it is different to current */
                if ((s_pScreenInfo->dwWidth != dwWidth) ||
                    (s_pScreenInfo->dwHeight != dwHeight)) {
                    winDoRandRScreenSetSize(s_pScreen,
                                            dwWidth,
                                            dwHeight,
                                            (dwWidth * 25.4) /
                                            monitorResolution,
                                            (dwHeight * 25.4) /
                                            monitorResolution);
                }
            }
            else {
                /*
                 * We can simply recreate the same-sized primary surface when
                 * the display dimensions change.
                 */

                /*
                 * NOTE: The non-DirectDraw engines set the ReleasePrimarySurface
                 * and CreatePrimarySurface function pointers to point
                 * to the no operation function, NoopDDA.  This allows us
                 * to blindly call these functions, even if they are not
                 * relevant to the current engine (e.g., Shadow GDI).
                 */

                winDebug
                    ("winWindowProc - WM_DISPLAYCHANGE - Releasing and recreating primary surface\n");

                /* Release the old primary surface */
                (*s_pScreenPriv->pwinReleasePrimarySurface) (s_pScreen);

                /* Create the new primary surface */
                (*s_pScreenPriv->pwinCreatePrimarySurface) (s_pScreen);
            }
        }

        break;

    case WM_SIZE:
    {
        SCROLLINFO si;
        RECT rcWindow;
        int iWidth, iHeight;

#if CYGDEBUG
        winDebug("winWindowProc - WM_SIZE\n");
#endif

        /* Break if we do not allow resizing */
        if ((s_pScreenInfo->iResizeMode == notAllowed)
            || !s_pScreenInfo->fDecoration
#ifdef XWIN_MULTIWINDOWEXTWM
            || s_pScreenInfo->fMWExtWM
#endif
            || s_pScreenInfo->fRootless
#ifdef XWIN_MULTIWINDOW
            || s_pScreenInfo->fMultiWindow
#endif
            || s_pScreenInfo->fFullScreen)
            break;

        /* No need to resize if we get minimized */
        if (wParam == SIZE_MINIMIZED)
            return 0;

        ErrorF("winWindowProc - WM_SIZE - new client area w: %d h: %d\n",
               LOWORD(lParam), HIWORD(lParam));

        if (s_pScreenInfo->iResizeMode == resizeWithRandr) {
            /* Actual resizing is done on WM_EXITSIZEMOVE */
            return 0;
        }

        /* Otherwise iResizeMode == resizeWithScrollbars */

        /*
         * Get the size of the whole window, including client area,
         * scrollbars, and non-client area decorations (caption, borders).
         * We do this because we need to check if the client area
         * without scrollbars is large enough to display the whole visual.
         * The new client area size passed by lParam already subtracts
         * the size of the scrollbars if they are currently displayed.
         * So checking is LOWORD(lParam) == visual_width and
         * HIWORD(lParam) == visual_height will never tell us to hide
         * the scrollbars because the client area would always be too small.
         * GetClientRect returns the same sizes given by lParam, so we
         * cannot use GetClientRect either.
         */
        GetWindowRect(hwnd, &rcWindow);
        iWidth = rcWindow.right - rcWindow.left;
        iHeight = rcWindow.bottom - rcWindow.top;

        /* Subtract the frame size from the window size. */
        iWidth -= 2 * GetSystemMetrics(SM_CXSIZEFRAME);
        iHeight -= (2 * GetSystemMetrics(SM_CYSIZEFRAME)
                    + GetSystemMetrics(SM_CYCAPTION));

        /*
         * Update scrollbar page sizes.
         * NOTE: If page size == range, then the scrollbar is
         * automatically hidden.
         */

        /* Is the naked client area large enough to show the whole visual? */
        if (iWidth < s_pScreenInfo->dwWidth
            || iHeight < s_pScreenInfo->dwHeight) {
            /* Client area too small to display visual, use scrollbars */
            iWidth -= GetSystemMetrics(SM_CXVSCROLL);
            iHeight -= GetSystemMetrics(SM_CYHSCROLL);
        }

        /* Set the horizontal scrollbar page size */
        si.cbSize = sizeof(si);
        si.fMask = SIF_PAGE | SIF_RANGE;
        si.nMin = 0;
        si.nMax = s_pScreenInfo->dwWidth - 1;
        si.nPage = iWidth;
        SetScrollInfo(hwnd, SB_HORZ, &si, TRUE);

        /* Set the vertical scrollbar page size */
        si.cbSize = sizeof(si);
        si.fMask = SIF_PAGE | SIF_RANGE;
        si.nMin = 0;
        si.nMax = s_pScreenInfo->dwHeight - 1;
        si.nPage = iHeight;
        SetScrollInfo(hwnd, SB_VERT, &si, TRUE);

        /*
         * NOTE: Scrollbars may have moved if they were at the 
         * far right/bottom, so we query their current position.
         */

        /* Get the horizontal scrollbar position and set the offset */
        si.cbSize = sizeof(si);
        si.fMask = SIF_POS;
        GetScrollInfo(hwnd, SB_HORZ, &si);
        s_pScreenInfo->dwXOffset = -si.nPos;

        /* Get the vertical scrollbar position and set the offset */
        si.cbSize = sizeof(si);
        si.fMask = SIF_POS;
        GetScrollInfo(hwnd, SB_VERT, &si);
        s_pScreenInfo->dwYOffset = -si.nPos;
    }
        return 0;

    case WM_SYSCOMMAND:
        if (s_pScreenInfo->iResizeMode == resizeWithRandr &&
            ((wParam & 0xfff0) == SC_MAXIMIZE ||
             (wParam & 0xfff0) == SC_RESTORE))
            PostMessage(hwnd, WM_EXITSIZEMOVE, 0, 0);
        break;

    case WM_ENTERSIZEMOVE:
        ErrorF("winWindowProc - WM_ENTERSIZEMOVE\n");
        break;

    case WM_EXITSIZEMOVE:
        ErrorF("winWindowProc - WM_EXITSIZEMOVE\n");

        if (s_pScreenInfo->iResizeMode == resizeWithRandr) {
            /* Set screen size to match new client area, if it is different to current */
            RECT rcClient;
            DWORD dwWidth, dwHeight;

            GetClientRect(hwnd, &rcClient);
            dwWidth = rcClient.right - rcClient.left;
            dwHeight = rcClient.bottom - rcClient.top;

            if ((s_pScreenInfo->dwWidth != dwWidth) ||
                (s_pScreenInfo->dwHeight != dwHeight)) {
                /* mm = dots * (25.4 mm / inch) / (dots / inch) */
                winDoRandRScreenSetSize(s_pScreen,
                                        dwWidth,
                                        dwHeight,
                                        (dwWidth * 25.4) / monitorResolution,
                                        (dwHeight * 25.4) / monitorResolution);
            }
        }

        break;

    case WM_VSCROLL:
    {
        SCROLLINFO si;
        int iVertPos;

#if CYGDEBUG
        winDebug("winWindowProc - WM_VSCROLL\n");
#endif

        /* Get vertical scroll bar info */
        si.cbSize = sizeof(si);
        si.fMask = SIF_ALL;
        GetScrollInfo(hwnd, SB_VERT, &si);

        /* Save the vertical position for comparison later */
        iVertPos = si.nPos;

        /*
         * Don't forget:
         * moving the scrollbar to the DOWN, scroll the content UP
         */
        switch (LOWORD(wParam)) {
        case SB_TOP:
            si.nPos = si.nMin;
            break;

        case SB_BOTTOM:
            si.nPos = si.nMax - si.nPage + 1;
            break;

        case SB_LINEUP:
            si.nPos -= 1;
            break;

        case SB_LINEDOWN:
            si.nPos += 1;
            break;

        case SB_PAGEUP:
            si.nPos -= si.nPage;
            break;

        case SB_PAGEDOWN:
            si.nPos += si.nPage;
            break;

        case SB_THUMBTRACK:
            si.nPos = si.nTrackPos;
            break;

        default:
            break;
        }

        /*
         * We retrieve the position after setting it,
         * because Windows may adjust it.
         */
        si.fMask = SIF_POS;
        SetScrollInfo(hwnd, SB_VERT, &si, TRUE);
        GetScrollInfo(hwnd, SB_VERT, &si);

        /* Scroll the window if the position has changed */
        if (si.nPos != iVertPos) {
            /* Save the new offset for bit block transfers, etc. */
            s_pScreenInfo->dwYOffset = -si.nPos;

            /* Change displayed region in the window */
            ScrollWindowEx(hwnd,
                           0,
                           iVertPos - si.nPos,
                           NULL, NULL, NULL, NULL, SW_INVALIDATE);

            /* Redraw the window contents */
            UpdateWindow(hwnd);
        }
    }
        return 0;

    case WM_HSCROLL:
    {
        SCROLLINFO si;
        int iHorzPos;

#if CYGDEBUG
        winDebug("winWindowProc - WM_HSCROLL\n");
#endif

        /* Get horizontal scroll bar info */
        si.cbSize = sizeof(si);
        si.fMask = SIF_ALL;
        GetScrollInfo(hwnd, SB_HORZ, &si);

        /* Save the horizontal position for comparison later */
        iHorzPos = si.nPos;

        /*
         * Don't forget:
         * moving the scrollbar to the RIGHT, scroll the content LEFT
         */
        switch (LOWORD(wParam)) {
        case SB_LEFT:
            si.nPos = si.nMin;
            break;

        case SB_RIGHT:
            si.nPos = si.nMax - si.nPage + 1;
            break;

        case SB_LINELEFT:
            si.nPos -= 1;
            break;

        case SB_LINERIGHT:
            si.nPos += 1;
            break;

        case SB_PAGELEFT:
            si.nPos -= si.nPage;
            break;

        case SB_PAGERIGHT:
            si.nPos += si.nPage;
            break;

        case SB_THUMBTRACK:
            si.nPos = si.nTrackPos;
            break;

        default:
            break;
        }

        /*
         * We retrieve the position after setting it,
         * because Windows may adjust it.
         */
        si.fMask = SIF_POS;
        SetScrollInfo(hwnd, SB_HORZ, &si, TRUE);
        GetScrollInfo(hwnd, SB_HORZ, &si);

        /* Scroll the window if the position has changed */
        if (si.nPos != iHorzPos) {
            /* Save the new offset for bit block transfers, etc. */
            s_pScreenInfo->dwXOffset = -si.nPos;

            /* Change displayed region in the window */
            ScrollWindowEx(hwnd,
                           iHorzPos - si.nPos,
                           0, NULL, NULL, NULL, NULL, SW_INVALIDATE);

            /* Redraw the window contents */
            UpdateWindow(hwnd);
        }
    }
        return 0;

    case WM_GETMINMAXINFO:
    {
        MINMAXINFO *pMinMaxInfo = (MINMAXINFO *) lParam;
        int iCaptionHeight;
        int iBorderHeight, iBorderWidth;

#if CYGDEBUG
        winDebug("winWindowProc - WM_GETMINMAXINFO - pScreenInfo: %08x\n",
                 s_pScreenInfo);
#endif

        /* Can't do anything without screen info */
        if (s_pScreenInfo == NULL
            || (s_pScreenInfo->iResizeMode != resizeWithScrollbars)
            || s_pScreenInfo->fFullScreen || !s_pScreenInfo->fDecoration
#ifdef XWIN_MULTIWINDOWEXTWM
            || s_pScreenInfo->fMWExtWM
#endif
            || s_pScreenInfo->fRootless
#ifdef XWIN_MULTIWINDOW
            || s_pScreenInfo->fMultiWindow
#endif
            )
            break;

        /*
         * Here we can override the maximum tracking size, which
         * is the largest size that can be assigned to our window
         * via the sizing border.
         */

        /*
         * FIXME: Do we only need to do this once, since our visual size
         * does not change?  Does Windows store this value statically
         * once we have set it once?
         */

        /* Get the border and caption sizes */
        iCaptionHeight = GetSystemMetrics(SM_CYCAPTION);
        iBorderWidth = 2 * GetSystemMetrics(SM_CXSIZEFRAME);
        iBorderHeight = 2 * GetSystemMetrics(SM_CYSIZEFRAME);

        /* Allow the full visual to be displayed */
        pMinMaxInfo->ptMaxTrackSize.x = s_pScreenInfo->dwWidth + iBorderWidth;
        pMinMaxInfo->ptMaxTrackSize.y
            = s_pScreenInfo->dwHeight + iBorderHeight + iCaptionHeight;
    }
        return 0;

    case WM_ERASEBKGND:
#if CYGDEBUG
        winDebug("winWindowProc - WM_ERASEBKGND\n");
#endif
        /*
         * Pretend that we did erase the background but we don't care,
         * the application uses the full window estate. This avoids some
         * flickering when resizing.
         */
        return TRUE;

    case WM_PAINT:
#if CYGDEBUG
        winDebug("winWindowProc - WM_PAINT\n");
#endif
        /* Only paint if we have privates and the server is enabled */
        if (s_pScreenPriv == NULL
            || !s_pScreenPriv->fEnabled
            || (s_pScreenInfo->fFullScreen && !s_pScreenPriv->fActive)
            || s_pScreenPriv->fBadDepth) {
            /* We don't want to paint */
            break;
        }

        /* Break out here if we don't have a valid paint routine */
        if (s_pScreenPriv->pwinBltExposedRegions == NULL)
            break;

        /* Call the engine dependent repainter */
        (*s_pScreenPriv->pwinBltExposedRegions) (s_pScreen);
        return 0;

    case WM_PALETTECHANGED:
    {
#if CYGDEBUG
        winDebug("winWindowProc - WM_PALETTECHANGED\n");
#endif
        /*
         * Don't process if we don't have privates or a colormap,
         * or if we have an invalid depth.
         */
        if (s_pScreenPriv == NULL
            || s_pScreenPriv->pcmapInstalled == NULL
            || s_pScreenPriv->fBadDepth)
            break;

        /* Return if we caused the palette to change */
        if ((HWND) wParam == hwnd) {
            /* Redraw the screen */
            (*s_pScreenPriv->pwinRedrawScreen) (s_pScreen);
            return 0;
        }

        /* Reinstall the windows palette */
        (*s_pScreenPriv->pwinRealizeInstalledPalette) (s_pScreen);

        /* Redraw the screen */
        (*s_pScreenPriv->pwinRedrawScreen) (s_pScreen);
        return 0;
    }

    case WM_MOUSEMOVE:
        /* We can't do anything without privates */
        if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
            break;

        /* We can't do anything without g_pwinPointer */
        if (g_pwinPointer == NULL)
            break;

        /* Has the mouse pointer crossed screens? */
        if (s_pScreen != miPointerGetScreen(g_pwinPointer))
            miPointerSetScreen(g_pwinPointer, s_pScreenInfo->dwScreen,
                               GET_X_LPARAM(lParam) - s_pScreenInfo->dwXOffset,
                               GET_Y_LPARAM(lParam) - s_pScreenInfo->dwYOffset);

        /* Are we tracking yet? */
        if (!s_fTracking) {
            TRACKMOUSEEVENT tme;

            /* Setup data structure */
            ZeroMemory(&tme, sizeof(tme));
            tme.cbSize = sizeof(tme);
            tme.dwFlags = TME_LEAVE;
            tme.hwndTrack = hwnd;

            /* Call the tracking function */
            if (!TrackMouseEvent(&tme))
                ErrorF("winWindowProc - TrackMouseEvent failed\n");

            /* Flag that we are tracking now */
            s_fTracking = TRUE;
        }

        /* Hide or show the Windows mouse cursor */
        if (g_fSoftwareCursor && g_fCursor &&
            (s_pScreenPriv->fActive || s_pScreenInfo->fLessPointer)) {
            /* Hide Windows cursor */
            g_fCursor = FALSE;
            ShowCursor(FALSE);
        }
        else if (g_fSoftwareCursor && !g_fCursor && !s_pScreenPriv->fActive
                 && !s_pScreenInfo->fLessPointer) {
            /* Show Windows cursor */
            g_fCursor = TRUE;
            ShowCursor(TRUE);
        }

        /* Deliver absolute cursor position to X Server */
        winEnqueueMotion(GET_X_LPARAM(lParam) - s_pScreenInfo->dwXOffset,
                         GET_Y_LPARAM(lParam) - s_pScreenInfo->dwYOffset);
        return 0;

    case WM_NCMOUSEMOVE:
        /*
         * We break instead of returning 0 since we need to call
         * DefWindowProc to get the mouse cursor changes
         * and min/max/close button highlighting in Windows XP.
         * The Platform SDK says that you should return 0 if you
         * process this message, but it fails to mention that you
         * will give up any default functionality if you do return 0.
         */

        /* We can't do anything without privates */
        if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
            break;

        /* Non-client mouse movement, show Windows cursor */
        if (g_fSoftwareCursor && !g_fCursor) {
            g_fCursor = TRUE;
            ShowCursor(TRUE);
        }
        break;

    case WM_MOUSELEAVE:
        /* Mouse has left our client area */

        /* Flag that we are no longer tracking */
        s_fTracking = FALSE;

        /* Show the mouse cursor, if necessary */
        if (g_fSoftwareCursor && !g_fCursor) {
            g_fCursor = TRUE;
            ShowCursor(TRUE);
        }
        return 0;

    case WM_LBUTTONDBLCLK:
    case WM_LBUTTONDOWN:
        if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
            break;
        if (s_pScreenInfo->fRootless
#ifdef XWIN_MULTIWINDOWEXTWM
            || s_pScreenInfo->fMWExtWM
#endif
            )
            SetCapture(hwnd);
        return winMouseButtonsHandle(s_pScreen, ButtonPress, Button1, wParam);

    case WM_LBUTTONUP:
        if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
            break;
        if (s_pScreenInfo->fRootless
#ifdef XWIN_MULTIWINDOWEXTWM
            || s_pScreenInfo->fMWExtWM
#endif
            )
            ReleaseCapture();
        return winMouseButtonsHandle(s_pScreen, ButtonRelease, Button1, wParam);

    case WM_MBUTTONDBLCLK:
    case WM_MBUTTONDOWN:
        if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
            break;
        if (s_pScreenInfo->fRootless
#ifdef XWIN_MULTIWINDOWEXTWM
            || s_pScreenInfo->fMWExtWM
#endif
            )
            SetCapture(hwnd);
        return winMouseButtonsHandle(s_pScreen, ButtonPress, Button2, wParam);

    case WM_MBUTTONUP:
        if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
            break;
        if (s_pScreenInfo->fRootless
#ifdef XWIN_MULTIWINDOWEXTWM
            || s_pScreenInfo->fMWExtWM
#endif
            )
            ReleaseCapture();
        return winMouseButtonsHandle(s_pScreen, ButtonRelease, Button2, wParam);

    case WM_RBUTTONDBLCLK:
    case WM_RBUTTONDOWN:
        if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
            break;
        if (s_pScreenInfo->fRootless
#ifdef XWIN_MULTIWINDOWEXTWM
            || s_pScreenInfo->fMWExtWM
#endif
            )
            SetCapture(hwnd);
        return winMouseButtonsHandle(s_pScreen, ButtonPress, Button3, wParam);

    case WM_RBUTTONUP:
        if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
            break;
        if (s_pScreenInfo->fRootless
#ifdef XWIN_MULTIWINDOWEXTWM
            || s_pScreenInfo->fMWExtWM
#endif
            )
            ReleaseCapture();
        return winMouseButtonsHandle(s_pScreen, ButtonRelease, Button3, wParam);

    case WM_XBUTTONDBLCLK:
    case WM_XBUTTONDOWN:
        if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
            break;
        if (s_pScreenInfo->fRootless
#ifdef XWIN_MULTIWINDOWEXTWM
            || s_pScreenInfo->fMWExtWM
#endif
            )
            SetCapture(hwnd);
        return winMouseButtonsHandle(s_pScreen, ButtonPress, HIWORD(wParam) + 5,
                                     wParam);
    case WM_XBUTTONUP:
        if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
            break;
        if (s_pScreenInfo->fRootless
#ifdef XWIN_MULTIWINDOWEXTWM
            || s_pScreenInfo->fMWExtWM
#endif
            )
            ReleaseCapture();
        return winMouseButtonsHandle(s_pScreen, ButtonRelease,
                                     HIWORD(wParam) + 5, wParam);

    case WM_TIMER:
        if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
            break;

        /* Branch on the timer id */
        switch (wParam) {
        case WIN_E3B_TIMER_ID:
            /* Send delayed button press */
            winMouseButtonsSendEvent(ButtonPress,
                                     s_pScreenPriv->iE3BCachedPress);

            /* Kill this timer */
            KillTimer(s_pScreenPriv->hwndScreen, WIN_E3B_TIMER_ID);

            /* Clear screen privates flags */
            s_pScreenPriv->iE3BCachedPress = 0;
            break;

        case WIN_POLLING_MOUSE_TIMER_ID:
        {
            POINT point;
            WPARAM wL, wM, wR, wShift, wCtrl;
            LPARAM lPos;

            /* Get the current position of the mouse cursor */
            GetCursorPos(&point);

            /* Map from screen (-X, -Y) to root (0, 0) */
            point.x -= GetSystemMetrics(SM_XVIRTUALSCREEN);
            point.y -= GetSystemMetrics(SM_YVIRTUALSCREEN);

            /* Deliver absolute cursor position to X Server */
            winEnqueueMotion(point.x, point.y);

            /* Check if a button was released but we didn't see it */
            GetCursorPos(&point);
            wL = (GetKeyState(VK_LBUTTON) & 0x8000) ? MK_LBUTTON : 0;
            wM = (GetKeyState(VK_MBUTTON) & 0x8000) ? MK_MBUTTON : 0;
            wR = (GetKeyState(VK_RBUTTON) & 0x8000) ? MK_RBUTTON : 0;
            wShift = (GetKeyState(VK_SHIFT) & 0x8000) ? MK_SHIFT : 0;
            wCtrl = (GetKeyState(VK_CONTROL) & 0x8000) ? MK_CONTROL : 0;
            lPos = MAKELPARAM(point.x, point.y);
            if (g_fButton[0] & !wL)
                PostMessage(hwnd, WM_LBUTTONUP, wCtrl | wM | wR | wShift, lPos);
            if (g_fButton[1] & !wM)
                PostMessage(hwnd, WM_MBUTTONUP, wCtrl | wL | wR | wShift, lPos);
            if (g_fButton[2] & !wR)
                PostMessage(hwnd, WM_RBUTTONUP, wCtrl | wL | wM | wShift, lPos);
        }
        }
        return 0;

    case WM_CTLCOLORSCROLLBAR:
        FatalError("winWindowProc - WM_CTLCOLORSCROLLBAR - We are not "
                   "supposed to get this message.  Exiting.\n");
        return 0;

    case WM_MOUSEWHEEL:
        if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
            break;
#if CYGDEBUG
        winDebug("winWindowProc - WM_MOUSEWHEEL\n");
#endif
        winMouseWheel(s_pScreen, GET_WHEEL_DELTA_WPARAM(wParam));
        break;

    case WM_SETFOCUS:
        if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
            break;

        /* Restore the state of all mode keys */
        winRestoreModeKeyStates();

        /* Add the keyboard hook if possible */
        if (g_fKeyboardHookLL)
            g_fKeyboardHookLL = winInstallKeyboardHookLL();
        return 0;

    case WM_KILLFOCUS:
        if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
            break;

        /* Release any pressed keys */
        winKeybdReleaseKeys();

        /* Remove our keyboard hook if it is installed */
        winRemoveKeyboardHookLL();
        return 0;

    case WM_SYSKEYDOWN:
    case WM_KEYDOWN:
        if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
            break;

        /*
         * FIXME: Catching Alt-F4 like this is really terrible.  This should
         * be generalized to handle other Windows keyboard signals.  Actually,
         * the list keys to catch and the actions to perform when caught should
         * be configurable; that way user's can customize the keys that they
         * need to have passed through to their window manager or apps, or they
         * can remap certain actions to new key codes that do not conflict
         * with the X apps that they are using.  Yeah, that'll take awhile.
         */
        if ((s_pScreenInfo->fUseWinKillKey && wParam == VK_F4
             && (GetKeyState(VK_MENU) & 0x8000))
            || (s_pScreenInfo->fUseUnixKillKey && wParam == VK_BACK
                && (GetKeyState(VK_MENU) & 0x8000)
                && (GetKeyState(VK_CONTROL) & 0x8000))) {
            /*
             * Better leave this message here, just in case some unsuspecting
             * user enters Alt + F4 and is surprised when the application
             * quits.
             */
            ErrorF("winWindowProc - WM_*KEYDOWN - Closekey hit, quitting\n");

            /* Display Exit dialog */
            winDisplayExitDialog(s_pScreenPriv);
            return 0;
        }

        /*
         * Don't do anything for the Windows keys, as focus will soon
         * be returned to Windows.  We may be able to trap the Windows keys,
         * but we should determine if that is desirable before doing so.
         */
        if ((wParam == VK_LWIN || wParam == VK_RWIN) && !g_fKeyboardHookLL)
            break;

        /* Discard fake Ctrl_L events that precede AltGR on non-US keyboards */
        if (winIsFakeCtrl_L(message, wParam, lParam))
            return 0;

        /* 
         * Discard presses generated from Windows auto-repeat
         */
        if (lParam & (1 << 30)) {
            switch (wParam) {
                /* ago: Pressing LControl while RControl is pressed is 
                 * Indicated as repeat. Fix this!
                 */
            case VK_CONTROL:
            case VK_SHIFT:
                if (winCheckKeyPressed(wParam, lParam))
                    return 0;
                break;
            default:
                return 0;
            }
        }

        /* Translate Windows key code to X scan code */
        winTranslateKey(wParam, lParam, &iScanCode);

        /* Ignore repeats for CapsLock */
        if (wParam == VK_CAPITAL)
            lParam = 1;

        /* Send the key event(s) */
        for (i = 0; i < LOWORD(lParam); ++i)
            winSendKeyEvent(iScanCode, TRUE);
        return 0;

    case WM_SYSKEYUP:
    case WM_KEYUP:
        if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
            break;

        /*
         * Don't do anything for the Windows keys, as focus will soon
         * be returned to Windows.  We may be able to trap the Windows keys,
         * but we should determine if that is desirable before doing so.
         */
        if ((wParam == VK_LWIN || wParam == VK_RWIN) && !g_fKeyboardHookLL)
            break;

        /* Ignore the fake Ctrl_L that follows an AltGr release */
        if (winIsFakeCtrl_L(message, wParam, lParam))
            return 0;

        /* Enqueue a keyup event */
        winTranslateKey(wParam, lParam, &iScanCode);
        winSendKeyEvent(iScanCode, FALSE);

        /* Release all pressed shift keys */
        if (wParam == VK_SHIFT)
            winFixShiftKeys(iScanCode);
        return 0;

    case WM_HOTKEY:
        if (s_pScreenPriv == NULL)
            break;

        /* Call the engine-specific hot key handler */
        (*s_pScreenPriv->pwinHotKeyAltTab) (s_pScreen);
        return 0;

    case WM_ACTIVATE:
        if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
            break;

        /* TODO: Override display of window when we have a bad depth */
        if (LOWORD(wParam) != WA_INACTIVE && s_pScreenPriv->fBadDepth) {
            ErrorF("winWindowProc - WM_ACTIVATE - Bad depth, trying "
                   "to override window activation\n");

            /* Minimize the window */
            ShowWindow(hwnd, SW_MINIMIZE);

            /* Display dialog box */
            if (g_hDlgDepthChange != NULL) {
                /* Make the existing dialog box active */
                SetActiveWindow(g_hDlgDepthChange);
            }
            else {
                /* TODO: Recreate the dialog box and bring to the top */
                ShowWindow(g_hDlgDepthChange, SW_SHOWDEFAULT);
            }

            /* Don't do any other processing of this message */
            return 0;
        }

#if CYGDEBUG
        winDebug("winWindowProc - WM_ACTIVATE\n");
#endif

        /*
         * Focus is being changed to another window.
         * The other window may or may not belong to
         * our process.
         */

        /* Clear any lingering wheel delta */
        s_pScreenPriv->iDeltaZ = 0;

        /* Reshow the Windows mouse cursor if we are being deactivated */
        if (g_fSoftwareCursor && LOWORD(wParam) == WA_INACTIVE && !g_fCursor) {
            /* Show Windows cursor */
            g_fCursor = TRUE;
            ShowCursor(TRUE);
        }
        return 0;

    case WM_ACTIVATEAPP:
        if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
            break;

#if CYGDEBUG || TRUE
        winDebug("winWindowProc - WM_ACTIVATEAPP\n");
#endif

        /* Activate or deactivate */
        s_pScreenPriv->fActive = wParam;

        /* Reshow the Windows mouse cursor if we are being deactivated */
        if (g_fSoftwareCursor && !s_pScreenPriv->fActive && !g_fCursor) {
            /* Show Windows cursor */
            g_fCursor = TRUE;
            ShowCursor(TRUE);
        }

#ifdef XWIN_CLIPBOARD
        /* Make sure the clipboard chain is ok. */
        winFixClipboardChain();
#endif

        /* Call engine specific screen activation/deactivation function */
        (*s_pScreenPriv->pwinActivateApp) (s_pScreen);

#ifdef XWIN_MULTIWINDOWEXTWM
        if (s_pScreenPriv->fActive) {
            /* Restack all window unless using built-in wm. */
            if (s_pScreenInfo->fInternalWM && s_pScreenInfo->fAnotherWMRunning)
                winMWExtWMRestackWindows(s_pScreen);
        }
#endif

        return 0;

    case WM_COMMAND:
        switch (LOWORD(wParam)) {
        case ID_APP_EXIT:
            /* Display Exit dialog */
            winDisplayExitDialog(s_pScreenPriv);
            return 0;

#ifdef XWIN_MULTIWINDOW
        case ID_APP_HIDE_ROOT:
            if (s_pScreenPriv->fRootWindowShown)
                ShowWindow(s_pScreenPriv->hwndScreen, SW_HIDE);
            else
                ShowWindow(s_pScreenPriv->hwndScreen, SW_SHOW);
            s_pScreenPriv->fRootWindowShown = !s_pScreenPriv->fRootWindowShown;
            return 0;
#endif

        case ID_APP_ABOUT:
            /* Display the About box */
            winDisplayAboutDialog(s_pScreenPriv);
            return 0;

        default:
            /* It's probably one of the custom menus... */
            if (HandleCustomWM_COMMAND(0, LOWORD(wParam)))
                return 0;
        }
        break;

    case WM_ENDSESSION:
    case WM_GIVEUP:
        /* Tell X that we are giving up */
#ifdef XWIN_MULTIWINDOW
        if (s_pScreenInfo->fMultiWindow)
            winDeinitMultiWindowWM();
#endif
        GiveUp(0);
        return 0;

    case WM_CLOSE:
        /* Display Exit dialog */
        winDisplayExitDialog(s_pScreenPriv);
        return 0;

    case WM_SETCURSOR:
        if (LOWORD(lParam) == HTCLIENT) {
            if (!g_fSoftwareCursor)
                SetCursor(s_pScreenPriv->cursor.handle);
            return TRUE;
        }
        break;

#ifdef XWIN_MULTIWINDOWEXTWM
    case WM_MANAGE:
        ErrorF("winWindowProc - WM_MANAGE\n");
        s_pScreenInfo->fAnotherWMRunning = FALSE;

        if (s_pScreenInfo->fInternalWM) {
            EnumThreadWindows(g_dwCurrentThreadID, winMWExtWMDecorateWindow, 0);
            //RootlessRepositionWindows (s_pScreen);
        }
        break;

    case WM_UNMANAGE:
        ErrorF("winWindowProc - WM_UNMANAGE\n");
        s_pScreenInfo->fAnotherWMRunning = TRUE;

        if (s_pScreenInfo->fInternalWM) {
            EnumThreadWindows(g_dwCurrentThreadID, winMWExtWMDecorateWindow, 0);
            winMWExtWMRestackWindows(s_pScreen);
        }
        break;
#endif

    default:
        if (message == s_uTaskbarRestart) {
            winInitNotifyIcon(s_pScreenPriv);
        }
        break;
    }

    return DefWindowProc(hwnd, message, wParam, lParam);
}