ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

static LRESULT CALLBACK TrayWndProc ( IN HWND  hwnd,
IN UINT  uMsg,
IN WPARAM  wParam,
IN LPARAM  lParam 
) [static]

Definition at line 1887 of file traywnd.c.

Referenced by RegisterTrayWindowClass().

{
    ITrayWindowImpl *This = NULL;
    LRESULT Ret = FALSE;

    if (uMsg != WM_NCCREATE)
    {
        This = (ITrayWindowImpl*)GetWindowLongPtr(hwnd,
                                                  0);
    }

    if (This != NULL || uMsg == WM_NCCREATE)
    {
        if (This != NULL && This->StartMenuBand != NULL)
        {
            MSG Msg;
            LRESULT lRet;

            Msg.hwnd = hwnd;
            Msg.message = uMsg;
            Msg.wParam = wParam;
            Msg.lParam = lParam;

            if (IMenuBand_TranslateMenuMessage(This->StartMenuBand,
                                               &Msg,
                                               &lRet) == S_OK)
            {
                return lRet;
            }

            wParam = Msg.wParam;
            lParam = Msg.lParam;
        }

        switch (uMsg)
        {
            case WM_NCHITTEST:
            {
                RECT rcClient;
                POINT pt;

                if (This->Locked)
                {
                    /* The user may not be able to resize the tray window.
                       Pretend like the window is not sizeable when the user
                       clicks on the border. */
                    return HTBORDER;
                }

                if (GetClientRect(hwnd,
                                  &rcClient) &&
                    MapWindowPoints(hwnd,
                                    NULL,
                                    (LPPOINT)&rcClient,
                                    2) != 0)
                {
                    pt.x = (SHORT)LOWORD(lParam);
                    pt.y = (SHORT)HIWORD(lParam);

                    if (PtInRect(&rcClient,
                                 pt))
                    {
                        /* The user is trying to drag the tray window */
                        return HTCAPTION;
                    }

                    /* Depending on the position of the tray window, allow only
                       changing the border next to the monitor working area */
                    switch (This->Position)
                    {
                        case ABE_TOP:
                            if (pt.y > rcClient.bottom)
                                return HTBOTTOM;
                            break;

                        case ABE_BOTTOM:
                            if (pt.y < rcClient.top)
                                return HTTOP;
                            break;

                        case ABE_LEFT:
                            if (pt.x > rcClient.right)
                                return HTRIGHT;
                            break;

                        case ABE_RIGHT:
                            if (pt.x < rcClient.left)
                                return HTLEFT;
                            break;

                        default:
                            break;
                    }
                }

                return HTBORDER;
            }

            case WM_MOVING:
            {
                POINT ptCursor;
                PRECT pRect = (PRECT)lParam;

                /* We need to ensure that an application can not accidently
                   move the tray window (using SetWindowPos). However, we still
                   need to be able to move the window in case the user wants to
                   drag the tray window to another position or in case the user
                   wants to resize the tray window. */
                if (!This->Locked && GetCursorPos(&ptCursor))
                {
                    This->IsDragging = TRUE;
                    This->DraggingPosition = ITrayWindowImpl_GetDraggingRectFromPt(This,
                                                                                   ptCursor,
                                                                                   pRect,
                                                                                   &This->DraggingMonitor);
                }
                else
                {
                    *pRect = This->rcTrayWnd[This->Position];
                }
                return TRUE;
            }

            case WM_SIZING:
            {
                PRECT pRect = (PRECT)lParam;

                if (!This->Locked)
                {
                    ITrayWindowImpl_CalculateValidSize(This,
                                                       This->Position,
                                                       pRect);
                }
                else
                {
                    *pRect = This->rcTrayWnd[This->Position];
                }
                return TRUE;
            }

            case WM_WINDOWPOSCHANGING:
            {
                ITrayWindowImpl_ChangingWinPos(This,
                                               (LPWINDOWPOS)lParam);
                break;
            }

            case WM_SIZE:
            {
                RECT rcClient;

                if (wParam == SIZE_RESTORED && lParam == 0)
                {
                    ITrayWindowImpl_ResizeWorkArea(This);
                    /* Clip the tray window on multi monitor systems so the edges can't
                       overlap into another monitor */
                    ITrayWindowImpl_ApplyClipping(This,
                                                  TRUE);

                    if (!GetClientRect(This->hWnd,
                                       &rcClient))
                    {
                        break;
                    }
                }
                else
                {
                    rcClient.left = rcClient.top = 0;
                    rcClient.right = LOWORD(lParam);
                    rcClient.bottom = HIWORD(lParam);
                }

                ITrayWindowImpl_AlignControls(This,
                                              &rcClient);
                break;
            }

            case WM_ENTERSIZEMOVE:
                This->InSizeMove = TRUE;
                This->IsDragging = FALSE;
                if (!This->Locked)
                {
                    /* Remove the clipping on multi monitor systems while dragging around */
                    ITrayWindowImpl_ApplyClipping(This,
                                                  FALSE);
                }
                break;

            case WM_EXITSIZEMOVE:
                This->InSizeMove = FALSE;
                if (!This->Locked)
                {
                    /* Apply clipping */
                    PostMessage(This->hWnd,
                                WM_SIZE,
                                SIZE_RESTORED,
                                0);
                }
                break;

            case WM_SYSCHAR:
                switch (wParam)
                {
                    case TEXT(' '):
                    {
                        /* The user pressed Alt+Space, this usually brings up the system menu of a window.
                           The tray window needs to handle this specially, since it normally doesn't have
                           a system menu. */

                        static const UINT uidDisableItem[] = {
                            SC_RESTORE,
                            SC_MOVE,
                            SC_SIZE,
                            SC_MAXIMIZE,
                            SC_MINIMIZE,
                        };
                        HMENU hSysMenu;
                        INT i;
                        UINT uId;

                        /* temporarily enable the system menu */
                        SetWindowStyle(hwnd,
                                       WS_SYSMENU,
                                       WS_SYSMENU);

                        hSysMenu = GetSystemMenu(hwnd,
                                                 FALSE);
                        if (hSysMenu != NULL)
                        {
                            /* Disable all items that are not relevant */
                            for (i = 0; i != sizeof(uidDisableItem) / sizeof(uidDisableItem[0]); i++)
                            {
                                EnableMenuItem(hSysMenu,
                                               uidDisableItem[i],
                                               MF_BYCOMMAND | MF_GRAYED);
                            }

                            EnableMenuItem(hSysMenu,
                                           SC_CLOSE,
                                           MF_BYCOMMAND |
                                               (SHRestricted(REST_NOCLOSE) ? MF_GRAYED : MF_ENABLED));

                            /* Display the system menu */
                            uId = ITrayWindowImpl_TrackMenu(This,
                                                            hSysMenu,
                                                            NULL,
                                                            This->hwndStart,
                                                            This->Position != ABE_TOP,
                                                            FALSE);
                            if (uId != 0)
                            {
                                SendMessage(This->hWnd,
                                            WM_SYSCOMMAND,
                                            (WPARAM)uId,
                                            0);
                            }
                        }

                        /* revert the system menu window style */
                        SetWindowStyle(hwnd,
                                       WS_SYSMENU,
                                       0);
                        break;
                    }

                    default:
                        goto DefHandler;
                }
                break;

            case WM_NCRBUTTONUP:
                /* We want the user to be able to get a context menu even on the nonclient
                   area (including the sizing border)! */
                uMsg = WM_CONTEXTMENU;
                wParam = (WPARAM)hwnd;
                /* fall through */

            case WM_CONTEXTMENU:
            {
                POINT pt, *ppt = NULL;
                HWND hWndExclude = NULL;

                /* Check if the administrator has forbidden access to context menus */
                if (SHRestricted(REST_NOTRAYCONTEXTMENU))
                    break;

                pt.x = (SHORT)LOWORD(lParam);
                pt.y = (SHORT)HIWORD(lParam);

                if (pt.x != -1 || pt.y != -1)
                    ppt = &pt;
                else
                    hWndExclude = This->hwndStart;

                if ((HWND)wParam == This->hwndStart)
                {
                    /* Make sure we can't track the context menu if the start
                       menu is currently being shown */
                    if (!(SendMessage(This->hwndStart,
                                      BM_GETSTATE,
                                      0,
                                      0) & BST_PUSHED))
                    {
                        ITrayWindowImpl_TrackCtxMenu(This,
                                                     &StartMenuBtnCtxMenu,
                                                     ppt,
                                                     hWndExclude,
                                                     This->Position == ABE_BOTTOM,
                                                     This);
                    }
                }
                else
                {
                    /* See if the context menu should be handled by the task band site */
                    if (ppt != NULL && This->TrayBandSite != NULL)
                    {
                        HWND hWndAtPt;
                        POINT ptClient = *ppt;

                        /* Convert the coordinates to client-coordinates */
                        MapWindowPoints(NULL,
                                        This->hWnd,
                                        &ptClient,
                                        1);

                        hWndAtPt = ChildWindowFromPoint(This->hWnd,
                                                        ptClient);
                        if (hWndAtPt != NULL &&
                            (hWndAtPt == This->hwndRebar || IsChild(This->hwndRebar,
                                                                    hWndAtPt)))
                        {
                            /* Check if the user clicked on the task switch window */
                            ptClient = *ppt;
                            MapWindowPoints(NULL,
                                            This->hwndRebar,
                                            &ptClient,
                                            1);

                            hWndAtPt = ChildWindowFromPointEx(This->hwndRebar,
                                                              ptClient,
                                                              CWP_SKIPINVISIBLE | CWP_SKIPDISABLED);
                            if (hWndAtPt == This->hwndTaskSwitch)
                                goto HandleTrayContextMenu;

                            /* Forward the message to the task band site */
                            ITrayBandSite_ProcessMessage(This->TrayBandSite,
                                                         hwnd,
                                                         uMsg,
                                                         wParam,
                                                         lParam,
                                                         &Ret);
                        }
                        else
                            goto HandleTrayContextMenu;
                    }
                    else
                    {
HandleTrayContextMenu:
                        /* Tray the default tray window context menu */
                        ITrayWindowImpl_TrackCtxMenu(This,
                                                     &TrayWindowCtxMenu,
                                                     ppt,
                                                     NULL,
                                                     FALSE,
                                                     This);
                    }
                }
                break;
            }

            case WM_NOTIFY:
            {
                /* FIXME: We can't check with IsChild whether the hwnd is somewhere inside
                          the rebar control! But we shouldn't forward messages that the band
                          site doesn't handle, such as other controls (start button, tray window */
                if (This->TrayBandSite == NULL ||
                    !SUCCEEDED(ITrayBandSite_ProcessMessage(This->TrayBandSite,
                                                            hwnd,
                                                            uMsg,
                                                            wParam,
                                                            lParam,
                                                            &Ret)))
                {
                    const NMHDR *nmh = (const NMHDR *)lParam;

                    if (nmh->hwndFrom == This->hwndTrayNotify)
                    {
                        switch (nmh->code)
                        {
                            case NTNWM_REALIGN:
                                /* Cause all controls to be aligned */
                                PostMessage(This->hWnd,
                                            WM_SIZE,
                                            SIZE_RESTORED,
                                            0);
                                break;
                        }
                    }
                }
                break;
            }

            case WM_NCLBUTTONDBLCLK:
                /* We "handle" this message so users can't cause a weird maximize/restore
                   window animation when double-clicking the tray window! */
                break;

            case WM_NCCREATE:
            {
                LPCREATESTRUCT CreateStruct = (LPCREATESTRUCT)lParam;
                This = (ITrayWindowImpl*)CreateStruct->lpCreateParams;

                if (InterlockedCompareExchangePointer((PVOID*)&This->hWnd,
                                                      (PVOID)hwnd,
                                                      NULL) != NULL)
                {
                    /* Somebody else was faster... */
                    return FALSE;
                }

                SetWindowLongPtr(hwnd,
                                 0,
                                 (LONG_PTR)This);

                return ITrayWindowImpl_NCCreate(This);
            }

            case WM_CREATE:
                ITrayWindowImpl_Create(This);
                break;

            case WM_NCDESTROY:
                ITrayWindowImpl_Destroy(This);
                break;

            case WM_APP_TRAYDESTROY:
                DestroyWindow(hwnd);
                break;

            case WM_COMMAND:
                if ((HWND)lParam == This->hwndStart)
                {
                    if (This->StartMenuPopup != NULL)
                    {
                        POINTL pt;
                        RECTL rcExclude;
                        DWORD dwFlags = 0;

                        if (GetWindowRect(This->hwndStart,
                                          (RECT*)&rcExclude))
                        {
                            if (ITrayWindowImpl_IsPosHorizontal(This))
                            {
                                pt.x = rcExclude.left;
                                pt.y = rcExclude.top;
                                dwFlags |= MPPF_BOTTOM;
                            }
                            else
                            {
                                if (This->Position == ABE_LEFT)
                                    pt.x = rcExclude.left;
                                else
                                    pt.x = rcExclude.right;

                                pt.y = rcExclude.bottom;
                                dwFlags |= MPPF_BOTTOM;
                            }

                            IMenuPopup_Popup(This->StartMenuPopup,
                                             &pt,
                                             &rcExclude,
                                             dwFlags);
                        }
                    }
                    break;
                }

                if (This->TrayBandSite == NULL ||
                    !SUCCEEDED(ITrayBandSite_ProcessMessage(This->TrayBandSite,
                                                            hwnd,
                                                            uMsg,
                                                            wParam,
                                                            lParam,
                                                            &Ret)))
                {
                    switch(LOWORD(wParam))
                    {
                        /* FIXME: Handle these commands as well */
                        case IDM_TASKBARANDSTARTMENU:
                        case IDM_SEARCH:
                        case IDM_HELPANDSUPPORT:
                            break;

                        case IDM_RUN:
                        {
                            HANDLE hShell32;
                            RUNFILEDLG RunFileDlg;

                            hShell32 = GetModuleHandle(TEXT("SHELL32.DLL"));
                            RunFileDlg = (RUNFILEDLG)GetProcAddress(hShell32, (LPCSTR)61);

                            RunFileDlg(hwnd, NULL, NULL, NULL, NULL, RFF_CALCDIRECTORY);
                            break;
                        }

                        /* FIXME: Handle these commands as well */
                        case IDM_SYNCHRONIZE:
                        case IDM_LOGOFF:
                        case IDM_DISCONNECT:
                        case IDM_UNDOCKCOMPUTER:
                            break;

                        case IDM_SHUTDOWN:
                        {
                            HANDLE hShell32;
                            EXITWINDLG ExitWinDlg;

                            hShell32 = GetModuleHandle(TEXT("SHELL32.DLL"));
                            ExitWinDlg = (EXITWINDLG)GetProcAddress(hShell32, (LPCSTR)60);

                            ExitWinDlg(hwnd);
                            break;
                        }
                    }
                }
                break;

            default:
                goto DefHandler;
        }
    }
    else
    {
DefHandler:
        Ret = DefWindowProc(hwnd,
                            uMsg,
                            wParam,
                            lParam);
    }

    return Ret;
}

Generated on Sat May 26 2012 04:45:09 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.