#define IDHK_DESKTOP 0x1fe
#define IDHK_PAGER 0x1ff
-static LONG TrayWndCount = 0;
-
-static const WCHAR szTrayWndClass [] = TEXT("Shell_TrayWnd");
+static const WCHAR szTrayWndClass[] = L"Shell_TrayWnd";
/*
* ITrayWindow
const GUID IID_IShellDesktopTray = { 0x213e2df9, 0x9a14, 0x4328, { 0x99, 0xb1, 0x69, 0x61, 0xf9, 0x14, 0x3c, 0xe9 } };
+class CStartButton
+ : public CWindow
+{
+ HIMAGELIST m_ImageList;
+ SIZE m_Size;
+ HFONT m_Font;
+
+public:
+ CStartButton()
+ : m_ImageList(NULL),
+ m_Font(NULL)
+ {
+ m_Size.cx = 0;
+ m_Size.cy = 0;
+ }
+
+ virtual ~CStartButton()
+ {
+ if (m_ImageList != NULL)
+ ImageList_Destroy(m_ImageList);
+
+ if (m_Font != NULL)
+ DeleteObject(m_Font);
+ }
+
+ SIZE GetSize()
+ {
+ return m_Size;
+ }
+
+ VOID UpdateSize()
+ {
+ SIZE Size = { 0, 0 };
+
+ if (m_ImageList == NULL ||
+ !SendMessageW(BCM_GETIDEALSIZE, 0, (LPARAM) &Size))
+ {
+ Size.cx = 2 * GetSystemMetrics(SM_CXEDGE) + GetSystemMetrics(SM_CYCAPTION) * 3;
+ }
+
+ if (GetWindowTheme(m_hWnd))
+ Size.cy = max(Size.cy, GetSystemMetrics(SM_CYCAPTION));
+ else
+ Size.cy = max(Size.cy, GetSystemMetrics(SM_CYSIZE) + (2 * GetSystemMetrics(SM_CYEDGE)));
+
+ /* Save the size of the start button */
+ m_Size = Size;
+ }
+
+ VOID UpdateFont()
+ {
+ /* Get the system fonts, we use the caption font, always bold, though. */
+ NONCLIENTMETRICS ncm = {sizeof(ncm)};
+ if (!SystemParametersInfoW(SPI_GETNONCLIENTMETRICS, sizeof(ncm), &ncm, FALSE))
+ return;
+
+ if (m_Font)
+ DeleteObject(m_Font);
+
+ ncm.lfCaptionFont.lfWeight = FW_BOLD;
+ m_Font = CreateFontIndirect(&ncm.lfCaptionFont);
+
+ SetFont(m_Font, FALSE);
+ }
+
+ VOID Initialize()
+ {
+ SetWindowTheme(m_hWnd, L"Start", NULL);
+
+ m_ImageList = ImageList_LoadImageW(hExplorerInstance,
+ MAKEINTRESOURCEW(IDB_START),
+ 0, 0, 0,
+ IMAGE_BITMAP,
+ LR_LOADTRANSPARENT | LR_CREATEDIBSECTION);
+
+ BUTTON_IMAGELIST bil = {m_ImageList, {1,1,1,1}, BUTTON_IMAGELIST_ALIGN_LEFT};
+ SendMessageW(BCM_SETIMAGELIST, 0, (LPARAM) &bil);
+ UpdateSize();
+ }
+
+ HWND Create(HWND hwndParent)
+ {
+ WCHAR szStartCaption[32];
+ if (!LoadStringW(hExplorerInstance,
+ IDS_START,
+ szStartCaption,
+ _countof(szStartCaption)))
+ {
+ wcscpy(szStartCaption, L"Start");
+ }
+
+ DWORD dwStyle = WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | BS_PUSHBUTTON | BS_LEFT | BS_VCENTER;
+
+ m_hWnd = CreateWindowEx(
+ 0,
+ WC_BUTTON,
+ szStartCaption,
+ dwStyle,
+ 0, 0, 0, 0,
+ hwndParent,
+ (HMENU) IDC_STARTBTN,
+ hExplorerInstance,
+ NULL);
+
+ if (m_hWnd)
+ Initialize();
+
+ return m_hWnd;
+ }
+};
+
class CTrayWindow :
public CComCoClass<CTrayWindow>,
public CComObjectRootEx<CComMultiThreadModelNoCS>,
public CWindowImpl < CTrayWindow, CWindow, CControlWinTraits >,
public ITrayWindow,
- public IShellDesktopTray
+ public IShellDesktopTray,
+ public IOleWindow
{
- CContainedWindow StartButton;
+ CStartButton m_StartButton;
- HTHEME TaskbarTheme;
- HWND hWndDesktop;
+ CComPtr<IMenuBand> m_StartMenuBand;
+ CComPtr<IMenuPopup> m_StartMenuPopup;
- IImageList * himlStartBtn;
- SIZE StartBtnSize;
- HFONT hStartBtnFont;
- HFONT hCaptionFont;
+ CComPtr<IDeskBand> m_TaskBand;
+ HTHEME m_Theme;
- HWND hwndRebar;
- HWND hwndTaskSwitch;
- HWND hwndTrayNotify;
+ HFONT m_Font;
- DWORD Position;
- HMONITOR Monitor;
- HMONITOR PreviousMonitor;
- DWORD DraggingPosition;
- HMONITOR DraggingMonitor;
+ HWND m_DesktopWnd;
+ HWND m_Rebar;
+ HWND m_TaskSwitch;
+ HWND m_TrayNotify;
- RECT rcTrayWnd[4];
- RECT rcNewPosSize;
- SIZE TraySize;
+ CTrayNotifyWnd* m_TrayNotifyInstance;
- NONCLIENTMETRICS ncm;
- HFONT hFont;
+ DWORD m_Position;
+ HMONITOR m_Monitor;
+ HMONITOR m_PreviousMonitor;
+ DWORD m_DraggingPosition;
+ HMONITOR m_DraggingMonitor;
- CComPtr<IMenuBand> StartMenuBand;
- CComPtr<IMenuPopup> StartMenuPopup;
- HBITMAP hbmStartMenu;
+ RECT m_TrayRects[4];
+ SIZE m_TraySize;
- HWND hwndTrayPropertiesOwner;
- HWND hwndRunFileDlgOwner;
+ HWND m_TrayPropertiesOwner;
+ HWND m_RunFileDlgOwner;
- UINT AutoHideState;
- SIZE AutoHideOffset;
- TRACKMOUSEEVENT MouseTrackingInfo;
+ UINT m_AutoHideState;
+ SIZE m_AutoHideOffset;
+ TRACKMOUSEEVENT m_MouseTrackingInfo;
- HDPA hdpaShellServices;
+ HDPA m_ShellServices;
public:
- CComPtr<ITrayBandSite> TrayBandSite;
+ CComPtr<ITrayBandSite> m_TrayBandSite;
+
union
{
DWORD Flags;
public:
CTrayWindow() :
- StartButton(this, 1),
- TaskbarTheme(NULL),
- hWndDesktop(NULL),
- himlStartBtn(NULL),
- hStartBtnFont(NULL),
- hCaptionFont(NULL),
- hwndRebar(NULL),
- hwndTaskSwitch(NULL),
- hwndTrayNotify(NULL),
- Position(0),
- Monitor(NULL),
- PreviousMonitor(NULL),
- DraggingPosition(0),
- DraggingMonitor(NULL),
- hFont(NULL),
- hbmStartMenu(NULL),
- hwndTrayPropertiesOwner(NULL),
- hwndRunFileDlgOwner(NULL),
- AutoHideState(NULL),
- hdpaShellServices(NULL),
+ m_StartButton(),
+ m_Theme(NULL),
+ m_Font(NULL),
+ m_DesktopWnd(NULL),
+ m_Rebar(NULL),
+ m_TaskSwitch(NULL),
+ m_TrayNotify(NULL),
+ m_Position(0),
+ m_Monitor(NULL),
+ m_PreviousMonitor(NULL),
+ m_DraggingPosition(0),
+ m_DraggingMonitor(NULL),
+ m_TrayPropertiesOwner(NULL),
+ m_RunFileDlgOwner(NULL),
+ m_AutoHideState(NULL),
+ m_ShellServices(NULL),
Flags(0)
{
- ZeroMemory(&StartBtnSize, sizeof(StartBtnSize));
- ZeroMemory(&rcTrayWnd, sizeof(rcTrayWnd));
- ZeroMemory(&rcNewPosSize, sizeof(rcNewPosSize));
- ZeroMemory(&TraySize, sizeof(TraySize));
- ZeroMemory(&ncm, sizeof(ncm));
- ZeroMemory(&AutoHideOffset, sizeof(AutoHideOffset));
- ZeroMemory(&MouseTrackingInfo, sizeof(MouseTrackingInfo));
+ ZeroMemory(&m_TrayRects, sizeof(m_TrayRects));
+ ZeroMemory(&m_TraySize, sizeof(m_TraySize));
+ ZeroMemory(&m_AutoHideOffset, sizeof(m_AutoHideOffset));
+ ZeroMemory(&m_MouseTrackingInfo, sizeof(m_MouseTrackingInfo));
}
virtual ~CTrayWindow()
{
- (void) InterlockedExchangePointer((PVOID*) &m_hWnd, NULL);
-
-
- if (hdpaShellServices != NULL)
+ if (m_ShellServices != NULL)
{
- ShutdownShellServices(hdpaShellServices);
- hdpaShellServices = NULL;
+ ShutdownShellServices(m_ShellServices);
+ m_ShellServices = NULL;
}
- if (himlStartBtn != NULL)
+ if (m_Font != NULL)
{
- himlStartBtn->Release();
- himlStartBtn = NULL;
+ DeleteObject(m_Font);
+ m_Font = NULL;
}
- if (hCaptionFont != NULL)
+ if (m_Theme)
{
- DeleteObject(hCaptionFont);
- hCaptionFont = NULL;
+ CloseThemeData(m_Theme);
+ m_Theme = NULL;
}
- if (hStartBtnFont != NULL)
- {
- DeleteObject(hStartBtnFont);
- hStartBtnFont = NULL;
- }
+ PostQuitMessage(0);
+ }
- if (hFont != NULL)
- {
- DeleteObject(hFont);
- hFont = NULL;
- }
- if (hbmStartMenu != NULL)
- {
- DeleteObject(hbmStartMenu);
- hbmStartMenu = NULL;
- }
- if (TaskbarTheme)
- {
- CloseThemeData(TaskbarTheme);
- TaskbarTheme = NULL;
- }
- if (InterlockedDecrement(&TrayWndCount) == 0)
- PostQuitMessage(0);
- }
- /*
- * ITrayWindow
+ /**********************************************************
+ * ##### command handling #####
*/
- BOOL UpdateNonClientMetrics()
+ HRESULT ExecResourceCmd(int id)
{
- ncm.cbSize = sizeof(ncm);
- if (SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(ncm), &ncm, 0))
+ WCHAR szCommand[256];
+ WCHAR *pszParameters;
+
+ if (!LoadStringW(hExplorerInstance,
+ id,
+ szCommand,
+ _countof(szCommand)))
{
- if (hFont != NULL)
- DeleteObject(hFont);
+ return E_FAIL;
+ }
- hFont = CreateFontIndirect(&ncm.lfMessageFont);
- return TRUE;
+ pszParameters = wcschr(szCommand, L'>');
+ if (pszParameters)
+ {
+ *pszParameters = 0;
+ pszParameters++;
}
- return FALSE;
+ ShellExecuteW(m_hWnd, NULL, szCommand, pszParameters, NULL, SW_SHOWNORMAL);
+ return S_OK;
}
- VOID SetWindowsFont()
+ LRESULT DoExitWindows()
{
- if (hwndTrayNotify != NULL)
- {
- SendMessage(hwndTrayNotify, WM_SETFONT, (WPARAM) hFont, TRUE);
- }
+ ExitWindowsDialog(m_hWnd);
+ return 0;
}
- HMONITOR GetScreenRectFromRect(
- IN OUT RECT *pRect,
- IN DWORD dwFlags)
+ DWORD WINAPI RunFileDlgThread()
{
- MONITORINFO mi;
- HMONITOR hMon;
-
- mi.cbSize = sizeof(mi);
- hMon = MonitorFromRect(pRect,
- dwFlags);
- if (hMon != NULL &&
- GetMonitorInfo(hMon,
- &mi))
- {
- *pRect = mi.rcMonitor;
- }
- else
- {
- pRect->left = 0;
- pRect->top = 0;
- pRect->right = GetSystemMetrics(SM_CXSCREEN);
- pRect->bottom = GetSystemMetrics(SM_CYSCREEN);
-
- hMon = NULL;
- }
+ HWND hwnd;
+ RECT posRect;
- return hMon;
- }
+ m_StartButton.GetWindowRect(&posRect);
- HMONITOR GetMonitorFromRect(
- IN const RECT *pRect)
- {
- HMONITOR hMon;
+ hwnd = CreateWindowEx(0,
+ WC_STATIC,
+ NULL,
+ WS_OVERLAPPED | WS_DISABLED | WS_CLIPSIBLINGS | WS_BORDER | SS_LEFT,
+ posRect.left,
+ posRect.top,
+ posRect.right - posRect.left,
+ posRect.bottom - posRect.top,
+ NULL,
+ NULL,
+ NULL,
+ NULL);
- /* In case the monitor sizes or saved sizes differ a bit (probably
- not a lot, only so the tray window overlaps into another monitor
- now), minimize the risk that we determine a wrong monitor by
- using the center point of the tray window if we can't determine
- it using the rectangle. */
- hMon = MonitorFromRect(pRect,
- MONITOR_DEFAULTTONULL);
- if (hMon == NULL)
- {
- POINT pt;
+ m_RunFileDlgOwner = hwnd;
- pt.x = pRect->left + ((pRect->right - pRect->left) / 2);
- pt.y = pRect->top + ((pRect->bottom - pRect->top) / 2);
+ RunFileDlg(hwnd, NULL, NULL, NULL, NULL, RFF_CALCDIRECTORY);
- /* be less error-prone, find the nearest monitor */
- hMon = MonitorFromPoint(pt,
- MONITOR_DEFAULTTONEAREST);
- }
+ m_RunFileDlgOwner = NULL;
+ ::DestroyWindow(hwnd);
- return hMon;
+ return 0;
}
- HMONITOR GetScreenRect(
- IN HMONITOR hMonitor,
- IN OUT RECT *pRect)
+ static DWORD WINAPI s_RunFileDlgThread(IN OUT PVOID pParam)
{
- HMONITOR hMon = NULL;
+ CTrayWindow * This = (CTrayWindow*) pParam;
+ return This->RunFileDlgThread();
+ }
- if (hMonitor != NULL)
+ void DisplayRunFileDlg()
+ {
+ HWND hRunDlg;
+ if (m_RunFileDlgOwner)
{
- MONITORINFO mi;
-
- mi.cbSize = sizeof(mi);
- if (!GetMonitorInfo(hMonitor,
- &mi))
+ hRunDlg = ::GetLastActivePopup(m_RunFileDlgOwner);
+ if (hRunDlg != NULL &&
+ hRunDlg != m_RunFileDlgOwner)
{
- /* Hm, the monitor is gone? Try to find a monitor where it
- could be located now */
- hMon = GetMonitorFromRect(
- pRect);
- if (hMon == NULL ||
- !GetMonitorInfo(hMon,
- &mi))
- {
- hMon = NULL;
- goto GetPrimaryRect;
- }
+ SetForegroundWindow(hRunDlg);
+ return;
}
-
- *pRect = mi.rcMonitor;
- }
- else
- {
-GetPrimaryRect:
- pRect->left = 0;
- pRect->top = 0;
- pRect->right = GetSystemMetrics(SM_CXSCREEN);
- pRect->bottom = GetSystemMetrics(SM_CYSCREEN);
}
- return hMon;
+ CloseHandle(CreateThread(NULL, 0, s_RunFileDlgThread, this, 0, NULL));
}
- VOID MakeTrayRectWithSize(IN DWORD Position,
- IN const SIZE *pTraySize,
- IN OUT RECT *pRect)
+ DWORD WINAPI TrayPropertiesThread()
{
- switch (Position)
- {
- case ABE_LEFT:
- pRect->right = pRect->left + pTraySize->cx;
- break;
-
- case ABE_TOP:
- pRect->bottom = pRect->top + pTraySize->cy;
- break;
-
- case ABE_RIGHT:
- pRect->left = pRect->right - pTraySize->cx;
- break;
+ HWND hwnd;
+ RECT posRect;
- case ABE_BOTTOM:
- default:
- pRect->top = pRect->bottom - pTraySize->cy;
- break;
- }
- }
+ m_StartButton.GetWindowRect(&posRect);
+ hwnd = CreateWindowEx(0,
+ WC_STATIC,
+ NULL,
+ WS_OVERLAPPED | WS_DISABLED | WS_CLIPSIBLINGS | WS_BORDER | SS_LEFT,
+ posRect.left,
+ posRect.top,
+ posRect.right - posRect.left,
+ posRect.bottom - posRect.top,
+ NULL,
+ NULL,
+ NULL,
+ NULL);
- VOID GetTrayRectFromScreenRect(IN DWORD Position,
- IN const RECT *pScreen,
- IN const SIZE *pTraySize OPTIONAL,
- OUT RECT *pRect)
- {
- if (pTraySize == NULL)
- pTraySize = &TraySize;
+ m_TrayPropertiesOwner = hwnd;
- *pRect = *pScreen;
+ DisplayTrayProperties(hwnd);
- /* Move the border outside of the screen */
- InflateRect(pRect,
- GetSystemMetrics(SM_CXEDGE),
- GetSystemMetrics(SM_CYEDGE));
+ m_TrayPropertiesOwner = NULL;
+ ::DestroyWindow(hwnd);
- MakeTrayRectWithSize(Position, pTraySize, pRect);
+ return 0;
}
- BOOL
- IsPosHorizontal()
+ static DWORD WINAPI s_TrayPropertiesThread(IN OUT PVOID pParam)
{
- return Position == ABE_TOP || Position == ABE_BOTTOM;
+ CTrayWindow *This = (CTrayWindow*) pParam;
+
+ return This->TrayPropertiesThread();
}
- HMONITOR
- CalculateValidSize(
- IN DWORD Position,
- IN OUT RECT *pRect)
+ HWND STDMETHODCALLTYPE DisplayProperties()
{
- RECT rcScreen;
- //BOOL Horizontal;
- HMONITOR hMon;
- SIZE szMax, szWnd;
+ HWND hTrayProp;
- //Horizontal = IsPosHorizontal();
+ if (m_TrayPropertiesOwner)
+ {
+ hTrayProp = ::GetLastActivePopup(m_TrayPropertiesOwner);
+ if (hTrayProp != NULL &&
+ hTrayProp != m_TrayPropertiesOwner)
+ {
+ SetForegroundWindow(hTrayProp);
+ return NULL;
+ }
+ }
- szWnd.cx = pRect->right - pRect->left;
- szWnd.cy = pRect->bottom - pRect->top;
+ CloseHandle(CreateThread(NULL, 0, s_TrayPropertiesThread, this, 0, NULL));
+ return NULL;
+ }
- rcScreen = *pRect;
- hMon = GetScreenRectFromRect(
- &rcScreen,
- MONITOR_DEFAULTTONEAREST);
-
- /* Calculate the maximum size of the tray window and limit the window
- size to half of the screen's size. */
- szMax.cx = (rcScreen.right - rcScreen.left) / 2;
- szMax.cy = (rcScreen.bottom - rcScreen.top) / 2;
- if (szWnd.cx > szMax.cx)
- szWnd.cx = szMax.cx;
- if (szWnd.cy > szMax.cy)
- szWnd.cy = szMax.cy;
-
- /* FIXME - calculate */
+ VOID OpenCommonStartMenuDirectory(IN HWND hWndOwner, IN LPCTSTR lpOperation)
+ {
+ WCHAR szDir[MAX_PATH];
- GetTrayRectFromScreenRect(
- Position,
- &rcScreen,
- &szWnd,
- pRect);
+ if (SHGetSpecialFolderPath(hWndOwner,
+ szDir,
+ CSIDL_COMMON_STARTMENU,
+ FALSE))
+ {
+ ShellExecute(hWndOwner,
+ lpOperation,
+ szDir,
+ NULL,
+ NULL,
+ SW_SHOWNORMAL);
+ }
+ }
- return hMon;
+ VOID OpenTaskManager(IN HWND hWndOwner)
+ {
+ ShellExecute(hWndOwner,
+ TEXT("open"),
+ TEXT("taskmgr.exe"),
+ NULL,
+ NULL,
+ SW_SHOWNORMAL);
}
-#if 0
- VOID
- GetMinimumWindowSize(
- OUT RECT *pRect)
+ BOOL STDMETHODCALLTYPE ExecContextMenuCmd(IN UINT uiCmd)
{
- RECT rcMin = {0};
+ switch (uiCmd)
+ {
+ case ID_SHELL_CMD_PROPERTIES:
+ DisplayProperties();
+ break;
- AdjustWindowRectEx(&rcMin,
- GetWindowLong(m_hWnd,
- GWL_STYLE),
- FALSE,
- GetWindowLong(m_hWnd,
- GWL_EXSTYLE));
+ case ID_SHELL_CMD_OPEN_ALL_USERS:
+ OpenCommonStartMenuDirectory(m_hWnd,
+ TEXT("open"));
+ break;
- *pRect = rcMin;
- }
-#endif
+ case ID_SHELL_CMD_EXPLORE_ALL_USERS:
+ OpenCommonStartMenuDirectory(m_hWnd,
+ TEXT("explore"));
+ break;
+ case ID_LOCKTASKBAR:
+ if (SHRestricted(REST_CLASSICSHELL) == 0)
+ {
+ Lock(!Locked);
+ }
+ break;
- DWORD
- GetDraggingRectFromPt(
- IN POINT pt,
- OUT RECT *pRect,
- OUT HMONITOR *phMonitor)
- {
- HMONITOR hMon, hMonNew;
- DWORD PosH, PosV, Pos;
- SIZE DeltaPt, ScreenOffset;
- RECT rcScreen;
+ case ID_SHELL_CMD_OPEN_TASKMGR:
+ OpenTaskManager(m_hWnd);
+ break;
- rcScreen.left = 0;
- rcScreen.top = 0;
+ case ID_SHELL_CMD_UNDO_ACTION:
+ break;
- /* Determine the screen rectangle */
- hMon = MonitorFromPoint(pt,
- MONITOR_DEFAULTTONULL);
+ case ID_SHELL_CMD_SHOW_DESKTOP:
+ break;
- if (hMon != NULL)
- {
- MONITORINFO mi;
+ case ID_SHELL_CMD_TILE_WND_H:
+ TileWindows(NULL, MDITILE_HORIZONTAL, NULL, 0, NULL);
+ break;
- mi.cbSize = sizeof(mi);
- if (!GetMonitorInfo(hMon,
- &mi))
- {
- hMon = NULL;
- goto GetPrimaryScreenRect;
- }
+ case ID_SHELL_CMD_TILE_WND_V:
+ TileWindows(NULL, MDITILE_VERTICAL, NULL, 0, NULL);
+ break;
- /* make left top corner of the screen zero based to
- make calculations easier */
- pt.x -= mi.rcMonitor.left;
- pt.y -= mi.rcMonitor.top;
+ case ID_SHELL_CMD_CASCADE_WND:
+ CascadeWindows(NULL, MDITILE_SKIPDISABLED, NULL, 0, NULL);
+ break;
- ScreenOffset.cx = mi.rcMonitor.left;
- ScreenOffset.cy = mi.rcMonitor.top;
- rcScreen.right = mi.rcMonitor.right - mi.rcMonitor.left;
- rcScreen.bottom = mi.rcMonitor.bottom - mi.rcMonitor.top;
- }
- else
- {
-GetPrimaryScreenRect:
- ScreenOffset.cx = 0;
- ScreenOffset.cy = 0;
- rcScreen.right = GetSystemMetrics(SM_CXSCREEN);
- rcScreen.bottom = GetSystemMetrics(SM_CYSCREEN);
- }
+ case ID_SHELL_CMD_CUST_NOTIF:
+ ShowCustomizeNotifyIcons(hExplorerInstance, m_hWnd);
+ break;
- /* Calculate the nearest screen border */
- if (pt.x < rcScreen.right / 2)
- {
- DeltaPt.cx = pt.x;
- PosH = ABE_LEFT;
- }
- else
- {
- DeltaPt.cx = rcScreen.right - pt.x;
- PosH = ABE_RIGHT;
+ case ID_SHELL_CMD_ADJUST_DAT:
+ //FIXME: Use SHRunControlPanel
+ ShellExecuteW(m_hWnd, NULL, L"timedate.cpl", NULL, NULL, SW_NORMAL);
+ break;
+
+ default:
+ TRACE("ITrayWindow::ExecContextMenuCmd(%u): Unhandled Command ID!\n", uiCmd);
+ return FALSE;
}
- if (pt.y < rcScreen.bottom / 2)
+ return TRUE;
+ }
+
+ LRESULT HandleHotKey(DWORD id)
+ {
+ switch (id)
{
- DeltaPt.cy = pt.y;
- PosV = ABE_TOP;
+ case IDHK_RUN:
+ DisplayRunFileDlg();
+ break;
+ case IDHK_HELP:
+ ExecResourceCmd(IDS_HELP_COMMAND);
+ break;
+ case IDHK_EXPLORE:
+ //FIXME: We don't support this yet:
+ //ShellExecuteW(0, L"explore", NULL, NULL, NULL, 1);
+ ShellExecuteW(0, NULL, L"explorer.exe", NULL, NULL, 1);
+ break;
+ case IDHK_FIND:
+ SHFindFiles(NULL, NULL);
+ break;
+ case IDHK_FIND_COMPUTER:
+ SHFindComputer(NULL, NULL);
+ break;
+ case IDHK_SYS_PROPERTIES:
+ //FIXME: Use SHRunControlPanel
+ ShellExecuteW(m_hWnd, NULL, L"sysdm.cpl", NULL, NULL, SW_NORMAL);
+ break;
+ case IDHK_NEXT_TASK:
+ break;
+ case IDHK_PREV_TASK:
+ break;
+ case IDHK_MINIMIZE_ALL:
+ break;
+ case IDHK_RESTORE_ALL:
+ break;
+ case IDHK_DESKTOP:
+ break;
+ case IDHK_PAGER:
+ break;
}
- else
+
+ return 0;
+ }
+
+ LRESULT HandleCommand(UINT uCommand)
+ {
+ switch (uCommand)
{
- DeltaPt.cy = rcScreen.bottom - pt.y;
- PosV = ABE_BOTTOM;
- }
+ case IDM_TASKBARANDSTARTMENU:
+ DisplayProperties();
+ break;
- Pos = (DeltaPt.cx * rcScreen.bottom < DeltaPt.cy * rcScreen.right) ? PosH : PosV;
+ case IDM_SEARCH:
+ SHFindFiles(NULL, NULL);
+ break;
- /* Fix the screen origin to be relative to the primary monitor again */
- OffsetRect(&rcScreen,
- ScreenOffset.cx,
- ScreenOffset.cy);
+ case IDM_HELPANDSUPPORT:
+ ExecResourceCmd(IDS_HELP_COMMAND);
+ break;
- hMonNew = GetMonitorFromRect(
- &rcTrayWnd[Pos]);
- if (hMon != hMonNew)
- {
- SIZE szTray;
+ case IDM_RUN:
+ DisplayRunFileDlg();
+ break;
- /* Recalculate the rectangle, we're dragging to another monitor.
- We don't need to recalculate the rect on single monitor systems. */
- szTray.cx = rcTrayWnd[Pos].right - rcTrayWnd[Pos].left;
- szTray.cy = rcTrayWnd[Pos].bottom - rcTrayWnd[Pos].top;
+ /* FIXME: Handle these commands as well */
+ case IDM_SYNCHRONIZE:
+ case IDM_DISCONNECT:
+ case IDM_UNDOCKCOMPUTER:
+ break;
- GetTrayRectFromScreenRect(
- Pos,
- &rcScreen,
- &szTray,
- pRect);
- if (AutoHide)
+ case IDM_LOGOFF:
+ LogoffWindowsDialog(m_hWnd); // FIXME: Maybe handle it in a similar way as DoExitWindows?
+ break;
+
+ case IDM_SHUTDOWN:
+ DoExitWindows();
+ break;
+ }
+
+ return FALSE;
+ }
+
+
+ UINT TrackMenu(
+ IN HMENU hMenu,
+ IN POINT *ppt OPTIONAL,
+ IN HWND hwndExclude OPTIONAL,
+ IN BOOL TrackUp,
+ IN BOOL IsContextMenu)
+ {
+ TPMPARAMS tmp, *ptmp = NULL;
+ POINT pt;
+ UINT cmdId;
+ UINT fuFlags;
+
+ if (hwndExclude != NULL)
+ {
+ /* Get the client rectangle and map it to screen coordinates */
+ if (::GetClientRect(hwndExclude,
+ &tmp.rcExclude) &&
+ ::MapWindowPoints(hwndExclude,
+ NULL,
+ (LPPOINT) &tmp.rcExclude,
+ 2) != 0)
{
- pRect->left += AutoHideOffset.cx;
- pRect->right += AutoHideOffset.cx;
- pRect->top += AutoHideOffset.cy;
- pRect->bottom += AutoHideOffset.cy;
+ ptmp = &tmp;
}
- hMon = hMonNew;
}
- else
+
+ if (ppt == NULL)
{
- /* The user is dragging the tray window on the same monitor. We don't need
- to recalculate the rectangle */
- *pRect = rcTrayWnd[Pos];
- if (AutoHide)
+ if (ptmp == NULL &&
+ GetClientRect(&tmp.rcExclude) &&
+ MapWindowPoints(
+ NULL,
+ (LPPOINT) &tmp.rcExclude,
+ 2) != 0)
{
- pRect->left += AutoHideOffset.cx;
- pRect->right += AutoHideOffset.cx;
- pRect->top += AutoHideOffset.cy;
- pRect->bottom += AutoHideOffset.cy;
+ ptmp = &tmp;
+ }
+
+ if (ptmp != NULL)
+ {
+ /* NOTE: TrackPopupMenuEx will eventually align the track position
+ for us, no need to take care of it here as long as the
+ coordinates are somewhere within the exclusion rectangle */
+ pt.x = ptmp->rcExclude.left;
+ pt.y = ptmp->rcExclude.top;
}
+ else
+ pt.x = pt.y = 0;
}
+ else
+ pt = *ppt;
- *phMonitor = hMon;
+ tmp.cbSize = sizeof(tmp);
- return Pos;
+ fuFlags = TPM_RETURNCMD | TPM_VERTICAL;
+ fuFlags |= (TrackUp ? TPM_BOTTOMALIGN : TPM_TOPALIGN);
+ if (IsContextMenu)
+ fuFlags |= TPM_RIGHTBUTTON;
+ else
+ fuFlags |= (TrackUp ? TPM_VERNEGANIMATION : TPM_VERPOSANIMATION);
+
+ cmdId = TrackPopupMenuEx(hMenu,
+ fuFlags,
+ pt.x,
+ pt.y,
+ m_hWnd,
+ ptmp);
+
+ return cmdId;
}
- DWORD
- GetDraggingRectFromRect(
- IN OUT RECT *pRect,
- OUT HMONITOR *phMonitor)
+ HRESULT TrackCtxMenu(
+ IN IContextMenu * contextMenu,
+ IN POINT *ppt OPTIONAL,
+ IN HWND hwndExclude OPTIONAL,
+ IN BOOL TrackUp,
+ IN PVOID Context OPTIONAL)
{
- POINT pt;
+ INT x = ppt->x;
+ INT y = ppt->y;
+ HRESULT hr;
+ UINT uCommand;
+ HMENU popup = CreatePopupMenu();
- /* Calculate the center of the rectangle. We call
- GetDraggingRectFromPt to calculate a valid
- dragging rectangle */
- pt.x = pRect->left + ((pRect->right - pRect->left) / 2);
- pt.y = pRect->top + ((pRect->bottom - pRect->top) / 2);
+ if (popup == NULL)
+ return E_FAIL;
- return GetDraggingRectFromPt(
- pt,
- pRect,
- phMonitor);
- }
+ TRACE("Before Query\n");
+ hr = contextMenu->QueryContextMenu(popup, 0, 0, UINT_MAX, CMF_NORMAL);
+ if (FAILED_UNEXPECTEDLY(hr))
+ {
+ TRACE("Query failed\n");
+ DestroyMenu(popup);
+ return hr;
+ }
- VOID
- ChangingWinPos(
- IN OUT LPWINDOWPOS pwp)
- {
- RECT rcTray;
+ TRACE("Before Tracking\n");
+ uCommand = ::TrackPopupMenuEx(popup, TPM_RETURNCMD, x, y, m_hWnd, NULL);
- if (IsDragging)
+ if (uCommand != 0)
{
- rcTray.left = pwp->x;
- rcTray.top = pwp->y;
- rcTray.right = rcTray.left + pwp->cx;
- rcTray.bottom = rcTray.top + pwp->cy;
- if (AutoHide)
- {
- rcTray.left -= AutoHideOffset.cx;
- rcTray.right -= AutoHideOffset.cx;
- rcTray.top -= AutoHideOffset.cy;
- rcTray.bottom -= AutoHideOffset.cy;
- }
+ TRACE("Before InvokeCommand\n");
+ CMINVOKECOMMANDINFO cmi = { 0 };
+ cmi.cbSize = sizeof(cmi);
+ cmi.lpVerb = MAKEINTRESOURCEA(uCommand);
+ cmi.hwnd = m_hWnd;
+ hr = contextMenu->InvokeCommand(&cmi);
+ }
+ else
+ {
+ TRACE("TrackPopupMenu failed. Code=%d, LastError=%d\n", uCommand, GetLastError());
+ hr = S_FALSE;
+ }
- if (!EqualRect(&rcTray,
- &rcTrayWnd[DraggingPosition]))
- {
- /* Recalculate the rectangle, the user dragged the tray
- window to another monitor or the window was somehow else
- moved or resized */
- DraggingPosition = GetDraggingRectFromRect(
- &rcTray,
- &DraggingMonitor);
- //rcTrayWnd[DraggingPosition] = rcTray;
- }
+ DestroyMenu(popup);
+ return hr;
+ }
- //Monitor = CalculateValidSize(
- // DraggingPosition,
- // &rcTray);
- Monitor = DraggingMonitor;
- Position = DraggingPosition;
- IsDragging = FALSE;
- rcTrayWnd[Position] = rcTray;
- goto ChangePos;
+
+
+ /**********************************************************
+ * ##### moving and sizing handling #####
+ */
+
+ void UpdateFonts()
+ {
+ m_StartButton.UpdateFont();
+
+ NONCLIENTMETRICS ncm = {sizeof(ncm)};
+ if (!SystemParametersInfoW(SPI_GETNONCLIENTMETRICS, sizeof(ncm), &ncm, FALSE))
+ {
+ ERR("SPI_GETNONCLIENTMETRICS failed\n");
+ return;
}
- else if (GetWindowRect(m_hWnd, &rcTray))
+
+ if (m_Font != NULL)
+ DeleteObject(m_Font);
+
+ ncm.lfCaptionFont.lfWeight = FW_NORMAL;
+ m_Font = CreateFontIndirect(&ncm.lfCaptionFont);
+ if (!m_Font)
{
- if (InSizeMove)
- {
- if (!(pwp->flags & SWP_NOMOVE))
- {
- rcTray.left = pwp->x;
- rcTray.top = pwp->y;
- }
+ ERR("CreateFontIndirect failed\n");
+ return;
+ }
- if (!(pwp->flags & SWP_NOSIZE))
- {
- rcTray.right = rcTray.left + pwp->cx;
- rcTray.bottom = rcTray.top + pwp->cy;
- }
+ SendMessage(m_Rebar, WM_SETFONT, (WPARAM) m_Font, TRUE);
+ SendMessage(m_TaskSwitch, WM_SETFONT, (WPARAM) m_Font, TRUE);
+ SendMessage(m_TrayNotify, WM_SETFONT, (WPARAM) m_Font, TRUE);
+ }
- Position = GetDraggingRectFromRect(
- &rcTray,
- &Monitor);
+ HMONITOR GetScreenRectFromRect(
+ IN OUT RECT *pRect,
+ IN DWORD dwFlags)
+ {
+ MONITORINFO mi;
+ HMONITOR hMon;
- if (!(pwp->flags & (SWP_NOMOVE | SWP_NOSIZE)))
- {
- SIZE szWnd;
+ mi.cbSize = sizeof(mi);
+ hMon = MonitorFromRect(pRect, dwFlags);
+ if (hMon != NULL &&
+ GetMonitorInfo(hMon, &mi))
+ {
+ *pRect = mi.rcMonitor;
+ }
+ else
+ {
+ pRect->left = 0;
+ pRect->top = 0;
+ pRect->right = GetSystemMetrics(SM_CXSCREEN);
+ pRect->bottom = GetSystemMetrics(SM_CYSCREEN);
- szWnd.cx = pwp->cx;
- szWnd.cy = pwp->cy;
+ hMon = NULL;
+ }
- MakeTrayRectWithSize(Position, &szWnd, &rcTray);
- }
+ return hMon;
+ }
- if (AutoHide)
- {
- rcTray.left -= AutoHideOffset.cx;
- rcTray.right -= AutoHideOffset.cx;
- rcTray.top -= AutoHideOffset.cy;
- rcTray.bottom -= AutoHideOffset.cy;
- }
- rcTrayWnd[Position] = rcTray;
- }
- else
- {
- /* If the user isn't resizing the tray window we need to make sure the
- new size or position is valid. this is to prevent changes to the window
- without user interaction. */
- rcTray = rcTrayWnd[Position];
- }
+ HMONITOR GetMonitorFromRect(
+ IN const RECT *pRect)
+ {
+ HMONITOR hMon;
-ChangePos:
- TraySize.cx = rcTray.right - rcTray.left;
- TraySize.cy = rcTray.bottom - rcTray.top;
+ /* In case the monitor sizes or saved sizes differ a bit (probably
+ not a lot, only so the tray window overlaps into another monitor
+ now), minimize the risk that we determine a wrong monitor by
+ using the center point of the tray window if we can't determine
+ it using the rectangle. */
+ hMon = MonitorFromRect(pRect, MONITOR_DEFAULTTONULL);
+ if (hMon == NULL)
+ {
+ POINT pt;
- if (AutoHide)
- {
- rcTray.left += AutoHideOffset.cx;
- rcTray.right += AutoHideOffset.cx;
- rcTray.top += AutoHideOffset.cy;
- rcTray.bottom += AutoHideOffset.cy;
- }
+ pt.x = pRect->left + ((pRect->right - pRect->left) / 2);
+ pt.y = pRect->top + ((pRect->bottom - pRect->top) / 2);
- pwp->flags &= ~(SWP_NOMOVE | SWP_NOSIZE);
- pwp->x = rcTray.left;
- pwp->y = rcTray.top;
- pwp->cx = TraySize.cx;
- pwp->cy = TraySize.cy;
+ /* be less error-prone, find the nearest monitor */
+ hMon = MonitorFromPoint(pt, MONITOR_DEFAULTTONEAREST);
}
+
+ return hMon;
}
- VOID
- ApplyClipping(IN BOOL Clip)
+ HMONITOR GetScreenRect(
+ IN HMONITOR hMonitor,
+ IN OUT RECT *pRect)
{
- RECT rcClip, rcWindow;
- HRGN hClipRgn;
+ HMONITOR hMon = NULL;
- if (GetWindowRect(m_hWnd, &rcWindow))
+ if (hMonitor != NULL)
{
- /* Disable clipping on systems with only one monitor */
- if (GetSystemMetrics(SM_CMONITORS) <= 1)
- Clip = FALSE;
+ MONITORINFO mi;
- if (Clip)
+ mi.cbSize = sizeof(mi);
+ if (!GetMonitorInfo(hMonitor, &mi))
{
- rcClip = rcWindow;
-
- GetScreenRect(Monitor, &rcClip);
-
- if (!IntersectRect(&rcClip, &rcClip, &rcWindow))
+ /* Hm, the monitor is gone? Try to find a monitor where it
+ could be located now */
+ hMon = GetMonitorFromRect(pRect);
+ if (hMon == NULL ||
+ !GetMonitorInfo(hMon, &mi))
{
- rcClip = rcWindow;
+ hMon = NULL;
+ goto GetPrimaryRect;
}
-
- OffsetRect(&rcClip,
- -rcWindow.left,
- -rcWindow.top);
-
- hClipRgn = CreateRectRgnIndirect(&rcClip);
}
- else
- hClipRgn = NULL;
- /* Set the clipping region or make sure the window isn't clipped
- by disabling it explicitly. */
- SetWindowRgn(m_hWnd, hClipRgn, TRUE);
+ *pRect = mi.rcMonitor;
}
- }
-
- VOID ResizeWorkArea()
- {
-#if !WIN7_COMPAT_MODE
- RECT rcTray, rcWorkArea;
-
- /* If monitor has changed then fix the previous monitors work area */
- if (PreviousMonitor != Monitor)
+ else
{
- GetScreenRect(
- PreviousMonitor,
- &rcWorkArea);
- SystemParametersInfo(SPI_SETWORKAREA,
- 1,
- &rcWorkArea,
- SPIF_SENDCHANGE);
+GetPrimaryRect:
+ pRect->left = 0;
+ pRect->top = 0;
+ pRect->right = GetSystemMetrics(SM_CXSCREEN);
+ pRect->bottom = GetSystemMetrics(SM_CYSCREEN);
}
- rcTray = rcTrayWnd[Position];
-
- GetScreenRect(
- Monitor,
- &rcWorkArea);
- PreviousMonitor = Monitor;
+ return hMon;
+ }
- /* If AutoHide is false then change the workarea to exclude the area that
- the taskbar covers. */
- if (!AutoHide)
+ VOID AdjustSizerRect(RECT *rc, DWORD pos)
+ {
+ switch (pos)
{
- switch (Position)
- {
case ABE_TOP:
- rcWorkArea.top = rcTray.bottom;
+ rc->bottom -= GetSystemMetrics(SM_CXSIZEFRAME);
+ break;
+ case ABE_BOTTOM:
+ rc->top += GetSystemMetrics(SM_CXSIZEFRAME);
break;
case ABE_LEFT:
- rcWorkArea.left = rcTray.right;
+ rc->right -= GetSystemMetrics(SM_CYSIZEFRAME);
break;
case ABE_RIGHT:
- rcWorkArea.right = rcTray.left;
+ rc->left += GetSystemMetrics(SM_CYSIZEFRAME);
break;
- case ABE_BOTTOM:
- rcWorkArea.bottom = rcTray.top;
- break;
- }
}
- SystemParametersInfo(SPI_SETWORKAREA,
- 1,
- &rcWorkArea,
- SPIF_SENDCHANGE);
-#endif
}
- VOID CheckTrayWndPosition()
+ VOID MakeTrayRectWithSize(IN DWORD Position,
+ IN const SIZE *pTraySize,
+ IN OUT RECT *pRect)
{
- RECT rcTray;
+ switch (Position)
+ {
+ case ABE_LEFT:
+ pRect->right = pRect->left + pTraySize->cx;
+ break;
+
+ case ABE_TOP:
+ pRect->bottom = pRect->top + pTraySize->cy;
+ break;
- rcTray = rcTrayWnd[Position];
+ case ABE_RIGHT:
+ pRect->left = pRect->right - pTraySize->cx;
+ break;
- if (AutoHide)
- {
- rcTray.left += AutoHideOffset.cx;
- rcTray.right += AutoHideOffset.cx;
- rcTray.top += AutoHideOffset.cy;
- rcTray.bottom += AutoHideOffset.cy;
+ case ABE_BOTTOM:
+ default:
+ pRect->top = pRect->bottom - pTraySize->cy;
+ break;
}
+ }
- // TRACE("CheckTray: %d: %d,%d,%d,%d\n", Position, rcTray.left, rcTray.top, rcTray.right, rcTray.bottom);
+ VOID GetTrayRectFromScreenRect(IN DWORD Position,
+ IN const RECT *pScreen,
+ IN const SIZE *pTraySize OPTIONAL,
+ OUT RECT *pRect)
+ {
+ if (pTraySize == NULL)
+ pTraySize = &m_TraySize;
- /* Move the tray window */
- SetWindowPos(NULL,
- rcTray.left,
- rcTray.top,
- rcTray.right - rcTray.left,
- rcTray.bottom - rcTray.top,
- SWP_NOZORDER);
+ *pRect = *pScreen;
- ResizeWorkArea();
+ if(!IsThemeActive())
+ {
+ /* Move the border outside of the screen */
+ InflateRect(pRect,
+ GetSystemMetrics(SM_CXEDGE),
+ GetSystemMetrics(SM_CYEDGE));
+ }
- ApplyClipping(TRUE);
+ MakeTrayRectWithSize(Position, pTraySize, pRect);
}
- typedef struct _TW_STUCKRECTS2
+ BOOL IsPosHorizontal()
{
- DWORD cbSize;
- LONG Unknown;
- DWORD dwFlags;
- DWORD Position;
- SIZE Size;
- RECT Rect;
- } TW_STRUCKRECTS2, *PTW_STUCKRECTS2;
+ return m_Position == ABE_TOP || m_Position == ABE_BOTTOM;
+ }
- VOID
- RegLoadSettings()
+ HMONITOR CalculateValidSize(
+ IN DWORD Position,
+ IN OUT RECT *pRect)
{
- DWORD Pos;
- TW_STRUCKRECTS2 sr;
RECT rcScreen;
- SIZE WndSize, EdgeSize, DlgFrameSize;
- DWORD cbSize = sizeof(sr);
-
- EdgeSize.cx = GetSystemMetrics(SM_CXEDGE);
- EdgeSize.cy = GetSystemMetrics(SM_CYEDGE);
- DlgFrameSize.cx = GetSystemMetrics(SM_CXDLGFRAME);
- DlgFrameSize.cy = GetSystemMetrics(SM_CYDLGFRAME);
-
- if (SHGetValue(hkExplorer,
- TEXT("StuckRects2"),
- TEXT("Settings"),
- NULL,
- &sr,
- &cbSize) == ERROR_SUCCESS &&
- sr.cbSize == sizeof(sr))
- {
- AutoHide = (sr.dwFlags & ABS_AUTOHIDE) != 0;
- AlwaysOnTop = (sr.dwFlags & ABS_ALWAYSONTOP) != 0;
- SmSmallIcons = (sr.dwFlags & 0x4) != 0;
- HideClock = (sr.dwFlags & 0x8) != 0;
-
- /* FIXME: Are there more flags? */
+ //BOOL Horizontal;
+ HMONITOR hMon;
+ SIZE szMax, szWnd;
-#if WIN7_COMPAT_MODE
- Position = ABE_LEFT;
-#else
- if (sr.Position > ABE_BOTTOM)
- Position = ABE_BOTTOM;
- else
- Position = sr.Position;
-#endif
+ //Horizontal = IsPosHorizontal();
- /* Try to find out which monitor the tray window was located on last.
- Here we're only interested in the monitor screen that we think
- is the last one used. We're going to determine on which monitor
- we really are after calculating the docked position. */
- rcScreen = sr.Rect;
- GetScreenRectFromRect(
- &rcScreen,
- MONITOR_DEFAULTTONEAREST);
- }
- else
- {
- Position = ABE_BOTTOM;
- AlwaysOnTop = TRUE;
+ szWnd.cx = pRect->right - pRect->left;
+ szWnd.cy = pRect->bottom - pRect->top;
- /* Use the minimum size of the taskbar, we'll use the start
- button as a minimum for now. Make sure we calculate the
- entire window size, not just the client size. However, we
- use a thinner border than a standard thick border, so that
- the start button and bands are not stuck to the screen border. */
- sr.Size.cx = StartBtnSize.cx + (2 * (EdgeSize.cx + DlgFrameSize.cx));
- sr.Size.cy = StartBtnSize.cy + (2 * (EdgeSize.cy + DlgFrameSize.cy));
+ rcScreen = *pRect;
+ hMon = GetScreenRectFromRect(
+ &rcScreen,
+ MONITOR_DEFAULTTONEAREST);
- /* Use the primary screen by default */
- rcScreen.left = 0;
- rcScreen.top = 0;
- rcScreen.right = GetSystemMetrics(SM_CXSCREEN);
- rcScreen.bottom = GetSystemMetrics(SM_CYSCREEN);
- GetScreenRectFromRect(
- &rcScreen,
- MONITOR_DEFAULTTOPRIMARY);
- }
+ /* Calculate the maximum size of the tray window and limit the window
+ size to half of the screen's size. */
+ szMax.cx = (rcScreen.right - rcScreen.left) / 2;
+ szMax.cy = (rcScreen.bottom - rcScreen.top) / 2;
+ if (szWnd.cx > szMax.cx)
+ szWnd.cx = szMax.cx;
+ if (szWnd.cy > szMax.cy)
+ szWnd.cy = szMax.cy;
- if (m_hWnd != NULL)
- SetWindowPos(
- AlwaysOnTop ? HWND_TOPMOST : HWND_NOTOPMOST,
- 0,
- 0,
- 0,
- 0,
- SWP_NOMOVE | SWP_NOSIZE);
+ /* FIXME - calculate */
- /* Determine a minimum tray window rectangle. The "client" height is
- zero here since we cannot determine an optimal minimum width when
- loaded as a vertical tray window. We just need to make sure the values
- loaded from the registry are at least. The windows explorer behaves
- the same way, it allows the user to save a zero width vertical tray
- window, but not a zero height horizontal tray window. */
- WndSize.cx = 2 * (EdgeSize.cx + DlgFrameSize.cx);
- WndSize.cy = StartBtnSize.cy + (2 * (EdgeSize.cy + DlgFrameSize.cy));
+ GetTrayRectFromScreenRect(Position,
+ &rcScreen,
+ &szWnd,
+ pRect);
- if (WndSize.cx < sr.Size.cx)
- WndSize.cx = sr.Size.cx;
- if (WndSize.cy < sr.Size.cy)
- WndSize.cy = sr.Size.cy;
+ return hMon;
+ }
- /* Save the calculated size */
- TraySize = WndSize;
+#if 0
+ VOID
+ GetMinimumWindowSize(
+ OUT RECT *pRect)
+ {
+ RECT rcMin = {0};
- /* Calculate all docking rectangles. We need to do this here so they're
- initialized and dragging the tray window to another position gives
- usable results */
- for (Pos = ABE_LEFT;
- Pos <= ABE_BOTTOM;
- Pos++)
- {
- GetTrayRectFromScreenRect(
- Pos,
- &rcScreen,
- &TraySize,
- &rcTrayWnd[Pos]);
- // TRACE("rcTrayWnd[%d(%d)]: %d,%d,%d,%d\n", Pos, Position, rcTrayWnd[Pos].left, rcTrayWnd[Pos].top, rcTrayWnd[Pos].right, rcTrayWnd[Pos].bottom);
- }
+ AdjustWindowRectEx(&rcMin,
+ GetWindowLong(m_hWnd,
+ GWL_STYLE),
+ FALSE,
+ GetWindowLong(m_hWnd,
+ GWL_EXSTYLE));
- /* Determine which monitor we are on. It shouldn't matter which docked
- position rectangle we use */
- Monitor = GetMonitorFromRect(
- &rcTrayWnd[ABE_LEFT]);
+ *pRect = rcMin;
}
+#endif
- UINT
- TrackMenu(
- IN HMENU hMenu,
- IN POINT *ppt OPTIONAL,
- IN HWND hwndExclude OPTIONAL,
- IN BOOL TrackUp,
- IN BOOL IsContextMenu)
- {
- TPMPARAMS tmp, *ptmp = NULL;
- POINT pt;
- UINT cmdId;
- UINT fuFlags;
- if (hwndExclude != NULL)
- {
- /* Get the client rectangle and map it to screen coordinates */
- if (::GetClientRect(hwndExclude,
- &tmp.rcExclude) &&
- MapWindowPoints(hwndExclude,
- NULL,
- (LPPOINT) &tmp.rcExclude,
- 2) != 0)
- {
- ptmp = &tmp;
- }
- }
+ DWORD GetDraggingRectFromPt(
+ IN POINT pt,
+ OUT RECT *pRect,
+ OUT HMONITOR *phMonitor)
+ {
+ HMONITOR hMon, hMonNew;
+ DWORD PosH, PosV, Pos;
+ SIZE DeltaPt, ScreenOffset;
+ RECT rcScreen;
- if (ppt == NULL)
+ rcScreen.left = 0;
+ rcScreen.top = 0;
+
+ /* Determine the screen rectangle */
+ hMon = MonitorFromPoint(pt, MONITOR_DEFAULTTONULL);
+ if (hMon != NULL)
{
- if (ptmp == NULL &&
- GetClientRect(&tmp.rcExclude) &&
- MapWindowPoints(m_hWnd,
- NULL,
- (LPPOINT) &tmp.rcExclude,
- 2) != 0)
- {
- ptmp = &tmp;
- }
+ MONITORINFO mi;
- if (ptmp != NULL)
+ mi.cbSize = sizeof(mi);
+ if (!GetMonitorInfo(hMon, &mi))
{
- /* NOTE: TrackPopupMenuEx will eventually align the track position
- for us, no need to take care of it here as long as the
- coordinates are somewhere within the exclusion rectangle */
- pt.x = ptmp->rcExclude.left;
- pt.y = ptmp->rcExclude.top;
+ hMon = NULL;
+ goto GetPrimaryScreenRect;
}
- else
- pt.x = pt.y = 0;
- }
- else
- pt = *ppt;
- tmp.cbSize = sizeof(tmp);
+ /* make left top corner of the screen zero based to
+ make calculations easier */
+ pt.x -= mi.rcMonitor.left;
+ pt.y -= mi.rcMonitor.top;
- fuFlags = TPM_RETURNCMD | TPM_VERTICAL;
- fuFlags |= (TrackUp ? TPM_BOTTOMALIGN : TPM_TOPALIGN);
- if (IsContextMenu)
- fuFlags |= TPM_RIGHTBUTTON;
+ ScreenOffset.cx = mi.rcMonitor.left;
+ ScreenOffset.cy = mi.rcMonitor.top;
+ rcScreen.right = mi.rcMonitor.right - mi.rcMonitor.left;
+ rcScreen.bottom = mi.rcMonitor.bottom - mi.rcMonitor.top;
+ }
else
- fuFlags |= (TrackUp ? TPM_VERNEGANIMATION : TPM_VERPOSANIMATION);
-
- cmdId = TrackPopupMenuEx(hMenu,
- fuFlags,
- pt.x,
- pt.y,
- m_hWnd,
- ptmp);
-
- return cmdId;
- }
-
- HRESULT TrackCtxMenu(
- IN IContextMenu * contextMenu,
- IN POINT *ppt OPTIONAL,
- IN HWND hwndExclude OPTIONAL,
- IN BOOL TrackUp,
- IN PVOID Context OPTIONAL)
- {
- INT x = ppt->x;
- INT y = ppt->y;
- HRESULT hr;
- UINT uCommand;
- HMENU popup = CreatePopupMenu();
-
- if (popup == NULL)
- return E_FAIL;
+ {
+GetPrimaryScreenRect:
+ ScreenOffset.cx = 0;
+ ScreenOffset.cy = 0;
+ rcScreen.right = GetSystemMetrics(SM_CXSCREEN);
+ rcScreen.bottom = GetSystemMetrics(SM_CYSCREEN);
+ }
- TRACE("Before Query\n");
- hr = contextMenu->QueryContextMenu(popup, 0, 0, UINT_MAX, CMF_NORMAL);
- if (FAILED_UNEXPECTEDLY(hr))
+ /* Calculate the nearest screen border */
+ if (pt.x < rcScreen.right / 2)
{
- TRACE("Query failed\n");
- DestroyMenu(popup);
- return hr;
+ DeltaPt.cx = pt.x;
+ PosH = ABE_LEFT;
+ }
+ else
+ {
+ DeltaPt.cx = rcScreen.right - pt.x;
+ PosH = ABE_RIGHT;
}
-
- TRACE("Before Tracking\n");
- uCommand = ::TrackPopupMenuEx(popup, TPM_RETURNCMD, x, y, m_hWnd, NULL);
- if (uCommand != 0)
+ if (pt.y < rcScreen.bottom / 2)
{
- TRACE("Before InvokeCommand\n");
- CMINVOKECOMMANDINFO cmi = { 0 };
- cmi.cbSize = sizeof(cmi);
- cmi.lpVerb = MAKEINTRESOURCEA(uCommand);
- cmi.hwnd = m_hWnd;
- hr = contextMenu->InvokeCommand(&cmi);
+ DeltaPt.cy = pt.y;
+ PosV = ABE_TOP;
}
else
{
- TRACE("TrackPopupMenu failed. Code=%d, LastError=%d\n", uCommand, GetLastError());
- hr = S_FALSE;
+ DeltaPt.cy = rcScreen.bottom - pt.y;
+ PosV = ABE_BOTTOM;
}
- DestroyMenu(popup);
- return hr;
- }
+ Pos = (DeltaPt.cx * rcScreen.bottom < DeltaPt.cy * rcScreen.right) ? PosH : PosV;
+ /* Fix the screen origin to be relative to the primary monitor again */
+ OffsetRect(&rcScreen,
+ ScreenOffset.cx,
+ ScreenOffset.cy);
- VOID UpdateStartButton(IN HBITMAP hbmStart OPTIONAL)
- {
- SIZE Size = { 0, 0 };
+ RECT rcPos = m_TrayRects[Pos];
- if (himlStartBtn == NULL ||
- !StartButton.SendMessage(BCM_GETIDEALSIZE, 0, (LPARAM) &Size))
+ hMonNew = GetMonitorFromRect(&rcPos);
+ if (hMon != hMonNew)
{
- Size.cx = GetSystemMetrics(SM_CXEDGE);
- Size.cy = GetSystemMetrics(SM_CYEDGE);
+ SIZE szTray;
- if (hbmStart == NULL)
- {
- hbmStart = (HBITMAP) StartButton.SendMessage(BM_GETIMAGE, IMAGE_BITMAP, 0);
- }
+ /* Recalculate the rectangle, we're dragging to another monitor.
+ We don't need to recalculate the rect on single monitor systems. */
+ szTray.cx = rcPos.right - rcPos.left;
+ szTray.cy = rcPos.bottom - rcPos.top;
- if (hbmStart != NULL)
+ GetTrayRectFromScreenRect(Pos, &rcScreen, &szTray, pRect);
+ if (AutoHide)
{
- BITMAP bmp;
-
- if (GetObject(hbmStart,
- sizeof(bmp),
- &bmp) != 0)
- {
- Size.cx += bmp.bmWidth;
- Size.cy += max(bmp.bmHeight,
- GetSystemMetrics(SM_CYCAPTION));
- }
- else
- {
- /* Huh?! Shouldn't happen... */
- goto DefSize;
- }
+ pRect->left += m_AutoHideOffset.cx;
+ pRect->right += m_AutoHideOffset.cx;
+ pRect->top += m_AutoHideOffset.cy;
+ pRect->bottom += m_AutoHideOffset.cy;
}
- else
+ hMon = hMonNew;
+ }
+ else
+ {
+ /* The user is dragging the tray window on the same monitor. We don't need
+ to recalculate the rectangle */
+ *pRect = rcPos;
+ if (AutoHide)
{
-DefSize:
- Size.cx += GetSystemMetrics(SM_CXMINIMIZED);
- Size.cy += GetSystemMetrics(SM_CYCAPTION);
+ pRect->left += m_AutoHideOffset.cx;
+ pRect->right += m_AutoHideOffset.cx;
+ pRect->top += m_AutoHideOffset.cy;
+ pRect->bottom += m_AutoHideOffset.cy;
}
}
- /* Save the size of the start button */
- StartBtnSize = Size;
+ *phMonitor = hMon;
+
+ return Pos;
}
- VOID
- AlignControls(IN PRECT prcClient OPTIONAL)
+ DWORD GetDraggingRectFromRect(
+ IN OUT RECT *pRect,
+ OUT HMONITOR *phMonitor)
{
- RECT rcClient;
- SIZE TraySize, StartSize;
- POINT ptTrayNotify = { 0, 0 };
- BOOL Horizontal;
- HDWP dwp;
+ POINT pt;
- UpdateStartButton(NULL);
- if (prcClient != NULL)
- {
- rcClient = *prcClient;
- }
- else
+ /* Calculate the center of the rectangle. We call
+ GetDraggingRectFromPt to calculate a valid
+ dragging rectangle */
+ pt.x = pRect->left + ((pRect->right - pRect->left) / 2);
+ pt.y = pRect->top + ((pRect->bottom - pRect->top) / 2);
+
+ return GetDraggingRectFromPt(
+ pt,
+ pRect,
+ phMonitor);
+ }
+
+ VOID ChangingWinPos(IN OUT LPWINDOWPOS pwp)
+ {
+ RECT rcTray;
+
+ if (IsDragging)
{
- if (!GetClientRect(&rcClient))
+ rcTray.left = pwp->x;
+ rcTray.top = pwp->y;
+ rcTray.right = rcTray.left + pwp->cx;
+ rcTray.bottom = rcTray.top + pwp->cy;
+ if (AutoHide)
{
- return;
+ rcTray.left -= m_AutoHideOffset.cx;
+ rcTray.right -= m_AutoHideOffset.cx;
+ rcTray.top -= m_AutoHideOffset.cy;
+ rcTray.bottom -= m_AutoHideOffset.cy;
}
- }
-
- Horizontal = IsPosHorizontal();
- /* We're about to resize/move the start button, the rebar control and
- the tray notification control */
- dwp = BeginDeferWindowPos(3);
- if (dwp == NULL)
- return;
+ if (!EqualRect(&rcTray,
+ &m_TrayRects[m_DraggingPosition]))
+ {
+ /* Recalculate the rectangle, the user dragged the tray
+ window to another monitor or the window was somehow else
+ moved or resized */
+ m_DraggingPosition = GetDraggingRectFromRect(
+ &rcTray,
+ &m_DraggingMonitor);
+ //m_TrayRects[DraggingPosition] = rcTray;
+ }
- /* Limit the Start button width to the client width, if neccessary */
- StartSize = StartBtnSize;
- if (StartSize.cx > rcClient.right)
- StartSize.cx = rcClient.right;
+ //Monitor = CalculateValidSize(DraggingPosition,
+ // &rcTray);
- if (StartButton.m_hWnd != NULL)
- {
- /* Resize and reposition the button */
- dwp = DeferWindowPos(dwp,
- StartButton.m_hWnd,
- NULL,
- 0,
- 0,
- StartSize.cx,
- StartSize.cy,
- SWP_NOZORDER | SWP_NOACTIVATE);
- if (dwp == NULL)
- return;
- }
+ m_Monitor = m_DraggingMonitor;
+ m_Position = m_DraggingPosition;
+ IsDragging = FALSE;
- /* Determine the size that the tray notification window needs */
- if (Horizontal)
- {
- TraySize.cx = 0;
- TraySize.cy = rcClient.bottom;
+ m_TrayRects[m_Position] = rcTray;
+ goto ChangePos;
}
- else
+ else if (GetWindowRect(&rcTray))
{
- TraySize.cx = rcClient.right;
- TraySize.cy = 0;
- }
+ if (InSizeMove)
+ {
+ if (!(pwp->flags & SWP_NOMOVE))
+ {
+ rcTray.left = pwp->x;
+ rcTray.top = pwp->y;
+ }
- if (hwndTrayNotify != NULL &&
- SendMessage(hwndTrayNotify,
- TNWM_GETMINIMUMSIZE,
- (WPARAM) Horizontal,
- (LPARAM) &TraySize))
- {
- /* Move the tray notification window to the desired location */
- if (Horizontal)
- ptTrayNotify.x = rcClient.right - TraySize.cx;
- else
- ptTrayNotify.y = rcClient.bottom - TraySize.cy;
+ if (!(pwp->flags & SWP_NOSIZE))
+ {
+ rcTray.right = rcTray.left + pwp->cx;
+ rcTray.bottom = rcTray.top + pwp->cy;
+ }
- dwp = DeferWindowPos(dwp,
- hwndTrayNotify,
- NULL,
- ptTrayNotify.x,
- ptTrayNotify.y,
- TraySize.cx,
- TraySize.cy,
- SWP_NOZORDER | SWP_NOACTIVATE);
- if (dwp == NULL)
- return;
- }
+ m_Position = GetDraggingRectFromRect(&rcTray, &m_Monitor);
- /* Resize/Move the rebar control */
- if (hwndRebar != NULL)
- {
- POINT ptRebar = { 0, 0 };
- SIZE szRebar;
+ if (!(pwp->flags & (SWP_NOMOVE | SWP_NOSIZE)))
+ {
+ SIZE szWnd;
- SetWindowStyle(hwndRebar, CCS_VERT, Horizontal ? 0 : CCS_VERT);
+ szWnd.cx = pwp->cx;
+ szWnd.cy = pwp->cy;
- if (Horizontal)
- {
- ptRebar.x = StartSize.cx + GetSystemMetrics(SM_CXSIZEFRAME);
- szRebar.cx = ptTrayNotify.x - ptRebar.x;
- szRebar.cy = rcClient.bottom;
+ MakeTrayRectWithSize(m_Position, &szWnd, &rcTray);
+ }
+
+ if (AutoHide)
+ {
+ rcTray.left -= m_AutoHideOffset.cx;
+ rcTray.right -= m_AutoHideOffset.cx;
+ rcTray.top -= m_AutoHideOffset.cy;
+ rcTray.bottom -= m_AutoHideOffset.cy;
+ }
+ m_TrayRects[m_Position] = rcTray;
}
else
{
- ptRebar.y = StartSize.cy + GetSystemMetrics(SM_CYSIZEFRAME);
- szRebar.cx = rcClient.right;
- szRebar.cy = ptTrayNotify.y - ptRebar.y;
+ /* If the user isn't resizing the tray window we need to make sure the
+ new size or position is valid. this is to prevent changes to the window
+ without user interaction. */
+ rcTray = m_TrayRects[m_Position];
}
- dwp = DeferWindowPos(dwp,
- hwndRebar,
- NULL,
- ptRebar.x,
- ptRebar.y,
- szRebar.cx,
- szRebar.cy,
- SWP_NOZORDER | SWP_NOACTIVATE);
- }
+ChangePos:
+ m_TraySize.cx = rcTray.right - rcTray.left;
+ m_TraySize.cy = rcTray.bottom - rcTray.top;
- if (dwp != NULL)
- EndDeferWindowPos(dwp);
+ if (AutoHide)
+ {
+ rcTray.left += m_AutoHideOffset.cx;
+ rcTray.right += m_AutoHideOffset.cx;
+ rcTray.top += m_AutoHideOffset.cy;
+ rcTray.bottom += m_AutoHideOffset.cy;
+ }
- if (hwndTaskSwitch != NULL)
- {
- /* Update the task switch window configuration */
- SendMessage(hwndTaskSwitch,
- TSWM_UPDATETASKBARPOS,
- 0,
- 0);
+ pwp->flags &= ~(SWP_NOMOVE | SWP_NOSIZE);
+ pwp->x = rcTray.left;
+ pwp->y = rcTray.top;
+ pwp->cx = m_TraySize.cx;
+ pwp->cy = m_TraySize.cy;
}
}
- BOOL
- CreateStartBtnImageList()
+ VOID ApplyClipping(IN BOOL Clip)
{
- HICON hIconStart;
- SIZE IconSize;
+ RECT rcClip, rcWindow;
+ HRGN hClipRgn;
- if (himlStartBtn != NULL)
- return TRUE;
+ if (GetWindowRect(&rcWindow))
+ {
+ /* Disable clipping on systems with only one monitor */
+ if (GetSystemMetrics(SM_CMONITORS) <= 1)
+ Clip = FALSE;
- IconSize.cx = GetSystemMetrics(SM_CXSMICON);
- IconSize.cy = GetSystemMetrics(SM_CYSMICON);
+ if (Clip)
+ {
+ rcClip = rcWindow;
- /* Load the start button icon and create a image list for it */
- hIconStart = (HICON) LoadImage(hExplorerInstance,
- MAKEINTRESOURCE(IDI_START),
- IMAGE_ICON,
- IconSize.cx,
- IconSize.cy,
- LR_SHARED | LR_DEFAULTCOLOR);
+ GetScreenRect(m_Monitor, &rcClip);
- if (hIconStart != NULL)
- {
- himlStartBtn = (IImageList*) ImageList_Create(IconSize.cx,
- IconSize.cy,
- ILC_COLOR32 | ILC_MASK,
- 1,
- 1);
- if (himlStartBtn != NULL)
- {
- int s;
- himlStartBtn->ReplaceIcon(-1, hIconStart, &s);
- if (s >= 0)
+ if (!IntersectRect(&rcClip, &rcClip, &rcWindow))
{
- return TRUE;
+ rcClip = rcWindow;
}
- /* Failed to add the icon! */
- himlStartBtn->Release();
- himlStartBtn = NULL;
+ OffsetRect(&rcClip,
+ -rcWindow.left,
+ -rcWindow.top);
+
+ hClipRgn = CreateRectRgnIndirect(&rcClip);
}
- }
+ else
+ hClipRgn = NULL;
- return FALSE;
+ /* Set the clipping region or make sure the window isn't clipped
+ by disabling it explicitly. */
+ SetWindowRgn(hClipRgn, TRUE);
+ }
}
- HBITMAP CreateStartButtonBitmap()
+ VOID ResizeWorkArea()
{
- WCHAR szStartCaption[32];
- HFONT hFontOld;
- HDC hDC = NULL;
- HDC hDCScreen = NULL;
- SIZE Size, SmallIcon;
- HBITMAP hbmpOld, hbmp = NULL;
- HBITMAP hBitmap = NULL;
- HICON hIconStart;
- BOOL Ret;
- UINT Flags;
- RECT rcButton;
-
- /* NOTE: this is the backwards compatibility code that is used if the
- Common Controls Version 6.0 are not available! */
+#if !WIN7_DEBUG_MODE
+ RECT rcTray, rcWorkArea;
- if (!LoadString(hExplorerInstance,
- IDS_START,
- szStartCaption,
- sizeof(szStartCaption) / sizeof(szStartCaption[0])))
+ /* If monitor has changed then fix the previous monitors work area */
+ if (m_PreviousMonitor != m_Monitor)
{
- return NULL;
+ GetScreenRect(m_PreviousMonitor, &rcWorkArea);
+ SystemParametersInfoW(SPI_SETWORKAREA,
+ 1,
+ &rcWorkArea,
+ SPIF_SENDCHANGE);
}
- /* Load the start button icon */
- SmallIcon.cx = GetSystemMetrics(SM_CXSMICON);
- SmallIcon.cy = GetSystemMetrics(SM_CYSMICON);
- hIconStart = (HICON) LoadImage(hExplorerInstance,
- MAKEINTRESOURCE(IDI_START),
- IMAGE_ICON,
- SmallIcon.cx,
- SmallIcon.cy,
- LR_SHARED | LR_DEFAULTCOLOR);
-
- hDCScreen = GetDC(NULL);
- if (hDCScreen == NULL)
- goto Cleanup;
-
- hDC = CreateCompatibleDC(hDCScreen);
- if (hDC == NULL)
- goto Cleanup;
-
- hFontOld = (HFONT) SelectObject(hDC, hStartBtnFont);
+ rcTray = m_TrayRects[m_Position];
- Ret = GetTextExtentPoint32(hDC,
- szStartCaption,
- _tcslen(szStartCaption),
- &Size);
+ GetScreenRect(m_Monitor, &rcWorkArea);
+ m_PreviousMonitor = m_Monitor;
- SelectObject(hDC,
- hFontOld);
- if (!Ret)
- goto Cleanup;
-
- /* Make sure the height is at least the size of a caption icon. */
- if (hIconStart != NULL)
- Size.cx += SmallIcon.cx + 4;
- Size.cy = max(Size.cy, SmallIcon.cy);
-
- /* Create the bitmap */
- hbmp = CreateCompatibleBitmap(hDCScreen,
- Size.cx,
- Size.cy);
- if (hbmp == NULL)
- goto Cleanup;
-
- /* Caluclate the button rect */
- rcButton.left = 0;
- rcButton.top = 0;
- rcButton.right = Size.cx;
- rcButton.bottom = Size.cy;
-
- /* Draw the button */
- hbmpOld = (HBITMAP) SelectObject(hDC, hbmp);
-
- Flags = DC_TEXT | DC_INBUTTON;
- if (hIconStart != NULL)
- Flags |= DC_ICON;
-
- if (DrawCapTemp != NULL)
+ /* If AutoHide is false then change the workarea to exclude
+ the area that the taskbar covers. */
+ if (!AutoHide)
{
- Ret = DrawCapTemp(NULL,
- hDC,
- &rcButton,
- hStartBtnFont,
- hIconStart,
- szStartCaption,
- Flags);
+ switch (m_Position)
+ {
+ case ABE_TOP:
+ rcWorkArea.top = rcTray.bottom;
+ break;
+ case ABE_LEFT:
+ rcWorkArea.left = rcTray.right;
+ break;
+ case ABE_RIGHT:
+ rcWorkArea.right = rcTray.left;
+ break;
+ case ABE_BOTTOM:
+ rcWorkArea.bottom = rcTray.top;
+ break;
+ }
}
- SelectObject(hDC,
- hbmpOld);
+ /*
+ * Resize the current monitor work area. Win32k will also send
+ * a WM_SIZE message to automatically resize the desktop.
+ */
+ SystemParametersInfoW(SPI_SETWORKAREA,
+ 1,
+ &rcWorkArea,
+ SPIF_SENDCHANGE);
+#endif
+ }
- if (!Ret)
- goto Cleanup;
+ VOID CheckTrayWndPosition()
+ {
+ RECT rcTray;
- /* We successfully created the bitmap! */
- hBitmap = hbmp;
- hbmp = NULL;
+ rcTray = m_TrayRects[m_Position];
-Cleanup:
- if (hDCScreen != NULL)
+ if (AutoHide)
{
- ReleaseDC(NULL,
- hDCScreen);
+ rcTray.left += m_AutoHideOffset.cx;
+ rcTray.right += m_AutoHideOffset.cx;
+ rcTray.top += m_AutoHideOffset.cy;
+ rcTray.bottom += m_AutoHideOffset.cy;
}
- if (hbmp != NULL)
- DeleteObject(hbmp);
+ IUnknown_Exec(m_TrayBandSite,
+ IID_IDeskBand,
+ DBID_BANDINFOCHANGED,
+ 0,
+ NULL,
+ NULL);
- if (hDC != NULL)
- DeleteDC(hDC);
-
- return hBitmap;
- }
-
- LRESULT OnThemeChanged()
- {
- if (TaskbarTheme)
- CloseThemeData(TaskbarTheme);
+ FitToRebar(&rcTray);
+ m_TrayRects[m_Position] = rcTray;
- if (IsThemeActive())
- TaskbarTheme = OpenThemeData(m_hWnd, L"TaskBar");
- else
- TaskbarTheme = NULL;
+ /* Move the tray window */
+ SetWindowPos(NULL,
+ rcTray.left,
+ rcTray.top,
+ rcTray.right - rcTray.left,
+ rcTray.bottom - rcTray.top,
+ SWP_NOZORDER | SWP_NOACTIVATE);
- if (TaskbarTheme)
- {
- SetWindowStyle(m_hWnd, WS_THICKFRAME | WS_BORDER, 0);
- }
- else
- {
- SetWindowStyle(m_hWnd, WS_THICKFRAME | WS_BORDER, WS_THICKFRAME | WS_BORDER);
- }
+ ResizeWorkArea();
- return TRUE;
+ ApplyClipping(TRUE);
}
- LRESULT OnThemeChanged(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
+ typedef struct _TW_STUCKRECTS2
{
- return OnThemeChanged();
- }
+ DWORD cbSize;
+ LONG Unknown;
+ DWORD dwFlags;
+ DWORD Position;
+ SIZE Size;
+ RECT Rect;
+ } TW_STRUCKRECTS2, *PTW_STUCKRECTS2;
- LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
+ VOID RegLoadSettings()
{
- WCHAR szStartCaption[32];
-
- ((ITrayWindow*)this)->AddRef();
-
- SetWindowTheme(m_hWnd, L"TaskBar", NULL);
- OnThemeChanged();
+ DWORD Pos;
+ TW_STRUCKRECTS2 sr;
+ RECT rcScreen;
+ SIZE WndSize, EdgeSize, DlgFrameSize;
+ DWORD cbSize = sizeof(sr);
+ SIZE StartBtnSize = m_StartButton.GetSize();
- InterlockedIncrement(&TrayWndCount);
+ EdgeSize.cx = GetSystemMetrics(SM_CXEDGE);
+ EdgeSize.cy = GetSystemMetrics(SM_CYEDGE);
+ DlgFrameSize.cx = GetSystemMetrics(SM_CXDLGFRAME);
+ DlgFrameSize.cy = GetSystemMetrics(SM_CYDLGFRAME);
- if (!LoadString(hExplorerInstance,
- IDS_START,
- szStartCaption,
- sizeof(szStartCaption) / sizeof(szStartCaption[0])))
+ if (SHGetValue(hkExplorer,
+ TEXT("StuckRects2"),
+ TEXT("Settings"),
+ NULL,
+ &sr,
+ &cbSize) == ERROR_SUCCESS &&
+ sr.cbSize == sizeof(sr))
{
- szStartCaption[0] = TEXT('\0');
- }
+ AutoHide = (sr.dwFlags & ABS_AUTOHIDE) != 0;
+ AlwaysOnTop = (sr.dwFlags & ABS_ALWAYSONTOP) != 0;
+ SmSmallIcons = (sr.dwFlags & 0x4) != 0;
+ HideClock = (sr.dwFlags & 0x8) != 0;
- if (hStartBtnFont == NULL || hCaptionFont == NULL)
- {
- NONCLIENTMETRICS ncm;
+ /* FIXME: Are there more flags? */
- /* Get the system fonts, we use the caption font,
- always bold, though. */
- ncm.cbSize = sizeof(ncm);
- if (SystemParametersInfo(SPI_GETNONCLIENTMETRICS,
- sizeof(ncm),
- &ncm,
- FALSE))
- {
- if (hCaptionFont == NULL)
- {
- ncm.lfCaptionFont.lfWeight = FW_NORMAL;
- hCaptionFont = CreateFontIndirect(&ncm.lfCaptionFont);
- }
+#if WIN7_DEBUG_MODE
+ m_Position = ABE_LEFT;
+#else
+ if (sr.Position > ABE_BOTTOM)
+ m_Position = ABE_BOTTOM;
+ else
+ m_Position = sr.Position;
+#endif
- if (hStartBtnFont == NULL)
- {
- ncm.lfCaptionFont.lfWeight = FW_BOLD;
- hStartBtnFont = CreateFontIndirect(&ncm.lfCaptionFont);
- }
- }
+ /* Try to find out which monitor the tray window was located on last.
+ Here we're only interested in the monitor screen that we think
+ is the last one used. We're going to determine on which monitor
+ we really are after calculating the docked position. */
+ rcScreen = sr.Rect;
+ GetScreenRectFromRect(
+ &rcScreen,
+ MONITOR_DEFAULTTONEAREST);
}
-
- /* Create the Start button */
- StartButton.SubclassWindow(CreateWindowEx(
- 0,
- WC_BUTTON,
- szStartCaption,
- WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS |
- BS_PUSHBUTTON | BS_CENTER | BS_VCENTER | BS_BITMAP,
- 0,
- 0,
- 0,
- 0,
- m_hWnd,
- (HMENU) IDC_STARTBTN,
- hExplorerInstance,
- NULL));
- if (StartButton.m_hWnd)
+ else
{
- SetWindowTheme(StartButton.m_hWnd, L"Start", NULL);
- StartButton.SendMessage(WM_SETFONT, (WPARAM) hStartBtnFont, FALSE);
+ m_Position = ABE_BOTTOM;
+ AlwaysOnTop = TRUE;
- if (CreateStartBtnImageList())
+ /* Use the minimum size of the taskbar, we'll use the start
+ button as a minimum for now. Make sure we calculate the
+ entire window size, not just the client size. However, we
+ use a thinner border than a standard thick border, so that
+ the start button and bands are not stuck to the screen border. */
+ if(!IsThemeActive())
{
- BUTTON_IMAGELIST bil;
-
- /* Try to set the start button image. this requires the Common
- Controls 6.0 to be present (XP and later) */
- bil.himl = (HIMAGELIST) himlStartBtn;
- bil.margin.left = bil.margin.right = 1;
- bil.margin.top = bil.margin.bottom = 1;
- bil.uAlign = BUTTON_IMAGELIST_ALIGN_LEFT;
-
- if (!StartButton.SendMessage(BCM_SETIMAGELIST, 0, (LPARAM) &bil))
- {
- /* Fall back to the deprecated method on older systems that don't
- support Common Controls 6.0 */
- himlStartBtn->Release();
- himlStartBtn = NULL;
-
- goto SetStartBtnImage;
- }
-
- /* We're using the image list, remove the BS_BITMAP style and
- don't center it horizontally */
- SetWindowStyle(StartButton.m_hWnd, BS_BITMAP | BS_RIGHT, 0);
-
- UpdateStartButton(NULL);
+ sr.Size.cx = StartBtnSize.cx + (2 * (EdgeSize.cx + DlgFrameSize.cx));
+ sr.Size.cy = StartBtnSize.cy + (2 * (EdgeSize.cy + DlgFrameSize.cy));
}
else
{
- HBITMAP hbmStart, hbmOld;
-
-SetStartBtnImage:
- hbmStart = CreateStartButtonBitmap();
- if (hbmStart != NULL)
- {
- UpdateStartButton(hbmStart);
-
- hbmOld = (HBITMAP) StartButton.SendMessage(BM_SETIMAGE, IMAGE_BITMAP, (LPARAM) hbmStart);
-
- if (hbmOld != NULL)
- DeleteObject(hbmOld);
- }
+ sr.Size.cx = StartBtnSize.cx - EdgeSize.cx;
+ sr.Size.cy = StartBtnSize.cy - EdgeSize.cy;
+ if(!Locked)
+ sr.Size.cy += GetSystemMetrics(SM_CYSIZEFRAME);
}
- }
- /* Load the saved tray window settings */
- RegLoadSettings();
+ /* Use the primary screen by default */
+ rcScreen.left = 0;
+ rcScreen.top = 0;
+ rcScreen.right = GetSystemMetrics(SM_CXSCREEN);
+ rcScreen.bottom = GetSystemMetrics(SM_CYSCREEN);
+ GetScreenRectFromRect(
+ &rcScreen,
+ MONITOR_DEFAULTTOPRIMARY);
+ }
- /* Create and initialize the start menu */
- hbmStartMenu = LoadBitmap(hExplorerInstance,
- MAKEINTRESOURCE(IDB_STARTMENU));
- StartMenuPopup = CreateStartMenu(this, &StartMenuBand, hbmStartMenu, 0);
+ if (m_hWnd != NULL)
+ SetWindowPos(
+ AlwaysOnTop ? HWND_TOPMOST : HWND_NOTOPMOST,
+ 0,
+ 0,
+ 0,
+ 0,
+ SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
- /* Load the tray band site */
- if (TrayBandSite != NULL)
+ /* Determine a minimum tray window rectangle. The "client" height is
+ zero here since we cannot determine an optimal minimum width when
+ loaded as a vertical tray window. We just need to make sure the values
+ loaded from the registry are at least. The windows explorer behaves
+ the same way, it allows the user to save a zero width vertical tray
+ window, but not a zero height horizontal tray window. */
+ if(!IsThemeActive())
{
- TrayBandSite.Release();
+ WndSize.cx = 2 * (EdgeSize.cx + DlgFrameSize.cx);
+ WndSize.cy = StartBtnSize.cy + (2 * (EdgeSize.cy + DlgFrameSize.cy));
+ }
+ else
+ {
+ WndSize.cx = StartBtnSize.cx;
+ WndSize.cy = StartBtnSize.cy - EdgeSize.cx;
}
- TrayBandSite = CreateTrayBandSite(this, &hwndRebar, &hwndTaskSwitch);
- SetWindowTheme(hwndRebar, L"TaskBar", NULL);
+ if (WndSize.cx < sr.Size.cx)
+ WndSize.cx = sr.Size.cx;
+ if (WndSize.cy < sr.Size.cy)
+ WndSize.cy = sr.Size.cy;
- /* Create the tray notification window */
- hwndTrayNotify = CreateTrayNotifyWnd(this, HideClock);
+ /* Save the calculated size */
+ m_TraySize = WndSize;
- if (UpdateNonClientMetrics())
+ /* Calculate all docking rectangles. We need to do this here so they're
+ initialized and dragging the tray window to another position gives
+ usable results */
+ for (Pos = ABE_LEFT; Pos <= ABE_BOTTOM; Pos++)
{
- SetWindowsFont();
+ GetTrayRectFromScreenRect(Pos,
+ &rcScreen,
+ &m_TraySize,
+ &m_TrayRects[Pos]);
+ // TRACE("m_TrayRects[%d(%d)]: %d,%d,%d,%d\n", Pos, Position, m_TrayRects[Pos].left, m_TrayRects[Pos].top, m_TrayRects[Pos].right, m_TrayRects[Pos].bottom);
}
- /* Move the tray window to the right position and resize it if neccessary */
- CheckTrayWndPosition();
-
- /* Align all controls on the tray window */
- AlignControls(
- NULL);
+ /* Determine which monitor we are on. It shouldn't matter which docked
+ position rectangle we use */
+ m_Monitor = GetMonitorFromRect(&m_TrayRects[ABE_LEFT]);
+ }
- InitShellServices(&(hdpaShellServices));
+ VOID AlignControls(IN PRECT prcClient OPTIONAL)
+ {
+ RECT rcClient;
+ SIZE TraySize, StartSize;
+ POINT ptTrayNotify = { 0, 0 };
+ BOOL Horizontal;
+ HDWP dwp;
- if (AutoHide)
+ m_StartButton.UpdateSize();
+ if (prcClient != NULL)
{
- AutoHideState = AUTOHIDE_HIDING;
- SetTimer(TIMER_ID_AUTOHIDE, AUTOHIDE_DELAY_HIDE, NULL);
+ rcClient = *prcClient;
+ }
+ else
+ {
+ if (!GetClientRect(&rcClient))
+ {
+ ERR("Could not get client rect lastErr=%d\n", GetLastError());
+ return;
+ }
}
- RegisterHotKey(m_hWnd, IDHK_RUN, MOD_WIN, 'R');
- RegisterHotKey(m_hWnd, IDHK_MINIMIZE_ALL, MOD_WIN, 'M');
- RegisterHotKey(m_hWnd, IDHK_RESTORE_ALL, MOD_WIN|MOD_SHIFT, 'M');
- RegisterHotKey(m_hWnd, IDHK_HELP, MOD_WIN, VK_F1);
- RegisterHotKey(m_hWnd, IDHK_EXPLORE, MOD_WIN, 'E');
- RegisterHotKey(m_hWnd, IDHK_FIND, MOD_WIN, 'F');
- RegisterHotKey(m_hWnd, IDHK_FIND_COMPUTER, MOD_WIN|MOD_CONTROL, 'F');
- RegisterHotKey(m_hWnd, IDHK_NEXT_TASK, MOD_WIN, VK_TAB);
- RegisterHotKey(m_hWnd, IDHK_PREV_TASK, MOD_WIN|MOD_SHIFT, VK_TAB);
- RegisterHotKey(m_hWnd, IDHK_SYS_PROPERTIES, MOD_WIN, VK_PAUSE);
- RegisterHotKey(m_hWnd, IDHK_DESKTOP, MOD_WIN, 'D');
- RegisterHotKey(m_hWnd, IDHK_PAGER, MOD_WIN, 'B');
+ Horizontal = IsPosHorizontal();
- return TRUE;
- }
+ /* We're about to resize/move the start button, the rebar control and
+ the tray notification control */
+ dwp = BeginDeferWindowPos(3);
+ if (dwp == NULL)
+ {
+ ERR("BeginDeferWindowPos failed. lastErr=%d\n", GetLastError());
+ return;
+ }
- HRESULT STDMETHODCALLTYPE Open()
- {
- RECT rcWnd;
+ /* Limit the Start button width to the client width, if necessary */
+ StartSize = m_StartButton.GetSize();
+ if (StartSize.cx > rcClient.right)
+ StartSize.cx = rcClient.right;
- /* Check if there's already a window created and try to show it.
- If it was somehow destroyed just create a new tray window. */
- if (m_hWnd != NULL && IsWindow())
+ if (m_StartButton.m_hWnd != NULL)
{
- if (!IsWindowVisible(m_hWnd))
+ /* Resize and reposition the button */
+ dwp = m_StartButton.DeferWindowPos(dwp,
+ NULL,
+ 0,
+ 0,
+ StartSize.cx,
+ StartSize.cy,
+ SWP_NOZORDER | SWP_NOACTIVATE);
+ if (dwp == NULL)
{
- CheckTrayWndPosition();
-
- ShowWindow(SW_SHOW);
+ ERR("DeferWindowPos for start button failed. lastErr=%d\n", GetLastError());
+ return;
}
+ }
- return S_OK;
+ /* Determine the size that the tray notification window needs */
+ if (Horizontal)
+ {
+ TraySize.cx = 0;
+ TraySize.cy = rcClient.bottom;
+ }
+ else
+ {
+ TraySize.cx = rcClient.right;
+ TraySize.cy = 0;
}
- DWORD dwExStyle = WS_EX_TOOLWINDOW | WS_EX_WINDOWEDGE;
- if (AlwaysOnTop)
- dwExStyle |= WS_EX_TOPMOST;
+ if (m_TrayNotify != NULL &&
+ SendMessage(m_TrayNotify,
+ TNWM_GETMINIMUMSIZE,
+ (WPARAM)Horizontal,
+ (LPARAM)&TraySize))
+ {
+ /* Move the tray notification window to the desired location */
+ if (Horizontal)
+ ptTrayNotify.x = rcClient.right - TraySize.cx;
+ else
+ ptTrayNotify.y = rcClient.bottom - TraySize.cy;
- DWORD dwStyle = WS_POPUP | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN |
- WS_BORDER | WS_THICKFRAME;
+ dwp = ::DeferWindowPos(dwp,
+ m_TrayNotify,
+ NULL,
+ ptTrayNotify.x,
+ ptTrayNotify.y,
+ TraySize.cx,
+ TraySize.cy,
+ SWP_NOZORDER | SWP_NOACTIVATE);
+ if (dwp == NULL)
+ {
+ ERR("DeferWindowPos for notification area failed. lastErr=%d\n", GetLastError());
+ return;
+ }
+ }
- ZeroMemory(&rcWnd, sizeof(rcWnd));
- if (Position != (DWORD) -1)
- rcWnd = rcTrayWnd[Position];
+ /* Resize/Move the rebar control */
+ if (m_Rebar != NULL)
+ {
+ POINT ptRebar = { 0, 0 };
+ SIZE szRebar;
- if (!Create(NULL, rcWnd, NULL, dwStyle, dwExStyle))
- return E_FAIL;
+ SetWindowStyle(m_Rebar, CCS_VERT, Horizontal ? 0 : CCS_VERT);
- return S_OK;
- }
+ if (Horizontal)
+ {
+ ptRebar.x = StartSize.cx + GetSystemMetrics(SM_CXSIZEFRAME);
+ szRebar.cx = ptTrayNotify.x - ptRebar.x;
+ szRebar.cy = rcClient.bottom;
+ }
+ else
+ {
+ ptRebar.y = StartSize.cy + GetSystemMetrics(SM_CYSIZEFRAME);
+ szRebar.cx = rcClient.right;
+ szRebar.cy = ptTrayNotify.y - ptRebar.y;
+ }
- HRESULT STDMETHODCALLTYPE Close()
- {
- if (m_hWnd != NULL)
- {
- SendMessage(m_hWnd,
- WM_APP_TRAYDESTROY,
- 0,
- 0);
+ dwp = ::DeferWindowPos(dwp,
+ m_Rebar,
+ NULL,
+ ptRebar.x,
+ ptRebar.y,
+ szRebar.cx,
+ szRebar.cy,
+ SWP_NOZORDER | SWP_NOACTIVATE);
}
- return S_OK;
- }
+ if (dwp != NULL)
+ EndDeferWindowPos(dwp);
- HWND STDMETHODCALLTYPE GetHWND()
- {
- return m_hWnd;
+ if (m_TaskSwitch != NULL)
+ {
+ /* Update the task switch window configuration */
+ SendMessage(m_TaskSwitch, TSWM_UPDATETASKBARPOS, 0, 0);
+ }
}
- BOOL STDMETHODCALLTYPE IsSpecialHWND(IN HWND hWnd)
+ void FitToRebar(PRECT pRect)
{
- return (m_hWnd == hWnd ||
- (hWndDesktop != NULL && m_hWnd == hWndDesktop));
- }
+ /* Get the rect of the rebar */
+ RECT rebarRect, taskbarRect;
+ ::GetWindowRect(m_Rebar, &rebarRect);
+ ::GetWindowRect(m_hWnd, &taskbarRect);
+ OffsetRect(&rebarRect, -taskbarRect.left, -taskbarRect.top);
- BOOL STDMETHODCALLTYPE
- IsHorizontal()
- {
- return IsPosHorizontal();
- }
+ /* Calculate the difference of size of the taskbar and the rebar */
+ SIZE margins;
+ margins.cx = taskbarRect.right - taskbarRect.left - rebarRect.right + rebarRect.left;
+ margins.cy = taskbarRect.bottom - taskbarRect.top - rebarRect.bottom + rebarRect.top;
- HFONT STDMETHODCALLTYPE GetCaptionFonts(OUT HFONT *phBoldCaption OPTIONAL)
- {
- if (phBoldCaption != NULL)
- *phBoldCaption = hStartBtnFont;
+ /* Calculate the new size of the rebar and make it resize, then change the new taskbar size */
+ switch (m_Position)
+ {
+ case ABE_TOP:
+ rebarRect.bottom = rebarRect.top + pRect->bottom - pRect->top - margins.cy;
+ ::SendMessageW(m_Rebar, RB_SIZETORECT, RBSTR_CHANGERECT, (LPARAM)&rebarRect);
+ pRect->bottom = pRect->top + rebarRect.bottom - rebarRect.top + margins.cy;
+ break;
+ case ABE_BOTTOM:
+ rebarRect.top = rebarRect.bottom - (pRect->bottom - pRect->top - margins.cy);
+ ::SendMessageW(m_Rebar, RB_SIZETORECT, RBSTR_CHANGERECT, (LPARAM)&rebarRect);
+ ERR("rebarRect: %d, %d, %d,%d\n", rebarRect.top, rebarRect.left, rebarRect.right, rebarRect.bottom);
+ pRect->top = pRect->bottom - (rebarRect.bottom - rebarRect.top + margins.cy);
+ break;
+ case ABE_LEFT:
+ case ABE_RIGHT:
+ /* FIXME: what to do here? */
+ break;
+ }
- return hCaptionFont;
+ CalculateValidSize(m_Position, pRect);
}
- DWORD WINAPI TrayPropertiesThread()
+ void PopupStartMenu()
{
- HWND hwnd;
- RECT posRect;
-
- GetWindowRect(StartButton.m_hWnd, &posRect);
- hwnd = CreateWindowEx(0,
- WC_STATIC,
- NULL,
- WS_OVERLAPPED | WS_DISABLED | WS_CLIPSIBLINGS | WS_BORDER | SS_LEFT,
- posRect.left,
- posRect.top,
- posRect.right - posRect.left,
- posRect.bottom - posRect.top,
- NULL,
- NULL,
- NULL,
- NULL);
-
- hwndTrayPropertiesOwner = hwnd;
+ if (m_StartMenuPopup != NULL)
+ {
+ POINTL pt;
+ RECTL rcExclude;
+ DWORD dwFlags = 0;
- DisplayTrayProperties(hwnd);
+ if (m_StartButton.GetWindowRect((RECT*) &rcExclude))
+ {
+ switch (m_Position)
+ {
+ case ABE_BOTTOM:
+ pt.x = rcExclude.left;
+ pt.y = rcExclude.top;
+ dwFlags |= MPPF_TOP;
+ break;
+ case ABE_TOP:
+ pt.x = rcExclude.left;
+ pt.y = rcExclude.bottom;
+ dwFlags |= MPPF_BOTTOM;
+ break;
+ case ABE_LEFT:
+ pt.x = rcExclude.right;
+ pt.y = rcExclude.top;
+ dwFlags |= MPPF_RIGHT;
+ break;
+ case ABE_RIGHT:
+ pt.x = rcExclude.left;
+ pt.y = rcExclude.top;
+ dwFlags |= MPPF_LEFT;
+ break;
+ }
- hwndTrayPropertiesOwner = NULL;
- DestroyWindow();
+ m_StartMenuPopup->Popup(&pt, &rcExclude, dwFlags);
- return 0;
+ m_StartButton.SendMessageW(BM_SETSTATE, TRUE, 0);
+ }
+ }
}
- static DWORD WINAPI s_TrayPropertiesThread(IN OUT PVOID pParam)
+ void ProcessMouseTracking()
{
- CTrayWindow *This = (CTrayWindow*) pParam;
+ RECT rcCurrent;
+ POINT pt;
+ BOOL over;
+ UINT state = m_AutoHideState;
- return This->TrayPropertiesThread();
- }
+ GetCursorPos(&pt);
+ GetWindowRect(&rcCurrent);
+ over = PtInRect(&rcCurrent, pt);
- HWND STDMETHODCALLTYPE DisplayProperties()
- {
- HWND hTrayProp;
+ if (m_StartButton.SendMessage( BM_GETSTATE, 0, 0) != BST_UNCHECKED)
+ {
+ over = TRUE;
+ }
- if (hwndTrayPropertiesOwner)
+ if (over)
{
- hTrayProp = GetLastActivePopup(hwndTrayPropertiesOwner);
- if (hTrayProp != NULL &&
- hTrayProp != hwndTrayPropertiesOwner)
+ if (state == AUTOHIDE_HIDING)
{
- SetForegroundWindow(hTrayProp);
- return NULL;
+ TRACE("AutoHide cancelling hide.\n");
+ m_AutoHideState = AUTOHIDE_SHOWING;
+ SetTimer(TIMER_ID_AUTOHIDE, AUTOHIDE_INTERVAL_ANIMATING, NULL);
+ }
+ else if (state == AUTOHIDE_HIDDEN)
+ {
+ TRACE("AutoHide starting show.\n");
+ m_AutoHideState = AUTOHIDE_SHOWING;
+ SetTimer(TIMER_ID_AUTOHIDE, AUTOHIDE_DELAY_SHOW, NULL);
}
}
-
- CloseHandle(CreateThread(NULL, 0, s_TrayPropertiesThread, this, 0, NULL));
- return NULL;
- }
-
- VOID OpenCommonStartMenuDirectory(IN HWND hWndOwner, IN LPCTSTR lpOperation)
- {
- WCHAR szDir[MAX_PATH];
-
- if (SHGetSpecialFolderPath(hWndOwner,
- szDir,
- CSIDL_COMMON_STARTMENU,
- FALSE))
+ else
{
- ShellExecute(hWndOwner,
- lpOperation,
- NULL,
- NULL,
- szDir,
- SW_SHOWNORMAL);
+ if (state == AUTOHIDE_SHOWING)
+ {
+ TRACE("AutoHide cancelling show.\n");
+ m_AutoHideState = AUTOHIDE_HIDING;
+ SetTimer(TIMER_ID_AUTOHIDE, AUTOHIDE_INTERVAL_ANIMATING, NULL);
+ }
+ else if (state == AUTOHIDE_SHOWN)
+ {
+ TRACE("AutoHide starting hide.\n");
+ m_AutoHideState = AUTOHIDE_HIDING;
+ SetTimer(TIMER_ID_AUTOHIDE, AUTOHIDE_DELAY_HIDE, NULL);
+ }
+
+ KillTimer(TIMER_ID_MOUSETRACK);
}
}
- VOID OpenTaskManager(IN HWND hWndOwner)
+ void ProcessAutoHide()
{
- ShellExecute(hWndOwner,
- TEXT("open"),
- TEXT("taskmgr.exe"),
- NULL,
- NULL,
- SW_SHOWNORMAL);
- }
+ RECT rc = m_TrayRects[m_Position];
+ INT w = m_TraySize.cx - GetSystemMetrics(SM_CXBORDER) * 2 - 1;
+ INT h = m_TraySize.cy - GetSystemMetrics(SM_CYBORDER) * 2 - 1;
- BOOL STDMETHODCALLTYPE ExecContextMenuCmd(IN UINT uiCmd)
- {
- BOOL bHandled = TRUE;
+ TRACE("AutoHide Timer received for %u, rc=(%d, %d, %d, %d), w=%d, h=%d.\n", m_AutoHideState, rc.left, rc.top, rc.right, rc.bottom, w, h);
- switch (uiCmd)
+ switch (m_AutoHideState)
{
- case ID_SHELL_CMD_PROPERTIES:
- DisplayProperties();
- break;
-
- case ID_SHELL_CMD_OPEN_ALL_USERS:
- OpenCommonStartMenuDirectory(m_hWnd,
- TEXT("open"));
- break;
-
- case ID_SHELL_CMD_EXPLORE_ALL_USERS:
- OpenCommonStartMenuDirectory(m_hWnd,
- TEXT("explore"));
- break;
+ case AUTOHIDE_HIDING:
+ switch (m_Position)
+ {
+ case ABE_LEFT:
+ m_AutoHideOffset.cy = 0;
+ m_AutoHideOffset.cx -= AUTOHIDE_SPEED_HIDE;
+ if (m_AutoHideOffset.cx < -w)
+ m_AutoHideOffset.cx = -w;
+ break;
+ case ABE_TOP:
+ m_AutoHideOffset.cx = 0;
+ m_AutoHideOffset.cy -= AUTOHIDE_SPEED_HIDE;
+ if (m_AutoHideOffset.cy < -h)
+ m_AutoHideOffset.cy = -h;
+ break;
+ case ABE_RIGHT:
+ m_AutoHideOffset.cy = 0;
+ m_AutoHideOffset.cx += AUTOHIDE_SPEED_HIDE;
+ if (m_AutoHideOffset.cx > w)
+ m_AutoHideOffset.cx = w;
+ break;
+ case ABE_BOTTOM:
+ m_AutoHideOffset.cx = 0;
+ m_AutoHideOffset.cy += AUTOHIDE_SPEED_HIDE;
+ if (m_AutoHideOffset.cy > h)
+ m_AutoHideOffset.cy = h;
+ break;
+ }
- case ID_LOCKTASKBAR:
- if (SHRestricted(REST_CLASSICSHELL) == 0)
+ if (m_AutoHideOffset.cx != w && m_AutoHideOffset.cy != h)
{
- Lock(!Locked);
+ SetTimer(TIMER_ID_AUTOHIDE, AUTOHIDE_INTERVAL_ANIMATING, NULL);
+ break;
}
- break;
- case ID_SHELL_CMD_OPEN_TASKMGR:
- OpenTaskManager(m_hWnd);
- break;
-
- case ID_SHELL_CMD_UNDO_ACTION:
- break;
+ /* fallthrough */
+ case AUTOHIDE_HIDDEN:
- case ID_SHELL_CMD_SHOW_DESKTOP:
- break;
+ switch (m_Position)
+ {
+ case ABE_LEFT:
+ m_AutoHideOffset.cx = -w;
+ m_AutoHideOffset.cy = 0;
+ break;
+ case ABE_TOP:
+ m_AutoHideOffset.cx = 0;
+ m_AutoHideOffset.cy = -h;
+ break;
+ case ABE_RIGHT:
+ m_AutoHideOffset.cx = w;
+ m_AutoHideOffset.cy = 0;
+ break;
+ case ABE_BOTTOM:
+ m_AutoHideOffset.cx = 0;
+ m_AutoHideOffset.cy = h;
+ break;
+ }
- case ID_SHELL_CMD_TILE_WND_H:
- TileWindows(NULL, MDITILE_HORIZONTAL, NULL, 0, NULL);
+ KillTimer(TIMER_ID_AUTOHIDE);
+ m_AutoHideState = AUTOHIDE_HIDDEN;
break;
- case ID_SHELL_CMD_TILE_WND_V:
- TileWindows(NULL, MDITILE_VERTICAL, NULL, 0, NULL);
- break;
+ case AUTOHIDE_SHOWING:
+ if (m_AutoHideOffset.cx >= AUTOHIDE_SPEED_SHOW)
+ {
+ m_AutoHideOffset.cx -= AUTOHIDE_SPEED_SHOW;
+ }
+ else if (m_AutoHideOffset.cx <= -AUTOHIDE_SPEED_SHOW)
+ {
+ m_AutoHideOffset.cx += AUTOHIDE_SPEED_SHOW;
+ }
+ else
+ {
+ m_AutoHideOffset.cx = 0;
+ }
- case ID_SHELL_CMD_CASCADE_WND:
- CascadeWindows(NULL, MDITILE_SKIPDISABLED, NULL, 0, NULL);
- break;
+ if (m_AutoHideOffset.cy >= AUTOHIDE_SPEED_SHOW)
+ {
+ m_AutoHideOffset.cy -= AUTOHIDE_SPEED_SHOW;
+ }
+ else if (m_AutoHideOffset.cy <= -AUTOHIDE_SPEED_SHOW)
+ {
+ m_AutoHideOffset.cy += AUTOHIDE_SPEED_SHOW;
+ }
+ else
+ {
+ m_AutoHideOffset.cy = 0;
+ }
- case ID_SHELL_CMD_CUST_NOTIF:
- break;
+ if (m_AutoHideOffset.cx != 0 || m_AutoHideOffset.cy != 0)
+ {
+ SetTimer(TIMER_ID_AUTOHIDE, AUTOHIDE_INTERVAL_ANIMATING, NULL);
+ break;
+ }
- case ID_SHELL_CMD_ADJUST_DAT:
- //FIXME: Use SHRunControlPanel
- ShellExecuteW(m_hWnd, NULL, L"timedate.cpl", NULL, NULL, SW_NORMAL);
- break;
+ /* fallthrough */
+ case AUTOHIDE_SHOWN:
- default:
- TRACE("ITrayWindow::ExecContextMenuCmd(%u): Unhandled Command ID!\n", uiCmd);
- bHandled = FALSE;
+ KillTimer(TIMER_ID_AUTOHIDE);
+ m_AutoHideState = AUTOHIDE_SHOWN;
break;
}
- return bHandled;
+ rc.left += m_AutoHideOffset.cx;
+ rc.right += m_AutoHideOffset.cx;
+ rc.top += m_AutoHideOffset.cy;
+ rc.bottom += m_AutoHideOffset.cy;
+
+ TRACE("AutoHide Changing position to (%d, %d, %d, %d) and state=%u.\n", rc.left, rc.top, rc.right, rc.bottom, m_AutoHideState);
+ SetWindowPos(NULL, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, SWP_NOACTIVATE | SWP_NOZORDER);
}
- BOOL STDMETHODCALLTYPE Lock(IN BOOL bLock)
- {
- BOOL bPrevLock;
- bPrevLock = Locked;
- if (Locked != bLock)
- {
- Locked = bLock;
- if (TrayBandSite != NULL)
- {
- if (!SUCCEEDED(TrayBandSite->Lock(
- bLock)))
- {
- /* Reset?? */
- Locked = bPrevLock;
- }
- }
- }
- return bPrevLock;
- }
+ /**********************************************************
+ * ##### taskbar drawing #####
+ */
- LRESULT DrawBackground(HDC hdc)
+ LRESULT EraseBackgroundWithTheme(HDC hdc)
{
RECT rect;
int partId;
+ HRESULT res;
GetClientRect(&rect);
- if (TaskbarTheme)
+ if (m_Theme)
{
GetClientRect(&rect);
- switch (Position)
+ switch (m_Position)
{
case ABE_LEFT:
partId = TBP_BACKGROUNDLEFT;
partId = TBP_BACKGROUNDBOTTOM;
break;
}
-
- DrawThemeBackground(TaskbarTheme, hdc, partId, 0, &rect, 0);
- }
-
- return TRUE;
- }
-
- LRESULT OnEraseBackground(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
- {
- HDC hdc = (HDC) wParam;
-
- if (!TaskbarTheme)
- {
- bHandled = FALSE;
- return 0;
+ res = DrawThemeBackground(m_Theme, hdc, partId, 0, &rect, 0);
}
- return DrawBackground(hdc);
+ return res;
}
- int DrawSizer(IN HRGN hRgn)
+ int DrawSizerWithTheme(IN HRGN hRgn)
{
HDC hdc;
RECT rect;
- int backoundPart;
+ int backgroundPart;
- GetWindowRect(m_hWnd, &rect);
+ GetWindowRect(&rect);
OffsetRect(&rect, -rect.left, -rect.top);
- hdc = GetDCEx(m_hWnd, hRgn, DCX_WINDOW | DCX_INTERSECTRGN | DCX_PARENTCLIP);
+ hdc = GetWindowDC();
- switch (Position)
+ switch (m_Position)
{
case ABE_LEFT:
- backoundPart = TBP_SIZINGBARLEFT;
+ backgroundPart = TBP_SIZINGBARLEFT;
rect.left = rect.right - GetSystemMetrics(SM_CXSIZEFRAME);
break;
case ABE_TOP:
- backoundPart = TBP_SIZINGBARTOP;
+ backgroundPart = TBP_SIZINGBARTOP;
rect.top = rect.bottom - GetSystemMetrics(SM_CYSIZEFRAME);
break;
case ABE_RIGHT:
- backoundPart = TBP_SIZINGBARRIGHT;
+ backgroundPart = TBP_SIZINGBARRIGHT;
rect.right = rect.left + GetSystemMetrics(SM_CXSIZEFRAME);
break;
case ABE_BOTTOM:
default:
- backoundPart = TBP_SIZINGBARBOTTOM;
+ backgroundPart = TBP_SIZINGBARBOTTOM;
rect.bottom = rect.top + GetSystemMetrics(SM_CYSIZEFRAME);
break;
}
+ if (IsThemeBackgroundPartiallyTransparent(m_Theme, backgroundPart, 0))
+ {
+ DrawThemeParentBackground(m_hWnd, hdc, &rect);
+ }
+ DrawThemeBackground(m_Theme, hdc, backgroundPart, 0, &rect, 0);
- DrawThemeBackground(TaskbarTheme, hdc, backoundPart, 0, &rect, 0);
-
- ReleaseDC(m_hWnd, hdc);
+ ReleaseDC(hdc);
return 0;
}
- DWORD WINAPI RunFileDlgThread()
+
+
+
+
+ /*
+ * ITrayWindow
+ */
+ HRESULT STDMETHODCALLTYPE Open()
{
- HINSTANCE hShell32;
- RUNFILEDLG RunFileDlg;
- HWND hwnd;
- RECT posRect;
+ RECT rcWnd;
- GetWindowRect(StartButton.m_hWnd, &posRect);
+ /* Check if there's already a window created and try to show it.
+ If it was somehow destroyed just create a new tray window. */
+ if (m_hWnd != NULL && IsWindow())
+ {
+ return S_OK;
+ }
- hwnd = CreateWindowEx(0,
- WC_STATIC,
- NULL,
- WS_OVERLAPPED | WS_DISABLED | WS_CLIPSIBLINGS | WS_BORDER | SS_LEFT,
- posRect.left,
- posRect.top,
- posRect.right - posRect.left,
- posRect.bottom - posRect.top,
- NULL,
- NULL,
- NULL,
- NULL);
+ DWORD dwExStyle = WS_EX_TOOLWINDOW | WS_EX_WINDOWEDGE;
+ if (AlwaysOnTop)
+ dwExStyle |= WS_EX_TOPMOST;
- hwndRunFileDlgOwner = hwnd;
+ DWORD dwStyle = WS_POPUP | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
+ if(!IsThemeActive())
+ {
+ dwStyle |= WS_THICKFRAME | WS_BORDER;
+ }
- hShell32 = GetModuleHandle(TEXT("SHELL32.DLL"));
- RunFileDlg = (RUNFILEDLG) GetProcAddress(hShell32, (LPCSTR) 61);
+ ZeroMemory(&rcWnd, sizeof(rcWnd));
+ if (m_Position != (DWORD) -1)
+ rcWnd = m_TrayRects[m_Position];
- RunFileDlg(hwnd, NULL, NULL, NULL, NULL, RFF_CALCDIRECTORY);
+ if (!Create(NULL, rcWnd, NULL, dwStyle, dwExStyle))
+ return E_FAIL;
- hwndRunFileDlgOwner = NULL;
- ::DestroyWindow(hwnd);
+ /* Align all controls on the tray window */
+ AlignControls(NULL);
- return 0;
- }
+ /* Move the tray window to the right position and resize it if necessary */
+ CheckTrayWndPosition();
- static DWORD WINAPI s_RunFileDlgThread(IN OUT PVOID pParam)
- {
- CTrayWindow * This = (CTrayWindow*) pParam;
- return This->RunFileDlgThread();
+ return S_OK;
}
- void DisplayRunFileDlg()
+ HRESULT STDMETHODCALLTYPE Close()
{
- HWND hRunDlg;
- if (hwndRunFileDlgOwner)
+ if (m_hWnd != NULL)
{
- hRunDlg = GetLastActivePopup(hwndRunFileDlgOwner);
- if (hRunDlg != NULL &&
- hRunDlg != hwndRunFileDlgOwner)
- {
- SetForegroundWindow(hRunDlg);
- return;
- }
+ SendMessage(m_hWnd,
+ WM_APP_TRAYDESTROY,
+ 0,
+ 0);
}
- CloseHandle(CreateThread(NULL, 0, s_RunFileDlgThread, this, 0, NULL));
+ return S_OK;
}
- void PopupStartMenu()
+ HWND STDMETHODCALLTYPE GetHWND()
+ {
+ return m_hWnd;
+ }
+
+ BOOL STDMETHODCALLTYPE IsSpecialHWND(IN HWND hWnd)
+ {
+ return (m_hWnd == hWnd ||
+ (m_DesktopWnd != NULL && m_hWnd == m_DesktopWnd));
+ }
+
+ BOOL STDMETHODCALLTYPE IsHorizontal()
+ {
+ return IsPosHorizontal();
+ }
+
+ BOOL STDMETHODCALLTYPE Lock(IN BOOL bLock)
{
- if (StartMenuPopup != NULL)
+ BOOL bPrevLock = Locked;
+
+ if (Locked != bLock)
{
- POINTL pt;
- RECTL rcExclude;
- DWORD dwFlags = 0;
+ Locked = bLock;
- if (GetWindowRect(StartButton.m_hWnd, (RECT*) &rcExclude))
+ if (m_TrayBandSite != NULL)
{
- switch (Position)
+ if (!SUCCEEDED(m_TrayBandSite->Lock(bLock)))
{
- case ABE_BOTTOM:
- pt.x = rcExclude.left;
- pt.y = rcExclude.top;
- dwFlags |= MPPF_BOTTOM;
- break;
- case ABE_TOP:
- case ABE_LEFT:
- pt.x = rcExclude.left;
- pt.y = rcExclude.bottom;
- dwFlags |= MPPF_TOP | MPPF_ALIGN_RIGHT;
- break;
- case ABE_RIGHT:
- pt.x = rcExclude.right;
- pt.y = rcExclude.bottom;
- dwFlags |= MPPF_TOP | MPPF_ALIGN_LEFT;
- break;
+ /* Reset?? */
+ Locked = bPrevLock;
+ return bPrevLock;
+ }
+ }
+
+ if (m_Theme)
+ {
+ /* Update cached tray sizes */
+ for(DWORD Pos = ABE_LEFT; Pos <= ABE_BOTTOM; Pos++)
+ {
+ RECT rcGripper = {0};
+ AdjustSizerRect(&rcGripper, Pos);
+
+ if(Locked)
+ {
+ m_TrayRects[Pos].top += rcGripper.top;
+ m_TrayRects[Pos].left += rcGripper.left;
+ m_TrayRects[Pos].bottom += rcGripper.bottom;
+ m_TrayRects[Pos].right += rcGripper.right;
+ }
+ else
+ {
+ m_TrayRects[Pos].top -= rcGripper.top;
+ m_TrayRects[Pos].left -= rcGripper.left;
+ m_TrayRects[Pos].bottom -= rcGripper.bottom;
+ m_TrayRects[Pos].right -= rcGripper.right;
+ }
}
+ }
+ SetWindowPos(NULL, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOOWNERZORDER);
+ ResizeWorkArea();
+ ApplyClipping(TRUE);
+ }
+
+ return bPrevLock;
+ }
+
+
+
+
+
+
+ /**********************************************************
+ * ##### message handling #####
+ */
+
+ LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
+ {
+ HRESULT hRet;
+
+ ((ITrayWindow*)this)->AddRef();
+
+ SetWindowTheme(m_hWnd, L"TaskBar", NULL);
+
+ /* Create the Start button */
+ m_StartButton.Create(m_hWnd);
+
+ /* Load the saved tray window settings */
+ RegLoadSettings();
+
+ /* Create and initialize the start menu */
+ HBITMAP hbmBanner = LoadBitmapW(hExplorerInstance, MAKEINTRESOURCEW(IDB_STARTMENU));
+ m_StartMenuPopup = CreateStartMenu(this, &m_StartMenuBand, hbmBanner, 0);
+
+ /* Create the task band */
+ hRet = CTaskBand_CreateInstance(this, IID_PPV_ARG(IDeskBand, &m_TaskBand));
+ if (FAILED_UNEXPECTEDLY(hRet))
+ return FALSE;
+
+ /* Create the rebar band site. This actually creates the rebar and the tasks toolbar. */
+ hRet = CTrayBandSite_CreateInstance(this, m_TaskBand, &m_TrayBandSite);
+ if (FAILED_UNEXPECTEDLY(hRet))
+ return FALSE;
+
+ /* Get the hwnd of the rebar */
+ hRet = IUnknown_GetWindow(m_TrayBandSite, &m_Rebar);
+ if (FAILED_UNEXPECTEDLY(hRet))
+ return FALSE;
+
+ /* Get the hwnd of the tasks toolbar */
+ hRet = IUnknown_GetWindow(m_TaskBand, &m_TaskSwitch);
+ if (FAILED_UNEXPECTEDLY(hRet))
+ return FALSE;
+
+ SetWindowTheme(m_Rebar, L"TaskBar", NULL);
+
+ /* Create the tray notification window */
+ m_TrayNotify = CreateTrayNotifyWnd(this, HideClock, &m_TrayNotifyInstance);
+
+ UpdateFonts();
+
+ InitShellServices(&m_ShellServices);
+
+ if (AutoHide)
+ {
+ m_AutoHideState = AUTOHIDE_HIDING;
+ SetTimer(TIMER_ID_AUTOHIDE, AUTOHIDE_DELAY_HIDE, NULL);
+ }
- StartMenuPopup->Popup(
- &pt,
- &rcExclude,
- dwFlags);
+ RegisterHotKey(m_hWnd, IDHK_RUN, MOD_WIN, 'R');
+ RegisterHotKey(m_hWnd, IDHK_MINIMIZE_ALL, MOD_WIN, 'M');
+ RegisterHotKey(m_hWnd, IDHK_RESTORE_ALL, MOD_WIN|MOD_SHIFT, 'M');
+ RegisterHotKey(m_hWnd, IDHK_HELP, MOD_WIN, VK_F1);
+ RegisterHotKey(m_hWnd, IDHK_EXPLORE, MOD_WIN, 'E');
+ RegisterHotKey(m_hWnd, IDHK_FIND, MOD_WIN, 'F');
+ RegisterHotKey(m_hWnd, IDHK_FIND_COMPUTER, MOD_WIN|MOD_CONTROL, 'F');
+ RegisterHotKey(m_hWnd, IDHK_NEXT_TASK, MOD_WIN, VK_TAB);
+ RegisterHotKey(m_hWnd, IDHK_PREV_TASK, MOD_WIN|MOD_SHIFT, VK_TAB);
+ RegisterHotKey(m_hWnd, IDHK_SYS_PROPERTIES, MOD_WIN, VK_PAUSE);
+ RegisterHotKey(m_hWnd, IDHK_DESKTOP, MOD_WIN, 'D');
+ RegisterHotKey(m_hWnd, IDHK_PAGER, MOD_WIN, 'B');
- StartButton.SendMessageW(BM_SETSTATE, TRUE, 0);
- }
- }
+ return TRUE;
}
- void ProcessMouseTracking()
+ LRESULT OnThemeChanged(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
- RECT rcCurrent;
- POINT pt;
- BOOL over;
- UINT state = AutoHideState;
+ if (m_Theme)
+ CloseThemeData(m_Theme);
- GetCursorPos(&pt);
- GetWindowRect(m_hWnd, &rcCurrent);
- over = PtInRect(&rcCurrent, pt);
-
- if (StartButton.SendMessage( BM_GETSTATE, 0, 0) != BST_UNCHECKED)
- {
- over = TRUE;
- }
+ if (IsThemeActive())
+ m_Theme = OpenThemeData(m_hWnd, L"TaskBar");
+ else
+ m_Theme = NULL;
- if (over)
+ if (m_Theme)
{
- if (state == AUTOHIDE_HIDING)
- {
- TRACE("AutoHide cancelling hide.\n");
- AutoHideState = AUTOHIDE_SHOWING;
- SetTimer(TIMER_ID_AUTOHIDE, AUTOHIDE_INTERVAL_ANIMATING, NULL);
- }
- else if (state == AUTOHIDE_HIDDEN)
- {
- TRACE("AutoHide starting show.\n");
- AutoHideState = AUTOHIDE_SHOWING;
- SetTimer(TIMER_ID_AUTOHIDE, AUTOHIDE_DELAY_SHOW, NULL);
- }
+ SetWindowStyle(m_hWnd, WS_THICKFRAME | WS_BORDER, 0);
}
else
{
- if (state == AUTOHIDE_SHOWING)
- {
- TRACE("AutoHide cancelling show.\n");
- AutoHideState = AUTOHIDE_HIDING;
- SetTimer(TIMER_ID_AUTOHIDE, AUTOHIDE_INTERVAL_ANIMATING, NULL);
- }
- else if (state == AUTOHIDE_SHOWN)
- {
- TRACE("AutoHide starting hide.\n");
- AutoHideState = AUTOHIDE_HIDING;
- SetTimer(TIMER_ID_AUTOHIDE, AUTOHIDE_DELAY_HIDE, NULL);
- }
-
- KillTimer(TIMER_ID_MOUSETRACK);
+ SetWindowStyle(m_hWnd, WS_THICKFRAME | WS_BORDER, WS_THICKFRAME | WS_BORDER);
}
+ SetWindowPos(NULL, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOOWNERZORDER);
+
+ return TRUE;
}
- void ProcessAutoHide()
+ LRESULT OnSettingChanged(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
- RECT rc = rcTrayWnd[Position];
- INT w = TraySize.cx - GetSystemMetrics(SM_CXBORDER) * 2 - 1;
- INT h = TraySize.cy - GetSystemMetrics(SM_CYBORDER) * 2 - 1;
-
- TRACE("AutoHide Timer received for %u, rc=(%d, %d, %d, %d), w=%d, h=%d.\n", AutoHideState, rc.left, rc.top, rc.right, rc.bottom, w, h);
-
- switch (AutoHideState)
+ if (wParam == SPI_SETNONCLIENTMETRICS)
{
- case AUTOHIDE_HIDING:
- switch (Position)
- {
- case ABE_LEFT:
- AutoHideOffset.cy = 0;
- AutoHideOffset.cx -= AUTOHIDE_SPEED_HIDE;
- if (AutoHideOffset.cx < -w)
- AutoHideOffset.cx = -w;
- break;
- case ABE_TOP:
- AutoHideOffset.cx = 0;
- AutoHideOffset.cy -= AUTOHIDE_SPEED_HIDE;
- if (AutoHideOffset.cy < -h)
- AutoHideOffset.cy = -h;
- break;
- case ABE_RIGHT:
- AutoHideOffset.cy = 0;
- AutoHideOffset.cx += AUTOHIDE_SPEED_HIDE;
- if (AutoHideOffset.cx > w)
- AutoHideOffset.cx = w;
- break;
- case ABE_BOTTOM:
- AutoHideOffset.cx = 0;
- AutoHideOffset.cy += AUTOHIDE_SPEED_HIDE;
- if (AutoHideOffset.cy > h)
- AutoHideOffset.cy = h;
- break;
- }
-
- if (AutoHideOffset.cx != w && AutoHideOffset.cy != h)
- {
- SetTimer(TIMER_ID_AUTOHIDE, AUTOHIDE_INTERVAL_ANIMATING, NULL);
- break;
- }
-
- /* fallthrough */
- case AUTOHIDE_HIDDEN:
-
- switch (Position)
- {
- case ABE_LEFT:
- AutoHideOffset.cx = -w;
- AutoHideOffset.cy = 0;
- break;
- case ABE_TOP:
- AutoHideOffset.cx = 0;
- AutoHideOffset.cy = -h;
- break;
- case ABE_RIGHT:
- AutoHideOffset.cx = w;
- AutoHideOffset.cy = 0;
- break;
- case ABE_BOTTOM:
- AutoHideOffset.cx = 0;
- AutoHideOffset.cy = h;
- break;
- }
-
- KillTimer(TIMER_ID_AUTOHIDE);
- AutoHideState = AUTOHIDE_HIDDEN;
- break;
-
- case AUTOHIDE_SHOWING:
- if (AutoHideOffset.cx >= AUTOHIDE_SPEED_SHOW)
- {
- AutoHideOffset.cx -= AUTOHIDE_SPEED_SHOW;
- }
- else if (AutoHideOffset.cx <= -AUTOHIDE_SPEED_SHOW)
- {
- AutoHideOffset.cx += AUTOHIDE_SPEED_SHOW;
- }
- else
- {
- AutoHideOffset.cx = 0;
- }
-
- if (AutoHideOffset.cy >= AUTOHIDE_SPEED_SHOW)
- {
- AutoHideOffset.cy -= AUTOHIDE_SPEED_SHOW;
- }
- else if (AutoHideOffset.cy <= -AUTOHIDE_SPEED_SHOW)
- {
- AutoHideOffset.cy += AUTOHIDE_SPEED_SHOW;
- }
- else
- {
- AutoHideOffset.cy = 0;
- }
+ SendMessage(m_TaskSwitch, uMsg, wParam, lParam);
+ UpdateFonts();
+ AlignControls(NULL);
+ CheckTrayWndPosition();
+ }
- if (AutoHideOffset.cx != 0 || AutoHideOffset.cy != 0)
- {
- SetTimer(TIMER_ID_AUTOHIDE, AUTOHIDE_INTERVAL_ANIMATING, NULL);
- break;
- }
+ return 0;
+ }
- /* fallthrough */
- case AUTOHIDE_SHOWN:
+ LRESULT OnEraseBackground(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
+ {
+ HDC hdc = (HDC) wParam;
- KillTimer(TIMER_ID_AUTOHIDE);
- AutoHideState = AUTOHIDE_SHOWN;
- break;
+ if (!m_Theme)
+ {
+ bHandled = FALSE;
+ return 0;
}
- rc.left += AutoHideOffset.cx;
- rc.right += AutoHideOffset.cx;
- rc.top += AutoHideOffset.cy;
- rc.bottom += AutoHideOffset.cy;
-
- TRACE("AutoHide Changing position to (%d, %d, %d, %d) and state=%u.\n", rc.left, rc.top, rc.right, rc.bottom, AutoHideState);
- SetWindowPos(NULL, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, SWP_NOACTIVATE | SWP_NOZORDER);
+ return EraseBackgroundWithTheme(hdc);
}
LRESULT OnDisplayChange(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
- /* Load the saved tray window settings */
- RegLoadSettings();
-
- /* Move the tray window to the right position and resize it if neccessary */
+ /* Move the tray window to the right position and resize it if necessary */
CheckTrayWndPosition();
- /* Align all controls on the tray window */
- AlignControls(NULL);
-
return TRUE;
}
LRESULT OnCopyData(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
- if (hwndTrayNotify)
+ if (m_TrayNotify)
{
- TrayNotify_NotifyMsg(wParam, lParam);
+ TRACE("WM_COPYDATA notify message received. Handling...\n");
+ return TrayNotify_NotifyIconCmd(m_TrayNotifyInstance, wParam, lParam);
}
return TRUE;
}
LRESULT OnNcPaint(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
- if (!TaskbarTheme)
+ if (!m_Theme)
{
bHandled = FALSE;
return 0;
}
- return DrawSizer((HRGN) wParam);
+ return DrawSizerWithTheme((HRGN) wParam);
}
LRESULT OnCtlColorBtn(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
SetLastError(ERROR_SUCCESS);
if (GetClientRect(&rcClient) &&
- (MapWindowPoints(m_hWnd, NULL, (LPPOINT) &rcClient, 2) != 0 || GetLastError() == ERROR_SUCCESS))
+ (MapWindowPoints(NULL, (LPPOINT) &rcClient, 2) != 0 || GetLastError() == ERROR_SUCCESS))
{
pt.x = (SHORT) LOWORD(lParam);
pt.y = (SHORT) HIWORD(lParam);
/* Depending on the position of the tray window, allow only
changing the border next to the monitor working area */
- switch (Position)
+ switch (m_Position)
{
case ABE_TOP:
if (pt.y > rcClient.bottom)
if (!Locked && GetCursorPos(&ptCursor))
{
IsDragging = TRUE;
- DraggingPosition = GetDraggingRectFromPt(
- ptCursor,
- pRect,
- &DraggingMonitor);
+ m_DraggingPosition = GetDraggingRectFromPt(ptCursor, pRect, &m_DraggingMonitor);
}
else
{
- *pRect = rcTrayWnd[Position];
+ *pRect = m_TrayRects[m_Position];
if (AutoHide)
{
- pRect->left += AutoHideOffset.cx;
- pRect->right += AutoHideOffset.cx;
- pRect->top += AutoHideOffset.cy;
- pRect->bottom += AutoHideOffset.cy;
+ pRect->left += m_AutoHideOffset.cx;
+ pRect->right += m_AutoHideOffset.cx;
+ pRect->top += m_AutoHideOffset.cy;
+ pRect->bottom += m_AutoHideOffset.cy;
}
}
return TRUE;
if (!Locked)
{
- CalculateValidSize(Position, pRect);
+ FitToRebar(pRect);
}
else
{
- *pRect = rcTrayWnd[Position];
+ *pRect = m_TrayRects[m_Position];
if (AutoHide)
{
- pRect->left += AutoHideOffset.cx;
- pRect->right += AutoHideOffset.cx;
- pRect->top += AutoHideOffset.cy;
- pRect->bottom += AutoHideOffset.cy;
+ pRect->left += m_AutoHideOffset.cx;
+ pRect->right += m_AutoHideOffset.cx;
+ pRect->top += m_AutoHideOffset.cy;
+ pRect->bottom += m_AutoHideOffset.cy;
}
}
return TRUE;
LRESULT OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
RECT rcClient;
- InvalidateRect(NULL, TRUE);
if (wParam == SIZE_RESTORED && lParam == 0)
{
ResizeWorkArea();
if (!Locked)
{
/* Apply clipping */
- PostMessage(m_hWnd, WM_SIZE, SIZE_RESTORED, 0);
+ PostMessage(WM_SIZE, SIZE_RESTORED, 0);
}
return TRUE;
}
SC_MINIMIZE,
};
HMENU hSysMenu;
- INT i;
- UINT uId;
+ UINT i, uId;
/* temporarily enable the system menu */
SetWindowStyle(m_hWnd, WS_SYSMENU, WS_SYSMENU);
- hSysMenu = GetSystemMenu(m_hWnd, FALSE);
+ hSysMenu = GetSystemMenu(FALSE);
if (hSysMenu != NULL)
{
/* Disable all items that are not relevant */
- for (i = 0; i != sizeof(uidDisableItem) / sizeof(uidDisableItem[0]); i++)
+ for (i = 0; i < _countof(uidDisableItem); i++)
{
EnableMenuItem(hSysMenu,
uidDisableItem[i],
uId = TrackMenu(
hSysMenu,
NULL,
- StartButton.m_hWnd,
- Position != ABE_TOP,
+ m_StartButton.m_hWnd,
+ m_Position != ABE_TOP,
FALSE);
if (uId != 0)
{
- SendMessage(m_hWnd,
- WM_SYSCOMMAND,
- (WPARAM) uId,
- 0);
+ SendMessage(m_hWnd, WM_SYSCOMMAND, (WPARAM) uId, 0);
}
}
if (pt.x != -1 || pt.y != -1)
ppt = &pt;
else
- hWndExclude = StartButton.m_hWnd;
+ hWndExclude = m_StartButton.m_hWnd;
- if ((HWND) wParam == StartButton.m_hWnd)
+ if ((HWND) wParam == m_StartButton.m_hWnd)
{
/* Make sure we can't track the context menu if the start
menu is currently being shown */
- if (!(StartButton.SendMessage(BM_GETSTATE, 0, 0) & BST_PUSHED))
+ if (!(m_StartButton.SendMessage(BM_GETSTATE, 0, 0) & BST_PUSHED))
{
CComPtr<IContextMenu> ctxMenu;
StartMenuBtnCtxMenuCreator(this, m_hWnd, &ctxMenu);
- TrackCtxMenu(ctxMenu, ppt, hWndExclude, Position == ABE_BOTTOM, this);
+ TrackCtxMenu(ctxMenu, ppt, hWndExclude, m_Position == ABE_BOTTOM, this);
}
}
else
{
/* See if the context menu should be handled by the task band site */
- if (ppt != NULL && TrayBandSite != NULL)
+ if (ppt != NULL && m_TrayBandSite != NULL)
{
HWND hWndAtPt;
POINT ptClient = *ppt;
/* Convert the coordinates to client-coordinates */
- MapWindowPoints(NULL, m_hWnd, &ptClient, 1);
+ ::MapWindowPoints(NULL, m_hWnd, &ptClient, 1);
- hWndAtPt = ChildWindowFromPoint(m_hWnd, ptClient);
+ hWndAtPt = ChildWindowFromPoint(ptClient);
if (hWndAtPt != NULL &&
- (hWndAtPt == hwndRebar || IsChild(hwndRebar,
- hWndAtPt)))
+ (hWndAtPt == m_Rebar || ::IsChild(m_Rebar, hWndAtPt)))
{
/* Check if the user clicked on the task switch window */
ptClient = *ppt;
- MapWindowPoints(NULL, hwndRebar, &ptClient, 1);
+ ::MapWindowPoints(NULL, m_Rebar, &ptClient, 1);
- hWndAtPt = ChildWindowFromPointEx(hwndRebar, ptClient, CWP_SKIPINVISIBLE | CWP_SKIPDISABLED);
- if (hWndAtPt == hwndTaskSwitch)
+ hWndAtPt = ::ChildWindowFromPointEx(m_Rebar, ptClient, CWP_SKIPINVISIBLE | CWP_SKIPDISABLED);
+ if (hWndAtPt == m_TaskSwitch)
goto HandleTrayContextMenu;
/* Forward the message to the task band site */
- TrayBandSite->ProcessMessage(m_hWnd, uMsg, wParam, lParam, &Ret);
+ m_TrayBandSite->ProcessMessage(m_hWnd, uMsg, wParam, lParam, &Ret);
}
else
goto HandleTrayContextMenu;
HRESULT hr = E_FAIL;
- if (TrayBandSite)
+ if (m_TrayBandSite)
{
- hr = TrayBandSite->ProcessMessage(m_hWnd, uMsg, wParam, lParam, &Ret);
+ hr = m_TrayBandSite->ProcessMessage(m_hWnd, uMsg, wParam, lParam, &Ret);
if (SUCCEEDED(hr))
return Ret;
}
- if (TrayBandSite == NULL || FAILED(hr))
+ if (m_TrayBandSite == NULL || FAILED(hr))
{
const NMHDR *nmh = (const NMHDR *) lParam;
- if (nmh->hwndFrom == hwndTrayNotify)
+ if (nmh->hwndFrom == m_TrayNotify)
{
switch (nmh->code)
{
case NTNWM_REALIGN:
/* Cause all controls to be aligned */
- PostMessage(m_hWnd, WM_SIZE, SIZE_RESTORED, 0);
+ PostMessage(WM_SIZE, SIZE_RESTORED, 0);
break;
}
}
/* We should forward mouse messages to child windows here.
Right now, this is only clock double-click */
RECT rcClock;
- if (TrayNotify_GetClockRect(&rcClock))
+ if (TrayNotify_GetClockRect(m_TrayNotifyInstance, &rcClock))
{
POINT ptClick;
ptClick.x = MAKEPOINTS(lParam).x;
LRESULT OnOpenStartMenu(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
HWND hwndStartMenu;
- HRESULT hr = IUnknown_GetWindow((IUnknown*) StartMenuPopup, &hwndStartMenu);
+ HRESULT hr = IUnknown_GetWindow(m_StartMenuPopup, &hwndStartMenu);
if (FAILED_UNEXPECTEDLY(hr))
return FALSE;
- if (IsWindowVisible(hwndStartMenu))
+ if (::IsWindowVisible(hwndStartMenu))
{
- StartMenuPopup->OnSelect(MPOS_CANCELLEVEL);
+ m_StartMenuPopup->OnSelect(MPOS_CANCELLEVEL);
}
else
{
return TRUE;
}
- LRESULT DoExitWindows()
- {
- ExitWindowsDialog(m_hWnd);
- return 0;
- }
-
LRESULT OnDoExitWindows(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
- /*
- * TWM_DOEXITWINDOWS is send by the CDesktopBrowserr to us to
- * show the shutdown dialog
+ /*
+ * TWM_DOEXITWINDOWS is send by the CDesktopBrowser to us
+ * to show the shutdown dialog. Also a WM_CLOSE message sent
+ * by apps should show the dialog.
*/
return DoExitWindows();
}
return TRUE;
}
- HRESULT ExecResourceCmd(int id)
- {
- WCHAR szCommand[256];
- WCHAR *pszParameters;
-
- if (!LoadString(hExplorerInstance,
- id,
- szCommand,
- sizeof(szCommand) / sizeof(szCommand[0])))
- {
- return E_FAIL;
- }
-
- pszParameters = wcschr(szCommand, L'>');
- if (!pszParameters)
- return E_FAIL;
-
- *pszParameters = 0;
- pszParameters++;
-
- ShellExecuteW(m_hWnd, NULL, szCommand, pszParameters, NULL, 0);
- return S_OK;
- }
-
LRESULT OnHotkey(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
- switch (wParam)
- {
- case IDHK_RUN:
- DisplayRunFileDlg();
- break;
- case IDHK_HELP:
- ExecResourceCmd(IDS_HELP_COMMAND);
- break;
- case IDHK_EXPLORE:
- ShellExecuteW(0, L"explore", NULL, NULL, NULL, 1);
- break;
- case IDHK_FIND:
- SHFindFiles(NULL, NULL);
- break;
- case IDHK_FIND_COMPUTER:
- SHFindComputer(NULL, NULL);
- break;
- case IDHK_SYS_PROPERTIES:
- //FIXME: Use SHRunControlPanel
- ShellExecuteW(m_hWnd, NULL, L"sysdm.cpl", NULL, NULL, SW_NORMAL);
- break;
- case IDHK_NEXT_TASK:
- break;
- case IDHK_PREV_TASK:
- break;
- case IDHK_MINIMIZE_ALL:
- break;
- case IDHK_RESTORE_ALL:
- break;
- case IDHK_DESKTOP:
- break;
- case IDHK_PAGER:
- break;
- }
-
- return 0;
+ return HandleHotKey(wParam);
}
LRESULT OnCommand(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
LRESULT Ret = FALSE;
- if ((HWND) lParam == StartButton.m_hWnd)
+ if ((HWND) lParam == m_StartButton.m_hWnd)
{
PopupStartMenu();
return FALSE;
}
- if (TrayBandSite == NULL || FAILED_UNEXPECTEDLY(TrayBandSite->ProcessMessage(m_hWnd, uMsg, wParam, lParam, &Ret)))
+ if (m_TrayBandSite == NULL || FAILED_UNEXPECTEDLY(m_TrayBandSite->ProcessMessage(m_hWnd, uMsg, wParam, lParam, &Ret)))
{
- switch (LOWORD(wParam))
- {
- /* FIXME: Handle these commands as well */
- case IDM_TASKBARANDSTARTMENU:
- DisplayProperties();
- break;
-
- case IDM_SEARCH:
- SHFindFiles(NULL, NULL);
- break;
-
- case IDM_HELPANDSUPPORT:
- ExecResourceCmd(IDS_HELP_COMMAND);
- break;
-
- case IDM_RUN:
- DisplayRunFileDlg();
- break;
-
- /* FIXME: Handle these commands as well */
- case IDM_SYNCHRONIZE:
- case IDM_LOGOFF:
- case IDM_DISCONNECT:
- case IDM_UNDOCKCOMPUTER:
- break;
-
- case IDM_SHUTDOWN:
- DoExitWindows();
- break;
- }
+ return HandleCommand(LOWORD(wParam));
}
return Ret;
}
return TRUE;
}
+ LRESULT OnNcCalcSize(INT code, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
+ {
+ RECT *rc = NULL;
+ /* Ignore WM_NCCALCSIZE if we are not themed or locked */
+ if(!IsThemeActive() || Locked)
+ {
+ bHandled = FALSE;
+ return 0;
+ }
+ if(!wParam)
+ {
+ rc = (RECT*)wParam;
+ }
+ else
+ {
+ NCCALCSIZE_PARAMS *prms = (NCCALCSIZE_PARAMS*)lParam;
+ if(prms->lppos->flags & SWP_NOSENDCHANGING)
+ {
+ bHandled = FALSE;
+ return 0;
+ }
+ rc = &prms->rgrc[0];
+ }
+
+ AdjustSizerRect(rc, m_Position);
+
+ return 0;
+ }
+
LRESULT OnRebarAutoSize(INT code, LPNMHDR nmhdr, BOOL& bHandled)
{
#if 0
szWindow.cy - szTarget.cx,
};
- switch (Position)
+ switch (m_Position)
{
case ABE_LEFT:
szWindow.cx = szActual.cx + borders.cx;
DECLARE_WND_CLASS_EX(szTrayWndClass, CS_DBLCLKS, COLOR_3DFACE)
BEGIN_MSG_MAP(CTrayWindow)
- if (StartMenuBand != NULL)
+ if (m_StartMenuBand != NULL)
{
MSG Msg;
LRESULT lRet;
Msg.wParam = wParam;
Msg.lParam = lParam;
- if (StartMenuBand->TranslateMenuMessage(&Msg, &lRet) == S_OK)
+ if (m_StartMenuBand->TranslateMenuMessage(&Msg, &lRet) == S_OK)
{
return lRet;
}
lParam = Msg.lParam;
}
MESSAGE_HANDLER(WM_THEMECHANGED, OnThemeChanged)
+ MESSAGE_HANDLER(WM_SETTINGCHANGE, OnSettingChanged)
NOTIFY_CODE_HANDLER(RBN_AUTOSIZE, OnRebarAutoSize) // Doesn't quite work ;P
MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBackground)
MESSAGE_HANDLER(WM_SIZE, OnSize)
MESSAGE_HANDLER(WM_APP_TRAYDESTROY, OnAppTrayDestroy)
MESSAGE_HANDLER(TWM_OPENSTARTMENU, OnOpenStartMenu)
MESSAGE_HANDLER(TWM_DOEXITWINDOWS, OnDoExitWindows)
+ MESSAGE_HANDLER(WM_CLOSE, OnDoExitWindows)
MESSAGE_HANDLER(WM_HOTKEY, OnHotkey)
+ MESSAGE_HANDLER(WM_NCCALCSIZE, OnNcCalcSize)
ALT_MSG_MAP(1)
END_MSG_MAP()
/* FIXME: We should keep a reference here... */
- while (PeekMessage(&Msg,
- NULL,
- 0,
- 0,
- PM_REMOVE))
+ while (PeekMessage(&Msg, NULL, 0, 0, PM_REMOVE))
{
if (Msg.message == WM_QUIT)
break;
- if (StartMenuBand == NULL ||
- StartMenuBand->IsMenuMessage(
- &Msg) != S_OK)
+ if (m_StartMenuBand == NULL ||
+ m_StartMenuBand->IsMenuMessage(&Msg) != S_OK)
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
/* FIXME: We should keep a reference here... */
- while (1)
+ while (true)
{
Ret = GetMessage(&Msg, NULL, 0, 0);
if (!Ret || Ret == -1)
break;
- if (StartMenuBand == NULL ||
- StartMenuBand->IsMenuMessage(&Msg) != S_OK)
+ if (m_StartMenuBand == NULL ||
+ m_StartMenuBand->IsMenuMessage(&Msg) != S_OK)
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
{
TRACE("IShellDesktopTray::RegisterDesktopWindow(0x%p)\n", hWndDesktop);
- this->hWndDesktop = hWndDesktop;
+ m_DesktopWnd = hWndDesktop;
return S_OK;
}
virtual HRESULT RaiseStartButton()
{
- StartButton.SendMessageW(BM_SETSTATE, FALSE, 0);
+ m_StartButton.SendMessageW(BM_SETSTATE, FALSE, 0);
return S_OK;
}
+ HRESULT WINAPI GetWindow(HWND* phwnd)
+ {
+ if (!phwnd)
+ return E_INVALIDARG;
+ *phwnd = m_hWnd;
+ return S_OK;
+ }
+
+ HRESULT WINAPI ContextSensitiveHelp(BOOL fEnterMode)
+ {
+ return E_NOTIMPL;
+ }
+
void _Init()
{
- Position = (DWORD) -1;
+ m_Position = (DWORD) -1;
}
DECLARE_NOT_AGGREGATABLE(CTrayWindow)
BEGIN_COM_MAP(CTrayWindow)
/*COM_INTERFACE_ENTRY_IID(IID_ITrayWindow, ITrayWindow)*/
COM_INTERFACE_ENTRY_IID(IID_IShellDesktopTray, IShellDesktopTray)
+ COM_INTERFACE_ENTRY_IID(IID_IOleWindow, IOleWindow)
END_COM_MAP()
};
UINT idCmdLast,
UINT uFlags)
{
- HMENU menubase = LoadPopupMenu(hExplorerInstance, MAKEINTRESOURCE(IDM_TRAYWND));
+ HMENU menubase = LoadPopupMenu(hExplorerInstance, MAKEINTRESOURCEW(IDM_TRAYWND));
- if (menubase)
- {
- int count = ::GetMenuItemCount(menubase);
+ if (!menubase)
+ return HRESULT_FROM_WIN32(GetLastError());
- for (int i = 0; i < count; i++)
- {
- WCHAR label[128];
+ int count = ::GetMenuItemCount(menubase);
- MENUITEMINFOW mii = { 0 };
- mii.cbSize = sizeof(mii);
- mii.fMask = MIIM_STATE | MIIM_ID | MIIM_SUBMENU | MIIM_CHECKMARKS
- | MIIM_DATA | MIIM_STRING | MIIM_BITMAP | MIIM_FTYPE;
- mii.dwTypeData = label;
- mii.cch = _countof(label);
- ::GetMenuItemInfoW(menubase, i, TRUE, &mii);
+ for (int i = 0; i < count; i++)
+ {
+ WCHAR label[128];
- TRACE("Adding item %d label %S type %d\n", mii.wID, mii.dwTypeData, mii.fType);
+ MENUITEMINFOW mii = { 0 };
+ mii.cbSize = sizeof(mii);
+ mii.fMask = MIIM_STATE | MIIM_ID | MIIM_SUBMENU | MIIM_CHECKMARKS
+ | MIIM_DATA | MIIM_STRING | MIIM_BITMAP | MIIM_FTYPE;
+ mii.dwTypeData = label;
+ mii.cch = _countof(label);
+ ::GetMenuItemInfoW(menubase, i, TRUE, &mii);
- mii.fType |= MFT_RADIOCHECK;
+ TRACE("Adding item %d label %S type %d\n", mii.wID, mii.dwTypeData, mii.fType);
- ::InsertMenuItemW(hPopup, i + 1, TRUE, &mii);
- }
+ ::InsertMenuItemW(hPopup, i + 1, TRUE, &mii);
+ }
- ::DestroyMenu(menubase);
+ ::DestroyMenu(menubase);
- if (SHRestricted(REST_CLASSICSHELL) != 0)
- {
- DeleteMenu(hPopup,
- ID_LOCKTASKBAR,
- MF_BYCOMMAND);
- }
+ if (SHRestricted(REST_CLASSICSHELL) != 0)
+ {
+ DeleteMenu(hPopup,
+ ID_LOCKTASKBAR,
+ MF_BYCOMMAND);
+ }
- CheckMenuItem(hPopup,
- ID_LOCKTASKBAR,
- MF_BYCOMMAND | (TrayWnd->Locked ? MF_CHECKED : MF_UNCHECKED));
+ CheckMenuItem(hPopup,
+ ID_LOCKTASKBAR,
+ MF_BYCOMMAND | (TrayWnd->Locked ? MF_CHECKED : MF_UNCHECKED));
- if (TrayWnd->TrayBandSite != NULL)
+ if (TrayWnd->m_TrayBandSite != NULL)
+ {
+ if (FAILED(TrayWnd->m_TrayBandSite->AddContextMenus(
+ hPopup,
+ 0,
+ ID_SHELL_CMD_FIRST,
+ ID_SHELL_CMD_LAST,
+ CMF_NORMAL,
+ &pcm)))
{
- if (SUCCEEDED(TrayWnd->TrayBandSite->AddContextMenus(
- hPopup,
- 0,
- ID_SHELL_CMD_FIRST,
- ID_SHELL_CMD_LAST,
- CMF_NORMAL,
- &pcm)))
- {
- return S_OK;
- }
+ WARN("AddContextMenus failed.\n");
+ pcm = NULL;
}
-
}
- return E_FAIL;
+ return S_OK;
}
virtual HRESULT STDMETHODCALLTYPE
/* Setup and invoke the shell command */
cmici.cbSize = sizeof(cmici);
cmici.hwnd = hWndOwner;
- cmici.lpVerb = (LPCSTR) MAKEINTRESOURCE(uiCmdId - ID_SHELL_CMD_FIRST);
+ cmici.lpVerb = (LPCSTR) MAKEINTRESOURCEW(uiCmdId - ID_SHELL_CMD_FIRST);
cmici.nShow = SW_NORMAL;
pcm->InvokeCommand(&cmici);
return S_OK;
}
-CTrayWindow * g_TrayWindow;
-
-HRESULT
-Tray_OnStartMenuDismissed()
-{
- return g_TrayWindow->RaiseStartButton();
-}
-
-
HRESULT CreateTrayWindow(ITrayWindow ** ppTray)
{
CComPtr<CTrayWindow> Tray = new CComObject<CTrayWindow>();
Tray->_Init();
Tray->Open();
- g_TrayWindow = Tray;
*ppTray = (ITrayWindow *) Tray;
return S_OK;
}
-VOID TrayProcessMessages(ITrayWindow *)
+HRESULT
+Tray_OnStartMenuDismissed(ITrayWindow* Tray)
+{
+ CTrayWindow * TrayWindow = static_cast<CTrayWindow *>(Tray);
+ return TrayWindow->RaiseStartButton();
+}
+
+VOID TrayProcessMessages(ITrayWindow *Tray)
{
- g_TrayWindow->TrayProcessMessages();
+ CTrayWindow * TrayWindow = static_cast<CTrayWindow *>(Tray);
+ TrayWindow->TrayProcessMessages();
}
-VOID TrayMessageLoop(ITrayWindow *)
+VOID TrayMessageLoop(ITrayWindow *Tray)
{
- g_TrayWindow->TrayMessageLoop();
+ CTrayWindow * TrayWindow = static_cast<CTrayWindow *>(Tray);
+ TrayWindow->TrayMessageLoop();
}