From 6ecc35f00e70dc902b7fe13cbd1a40db9ff395ea Mon Sep 17 00:00:00 2001 From: OrthodoxWin32 <100134023+OrthodoxWindows@users.noreply.github.com> Date: Tue, 1 Aug 2023 23:03:00 +0200 Subject: [PATCH] Update StartMenuDLL.cpp Fixed DLL code for classic theme support. --- Src/StartMenu/StartMenuDLL/StartMenuDLL.cpp | 3038 +------------------ 1 file changed, 1 insertion(+), 3037 deletions(-) diff --git a/Src/StartMenu/StartMenuDLL/StartMenuDLL.cpp b/Src/StartMenu/StartMenuDLL/StartMenuDLL.cpp index 278f3bc9f..7580fe1f2 100644 --- a/Src/StartMenu/StartMenuDLL/StartMenuDLL.cpp +++ b/Src/StartMenu/StartMenuDLL/StartMenuDLL.cpp @@ -1246,3040 +1246,4 @@ static void UpdateStartButtonPosition(const TaskbarInfo* taskBar, const WINDOWPO if (rcTask.left < info.rcMonitor.left) rcTask.left = info.rcMonitor.left; if (rcTask.right > info.rcMonitor.right) rcTask.right = info.rcMonitor.right; } - else - { - if (rcTask.top < info.rcMonitor.top) rcTask.top = info.rcMonitor.top; - } - - HWND zPos = NULL; - if (pPos->flags & SWP_NOZORDER) - buttonFlags |= SWP_NOZORDER; - else - { - zPos = pPos->hwndInsertAfter; - if (zPos == HWND_TOP && !(GetWindowLongPtr(taskBar->startButton, GWL_EXSTYLE) & WS_EX_TOPMOST)) - zPos = HWND_TOPMOST; - if (zPos == HWND_TOPMOST && !(GetWindowLongPtr(taskBar->taskBar, GWL_EXSTYLE) & WS_EX_TOPMOST)) - zPos = HWND_TOP; - if (zPos == HWND_BOTTOM) - buttonFlags |= SWP_NOZORDER; - if (zPos == taskBar->startButton) - buttonFlags |= SWP_NOZORDER; - } - - if (!IsStartButtonSmallIcons(taskBar->taskbarId)) - { - bool bClassic; - if (GetWinVersion() < WIN_VER_WIN8) - bClassic = !IsAppThemed(); - else - { - HIGHCONTRAST contrast = { sizeof(contrast) }; - bClassic = (SystemParametersInfo(SPI_GETHIGHCONTRAST, sizeof(contrast), &contrast, 0) && (contrast.dwFlags & HCF_HIGHCONTRASTON)); - } - if (!bClassic) - { - if (uEdge == ABE_TOP) - OffsetRect(&rcTask, 0, -1); - else if (uEdge == ABE_BOTTOM) - OffsetRect(&rcTask, 0, 1); - } - } - - RECT rcOldButton; - if (taskBar->oldButton) - GetWindowRect(taskBar->oldButton, &rcOldButton); - - int x, y; - if (uEdge == ABE_LEFT || uEdge == ABE_RIGHT) - { - if (GetSettingInt(L"StartButtonType") != START_BUTTON_CUSTOM || !GetSettingBool(L"StartButtonAlign")) - x = (rcTask.left + rcTask.right - taskBar->startButtonSize.cx) / 2; - else if (uEdge == ABE_LEFT) - x = rcTask.left; - else - x = rcTask.right - taskBar->startButtonSize.cx; - y = taskBar->oldButton ? rcOldButton.top : rcTask.top; - } - else - { - if (GetWindowLongPtr(taskBar->rebar, GWL_EXSTYLE) & WS_EX_LAYOUTRTL) - x = (taskBar->oldButton ? rcOldButton.right : rcTask.right) - taskBar->startButtonSize.cx; - else - x = taskBar->oldButton ? rcOldButton.left : rcTask.left; - if (GetSettingInt(L"StartButtonType") != START_BUTTON_CUSTOM || !GetSettingBool(L"StartButtonAlign")) - y = (rcTask.top + rcTask.bottom - taskBar->startButtonSize.cy) / 2; - else if (uEdge == ABE_TOP) - y = rcTask.top; - else - y = rcTask.bottom - taskBar->startButtonSize.cy; - - // Start button on Win11 is a bit shifted to the right - // We will shift our Aero button to cover original button - if (IsWin11() && (x == info.rcMonitor.left) && (GetStartButtonType() == START_BUTTON_AERO)) - x += ScaleForDpi(taskBar->taskBar, 6); - } - - RECT rcButton = { x, y, x + taskBar->startButtonSize.cx, y + taskBar->startButtonSize.cy }; - RECT rc; - IntersectRect(&rc, &rcButton, &info.rcMonitor); - HRGN rgn = CreateRectRgn(rc.left - x, rc.top - y, rc.right - x, rc.bottom - y); - if (!SetWindowRgn(taskBar->startButton, rgn, FALSE)) - { - AddTrackedObject(rgn); - DeleteObject(rgn); - } - - SetWindowPos(taskBar->startButton, zPos, x, y, 0, 0, buttonFlags); - - if (buttonFlags & SWP_SHOWWINDOW) - UpdateStartButton(taskBar->taskbarId); -} - -static LRESULT CALLBACK SubclassWin81StartButton( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData ) -{ - TaskbarInfo* taskBar = GetTaskbarInfo((int)dwRefData); - - if (uMsg==WM_WINDOWPOSCHANGING) - { - // keep the original start button hidden at all times - if (taskBar && taskBar->bHideButton) - { - ((WINDOWPOS*)lParam)->flags&=~SWP_SHOWWINDOW; - } - } - if (uMsg==WM_WINDOWPOSCHANGED) - { - if (taskBar && taskBar->bReplaceButton) - { - UpdateStartButtonPosition(taskBar,(WINDOWPOS*)lParam); - } - } - if (uMsg==WM_SIZE) - { - RECT rc; - GetWindowRect(hWnd,&rc); - rc.right-=rc.left; - rc.bottom-=rc.top; - if (taskBar && (taskBar->oldButtonSize.cx!=rc.right || taskBar->oldButtonSize.cy!=rc.bottom)) - { - taskBar->oldButtonSize.cx=rc.right; - taskBar->oldButtonSize.cy=rc.bottom; - RECT rcTask; - GetWindowRect(taskBar->taskBar,&rcTask); - PostMessage(taskBar->taskBar,WM_SIZE,SIZE_RESTORED,MAKELONG(rcTask.right-rcTask.left,rcTask.bottom-rcTask.top)); - } - } - if (uMsg==WM_POINTERACTIVATE && CMenuContainer::IsMenuOpened()) - return MA_NOACTIVATE; -#ifdef START_TOUCH - if (uMsg==WM_POINTERUP || uMsg==WM_POINTERUPDATE || uMsg==WM_POINTERUP) - { - POINTER_INPUT_TYPE type; - GetPointerType2(GET_POINTERID_WPARAM(wParam),&type); - if (type==PT_TOUCH) - { - return SendMessage(GetParent(hWnd),uMsg,wParam,lParam); - } - } -#endif - if (uMsg==WM_PAINT && GetWinVersion()>=WIN_VER_WIN10) - { - g_CurrentTaskbarButton=hWnd; - LRESULT res=DefSubclassProc(hWnd,uMsg,wParam,lParam); - g_CurrentTaskbarButton=NULL; - return res; - } - return DefSubclassProc(hWnd,uMsg,wParam,lParam); -} - -static bool g_bSuppressMessage243; - -static LRESULT CALLBACK SubclassWin7StartButton( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData ) -{ - if (uMsg==243 && g_bSuppressMessage243) - { - // HACK: if the start button is smaller than the original, some NC clicks on the taskbar may be interpreted as clicks on the start button and open the WSM - // This is prevented by suppressing message 243 while processing WM_NCLBUTTONDOWN on the taskbar - return 0; - } - if (uMsg==WM_WINDOWPOSCHANGING) - { - // keep the Win7 start button hidden at all times - ((WINDOWPOS*)lParam)->flags&=~SWP_SHOWWINDOW; - } - return DefSubclassProc(hWnd,uMsg,wParam,lParam); -} - -static LRESULT CALLBACK SubclassUserPicProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData ) -{ - if (uMsg==WM_WINDOWPOSCHANGING && !(((WINDOWPOS*)lParam)->flags&SWP_NOMOVE)) - { - if (GetSettingBool(L"HideUserPic")) - { - ((WINDOWPOS*)lParam)->x=-32000; - ((WINDOWPOS*)lParam)->y=-32000; - } - } - return DefSubclassProc(hWnd,uMsg,wParam,lParam); -} - -static LRESULT CALLBACK SubclassTopMenuProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData ) -{ - if (uMsg==WM_ACTIVATE && GetSettingBool(L"CascadeAll")) - { - if (!wParam) - { - if (CMenuContainer::s_bPreventClosing) return 0; - // check if another menu window is being activated - // if not, close all menus - for (std::vector::const_iterator it=CMenuContainer::s_Menus.begin();it!=CMenuContainer::s_Menus.end();++it) - if ((*it)->m_hWnd==(HWND)lParam) - return 0; - } - } - if (uMsg==WM_WINDOWPOSCHANGED && (((WINDOWPOS*)lParam)->flags&SWP_SHOWWINDOW)) - { - g_LastHoverPos=GetMessagePos(); - if (g_ProgramsButton && GetSettingInt(L"InitiallySelect")==1) - PostMessage(hWnd,WM_CLEAR,'CLSH',0); - g_CurrentWSMTaskbar=MAIN_TASK_BAR; - PressStartButton(MAIN_TASK_BAR,true); - } - if (uMsg==WM_CLEAR && wParam=='CLSH' && g_ProgramsButton) - { - SetFocus(g_ProgramsButton); - return 0; - } - if (uMsg==WM_SHOWWINDOW) - { - if (!wParam) - { - CMenuContainer::CloseProgramsMenu(); - g_CurrentWSMTaskbar=-1; - PressStartButton(MAIN_TASK_BAR,false); - } - g_bAllProgramsTimer=false; - if (g_ProgramsButton) KillTimer(g_ProgramsButton,'CLSM'); - } - if (uMsg==WM_DESTROY) - g_TopWin7Menu=NULL; - if (uMsg==WM_ACTIVATEAPP && !wParam) - { - if (CMenuContainer::s_bPreventClosing) return 0; - } - if (uMsg==WM_MOUSEACTIVATE && GetSettingBool(L"CascadeAll") && CMenuContainer::IsMenuOpened()) - { - CPoint pt(GetMessagePos()); - if (g_ProgramsButton && WindowFromPoint(pt)==g_ProgramsButton) - return MA_NOACTIVATEANDEAT; - CMenuContainer::CloseProgramsMenu(); - return MA_ACTIVATEANDEAT; - } - return DefSubclassProc(hWnd,uMsg,wParam,lParam); -} - -static LRESULT CALLBACK SubclassProgramsProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData ) -{ - if (uMsg==WM_COMMAND && wParam==IDOK && GetSettingBool(L"CascadeAll")) - { - if (GetKeyState(VK_SHIFT)<0) - { - if (CMenuContainer::IsMenuOpened()) - return 0; // ignore shift+click when the menu is opened - } - else - { - if (!CMenuContainer::IsMenuOpened()) - CMenuContainer::ToggleStartMenu(MAIN_TASK_BAR,GetKeyState(VK_SPACE)<0 || GetKeyState(VK_RETURN)<0 || GetKeyState(VK_LEFT)<0 || GetKeyState(VK_RIGHT)<0,true); - return 0; - } - } - if (uMsg==WM_DRAWITEM && wParam==IDOK && CMenuContainer::IsMenuOpened()) - { - DRAWITEMSTRUCT *pDraw=(DRAWITEMSTRUCT*)lParam; - pDraw->itemState=ODS_HOTLIGHT; // draw highlighted when the menu is open - } - return DefSubclassProc(hWnd,uMsg,wParam,lParam); -} - -static BOOL CALLBACK FindWindowsMenuProc( HWND hwnd, LPARAM lParam ) -{ - wchar_t name[100]; - GetClassName(hwnd,name,_countof(name)); - if (_wcsicmp(name,L"DV2ControlHost")==0) - { - HWND w1=hwnd; - if (GetWinVersion()==WIN_VER_VISTA) - { - w1=FindWindowEx(w1,NULL,L"Desktop Open Pane Host",NULL); - if (!w1) return TRUE; - } - w1=FindWindowEx(w1,NULL,L"Desktop More Programs Pane",NULL); - if (!w1) return TRUE; - - g_TopWin7Menu=hwnd; - g_AllPrograms=w1; - g_ProgramsButton=GetDlgItem(w1,IDOK); // this may not exist - return FALSE; - } - return TRUE; -} - -static void FindWindowsMenu( void ) -{ - if (g_TopWin7Menu) return; - if (GetWinVersion()=rcPaint.bottom) break; - for (int x=0;x=rcPaint.right) break; - MarginsBlit(hsrc,hdc,rSrc,rDst,g_TaskbarMargins,true); - } - } - - SelectObject(hsrc,bmp0); - DeleteDC(hsrc); -} - -static void ComputeTaskbarColors( int *data ) -{ - bool bDefLook; - int look=GetSettingInt(L"TaskbarLook",bDefLook); - if (GetWinVersion()255) a=255; - bool bDefColor; - DWORD color=GetSettingInt(L"TaskbarColor",bDefColor); - if (bDefColor) - color=color0; - data[2]=(color&0xFFFFFF)|(a<<24); - } - data[3]=0; -} - -static void ShowWinX( void ) -{ - if (IsWin11()) - { - HWND hwnd=FindWindowEx(NULL,NULL,L"Shell_TrayWnd",NULL); - if (hwnd) - PostMessage(hwnd,WM_HOTKEY,590,MAKELPARAM(MOD_WIN,'X')); - - return; - } - - if (GetWinVersion()>=WIN_VER_WIN10) - { - CComPtr pImmersiveShell; - if (CreateImmersiveShell(pImmersiveShell)) - { - CComPtr pMonitorService; - IUnknown_QueryService(pImmersiveShell,SID_IImmersiveMonitorService,IID_IImmersiveMonitorService,(void**)&pMonitorService); - if (pMonitorService) - { - CPoint pt(GetMessagePos()); - HMONITOR monitor=MonitorFromPoint(pt,MONITOR_DEFAULTTONEAREST); - CComPtr pMonitor; - pMonitorService->GetFromHandle(monitor,&pMonitor); - if (pMonitorService) - { - CComPtr pMenu; - IUnknown_QueryService(pMonitor,SID_LauncherTipContextMenu,SID_LauncherTipContextMenu,(void**)&pMenu); - if (pMenu) - pMenu->ShowLauncherTipContextMenu(&pt); - } - } - } - } - else if (g_AppManagerThread) - PostThreadMessage(g_AppManagerThread,g_StartMenuMsg,MSG_WINXMENU,GetMessagePos()); -} - -static LRESULT CALLBACK SubclassTrayButtonProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData ) -{ - if (uMsg==WM_WINDOWPOSCHANGING) - { - const TaskbarInfo *taskBar=GetTaskbarInfo((int)dwRefData); - if (taskBar && (taskBar->bReplaceButton || taskBar->bHideButton)) - { - WINDOWPOS *pPos=(WINDOWPOS*)lParam; - if (!(pPos->flags&SWP_NOMOVE) || !(pPos->flags&SWP_NOSIZE)) - { - if (pPos->flags&(SWP_NOMOVE|SWP_NOSIZE)) - { - RECT rc; - GetWindowRect(hWnd,&rc); - MapWindowPoints(NULL,GetParent(hWnd),(POINT*)&rc,2); - if (pPos->flags&SWP_NOMOVE) - { - pPos->x=rc.left; - pPos->y=rc.top; - } - else - { - pPos->cx=rc.right-rc.left; - pPos->cy=rc.bottom-rc.top; - } - } - int dx=0, dy=0; - UINT uEdge=GetTaskbarPosition(taskBar->taskBar,NULL,NULL,NULL); - if (uEdge==ABE_LEFT || uEdge==ABE_RIGHT) - { - dy=taskBar->startButtonSize.cy-taskBar->oldButtonSize.cy; - } - else - { - dx=taskBar->startButtonSize.cx-taskBar->oldButtonSize.cx; - } - if (dx || dy) - { - pPos->x+=dx; - pPos->y+=dy; - pPos->flags&=~(SWP_NOMOVE); - } - } - } - } - return DefSubclassProc(hWnd,uMsg,wParam,lParam); -} - -static LRESULT CALLBACK SubclassTaskBarProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData ) -{ - if (uMsg==WM_MOUSEACTIVATE && (HIWORD(lParam)==WM_MBUTTONDOWN || GetWinVersion()>=WIN_VER_WIN10)) - { - if (GetWinVersion()>=WIN_VER_WIN10 && CMenuContainer::IsMenuOpened() && CMenuContainer::HasInputHandler() && GetFocus()) - { - // Win10: if the taskbar is clicked while the menu is opened, check if the touch keyboard button was clicked and ignore the activation - // Otherwise the click on the touch keyboard button will deactivate the menu (possibly because both run on the same thread) - // On Win8.1 the button already handles this and returns MA_NOACTIVATE - HWND hwnd=WindowFromPoint(CPoint(GetMessagePos())); - if (hwnd) - { - wchar_t className[256]; - GetClassName(hwnd,className,_countof(className)); - if (_wcsicmp(className,L"TIPBand")==0) - return MA_NOACTIVATE; - } - } - FindWindowsMenu(); - if (g_TopWin7Menu && WindowsMenuOpened()) - { - DefSubclassProc(hWnd,uMsg,wParam,lParam); - return MA_ACTIVATEANDEAT; // ignore the next middle click, so it doesn't re-open the start menu - } - } - TaskbarInfo *taskBar=GetTaskbarInfo((int)dwRefData); - if (taskBar && (uMsg==WM_NCMOUSEMOVE || uMsg==WM_MOUSEMOVE) && PointAroundStartButton((int)dwRefData)) - TaskBarMouseMove(taskBar->taskbarId); - if (taskBar && uMsg==WM_POINTERACTIVATE && CMenuContainer::IsMenuOpened()) - return MA_NOACTIVATE; - static int touchTime; -#ifdef START_TOUCH - if (taskBar && (uMsg==WM_NCPOINTERDOWN || (uMsg==WM_POINTERDOWN && IS_POINTER_INCONTACT_WPARAM(wParam) && IS_POINTER_PRIMARY_WPARAM(wParam) && IS_POINTER_FIRSTBUTTON_WPARAM(wParam)))) - { - POINTER_INPUT_TYPE type; - GetPointerType2(GET_POINTERID_WPARAM(wParam),&type); - if (type==PT_TOUCH) - { - if (PointAroundStartButton((int)dwRefData,CPoint(lParam))) - { - taskBar->pointerId=GET_POINTERID_WPARAM(wParam); - touchTime=GetMessageTime(); - return 0; - } - } - } - if (taskBar && (uMsg==WM_NCPOINTERUPDATE || uMsg==WM_POINTERUPDATE) && taskBar->pointerId==GET_POINTERID_WPARAM(wParam)) - { - if (uMsg==WM_NCPOINTERUPDATE) - { - POINTER_INFO info; - if (GetPointerInfo2(taskBar->pointerId,&info) && (info.pointerFlags&4)!=0) - { - int time=GetMessageTime(); - if (time-touchTime>500) - { - taskBar->pointerId=0; - ShowWinX(); - return 0; - } - } - } - else if (IS_POINTER_INCONTACT_WPARAM(wParam)) - { - int time=GetMessageTime(); - if (time-touchTime>500) - { - taskBar->pointerId=0; - PostMessage(taskBar->startButton,WM_RBUTTONUP,0,MAKELPARAM(-1,-1)); - return 0; - } - } - else - uMsg=WM_POINTERUP; - } - if (taskBar && (uMsg==WM_POINTERUP || uMsg==WM_NCPOINTERUP) && taskBar->pointerId==GET_POINTERID_WPARAM(wParam)) - { - if (PointAroundStartButton((int)dwRefData,CPoint(lParam))) - { - int control=GetSettingInt(L"MouseClick"); - if (control==OPEN_BOTH && GetWinVersion()>=WIN_VER_WIN10) - control=GetWin10TabletMode()?OPEN_WINDOWS:OPEN_CLASSIC; - if (control==OPEN_CLASSIC) - ToggleStartMenu(taskBar->taskbarId,false); - else if (control==OPEN_WINDOWS) - PostMessage(g_ProgWin,WM_SYSCOMMAND,SC_TASKLIST,'WSMM'); - } - taskBar->pointerId=0; - return 0; - } -#endif - if (uMsg==WM_SHOWWINDOW && taskBar) - { - if (taskBar->bReplaceButton) - ShowWindow(taskBar->startButton,wParam?SW_SHOW:SW_HIDE); - } - if (uMsg==WM_WINDOWPOSCHANGING && taskBar && taskBar->bReplaceButton) - { - WINDOWPOS *pPos=(WINDOWPOS*)lParam; - if (!(pPos->flags&SWP_NOZORDER) && pPos->hwndInsertAfter==HWND_BOTTOM) - { - SetWindowPos(taskBar->startButton,HWND_BOTTOM,0,0,0,0,SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOSIZE|SWP_NOMOVE); - pPos->hwndInsertAfter=taskBar->startButton; - } - } - if (uMsg==WM_WINDOWPOSCHANGED && taskBar) - { - if (taskBar->bReplaceButton) - { - UpdateStartButtonPosition(taskBar,(WINDOWPOS*)lParam); - } - if (taskBar->oldButton && GetWinVersion()oldButton,NULL,x,0,0,0,SWP_NOSIZE|SWP_NOZORDER); - } - } - if (uMsg==WM_THEMECHANGED && taskBar) - { - if (taskBar->bReplaceButton) - { - RecreateStartButton((int)dwRefData); - } - taskBar->bThemeChanging=true; - LRESULT res=DefSubclassProc(hWnd,uMsg,wParam,lParam); - taskBar->bThemeChanging=false; - return res; - } - if ((uMsg==WM_DWMCOLORIZATIONCOLORCHANGED || uMsg==WM_SETTINGCHANGE || uMsg==0x5CB || uMsg==0x5BB) && taskBar && taskBar->bCustomLook && SetWindowCompositionAttribute && GetWinVersion()>=WIN_VER_WIN10) - { - LRESULT res=DefSubclassProc(hWnd,uMsg,wParam,lParam); - int data[4]; - ComputeTaskbarColors(data); - WINCOMPATTRDATA attrData={0x13,&data,sizeof(data)}; - SetWindowCompositionAttribute(hWnd,&attrData); - return res; - } - if ((uMsg==WM_DWMCOLORIZATIONCOLORCHANGED || uMsg==WM_SETTINGCHANGE) && taskBar && taskBar->bCustomLook && SetWindowCompositionAttribute && GetWinVersion()bCustomLook) - { - TTaskbarLook look=(TTaskbarLook)GetSettingInt(L"TaskbarLook"); - WORD winVer=GetWinVersion(); - BOOL blurBehind; - int margin; - enum { FLAG_BLUR=1, FLAG_MARGIN=2, FLAG_ATTRIBUTE=4}; - int flags=0; - if (winVer==WIN_VER_WIN7) - { - blurBehind=look==TASKBAR_GLASS; - margin=look==TASKBAR_OPAQUE?0:-1; - flags=FLAG_BLUR|FLAG_MARGIN; - } - else if (winVer==WIN_VER_WIN8) - { - blurBehind=look==TASKBAR_OPAQUE; - margin=look==TASKBAR_OPAQUE?0:-1; - flags=FLAG_BLUR|FLAG_MARGIN|((look==TASKBAR_TRANSPARENT && g_TaskbarTexture)?FLAG_ATTRIBUTE:0); - } - else if (winVer==WIN_VER_WIN81) - { - blurBehind=look==TASKBAR_OPAQUE; - margin=look==TASKBAR_OPAQUE?0:-1; - flags=FLAG_BLUR|FLAG_MARGIN|((look==TASKBAR_OPAQUE || g_TaskbarTexture)?FLAG_ATTRIBUTE:0); - } - else if (winVer>=WIN_VER_WIN10) - { - blurBehind=TRUE; - margin=look==TASKBAR_OPAQUE?0:-1; - flags=(look==TASKBAR_AEROGLASS?FLAG_BLUR:0)|(look!=TASKBAR_GLASS?FLAG_MARGIN:0)|FLAG_ATTRIBUTE; - } - - if (flags&FLAG_BLUR) - { - DWM_BLURBEHIND blur={DWM_BB_ENABLE,blurBehind}; - DwmEnableBlurBehindWindow(hWnd,&blur); - } - if (flags&FLAG_MARGIN) - { - MARGINS margins={margin}; - DwmExtendFrameIntoClientArea(hWnd,&margins); - } - if (SetWindowCompositionAttribute && (flags&FLAG_ATTRIBUTE)) - { - int data[4]; - ComputeTaskbarColors(data); - WINCOMPATTRDATA attrData={0x13,&data,sizeof(data)}; - SetWindowCompositionAttribute(hWnd,&attrData); - } - if (g_TaskbarTexture && IsAppThemed()) - { - // draw taskbar background (behind start button and separators) - PAINTSTRUCT ps; - HDC hdc=BeginPaint(hWnd,&ps); - RECT rc; - GetClientRect(hWnd,&rc); - UINT uEdge=GetTaskbarPosition(hWnd,NULL,NULL,NULL); - PrintTaskbarBackground(hdc,rc,ps.rcPaint,uEdge); - EndPaint(hWnd,&ps); - return 0; - } - } - if (taskBar->bReplaceButton && g_WinStartButton && !IsAppThemed()) - { - // prevent painting of the default classic button - PAINTSTRUCT ps; - HDC hdc=BeginPaint(hWnd,&ps); - EndPaint(hWnd,&ps); - return 0; - } - } - if (uMsg==WM_PRINTCLIENT && g_TaskbarTexture) - { - // print taskbar background - for background of buttons and tray area - HDC hdc=(HDC)wParam; - RECT rc; - GetClientRect(hWnd,&rc); - UINT uEdge=GetTaskbarPosition(hWnd,NULL,NULL,NULL); - PrintTaskbarBackground(hdc,rc,rc,uEdge); - return 0; - } - if (uMsg==0x5C5 && taskBar && taskBar->bCustomLook && IsWin81Update1()) // some secret message when the taskbar is raised to the top - { - // reset the opaqueness - PostMessage(g_TaskBar,g_StartMenuMsg,MSG_REDRAWTASKBAR,(LPARAM)hWnd); - } - if (uMsg==WM_DESTROY && taskBar) - { - if (taskBar->bReplaceButton) - DestroyStartButton(taskBar->taskbarId); - g_TaskbarInfos.erase(g_TaskbarInfos.find(taskBar->taskbarId)); - } - if (uMsg==WM_TIMER && wParam=='CLSM') - { - if (GetMetroMode(NULL)==METRO_NONE) - { - KillTimer(hWnd,'CLSM'); - return 0; - } - SetForegroundWindow(hWnd); - LogToFile(STARTUP_LOG,L"StartMenu DLL: skipping Metro"); - if (GetSettingInt(L"SkipMetroCount")<0) - { - INPUT inputs[4]={ - {INPUT_KEYBOARD}, - {INPUT_KEYBOARD}, - {INPUT_KEYBOARD}, - {INPUT_KEYBOARD}, - }; - inputs[0].ki.wVk=VK_LWIN; - inputs[1].ki.wVk='D'; - inputs[2].ki.wVk='D'; - inputs[2].ki.dwFlags=KEYEVENTF_KEYUP; - inputs[3].ki.wVk=VK_LWIN; - inputs[3].ki.dwFlags=KEYEVENTF_KEYUP; - SendInput(_countof(inputs),inputs,sizeof(INPUT)); - } - else - { - HWND hwnd=FindWindow(L"ModeInputWnd",NULL); - if (hwnd) - { - DWORD process; - GetWindowThreadProcessId(hwnd,&process); - if (process==GetCurrentProcessId()) - { - IObjectWithSite *pObject=(IObjectWithSite*)GetWindowLongPtr(hwnd,0); - if (pObject) - { - CComPtr pSite; - pObject->GetSite(IID_IUnknown,(void**)&pSite); - if (pSite) - { - CComPtr pLauncher; - IUnknown_QueryService(pSite,SID_ImmersiveLauncher,IID_IImmersiveLauncher80,(void**)&pLauncher); - if (pLauncher) - pLauncher->Dismiss(5); - } - } - } - } - } - g_SkipMetroCount--; - if (g_SkipMetroCount<=0) - KillTimer(hWnd,'CLSM'); - return 0; - } - if (uMsg==WM_MOVE) - { - ResetHotCorners(); - } - if (uMsg==WM_NCLBUTTONDOWN && taskBar && GetWinVersion()==WIN_VER_WIN7 && taskBar->bReplaceButton) - { - g_bSuppressMessage243=true; - LRESULT res=DefSubclassProc(hWnd,uMsg,wParam,lParam); - g_bSuppressMessage243=false; - return res; - } - if (uMsg==WM_PARENTNOTIFY && taskBar && LOWORD(wParam)==WM_CREATE && GetWinVersion()>=WIN_VER_WIN10) - { - wchar_t name[100]; - HWND child=(HWND)lParam; - GetClassName(child,name,_countof(name)); - if (_wcsicmp(name,L"TrayButton")==0 && GetParent(child)==hWnd) - { - bool bFound=false; - for (std::vector::const_iterator it=taskBar->trayButtons.begin();it!=taskBar->trayButtons.end();++it) - if (*it==child) - { - bFound=true; - break; - } - if (!bFound) - { - taskBar->trayButtons.push_back(child); - SetWindowSubclass(child,SubclassTrayButtonProc,'CLSH',taskBar->taskbarId); - } - } - } - return DefSubclassProc(hWnd,uMsg,wParam,lParam); -} - -static LRESULT CALLBACK SubclassTaskListProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData ) -{ - if (uMsg==WM_PAINT && g_TaskbarTexture) - { - wchar_t name[100]; - GetClassName(hWnd,name,_countof(name)); - if (_wcsicmp(name,L"MSTaskSwWClass")==0) - { - // draw taskbar background (behind task list) - PAINTSTRUCT ps; - HDC hdc=BeginPaint(hWnd,&ps); - DrawThemeParentBackground(hWnd,hdc,NULL); - EndPaint(hWnd,&ps); - return 0; - } - } - - if (uMsg==WM_PAINT || uMsg==WM_PRINT || uMsg==WM_PRINTCLIENT) - { - g_CurrentTaskList=hWnd; - LRESULT res=DefSubclassProc(hWnd,uMsg,wParam,lParam); - g_CurrentTaskList=NULL; - return res; - } - return DefSubclassProc(hWnd,uMsg,wParam,lParam); -} - -static LRESULT CALLBACK SubclassTrayChevronProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData ) -{ - if (uMsg==WM_PAINT || uMsg==WM_PRINT || uMsg==WM_PRINTCLIENT) - { - g_CurrentTaskChevron=hWnd; - LRESULT res=DefSubclassProc(hWnd,uMsg,wParam,lParam); - g_CurrentTaskChevron=NULL; - return res; - } - return DefSubclassProc(hWnd,uMsg,wParam,lParam); -} - -static LRESULT CALLBACK SubclassDesktopButtonProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData ) -{ - if (uMsg==WM_PAINT || uMsg==WM_PRINT || uMsg==WM_PRINTCLIENT) - { - g_CurrentDesktopButton=hWnd; - LRESULT res=DefSubclassProc(hWnd,uMsg,wParam,lParam); - g_CurrentDesktopButton=NULL; - return res; - } - return DefSubclassProc(hWnd,uMsg,wParam,lParam); -} - -static LRESULT CALLBACK SubclassRebarProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData ) -{ - if (uMsg==WM_WINDOWPOSCHANGING) - { - const TaskbarInfo *taskBar=GetTaskbarInfo((int)dwRefData); - if (taskBar && (taskBar->bReplaceButton || taskBar->bHideButton)) - { - WINDOWPOS *pPos=(WINDOWPOS*)lParam; - if (!(pPos->flags&SWP_NOMOVE) || !(pPos->flags&SWP_NOSIZE)) - { - if (pPos->flags&(SWP_NOMOVE|SWP_NOSIZE)) - { - RECT rc; - GetWindowRect(hWnd,&rc); - MapWindowPoints(NULL,GetParent(hWnd),(POINT*)&rc,2); - if (pPos->flags&SWP_NOMOVE) - { - pPos->x=rc.left; - pPos->y=rc.top; - } - else - { - pPos->cx=rc.right-rc.left; - pPos->cy=rc.bottom-rc.top; - } - } - int dx=0, dy=0; - UINT uEdge=GetTaskbarPosition(taskBar->taskBar,NULL,NULL,NULL); - if (taskBar->oldButton) - { - if (uEdge==ABE_LEFT || uEdge==ABE_RIGHT) - { - dy=taskBar->startButtonSize.cy-taskBar->oldButtonSize.cy; - } - else - { - dx=taskBar->startButtonSize.cx-taskBar->oldButtonSize.cx; - } - } - else - { - if (uEdge==ABE_LEFT || uEdge==ABE_RIGHT) - { - dy=taskBar->startButtonSize.cy-pPos->y; - } - else - { - dx=taskBar->startButtonSize.cx-pPos->x; - } - } - if (dx || dy) - { - pPos->x+=dx; - pPos->cx-=dx; - pPos->y+=dy; - pPos->cy-=dy; - pPos->flags&=~(SWP_NOMOVE|SWP_NOSIZE); - } - } - } - } - if (uMsg==WM_PAINT || uMsg==WM_PRINT || uMsg==WM_PRINTCLIENT) - { - g_CurrentRebar=hWnd; - LRESULT res=DefSubclassProc(hWnd,uMsg,wParam,lParam); - g_CurrentRebar=NULL; - return res; - } - return DefSubclassProc(hWnd,uMsg,wParam,lParam); -} - -static LRESULT CALLBACK SubclassTaskbarPartProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData ) -{ - if (uMsg==WM_PAINT || uMsg==WM_PRINT || uMsg==WM_PRINTCLIENT) - { - g_CurrentTaskbarPart=hWnd; - LRESULT res=DefSubclassProc(hWnd,uMsg,wParam,lParam); - g_CurrentTaskbarPart=NULL; - return res; - } - if (uMsg==WM_NCDESTROY) - { - TaskbarInfo *info=GetTaskbarInfo((int)dwRefData); - if (info) - { - for (std::vector::const_iterator it=info->taskbarParts.begin();it!=info->taskbarParts.end();++it) - if (*it==hWnd) - { - info->taskbarParts.erase(it); - break; - } - } - } - return DefSubclassProc(hWnd,uMsg,wParam,lParam); -} - -static void HandleTaskbarParts( TaskbarInfo &taskBar, bool bPrimary ) -{ - if (taskBar.rebar) - { - int count=(int)SendMessage(taskBar.rebar,RB_GETBANDCOUNT,0,0); - for (int i=0;i=WIN_VER_WIN10) - { - HWND clock=FindWindowEx(taskBar.taskBar,NULL,L"ClockButton",NULL); - if (clock && !taskBar.HasPart(clock)) - { - SetWindowSubclass(clock,SubclassTaskbarPartProc,'CLSH',taskBar.taskbarId); - taskBar.taskbarParts.push_back(clock); - } - } -} - -static void HandleSecondaryTaskbar( HWND hwnd ) -{ - int taskbarId=g_NextTaskbar++; - TaskbarInfo &taskBar=g_TaskbarInfos[taskbarId]; - taskBar.taskBar=hwnd; - taskBar.taskbarId=taskbarId; - - taskBar.rebar=FindWindowEx(hwnd,NULL,L"WorkerW",NULL); - if (taskBar.rebar) - { - SetWindowSubclass(taskBar.rebar,SubclassRebarProc,'CLSH',taskbarId); - taskBar.taskList=FindWindowEx(taskBar.rebar,NULL,L"MSTaskListWClass",NULL); - if (taskBar.taskList) - SetWindowSubclass(taskBar.taskList,SubclassTaskListProc,'CLSH',taskbarId); - } - if (GetWinVersion()>WIN_VER_WIN8) - { - taskBar.oldButton=FindWindowEx(taskBar.taskBar,NULL,L"Start",NULL); - if (taskBar.oldButton) - { - if (GetWinVersion()>=WIN_VER_WIN10) - { - taskBar.pOriginalTarget=(IDropTarget*)GetProp(taskBar.oldButton,L"OleDropTargetInterface"); - if (taskBar.pOriginalTarget) - RevokeDragDrop(taskBar.oldButton); - } - - CStartMenuTarget *pNewTarget=new CStartMenuTarget(taskBar.taskbarId); - RegisterDragDrop(taskBar.oldButton,pNewTarget); - pNewTarget->Release(); - if (GetWinVersion()=WIN_VER_WIN10) - { - for (HWND button=FindWindowEx(taskBar.taskBar,NULL,L"TrayButton",NULL);button;button=FindWindowEx(taskBar.taskBar,button,L"TrayButton",NULL)) - { - taskBar.trayButtons.push_back(button); - SetWindowSubclass(button,SubclassTrayButtonProc,'CLSH',taskBar.taskbarId); - } - HWND search=FindWindowEx(taskBar.taskBar,NULL,L"TrayDummySearchControl",NULL); - if (search) - { - taskBar.trayButtons.push_back(search); - SetWindowSubclass(search,SubclassTrayButtonProc,'CLSH',taskBar.taskbarId); - } - } - HandleTaskbarParts(taskBar,false); - SetWindowSubclass(taskBar.taskBar,SubclassTaskBarProc,'CLSH',taskbarId); - UpdateTaskBars(TASKBAR_UPDATE); - UpdateTaskBars(TASKBAR_UPDATE_TEXTURE); -} - -static BOOL CALLBACK HookAllTaskbarsEnum( HWND hwnd, LPARAM lParam ) -{ - // look for top-level windows with class "Shell_SecondaryTrayWnd" in the current thread - if (GetWindowThreadProcessId(hwnd,NULL)!=GetCurrentThreadId()) return TRUE; - wchar_t name[256]; - GetClassName(hwnd,name,_countof(name)); - if (_wcsicmp(name,L"Shell_SecondaryTrayWnd")==0) - HandleSecondaryTaskbar(hwnd); - return TRUE; -} - -void UpdateTaskBars( TUpdateTaskbar update ) -{ - if (update==TASKBAR_UPDATE_TEXTURE) - { - if (g_TaskbarTexture) - DeleteObject(g_TaskbarTexture); - g_TaskbarTexture=NULL; - if (GetSettingBool(L"CustomTaskbar")) - { - g_TaskbarTileH=g_TaskbarTileV=TILE_STRETCH; - g_TaskbarMargins.left=g_TaskbarMargins.right=g_TaskbarMargins.top=g_TaskbarMargins.bottom=0; - TTaskbarLook look=(TTaskbarLook)GetSettingInt(L"TaskbarLook"); - bool bDefOpacity; - int opacity=GetSettingInt(L"TaskbarOpacity",bDefOpacity); - if (look==TASKBAR_OPAQUE) - opacity=100, bDefOpacity=true; - bool bDefColor; - COLORREF color=GetSettingInt(L"TaskbarColor",bDefColor); - wchar_t fname[_MAX_PATH]; - Strcpy(fname,_countof(fname),GetSettingString(L"TaskbarTexture")); - DoEnvironmentSubst(fname,_countof(fname)); - if (*fname) - { - g_TaskbarTexture=LoadImageResource(NULL,fname,false,true); - g_TaskbarTileH=(TTaskbarTile)GetSettingInt(L"TaskbarTileH"); - g_TaskbarTileV=(TTaskbarTile)GetSettingInt(L"TaskbarTileV"); - if (g_TaskbarTileH==TILE_STRETCH) - { - CString borders=GetSettingString(L"TaskbarBordersH"); - if (!borders.IsEmpty()) - { - wchar_t token[256]; - const wchar_t *str=GetToken(borders,token,_countof(token),L", \t"); - g_TaskbarMargins.left=_wtol(token); - if (g_TaskbarMargins.left<0) g_TaskbarMargins.left=0; - str=GetToken(str,token,_countof(token),L", \t"); - g_TaskbarMargins.right=_wtol(token); - if (g_TaskbarMargins.right<0) g_TaskbarMargins.right=0; - } - } - if (g_TaskbarTileV==TILE_STRETCH) - { - CString borders=GetSettingString(L"TaskbarBordersV"); - if (!borders.IsEmpty()) - { - wchar_t token[256]; - const wchar_t *str=GetToken(borders,token,_countof(token),L", \t"); - g_TaskbarMargins.top=_wtol(token); - if (g_TaskbarMargins.top<0) g_TaskbarMargins.top=0; - str=GetToken(str,token,_countof(token),L", \t"); - g_TaskbarMargins.bottom=_wtol(token); - if (g_TaskbarMargins.bottom<0) g_TaskbarMargins.bottom=0; - } - } - } - else if (GetWinVersion()WIN_VER_WIN7) - { - color=GetSystemGlassColor8(); - color=((color&0xFF)<<16)|(color&0xFF00)|((color>>16)&0xFF); - } - BITMAPINFO bi={0}; - bi.bmiHeader.biSize=sizeof(BITMAPINFOHEADER); - bi.bmiHeader.biWidth=bi.bmiHeader.biHeight=32; - bi.bmiHeader.biPlanes=1; - bi.bmiHeader.biBitCount=32; - - HDC hdc=CreateCompatibleDC(NULL); - unsigned int *bits; - g_TaskbarTexture=CreateDIBSection(hdc,&bi,DIB_RGB_COLORS,(void**)&bits,NULL,0); - if (g_TaskbarTexture) - { - unsigned int val=((color&0xFF)<<16)|(color&0x00FF00)|((color>>16)&0xFF)|0xFF000000; - int count=bi.bmiHeader.biWidth*bi.bmiHeader.biHeight; - for (int i=0;i1 || countV>1) - { - // pretile texture - BITMAPINFO bi={0}; - bi.bmiHeader.biSize=sizeof(BITMAPINFOHEADER); - bi.bmiHeader.biWidth=countH*info.bmWidth; - bi.bmiHeader.biHeight=countV*info.bmHeight; - bi.bmiHeader.biPlanes=1; - bi.bmiHeader.biBitCount=32; - - HDC hdc=CreateCompatibleDC(NULL); - HDC hsrc=CreateCompatibleDC(hdc); - unsigned int *bits; - HBITMAP bmp=CreateDIBSection(hdc,&bi,DIB_RGB_COLORS,(void**)&bits,NULL,0); - if (bmp) - { - HGDIOBJ bmp01=SelectObject(hdc,bmp); - HGDIOBJ bmp02=SelectObject(hsrc,g_TaskbarTexture); - for (int y=0;ysecond.taskBar,NULL,NULL,RDW_INVALIDATE|RDW_ALLCHILDREN); - } - return; - } - bool bButton=false, bCustomLook= false, bAll= false; - if (update==TASKBAR_CLEAR) - { - if (g_TaskbarTexture) - DeleteObject(g_TaskbarTexture); - g_TaskbarTexture=NULL; - } - else - { - bButton=GetSettingBool(L"EnableStartButton"); - bCustomLook=GetSettingBool(L"CustomTaskbar"); - bAll=GetSettingBool(L"AllTaskbars"); - } - if (g_bTrimHooks) - bButton=false; - for (id_taskbar_map::iterator it=g_TaskbarInfos.begin();it!=g_TaskbarInfos.end();++it) - { - TaskbarInfo &taskBar=it->second; - bool bButton2=bButton && (bAll || taskBar.taskBar==g_TaskBar); - bool bHideButton2=bButton; - if (taskBar.oldButton) - { - if (bHideButton2 && !bButton2) - { - // reposition rebar - if (taskBar.oldButton) - { - RECT rc; - GetWindowRect(taskBar.oldButton,&rc); - taskBar.oldButtonSize.cx=rc.right-rc.left; - taskBar.oldButtonSize.cy=rc.bottom-rc.top; - } - RECT rcTask; - GetWindowRect(taskBar.taskBar,&rcTask); - PostMessage(taskBar.taskBar,WM_SIZE,SIZE_RESTORED,MAKELONG(rcTask.right-rcTask.left,rcTask.bottom-rcTask.top)); - } - if (taskBar.bHideButton!=bHideButton2) - { - // show/hide 8.1 button - taskBar.bHideButton=bHideButton2; - if (bHideButton2) - { - ShowWindow(taskBar.oldButton,SW_HIDE); - } - else - { - ShowWindow(taskBar.oldButton,SW_SHOW); - } - } - } - if (taskBar.bReplaceButton!=bButton2) - { - // create or destroy button - taskBar.bReplaceButton=bButton2; - - if (bButton2) - { - RecreateStartButton(it->first); - if (g_WinStartButton) - { - ShowWindow(g_WinStartButton,SW_HIDE); - SetWindowSubclass(g_WinStartButton,SubclassWin7StartButton,'CLSH',0); - if (GetWinVersion()==WIN_VER_WIN7) - { - // Windows 7 draws the start button on the taskbar as well - // so we zero out the bitmap resources - HMODULE hExplorer=GetModuleHandle(NULL); - for (int res=0;res<_countof(g_StartButtonOldSizes);res++) - { - HRSRC hrSrc=FindResource(hExplorer,MAKEINTRESOURCE(res+FIRST_BUTTON_BITMAP),RT_BITMAP); - if (hrSrc) - { - HGLOBAL hRes=LoadResource(hExplorer,hrSrc); - if (hRes) - { - void *pRes=LockResource(hRes); - if (pRes) - { - DWORD old; - BITMAPINFOHEADER *pHeader=(BITMAPINFOHEADER*)pRes; - if (pHeader->biWidth) - { - g_StartButtonOldSizes[res]=MAKELONG(pHeader->biWidth,pHeader->biHeight); - VirtualProtect(pRes,sizeof(BITMAPINFOHEADER),PAGE_READWRITE,&old); - pHeader->biHeight=pHeader->biWidth=0; - VirtualProtect(pRes,sizeof(BITMAPINFOHEADER),old,&old); - } - } - } - } - } - } - SendMessage(taskBar.taskBar,WM_SETTINGCHANGE,0,0); - } - } - else - { - if (taskBar.startButton && taskBar.startButton!=g_WinStartButton) - { - RevokeDragDrop(taskBar.startButton); - DestroyStartButton(taskBar.taskbarId); - } - taskBar.startButton=taskBar.taskBar==g_TaskBar?g_WinStartButton:NULL; - taskBar.startButtonSize.cx=taskBar.startButtonSize.cy=0; - if (g_WinStartButton && g_WinStartButton==taskBar.startButton) - { - // restore the bitmap sizes - HMODULE hExplorer=GetModuleHandle(NULL); - for (int res=0;res<_countof(g_StartButtonOldSizes);res++) - { - HRSRC hrSrc=FindResource(hExplorer,MAKEINTRESOURCE(res+FIRST_BUTTON_BITMAP),RT_BITMAP); - if (hrSrc) - { - HGLOBAL hRes=LoadResource(hExplorer,hrSrc); - if (hRes) - { - void *pRes=LockResource(hRes); - if (pRes) - { - DWORD old; - BITMAPINFOHEADER *pHeader=(BITMAPINFOHEADER*)pRes; - if (g_StartButtonOldSizes[res]) - { - VirtualProtect(pRes,sizeof(BITMAPINFOHEADER),PAGE_READWRITE,&old); - pHeader->biWidth=LOWORD(g_StartButtonOldSizes[res]); - pHeader->biHeight=HIWORD(g_StartButtonOldSizes[res]); - VirtualProtect(pRes,sizeof(BITMAPINFOHEADER),old,&old); - } - } - } - } - } - RemoveWindowSubclass(g_WinStartButton,SubclassWin7StartButton,'CLSH'); - SendMessage(g_WinStartButton,WM_THEMECHANGED,0,0); - ShowWindow(g_WinStartButton,SW_SHOW); - } - } - } - else if (update==TASKBAR_RECREATE_BUTTONS && bButton2) - { - RecreateStartButton(it->first); - } - if (taskBar.bCustomLook!=bCustomLook) - { - // set custom look - taskBar.bCustomLook=bCustomLook; - - if (!bCustomLook && GetWinVersion()second; - SendMessage(taskBar.taskBar,WM_SETTINGCHANGE,0,0); - InvalidateRect(taskBar.taskBar,NULL,TRUE); - PostMessage(taskBar.taskBar,WM_THEMECHANGED,0,0); - } -} - -/////////////////////////////////////////////////////////////////////////////// -// hooks for animating the start button - -typedef void (WINAPI *tDwmpBeginTransitionRequest)(int param); -typedef void (WINAPI *tDwmpTransitionWindowWithRects)(HWND,int,RECT*,RECT*,RECT*,RECT*,RECT*); -typedef void (WINAPI *tDwmpEndTransitionRequest)(int param); - -static IatHookData *g_DwmpBTRHook, *g_DwmpTWWRHook, *g_DwmpETRHook; - -static tDwmpBeginTransitionRequest g_DwmpBeginTransitionRequest; -static tDwmpTransitionWindowWithRects g_DwmpTransitionWindowWithRects; -static tDwmpEndTransitionRequest g_DwmpEndTransitionRequest; - -static HWND g_TransitionButton; -static HWND g_TransitionBar; -static RECT g_TransitionClip; -static POINT g_TransitionVector; -static bool g_bTransitionIn; - -void WINAPI DwmpBeginTransitionRequest2( int param ) -{ - g_TransitionButton=NULL; - ((tDwmpBeginTransitionRequest)g_DwmpBTRHook->oldProc)(param); -} - -void WINAPI DwmpTransitionWindowWithRects2( HWND hWnd, int flags, RECT *prcClient1, RECT *prcStart, RECT *prcClient2, RECT *prcEnd, RECT *prcClip ) -{ - g_TransitionButton=NULL; - const TaskbarInfo *taskBar=FindTaskBarInfoBar(hWnd); - if (taskBar && taskBar->bCustomLook) - { - g_TransitionBar=hWnd; - TTaskbarLook look=(TTaskbarLook)GetSettingInt(L"TaskbarLook"); - DWM_BLURBEHIND blur={DWM_BB_ENABLE,look==TASKBAR_OPAQUE}; - DwmEnableBlurBehindWindow(hWnd,&blur); - int data[4]; - ComputeTaskbarColors(data); - WINCOMPATTRDATA attrData={0x13,&data,sizeof(data)}; - SetWindowCompositionAttribute(hWnd,&attrData); - } - if (taskBar && taskBar->startButton && prcStart && prcEnd && prcClip) - { - g_TransitionButton=taskBar->startButton; - g_TransitionVector.x=prcEnd->left-prcStart->left; - g_TransitionVector.y=prcEnd->top-prcStart->top; - g_TransitionClip=*prcClip; - g_bTransitionIn=true; - switch (GetTaskbarPosition(taskBar->taskBar,NULL,NULL,NULL)) - { - case ABE_LEFT: - g_bTransitionIn=g_TransitionVector.x>0; - break; - case ABE_TOP: - g_bTransitionIn=g_TransitionVector.y>0; - break; - case ABE_RIGHT: - g_bTransitionIn=g_TransitionVector.x<0; - break; - default: - g_bTransitionIn=g_TransitionVector.y<0; - } - } - ((tDwmpTransitionWindowWithRects)g_DwmpTWWRHook->oldProc)(hWnd,flags,prcClient1,prcStart,prcClient2,prcEnd,prcClip); -} - -void WINAPI DwmpEndTransitionRequest2( int param ) -{ - ((tDwmpEndTransitionRequest)g_DwmpETRHook->oldProc)(param); - if (g_TransitionBar) - { - TTaskbarLook look=(TTaskbarLook)GetSettingInt(L"TaskbarLook"); - DWM_BLURBEHIND blur={DWM_BB_ENABLE,look==TASKBAR_OPAQUE}; - DwmEnableBlurBehindWindow(g_TransitionBar,&blur); - int data[4]; - ComputeTaskbarColors(data); - WINCOMPATTRDATA attrData={0x13,&data,sizeof(data)}; - SetWindowCompositionAttribute(g_TransitionBar,&attrData); - g_TransitionBar=NULL; - } - if (g_TransitionButton) - { - HWND button=g_TransitionButton; - g_TransitionButton=NULL; - g_DwmpBeginTransitionRequest(15); - RECT rcClient; - GetClientRect(button,&rcClient); - RECT rcStart, rcEnd; - if (g_bTransitionIn) - { - GetWindowRect(button,&rcEnd); - rcStart=rcEnd; - OffsetRect(&rcStart,-g_TransitionVector.x,-g_TransitionVector.y); - } - else - { - GetWindowRect(button,&rcStart); - rcEnd=rcStart; - int dx=0, dy=0; - if (g_TransitionVector.x<0) // left - { - dx=g_TransitionClip.left-rcStart.right; - if (dx>0) dx=g_TransitionVector.x; - } - else if (g_TransitionVector.x>0) // right - { - dx=g_TransitionClip.right-rcStart.left; - if (dx<0) dx=g_TransitionVector.x; - } - else if (g_TransitionVector.y<0) // top - { - dy=g_TransitionClip.top-rcStart.bottom; - if (dy>0) dy=g_TransitionVector.y; - } - else if (g_TransitionVector.y>0) // bottom - { - dy=g_TransitionClip.bottom-rcStart.top; - if (dy<0) dy=g_TransitionVector.y; - } - OffsetRect(&rcEnd,dx,dy); - } - g_DwmpTransitionWindowWithRects(button,0x21800046,&rcClient,&rcStart,&rcClient,&rcEnd,&g_TransitionClip); - g_DwmpEndTransitionRequest(15); - } -} - -/////////////////////////////////////////////////////////////////////////////// -// hooks for skinning the taskbar - -typedef void (WINAPI *tSHFillRectClr)(HDC hdc, const RECT *pRect, COLORREF color); - -static IatHookData *g_SHFillRectClrHook, *g_StretchDIBitsHook; -static IatHookData *g_DrawThemeBackgroundHook, *g_DrawThemeTextHook, *g_DrawThemeTextExHook, *g_DrawThemeTextCtlHook, *g_SetWindowCompositionAttributeHook; - -static tSHFillRectClr g_SHFillRectClr; - -static void WINAPI SHFillRectClr2( HDC hdc, const RECT *pRect, COLORREF color ) -{ - if (!g_CurrentTaskList || !g_TaskbarTexture || GetCurrentThreadId()!=g_TaskbarThreadId) - g_SHFillRectClr(hdc,pRect,color); -} - -static HRESULT STDAPICALLTYPE DrawThemeBackground2( HTHEME hTheme, HDC hdc, int iPartId, int iStateId, LPCRECT pRect, LPCRECT pClipRect ) -{ - if (g_CurrentTaskList && g_TaskbarTexture && iPartId==1 && iStateId==0 && GetCurrentThreadId()==g_TaskbarThreadId) - { - HWND taskbar=GetAncestor(g_CurrentTaskList,GA_ROOT); - RECT rcClient; - GetClientRect(taskbar,&rcClient); - MapWindowPoints(taskbar,g_CurrentTaskList,(POINT*)&rcClient,2); - PrintTaskbarBackground(hdc,rcClient,*pRect,0); - return S_OK; - } - if (g_CurrentDesktopButton && g_TaskbarTexture && GetCurrentThreadId()==g_TaskbarThreadId && hTheme==GetWindowTheme(g_CurrentDesktopButton)) - { - HWND taskbar=GetAncestor(g_CurrentDesktopButton,GA_ROOT); - RECT rcClient; - GetClientRect(taskbar,&rcClient); - MapWindowPoints(taskbar,g_CurrentDesktopButton,(POINT*)&rcClient,2); - UINT uEdge=GetTaskbarPosition(taskbar,NULL,NULL,NULL); - PrintTaskbarBackground(hdc,rcClient,*pRect,uEdge); - return DrawThemeBackground(hTheme,hdc,iPartId,iStateId,pRect,pClipRect); - } - return DrawThemeBackground(hTheme,hdc,iPartId,iStateId,pRect,pClipRect); -} - -// toolbar text, rebar band titles, clock -static HRESULT STDAPICALLTYPE DrawThemeText2( HTHEME hTheme, HDC hdc, int iPartId, int iStateId, LPCWSTR pszText, int iCharCount, DWORD dwTextFlags, DWORD dwTextFlags2, LPCRECT pRect ) -{ - if ((g_CurrentRebar || g_CurrentTaskbarPart) && GetCurrentThreadId()==g_TaskbarThreadId && GetSettingBool(L"CustomTaskbar")) - { - bool bDef; - COLORREF color=GetSettingInt(L"TaskbarTextColor",bDef)&0xFFFFFF; - if (!bDef) - { - // change the color for the toolbar titles, the toolbar buttons and the clock - DTTOPTS options={sizeof(options),DTT_TEXTCOLOR}; - options.crText=color; - return DrawThemeTextEx(hTheme,hdc,iPartId,iStateId,pszText,iCharCount,dwTextFlags,(RECT*)pRect,&options); - } - } - return DrawThemeText(hTheme,hdc,iPartId,iStateId,pszText,iCharCount,dwTextFlags,dwTextFlags2,pRect); -} - -// taskbar text -static HRESULT STDAPICALLTYPE DrawThemeTextEx2( HTHEME hTheme, HDC hdc, int iPartId, int iStateId, LPCWSTR pszText, int iCharCount, DWORD dwFlags, LPRECT pRect, const DTTOPTS *pOptions ) -{ - if ((g_CurrentTaskList || g_CurrentTaskbarPart) && GetCurrentThreadId()==g_TaskbarThreadId && GetSettingBool(L"CustomTaskbar")) - { - bool bDef; - COLORREF color=GetSettingInt(L"TaskbarTextColor",bDef)&0xFFFFFF; - if (!bDef) - { - // change the color dor the taskbar buttons - DTTOPTS options=*pOptions; - options.dwFlags|=DTT_TEXTCOLOR; - options.crText=color; - return DrawThemeTextEx(hTheme,hdc,iPartId,iStateId,pszText,iCharCount,dwFlags,pRect,&options); - } - } - return DrawThemeTextEx(hTheme,hdc,iPartId,iStateId,pszText,iCharCount,dwFlags,pRect,pOptions); -} - -static BLENDFUNCTION g_AlphaFunc={AC_SRC_OVER,0,255,AC_SRC_ALPHA}; - -static int WINAPI StretchDIBits2( HDC hdc, int xDest, int yDest, int DestWidth, int DestHeight, int xSrc, int ySrc, int SrcWidth, int SrcHeight, CONST VOID *lpBits, CONST BITMAPINFO *lpbmi, UINT iUsage, DWORD rop ) -{ - if ((g_CurrentTaskChevron || g_CurrentTaskbarButton) && g_TaskbarTexture && GetCurrentThreadId()==g_TaskbarThreadId) - { - HDC hsrc=CreateCompatibleDC(hdc); - BITMAPINFO bi={0}; - bi.bmiHeader.biSize=sizeof(BITMAPINFOHEADER); - bi.bmiHeader.biWidth=DestWidth; - bi.bmiHeader.biHeight=DestHeight; - bi.bmiHeader.biPlanes=1; - bi.bmiHeader.biBitCount=32; - HBITMAP bitmap=CreateDIBSection(hsrc,&bi,DIB_RGB_COLORS,NULL,NULL,0); - HGDIOBJ bmp0=SelectObject(hsrc,bitmap); - int res=StretchDIBits(hsrc,0,0,DestWidth,DestHeight,xSrc,ySrc,SrcWidth,SrcHeight,lpBits,lpbmi,iUsage,SRCCOPY); - AlphaBlend(hdc,xDest,yDest,DestWidth,DestHeight,hsrc,0,0,DestWidth,DestHeight,g_AlphaFunc); - SelectObject(hsrc,bmp0); - DeleteObject(bitmap); - DeleteDC(hsrc); - return res; - } - return StretchDIBits(hdc,xDest,yDest,DestWidth,DestHeight,xSrc,ySrc,SrcWidth,SrcHeight,lpBits,lpbmi,iUsage,rop); -} - -static BOOL WINAPI SetWindowCompositionAttribute2( HWND hwnd, WINCOMPATTRDATA *pAttrData ) -{ - if (pAttrData->attribute==0x13 && GetCurrentThreadId()==g_TaskbarThreadId) - { - const TaskbarInfo *taskBar=FindTaskBarInfoBar(hwnd); - if (taskBar && taskBar->bCustomLook) - { - int data[4]; - ComputeTaskbarColors(data); - WINCOMPATTRDATA attrData={0x13,&data,sizeof(data)}; - if (data[0]==3 && taskBar->bThemeChanging) - { - // send extra attribute when dealing with glass. without it the image behind the glass may not update when the taskbar is resized - SetWindowCompositionAttribute(hwnd,pAttrData); - } - return SetWindowCompositionAttribute(hwnd,&attrData); - } - } - return SetWindowCompositionAttribute(hwnd,pAttrData); -} - -/////////////////////////////////////////////////////////////////////////////// -// hooks for preventing shell hotkeys registration on Win11 - -using ShellRegisterHotKey_t = BOOL(WINAPI*)(HWND, int, UINT, UINT, HWND); - -static IatHookData* g_ShellRegisterHotKeyHook; -static ShellRegisterHotKey_t g_ShellRegisterHotKey; - -static BOOL WINAPI ShellRegisterHotKeyHook(HWND hWnd, int id, UINT fsModifiers, UINT vk, HWND hWndTarget) -{ - // Win key - if (fsModifiers == MOD_WIN && vk == 0) - return FALSE; - - // Ctrl+Esc - if (fsModifiers == MOD_CONTROL && vk == VK_ESCAPE) - return FALSE; - - return g_ShellRegisterHotKey(hWnd, id, fsModifiers, vk, hWndTarget); -} - -// one-time APC function to unregister shell hotkeys -void NTAPI DisableShellHotkeysFunc(ULONG_PTR Parameter) -{ - UnregisterHotKey(NULL, 1); - UnregisterHotKey(NULL, 2); -} - -/////////////////////////////////////////////////////////////////////////////// - -static void OpenCortana( void ) -{ - if (GetWinVersion()>=WIN_VER_WIN10) - ShellExecute(NULL,NULL,L"shell:::{2559a1f8-21d7-11d4-bdaf-00c04f60b9f0}",NULL,NULL,SW_SHOWNORMAL); -} - -static void InitStartMenuDLL( void ) -{ - LogToFile(STARTUP_LOG, L"StartMenu DLL: InitStartMenuDLL"); - WaitDllInitThread(); - - InitializeIatHooks(); - if (IsWin81Update1()) - { - HMODULE dwm=GetModuleHandle(L"dwmapi.dll"); - if (dwm) - { - g_DwmpBeginTransitionRequest=(tDwmpBeginTransitionRequest)GetProcAddress(dwm,MAKEINTRESOURCEA(138)); - g_DwmpTransitionWindowWithRects=(tDwmpTransitionWindowWithRects)GetProcAddress(dwm,MAKEINTRESOURCEA(141)); - g_DwmpEndTransitionRequest=(tDwmpEndTransitionRequest)GetProcAddress(dwm,MAKEINTRESOURCEA(140)); - if (g_DwmpBeginTransitionRequest && g_DwmpTransitionWindowWithRects && g_DwmpEndTransitionRequest) - { - g_DwmpBTRHook=SetIatHook(GetModuleHandle(NULL),"dwmapi.dll",MAKEINTRESOURCEA(138),DwmpBeginTransitionRequest2); - g_DwmpTWWRHook=SetIatHook(GetModuleHandle(NULL),"dwmapi.dll",MAKEINTRESOURCEA(141),DwmpTransitionWindowWithRects2); - g_DwmpETRHook=SetIatHook(GetModuleHandle(NULL),"dwmapi.dll",MAKEINTRESOURCEA(140),DwmpEndTransitionRequest2); - if (!g_DwmpBTRHook || !g_DwmpTWWRHook || !g_DwmpETRHook) - { - ClearIatHook(g_DwmpBTRHook); - g_DwmpBTRHook=NULL; - ClearIatHook(g_DwmpTWWRHook); - g_DwmpTWWRHook=NULL; - ClearIatHook(g_DwmpETRHook); - g_DwmpETRHook=NULL; - } - } - } - } - - if (GetSettingBool(L"CustomTaskbar")) - { - auto module=GetModuleHandle(L"taskbar.dll"); - if (!module) - module=GetModuleHandle(NULL); - - if (GetWinVersion()>=WIN_VER_WIN10) - { - HMODULE shlwapi=GetModuleHandle(L"shlwapi.dll"); - if (shlwapi) - { - g_SHFillRectClr=(tSHFillRectClr)GetProcAddress(shlwapi,MAKEINTRESOURCEA(197)); - if (g_SHFillRectClr) - { - g_SHFillRectClrHook=SetIatHook(module,"shlwapi.dll",MAKEINTRESOURCEA(197),SHFillRectClr2); - if (!g_SHFillRectClrHook) - g_SHFillRectClrHook=SetIatHook(module,"api-ms-win-shlwapi-winrt-storage-l1-1-1.dll",MAKEINTRESOURCEA(197),SHFillRectClr2); - } - } - g_StretchDIBitsHook=SetIatHook(module,"gdi32.dll","StretchDIBits",StretchDIBits2); - if (!g_StretchDIBitsHook) - g_StretchDIBitsHook=SetIatHook(module,"ext-ms-win-gdi-draw-l1-1-0.dll","StretchDIBits",StretchDIBits2); - } - - { - HWND dlg=CreateWindow(L"#32770",L"",WS_POPUP,0,0,0,0,NULL,0,0,0); - HWND toolbar=CreateWindow(TOOLBARCLASSNAME,L"",WS_CHILD|TBS_TOOLTIPS,0,0,0,0,dlg,0,0,0); - DestroyWindow(dlg); - } - - if (GetWinVersion()<=WIN_VER_WIN81) - g_DrawThemeBackgroundHook=SetIatHook(module,"uxtheme.dll","DrawThemeBackground",DrawThemeBackground2); - g_DrawThemeTextHook=SetIatHook(module,"uxtheme.dll","DrawThemeText",DrawThemeText2); - g_DrawThemeTextExHook=SetIatHook(module,"uxtheme.dll","DrawThemeTextEx",DrawThemeTextEx2); - g_DrawThemeTextCtlHook=SetIatHook(GetModuleHandle(L"comctl32.dll"),"uxtheme.dll","DrawThemeText",DrawThemeText2); - if (GetWinVersion()>=WIN_VER_WIN10) - g_SetWindowCompositionAttributeHook=SetIatHook(module,"user32.dll","SetWindowCompositionAttribute",SetWindowCompositionAttribute2); - } - - g_TaskbarThreadId=GetCurrentThreadId(); - g_bTrimHooks=GetWinVersion()==WIN_VER_WIN7 && (GetSettingInt(L"CompatibilityFixes")&COMPATIBILITY_TRIM_HOOKS); - InitManagers(false); - int level=GetSettingInt(L"CrashDump"); - if (level>=1 && level<=3) - { - if (level==1) MiniDumpType=MiniDumpNormal; - if (level==2) MiniDumpType=MiniDumpWithDataSegs; - if (level==3) MiniDumpType=MiniDumpWithFullMemory; - SetUnhandledExceptionFilter(TopLevelFilter); - _set_invalid_parameter_handler(InvalidParameterHandler); - g_bCrashDump=true; - } - FindTaskBar(); - g_ProgWin=FindWindowEx(NULL,NULL,L"Progman",NULL); - DWORD progThread=GetWindowThreadProcessId(g_ProgWin,NULL); - g_ProgHook=SetWindowsHookEx(WH_GETMESSAGE,HookProgManThread,NULL,progThread); - g_StartHook=SetWindowsHookEx(WH_GETMESSAGE,HookDesktopThread,NULL,GetCurrentThreadId()); - if (IsWin11()) - { - g_StartMouseHook=SetWindowsHookEx(WH_MOUSE,HookDesktopThreadMouse,NULL,GetCurrentThreadId()); - - // hook ShellRegisterHotKey to prevent twinui.dll to install shell hotkeys (Win, Ctrl+Esc) - // without these hotkeys there is standard WM_SYSCOMMAND+SC_TASKLIST sent when start menu is invoked by keyboard shortcut - g_ShellRegisterHotKey = (ShellRegisterHotKey_t)GetProcAddress(GetModuleHandle(L"user32.dll"), MAKEINTRESOURCEA(2671)); - auto twinui = GetModuleHandle(L"twinui.dll"); - - if (g_ShellRegisterHotKey && twinui) - { - g_ShellRegisterHotKeyHook = SetIatHook(twinui, "user32.dll" ,MAKEINTRESOURCEA(2671), ShellRegisterHotKeyHook); - - // unregister shell hotkeys as they may be registered already - // this has to be done from context of thread that registered them - auto hwnd = FindWindow(L"ApplicationManager_ImmersiveShellWindow", NULL); - if (hwnd) - { - auto thread = OpenThread(THREAD_SET_CONTEXT, FALSE, GetWindowThreadProcessId(hwnd, NULL)); - if (thread) - { - QueueUserAPC(DisableShellHotkeysFunc, thread, 0); - CloseHandle(thread); - } - } - } - } - - HWND hwnd=FindWindow(L"OpenShellMenu.CStartHookWindow",L"StartHookWindow"); - LoadLibrary(L"StartMenuDLL.dll"); // keep the DLL from unloading - if (hwnd) PostMessage(hwnd,WM_CLEAR,0,0); // tell the exe to unhook this hook - if (GetWinVersion()>=WIN_VER_WIN8) - { - SetWindowCompositionAttribute=(tSetWindowCompositionAttribute)GetProcAddress(GetModuleHandle(L"user32.dll"),"SetWindowCompositionAttribute"); - } - int taskbarId=g_NextTaskbar++; - TaskbarInfo &taskBar=g_TaskbarInfos[taskbarId]; - taskBar.taskBar=g_TaskBar; - taskBar.taskbarId=taskbarId; - taskBar.rebar=FindWindowEx(g_TaskBar,NULL,REBARCLASSNAME,NULL); - if (taskBar.rebar) - { - SetWindowSubclass(taskBar.rebar,SubclassRebarProc,'CLSH',taskbarId); - // TaskBand window - HWND hwnd=FindWindowEx(taskBar.rebar,NULL,L"MSTaskSwWClass",NULL); - if (hwnd) - { - taskBar.taskList=hwnd; - // TaskList window - // it has to be visible, otherwise it won't receive WM_PAINT that we need to intercept - // in such case we will intercept parent instead - hwnd=FindWindowEx(hwnd,NULL,L"MSTaskListWClass",NULL); - if (hwnd&&IsWindowVisible(hwnd)) - taskBar.taskList=hwnd; - } - if (taskBar.taskList) - SetWindowSubclass(taskBar.taskList,SubclassTaskListProc,'CLSH',taskbarId); - } - if (GetWinVersion()>WIN_VER_WIN8) - { - taskBar.oldButton=FindWindowEx(taskBar.taskBar,NULL,L"Start",NULL); - if (taskBar.oldButton) - { - if (GetWinVersion()>=WIN_VER_WIN10) - { - taskBar.pOriginalTarget=(IDropTarget*)GetProp(taskBar.oldButton,L"OleDropTargetInterface"); - if (taskBar.pOriginalTarget) - RevokeDragDrop(taskBar.oldButton); - } - - CStartMenuTarget *pNewTarget=new CStartMenuTarget(taskBar.taskbarId); - RegisterDragDrop(taskBar.oldButton,pNewTarget); - pNewTarget->Release(); - if (GetWinVersion()=WIN_VER_WIN10) - { - for (HWND button=FindWindowEx(g_TaskBar,NULL,L"TrayButton",NULL);button;button=FindWindowEx(g_TaskBar,button,L"TrayButton",NULL)) - { - taskBar.trayButtons.push_back(button); - SetWindowSubclass(button,SubclassTrayButtonProc,'CLSH',taskBar.taskbarId); - } - HWND search=FindWindowEx(g_TaskBar,NULL,L"TrayDummySearchControl",NULL); - if (search) - { - taskBar.trayButtons.push_back(search); - SetWindowSubclass(search,SubclassTrayButtonProc,'CLSH',taskBar.taskbarId); - } - HWND tray=FindWindowEx(g_TaskBar,NULL,L"TrayNotifyWnd",NULL); - if (tray) - taskBar.chevron=FindWindowEx(tray,NULL,L"Button",NULL); - if (taskBar.chevron) - SetWindowSubclass(taskBar.chevron,SubclassTrayChevronProc,'CLSH',taskBar.taskbarId); - } - - HandleTaskbarParts(taskBar,true); -if (!g_bTrimHooks) - SetWindowSubclass(taskBar.taskBar,SubclassTaskBarProc,'CLSH',taskbarId); - taskBar.startButton=g_WinStartButton; - -#ifdef HOOK_DROPTARGET - if (g_WinStartButton) - { - g_pOriginalTarget=(IDropTarget*)GetProp(g_WinStartButton,L"OleDropTargetInterface"); - if (g_pOriginalTarget) - RevokeDragDrop(g_WinStartButton); - - CStartMenuTarget *pNewTarget=new CStartMenuTarget(taskbarId); - RegisterDragDrop(g_WinStartButton,pNewTarget); - pNewTarget->Release(); - } -#endif - - if (GetWinVersion()>=WIN_VER_WIN8) - { - g_pAppVisibility.CoCreateInstance(CLSID_MetroMode); - if (g_pAppVisibility) - { - CMonitorModeEvents *monitor=new CMonitorModeEvents(); - g_pAppVisibility->Advise(monitor,&g_AppVisibilityMonitorCookie); - monitor->Release(); - } - if (GetWinVersion()second; - if (taskbarId>=0 && taskBar.taskbarId!=taskbarId) - continue; - if (taskBar.bRecreatingButton) - continue; - - taskBar.bRecreatingButton=true; - { - if (taskBar.startButton && taskBar.startButton!=g_WinStartButton) - { - RevokeDragDrop(taskBar.startButton); - DestroyStartButton(taskBar.taskbarId); - } - taskBar.startButton=CreateStartButton(taskBar.taskbarId,taskBar.taskBar,taskBar.rebar); - CStartMenuTarget *pNewTarget=new CStartMenuTarget(taskBar.taskbarId); - RegisterDragDrop(taskBar.startButton,pNewTarget); - pNewTarget->Release(); - } - taskBar.bRecreatingButton=false; - - taskBar.startButtonSize=GetStartButtonSize(taskBar.taskbarId); - if (taskBar.oldButton) - { - RECT rc; - GetWindowRect(taskBar.oldButton,&rc); - taskBar.oldButtonSize.cx=rc.right-rc.left; - taskBar.oldButtonSize.cy=rc.bottom-rc.top; - } - - RECT rcTask; - GetWindowRect(taskBar.taskBar,&rcTask); - PostMessage(taskBar.taskBar,WM_SIZE,SIZE_RESTORED,MAKELONG(rcTask.right-rcTask.left,rcTask.bottom-rcTask.top)); - for (auto btn : taskBar.trayButtons) - { - RECT rc; - GetWindowRect(btn,&rc); - SetWindowPos(btn,HWND_TOP,rc.left,rc.top,0,0,SWP_NOSIZE|SWP_NOACTIVATE|SWP_NOZORDER); - } - } -} - -static DWORD WINAPI ExitThreadProc( void *param ) -{ - Sleep(1000); // wait a second! hopefully by then the hooks will be finished and no more of our code will be executing - // send WM_CLOSE to the window in StartMenu.exe to close that process - if (param) PostMessage((HWND)param,WM_CLOSE,0,0); - FreeLibraryAndExitThread(g_Instance,0); -} - -static void CleanStartMenuDLL( void ) -{ - ClearIatHook(g_DwmpBTRHook); - g_DwmpBTRHook=NULL; - ClearIatHook(g_DwmpTWWRHook); - g_DwmpTWWRHook=NULL; - ClearIatHook(g_DwmpETRHook); - g_DwmpETRHook=NULL; - ClearIatHook(g_SHFillRectClrHook); - g_SHFillRectClrHook=NULL; - ClearIatHook(g_StretchDIBitsHook); - g_StretchDIBitsHook=NULL; - - ClearIatHook(g_DrawThemeBackgroundHook); - g_DrawThemeBackgroundHook=NULL; - ClearIatHook(g_DrawThemeTextHook); - g_DrawThemeTextHook=NULL; - ClearIatHook(g_DrawThemeTextExHook); - g_DrawThemeTextExHook=NULL; - ClearIatHook(g_DrawThemeTextCtlHook); - g_DrawThemeTextCtlHook=NULL; - ClearIatHook(g_SetWindowCompositionAttributeHook); - g_SetWindowCompositionAttributeHook=NULL; - ClearIatHook(g_ShellRegisterHotKeyHook); - g_ShellRegisterHotKeyHook=NULL; - - CloseManagers(false); - ClearIatHooks(); - - // cleanup - if (g_Owner.m_hWnd) g_Owner.DestroyWindow(); - CloseSettings(); - CMenuContainer::CloseStartMenu(); - CMenuFader::ClearAll(); - UnhookDropTarget(); - EnableHotkeys(HOTKEYS_CLEAR); - HWND hwnd=FindWindow(L"OpenShellMenu.CStartHookWindow",L"StartHookWindow"); - UnhookWindowsHookEx(g_ProgHook); - UnhookWindowsHookEx(g_StartHook); - if (g_StartMouseHook) UnhookWindowsHookEx(g_StartMouseHook); - g_StartMouseHook=NULL; - if (g_AppManagerHook) UnhookWindowsHookEx(g_AppManagerHook); - g_AppManagerHook=NULL; - if (g_NewWindowHook) UnhookWindowsHookEx(g_NewWindowHook); - g_NewWindowHook=NULL; - if (g_pAppVisibility) - { - g_pAppVisibility->Unadvise(g_AppVisibilityMonitorCookie); - g_pAppVisibility=NULL; - } - ResetHotCorners(); - UpdateTaskBars(TASKBAR_CLEAR); - g_WinStartButton=NULL; - for (id_taskbar_map::const_iterator it=g_TaskbarInfos.begin();it!=g_TaskbarInfos.end();++it) - { - if (it->second.rebar) - RemoveWindowSubclass(it->second.rebar,SubclassRebarProc,'CLSH'); - if (it->second.taskList) - RemoveWindowSubclass(it->second.taskList,SubclassTaskListProc,'CLSH'); - if (it->second.oldButton) - { - RemoveWindowSubclass(it->second.oldButton,SubclassWin81StartButton,'CLSH'); - if (GetWinVersion()second.taskBar,NULL,NULL,NULL)==ABE_BOTTOM) - SetWindowPos(it->second.oldButton,NULL,0,0,0,0,SWP_NOSIZE|SWP_NOZORDER); - RevokeDragDrop(it->second.oldButton); - if (it->second.pOriginalTarget) - RegisterDragDrop(it->second.oldButton,it->second.pOriginalTarget); - } -if (!g_bTrimHooks) - RemoveWindowSubclass(it->second.taskBar,SubclassTaskBarProc,'CLSH'); - for (std::vector::const_iterator it2=it->second.trayButtons.begin();it2!=it->second.trayButtons.end();++it2) - { - RemoveWindowSubclass(*it2,SubclassTrayButtonProc,'CLSH'); - } - for (std::vector::const_iterator it2=it->second.taskbarParts.begin();it2!=it->second.taskbarParts.end();++it2) - { - RemoveWindowSubclass(*it2,SubclassTaskbarPartProc,'CLSH'); - } - if (it->second.chevron) - RemoveWindowSubclass(it->second.chevron,SubclassTrayChevronProc,'CLSH'); - if (it->second.desktop) - RemoveWindowSubclass(it->second.desktop,SubclassDesktopButtonProc,'CLSH'); - if (it->second.bTimer) - KillTimer(it->second.startButton,'CLSM'); - RECT rcTask; - GetWindowRect(it->second.taskBar,&rcTask); - PostMessage(it->second.taskBar,WM_SIZE,SIZE_RESTORED,MAKELONG(rcTask.right-rcTask.left,rcTask.bottom-rcTask.top)); - PostMessage(it->second.taskBar,WM_THEMECHANGED,0,0); - } - g_TaskbarInfos.clear(); - if (g_TopWin7Menu) - { - RemoveWindowSubclass(g_UserPic,SubclassUserPicProc,'CLSH'); - RemoveWindowSubclass(g_TopWin7Menu,SubclassTopMenuProc,'CLSH'); - RemoveWindowSubclass(g_AllPrograms,SubclassProgramsProc,'CLSH'); - } - if (g_bCrashDump) - { - SetUnhandledExceptionFilter(NULL); - g_bCrashDump=false; - } - - // we need to unload the DLL here. but we can't just call FreeLibrary because it will unload the code - // while it is still executing. So we create a separate thread and use FreeLibraryAndExitThread - CreateThread(NULL,0,ExitThreadProc,(void*)hwnd,0,NULL); -} - -/////////////////////////////////////////////////////////////////////////////// - - -static BOOL CALLBACK FindImmersiveWindows( HWND hwnd, LPARAM lParam ) -{ - wchar_t name[100]; - GetClassName(hwnd,name,_countof(name)); - if (wcscmp(name,L"ImmersiveLauncher")==0) - ((HWND*)lParam)[0]=hwnd; - if (wcscmp(name,L"ImmersiveBackgroundWindow")==0) - ((HWND*)lParam)[1]=hwnd; - if (wcscmp(name,L"SearchPane")==0) - ((HWND*)lParam)[2]=hwnd; - return TRUE; -} - -static bool WindowsMenuOpened( void ) -{ - FindWindowsMenu(); - CComPtr pImmersiveShell; - if (GetWinVersion()>=WIN_VER_WIN10 && CreateImmersiveShell(pImmersiveShell)) - { - { - CComPtr pLauncher; - IUnknown_QueryService(pImmersiveShell,SID_ImmersiveLauncher,IID_IImmersiveLauncher81,(void**)&pLauncher); - BOOL bIsVisible; - if (pLauncher && SUCCEEDED(pLauncher->IsVisible(&bIsVisible))) - return bIsVisible!=0; - } - { - CComPtr pLauncher; - IUnknown_QueryService(pImmersiveShell,SID_ImmersiveLauncher,IID_IImmersiveLauncher10RS,(void**)&pLauncher); - BOOL bIsVisible; - if (pLauncher && SUCCEEDED(pLauncher->IsVisible(&bIsVisible))) - return bIsVisible!=0; - } - } - if (GetWinVersion()>=WIN_VER_WIN8) - { - return GetMetroMode(NULL)!=METRO_NONE; - } - else - { - return g_TopWin7Menu && IsWindowVisible(g_TopWin7Menu); - } -} - -static void OpenStartScreen( HMONITOR monitor ) -{ - CComPtr pImmersiveShell; - if (CreateImmersiveShell(pImmersiveShell)) - { - CComPtr pMonitor; - if (GetWinVersion()==WIN_VER_WIN8) - { - if (monitor) - { - CComPtr pMonitorService; - IUnknown_QueryService(pImmersiveShell,SID_IImmersiveMonitorService,IID_IImmersiveMonitorService,(void**)&pMonitorService); - if (pMonitorService) - { - CComPtr pMonitor; - pMonitorService->GetFromHandle(monitor,&pMonitor); - if (pMonitor) - pMonitorService->SetImmersiveMonitor(pMonitor); - } - } - CComPtr pLauncher; - IUnknown_QueryService(pImmersiveShell,SID_ImmersiveLauncher,IID_IImmersiveLauncher80,(void**)&pLauncher); - if (pLauncher) - pLauncher->ShowStartView(5); - return; - } - if (monitor) - { - CComPtr pMonitorService; - IUnknown_QueryService(pImmersiveShell,SID_IImmersiveMonitorService,IID_IImmersiveMonitorService,(void**)&pMonitorService); - if (pMonitorService) - pMonitorService->GetFromHandle(monitor,&pMonitor); - } - { - CComPtr pLauncher; - IUnknown_QueryService(pImmersiveShell,SID_ImmersiveLauncher,IID_IImmersiveLauncher81,(void**)&pLauncher); - if (pLauncher) - { - if (pMonitor) - pLauncher->ConnectToMonitor(pMonitor); - HRESULT hr=pLauncher->ShowStartView(GetWinVersion()>=WIN_VER_WIN10?11:5,0); - return; - } - } - { - CComPtr pLauncher; - IUnknown_QueryService(pImmersiveShell,SID_ImmersiveLauncher,IID_IImmersiveLauncher10RS,(void**)&pLauncher); - if (pLauncher) - { - if (pMonitor) - pLauncher->ConnectToMonitor(pMonitor); - HRESULT hr=pLauncher->ShowStartView(GetWinVersion()>=WIN_VER_WIN10?11:5,0); - return; - } - } - } - else if (g_AppManagerThread) - PostThreadMessage(g_AppManagerThread,g_StartMenuMsg,MSG_SHIFTWIN,(LPARAM)monitor); -} - -// WH_GETMESSAGE hook for the Progman window -static LRESULT CALLBACK HookProgManThread( int code, WPARAM wParam, LPARAM lParam ) -{ - if (code==HC_ACTION && wParam) - { - MSG *msg=(MSG*)lParam; - if (msg->message==WM_SYSCOMMAND && (msg->wParam&0xFFF0)==SC_TASKLIST) - { - if (GetWinVersion()message=WM_NULL; - // Win button pressed - if (msg->lParam=='WSMK' || msg->lParam=='WSMM' || msg->lParam=='WSMH') - { - if ((g_AppManagerThread || GetWinVersion()>=WIN_VER_WIN10) && (msg->lParam=='WSMM' || msg->lParam=='WSMH' || (g_TaskbarInfos.size()>1 && GetSettingBool(L"OpenMouseMonitor")))) - { - if (!WindowsMenuOpened()) - { - HMONITOR monitor=msg->lParam=='WSMH'?g_WSMHMonitor:MonitorFromPoint(CPoint(GetMessagePos()),MONITOR_DEFAULTTONULL); - OpenStartScreen(monitor); - msg->message=WM_NULL; - } - } - } - else if (msg->lParam=='CSM') - { - msg->message=WM_NULL; - PostMessage(g_TaskBar,g_StartMenuMsg,MSG_TOGGLE,0); - } - else - { - FindTaskBar(); - int control=GetSettingInt(L"WinKey"); - if (control==OPEN_BOTH) - { - if (GetWinVersion()>=WIN_VER_WIN10) - control=GetWin10TabletMode()?OPEN_WINDOWS:OPEN_CLASSIC; - else - control=GetMetroMode(MonitorFromPoint(CPoint(GetMessagePos()),MONITOR_DEFAULTTONEAREST))?OPEN_WINDOWS:OPEN_CLASSIC; - } - if (control==OPEN_DESKTOP) - { - TMetroMode metro=GetMetroMode(MonitorFromPoint(CPoint(GetMessagePos()),MONITOR_DEFAULTTONEAREST)); - if (metro==METRO_NONE) - control=OPEN_CLASSIC; - else if (metro==METRO_APP) - control=OPEN_WINDOWS; - else - { - msg->message=WM_NULL; - SetForegroundWindow(GetDefaultTaskbarInfo()->taskBar); - } - } - - if (control==OPEN_WINDOWS) - { - FindWindowsMenu(); - if (g_TopWin7Menu && WindowsMenuOpened()) - { - const TaskbarInfo *taskBar=GetDefaultTaskbarInfo(); - SetForegroundWindow(taskBar->startButton?taskBar->startButton:taskBar->taskBar); - msg->message=WM_NULL; - } - else if (GetWinVersion()>=WIN_VER_WIN8 && g_TaskbarInfos.size()>1 && GetSettingBool(L"OpenMouseMonitor") && !WindowsMenuOpened()) - { - HMONITOR monitor=MonitorFromPoint(CPoint(GetMessagePos()),MONITOR_DEFAULTTONULL); - OpenStartScreen(monitor); - msg->message=WM_NULL; - } - else - { - PostMessage(g_TaskBar,g_StartMenuMsg,MSG_NOP,0); - } - } - else - { - msg->message=WM_NULL; - if (control==OPEN_CLASSIC) - PostMessage(g_TaskBar,g_StartMenuMsg,MSG_TOGGLE,0); - else if (control==OPEN_CUSTOM) - { - CString commandText=GetSettingString(L"WinKeyCommand"); - if (!commandText.IsEmpty()) - { - wchar_t expandedCommand[_MAX_PATH]{}; - ::ExpandEnvironmentStrings(commandText, expandedCommand, _countof(expandedCommand)); - ShellExecute(NULL,NULL,expandedCommand,NULL,NULL,SW_SHOWNORMAL); - } - } - } - } - } - if ((msg->message==WM_MOUSEMOVE || msg->message==WM_LBUTTONDOWN) && GetWinVersion()>=WIN_VER_WIN8 && HIWORD(msg->lParam)<10 && GetSettingInt(L"DisableHotCorner")==2) - { - if (msg->hwnd!=g_TopDesktopBar || !g_TopDesktopBar || !IsWindow(g_TopDesktopBar)) - { - wchar_t name[100]; - if (!GetClassName(msg->hwnd,name,_countof(name)) || _wcsicmp(name,L"WorkerW")!=0) - return CallNextHookEx(NULL,code,wParam,lParam); - HWND parent=GetParent(msg->hwnd); - if (parent!=g_ProgWin && !FindWindowEx(parent,NULL,L"SHELLDLL_DefView",NULL)) - return CallNextHookEx(NULL,code,wParam,lParam); - g_EdgeWindows.erase(g_TopDesktopBar); - g_TopDesktopBar=msg->hwnd; - } - g_EdgeWindows.insert(g_TopDesktopBar); - ShowWindow(g_TopDesktopBar,SW_HIDE); - msg->message=WM_NULL; - } - } - return CallNextHookEx(NULL,code,wParam,lParam); -} - -// WH_MOUSE hook for taskbar thread (Win11+) -static LRESULT CALLBACK HookDesktopThreadMouse(int code, WPARAM wParam, LPARAM lParam) -{ - if (code == HC_ACTION) - { - // we need to steal mouse messages that are issues in start button area - // so that they won't get to XAML framework that is handling original start button - auto info = (const MOUSEHOOKSTRUCT*)lParam; - { - auto taskBar = FindTaskBarInfoButton(info->hwnd); // click on start button - if (!taskBar) - { - taskBar = FindTaskBarInfoBar(GetAncestor(info->hwnd, GA_ROOT)); // click on taskbar - if (taskBar && !PointAroundStartButton(taskBar->taskbarId)) - taskBar = NULL; - } - - if (taskBar && (info->hwnd != taskBar->startButton) && taskBar->oldButton) - { - // steal messages from other than our custom button window - PostMessage(taskBar->oldButton, (UINT)wParam, 0, MAKELPARAM(info->pt.x, info->pt.y)); - return 1; - } - } - } - - return CallNextHookEx(NULL, code, wParam, lParam); -} - -// WH_GETMESSAGE hook for the taskbar thread -static LRESULT CALLBACK HookDesktopThread( int code, WPARAM wParam, LPARAM lParam ) -{ - if (code==HC_ACTION && wParam && !g_bInMenu) - { - MSG *msg=(MSG*)lParam; - FindTaskBar(); - if (IsSettingsMessage(msg)) - { - msg->message=WM_NULL; - return 0; - } -if (!g_bTrimHooks) -{ - if (((msg->message>=WM_MOUSEFIRST && msg->message<=WM_MOUSELAST) || msg->message==WM_MOUSEHOVER || msg->message==WM_MOUSELEAVE) && GetWinVersion()<=WIN_VER_WIN7 && CMenuContainer::ProcessMouseMessage(msg->hwnd,msg->message,msg->wParam,msg->lParam)) - { - msg->message=WM_NULL; - return 0; - } -} - if (msg->message==g_StartMenuMsg && msg->hwnd==g_TaskBar) - { - msg->message=WM_NULL; - static bool bProcessing; // prevent reentry - if (!bProcessing) - { - FindWindowsMenu(); - bProcessing=true; - if (msg->wParam==MSG_TOGGLE || (msg->wParam==MSG_OPEN && !CMenuContainer::IsMenuOpened())) - { - const TaskbarInfo *taskBar=GetDefaultTaskbarInfo(); - ToggleStartMenu(taskBar->taskbarId,true); - } - else if (msg->wParam==MSG_TOGGLENEW) - { - PostMessage(g_ProgWin,WM_SYSCOMMAND,SC_TASKLIST,'WSMK'); - } - else if (msg->wParam==MSG_SETTINGS) - { - if (GetSettingBool(L"EnableSettings")) - EditSettings(false,0); - } - else if (msg->wParam==MSG_SHIFTWIN) - { - const TaskbarInfo *taskBar=GetDefaultTaskbarInfo(); - int control=GetSettingInt(L"ShiftWin"); - if (control==OPEN_BOTH) - { - if (GetWinVersion()>=WIN_VER_WIN10) - control=GetWin10TabletMode()?OPEN_WINDOWS:OPEN_CLASSIC; - else - control=GetMetroMode(MonitorFromPoint(CPoint(GetMessagePos()),MONITOR_DEFAULTTONEAREST))?OPEN_WINDOWS:OPEN_CLASSIC; - } - if (control==OPEN_CLASSIC) - ToggleStartMenu(taskBar->taskbarId,true); - else if (control==OPEN_WINDOWS) - PostMessage(g_ProgWin,WM_SYSCOMMAND,SC_TASKLIST,'WSMK'); - else if (control==OPEN_CORTANA) - OpenCortana(); - else if (control==OPEN_CUSTOM) - { - CString commandText=GetSettingString(L"ShiftWinCommand"); - if (!commandText.IsEmpty()) - { - wchar_t expandedCommand[_MAX_PATH]{}; - ::ExpandEnvironmentStrings(commandText, expandedCommand, _countof(expandedCommand)); - ShellExecute(NULL,NULL,expandedCommand,NULL,NULL,SW_SHOWNORMAL); - } - } - } - else if (msg->wParam==MSG_DRAG || msg->wParam==MSG_SHIFTDRAG) - { - const TaskbarInfo *taskBar=GetTaskbarInfo((int)msg->lParam); - if (taskBar) - { - int control=GetSettingInt((msg->wParam==MSG_DRAG)?L"MouseClick":L"ShiftClick"); - if (control==OPEN_BOTH && GetWinVersion()>=WIN_VER_WIN10) - control=GetWin10TabletMode()?OPEN_WINDOWS:OPEN_CLASSIC; - if (control==OPEN_CLASSIC || (control==OPEN_WINDOWS && GetWinVersion()>=WIN_VER_WIN8)) - ToggleStartMenu(taskBar->taskbarId,true); - else if (control==OPEN_WINDOWS) - PostMessage(g_ProgWin,WM_SYSCOMMAND,SC_TASKLIST,'WSMM'); - } - } - else if (msg->wParam==MSG_EXIT && CMenuContainer::CanShowMenu()) - { - LRESULT res=CallNextHookEx(NULL,code,wParam,lParam); - CleanStartMenuDLL(); - return res; // we should exit as quickly as possible now. the DLL is about to be unloaded - } - else if (msg->wParam==MSG_HOTKEYS) - { - EnableHotkeys((THotkeys)msg->lParam); - } - else if (msg->wParam==MSG_NEWTASKBAR) - { - HWND child=(HWND)msg->lParam; - if (IsWindow(child)) - { - wchar_t className[100]; - GetClassName(child,className,_countof(className)); - if (_wcsicmp(className,L"Shell_SecondaryTrayWnd")==0) - HandleSecondaryTaskbar((HWND)msg->lParam); - else if (_wcsicmp(className,L"ToolbarWindow32")==0) - { - HWND taskbar=GetAncestor(child,GA_ROOT); - TaskbarInfo *info=FindTaskBarInfoBar(taskbar); - if (info && !info->HasPart(child) && GetParent(child)==info->rebar) - { - SetWindowSubclass(child,SubclassTaskbarPartProc,'CLSH',info->taskbarId); - info->taskbarParts.push_back(child); - } - } - else if (_wcsicmp(className,L"TrayClockWClass")==0 || _wcsicmp(className,L"ClockButton")==0) - { - HWND taskbar=GetAncestor(child,GA_ROOT); - TaskbarInfo *info=FindTaskBarInfoBar(taskbar); - if (info && !info->HasPart(child)) - { - SetWindowSubclass(child,SubclassTaskbarPartProc,'CLSH',info->taskbarId); - info->taskbarParts.push_back(child); - } - } - } - } - else if (msg->wParam==MSG_REDRAWTASKBAR) - { - if (msg->lParam) - InvalidateRect((HWND)msg->lParam,NULL,TRUE); - else - RedrawTaskbars(); - } - else if (msg->wParam==MSG_RELOADSETTINGS) - { - LoadSettings(); - UpdateTaskBars(TASKBAR_RECREATE_BUTTONS); - UpdateTaskBars(TASKBAR_UPDATE_TEXTURE); - ResetHotCorners(); - RedrawTaskbars(); - } - bProcessing=false; - } - } -if (!g_bTrimHooks) -{ - if (msg->message==WM_HOTKEY && msg->hwnd==g_TaskBar) - { - if (msg->wParam==g_HotkeyShiftID) - PostMessage(g_TaskBar,g_StartMenuMsg,MSG_SHIFTWIN,0); - else if (msg->wParam==g_HotkeyCSMID) - { - msg->message=WM_NULL; - const TaskbarInfo *taskBar=GetDefaultTaskbarInfo(); - if (taskBar->startButton) - SetForegroundWindow(taskBar->startButton); - ToggleStartMenu(taskBar->taskbarId,true); - } - else if (msg->wParam==g_HotkeyWSMID) - PostMessage(g_ProgWin,WM_SYSCOMMAND,SC_TASKLIST,'WSMK'); - } - - if (msg->message==WM_KEYDOWN && msg->hwnd==g_TaskBar && (msg->wParam==VK_SPACE || msg->wParam==VK_RETURN)) - { - GUITHREADINFO info={sizeof(info)}; - if (!GetGUIThreadInfo(GetCurrentThreadId(),&info) || !(info.flags&GUI_INMENUMODE)) - { - FindWindowsMenu(); - int control=GetSettingInt(L"WinKey"); - if (control==OPEN_BOTH) - { - if (GetWinVersion()>=WIN_VER_WIN10) - control=GetWin10TabletMode()?OPEN_WINDOWS:OPEN_CLASSIC; - else - control=GetMetroMode(MonitorFromWindow(g_TaskBar,MONITOR_DEFAULTTONEAREST))?OPEN_WINDOWS:OPEN_CLASSIC; - } - if (control==OPEN_CLASSIC) - { - msg->message=WM_NULL; - const TaskbarInfo *taskBar=FindTaskBarInfoBar(g_TaskBar); - if (taskBar->startButton) - SetForegroundWindow(taskBar->startButton); - ToggleStartMenu(taskBar->taskbarId,true); - } - } - } - - if (msg->message==WM_KEYDOWN && msg->wParam==VK_TAB && CMenuContainer::IsMenuWindow(msg->hwnd)) - { - // the taskbar steals the Tab key. we need to forward it to the menu instead - SendMessage(msg->hwnd,msg->message,msg->wParam,msg->lParam); - msg->message=WM_NULL; - } - - if (msg->message==WM_SYSKEYDOWN && msg->wParam==VK_RETURN && CMenuContainer::IsMenuWindow(msg->hwnd)) - { - // the taskbar steals the Alt+Enter key. we need to forward it to the menu instead - SendMessage(msg->hwnd,msg->message,msg->wParam,msg->lParam); - msg->message=WM_NULL; - } -} - bool bClick=(msg->message==WM_LBUTTONDOWN || msg->message==WM_LBUTTONDBLCLK || msg->message==WM_MBUTTONDOWN || msg->message==WM_MBUTTONDBLCLK); - bool bNcClick=(msg->message==WM_NCLBUTTONDOWN || msg->message==WM_NCLBUTTONDBLCLK || msg->message==WM_NCMBUTTONDOWN || msg->message==WM_NCMBUTTONDBLCLK); - bool bMiddle=(msg->message==WM_NCMBUTTONDOWN || msg->message==WM_MBUTTONDOWN || msg->message==WM_NCMBUTTONDBLCLK || msg->message==WM_MBUTTONDBLCLK); - if (bClick || bNcClick) - { - const TaskbarInfo *taskBar=NULL; - if (bClick) - taskBar=FindTaskBarInfoButton(msg->hwnd); // click on start button - if (!taskBar) - { - taskBar=FindTaskBarInfoBar(msg->hwnd); // click on taskbar - if (taskBar && !PointAroundStartButton(taskBar->taskbarId)) - taskBar=NULL; - } - if (taskBar) - { - if (msg->message==WM_LBUTTONDOWN && GetWinVersion()==WIN_VER_WIN7 && msg->hwnd==taskBar->startButton) - { - // on Win7 ignore the click if the mouse is not over the start button (clicks on the context menu are sent to the start button) - CPoint pt(GetMessagePos()); - if (WindowFromPoint(pt)!=msg->hwnd) - { - return CallNextHookEx(NULL,code,wParam,lParam); - } - } - // left or middle click on start button - FindWindowsMenu(); - const wchar_t *name; - const wchar_t *command; - if (bMiddle) - { - name=L"MiddleClick"; - command=L"MiddleClickCommand"; - } - else if (GetKeyState(VK_SHIFT)<0) - { - name=L"ShiftClick"; - command=L"ShiftClickCommand"; - } - else - { - name=L"MouseClick"; - command=L"MouseClickCommand"; - } - - int control=GetSettingInt(name); - if (control==OPEN_BOTH && GetWinVersion()>=WIN_VER_WIN10) - control=GetWin10TabletMode()?OPEN_WINDOWS:OPEN_CLASSIC; - if (control==OPEN_CLASSIC) - { - // click on the start button - toggle the menu - DWORD keyboard; - SystemParametersInfo(SPI_GETKEYBOARDCUES,NULL,&keyboard,0); - ToggleStartMenu(taskBar->taskbarId,keyboard!=0); - } - else if (control==OPEN_WINDOWS) - PostMessage(g_ProgWin,WM_SYSCOMMAND,SC_TASKLIST,'WSMM'); - else if (control==OPEN_CORTANA) - OpenCortana(); - else if (control==OPEN_CUSTOM) - { - CString commandText=GetSettingString(command); - if (!commandText.IsEmpty()) - { - wchar_t expandedCommand[_MAX_PATH]{}; - ::ExpandEnvironmentStrings(commandText, expandedCommand, _countof(expandedCommand)); - ShellExecute(NULL,NULL,expandedCommand,NULL,NULL,SW_SHOWNORMAL); - } - } - msg->message=WM_NULL; - } - } - - if (msg->message==WM_LBUTTONUP) - { - // ignore button up on the win81 start button - const TaskbarInfo *taskBar=FindTaskBarInfoButton(msg->hwnd); - if (taskBar && taskBar->oldButton==msg->hwnd) - msg->message=WM_NULL; - } -if (!g_bTrimHooks) -{ - if (msg->message==WM_TIMER && FindTaskBarInfoBar(msg->hwnd) && CMenuContainer::IgnoreTaskbarTimers()) - { - // stop the taskbar timer messages. prevents the auto-hide taskbar from closing - msg->message=WM_NULL; - } - - if (msg->message==WM_MOUSEMOVE && g_ProgramsButton && msg->hwnd==g_ProgramsButton && GetSettingBool(L"CascadeAll") && !(msg->wParam&MK_SHIFT)) - { - DWORD pos=GetMessagePos(); - if (pos!=g_LastHoverPos && !g_bAllProgramsTimer) - { - g_bAllProgramsTimer=true; - bool bDef; - DWORD time=GetSettingInt(L"AllProgramsDelay",bDef); - if (bDef) - SystemParametersInfo(SPI_GETMENUSHOWDELAY,NULL,&time,0); - SetTimer(g_ProgramsButton,'CLSM',time,NULL); - } - g_LastHoverPos=pos; - } - if (msg->message==WM_TIMER && msg->wParam=='CLSM' && g_ProgramsButton && msg->hwnd==g_ProgramsButton) - { - g_bAllProgramsTimer=false; - KillTimer(g_ProgramsButton,'CLSM'); - DWORD pos=GetMessagePos(); - if (pos==g_LastHoverPos) - PostMessage(g_AllPrograms,WM_COMMAND,IDOK,(LPARAM)g_ProgramsButton); - msg->message=WM_NULL; - } - if (msg->message==WM_MOUSELEAVE && g_ProgramsButton && msg->hwnd==g_ProgramsButton) - { - g_bAllProgramsTimer=false; - KillTimer(g_ProgramsButton,'CLSM'); - } - - // handle hover - if (msg->message==WM_MOUSEMOVE) - { - TaskbarInfo *taskBar=FindTaskBarInfoButton(msg->hwnd); - if (taskBar && !CMenuContainer::IsMenuOpened() && !WindowsMenuOpened()) - { - if (GetSettingInt(L"Hover") && !taskBar->bTimer) - { - taskBar->bTimer=true; - int time=GetSettingInt(L"StartHoverDelay"); - SetTimer(msg->hwnd,'CLSM',time,NULL); - } - if (msg->hwnd==taskBar->oldButton) - { - APPBARDATA appbar={sizeof(appbar)}; - if (SHAppBarMessage(ABM_GETSTATE,&appbar)&ABS_AUTOHIDE) - SendMessage(taskBar->taskBar,WM_NCHITTEST,0,GetMessagePos()); - } - } - } - if (msg->message==WM_MOUSELEAVE) - { - TaskbarInfo *taskBar=FindTaskBarInfoButton(msg->hwnd); - if (taskBar) - { - taskBar->bTimer=false; - KillTimer(msg->hwnd,'CLSM'); - if (taskBar->oldButton==msg->hwnd) - { - RECT rc; - GetWindowRect(taskBar->oldButton,&rc); - CPoint pt(GetMessagePos()); - if (PtInRect(&rc,pt)) - { - wchar_t className[256]={0}; - GetClassName(WindowFromPoint(pt),className,_countof(className)); - if (wcscmp(className,L"ImmersiveSwitchList")==0 || wcscmp(className,L"EdgeUiInputWndClass")==0) - { - msg->message=WM_NULL; - TRACKMOUSEEVENT track={sizeof(track),TME_LEAVE,msg->hwnd,0}; - TrackMouseEvent(&track); - } - } - } - } - } - if ((msg->message==WM_NCMOUSEMOVE || msg->message==WM_NCMOUSELEAVE) && (msg->wParam==HTCAPTION || !IsAppThemed()) && GetSettingInt(L"Hover")) // HACK: in Classic mode the start menu can show up even if wParam is not HTCAPTION (most likely a bug in Windows) - { - TaskbarInfo *taskBar=FindTaskBarInfoBar(msg->hwnd); - if (taskBar) - { - if (!CMenuContainer::IsMenuOpened() && !WindowsMenuOpened() && PointAroundStartButton(taskBar->taskbarId)) - { - if (!taskBar->bTimer) - { - taskBar->bTimer=true; - int time=GetSettingInt(L"StartHoverDelay"); - SetTimer(taskBar->startButton,'CLSM',time,NULL); - } - } - else - { - if (taskBar->bTimer) - { - taskBar->bTimer=false; - KillTimer(taskBar->startButton,'CLSM'); - } - } - } - } - if (msg->message==WM_TIMER && msg->wParam=='CLSM' && CMenuContainer::CanShowMenu()) - { - TaskbarInfo *taskBar=FindTaskBarInfoButton(msg->hwnd); - if (taskBar) - { - KillTimer(msg->hwnd,'CLSM'); - msg->message=WM_NULL; - if (taskBar->bTimer && !CMenuContainer::IsMenuOpened() && !WindowsMenuOpened()) - { - CPoint pt(GetMessagePos()); - if (WindowFromPoint(pt)==msg->hwnd || PointAroundStartButton(taskBar->taskbarId)) - { - int control=GetSettingInt(L"Hover"); - if (control==OPEN_CLASSIC) - { - PostMessage(g_ProgWin,WM_SYSCOMMAND,SC_TASKLIST,'CSM'); - } - else if (control==OPEN_WINDOWS) - { - FindWindowsMenu(); - PostMessage(g_ProgWin,WM_SYSCOMMAND,SC_TASKLIST,'WSMM'); - } - else if (control==OPEN_CUSTOM) - { - CString commandText=GetSettingString(L"HoverCommand"); - if (!commandText.IsEmpty()) - { - wchar_t expandedCommand[_MAX_PATH]{}; - ::ExpandEnvironmentStrings(commandText, expandedCommand, _countof(expandedCommand)); - ShellExecute(NULL,NULL,expandedCommand,NULL,NULL,SW_SHOWNORMAL); - } - } - } - } - taskBar->bTimer=false; - } - } -} - // context menu - if (msg->message==WM_NCRBUTTONUP || msg->message==WM_RBUTTONUP) - { - TaskbarInfo *taskBar=FindTaskBarInfoButton(msg->hwnd); - DWORD winVer=GetWinVersion(); - if (!taskBar && winVer>=WIN_VER_WIN8) - { - taskBar=FindTaskBarInfoBar(msg->hwnd); - if (taskBar && !PointAroundStartButton(taskBar->taskbarId)) - taskBar=NULL; - } - if (taskBar) - { - CPoint pt0(GetMessagePos()); - if (msg->message==WM_RBUTTONUP && msg->hwnd==taskBar->startButton && msg->lParam==MAKELPARAM(-1,-1)) - { - RECT rc; - GetWindowRect(msg->hwnd,&rc); - pt0.x=(rc.left+rc.right)/2; - pt0.y=(rc.top+rc.bottom)/2; - } - bool bShowCSMenu=false, bShowWinX=false, bShowWin7=false; - if (msg->hwnd==taskBar->taskBar && taskBar->bReplaceButton) - bShowWinX=true; - else - { - bShowCSMenu=(GetSettingBool(L"ShiftRight")==(GetKeyState(VK_SHIFT)<0)); - bShowWinX=winVer>=WIN_VER_WIN8 && !bShowCSMenu; - } - bShowWin7=!bShowCSMenu && g_WinStartButton && msg->hwnd!=g_WinStartButton; - - if (bShowCSMenu || bShowWinX || bShowWin7) - { - msg->message=WM_NULL; - if (CMenuContainer::IsMenuOpened()) - CMenuContainer::CloseStartMenu(); - } - if (bShowCSMenu) - { - // additional commands for the context menu - enum - { - CMD_SETTINGS=1, - CMD_HELP, - CMD_EXIT, - CMD_OPEN, - CMD_OPEN_ALL, - CMD_EXPLORER, - CMD_OPEN_PINNED, - }; - - // right-click on the start button - open the context menu (Settings, Help, Exit) - HMENU menu=CreatePopupMenu(); - CString titleFmt=LoadStringEx(IDS_MENU_TITLE); - if (!titleFmt.IsEmpty()) - { - CString title; - DWORD ver=GetVersionEx(g_Instance); - title.Format(titleFmt,ver>>24,(ver>>16)&0xFF,ver&0xFFFF); - - AppendMenu(menu,MF_STRING,0,title); - EnableMenuItem(menu,0,MF_BYPOSITION|MF_DISABLED); - SetMenuDefaultItem(menu,0,TRUE); - AppendMenu(menu,MF_SEPARATOR,0,0); - } - int count0=GetMenuItemCount(menu); - if (GetSettingBool(L"EnableExplorer")) - { - if (!GetSettingString(L"ExplorerPath").IsEmpty()) - AppendMenu(menu,MF_STRING,CMD_EXPLORER,FindTranslation(L"Menu.Explorer",L"Windows Explorer")); - AppendMenu(menu,MF_STRING,CMD_OPEN,FindTranslation(L"Menu.Open",L"&Open")); - if (!SHRestricted(REST_NOCOMMONGROUPS)) - AppendMenu(menu,MF_STRING,CMD_OPEN_ALL,FindTranslation(L"Menu.OpenAll",L"O&pen All Users")); - if (GetSettingInt(L"PinnedPrograms")==PINNED_PROGRAMS_PINNED) - AppendMenu(menu,MF_STRING,CMD_OPEN_PINNED,FindTranslation(L"Menu.OpenPinned",L"O&pen Pinned")); - AppendMenu(menu,MF_SEPARATOR,0,0); - } - if (GetSettingBool(L"EnableSettings")) - AppendMenu(menu,MF_STRING,CMD_SETTINGS,FindTranslation(L"Menu.MenuSettings",L"Settings")); - if (HasHelp()) - AppendMenu(menu,MF_STRING,CMD_HELP,FindTranslation(L"Menu.MenuHelp",L"Help")); - if (GetSettingBool(L"EnableExit")) - { - AppendMenu(menu,MF_STRING,CMD_EXIT,FindTranslation(L"Menu.MenuExit",L"Exit")); - if (!CMenuContainer::CanShowMenu()) - EnableMenuItem(menu,CMD_EXIT,MF_BYCOMMAND|MF_DISABLED); - } - if (GetMenuItemCount(menu)>count0) - { - MENUITEMINFO mii={sizeof(mii)}; - mii.fMask=MIIM_BITMAP; - mii.hbmpItem=HBMMENU_POPUP_CLOSE; - SetMenuItemInfo(menu,CMD_EXIT,FALSE,&mii); - MENUINFO info={sizeof(info),MIM_STYLE,MNS_CHECKORBMP}; - SetMenuInfo(menu,&info); - g_bInMenu=true; - SetForegroundWindow(msg->hwnd); - int res=TrackPopupMenu(menu,TPM_RIGHTBUTTON|TPM_RETURNCMD|(IsLanguageRTL()?TPM_LAYOUTRTL:0),pt0.x,pt0.y,0,msg->hwnd,NULL); - DestroyMenu(menu); - g_bInMenu=false; - if (res==CMD_SETTINGS) - { - EditSettings(false,0); - } - if (res==CMD_HELP) - { - ShowHelp(); - return TRUE; - } - if (res==CMD_EXIT) - { - LRESULT res=CallNextHookEx(NULL,code,wParam,lParam); - CleanStartMenuDLL(); - return res; // we should exit as quickly as possible now. the DLL is about to be unloaded - } - if (res==CMD_OPEN || res==CMD_OPEN_ALL) - { - CComString pPath; - if (SUCCEEDED(ShGetKnownFolderPath((res==CMD_OPEN)?FOLDERID_StartMenu:FOLDERID_CommonStartMenu,&pPath))) - ShellExecute(NULL,L"open",pPath,NULL,NULL,SW_SHOWNORMAL); - } - if (res==CMD_OPEN_PINNED) // open pinned folder - { - SHELLEXECUTEINFO execute={sizeof(execute)}; - CString path=GetSettingString(L"PinnedItemsPath"); - execute.lpVerb=L"open"; - execute.lpFile=path; - execute.nShow=SW_SHOWNORMAL; - execute.fMask=SEE_MASK_DOENVSUBST; - ShellExecuteEx(&execute); - } - if (res==CMD_EXPLORER) - { - CString path=GetSettingString(L"ExplorerPath"); - ITEMIDLIST blank={0}; - SHELLEXECUTEINFO execute={sizeof(execute)}; - execute.lpVerb=L"open"; - execute.lpFile=path; - execute.nShow=SW_SHOWNORMAL; - if (_wcsicmp(path,L"computer")==0) - execute.lpFile=L"::{20D04FE0-3AEA-1069-A2D8-08002B30309D}"; - else if (_wcsicmp(path,L"libraries")==0) - execute.lpFile=L"::{031E4825-7B94-4DC3-B131-E946B44C8DD5}"; - else if (_wcsicmp(path,L"desktop")==0) - { - execute.fMask=SEE_MASK_IDLIST; - execute.lpIDList=␣ - execute.lpFile=NULL; - } - else - { - execute.fMask=SEE_MASK_DOENVSUBST; - } - ShellExecuteEx(&execute); - } - } - } - else if (bShowWinX) - { - ShowWinX(); - } - else if (bShowWin7) - { - CPoint pt(GetMessagePos()); - ScreenToClient(g_WinStartButton,&pt); - PostMessage(g_WinStartButton,WM_RBUTTONUP,wParam,MAKELONG(pt.x,pt.y)); - } - } - } - - } - return CallNextHookEx(NULL,code,wParam,lParam); -} - -HBITMAP GetStartScreenIcon( int size ) -{ - // for sizes >=64, use image directly - // for sizes>=32, get 64x64 and scale down - // for sizes<32 use the system background color - StartScreenThumbInfo info={{size<64?64:size}}; - info.size.cy=info.size.cx; - if (size>=32 && g_AppManagerThread && GetWinVersion()==WIN_VER_WIN8) - { - info.event=CreateEvent(NULL,TRUE,FALSE,NULL); - PostThreadMessage(g_AppManagerThread,g_StartMenuMsg,MSG_METROTHUMBNAIL,(LPARAM)&info); - WaitForSingleObject(info.event,100); // if it takes more than 100ms, screw it - CloseHandle(info.event); - } - info.size.cy=info.size.cx*3/4; - - BITMAPINFO bi={0}; - bi.bmiHeader.biSize=sizeof(BITMAPINFOHEADER); - bi.bmiHeader.biWidth=bi.bmiHeader.biHeight=size; - bi.bmiHeader.biPlanes=1; - bi.bmiHeader.biBitCount=32; - - HDC hDst=CreateCompatibleDC(NULL); - unsigned int *bits; - HBITMAP bitmap=CreateDIBSection(hDst,&bi,DIB_RGB_COLORS,(void**)&bits,NULL,0); - HGDIOBJ bmp0=SelectObject(hDst,bitmap); - RECT rc={0,size/8,size,size*7/8}; - - if (info.bitmap) - { - HDC hSrc=CreateCompatibleDC(hDst); - HGDIOBJ bmp02=SelectObject(hSrc,info.bitmap); - SetStretchBltMode(hDst,HALFTONE); - StretchBlt(hDst,rc.left,rc.top,rc.right-rc.left,rc.bottom-rc.top,hSrc,0,0,info.size.cx,info.size.cy,SRCCOPY); - SelectObject(hSrc,bmp02); - DeleteDC(hSrc); - DeleteObject(info.bitmap); - } - else - { - typedef int (WINAPI *TGetImmersiveUserColorSetPreference)(bool bForceCheckRegistry, bool bSkipCheckOnFail); - typedef DWORD (WINAPI *TGetImmersiveColorFromColorSetEx)(UINT dwImmersiveColorSet, UINT dwImmersiveColorType, bool bIgnoreHighContrast, UINT dwHighContrastCacheMode); - typedef int (WINAPI *TGetImmersiveColorTypeFromName)(const wchar_t *name); - COLORREF color=0; - HMODULE hUxTheme=GetModuleHandle(L"uxtheme.dll"); - if (hUxTheme) - { - TGetImmersiveUserColorSetPreference GetImmersiveUserColorSetPreference=(TGetImmersiveUserColorSetPreference)GetProcAddress(hUxTheme,MAKEINTRESOURCEA(98)); - TGetImmersiveColorFromColorSetEx GetImmersiveColorFromColorSetEx=(TGetImmersiveColorFromColorSetEx)GetProcAddress(hUxTheme,MAKEINTRESOURCEA(95)); - TGetImmersiveColorTypeFromName GetImmersiveColorTypeFromName=(TGetImmersiveColorTypeFromName)GetProcAddress(hUxTheme,MAKEINTRESOURCEA(96)); - if (GetImmersiveUserColorSetPreference && GetImmersiveColorFromColorSetEx && GetImmersiveColorTypeFromName) - { - int type=GetImmersiveColorTypeFromName(L"ImmersiveStartBackground"); - int set=GetImmersiveUserColorSetPreference(false,false); - color=GetImmersiveColorFromColorSetEx(set,type,false,0)&0xFFFFFF; - } - } - SetDCBrushColor(hDst,color); - FillRect(hDst,&rc,(HBRUSH)GetStockObject(DC_BRUSH)); - HICON hIcon=(HICON)LoadImage(g_Instance,MAKEINTRESOURCE(GetWinVersion()>=WIN_VER_WIN10?IDI_START10:IDI_START),IMAGE_ICON,size,size,LR_DEFAULTCOLOR); - DrawIconEx(hDst,0,0,hIcon,size,size,0,NULL,DI_NORMAL); - DestroyIcon(hIcon); - } - SelectObject(hDst,bmp0); - DeleteDC(hDst); - - int i=0; - int n=size*rc.top; - for (;i