예제 #1
0
파일: misc.c 프로젝트: Moteesh/reactos
HBRUSH
FASTCALL
GetControlColor(
   PWND pwndParent,
   PWND pwnd,
   HDC hdc,
   UINT CtlMsg)
{
    HBRUSH hBrush;

    if (!pwndParent) pwndParent = pwnd;

    if ( pwndParent->head.pti->ppi != PsGetCurrentProcessWin32Process())
    {
       return (HBRUSH)IntDefWindowProc( pwndParent, CtlMsg, (WPARAM)hdc, (LPARAM)UserHMGetHandle(pwnd), FALSE);
    }

    hBrush = (HBRUSH)co_IntSendMessage( UserHMGetHandle(pwndParent), CtlMsg, (WPARAM)hdc, (LPARAM)UserHMGetHandle(pwnd));

    if (!hBrush || !GreIsHandleValid(hBrush))
    {
       hBrush = (HBRUSH)IntDefWindowProc( pwndParent, CtlMsg, (WPARAM)hdc, (LPARAM)UserHMGetHandle(pwnd), FALSE);
    }
    return hBrush;
}
예제 #2
0
파일: kbdlayout.c 프로젝트: RPG-7/reactos
/*
 * co_UserActivateKbl
 *
 * Activates given layout in specified thread
 */
static PKL
co_UserActivateKbl(PTHREADINFO pti, PKL pKl, UINT Flags)
{
    PKL pklPrev;

    pklPrev = pti->KeyboardLayout;
    if (pklPrev)
        UserDereferenceObject(pklPrev);

    pti->KeyboardLayout = pKl;
    pti->pClientInfo->hKL = pKl->hkl;
    UserReferenceObject(pKl);

    if (Flags & KLF_SETFORPROCESS)
    {
        // FIXME
    }

    // Send WM_INPUTLANGCHANGE to thread's focus window
    co_IntSendMessage(pti->MessageQueue->spwndFocus ? UserHMGetHandle(pti->MessageQueue->spwndFocus) : 0,
                      WM_INPUTLANGCHANGE,
                      (WPARAM)pKl->iBaseCharset, // FIXME: How to set it?
                      (LPARAM)pKl->hkl); // hkl

    return pklPrev;
}
예제 #3
0
VOID FASTCALL
FindRemoveAsyncMsg(PWND Wnd, WPARAM wParam)
{
   PTHREADINFO pti;
   PUSER_SENT_MESSAGE Message;
   PLIST_ENTRY Entry;

   if (!Wnd) return;

   pti = Wnd->head.pti;

   if (!IsListEmpty(&pti->SentMessagesListHead))
   {
      // Scan sent queue messages to see if we received async messages.
      Entry = pti->SentMessagesListHead.Flink;
      Message = CONTAINING_RECORD(Entry, USER_SENT_MESSAGE, ListEntry);
      do
      {
         if (IsListEmpty(Entry)) return;
         if (!Message) return;
         Entry = Message->ListEntry.Flink;

         if (Message->Msg.message == WM_ASYNC_SETACTIVEWINDOW &&
             Message->Msg.hwnd == UserHMGetHandle(Wnd) &&
             Message->Msg.wParam == wParam )
         {
             ERR("ASYNC SAW: Found one in the Sent Msg Queue! %p Activate/Deactivate %d\n", Message->Msg.hwnd,!!wParam);
             RemoveEntryList(&Message->ListEntry); // Purge the entry.
             ExFreePoolWithTag(Message, TAG_USRMSG);
         }
         Message = CONTAINING_RECORD(Entry, USER_SENT_MESSAGE, ListEntry);
      }
      while (Entry != &pti->SentMessagesListHead);
   }
}
예제 #4
0
VOID FASTCALL
FindRemoveAsyncMsg(PWND Wnd)
{
   PTHREADINFO pti;
   PUSER_SENT_MESSAGE Message;
   PLIST_ENTRY Entry;

   if (!Wnd) return;

   pti = Wnd->head.pti;

   if (!IsListEmpty(&pti->SentMessagesListHead))
   {
      // Scan sent queue messages to see if we received async messages.
      Entry = pti->SentMessagesListHead.Flink;
      Message = CONTAINING_RECORD(Entry, USER_SENT_MESSAGE, ListEntry);
      do
      {
         if (Message->Msg.message == WM_ASYNC_SETACTIVEWINDOW &&
             Message->Msg.hwnd == UserHMGetHandle(Wnd) &&
             Message->Msg.wParam == 0 )
         {
             TRACE("ASYNC SAW: Found one in the Sent Msg Queue! %p\n", Message->Msg.hwnd);
             RemoveEntryList(Entry); // Purge the entry.
         }
         Entry = Message->ListEntry.Flink;
         Message = CONTAINING_RECORD(Entry, USER_SENT_MESSAGE, ListEntry);
      }
      while (Entry != &pti->SentMessagesListHead);
   }
}
예제 #5
0
static
BOOL
FASTCALL
RemoveTimer(PTIMER pTmr)
{
  BOOL Ret = FALSE;
  if (pTmr)
  {
     /* Set the flag, it will be removed when ready */
     RemoveEntryList(&pTmr->ptmrList);
     if ((pTmr->pWnd == NULL) && (!(pTmr->flags & TMRF_SYSTEM))) // System timers are reusable.
     {
        UINT_PTR IDEvent;

        IDEvent = NUM_WINDOW_LESS_TIMERS - pTmr->nID;
        IntLockWindowlessTimerBitmap();
        RtlClearBit(&WindowLessTimersBitMap, IDEvent);
        IntUnlockWindowlessTimerBitmap();
     }
     UserDereferenceObject(pTmr);
     Ret = UserDeleteObject( UserHMGetHandle(pTmr), otTimer);
  }
  if (!Ret) ERR("Warning: Unable to delete timer\n");

  return Ret;
}
예제 #6
0
//
// Dispatch MsgQueue Event Call processor!
//
LRESULT
FASTCALL
co_EVENT_CallEvents( DWORD event,
                     HWND hwnd, 
                     UINT_PTR idObject,
                     LONG_PTR idChild)
{
   PEVENTHOOK pEH;
   LRESULT Result;
   PEVENTPACK pEP = (PEVENTPACK)idChild;

   pEH = pEP->pEH;
   
   Result = co_IntCallEventProc( UserHMGetHandle(pEH),
                                 event,
                                 hwnd,
                                 pEP->idObject,
                                 pEP->idChild,
                                 PtrToUint(NtCurrentTeb()->ClientId.UniqueThread),
                                (DWORD)EngGetTickCount(),
                                 pEH->Proc);

   ExFreePoolWithTag(pEP, TAG_HOOK);
   return Result;
}
예제 #7
0
HWND FASTCALL
UserGetForegroundWindow(VOID)
{
   PUSER_MESSAGE_QUEUE ForegroundQueue;

   ForegroundQueue = IntGetFocusMessageQueue();
   return( ForegroundQueue ? (ForegroundQueue->spwndActive ? UserHMGetHandle(ForegroundQueue->spwndActive) : 0) : 0);
}
예제 #8
0
HWND FASTCALL UserGetActiveWindow(VOID)
{
   PTHREADINFO pti;
   PUSER_MESSAGE_QUEUE ThreadQueue;

   pti = PsGetCurrentThreadWin32Thread();
   ThreadQueue = pti->MessageQueue;
   return( ThreadQueue ? (ThreadQueue->spwndActive ? UserHMGetHandle(ThreadQueue->spwndActive) : 0) : 0);
}
예제 #9
0
VOID FASTCALL
IntSendFocusMessages( PTHREADINFO pti, PWND pWnd)
{
   PWND pWndPrev;
   PUSER_MESSAGE_QUEUE ThreadQueue = pti->MessageQueue; // Queue can change...

   ThreadQueue->QF_flags &= ~QF_FOCUSNULLSINCEACTIVE;
   if (!pWnd && ThreadQueue->spwndActive)
   {
      ThreadQueue->QF_flags |= QF_FOCUSNULLSINCEACTIVE;
   }

   pWndPrev = ThreadQueue->spwndFocus;

   /* check if the specified window can be set in the input data of a given queue */
   if (!pWnd || ThreadQueue == pWnd->head.pti->MessageQueue)
      /* set the current thread focus window */
      ThreadQueue->spwndFocus = pWnd;

   if (pWnd)
   {
      if (pWndPrev)
      {
         //co_IntPostOrSendMessage(UserHMGetHandle(pWndPrev), WM_KILLFOCUS, (WPARAM)UserHMGetHandle(pWnd), 0);
         co_IntSendMessage(UserHMGetHandle(pWndPrev), WM_KILLFOCUS, (WPARAM)UserHMGetHandle(pWnd), 0);
      }
      if (ThreadQueue->spwndFocus == pWnd)
      {
         IntNotifyWinEvent(EVENT_OBJECT_FOCUS, pWnd, OBJID_CLIENT, CHILDID_SELF, 0);
         //co_IntPostOrSendMessage(UserHMGetHandle(pWnd), WM_SETFOCUS, (WPARAM)(pWndPrev ? UserHMGetHandle(pWndPrev) : NULL), 0);
         co_IntSendMessage(UserHMGetHandle(pWnd), WM_SETFOCUS, (WPARAM)(pWndPrev ? UserHMGetHandle(pWndPrev) : NULL), 0);
      }
   }
   else
   {
      if (pWndPrev)
      {
         IntNotifyWinEvent(EVENT_OBJECT_FOCUS, NULL, OBJID_CLIENT, CHILDID_SELF, 0);
         //co_IntPostOrSendMessage(UserHMGetHandle(pWndPrev), WM_KILLFOCUS, 0, 0);
         co_IntSendMessage(UserHMGetHandle(pWndPrev), WM_KILLFOCUS, 0, 0);
      }
   }
}
예제 #10
0
HWND FASTCALL
IntGetThreadFocusWindow(VOID)
{
   PTHREADINFO pti;
   PUSER_MESSAGE_QUEUE ThreadQueue;

   pti = PsGetCurrentThreadWin32Thread();
   ThreadQueue = pti->MessageQueue;
   if (!ThreadQueue)
     return NULL;
   return ThreadQueue->spwndFocus ? UserHMGetHandle(ThreadQueue->spwndFocus) : 0;
}
예제 #11
0
파일: defwnd.c 프로젝트: staring/RosFE
LRESULT FASTCALL
DefWndGetIcon(PWND pWnd, WPARAM wParam, LPARAM lParam)
{
    HICON hIconRet;
    if ( wParam > ICON_SMALL2 )
    {
        SetLastError(ERROR_INVALID_PARAMETER);
        return 0;
    }
    switch(wParam)
    {
        case ICON_BIG:
            hIconRet = UserGetProp(UserHMGetHandle(pWnd), gpsi->atomIconProp);
            break;
        case ICON_SMALL:
        case ICON_SMALL2:
            hIconRet = UserGetProp(UserHMGetHandle(pWnd), gpsi->atomIconSmProp);
            break;
        default:
            break;
    }
    return (LRESULT)hIconRet;
}
예제 #12
0
/* IntAttachMonitor
 *
 * Creates a new MONITOR and appends it to the list of monitors.
 *
 * Arguments
 *
 *   pGdiDevice     Pointer to the PDEVOBJ onto which the monitor was attached
 *   DisplayNumber  Display Number (starting with 0)
 *
 * Return value
 *   Returns a NTSTATUS
 */
NTSTATUS
IntAttachMonitor(IN PDEVOBJ *pGdiDevice,
                 IN ULONG DisplayNumber)
{
    PMONITOR Monitor;
    WCHAR Buffer[CCHDEVICENAME];

    TRACE("Attaching monitor...\n");

    /* create new monitor object */
    Monitor = IntCreateMonitorObject();
    if (Monitor == NULL)
    {
        TRACE("Couldnt create monitor object\n");
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    _snwprintf(Buffer, CCHDEVICENAME, L"\\\\.\\DISPLAY%d", DisplayNumber + 1);
    if (!RtlCreateUnicodeString(&Monitor->DeviceName, Buffer))
    {
        TRACE("Couldn't duplicate monitor name!\n");
        UserDereferenceObject(Monitor);
        UserDeleteObject(UserHMGetHandle(Monitor), otMonitor);
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    Monitor->GdiDevice = pGdiDevice;
    Monitor->cWndStack = 0;

    if (gMonitorList == NULL)
    {
        TRACE("Primary monitor is beeing attached\n");
        Monitor->IsPrimary = TRUE;
        gMonitorList = Monitor;
    }
    else
    {
        PMONITOR p;
        TRACE("Additional monitor is beeing attached\n");
        for (p = gMonitorList; p->Next != NULL; p = p->Next)
        {
            p->Next = Monitor;
        }
        Monitor->Prev = p;
    }

    IntUpdateMonitorSize(pGdiDevice);

    return STATUS_SUCCESS;
}
예제 #13
0
파일: defwnd.c 프로젝트: staring/RosFE
// WM_SETICON
LRESULT FASTCALL
DefWndSetIcon(PWND pWnd, WPARAM wParam, LPARAM lParam)
{
    HICON hIcon, hIconSmall, hIconOld;

    if ( wParam > ICON_SMALL2 )
    {  
        SetLastError(ERROR_INVALID_PARAMETER);
        return 0;
    }
    hIconSmall = UserGetProp(UserHMGetHandle(pWnd), gpsi->atomIconSmProp);
    hIcon = UserGetProp(UserHMGetHandle(pWnd), gpsi->atomIconProp);

    hIconOld = wParam == ICON_BIG ? hIcon : hIconSmall;

    switch(wParam)
    {
        case ICON_BIG:
            hIcon = (HICON)lParam;
            break;
        case ICON_SMALL:
            hIconSmall = (HICON)lParam;
            break;
        case ICON_SMALL2:
            ERR("FIXME: Set ICON_SMALL2 support!\n");
        default:
            break;
    }

    NtUserSetProp(UserHMGetHandle(pWnd), gpsi->atomIconProp, hIcon);
    NtUserSetProp(UserHMGetHandle(pWnd), gpsi->atomIconSmProp, hIconSmall);

    if ((pWnd->style & WS_CAPTION ) == WS_CAPTION)
       UserPaintCaption(UserHMGetHandle(pWnd));  /* Repaint caption */

    return (LRESULT)hIconOld;
}
예제 #14
0
파일: monitor.c 프로젝트: RPG-7/reactos
/* IntDestroyMonitorObject
 *
 * Destroys a MONITOR
 * You have to be the owner of the monitors lock to safely destroy it.
 *
 * Arguments
 *
 *   pMonitor
 *      Pointer to the MONITOR which shall be deleted
 */
static
void
IntDestroyMonitorObject(IN PMONITOR pMonitor)
{
    /* Remove monitor region */
    if (pMonitor->hrgnMonitor)
    {
        GreSetObjectOwner(pMonitor->hrgnMonitor, GDI_OBJ_HMGR_POWNED);
        GreDeleteObject(pMonitor->hrgnMonitor);
    }

    /* Destroy monitor object */
    UserDereferenceObject(pMonitor);
    UserDeleteObject(UserHMGetHandle(pMonitor), TYPE_MONITOR);
}
예제 #15
0
HWND APIENTRY
IntGetCapture(VOID)
{
   PTHREADINFO pti;
   PUSER_MESSAGE_QUEUE ThreadQueue;
   DECLARE_RETURN(HWND);

   TRACE("Enter IntGetCapture\n");

   pti = PsGetCurrentThreadWin32Thread();
   ThreadQueue = pti->MessageQueue;
   RETURN( ThreadQueue ? (ThreadQueue->spwndCapture ? UserHMGetHandle(ThreadQueue->spwndCapture) : 0) : 0);

CLEANUP:
   TRACE("Leave IntGetCapture, ret=%p\n", _ret_);
   END_CLEANUP;
}
예제 #16
0
static
BOOL
FASTCALL
IntRemoveEvent(PEVENTHOOK pEH)
{
   if (pEH)
   {
      TRACE("IntRemoveEvent pEH 0x%x\n",pEH);
      KeEnterCriticalRegion();
      RemoveEntryList(&pEH->Chain);
      GlobalEvents->Counts--;
      if (!GlobalEvents->Counts) gpsi->dwInstalledEventHooks = 0;
      UserDeleteObject(UserHMGetHandle(pEH), otEvent);
      KeLeaveCriticalRegion();
      return TRUE;
   }
   return FALSE;
}
예제 #17
0
파일: window.c 프로젝트: hoangduit/reactos
/*
 * @implemented
 */
HWND WINAPI
GetDesktopWindow(VOID)
{
    PWND Wnd;
    HWND Ret = NULL;

    _SEH2_TRY
    {
        Wnd = GetThreadDesktopWnd();
        if (Wnd != NULL)
            Ret = UserHMGetHandle(Wnd);
    }
    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
    {
        /* Do nothing */
    }
    _SEH2_END;

    return Ret;
}
예제 #18
0
파일: window.c 프로젝트: hoangduit/reactos
/*
 * @implemented
 */
HWND WINAPI
GetAncestor(HWND hwnd, UINT gaFlags)
{
    HWND Ret = NULL;
    PWND Ancestor, Wnd;

    Wnd = ValidateHwnd(hwnd);
    if (!Wnd)
        return NULL;

    _SEH2_TRY
    {
        Ancestor = NULL;
        switch (gaFlags)
        {
            case GA_PARENT:
                if (Wnd->spwndParent != NULL)
                    Ancestor = DesktopPtrToUser(Wnd->spwndParent);
                break;

            default:
                /* FIXME: Call win32k for now */
                Wnd = NULL;
                break;
        }

        if (Ancestor != NULL)
            Ret = UserHMGetHandle(Ancestor);
    }
    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
    {
        /* Do nothing */
    }
    _SEH2_END;

    if (!Wnd) /* Fall back */
        Ret = NtUserGetAncestor(hwnd, gaFlags);

    return Ret;
}
예제 #19
0
파일: window.c 프로젝트: hoangduit/reactos
/*
 * @implemented
 */
HWND WINAPI
GetLastActivePopup(HWND hWnd)
{
    PWND Wnd;
    HWND Ret = hWnd;

    Wnd = ValidateHwnd(hWnd);
    if (Wnd != NULL)
    {
        _SEH2_TRY
        {
            if (Wnd->spwndLastActive)
            {
               PWND LastActive = DesktopPtrToUser(Wnd->spwndLastActive);
               Ret = UserHMGetHandle(LastActive);
            }
        }
        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
        {
            /* Do nothing */
        }
        _SEH2_END;
    }
예제 #20
0
HWND APIENTRY
NtUserSetActiveWindow(HWND hWnd)
{
   USER_REFERENCE_ENTRY Ref;
   HWND hWndPrev;
   PWND Window;
   DECLARE_RETURN(HWND);

   TRACE("Enter NtUserSetActiveWindow(%p)\n", hWnd);
   UserEnterExclusive();

   Window = NULL;
   if (hWnd)
   {
      if (!(Window = UserGetWindowObject(hWnd)))
      {
         ERR("NtUserSetActiveWindow: Invalid handle 0x%p!\n",hWnd);
         RETURN( NULL);
      }
   }

   if (!Window ||
        Window->head.pti->MessageQueue == gptiCurrent->MessageQueue)
   {
      hWndPrev = gptiCurrent->MessageQueue->spwndActive ? UserHMGetHandle(gptiCurrent->MessageQueue->spwndActive) : NULL;
      if (Window) UserRefObjectCo(Window, &Ref);
      UserSetActiveWindow(Window);
      if (Window) UserDerefObjectCo(Window);
      RETURN( hWndPrev ? (IntIsWindow(hWndPrev) ? hWndPrev : 0) : 0 );
   }
   RETURN( NULL);

CLEANUP:
   TRACE("Leave NtUserSetActiveWindow, ret=%p\n",_ret_);
   UserLeave();
   END_CLEANUP;
}
예제 #21
0
파일: misc.c 프로젝트: Moteesh/reactos
BOOL
APIENTRY
NtUserGetGUIThreadInfo(
   DWORD idThread, /* If NULL use foreground thread */
   LPGUITHREADINFO lpgui)
{
   NTSTATUS Status;
   PTHRDCARETINFO CaretInfo;
   GUITHREADINFO SafeGui;
   PDESKTOP Desktop;
   PUSER_MESSAGE_QUEUE MsgQueue;
   PTHREADINFO W32Thread;
   PETHREAD Thread = NULL;

   DECLARE_RETURN(BOOLEAN);

   TRACE("Enter NtUserGetGUIThreadInfo\n");
   UserEnterShared();

   Status = MmCopyFromCaller(&SafeGui, lpgui, sizeof(DWORD));
   if(!NT_SUCCESS(Status))
   {
      SetLastNtError(Status);
      RETURN( FALSE);
   }

   if(SafeGui.cbSize != sizeof(GUITHREADINFO))
   {
      EngSetLastError(ERROR_INVALID_PARAMETER);
      RETURN( FALSE);
   }

   if (idThread)
   {
      Status = PsLookupThreadByThreadId((HANDLE)(DWORD_PTR)idThread, &Thread);
      if(!NT_SUCCESS(Status))
      {
         EngSetLastError(ERROR_ACCESS_DENIED);
         RETURN( FALSE);
      }
      W32Thread = (PTHREADINFO)Thread->Tcb.Win32Thread;
      Desktop = W32Thread->rpdesk;

      if (!Thread || !Desktop )
      {
        if(Thread)
           ObDereferenceObject(Thread);
        EngSetLastError(ERROR_ACCESS_DENIED);
        RETURN( FALSE);
      }
      
      if ( W32Thread->MessageQueue )
        MsgQueue = W32Thread->MessageQueue;
      else
      {
        if ( Desktop ) MsgQueue = Desktop->ActiveMessageQueue;
      }
   }
   else
   {  /* Get the foreground thread */
      /* FIXME: Handle NULL queue properly? */
      MsgQueue = IntGetFocusMessageQueue();
      if(!MsgQueue)
      {
        EngSetLastError(ERROR_ACCESS_DENIED);
        RETURN( FALSE);
      }
   }

   CaretInfo = &MsgQueue->CaretInfo;

   SafeGui.flags = (CaretInfo->Visible ? GUI_CARETBLINKING : 0);
/*
   if (W32Thread->pMenuState->pGlobalPopupMenu)
   {
       SafeGui.flags |= GUI_INMENUMODE;

       if (W32Thread->pMenuState->pGlobalPopupMenu->spwndNotify)
          SafeGui.hwndMenuOwner = UserHMGetHandle(W32Thread->pMenuState->pGlobalPopupMenu->spwndNotify);

       if (W32Thread->pMenuState->pGlobalPopupMenu->fHasMenuBar)
       {
          if (W32Thread->pMenuState->pGlobalPopupMenu->fIsSysMenu)
          {
             SafeGui.flags |= GUI_SYSTEMMENUMODE;
          }
       }
       else
       {
          SafeGui.flags |= GUI_POPUPMENUMODE;
       }
   }
 */
   SafeGui.hwndMenuOwner = MsgQueue->MenuOwner;

   if (MsgQueue->MenuOwner)
      SafeGui.flags |= GUI_INMENUMODE | MsgQueue->MenuState;

   if (MsgQueue->MoveSize)
      SafeGui.flags |= GUI_INMOVESIZE;

   /* FIXME: Add flag GUI_16BITTASK */

   SafeGui.hwndActive = MsgQueue->spwndActive ? UserHMGetHandle(MsgQueue->spwndActive) : 0;
   SafeGui.hwndFocus = MsgQueue->spwndFocus ? UserHMGetHandle(MsgQueue->spwndFocus) : 0;
   SafeGui.hwndCapture = MsgQueue->spwndCapture ? UserHMGetHandle(MsgQueue->spwndCapture) : 0;
   SafeGui.hwndMoveSize = MsgQueue->MoveSize;
   SafeGui.hwndCaret = CaretInfo->hWnd;

   SafeGui.rcCaret.left = CaretInfo->Pos.x;
   SafeGui.rcCaret.top = CaretInfo->Pos.y;
   SafeGui.rcCaret.right = SafeGui.rcCaret.left + CaretInfo->Size.cx;
   SafeGui.rcCaret.bottom = SafeGui.rcCaret.top + CaretInfo->Size.cy;

   if (idThread)
      ObDereferenceObject(Thread);

   Status = MmCopyToCaller(lpgui, &SafeGui, sizeof(GUITHREADINFO));
   if(!NT_SUCCESS(Status))
   {
      SetLastNtError(Status);
      RETURN( FALSE);
   }

   RETURN( TRUE);

CLEANUP:
   TRACE("Leave NtUserGetGUIThreadInfo, ret=%u\n",_ret_);
   UserLeave();
   END_CLEANUP;
}
예제 #22
0
파일: monitor.c 프로젝트: RPG-7/reactos
/* IntGetMonitorsFromRect
 *
 * Returns a list of monitor handles/rectangles. The rectangles in the list are
 * the areas of intersection with the monitors.
 *
 * Arguments
 *
 *   pRect
 *      Rectangle in desktop coordinates. If this is NULL all monitors are
 *      returned and the rect list is filled with the sizes of the monitors.
 *
 *   phMonitorList
 *      Pointer to an array of HMONITOR which is filled with monitor handles.
 *      Can be NULL
 *
 *   prcMonitorList
 *      Pointer to an array of RECT which is filled with intersection rects in
 *      desktop coordinates.
 *      Can be NULL, will be ignored if no intersecting monitor is found and
 *      flags is MONITOR_DEFAULTTONEAREST
 *
 *   dwListSize
 *      Size of the phMonitorList and prcMonitorList arguments. If this is zero
 *      phMonitorList and prcMonitorList are ignored.
 *
 *   dwFlags
 *      Either 0 or MONITOR_DEFAULTTONEAREST (ignored if rect is NULL)
 *
 * Returns
 *   The number of monitors which intersect the specified region.
 */
static
UINT
IntGetMonitorsFromRect(OPTIONAL IN LPCRECTL pRect,
                       OPTIONAL OUT HMONITOR *phMonitorList,
                       OPTIONAL OUT PRECTL prcMonitorList,
                       OPTIONAL IN DWORD dwListSize,
                       OPTIONAL IN DWORD dwFlags)
{
    PMONITOR pMonitor, pNearestMonitor = NULL, pPrimaryMonitor = NULL;
    UINT cMonitors = 0;
    ULONG iNearestDistance = 0xffffffff;

    /* Find monitors which intersects the rectangle */
    for (pMonitor = gMonitorList; pMonitor != NULL; pMonitor = pMonitor->pMonitorNext)
    {
        RECTL MonitorRect, IntersectionRect;

        MonitorRect = pMonitor->rcMonitor;

        TRACE("MonitorRect: left = %d, top = %d, right = %d, bottom = %d\n",
               MonitorRect.left, MonitorRect.top, MonitorRect.right, MonitorRect.bottom);

        /* Save primary monitor for later usage */
        if (dwFlags == MONITOR_DEFAULTTOPRIMARY && pMonitor->IsPrimary)
            pPrimaryMonitor = pMonitor;

        /* Check if a rect is given */
        if (pRect == NULL)
        {
            /* No rect given, so use the full monitor rect */
            IntersectionRect = MonitorRect;
        }
        /* We have a rect, calculate intersection */
        else if (!RECTL_bIntersectRect(&IntersectionRect, &MonitorRect, pRect))
        {
            /* Rects did not intersect */
            if (dwFlags == MONITOR_DEFAULTTONEAREST)
            {
                ULONG cx, cy, iDistance;

                /* Get x and y distance */
                cx = min(abs(MonitorRect.left - pRect->right),
                         abs(pRect->left - MonitorRect.right));
                cy = min(abs(MonitorRect.top - pRect->bottom),
                         abs(pRect->top - MonitorRect.bottom));

                /* Calculate distance square */
                iDistance = cx * cx + cy * cy;

                /* Check if this is the new nearest monitor */
                if (iDistance < iNearestDistance)
                {
                    iNearestDistance = iDistance;
                    pNearestMonitor = pMonitor;
                }
            }

            continue;
        }

        /* Check if there's space in the buffer */
        if (cMonitors < dwListSize)
        {
            /* Save monitor data */
            if (phMonitorList != NULL)
                phMonitorList[cMonitors] = UserHMGetHandle(pMonitor);
            if (prcMonitorList != NULL)
                prcMonitorList[cMonitors] = IntersectionRect;
        }

        /* Increase count of found monitors */
        cMonitors++;
    }

    /* Nothing has been found? */
    if (cMonitors == 0)
    {
        /* Check if we shall default to the nearest monitor */
        if (dwFlags == MONITOR_DEFAULTTONEAREST && pNearestMonitor)
        {
            if (phMonitorList && dwListSize > 0)
                phMonitorList[cMonitors] = UserHMGetHandle(pNearestMonitor);
            cMonitors++;
        }
        /* Check if we shall default to the primary monitor */
        else if (dwFlags == MONITOR_DEFAULTTOPRIMARY && pPrimaryMonitor)
        {
            if (phMonitorList != NULL && dwListSize > 0)
                phMonitorList[cMonitors] = UserHMGetHandle(pPrimaryMonitor);
            cMonitors++;
        }
    }

    return cMonitors;
}
예제 #23
0
파일: misc.c 프로젝트: Moteesh/reactos
/*
 * @unimplemented
 */
DWORD_PTR APIENTRY
NtUserGetThreadState(
   DWORD Routine)
{
   DWORD_PTR ret = 0;

   TRACE("Enter NtUserGetThreadState\n");
   if (Routine != THREADSTATE_GETTHREADINFO)
   {
       UserEnterShared();
   }
   else
   {
       UserEnterExclusive();
   }

   switch (Routine)
   {
      case THREADSTATE_GETTHREADINFO:
         GetW32ThreadInfo();
         break;
      case THREADSTATE_FOCUSWINDOW:
         ret = (DWORD_PTR)IntGetThreadFocusWindow();
         break;
      case THREADSTATE_CAPTUREWINDOW:
         /* FIXME: Should use UserEnterShared */
         ret = (DWORD_PTR)IntGetCapture();
         break;
      case THREADSTATE_PROGMANWINDOW:
         ret = (DWORD_PTR)GetW32ThreadInfo()->pDeskInfo->hProgmanWindow;
         break;
      case THREADSTATE_TASKMANWINDOW:
         ret = (DWORD_PTR)GetW32ThreadInfo()->pDeskInfo->hTaskManWindow;
         break;
      case THREADSTATE_ACTIVEWINDOW:
         ret = (DWORD_PTR)UserGetActiveWindow();
         break;
      case THREADSTATE_INSENDMESSAGE:
         {
           PUSER_SENT_MESSAGE Message =
                ((PTHREADINFO)PsGetCurrentThreadWin32Thread())->pusmCurrent;
           TRACE("THREADSTATE_INSENDMESSAGE\n");

           ret = ISMEX_NOSEND;
           if (Message)
           {
             if (Message->ptiSender)
                ret = ISMEX_SEND;
             else
             {
                if (Message->CompletionCallback)
                   ret = ISMEX_CALLBACK;
                else
                   ret = ISMEX_NOTIFY;
             }
             /* If ReplyMessage */
             if (Message->QS_Flags & QS_SMRESULT) ret |= ISMEX_REPLIED;
           }

           break;
         }
      case THREADSTATE_GETMESSAGETIME:
         ret = ((PTHREADINFO)PsGetCurrentThreadWin32Thread())->timeLast;
         break;

      case THREADSTATE_UPTIMELASTREAD:
         {
           PTHREADINFO pti;
           pti = PsGetCurrentThreadWin32Thread();
           pti->timeLast = EngGetTickCount32();
           pti->pcti->tickLastMsgChecked = pti->timeLast;
         }
         break;

      case THREADSTATE_GETINPUTSTATE:
         ret = LOWORD(IntGetQueueStatus(QS_POSTMESSAGE|QS_TIMER|QS_PAINT|QS_SENDMESSAGE|QS_INPUT)) & (QS_KEY | QS_MOUSEBUTTON);
         break;

      case THREADSTATE_FOREGROUNDTHREAD:
         ret = (gpqForeground == GetW32ThreadInfo()->MessageQueue);
         break;
      case THREADSTATE_GETCURSOR:
         ret = (DWORD_PTR) (GetW32ThreadInfo()->MessageQueue->CursorObject ?
                            UserHMGetHandle(GetW32ThreadInfo()->MessageQueue->CursorObject) : 0);
         break;
      case THREADSTATE_GETMESSAGEEXTRAINFO:
         ret = (DWORD_PTR)MsqGetMessageExtraInfo();
        break;
   }

   TRACE("Leave NtUserGetThreadState, ret=%lu\n", ret);
   UserLeave();

   return ret;
}
예제 #24
0
/*
   Win32k counterpart of User DefWindowProc
 */
LRESULT FASTCALL
IntDefWindowProc(
   PWND Wnd,
   UINT Msg,
   WPARAM wParam,
   LPARAM lParam,
   BOOL Ansi)
{
   LRESULT lResult = 0;
   USER_REFERENCE_ENTRY Ref;

   if (Msg > WM_USER) return 0;

   switch (Msg)
   {
      case WM_SYSCOMMAND:
      {
         ERR("hwnd %p WM_SYSCOMMAND %lx %lx\n", Wnd->head.h, wParam, lParam );
         lResult = DefWndHandleSysCommand(Wnd, wParam, lParam);
         break;
      }
      case WM_SHOWWINDOW:
      {
         if ((Wnd->style & WS_VISIBLE) && wParam) break;
         if (!(Wnd->style & WS_VISIBLE) && !wParam) break;
         if (!Wnd->spwndOwner) break;
         if (LOWORD(lParam))
         {
            if (wParam)
            {
               if (!(Wnd->state & WNDS_HIDDENPOPUP)) break;
               Wnd->state &= ~WNDS_HIDDENPOPUP;
            }
            else
                Wnd->state |= WNDS_HIDDENPOPUP;

            co_WinPosShowWindow(Wnd, wParam ? SW_SHOWNOACTIVATE : SW_HIDE);
         }
      }
      break;
      case WM_CLIENTSHUTDOWN:
         return IntClientShutdown(Wnd, wParam, lParam);

      case WM_APPCOMMAND:
         ERR("WM_APPCOMMAND\n");
         if ( (Wnd->style & (WS_POPUP|WS_CHILD)) != WS_CHILD &&
               Wnd != co_GetDesktopWindow(Wnd) )
         {
            if (!co_HOOK_CallHooks(WH_SHELL, HSHELL_APPCOMMAND, wParam, lParam))
               co_IntShellHookNotify(HSHELL_APPCOMMAND, wParam, lParam);
            break;
         }
         UserRefObjectCo(Wnd->spwndParent, &Ref);
         lResult = co_IntSendMessage(UserHMGetHandle(Wnd->spwndParent), WM_APPCOMMAND, wParam, lParam);
         UserDerefObjectCo(Wnd->spwndParent);
         break;

      case WM_CTLCOLORMSGBOX:
      case WM_CTLCOLOREDIT:
      case WM_CTLCOLORLISTBOX:
      case WM_CTLCOLORBTN:
      case WM_CTLCOLORDLG:
      case WM_CTLCOLORSTATIC:
      case WM_CTLCOLORSCROLLBAR:
           return (LRESULT) DefWndControlColor((HDC)wParam, Msg - WM_CTLCOLORMSGBOX);

      case WM_CTLCOLOR:
           return (LRESULT) DefWndControlColor((HDC)wParam, HIWORD(lParam));

      case WM_GETHOTKEY:
         return DefWndGetHotKey(Wnd);
      case WM_SETHOTKEY:
         return DefWndSetHotKey(Wnd, wParam);

      case WM_NCHITTEST:
      {
         POINT Point;
         Point.x = GET_X_LPARAM(lParam);
         Point.y = GET_Y_LPARAM(lParam);
         return GetNCHitEx(Wnd, Point);
      }

      case WM_SYNCPAINT:
      {
         HRGN hRgn;
         Wnd->state &= ~WNDS_SYNCPAINTPENDING;
         ERR("WM_SYNCPAINT\n");
         hRgn = IntSysCreateRectRgn(0, 0, 0, 0);
         if (co_UserGetUpdateRgn(Wnd, hRgn, FALSE) != NULLREGION)
         {
            if (!wParam) wParam = (RDW_ERASENOW | RDW_ERASE | RDW_FRAME | RDW_ALLCHILDREN);
            co_UserRedrawWindow(Wnd, NULL, hRgn, wParam);
         }
         GreDeleteObject(hRgn);
         return 0;
      }

      case WM_SETREDRAW:
          if (wParam)
          {
             if (!(Wnd->style & WS_VISIBLE))
             {
                IntSetStyle( Wnd, WS_VISIBLE, 0 );
                Wnd->state |= WNDS_SENDNCPAINT;
             }
          }
          else
          {
             if (Wnd->style & WS_VISIBLE)
             {
                co_UserRedrawWindow( Wnd, NULL, NULL, RDW_ALLCHILDREN | RDW_VALIDATE );
                IntSetStyle( Wnd, 0, WS_VISIBLE );
             }
          }
          return 0;

      /* ReactOS only. */
      case WM_CBT:
      {
         switch (wParam)
         {
            case HCBT_MOVESIZE:
            {
               RECTL rt;

               if (lParam)
               {
                  _SEH2_TRY
                  {
                      ProbeForRead((PVOID)lParam,
                                   sizeof(RECT),
                                   1);

                      RtlCopyMemory(&rt,
                                    (PVOID)lParam,
                                    sizeof(RECT));
                  }
                  _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
                  {
                      lResult = 1;
                  }
                  _SEH2_END;
               }
               if (!lResult)
                  lResult = co_HOOK_CallHooks(WH_CBT, HCBT_MOVESIZE, (WPARAM)Wnd->head.h, lParam ? (LPARAM)&rt : 0);
           }
            break;
         }
         break;
      }
      break;
   }
   return lResult;
}
예제 #25
0
BOOL FASTCALL
co_IntSendActivateMessages(PWND WindowPrev, PWND Window, BOOL MouseActivate, BOOL Async)
{
   USER_REFERENCE_ENTRY Ref, RefPrev;
   HANDLE OldTID, NewTID;
   PTHREADINFO pti, ptiOld, ptiNew;
   BOOL InAAPM = FALSE;

   if (Window)
   {
      pti = PsGetCurrentThreadWin32Thread();

      UserRefObjectCo(Window, &Ref);

      if (WindowPrev) UserRefObjectCo(WindowPrev, &RefPrev);

      /* Send palette messages */
      if (gpsi->PUSIFlags & PUSIF_PALETTEDISPLAY &&
          //co_IntPostOrSendMessage(UserHMGetHandle(Window), WM_QUERYNEWPALETTE, 0, 0))
          co_IntSendMessage(UserHMGetHandle(Window), WM_QUERYNEWPALETTE, 0, 0))
      {
         UserSendNotifyMessage( HWND_BROADCAST,
                                WM_PALETTEISCHANGING,
                               (WPARAM)UserHMGetHandle(Window),
                                0);
      }
      //// Fixes bug 7089.
      if (!(Window->style & WS_CHILD))
      {
         PWND pwndTemp = co_GetDesktopWindow(Window)->spwndChild;

         while (pwndTemp && !(pwndTemp->style & WS_VISIBLE)) pwndTemp = pwndTemp->spwndNext;

         if (Window != pwndTemp || (WindowPrev && !IntIsWindowVisible(WindowPrev)))
         {
            if (!Async || pti->MessageQueue == gpqForeground)
            {
               UINT flags = SWP_NOSIZE | SWP_NOMOVE;
               if (Window == pwndTemp) flags |= SWP_NOACTIVATE;
               //ERR("co_IntSendActivateMessages SetWindowPos! Async %d pti Q == FGQ %d\n",Async,pti->MessageQueue == gpqForeground);
               co_WinPosSetWindowPos(Window, HWND_TOP, 0, 0, 0, 0, flags);
            }
         }
      }
      ////
      //// CORE-1161 and CORE-6651
      if (Window->spwndPrev)
      {
         HWND *phwndTopLevel, *phwndCurrent;
         PWND pwndCurrent, pwndDesktop;

         pwndDesktop = UserGetDesktopWindow();
         if (Window->spwndParent == pwndDesktop )
         {
            phwndTopLevel = IntWinListChildren(pwndDesktop);
            phwndCurrent = phwndTopLevel;
            while(*phwndCurrent)
            {
                pwndCurrent = UserGetWindowObject(*phwndCurrent);

                if (pwndCurrent && pwndCurrent->spwndOwner == Window )
                {
                    co_WinPosSetWindowPos(pwndCurrent, HWND_TOP, 0, 0, 0, 0, SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE);
                }
                phwndCurrent++;
            }
            ExFreePool(phwndTopLevel);
          }
      }
      ////
      OldTID = WindowPrev ? IntGetWndThreadId(WindowPrev) : NULL;
      NewTID = IntGetWndThreadId(Window);
      ptiOld = WindowPrev ? WindowPrev->head.pti : NULL;
      ptiNew = Window->head.pti;

      //ERR("SendActivateMessage Old -> %x, New -> %x\n", OldTID, NewTID);

      if (!(pti->TIF_flags & TIF_INACTIVATEAPPMSG) &&
           (!WindowPrev || OldTID != NewTID) )
      {
         PWND cWindow;
         HWND *List, *phWnd;

         List = IntWinListChildren(UserGetDesktopWindow());
         if ( List )
         {
            if ( OldTID )
            {
               ptiOld->TIF_flags |= TIF_INACTIVATEAPPMSG;
               // Note: Do not set pci flags, this does crash!
               for (phWnd = List; *phWnd; ++phWnd)
               {
                  cWindow = ValidateHwndNoErr(*phWnd);
                  if (cWindow && cWindow->head.pti == ptiOld)
                  {  // FALSE if the window is being deactivated,
                     // ThreadId that owns the window being activated.
                    co_IntSendMessageNoWait(*phWnd, WM_ACTIVATEAPP, FALSE, (LPARAM)NewTID);
                  }
               }
               ptiOld->TIF_flags &= ~TIF_INACTIVATEAPPMSG;
            }
            if ( NewTID )
            {  //// Prevents a resource crash due to reentrance!
               InAAPM = TRUE;
               pti->TIF_flags |= TIF_INACTIVATEAPPMSG;
               ////
               for (phWnd = List; *phWnd; ++phWnd)
               {
                  cWindow = ValidateHwndNoErr(*phWnd);
                  if (cWindow && cWindow->head.pti == ptiNew)
                  { // TRUE if the window is being activated,
                    // ThreadId that owns the window being deactivated.
                    co_IntSendMessageNoWait(*phWnd, WM_ACTIVATEAPP, TRUE, (LPARAM)OldTID);
                  }
               }
            }
            ExFreePoolWithTag(List, USERTAG_WINDOWLIST);
         }
      }
      if (WindowPrev)
         UserDerefObjectCo(WindowPrev); // Now allow the previous window to die.

      if (Window->state & WNDS_ACTIVEFRAME)
      {  // If already active frame do not allow NCPaint.
         //ERR("SendActivateMessage Is Active Frame!\n");
         Window->state |= WNDS_NONCPAINT;
      }

      if (Window->style & WS_MINIMIZE)
      {
         TRACE("Widow was minimized\n");
      }

      co_IntMakeWindowActive(Window);

      /* FIXME: IntIsWindow */

      co_IntSendMessageNoWait( UserHMGetHandle(Window),
                               WM_NCACTIVATE,
                              (WPARAM)(Window == (gpqForeground ? gpqForeground->spwndActive : NULL)),
                               0); //(LPARAM)hWndPrev);

      co_IntSendMessageNoWait( UserHMGetHandle(Window),
                               WM_ACTIVATE,
                               MAKEWPARAM(MouseActivate ? WA_CLICKACTIVE : WA_ACTIVE, Window->style & WS_MINIMIZE),
                              (LPARAM)(WindowPrev ? UserHMGetHandle(WindowPrev) : 0));

      if (!Window->spwndOwner && !IntGetParent(Window))
      {
         // FIXME lParam; The value is TRUE if the window is in full-screen mode, or FALSE otherwise.
         co_IntShellHookNotify(HSHELL_WINDOWACTIVATED, (WPARAM) UserHMGetHandle(Window), FALSE);
      }

      Window->state &= ~WNDS_NONCPAINT;

      UserDerefObjectCo(Window);
   }
   return InAAPM;
}
예제 #26
0
/* IntGetMonitorsFromRect
 *
 * Returns a list of monitor handles/rectangles. The rectangles in the list are
 * the areas of intersection with the monitors.
 *
 * Arguments
 *
 *   pRect
 *      Rectangle in desktop coordinates. If this is NULL all monitors are
 *      returned and the rect list is filled with the sizes of the monitors.
 *
 *   hMonitorList
 *      Pointer to an array of HMONITOR which is filled with monitor handles.
 *      Can be NULL
 *
 *   monitorRectList
 *      Pointer to an array of RECT which is filled with intersection rects in
 *      desktop coordinates.
 *      Can be NULL, will be ignored if no intersecting monitor is found and
 *      flags is MONITOR_DEFAULTTONEAREST
 *
 *   listSize
 *      Size of the hMonitorList and monitorRectList arguments. If this is zero
 *      hMonitorList and monitorRectList are ignored.
 *
 *   flags
 *      Either 0 or MONITOR_DEFAULTTONEAREST (ignored if rect is NULL)
 *
 * Returns
 *   The number of monitors which intersect the specified region.
 */
static
UINT
IntGetMonitorsFromRect(OPTIONAL IN LPCRECTL pRect,
                       OPTIONAL OUT HMONITOR *hMonitorList,
                       OPTIONAL OUT PRECTL monitorRectList,
                       OPTIONAL IN DWORD listSize,
                       OPTIONAL IN DWORD flags)
{
    PMONITOR Monitor, NearestMonitor = NULL, PrimaryMonitor = NULL;
    UINT iCount = 0;
    ULONG iNearestDistance = 0xffffffff;

    /* Find monitors which intersect the rectangle */
    for (Monitor = gMonitorList; Monitor != NULL; Monitor = Monitor->Next)
    {
        RECTL MonitorRect, IntersectionRect;

        ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&Monitor->Lock);
        MonitorRect = Monitor->rcMonitor;
        ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&Monitor->Lock);

        TRACE("MonitorRect: left = %d, top = %d, right = %d, bottom = %d\n",
               MonitorRect.left, MonitorRect.top, MonitorRect.right, MonitorRect.bottom);

        if (flags == MONITOR_DEFAULTTOPRIMARY && Monitor->IsPrimary)
        {
            PrimaryMonitor = Monitor;
        }

        /* Check if a rect is given */
        if (pRect == NULL)
        {
            /* No rect given, so use the full monitor rect */
            IntersectionRect = MonitorRect;
        }

        /* We have a rect, calculate intersection */
        else if (!RECTL_bIntersectRect(&IntersectionRect, &MonitorRect, pRect))
        {
            /* Rects did not intersect */
            if (flags == MONITOR_DEFAULTTONEAREST)
            {
                ULONG cx, cy, iDistance;

                /* Get x and y distance */
                cx = min(abs(MonitorRect.left - pRect->right),
                         abs(pRect->left - MonitorRect.right));
                cy = min(abs(MonitorRect.top - pRect->bottom),
                         abs(pRect->top - MonitorRect.bottom));

                /* Calculate distance square */
                iDistance = cx * cx + cy * cy;

                /* Check if this is the new nearest monitor */
                if (iDistance < iNearestDistance)
                {
                    iNearestDistance = iDistance;
                    NearestMonitor = Monitor;
                }
            }

            continue;
        }

        /* Check if there's space in the buffer */
        if (iCount < listSize)
        {
            if (hMonitorList != NULL)
                hMonitorList[iCount] = UserHMGetHandle(Monitor);
            if (monitorRectList != NULL)
                monitorRectList[iCount] = IntersectionRect;
        }

        /* Increase count of found monitors */
        iCount++;
    }

    /* Found nothing intersecting? */
    if (iCount == 0)
    {
        /* Check if we shall default to the nearest monitor */
        if (flags == MONITOR_DEFAULTTONEAREST && NearestMonitor)
        {
            if (hMonitorList && listSize > 0)
                hMonitorList[iCount] = UserHMGetHandle(NearestMonitor);
            iCount++;
        }
        /* Check if we shall default to the primary monitor */
        else if (flags == MONITOR_DEFAULTTOPRIMARY && PrimaryMonitor)
        {
            if (hMonitorList != NULL && listSize > 0)
                hMonitorList[iCount] = UserHMGetHandle(PrimaryMonitor);
            iCount++;
        }
    }

    return iCount;
}
예제 #27
0
HWND FASTCALL
IntGetCaptureWindow(VOID)
{
   PUSER_MESSAGE_QUEUE ForegroundQueue = IntGetFocusMessageQueue();
   return ( ForegroundQueue ? (ForegroundQueue->spwndCapture ? UserHMGetHandle(ForegroundQueue->spwndCapture) : 0) : 0);
}
예제 #28
0
HWND FASTCALL
co_UserSetFocus(PWND Window)
{
   HWND hWndPrev = 0;
   PWND pwndTop;
   PTHREADINFO pti;
   PUSER_MESSAGE_QUEUE ThreadQueue;

   if (Window)
      ASSERT_REFS_CO(Window);

   pti = PsGetCurrentThreadWin32Thread();
   ThreadQueue = pti->MessageQueue;
   ASSERT(ThreadQueue != 0);

   TRACE("Enter SetFocus hWnd 0x%p pti 0x%p\n",Window ? UserHMGetHandle(Window) : 0, pti );

   hWndPrev = ThreadQueue->spwndFocus ? UserHMGetHandle(ThreadQueue->spwndFocus) : 0;

   if (Window != 0)
   {
      if (hWndPrev == UserHMGetHandle(Window))
      {
         return hWndPrev ? (IntIsWindow(hWndPrev) ? hWndPrev : 0) : 0; /* Nothing to do */
      }

      if (Window->head.pti->MessageQueue != ThreadQueue)
      {
         ERR("SetFocus Must have the same Q!\n");
         return 0;
      }

      /* Check if we can set the focus to this window */
      for (pwndTop = Window; pwndTop != NULL; pwndTop = pwndTop->spwndParent)
      {
         if (pwndTop->style & (WS_MINIMIZED|WS_DISABLED)) return 0;
         if ((pwndTop->style & (WS_POPUP|WS_CHILD)) != WS_CHILD) break;
      }

      if (co_HOOK_CallHooks( WH_CBT, HCBT_SETFOCUS, (WPARAM)Window->head.h, (LPARAM)hWndPrev))
      {
         ERR("SetFocus 1 WH_CBT Call Hook return!\n");
         return 0;
      }

      /* Activate pwndTop if needed. */
      if (pwndTop != ThreadQueue->spwndActive)
      {
         PUSER_MESSAGE_QUEUE ForegroundQueue = IntGetFocusMessageQueue(); // Keep it based on desktop.
         if (ThreadQueue != ForegroundQueue && IsAllowedFGActive(pti, pwndTop)) // Rule 2 & 3.
         {
            //ERR("SetFocus: Set Foreground!\n");
            if (!(pwndTop->style & WS_VISIBLE))
            {
                pti->ppi->W32PF_flags |= W32PF_ALLOWFOREGROUNDACTIVATE;
            }
            if (!co_IntSetForegroundAndFocusWindow(pwndTop, FALSE))
            {
               ERR("SetFocus: Set Foreground and Focus Failed!\n");
               return 0;
            }
         }

         /* Set Active when it is needed. */
         if (pwndTop != ThreadQueue->spwndActive)
         {
            //ERR("SetFocus: Set Active!\n");
            if (!co_IntSetActiveWindow(pwndTop, FALSE, FALSE, FALSE))
            {
               ERR("SetFocus: Set Active Failed!\n");
               return 0;
            }
         }

         /* Abort if window destroyed */
         if (Window->state2 & WNDS2_INDESTROY) return 0;
         /* Do not change focus if the window is no longer active */
         if (pwndTop != ThreadQueue->spwndActive)
         {
            ERR("SetFocus: Top window did not go active!\n");
            return 0;
         }
      }

      // Check again! SetActiveWindow could have set the focus via WM_ACTIVATE.
      hWndPrev = ThreadQueue->spwndFocus ? UserHMGetHandle(ThreadQueue->spwndFocus) : 0;

      IntSendFocusMessages( pti, Window);

      TRACE("Focus: %p -> %p\n", hWndPrev, Window->head.h);
   }
   else /* NULL hwnd passed in */
   {
      if (co_HOOK_CallHooks( WH_CBT, HCBT_SETFOCUS, (WPARAM)0, (LPARAM)hWndPrev))
      {
         ERR("SetFocus: 2 WH_CBT Call Hook return!\n");
         return 0;
      }

      /* set the current thread focus window null */
      IntSendFocusMessages( pti, NULL);
   }
   return hWndPrev ? (IntIsWindow(hWndPrev) ? hWndPrev : 0) : 0;
}
예제 #29
0
BOOL FASTCALL
co_IntSetActiveWindow(PWND Wnd OPTIONAL, BOOL bMouse, BOOL bFocus, BOOL Async)
{
   PTHREADINFO pti;
   PUSER_MESSAGE_QUEUE ThreadQueue;
   PWND pWndChg, WndPrev; // State changes.
   HWND hWndPrev;
   HWND hWnd = 0;
   BOOL InAAPM;
   CBTACTIVATESTRUCT cbt;
   //ERR("co_IntSetActiveWindow 1\n");
   if (Wnd)
   {
      ASSERT_REFS_CO(Wnd);
      hWnd = UserHMGetHandle(Wnd);
      if ((Wnd->style & (WS_POPUP|WS_CHILD)) == WS_CHILD) return FALSE;
      if (Wnd == UserGetDesktopWindow()) return FALSE;
      //ERR("co_IntSetActiveWindow 1a hWnd 0x%p\n",hWnd);
   }

   //ERR("co_IntSetActiveWindow 2\n");
   pti = PsGetCurrentThreadWin32Thread();
   ThreadQueue = pti->MessageQueue;
   ASSERT(ThreadQueue != 0);

   hWndPrev = ThreadQueue->spwndActive ? UserHMGetHandle(ThreadQueue->spwndActive) : NULL;

   pWndChg = ThreadQueue->spwndActive; // Keep to notify of a preemptive switch.

   while (Wnd)
   {
      BOOL Ret, DoFG, AllowFG;

      if (Wnd->state & WNDS_BEINGACTIVATED) return TRUE;

      if (ThreadQueue == Wnd->head.pti->MessageQueue)
      {
         if (IsAllowedFGActive(pti, Wnd))
         {
             DoFG = TRUE;
         }
         else
         {
             //ERR("co_IntSetActiveWindow 3 Go Out!\n");
             break;
         }
         AllowFG = !pti->cVisWindows; // Nothing is visable.
         //ERR("co_IntSetActiveWindow 3a DoFG = %d AllowFG = %d\n",DoFG,AllowFG);
      }
      else //if (ThreadQueue != Wnd->head.pti->MessageQueue)
      {
         //PUSER_MESSAGE_QUEUE ForegroundQueue = IntGetFocusMessageQueue();
         // Rule 1 & 4, We are foreground so set this FG window or NULL foreground....
         //if (!ForegroundQueue || ForegroundQueue == ThreadQueue)
         if (!gpqForeground || gpqForeground == ThreadQueue)
         {
            DoFG = TRUE;
         }
         else
            DoFG = FALSE;
         if (DoFG)
         {
            if (pti->TIF_flags & TIF_ALLOWFOREGROUNDACTIVATE || pti->cVisWindows)
               AllowFG = TRUE;
            else
               AllowFG = FALSE;
         }
         else
            AllowFG = FALSE;
         //ERR("co_IntSetActiveWindow 3b DoFG = %d AllowFG = %d\n",DoFG,AllowFG);
      }
      Ret = FALSE;
      if (DoFG)
      {
         pti->TIF_flags |= TIF_ALLOWFOREGROUNDACTIVATE;
         //ERR("co_IntSetActiveWindow 3c FG set\n");
         Ret = co_IntSetForegroundAndFocusWindow(Wnd, bMouse);
         if (AllowFG)
         {
            pti->TIF_flags |= TIF_ALLOWFOREGROUNDACTIVATE;
         }
         else
         {
            pti->TIF_flags &= ~TIF_ALLOWFOREGROUNDACTIVATE;
         }
      }
      return Ret;
   }

   /* Call CBT hook chain */
   cbt.fMouse     = bMouse;
   cbt.hWndActive = hWndPrev;
   if (co_HOOK_CallHooks( WH_CBT, HCBT_ACTIVATE, (WPARAM)hWnd, (LPARAM)&cbt))
   {
      ERR("SetActiveWindow: WH_CBT Call Hook return!\n");
      return FALSE;
   }

   if ( ThreadQueue->spwndActive && ThreadQueue->spwndActive->state & WNDS_DESTROYED )
      ThreadQueue->spwndActive = NULL;
   else
      ThreadQueue->spwndActivePrev = ThreadQueue->spwndActive;

   WndPrev = ThreadQueue->spwndActive; // Keep to save changing active.

   if (WndPrev)
   {
      if (ThreadQueue == gpqForeground) gpqForegroundPrev = ThreadQueue;
      if (!co_IntSendDeactivateMessages(UserHMGetHandle(WndPrev), hWnd)) return FALSE;
   }

   WndPrev = ThreadQueue->spwndActive; // Again keep to save changing active.

   // While in calling message proc or hook:
   // Fail if a preemptive switch was made, current active not made previous,
   // focus window is dead or no longer the same thread queue.
   if ( ThreadQueue->spwndActivePrev != ThreadQueue->spwndActive ||
        pWndChg != WndPrev ||
        (Wnd && !VerifyWnd(Wnd)) ||
        ThreadQueue != pti->MessageQueue )
   {
      ERR("SetActiveWindow: Summery ERROR, active state changed!\n");
      return FALSE;
   }

   if (!WndPrev) ThreadQueue->QF_flags &= ~QF_FOCUSNULLSINCEACTIVE;

   if (Wnd) Wnd->state |= WNDS_BEINGACTIVATED;

   IntNotifyWinEvent(EVENT_SYSTEM_FOREGROUND, Wnd, OBJID_WINDOW, CHILDID_SELF, WEF_SETBYWNDPTI);
   //// Breaks Atl-Esc/Tab via User32.
   ////FindRemoveAsyncMsg(Wnd,(WPARAM)Wnd); // Clear out activate ASYNC messages.

   /* check if the specified window can be set in the input data of a given queue */
   if ( !Wnd || ThreadQueue == Wnd->head.pti->MessageQueue)
   {
      /* set the current thread active window */
      ThreadQueue->spwndActive = Wnd;
   }

   WndPrev = VerifyWnd(ThreadQueue->spwndActivePrev); // Now should be set but verify it again.

   InAAPM = co_IntSendActivateMessages(WndPrev, Wnd, bMouse, Async);

   /* now change focus if necessary */
   if (bFocus && !(ThreadQueue->QF_flags & QF_FOCUSNULLSINCEACTIVE))
   {
      /* Do not change focus if the window is no longer active */
      if (ThreadQueue->spwndActive == Wnd)
      {
         if (!ThreadQueue->spwndFocus ||
             !Wnd ||
              UserGetAncestor(ThreadQueue->spwndFocus, GA_ROOT) != Wnd)
         {
            co_UserSetFocus(Wnd);
         }
      }
   }

   if (InAAPM)
   {
      pti->TIF_flags &= ~TIF_INACTIVATEAPPMSG;
   }

   // FIXME: Used in the menu loop!!!
   //ThreadQueue->QF_flags |= QF_ACTIVATIONCHANGE;

   //ERR("co_IntSetActiveWindow Exit\n");
   if (Wnd) Wnd->state &= ~WNDS_BEINGACTIVATED;
   return (ThreadQueue->spwndActive == Wnd);
}
예제 #30
0
/*
   MSDN:
   The system restricts which processes can set the foreground window. A process
   can set the foreground window only if one of the following conditions is true:

    * The process is the foreground process.
    * The process was started by the foreground process.
    * The process received the last input event.
    * There is no foreground process.
    * The foreground process is being debugged.
    * The foreground is not locked (see LockSetForegroundWindow).
    * The foreground lock time-out has expired (see SPI_GETFOREGROUNDLOCKTIMEOUT in SystemParametersInfo).
    * No menus are active.
*/
static
BOOL FASTCALL
co_IntSetForegroundAndFocusWindow(
    _In_ PWND Wnd,
    _In_ BOOL MouseActivate)
{
   HWND hWnd = Wnd ? UserHMGetHandle(Wnd) : NULL;
   HWND hWndPrev = NULL;
   PWND pWndPrev = NULL;
   PUSER_MESSAGE_QUEUE PrevForegroundQueue;
   PTHREADINFO pti;
   BOOL fgRet = FALSE, Ret = FALSE;

   if (Wnd) ASSERT_REFS_CO(Wnd);

   //ERR("SetForegroundAndFocusWindow(%x, %s)\n", hWnd, (MouseActivate ? "TRUE" : "FALSE"));

   PrevForegroundQueue = IntGetFocusMessageQueue(); // Use this active desktop.
   pti = PsGetCurrentThreadWin32Thread();

   if (PrevForegroundQueue)
   {  // Same Window Q as foreground just do active.
      if (Wnd && Wnd->head.pti->MessageQueue == PrevForegroundQueue)
      {
         //ERR("Same Window Q as foreground just do active.\n");
         if (pti->MessageQueue == PrevForegroundQueue)
         { // Same WQ and TQ go active.
            //ERR("Same WQ and TQ go active.\n");
            Ret = co_IntSetActiveWindow(Wnd, MouseActivate, TRUE, FALSE);
         }
         else if (Wnd->head.pti->MessageQueue->spwndActive == Wnd)
         { // Same WQ and it is active.
            //ERR("Same WQ and it is active.\n");
            Ret = TRUE;
         }
         else
         { // Same WQ as FG but not the same TQ send active.
            //ERR("Same WQ as FG but not the same TQ send active.\n");
            co_IntSendMessage(hWnd, WM_ASYNC_SETACTIVEWINDOW, (WPARAM)Wnd, (LPARAM)MouseActivate );
            Ret = TRUE;
         }
         return Ret;
      }

      hWndPrev = PrevForegroundQueue->spwndActive ? UserHMGetHandle(PrevForegroundQueue->spwndActive) : 0;
      pWndPrev = PrevForegroundQueue->spwndActive;
   }

   if ( (( !IsFGLocked() || pti->ppi == gppiInputProvider ) &&
         ( CanForceFG(pti->ppi) || pti->TIF_flags & (TIF_SYSTEMTHREAD|TIF_CSRSSTHREAD|TIF_ALLOWFOREGROUNDACTIVATE) )) ||
        pti->ppi == ppiScrnSaver
      )
   {

      //ToggleFGActivate(pti); // win.c line 2662 fail
      if (Wnd)
      {
         IntSetFocusMessageQueue(Wnd->head.pti->MessageQueue);
         gptiForeground = Wnd->head.pti;
         //ERR("Set Foreground pti 0x%p Q 0x%p hWnd 0x%p\n",Wnd->head.pti, Wnd->head.pti->MessageQueue,Wnd->head.h);
      }
      else
      {
         IntSetFocusMessageQueue(NULL);
         gptiForeground = NULL;
         //ERR("Set Foreground pti 0x0 Q 0x0 hWnd 0x0\n");
      }
/*
     Henri Verbeet,
     What happens is that we get the WM_WINE_SETACTIVEWINDOW message sent by the
     other thread after we already changed the foreground window back to our own
     window.
 */
      //ERR("SFAFW: 1\n");
      FindRemoveAsyncMsg(Wnd, 0); // Do this to fix test_SFW todos!

      fgRet = TRUE;
   }

   //  Fix FG Bounce with regedit.
   if (hWndPrev != hWnd )
   {
      if (PrevForegroundQueue &&
          fgRet &&
          PrevForegroundQueue->spwndActive)
      {
         //ERR("SFGW: Send NULL to 0x%x\n",hWndPrev);
         if (pti->MessageQueue == PrevForegroundQueue)
         {
            //ERR("SFGW: TI same as Prev TI\n");
            co_IntSetActiveWindow(NULL, FALSE, TRUE, FALSE);
         }
         else if (pWndPrev)
         {
            //ERR("SFGW Deactivate: TI not same as Prev TI\n");
            // No real reason to wait here.
            co_IntSendMessageNoWait(hWndPrev, WM_ASYNC_SETACTIVEWINDOW, 0, 0 );
         }
      }
   }

   if (!Wnd) return FALSE; // Always return false.

   if (pti->MessageQueue == Wnd->head.pti->MessageQueue)
   {
       //ERR("Same PQ and WQ go active.\n");
       Ret = co_IntSetActiveWindow(Wnd, MouseActivate, TRUE, FALSE);
   }
   else if (Wnd->head.pti->MessageQueue->spwndActive == Wnd)
   {
       //ERR("Same Active and Wnd.\n");
       Ret = TRUE;
   }
   else
   {
       //ERR("Activate Not same PQ and WQ and Wnd.\n");
       co_IntSendMessageNoWait(hWnd, WM_ASYNC_SETACTIVEWINDOW, (WPARAM)Wnd, (LPARAM)MouseActivate );
       Ret = TRUE;
   }
   return Ret && fgRet;
}