Some branding and licensing work (#22)

* Fix stdafx include

* Fix basic handling of "Games" folder on Windows10 RS4 (#10)
This does the following:
- Sets the default state to hidden
- Skips the Games folder when searching

This does not:
- Hide the dead menu entry.

I do not currently know how to actively change the user preference setting to forcefully hide it.

* Add basic Visual Studio gitignore

* Add specific entries to gitignore

* Do not set default menu to Win7 on RS4 (#10)

* Rename "PC Settings" to "Settings" (#12)

* Create distinction between modern and legacy settings in search results

* Add more build artifacts to gitignore

* Add default paths for toolset and build all languages

* Fix several memsize, memtype and nullpointer issues

* create trunk branch containing all changes

* set fallback and next version to 4.3.2, set resource fallback value to allow loading in IDE

* add generated en-US.dll to gitignore

* Don't echo script contents, add disabled "git clean -dfx" to build fresh

* Initial re-branding work (#21)

* Create copy of __MakeFinal to build all languages (Use this file when releasing new versions)

* Move the registry key IvoSoft->Passionate-Coder (#21)

* Change company/mfg name IvoSoft->Passionate-Coder (#21)

* Update some leftover copyright dates (#21)

* Fix accidental copy-paste breaking MakeFinal scripts

* Fix invalid company name for Wix and change registry keys to match the new string (#21)

* Update more copyright and legal text (#21)

* Update RTF files format (Wordpad generated those) (#21)

* update license text in RTF files (#21)
We lost the blue link text in the installer page. Will have to manually re-color all the links later.
This commit is contained in:
Xenhat
2018-06-25 01:42:52 -04:00
committed by GitHub
parent e0d1c72b0b
commit 0adcd693e4
1296 changed files with 7476 additions and 27790 deletions

View File

@@ -0,0 +1,323 @@
// Classic Shell (c) 2009-2017, Ivo Beltchev
// Classic Start (c) 2017-2018, The Passionate-Coder Team
// Confidential information of Ivo Beltchev. Not for disclosure or distribution without prior written consent from the author
// Accessibility.cpp - contains the accessibility class CMenuAccessible, used by CMenuContainer
#include "stdafx.h"
#include "Accessibility.h"
#include "MenuContainer.h"
#include "Translations.h"
CMenuAccessible::CMenuAccessible( CMenuContainer *pOwner )
{
m_RefCount=0;
m_pOwner=pOwner;
CreateStdAccessibleObject(pOwner->m_hWnd,OBJID_CLIENT,IID_IAccessible,(void**)&m_pStdAccessible);
}
CMenuAccessible::~CMenuAccessible( void )
{
}
void CMenuAccessible::Reset( void )
{
m_pOwner=NULL;
m_pStdAccessible=NULL;
}
HRESULT STDMETHODCALLTYPE CMenuAccessible::get_accParent( IDispatch **ppdispParent )
{
if (!m_pOwner) return RPC_E_DISCONNECTED;
if (m_pStdAccessible)
return m_pStdAccessible->get_accParent(ppdispParent);
*ppdispParent=NULL;
return S_FALSE;
}
HRESULT STDMETHODCALLTYPE CMenuAccessible::get_accChildCount( long *pcountChildren )
{
if (!m_pOwner) return RPC_E_DISCONNECTED;
*pcountChildren=(long)m_pOwner->m_Items.size();
return S_OK;
}
HRESULT STDMETHODCALLTYPE CMenuAccessible::get_accChild( VARIANT varChild, IDispatch **ppdispChild )
{
if (!m_pOwner) return RPC_E_DISCONNECTED;
*ppdispChild=NULL; // no child IAccessibles
if (varChild.vt!=VT_I4) return E_INVALIDARG;
return S_FALSE;
}
HRESULT STDMETHODCALLTYPE CMenuAccessible::get_accName( VARIANT varChild, BSTR *pszName )
{
if (!m_pOwner) return RPC_E_DISCONNECTED;
*pszName=NULL;
if (varChild.vt!=VT_I4) return S_FALSE;
if (varChild.lVal==CHILDID_SELF) return S_FALSE;
int index=varChild.lVal-1;
if (index<0 || index>=(int)m_pOwner->m_Items.size()) return S_FALSE;
if (m_pOwner->m_Items[index].id==MENU_SEPARATOR) return S_FALSE;
wchar_t text[256];
Strcpy(text,_countof(text),m_pOwner->m_Items[index].name);
for (wchar_t *c1=text,*c2=text;;c1++)
{
if (*c1!='&')
*c2++=*c1;
if (*c1==0) break;
}
*pszName=SysAllocString(text);
return S_OK;
}
HRESULT STDMETHODCALLTYPE CMenuAccessible::get_accDescription( VARIANT varChild, BSTR *pszDescription )
{
return get_accName(varChild,pszDescription);
}
HRESULT STDMETHODCALLTYPE CMenuAccessible::get_accRole( VARIANT varChild, VARIANT *pvarRole )
{
if (!m_pOwner) return RPC_E_DISCONNECTED;
pvarRole->vt=VT_EMPTY;
if (varChild.vt!=VT_I4) return E_INVALIDARG;
if (varChild.lVal==CHILDID_SELF)
{
pvarRole->vt=VT_I4;
pvarRole->lVal=ROLE_SYSTEM_MENUPOPUP;
return S_OK;
}
int index=varChild.lVal-1;
if (index<0 || index>=(int)m_pOwner->m_Items.size()) return E_INVALIDARG;
pvarRole->vt=VT_I4;
pvarRole->lVal=m_pOwner->m_Items[index].id==MENU_SEPARATOR?ROLE_SYSTEM_SEPARATOR:ROLE_SYSTEM_MENUITEM;
return S_OK;
}
HRESULT STDMETHODCALLTYPE CMenuAccessible::get_accState( VARIANT varChild, VARIANT *pvarState )
{
if (!m_pOwner) return RPC_E_DISCONNECTED;
pvarState->vt=VT_EMPTY;
if (varChild.vt!=VT_I4) return E_INVALIDARG;
int flags=STATE_SYSTEM_FOCUSABLE;
int index=varChild.lVal-1;
if (index>=0 && index<(int)m_pOwner->m_Items.size())
{
const CMenuContainer::MenuItem &item=m_pOwner->m_Items[index];
if (m_pOwner->m_HotItem==index)
flags|=STATE_SYSTEM_FOCUSED;
if (item.bFolder)
flags|=STATE_SYSTEM_HASPOPUP;
if (item.id==MENU_SEPARATOR)
flags=0;
RECT rc;
if (!m_pOwner->GetItemRect(index,rc))
flags|=STATE_SYSTEM_INVISIBLE;
}
pvarState->vt=VT_I4;
pvarState->lVal=flags;
return S_OK;
}
HRESULT STDMETHODCALLTYPE CMenuAccessible::get_accKeyboardShortcut( VARIANT varChild, BSTR *pszKeyboardShortcut )
{
if (!m_pOwner) return RPC_E_DISCONNECTED;
*pszKeyboardShortcut=NULL;
if (varChild.vt!=VT_I4) return E_INVALIDARG;
int flags=0;
int index=varChild.lVal-1;
if (index<0 || index>=(int)m_pOwner->m_Items.size())
return S_FALSE;
const CMenuContainer::MenuItem &item=m_pOwner->m_Items[index];
wchar_t str[2]={item.accelerator,0};
*pszKeyboardShortcut=SysAllocString(str);
return S_OK;
}
HRESULT STDMETHODCALLTYPE CMenuAccessible::get_accFocus( VARIANT *pvarChild )
{
if (!m_pOwner) return RPC_E_DISCONNECTED;
HWND focus=GetFocus();
pvarChild->vt=VT_EMPTY;
if (m_pOwner->m_hWnd==focus && m_pOwner->m_HotItem>=0)
{
pvarChild->vt=VT_I4;
pvarChild->lVal=m_pOwner->m_HotItem+1;
}
return S_OK;
}
HRESULT STDMETHODCALLTYPE CMenuAccessible::get_accSelection( VARIANT *pvarChildren )
{
if (!m_pOwner) return RPC_E_DISCONNECTED;
pvarChildren->vt=VT_EMPTY;
return S_OK;
}
HRESULT STDMETHODCALLTYPE CMenuAccessible::get_accDefaultAction( VARIANT varChild, BSTR *pszDefaultAction )
{
if (!m_pOwner) return RPC_E_DISCONNECTED;
*pszDefaultAction=NULL;
if (varChild.vt!=VT_I4) return E_INVALIDARG;
if (varChild.lVal==CHILDID_SELF)
{
*pszDefaultAction=SysAllocString(FindTranslation(L"Menu.ActionClose",L"Close"));
return S_OK;
}
int index=varChild.lVal-1;
if (index<0 || index>=(int)m_pOwner->m_Items.size())
return S_FALSE;
const CMenuContainer::MenuItem &item=m_pOwner->m_Items[index];
if (item.id!=MENU_SEPARATOR && item.id!=MENU_EMPTY && item.id!=MENU_EMPTY_TOP)
*pszDefaultAction=SysAllocString(item.bFolder?FindTranslation(L"Menu.ActionOpen",L"Open"):FindTranslation(L"Menu.ActionExecute",L"Execute"));
return S_OK;
}
HRESULT STDMETHODCALLTYPE CMenuAccessible::accSelect( long flagsSelect, VARIANT varChild )
{
if (!m_pOwner) return RPC_E_DISCONNECTED;
if (varChild.vt!=VT_I4) return E_INVALIDARG;
if (flagsSelect&SELFLAG_TAKEFOCUS)
{
int index=varChild.lVal-1;
if (index<0 || index>=(int)m_pOwner->m_Items.size())
return S_FALSE;
m_pOwner->ActivateItem(index,CMenuContainer::ACTIVATE_SELECT,NULL,false);
}
return S_OK;
}
HRESULT STDMETHODCALLTYPE CMenuAccessible::accLocation( long *pxLeft, long *pyTop, long *pcxWidth, long *pcyHeight, VARIANT varChild )
{
if (!m_pOwner) return RPC_E_DISCONNECTED;
if (varChild.vt!=VT_I4) return E_INVALIDARG;
RECT rc;
if (varChild.lVal==CHILDID_SELF)
{
m_pOwner->GetWindowRect(&rc);
}
else
{
int index=varChild.lVal-1;
if (index<0 || index>=(int)m_pOwner->m_Items.size())
return S_FALSE;
m_pOwner->GetItemRect(index,rc);
m_pOwner->MapWindowPoints(NULL,&rc);
}
*pxLeft=rc.left;
*pyTop=rc.top;
*pcxWidth=rc.right-rc.left;
*pcyHeight=rc.bottom-rc.top;
return S_OK;
}
HRESULT STDMETHODCALLTYPE CMenuAccessible::accNavigate( long navDir, VARIANT varStart, VARIANT *pvarEndUpAt )
{
if (!m_pOwner) return RPC_E_DISCONNECTED;
pvarEndUpAt->vt=VT_EMPTY;
if (varStart.vt!=VT_I4) return E_INVALIDARG;
switch (navDir)
{
case NAVDIR_FIRSTCHILD:
if (varStart.lVal!=CHILDID_SELF) return S_FALSE;
pvarEndUpAt->vt=VT_I4;
pvarEndUpAt->lVal=1;
break;
case NAVDIR_LASTCHILD:
if (varStart.lVal!=CHILDID_SELF) return S_FALSE;
pvarEndUpAt->vt=VT_I4;
pvarEndUpAt->lVal=(int)m_pOwner->m_Items.size();
break;
case NAVDIR_NEXT:
case NAVDIR_DOWN:
if (varStart.lVal==CHILDID_SELF)
{
if (m_pStdAccessible)
return m_pStdAccessible->accNavigate(navDir,varStart,pvarEndUpAt);
return S_FALSE;
}
if (varStart.lVal>=(int)m_pOwner->m_Items.size())
pvarEndUpAt->vt=VT_EMPTY;
else
{
pvarEndUpAt->vt=VT_I4;
pvarEndUpAt->lVal=varStart.lVal+1;
}
break;
case NAVDIR_PREVIOUS:
case NAVDIR_UP:
if (varStart.lVal==CHILDID_SELF)
{
if (m_pStdAccessible)
return m_pStdAccessible->accNavigate(navDir,varStart,pvarEndUpAt);
return S_FALSE;
}
if (varStart.lVal<1)
pvarEndUpAt->vt=VT_EMPTY;
else
{
pvarEndUpAt->vt=VT_I4;
pvarEndUpAt->lVal=varStart.lVal-1;
}
break;
// Unsupported directions.
case NAVDIR_LEFT:
case NAVDIR_RIGHT:
if (varStart.lVal==CHILDID_SELF)
{
if (m_pStdAccessible)
return m_pStdAccessible->accNavigate(navDir,varStart,pvarEndUpAt);
}
return S_FALSE;
}
return S_OK;
}
HRESULT STDMETHODCALLTYPE CMenuAccessible::accHitTest( long xLeft, long yTop, VARIANT *pvarChild )
{
if (!m_pOwner) return RPC_E_DISCONNECTED;
POINT pt={xLeft,yTop};
RECT rc;
m_pOwner->GetWindowRect(&rc);
if (!PtInRect(&rc,pt))
{
pvarChild->vt=VT_EMPTY;
return S_FALSE;
}
POINT pt2=pt;
m_pOwner->ScreenToClient(&pt2);
int index=m_pOwner->HitTest(pt2,NULL);
if (index>=0)
{
pvarChild->vt=VT_I4;
pvarChild->lVal=index+1;
}
return S_OK;
}
HRESULT STDMETHODCALLTYPE CMenuAccessible::accDoDefaultAction( VARIANT varChild )
{
if (!m_pOwner) return RPC_E_DISCONNECTED;
if (varChild.vt!=VT_I4) return E_INVALIDARG;
if (varChild.lVal==CHILDID_SELF)
{
// close
for (std::vector<CMenuContainer*>::reverse_iterator it=CMenuContainer::s_Menus.rbegin();*it!=m_pOwner;++it)
(*it)->PostMessage(WM_CLOSE);
m_pOwner->PostMessage(WM_CLOSE);
return S_OK;
}
int index=varChild.lVal-1;
if (index<0 || index>=(int)m_pOwner->m_Items.size())
return S_FALSE;
// open or execute
const CMenuContainer::MenuItem &item=m_pOwner->m_Items[index];
if (item.id!=MENU_SEPARATOR && item.id!=MENU_EMPTY && item.id!=MENU_EMPTY_TOP)
m_pOwner->ActivateItem(index,item.bFolder?CMenuContainer::ACTIVATE_OPEN:CMenuContainer::ACTIVATE_EXECUTE,NULL,NULL);
return S_OK;
}

View File

@@ -0,0 +1,75 @@
// Classic Shell (c) 2009-2017, Ivo Beltchev
// Classic Start (c) 2017-2018, The Passionate-Coder Team
// Confidential information of Ivo Beltchev. Not for disclosure or distribution without prior written consent from the author
#pragma once
class CMenuContainer;
// CMenuAccessible - provides accessibility services for a CMenuContainer
class CMenuAccessible: public IAccessible
{
public:
CMenuAccessible( CMenuContainer *pOwner );
~CMenuAccessible( void );
void Reset( void ); // called by the owner when it is destroyed
// IUnknown
virtual STDMETHODIMP QueryInterface( REFIID riid, void **ppvObject )
{
*ppvObject=NULL;
if (IID_IUnknown==riid || IID_IDispatch==riid || IID_IAccessible==riid)
{
AddRef();
*ppvObject=static_cast<IAccessible*>(this);
return S_OK;
}
return E_NOINTERFACE;
}
virtual ULONG STDMETHODCALLTYPE AddRef( void )
{
return InterlockedIncrement(&m_RefCount);
}
virtual ULONG STDMETHODCALLTYPE Release( void )
{
long nTemp=InterlockedDecrement(&m_RefCount);
if (!nTemp) delete this;
return nTemp;
}
// IDispatch
virtual HRESULT STDMETHODCALLTYPE GetTypeInfoCount( UINT *pctinfo ) { return E_NOTIMPL; }
virtual HRESULT STDMETHODCALLTYPE GetTypeInfo( UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo ) { *ppTInfo=NULL; return E_NOTIMPL; }
virtual HRESULT STDMETHODCALLTYPE GetIDsOfNames( REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId ) { return E_NOTIMPL; }
virtual HRESULT STDMETHODCALLTYPE Invoke( DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr ) { return E_NOTIMPL; }
// IAccessible
virtual HRESULT STDMETHODCALLTYPE get_accParent( IDispatch **ppdispParent );
virtual HRESULT STDMETHODCALLTYPE get_accChildCount( long *pcountChildren );
virtual HRESULT STDMETHODCALLTYPE get_accChild( VARIANT varChild, IDispatch **ppdispChild );
virtual HRESULT STDMETHODCALLTYPE get_accName( VARIANT varChild, BSTR *pszName );
virtual HRESULT STDMETHODCALLTYPE get_accValue( VARIANT varChild, BSTR *pszValue ) { *pszValue=NULL; return DISP_E_MEMBERNOTFOUND; }
virtual HRESULT STDMETHODCALLTYPE get_accDescription( VARIANT varChild, BSTR *pszDescription );
virtual HRESULT STDMETHODCALLTYPE get_accRole( VARIANT varChild, VARIANT *pvarRole );
virtual HRESULT STDMETHODCALLTYPE get_accState( VARIANT varChild, VARIANT *pvarState );
virtual HRESULT STDMETHODCALLTYPE get_accHelp( VARIANT varChild, BSTR *pszHelp ) { *pszHelp=NULL; return S_FALSE; }
virtual HRESULT STDMETHODCALLTYPE get_accHelpTopic( BSTR *pszHelpFile, VARIANT varChild, long *pidTopic ) { *pszHelpFile=NULL; return S_FALSE; }
virtual HRESULT STDMETHODCALLTYPE get_accKeyboardShortcut( VARIANT varChild, BSTR *pszKeyboardShortcut );
virtual HRESULT STDMETHODCALLTYPE get_accFocus( VARIANT *pvarChild );
virtual HRESULT STDMETHODCALLTYPE get_accSelection( VARIANT *pvarChildren );
virtual HRESULT STDMETHODCALLTYPE get_accDefaultAction( VARIANT varChild, BSTR *pszDefaultAction );
virtual HRESULT STDMETHODCALLTYPE accSelect( long flagsSelect, VARIANT varChild );
virtual HRESULT STDMETHODCALLTYPE accLocation( long *pxLeft, long *pyTop, long *pcxWidth, long *pcyHeight, VARIANT varChild );
virtual HRESULT STDMETHODCALLTYPE accNavigate( long navDir, VARIANT varStart, VARIANT *pvarEndUpAt );
virtual HRESULT STDMETHODCALLTYPE accHitTest( long xLeft, long yTop, VARIANT *pvarChild );
virtual HRESULT STDMETHODCALLTYPE accDoDefaultAction( VARIANT varChild );
virtual HRESULT STDMETHODCALLTYPE put_accName( VARIANT varChild, BSTR szName ) { return E_NOTIMPL; }
virtual HRESULT STDMETHODCALLTYPE put_accValue( VARIANT varChild, BSTR szValue ) { return DISP_E_MEMBERNOTFOUND; }
private:
LONG m_RefCount;
CMenuContainer *m_pOwner;
CComPtr<IAccessible> m_pStdAccessible;
};

View File

@@ -0,0 +1,715 @@
// Classic Shell (c) 2009-2017, Ivo Beltchev
// Classic Start (c) 2017-2018, The Passionate-Coder Team
// Confidential information of Ivo Beltchev. Not for disclosure or distribution without prior written consent from the author
#include "stdafx.h"
#include "resource.h"
#include "Translations.h"
#include "Settings.h"
#include "SettingsUI.h"
#include "ResourceHelper.h"
#include "ItemManager.h"
#include "ClassicStartMenuDLL.h"
#include "ClassicStartButton.h"
#include "MenuContainer.h"
#include "TouchHelper.h"
#include "dllmain.h"
#include <uxtheme.h>
#include <vsstyle.h>
#include <vssym32.h>
#include <dwmapi.h>
static int START_ICON_SIZE=0;
const int START_BUTTON_PADDING=3;
const int START_BUTTON_OFFSET=2;
const int START_TEXT_PADDING=2;
const int BLEND_PRECISION=1000;
bool g_bAllowMoveButton;
// CStartButton - implementation of a start button (for Windows 8)
class CStartButton: public CWindowImpl<CStartButton>
{
public:
DECLARE_WND_CLASS_EX(L"ClassicStart.CStartButton",CS_DBLCLKS,COLOR_MENU)
CStartButton( void );
// message handlers
BEGIN_MSG_MAP( CStartButton )
MESSAGE_HANDLER( WM_CREATE, OnCreate )
MESSAGE_HANDLER( WM_DESTROY, OnDestroy )
MESSAGE_HANDLER( WM_CLOSE, OnClose )
MESSAGE_HANDLER( WM_MOUSEACTIVATE, OnMouseActivate )
MESSAGE_HANDLER( WM_MOUSEMOVE, OnMouseMove )
MESSAGE_HANDLER( WM_ERASEBKGND, OnEraseBkgnd )
MESSAGE_HANDLER( WM_TIMER, OnTimer )
MESSAGE_HANDLER( WM_SETTINGCHANGE, OnSettingChange )
MESSAGE_HANDLER( WM_THEMECHANGED, OnThemeChanged )
MESSAGE_HANDLER( WM_POINTERDOWN, OnPointer )
MESSAGE_HANDLER( WM_POINTERUPDATE, OnPointer )
MESSAGE_HANDLER( WM_POINTERUP, OnPointer )
END_MSG_MAP()
void SetPressed( bool bPressed );
void UpdateButton( void );
void TaskBarMouseMove( void );
SIZE GetSize( void ) const { return m_Size; }
bool GetSmallIcons( void ) const { return m_bSmallIcons; }
protected:
LRESULT OnCreate( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled );
LRESULT OnDestroy( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled );
LRESULT OnClose( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled ) { return 0; }
LRESULT OnEraseBkgnd( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled ) { return 1; }
LRESULT OnMouseActivate( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled ) { return MA_NOACTIVATE; }
LRESULT OnMouseMove( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled );
LRESULT OnTimer( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled );
LRESULT OnSettingChange( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled );
LRESULT OnThemeChanged( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled );
LRESULT OnPointer( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled );
private:
enum { TIMER_BLEND=1, TIMER_LEAVE=2 };
size_t m_TaskbarId;
SIZE m_Size;
HBITMAP m_Bitmap, m_Blendmap;
unsigned int *m_Bits, *m_BlendBits;
HICON m_Icon;
HFONT m_Font;
bool m_bHot, m_bPressed;
bool m_bTrackMouse;
bool m_bClassic;
bool m_bRTL;
bool m_bSmallIcons;
int m_HotBlend; // 0..BLEND_PRECISION
CWindow m_Tooltip;
HTHEME m_Theme;
// animations
int m_YOffset;
int m_Frames[3];
struct Animation
{
std::vector<int> frames;
int duration; // in ms
bool bBlend;
};
Animation m_Animations[2];
void ParseAnimation( Animation &animation, const std::vector<unsigned int> &pixels, int &index, int totalFrames );
void LoadBitmap( void );
void SetHot( bool bHot );
};
CStartButton::CStartButton( void )
{
m_Size.cx=m_Size.cy=0;
m_TaskbarId=-1;
m_Bitmap=m_Blendmap=NULL;
m_Bits=m_BlendBits=NULL;
m_Icon=NULL;
m_Font=NULL;
m_bHot=m_bPressed=false;
m_bTrackMouse=false;
m_bClassic=m_bSmallIcons=false;
m_bRTL=false;
m_HotBlend=0;
m_Theme=NULL;
}
LRESULT CStartButton::OnCreate( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled )
{
size_t params=(intptr_t)(((CREATESTRUCT*)lParam)->lpCreateParams);
m_bRTL=(params&1)!=0;
m_TaskbarId=params>>1;
m_bSmallIcons=IsTaskbarSmallIcons();
std::vector<HMODULE> modules;
m_Icon=NULL;
START_ICON_SIZE=0;
CString iconPath=GetSettingString(L"StartButtonIcon");
if (_wcsicmp(iconPath,L"none")!=0)
{
START_ICON_SIZE=GetSettingInt(L"StartButtonIconSize");
if (START_ICON_SIZE==0)
START_ICON_SIZE=GetSystemMetrics(m_bSmallIcons?SM_CXSMICON:SM_CXICON);
if (START_ICON_SIZE<8) START_ICON_SIZE=8;
if (START_ICON_SIZE>64) START_ICON_SIZE=64;
m_Icon=LoadIcon(START_ICON_SIZE,iconPath,modules);
for (std::vector<HMODULE>::const_iterator it=modules.begin();it!=modules.end();++it)
FreeLibrary(*it);
if (!m_Icon)
m_Icon=(HICON)LoadImage(g_Instance,MAKEINTRESOURCE(IDI_APPICON),IMAGE_ICON,START_ICON_SIZE,START_ICON_SIZE,LR_DEFAULTCOLOR);
}
int dpi=CItemManager::GetDPI(false);
m_Font=CreateFont(10*dpi/72,0,0,0,FW_BOLD,0,0,0,DEFAULT_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH,L"Tahoma");
int val=1;
DwmSetWindowAttribute(m_hWnd,DWMWA_EXCLUDED_FROM_PEEK,&val,sizeof(val));
val=DWMFLIP3D_EXCLUDEABOVE;
DwmSetWindowAttribute(m_hWnd,DWMWA_FLIP3D_POLICY,&val,sizeof(val));
LoadBitmap();
m_Tooltip=CreateWindowEx(WS_EX_TOPMOST|WS_EX_TOOLWINDOW|WS_EX_TRANSPARENT|(m_bRTL?WS_EX_LAYOUTRTL:0),TOOLTIPS_CLASS,NULL,WS_POPUP|TTS_NOPREFIX|TTS_ALWAYSTIP,0,0,0,0,NULL,NULL,g_Instance,NULL);
OnThemeChanged(WM_THEMECHANGED,0,0,bHandled);
m_bPressed=true;
SetPressed(false);
bHandled=FALSE;
return 0;
}
LRESULT CStartButton::OnDestroy( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled )
{
if (m_Bitmap) DeleteObject(m_Bitmap);
if (m_Blendmap) DeleteObject(m_Blendmap);
if (m_Icon) DestroyIcon(m_Icon);
if (m_Font) DeleteObject(m_Font);
if (m_Theme) CloseThemeData(m_Theme);
m_Tooltip.DestroyWindow();
KillTimer(TIMER_BLEND);
bHandled=FALSE;
return 0;
}
void CStartButton::UpdateButton( void )
{
BLENDFUNCTION func={AC_SRC_OVER,0,255,AC_SRC_ALPHA};
HDC hSrc=CreateCompatibleDC(NULL);
RECT rc;
GetWindowRect(&rc);
SIZE size={rc.right-rc.left,rc.bottom-rc.top};
if (m_bClassic)
{
if (m_bRTL)
SetLayout(hSrc,LAYOUT_RTL);
HGDIOBJ bmp0=SelectObject(hSrc,m_Blendmap);
RECT rc={0,0,m_Size.cx,m_Size.cy};
FillRect(hSrc,&rc,(HBRUSH)GetStockObject(BLACK_BRUSH));
InflateRect(&rc,-START_BUTTON_OFFSET,-START_BUTTON_OFFSET);
int offset=0;
if (m_Theme)
{
int state=m_bPressed?PBS_PRESSED:(m_bHot?PBS_HOT:PBS_NORMAL);
DrawThemeBackground(m_Theme,hSrc,BP_PUSHBUTTON,state,&rc,NULL);
}
else
{
DrawFrameControl(hSrc,&rc,DFC_BUTTON,DFCS_BUTTONPUSH|(m_bPressed?DFCS_PUSHED:0));
offset=m_bPressed?1:0;
}
if (m_Icon)
DrawIconEx(hSrc,START_BUTTON_PADDING+START_BUTTON_OFFSET+offset,(m_Size.cy-START_ICON_SIZE)/2+offset,m_Icon,0,0,0,NULL,DI_NORMAL|DI_NOMIRROR);
rc.left+=START_BUTTON_PADDING+START_ICON_SIZE+START_TEXT_PADDING+offset;
rc.top+=START_BUTTON_PADDING+offset;
rc.right-=START_BUTTON_PADDING+START_TEXT_PADDING-offset;
rc.bottom-=START_BUTTON_PADDING-offset;
HFONT font0=(HFONT)SelectObject(hSrc,m_Font);
COLORREF color=GetSysColor(COLOR_BTNTEXT);
if (m_Theme)
{
int state=m_bPressed?PBS_PRESSED:(m_bHot?PBS_HOT:PBS_NORMAL);
if (FAILED(GetThemeColor(m_Theme,BP_PUSHBUTTON,state,TMT_TEXTCOLOR,&color)))
color=GetSysColor(COLOR_BTNTEXT);
}
SetTextColor(hSrc,color);
SetBkMode(hSrc,TRANSPARENT);
CString startStr=GetSettingString(L"StartButtonText");
const wchar_t *startText=startStr;
if (startText[0]=='$')
startText=FindTranslation(startText+1,L"Start");
DrawText(hSrc,startText,-1,&rc,DT_NOPREFIX|DT_SINGLELINE|DT_VCENTER);
SelectObject(hSrc,bmp0);
// mark the button pixels as opaque
for (int y=START_BUTTON_OFFSET;y<m_Size.cy-START_BUTTON_OFFSET;y++)
for (int x=START_BUTTON_OFFSET;x<m_Size.cx-START_BUTTON_OFFSET;x++)
m_BlendBits[y*m_Size.cx+x]|=0xFF000000;
SelectObject(hSrc,m_Blendmap);
POINT pos={0,0};
UpdateLayeredWindow(m_hWnd,NULL,NULL,&size,hSrc,&pos,0,&func,ULW_ALPHA);
SelectObject(hSrc,font0);
SelectObject(hSrc,bmp0);
}
else
{
int image=-1;
int frame1, frame2, blend;
if (m_bPressed) image=m_Frames[2];
else if (m_HotBlend==0) image=m_Frames[0];
else if (m_HotBlend==BLEND_PRECISION) image=m_Frames[1];
else
{
const Animation &animation=m_Animations[m_bHot?0:1];
int count=(int)animation.frames.size()-1;
blend=m_bHot?m_HotBlend:(BLEND_PRECISION-m_HotBlend);
if (count<1 || animation.duration==0)
{
image=m_Frames[m_bHot?1:0];
}
else if (!animation.bBlend)
{
int index=(blend*count+50)/BLEND_PRECISION; // [0..count]
image=animation.frames[index];
}
else
{
int index=(blend*count)/BLEND_PRECISION; // [0..count-1]
blend=(blend*count)%BLEND_PRECISION;
frame1=animation.frames[index];
frame2=animation.frames[index+1];
}
}
if (image!=-1)
{
HGDIOBJ bmp0=SelectObject(hSrc,m_Bitmap);
POINT pos={0,image*m_Size.cy+m_YOffset};
UpdateLayeredWindow(m_hWnd,NULL,NULL,&size,hSrc,&pos,0,&func,ULW_ALPHA);
SelectObject(hSrc,bmp0);
}
else if (m_Bits)
{
// blend the two images
int n=m_Size.cx*m_Size.cy;
int n1=frame1*n;
int n2=frame2*n;
for (int i=0;i<n;i++)
{
unsigned int pixel1=m_Bits[i+n1];
unsigned int pixel2=m_Bits[i+n2];
int a1=(pixel1>>24);
int r1=(pixel1>>16)&255;
int g1=(pixel1>>8)&255;
int b1=(pixel1)&255;
int a2=(pixel2>>24);
int r2=(pixel2>>16)&255;
int g2=(pixel2>>8)&255;
int b2=(pixel2)&255;
int a=a1+(a2-a1)*blend/BLEND_PRECISION;
int r=r1+(r2-r1)*blend/BLEND_PRECISION;
int g=g1+(g2-g1)*blend/BLEND_PRECISION;
int b=b1+(b2-b1)*blend/BLEND_PRECISION;
m_BlendBits[i]=(a<<24)|(r<<16)|(g<<8)|b;
}
HGDIOBJ bmp0=SelectObject(hSrc,m_Blendmap);
POINT pos={0,0};
UpdateLayeredWindow(m_hWnd,NULL,NULL,&size,hSrc,&pos,0,&func,ULW_ALPHA);
SelectObject(hSrc,bmp0);
}
}
DeleteDC(hSrc);
}
void CStartButton::SetHot( bool bHot )
{
if (m_bHot!=bHot)
{
m_bHot=bHot;
if (!m_bPressed)
{
if (bHot)
CMenuContainer::PlayMenuSound(SOUND_BUTTON_HOVER);
SetTimer(TIMER_BLEND,30);
}
}
}
LRESULT CStartButton::OnMouseMove( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled )
{
SetTimer(TIMER_LEAVE,30);
SetHot(true);
return 0;
}
void CStartButton::TaskBarMouseMove( void )
{
SetHot(true);
SetTimer(CStartButton::TIMER_LEAVE,30);
}
LRESULT CStartButton::OnTimer( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled )
{
if (wParam==TIMER_BLEND)
{
int duration=m_Animations[m_bHot?0:1].duration;
int blend;
if (duration>0)
{
int dp=(30*BLEND_PRECISION)/duration;
blend=m_HotBlend+(m_bHot?dp:-dp);
if (blend<0) blend=0;
if (blend>BLEND_PRECISION) blend=BLEND_PRECISION;
}
else
{
blend=m_bHot?BLEND_PRECISION:0;
}
if (blend!=m_HotBlend)
{
m_HotBlend=blend;
UpdateButton();
}
else
KillTimer(TIMER_BLEND);
}
else if (wParam==TIMER_LEAVE)
{
CPoint pt(GetMessagePos());
if (WindowFromPoint(pt)!=m_hWnd && !PointAroundStartButton(m_TaskbarId))
{
KillTimer(TIMER_LEAVE);
SetHot(false);
}
}
else
bHandled=FALSE;
return 0;
}
LRESULT CStartButton::OnSettingChange( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled )
{
UpdateButton();
bHandled=FALSE;
return 0;
}
LRESULT CStartButton::OnThemeChanged( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled )
{
if (m_Theme) CloseThemeData(m_Theme);
m_Theme=NULL;
HIGHCONTRAST contrast={sizeof(contrast)};
if (GetWinVersion()>=WIN_VER_WIN8 && SystemParametersInfo(SPI_GETHIGHCONTRAST,sizeof(contrast),&contrast,0) && (contrast.dwFlags&HCF_HIGHCONTRASTON))
{
// only use themes on Win8 with high contrast
m_Theme=OpenThemeData(m_hWnd,L"button");
UpdateButton();
}
return 0;
}
LRESULT CStartButton::OnPointer( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled )
{
POINTER_INPUT_TYPE type;
GetPointerType2(GET_POINTERID_WPARAM(wParam),&type);
if (type==PT_TOUCH)
return GetParent().SendMessage(uMsg,wParam,lParam);
bHandled=FALSE;
return 0;
}
void CStartButton::SetPressed( bool bPressed )
{
if (m_bPressed!=bPressed)
{
m_bPressed=bPressed;
m_HotBlend=m_bHot?BLEND_PRECISION:0;
KillTimer(TIMER_BLEND);
TOOLINFO tool={sizeof(tool),TTF_CENTERTIP|TTF_SUBCLASS|TTF_IDISHWND|TTF_TRANSPARENT|(m_bRTL?TTF_RTLREADING:0U),m_hWnd};
tool.uId=(UINT_PTR)m_hWnd;
CString startStr=GetSettingString(L"StartButtonTip");
const wchar_t *startText=startStr;
if (startText[0]=='$')
startText=FindTranslation(startText+1,L"Start");
wchar_t buf[256];
Strcpy(buf,_countof(buf),startText);
DoEnvironmentSubst(buf,_countof(buf));
tool.lpszText=buf;
m_Tooltip.SendMessage(bPressed?TTM_DELTOOL:TTM_ADDTOOL,0,(LPARAM)&tool);
UpdateButton();
}
}
TStartButtonType GetStartButtonType( void )
{
bool bDef;
TStartButtonType buttonType=(TStartButtonType)GetSettingInt(L"StartButtonType",bDef);
if (bDef)
{
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));
}
buttonType=bClassic?START_BUTTON_CLASSIC:START_BUTTON_AERO;
}
return buttonType;
}
void CStartButton::ParseAnimation( Animation &animation, const std::vector<unsigned int> &pixels, int &index, int totalFrames )
{
animation.duration=0;
animation.bBlend=true;
if (index>=(int)pixels.size())
{
animation.frames.clear();
return;
}
animation.duration=((pixels[index]&255)*1000)/60;
animation.bBlend=((pixels[index]>>16)&255)==1;
int ranges=(pixels[index]>>8)&255;
if (ranges>0 && index+ranges<(int)pixels.size())
{
animation.frames.clear();
for (int r=1;r<=ranges;r++)
{
int from=pixels[index+r]&255;
if (from>totalFrames-1) from=totalFrames-1;
int to=(pixels[index+r]>>16)&255;
if (to>totalFrames-1) to=totalFrames-1;
if (from<to)
{
for (int i=from;i<=to;i++)
animation.frames.push_back(i);
}
else if (from>to)
{
for (int i=from;i>=to;i--)
animation.frames.push_back(i);
}
else
{
animation.frames.push_back(from);
}
}
}
index+=ranges+1;
}
void CStartButton::LoadBitmap( void )
{
m_Size.cx=m_Size.cy=0;
if (m_Bitmap) DeleteObject(m_Bitmap);
if (m_Blendmap) DeleteObject(m_Blendmap);
m_Bitmap=m_Blendmap=NULL;
m_Bits=m_BlendBits=NULL;
TStartButtonType buttonType=GetStartButtonType();
m_bClassic=(buttonType==START_BUTTON_CLASSIC);
wchar_t path[_MAX_PATH];
SIZE size={0,0};
if (buttonType==START_BUTTON_CUSTOM)
{
Strcpy(path,_countof(path),GetSettingString(L"StartButtonPath"));
DoEnvironmentSubst(path,_countof(path));
size.cx=GetSettingInt(L"StartButtonSize");
}
m_YOffset=0;
m_Frames[0]=0; // Normal
m_Frames[1]=1; // Hot
m_Frames[2]=2; // Pressed
m_Animations[0].frames.resize(2); m_Animations[0].frames[0]=0; m_Animations[0].frames[1]=1; m_Animations[0].duration=300; m_Animations[0].bBlend=true; // NH
m_Animations[1].frames.resize(2); m_Animations[1].frames[0]=1; m_Animations[1].frames[1]=0; m_Animations[1].duration=300; m_Animations[1].bBlend=true; // HN
if (m_bClassic)
{
// classic theme
HDC hdc=CreateCompatibleDC(NULL);
HFONT font0=(HFONT)SelectObject(hdc,m_Font);
RECT rc={0,0,0,0};
CString startStr=GetSettingString(L"StartButtonText");
const wchar_t *startText=startStr;
if (startText[0]=='$')
startText=FindTranslation(startText+1,L"Start");
DrawText(hdc,startText,-1,&rc,DT_NOPREFIX|DT_SINGLELINE|DT_CALCRECT);
m_Size.cx=rc.right+START_ICON_SIZE+2*START_TEXT_PADDING+2*START_BUTTON_PADDING+2*START_BUTTON_OFFSET;
m_Size.cy=rc.bottom;
if (m_Size.cy<START_ICON_SIZE) m_Size.cy=START_ICON_SIZE;
m_Size.cy+=2*START_BUTTON_PADDING+2*START_BUTTON_OFFSET;
DeleteDC(hdc);
}
else
{
bool bResource=false;
std::vector<unsigned int> buttonAnim;
if (*path)
{
m_Bitmap=LoadImageFile(path,&size,true,true,&buttonAnim);
}
if (!m_Bitmap)
{
int id;
int dpi=CItemManager::GetDPI(false);
if (dpi<120)
id=IDB_BUTTON96;
else if (dpi<144)
id=IDB_BUTTON120;
else if (dpi<180)
id=IDB_BUTTON144;
else
id=IDB_BUTTON180;
m_Bitmap=LoadImageResource(g_Instance,MAKEINTRESOURCE(id),true,true);
bResource=true;
}
BITMAP info;
GetObject(m_Bitmap,sizeof(info),&info);
m_Size.cx=info.bmWidth;
m_Size.cy=info.bmHeight;
m_Bits=(unsigned int*)info.bmBits;
if (buttonAnim.empty() && info.bmWidth>=10 && (m_Bits[0]&0xFFFFFF)==ANIM_BUTTON_TAG1 && (m_Bits[1]&0xFFFFFF)==ANIM_BUTTON_TAG2)
{
m_YOffset=(m_Bits[2]>>16)&255;
if (m_YOffset>info.bmHeight) m_YOffset=info.bmHeight;
if (m_YOffset>0)
{
int size=info.bmWidth*m_YOffset;
buttonAnim.resize(size);
memcpy(&buttonAnim[0],m_Bits,size*4);
m_Bits+=size;
m_Size.cy=info.bmHeight-m_YOffset;
}
}
if (!buttonAnim.empty())
{
int total=buttonAnim[2]&255;
if (total<1) total=1;
if (total>info.bmHeight-1) total=info.bmHeight-1;
m_Size.cy/=total;
m_Frames[0]=buttonAnim[3]&255; // Normal
if (m_Frames[0]>total-1) m_Frames[0]=total-1;
m_Frames[1]=buttonAnim[4]&255; // Hot
if (m_Frames[1]>total-1) m_Frames[1]=total-1;
m_Frames[2]=buttonAnim[5]&255; // Pressed
if (m_Frames[2]>total-1) m_Frames[2]=total-1;
m_Animations[0].frames[0]=m_Animations[1].frames[1]=m_Frames[0];
m_Animations[0].frames[1]=m_Animations[1].frames[0]=m_Frames[1];
int index=6;
ParseAnimation(m_Animations[0],buttonAnim,index,total);
ParseAnimation(m_Animations[1],buttonAnim,index,total);
}
else
{
m_Size.cy/=3;
}
}
if (m_Size.cx>0)
{
BITMAPINFO bi={0};
bi.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
bi.bmiHeader.biWidth=m_Size.cx;
bi.bmiHeader.biHeight=-m_Size.cy;
bi.bmiHeader.biPlanes=1;
bi.bmiHeader.biBitCount=32;
HDC hdc=CreateCompatibleDC(NULL);
m_Blendmap=CreateDIBSection(hdc,&bi,DIB_RGB_COLORS,(void**)&m_BlendBits,NULL,0);
DeleteDC(hdc);
}
}
static std::map<int,CStartButton> g_StartButtons;
HWND CreateStartButton( int taskbarId, HWND taskBar, HWND rebar, const RECT &rcTask )
{
bool bRTL=(GetWindowLongPtr(rebar,GWL_EXSTYLE)&WS_EX_LAYOUTRTL)!=0;
DWORD styleTopmost=GetWindowLongPtr(taskBar,GWL_EXSTYLE)&WS_EX_TOPMOST;
CStartButton &button=g_StartButtons[taskbarId];
button.Create(taskBar,NULL,NULL,WS_POPUP,styleTopmost|WS_EX_TOOLWINDOW|WS_EX_LAYERED,0U,(void*)(intptr_t)(taskbarId*2+(bRTL?1:0)));
SIZE size=button.GetSize();
RECT rcButton;
MONITORINFO info;
UINT uEdge=GetTaskbarPosition(taskBar,&info,NULL,NULL);
if (uEdge==ABE_LEFT || uEdge==ABE_RIGHT)
{
if (GetSettingInt(L"StartButtonType")!=START_BUTTON_CUSTOM || !GetSettingBool(L"StartButtonAlign"))
rcButton.left=(rcTask.left+rcTask.right-size.cx)/2;
else if (uEdge==ABE_LEFT)
rcButton.left=rcTask.left;
else
rcButton.left=rcTask.right-size.cx;
rcButton.top=rcTask.top;
}
else
{
if (bRTL)
rcButton.left=rcTask.right-size.cx;
else
rcButton.left=rcTask.left;
if (GetSettingInt(L"StartButtonType")!=START_BUTTON_CUSTOM || !GetSettingBool(L"StartButtonAlign"))
rcButton.top=(rcTask.top+rcTask.bottom-size.cy)/2;
else if (uEdge==ABE_TOP)
rcButton.top=rcTask.top;
else
rcButton.top=rcTask.bottom-size.cy;
}
rcButton.right=rcButton.left+size.cx;
rcButton.bottom=rcButton.top+size.cy;
g_bAllowMoveButton=true;
button.SetWindowPos(HWND_TOP,&rcButton,SWP_SHOWWINDOW|SWP_NOOWNERZORDER|SWP_NOACTIVATE);
g_bAllowMoveButton=false;
RECT rc;
IntersectRect(&rc,&rcButton,&info.rcMonitor);
HRGN rgn=CreateRectRgn(rc.left-rcButton.left,rc.top-rcButton.top,rc.right-rcButton.left,rc.bottom-rcButton.top);
if (!SetWindowRgn(button,rgn,FALSE))
{
AddTrackedObject(rgn);
DeleteObject(rgn);
}
button.UpdateButton();
return button.m_hWnd;
}
void DestroyStartButton( int taskbarId )
{
std::map<int,CStartButton>::iterator it=g_StartButtons.find(taskbarId);
if (it!=g_StartButtons.end())
{
if (it->second.m_hWnd)
it->second.DestroyWindow();
g_StartButtons.erase(it);
}
}
void UpdateStartButton( int taskbarId )
{
std::map<int,CStartButton>::iterator it=g_StartButtons.find(taskbarId);
if (it!=g_StartButtons.end())
it->second.UpdateButton();
}
void PressStartButton( int taskbarId, bool bPressed )
{
std::map<int,CStartButton>::iterator it=g_StartButtons.find(taskbarId);
if (it!=g_StartButtons.end())
it->second.SetPressed(bPressed);
}
SIZE GetStartButtonSize( int taskbarId )
{
std::map<int,CStartButton>::iterator it=g_StartButtons.find(taskbarId);
if (it!=g_StartButtons.end())
return it->second.GetSize();
SIZE size={0,0};
return size;
}
bool IsStartButtonSmallIcons( int taskbarId )
{
std::map<int,CStartButton>::iterator it=g_StartButtons.find(taskbarId);
if (it!=g_StartButtons.end())
return it->second.GetSmallIcons();
return false;
}
bool IsTaskbarSmallIcons( void )
{
CRegKey regKey;
if (regKey.Open(HKEY_CURRENT_USER,L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced")!=ERROR_SUCCESS)
return true;
DWORD val;
return regKey.QueryDWORDValue(L"TaskbarSmallIcons",val)!=ERROR_SUCCESS || val;
}
void TaskBarMouseMove( int taskbarId )
{
std::map<int,CStartButton>::iterator it=g_StartButtons.find(taskbarId);
if (it!=g_StartButtons.end())
it->second.TaskBarMouseMove();
}

View File

@@ -0,0 +1,25 @@
// Classic Shell (c) 2009-2017, Ivo Beltchev
// Classic Start (c) 2017-2018, The Passionate-Coder Team
// Confidential information of Ivo Beltchev. Not for disclosure or distribution without prior written consent from the author
#pragma once
enum TStartButtonType
{
START_BUTTON_AERO,
START_BUTTON_CLASSIC,
START_BUTTON_CUSTOM,
// START_BUTTON_METRO,
};
HWND CreateStartButton( int taskbarId, HWND taskBar, HWND rebar, const RECT &rcTask );
void DestroyStartButton( int taskbarId );
void UpdateStartButton( int taskbarId );
void PressStartButton( int taskbarId, bool bPressed );
TStartButtonType GetStartButtonType( void );
SIZE GetStartButtonSize( int taskbarId );
bool IsStartButtonSmallIcons( int taskbarId );
bool IsTaskbarSmallIcons( void );
void TaskBarMouseMove( int taskbarId );
extern bool g_bAllowMoveButton;

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,130 @@
// Classic Shell (c) 2009-2017, Ivo Beltchev
// Classic Start (c) 2017-2018, The Passionate-Coder Team
// Confidential information of Ivo Beltchev. Not for disclosure or distribution without prior written consent from the author
#pragma once
#include <vector>
#ifdef CLASSICSTARTMENUDLL_EXPORTS
#define STARTMENUAPI __declspec(dllexport)
#else
#define STARTMENUAPI __declspec(dllimport)
#endif
// Find the taskbar window for the given process
STARTMENUAPI HWND FindTaskBar( DWORD process );
// WH_GETMESSAGE hook for the explorer's GUI thread. The start menu exe uses this hook to inject code into the explorer process
STARTMENUAPI LRESULT CALLBACK HookInject( int code, WPARAM wParam, LPARAM lParam );
// Toggle the start menu. bKeyboard - set to true to show the keyboard cues
STARTMENUAPI HWND ToggleStartMenu( int taskbarId, bool bKeyboard );
STARTMENUAPI void InitManagers( bool bNohook );
STARTMENUAPI void CloseManagers( bool bNohook );
STARTMENUAPI void WaitDllInitThread( void );
STARTMENUAPI bool DllGetSettingBool( const wchar_t *name );
STARTMENUAPI int DllGetSettingInt( const wchar_t *name );
STARTMENUAPI void DllUpdateSettings( void );
STARTMENUAPI CString DllLoadStringEx( int stringID );
STARTMENUAPI void DllLogToFile( const wchar_t *location, const wchar_t *message, ... );
#ifndef _WIN64
enum TSettingsComponent;
STARTMENUAPI bool DllSaveAdmx( TSettingsComponent component, const char *admxFile, const char *admlFile, const char *docFile );
STARTMENUAPI void DllLoadTranslationResources( HINSTANCE hLngInstance, int *pDialogs );
#endif
STARTMENUAPI bool DllExecuteNamedCommand( const wchar_t *command );
#ifdef TRACK_GDI_RESOURCES
STARTMENUAPI void DllDumpResourceLeaks( void );
#endif
// Enable or disable the tooltip for the start button
void EnableStartTooltip( bool bEnable );
struct TaskbarInfo
{
TaskbarInfo( void ) { taskbarId=pointerId=0; taskBar=startButton=oldButton=rebar=taskList=chevron=desktop=NULL; startButtonSize.cx=startButtonSize.cy=0; oldButtonSize.cx=oldButtonSize.cy=0; bTimer=bCustomLook=bReplaceButton=bHideButton=bRecreatingButton=bThemeChanging=false; }
int taskbarId;
HWND taskBar;
HWND startButton; // either own start button or the win7 start button (depending on bReplaceButton)
HWND oldButton; // win81 start button (child of taskBar)
HWND rebar;
HWND taskList;
HWND chevron;
HWND desktop;
SIZE startButtonSize;
SIZE oldButtonSize;
int pointerId;
bool bTimer;
bool bCustomLook;
bool bReplaceButton;
bool bHideButton;
bool bRecreatingButton;
bool bThemeChanging;
std::vector<HWND> trayButtons; // ordered by Z order (for win10)
std::vector<HWND> taskbarParts;
CComPtr<IDropTarget> pOriginalTarget;
bool HasPart( HWND part ) const;
};
TaskbarInfo *GetTaskbarInfo( size_t taskbarId );
UINT GetTaskbarPosition( HWND taskBar, MONITORINFO *pInfo, HMONITOR *pMonitor, RECT *pRc );
extern HWND STARTMENUAPI g_TaskBar, g_OwnerWindow;
extern HWND g_TopWin7Menu, g_AllPrograms, g_ProgramsButton, g_UserPic; // from the Windows menu
extern HWND g_ProgWin;
extern HMONITOR g_WSMHMonitor;
extern int g_CurrentCSMTaskbar, g_CurrentWSMTaskbar;
enum TMenuMsgParam // wParam for the ClassicStartMenu.StartMenuMsg message
{
MSG_TOGGLE, // toggles the classic start menu
MSG_TOGGLENEW, // toggles the Windows start menu
MSG_OPEN, // opens the classic start menu
MSG_SETTINGS, // show Settings
MSG_SHIFTWIN, // Shift+Win was pressed
MSG_DRAG, // an item is dragged on the start button
MSG_SHIFTDRAG, // an item is dragged on the start button (Shift is pressed)
MSG_NOP, // does nothing (basically just finds the Windows menu)
MSG_EXIT, // unhook everything and exit
MSG_HOTKEYS, // updates the hotkeys
MSG_NEWTASKBAR, // new taskbar is created, lParam is the HWND
MSG_WINXMENU, // open the Win+X menu
MSG_METROTHUMBNAIL, // refresh the Metro thumbnail
MSG_REDRAWTASKBAR, // redraw taskbar, lParam is the HWND (NULL for all)
MSG_RELOADSETTINGS, // reloads the settings from the registry
MSG_SETMONITOR, // sets the start screen monitor
};
STARTMENUAPI extern enum _MINIDUMP_TYPE MiniDumpType;
STARTMENUAPI LONG _stdcall TopLevelFilter( _EXCEPTION_POINTERS *pExceptionInfo );
enum THotkeys
{
HOTKEYS_NORMAL,
HOTKEYS_SETTINGS,
HOTKEYS_CLEAR,
};
// Set the hotkeys and controls for the start menu
void EnableHotkeys( THotkeys enable );
bool PointAroundStartButton( size_t taskbarId, const CPoint &pt=CPoint(GetMessagePos()) );
void ResetHotCorners( void );
void RedrawTaskbars( void );
enum TUpdateTaskbar
{
TASKBAR_CLEAR,
TASKBAR_UPDATE,
TASKBAR_UPDATE_TEXTURE,
TASKBAR_RECREATE_BUTTONS,
};
void UpdateTaskBars( TUpdateTaskbar update );
HBITMAP GetStartScreenIcon( int size );

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,359 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Setup|Win32">
<Configuration>Setup</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Setup|x64">
<Configuration>Setup</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{85DEECBB-1F9B-4983-9D54-3BF42182B7E7}</ProjectGuid>
<RootNamespace>ClassicStartMenuDLL</RootNamespace>
<Keyword>Win32Proj</Keyword>
<WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Setup|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v141</PlatformToolset>
<UseOfAtl>Static</UseOfAtl>
<CharacterSet>Unicode</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v141</PlatformToolset>
<UseOfAtl>Static</UseOfAtl>
<CharacterSet>Unicode</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v141</PlatformToolset>
<UseOfAtl>Static</UseOfAtl>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Setup|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v141</PlatformToolset>
<UseOfAtl>Static</UseOfAtl>
<CharacterSet>Unicode</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v141</PlatformToolset>
<UseOfAtl>Static</UseOfAtl>
<CharacterSet>Unicode</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v141</PlatformToolset>
<UseOfAtl>Static</UseOfAtl>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Setup|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\..\Version.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\..\Version.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\..\Version.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Setup|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\..\Version.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\..\Version.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\..\Version.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<OutDir>..\$(Configuration)\</OutDir>
<IntDir>$(Configuration)\</IntDir>
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<OutDir>..\$(Configuration)64\</OutDir>
<IntDir>$(Configuration)64\</IntDir>
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<OutDir>..\$(Configuration)\</OutDir>
<IntDir>$(Configuration)\</IntDir>
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<OutDir>..\$(Configuration)64\</OutDir>
<IntDir>$(Configuration)64\</IntDir>
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Setup|Win32'">
<OutDir>..\$(Configuration)\</OutDir>
<IntDir>$(Configuration)\</IntDir>
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Setup|x64'">
<OutDir>..\$(Configuration)64\</OutDir>
<IntDir>$(Configuration)64\</IntDir>
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\..\ClassicStartLib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;CLASSICSTARTMENUDLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>false</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(IntDir);..\..\ClassicStartLib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ResourceCompile>
<Link>
<AdditionalDependencies>comctl32.lib;uxtheme.lib;WtsApi32.lib;Secur32.lib;Msimg32.lib;Netapi32.lib;dwmapi.lib;PowrProf.lib;Oleacc.lib;winmm.lib;htmlhelp.lib;wininet.lib;structuredquery.lib;Propsys.lib;wintrust.lib;crypt32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\..\ClassicStartLib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;CLASSICSTARTMENUDLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>false</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(IntDir);..\..\ClassicStartLib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ResourceCompile>
<Link>
<AdditionalDependencies>comctl32.lib;uxtheme.lib;WtsApi32.lib;Secur32.lib;Msimg32.lib;Netapi32.lib;dwmapi.lib;PowrProf.lib;Oleacc.lib;winmm.lib;htmlhelp.lib;wininet.lib;structuredquery.lib;Propsys.lib;wintrust.lib;crypt32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<Optimization>MaxSpeed</Optimization>
<AdditionalIncludeDirectories>..\..\ClassicStartLib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;CLASSICSTARTMENUDLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(IntDir);..\..\ClassicStartLib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ResourceCompile>
<Link>
<AdditionalDependencies>comctl32.lib;uxtheme.lib;WtsApi32.lib;Secur32.lib;Msimg32.lib;Netapi32.lib;dwmapi.lib;PowrProf.lib;Oleacc.lib;winmm.lib;htmlhelp.lib;wininet.lib;structuredquery.lib;Propsys.lib;wintrust.lib;crypt32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<Optimization>MaxSpeed</Optimization>
<AdditionalIncludeDirectories>..\..\ClassicStartLib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;CLASSICSTARTMENUDLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(IntDir);..\..\ClassicStartLib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ResourceCompile>
<Link>
<AdditionalDependencies>comctl32.lib;uxtheme.lib;WtsApi32.lib;Secur32.lib;Msimg32.lib;Netapi32.lib;dwmapi.lib;PowrProf.lib;Oleacc.lib;winmm.lib;htmlhelp.lib;wininet.lib;structuredquery.lib;Propsys.lib;wintrust.lib;crypt32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Setup|Win32'">
<ClCompile>
<Optimization>MaxSpeed</Optimization>
<AdditionalIncludeDirectories>..\..\ClassicStartLib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;CLASSICSTARTMENUDLL_EXPORTS;BUILD_SETUP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(IntDir);..\..\ClassicStartLib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ResourceCompile>
<Link>
<AdditionalDependencies>comctl32.lib;uxtheme.lib;WtsApi32.lib;Secur32.lib;Msimg32.lib;Netapi32.lib;dwmapi.lib;PowrProf.lib;Oleacc.lib;winmm.lib;htmlhelp.lib;wininet.lib;structuredquery.lib;Propsys.lib;wintrust.lib;crypt32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Setup|x64'">
<ClCompile>
<Optimization>MaxSpeed</Optimization>
<AdditionalIncludeDirectories>..\..\ClassicStartLib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;CLASSICSTARTMENUDLL_EXPORTS;BUILD_SETUP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(IntDir);..\..\ClassicStartLib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ResourceCompile>
<Link>
<AdditionalDependencies>comctl32.lib;uxtheme.lib;WtsApi32.lib;Secur32.lib;Msimg32.lib;Netapi32.lib;dwmapi.lib;PowrProf.lib;Oleacc.lib;winmm.lib;htmlhelp.lib;wininet.lib;structuredquery.lib;Propsys.lib;wintrust.lib;crypt32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="Accessibility.cpp" />
<ClCompile Include="ClassicStartButton.cpp" />
<ClCompile Include="ClassicStartMenuDLL.cpp" />
<ClCompile Include="CustomMenu.cpp" />
<ClCompile Include="dllmain.cpp" />
<ClCompile Include="DragDrop.cpp" />
<ClCompile Include="ItemManager.cpp" />
<ClCompile Include="JumpLists.cpp" />
<ClCompile Include="LogManager.cpp" />
<ClCompile Include="MenuCommands.cpp" />
<ClCompile Include="MenuContainer.cpp" />
<ClCompile Include="MenuPaint.cpp" />
<ClCompile Include="MetroLinkManager.cpp" />
<ClCompile Include="ProgramsTree.cpp" />
<ClCompile Include="SearchManager.cpp" />
<ClCompile Include="SettingsUI.cpp" />
<ClCompile Include="SkinManager.cpp" />
<ClCompile Include="stdafx.cpp">
<PrecompiledHeader>Create</PrecompiledHeader>
</ClCompile>
<ClCompile Include="TouchHelper.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="Accessibility.h" />
<ClInclude Include="ClassicStartButton.h" />
<ClInclude Include="ClassicStartMenuDLL.h" />
<ClInclude Include="CustomMenu.h" />
<ClInclude Include="dllmain.h" />
<ClInclude Include="DragDrop.h" />
<ClInclude Include="ItemManager.h" />
<ClInclude Include="JumpLists.h" />
<ClInclude Include="LogManager.h" />
<ClInclude Include="MenuContainer.h" />
<ClInclude Include="MetroLinkManager.h" />
<ClInclude Include="ProgramsTree.h" />
<ClInclude Include="resource.h" />
<ClInclude Include="SearchManager.h" />
<ClInclude Include="SettingsUI.h" />
<ClInclude Include="SkinManager.h" />
<ClInclude Include="stdafx.h" />
<ClInclude Include="targetver.h" />
<ClInclude Include="TouchHelper.h" />
</ItemGroup>
<ItemGroup>
<Image Include="..\..\ClassicStartSetup\ClassicStart.ico" />
<Image Include="apps.ico" />
<Image Include="btn_aero.ico" />
<Image Include="btn_classic.bmp" />
<Image Include="button120.png" />
<Image Include="button144.png" />
<Image Include="button180.png" />
<Image Include="button96.png" />
<Image Include="menu_arrows.bmp" />
<Image Include="menu_arrows150.bmp" />
<Image Include="search_icons.bmp" />
<Image Include="start.ico" />
<Image Include="start10.ico" />
<Image Include="style_7.bmp" />
<Image Include="style_7150.bmp" />
<Image Include="style_classic.bmp" />
<Image Include="style_classic150.bmp" />
<Image Include="style_vista.bmp" />
<Image Include="style_vista150.bmp" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="ClassicStartMenuDLL.rc" />
</ItemGroup>
<ItemGroup>
<Text Include="SkinDescription.txt" />
<Text Include="SkinDescription7.txt" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\ClassicStartLib\ClassicStartLib.vcxproj">
<Project>{d42fe717-485b-492d-884a-1999f6d51154}</Project>
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@@ -0,0 +1,207 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="Accessibility.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="ClassicStartButton.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="ClassicStartMenuDLL.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="CustomMenu.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="dllmain.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="DragDrop.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="ItemManager.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="JumpLists.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="LogManager.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="MenuCommands.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="MenuContainer.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="MenuPaint.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="MetroLinkManager.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="ProgramsTree.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="SearchManager.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="SettingsUI.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="SkinManager.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="stdafx.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="TouchHelper.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Accessibility.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ClassicStartButton.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ClassicStartMenuDLL.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="CustomMenu.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="dllmain.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="DragDrop.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ItemManager.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="JumpLists.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="LogManager.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="MenuContainer.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="MetroLinkManager.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ProgramsTree.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="SearchManager.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="SettingsUI.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="SkinManager.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="stdafx.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="targetver.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="TouchHelper.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="resource.h">
<Filter>Resource Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Image Include="apps.ico">
<Filter>Resource Files</Filter>
</Image>
<Image Include="btn_aero.ico">
<Filter>Resource Files</Filter>
</Image>
<Image Include="btn_classic.bmp">
<Filter>Resource Files</Filter>
</Image>
<Image Include="button120.png">
<Filter>Resource Files</Filter>
</Image>
<Image Include="button144.png">
<Filter>Resource Files</Filter>
</Image>
<Image Include="button180.png">
<Filter>Resource Files</Filter>
</Image>
<Image Include="button96.png">
<Filter>Resource Files</Filter>
</Image>
<Image Include="..\..\ClassicStartSetup\ClassicStart.ico">
<Filter>Resource Files</Filter>
</Image>
<Image Include="menu_arrows.bmp">
<Filter>Resource Files</Filter>
</Image>
<Image Include="menu_arrows150.bmp">
<Filter>Resource Files</Filter>
</Image>
<Image Include="search_icons.bmp">
<Filter>Resource Files</Filter>
</Image>
<Image Include="start.ico">
<Filter>Resource Files</Filter>
</Image>
<Image Include="start10.ico">
<Filter>Resource Files</Filter>
</Image>
<Image Include="style_7.bmp">
<Filter>Resource Files</Filter>
</Image>
<Image Include="style_7150.bmp">
<Filter>Resource Files</Filter>
</Image>
<Image Include="style_classic.bmp">
<Filter>Resource Files</Filter>
</Image>
<Image Include="style_classic150.bmp">
<Filter>Resource Files</Filter>
</Image>
<Image Include="style_vista.bmp">
<Filter>Resource Files</Filter>
</Image>
<Image Include="style_vista150.bmp">
<Filter>Resource Files</Filter>
</Image>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="ClassicStartMenuDLL.rc">
<Filter>Resource Files</Filter>
</ResourceCompile>
</ItemGroup>
<ItemGroup>
<Text Include="SkinDescription.txt">
<Filter>Resource Files</Filter>
</Text>
<Text Include="SkinDescription7.txt">
<Filter>Resource Files</Filter>
</Text>
</ItemGroup>
</Project>

View File

@@ -0,0 +1,618 @@
// Classic Shell (c) 2009-2017, Ivo Beltchev
// Classic Start (c) 2017-2018, The Passionate-Coder Team
// Confidential information of Ivo Beltchev. Not for disclosure or distribution without prior written consent from the author
#include "stdafx.h"
#include "CustomMenu.h"
#include "SettingsParser.h"
#include "Translations.h"
#include "MenuContainer.h"
#include "Settings.h"
#include "SettingsUI.h"
#include "FNVHash.h"
#include "ResourceHelper.h"
#include "resource.h"
#include <algorithm>
// This table defines the standard menu items
static StdMenuItem g_StdMenu[]=
{
// * means the command is not executable (for things like Settings, or for items that have FOLDERID)
{L"*programs",MENU_PROGRAMS,&FOLDERID_Programs,&FOLDERID_CommonPrograms},
{L"*favorites",MENU_FAVORITES,&FOLDERID_Favorites},
{L"*computer",MENU_COMPUTER,&FOLDERID_ComputerFolder},
{L"*recent_documents",MENU_DOCUMENTS,&FOLDERID_Recent},
{L"*settings",MENU_SETTINGS},
{L"*search",MENU_SEARCH},
{L"help",MENU_HELP},
{L"run",MENU_RUN},
{L"logoff",MENU_LOGOFF},
{L"undock",MENU_UNDOCK},
{L"monitor_off",MENU_MONITOROFF},
{L"disconnect",MENU_DISCONNECT},
{L"shutdown_box",MENU_SHUTDOWN_BOX},
{L"*user_files",MENU_USERFILES,&FOLDERID_UsersFiles},
{L"*user_documents",MENU_USERDOCUMENTS,&FOLDERID_Documents},
{L"*user_pictures",MENU_USERPICTURES,&FOLDERID_Pictures},
{L"*control_panel",MENU_CONTROLPANEL,&FOLDERID_ControlPanelFolder},
{L"pc_settings",MENU_PCSETTINGS},
{L"windows_security",MENU_SECURITY},
{L"*network_connections",MENU_NETWORK,&FOLDERID_ConnectionsFolder},
{L"*printers",MENU_PRINTERS,&FOLDERID_PrintersFolder},
{L"taskbar_settings",MENU_TASKBAR},
{L"programs_features",MENU_FEATURES},
{L"menu_settings",MENU_CLASSIC_SETTINGS},
{L"search_files",MENU_SEARCH_FILES},
{L"search_printer",MENU_SEARCH_PRINTER},
{L"search_computers",MENU_SEARCH_COMPUTERS},
{L"search_people",MENU_SEARCH_PEOPLE},
{L"sleep",MENU_SLEEP},
{L"hibernate",MENU_HIBERNATE},
{L"restart",MENU_RESTART},
{L"restart_noupdate",MENU_RESTART_NOUPDATE},
{L"shutdown",MENU_SHUTDOWN},
{L"shutdown_noupdate",MENU_SHUTDOWN_NOUPDATE},
{L"switch_user",MENU_SWITCHUSER},
{L"lock",MENU_LOCK},
{L"*recent_programs",MENU_RECENT_PROGRAMS},
{L"search_box",MENU_SEARCH_BOX},
{L"*apps",MENU_APPS},
{L"*fonts",MENU_CUSTOM,&FOLDERID_Fonts},
{L"*desktop",MENU_CUSTOM,&FOLDERID_Desktop},
{L"*admin",MENU_CUSTOM,&FOLDERID_CommonAdminTools,&FOLDERID_AdminTools},
{L"*startup",MENU_CUSTOM,&FOLDERID_Startup,&FOLDERID_CommonStartup},
{L"*user_music",MENU_CUSTOM,&FOLDERID_Music},
{L"*user_videos",MENU_CUSTOM,&FOLDERID_Videos},
{L"*downloads",MENU_CUSTOM,&FOLDERID_Downloads},
{L"*games",MENU_CUSTOM,&FOLDERID_Games},
{L"*links",MENU_CUSTOM,&FOLDERID_Links},
{L"*libraries",MENU_CUSTOM,&FOLDERID_Libraries},
{L"*lib_documents",MENU_CUSTOM,&FOLDERID_DocumentsLibrary},
{L"*lib_music",MENU_CUSTOM,&FOLDERID_MusicLibrary},
{L"*lib_pictures",MENU_CUSTOM,&FOLDERID_PicturesLibrary},
{L"*lib_videos",MENU_CUSTOM,&FOLDERID_VideosLibrary},
{L"*lib_tv",MENU_CUSTOM,&FOLDERID_RecordedTVLibrary},
{L"*homegroup",MENU_CUSTOM,&FOLDERID_HomeGroup},
{L"*network",MENU_CUSTOM,&FOLDERID_NetworkFolder},
{L"*devices",MENU_CUSTOM},
{L"*defaults",MENU_CUSTOM},
};
CStdCommand7 g_StdCommands7[]={
{L"separator",IDS_SEPARATOR_ITEM,NULL,NULL,NULL,NULL,NULL,0,CStdCommand7::ITEM_SINGLE}, // must be first
{L"favorites",0,NULL,NULL,L"imageres.dll,1024",&FOLDERID_Favorites,NULL,StdMenuItem::MENU_TRACK},
{L"recent_documents",0,NULL,NULL,NULL,&FOLDERID_Recent},
{L"computer",0,NULL,NULL,NULL,&FOLDERID_ComputerFolder,NULL,0,CStdCommand7::ITEM_COMPUTER},
{L"help",IDS_HELP_ITEM,L"$Menu.Help",L"$Menu.HelpTip",L"imageres.dll,99",NULL,NULL,0,CStdCommand7::ITEM_SINGLE},
{L"run",IDS_RUN_ITEM,L"$Menu.Run",L"$Menu.RunTip",L"imageres.dll,100",NULL,NULL,0,CStdCommand7::ITEM_SINGLE},
{L"windows_security",IDS_SECURITY_ITEM,L"$Menu.Security",L"$Menu.SecurityTip",L"shell32.dll,48",NULL,NULL,0,CStdCommand7::ITEM_SINGLE},
{L"user_files",IDS_SHOW_USERFILES,NULL,L"$Menu.UserFilesTip",NULL,&FOLDERID_UsersFiles},
{L"user_documents",0,NULL,L"$Menu.UserDocumentsTip",NULL,&FOLDERID_Documents},
{L"user_pictures",0,NULL,L"$Menu.UserPicturesTip",NULL,&FOLDERID_Pictures},
{L"user_music",0,NULL,L"$Menu.UserMusicTip",NULL,&FOLDERID_Music},
{L"user_videos",0,NULL,L"$Menu.UserVideosTip",NULL,&FOLDERID_Videos},
{L"control_panel",0,L"$Menu.ControlPanel",L"$Menu.ControlPanelTip",NULL,&FOLDERID_ControlPanelFolder,NULL,StdMenuItem::MENU_TRACK},
{L"pc_settings",IDS_PCSETTINGS,L"$Menu.PCSettings",L"",L"%windir%\\ImmersiveControlPanel\\SystemSettings.exe,10",NULL,NULL,StdMenuItem::MENU_TRACK,CStdCommand7::ITEM_SINGLE},
{L"network_connections",0,NULL,L"$Menu.NetworkTip",NULL,&FOLDERID_ConnectionsFolder},
{L"network",0,NULL,NULL,NULL,&FOLDERID_NetworkFolder,NULL,0,CStdCommand7::ITEM_SINGLE},
{L"printers",0,NULL,L"$Menu.PrintersTip",NULL,&FOLDERID_PrintersFolder},
{L"fonts",0,NULL,NULL,NULL,&FOLDERID_Fonts},
{L"desktop",0,NULL,NULL,NULL,&FOLDERID_Desktop},
{L"admin",0,NULL,L"$Menu.AdminToolsTip",L"imageres.dll,114",&FOLDERID_CommonAdminTools,NULL,StdMenuItem::MENU_TRACK},
{L"startup",0,NULL,NULL,NULL,&FOLDERID_Startup,NULL,StdMenuItem::MENU_TRACK},
{L"downloads",0,NULL,L"$Menu.DownloadTip",NULL,&FOLDERID_Downloads},
{L"games",0,NULL,L"$Menu.GamesTip",NULL,&FOLDERID_Games,NULL,StdMenuItem::MENU_TRACK},
{L"links",0,NULL,NULL,NULL,&FOLDERID_Links},
{L"libraries",0,NULL,NULL,NULL,&FOLDERID_Libraries},
{L"lib_documents",IDS_LIB_DOCS_ITEM,NULL,L"$Menu.DocumentsLibTip",NULL,&FOLDERID_DocumentsLibrary},
{L"lib_music",IDS_LIB_MUSIC_ITEM,NULL,L"$Menu.MusicLibTip",NULL,&FOLDERID_MusicLibrary},
{L"lib_pictures",IDS_LIB_PICS_ITEM,NULL,L"$Menu.PicturesLibTip",NULL,&FOLDERID_PicturesLibrary},
{L"lib_videos",IDS_LIB_VIDEOS_ITEM,NULL,L"$Menu.VideosLibTip",NULL,&FOLDERID_VideosLibrary},
{L"lib_tv",IDS_LIB_TV_ITEM,NULL,L"$Menu.RecordingsLibTip",NULL,&FOLDERID_RecordedTVLibrary},
{L"homegroup",0,NULL,L"$Menu.HomegroupTip",NULL,&FOLDERID_HomeGroup,NULL,0,CStdCommand7::ITEM_SINGLE},
{L"devices",0,NULL,NULL,NULL,NULL,L"::{26EE0668-A00A-44D7-9371-BEB064C98683}\\0\\::{A8A91A66-3A7D-4424-8D24-04E180695C7A}"},
{L"defaults",0,NULL,NULL,NULL,NULL,L"::{26EE0668-A00A-44D7-9371-BEB064C98683}\\0\\::{17CD9488-1228-4B2F-88CE-4298E93E0966}",0,CStdCommand7::ITEM_SINGLE},
{L"apps",IDS_METRO_APPS,L"$Menu.Apps",NULL,L",2",NULL,NULL,StdMenuItem::MENU_TRACK,CStdCommand7::ITEM_FOLDER},
{L"",IDS_CUSTOM_ITEM} // must be last
};
const int g_StdCommands7Count=_countof(g_StdCommands7);
// This table defines folders that need special treatment
SpecialFolder g_SpecialFolders[]=
{
{&FOLDERID_Games,SpecialFolder::FOLDER_NONEWFOLDER},
{&FOLDERID_ComputerFolder,SpecialFolder::FOLDER_NONEWFOLDER},
{&FOLDERID_RecycleBinFolder,SpecialFolder::FOLDER_NOSUBFOLDERS|SpecialFolder::FOLDER_NODROP},
{&FOLDERID_NetworkFolder,SpecialFolder::FOLDER_NODROP},
{&FOLDERID_ConnectionsFolder,SpecialFolder::FOLDER_NODROP|SpecialFolder::FOLDER_NOPATH},
{&FOLDERID_Recent,SpecialFolder::FOLDER_NODROP},
{&FOLDERID_ControlPanelFolder,SpecialFolder::FOLDER_NODROP},
{&FOLDERID_PrintersFolder,SpecialFolder::FOLDER_NODROP},
{&FOLDERID_HomeGroup,SpecialFolder::FOLDER_NODROP},
{NULL}
};
static std::vector<StdMenuItem> g_CustomMenu;
static unsigned int g_RootSettings;
static unsigned int g_MenuItemsHash;
static CSettingsParser g_CustomMenuParser;
static bool g_bSpecialFoldersInitialized;
void InitializeSpecialFolders( void )
{
if (!g_bSpecialFoldersInitialized)
{
g_bSpecialFoldersInitialized=true;
for (int i=0;g_SpecialFolders[i].folder;i++)
{
CComPtr<IShellItem> pItem;
if (SUCCEEDED(ShGetKnownFolderItem(*g_SpecialFolders[i].folder,&pItem)) && pItem)
{
CComString pPath;
pItem->GetDisplayName(SIGDN_DESKTOPABSOLUTEPARSING,&pPath);
pPath.MakeUpper();
Strcpy(g_SpecialFolders[i].PATH,_countof(g_SpecialFolders[i].PATH),pPath);
}
}
}
}
static const StdMenuItem *FindStdMenuItem( const wchar_t *command )
{
for (int i=0;i<_countof(g_StdMenu);i++)
{
const wchar_t *cmd=g_StdMenu[i].command;
if (*cmd=='*') cmd++;
if (_wcsicmp(cmd,command)==0)
return &g_StdMenu[i];
}
return NULL;
}
static unsigned int ParseItemSettings( const wchar_t *name )
{
wchar_t buf[256];
Sprintf(buf,_countof(buf),L"%s.Settings",name);
const wchar_t *str=g_CustomMenuParser.FindSetting(buf);
if (!str) return 0;
unsigned int settings=0;
while(*str)
{
wchar_t token[256];
str=GetToken(str,token,_countof(token),L", \t|;");
if (_wcsicmp(token,L"OPEN_UP")==0) settings|=StdMenuItem::MENU_OPENUP;
if (_wcsicmp(token,L"OPEN_UP_CHILDREN")==0) settings|=StdMenuItem::MENU_OPENUP_REC;
if (_wcsicmp(token,L"SORT_ZA")==0) settings|=StdMenuItem::MENU_SORTZA;
if (_wcsicmp(token,L"SORT_ZA_CHILDREN")==0) settings|=StdMenuItem::MENU_SORTZA_REC;
if (_wcsicmp(token,L"SORT_ONCE")==0) settings|=StdMenuItem::MENU_SORTONCE;
if (_wcsicmp(token,L"ITEMS_FIRST")==0) settings|=StdMenuItem::MENU_ITEMS_FIRST;
if (_wcsicmp(token,L"TRACK_RECENT")==0) settings|=StdMenuItem::MENU_TRACK;
if (_wcsicmp(token,L"NOTRACK_RECENT")==0) settings|=StdMenuItem::MENU_NOTRACK;
if (_wcsicmp(token,L"NOEXPAND")==0) settings|=StdMenuItem::MENU_NOEXPAND;
if (_wcsicmp(token,L"SINGLE_EXPAND")==0) settings|=StdMenuItem::MENU_SINGLE_EXPAND;
if (_wcsicmp(token,L"MULTICOLUMN")==0) settings|=StdMenuItem::MENU_MULTICOLUMN;
if (_wcsicmp(token,L"NOEXTENSIONS")==0) settings|=StdMenuItem::MENU_NOEXTENSIONS;
if (_wcsicmp(token,L"INLINE")==0) settings|=StdMenuItem::MENU_INLINE;
if (_wcsicmp(token,L"SPLIT")==0) settings|=StdMenuItem::MENU_SPLIT_BUTTON;
}
return settings;
}
static void ParseMenuItem( StdMenuItem &item, const wchar_t *name )
{
wchar_t buf[1024];
const wchar_t *str;
Sprintf(buf,_countof(buf),L"%s.Link",name);
str=g_CustomMenuParser.FindSetting(buf);
if (str)
{
// parse link
item.link=str;
const wchar_t *c=wcschr(item.link,'|');
if (c)
{
for (c++;*c==' ';)
c++;
item.link=c;
}
}
Sprintf(buf,_countof(buf),L"%s.Command",name);
str=g_CustomMenuParser.FindSetting(buf);
int custom7=-1;
if (str)
{
// parse command
const StdMenuItem *pItem=FindStdMenuItem(str);
if (pItem)
{
item.id=pItem->id;
item.folder1=pItem->folder1;
item.folder2=pItem->folder2;
if (item.id==MENU_CONTROLPANEL && GetSettingBool(L"ControlPanelCategories"))
item.command=L"::{26EE0668-A00A-44D7-9371-BEB064C98683}";
else if (item.id==MENU_SHUTDOWN_BOX && GetSettingInt(L"MenuStyle")==MENU_WIN7)
item.id=MENU_SHUTDOWN_BUTTON;
else if (*pItem->command!='*')
item.command=pItem->command;
}
else
{
item.id=MENU_CUSTOM;
item.command=str;
}
for (int i=0;i<g_StdCommands7Count;i++)
if (_wcsicmp(g_StdCommands7[i].command,str)==0)
{
custom7=i;
break;
}
}
Sprintf(buf,_countof(buf),L"%s.Label",name);
str=g_CustomMenuParser.FindSetting(buf);
if (str)
{
// parse name
if (*str=='$')
{
item.label=FindTranslation(str+1,NULL);
if (!item.label)
item.label=str;
}
else
item.label=str;
}
Sprintf(buf,_countof(buf),L"%s.Tip",name);
str=g_CustomMenuParser.FindSetting(buf);
if (str)
{
// parse name
if (*str=='$')
item.tip=FindTranslation(str+1,NULL);
else
item.tip=str;
}
Sprintf(buf,_countof(buf),L"%s.Icon",name);
item.iconPath=g_CustomMenuParser.FindSetting(buf);
item.settings=ParseItemSettings(name);
if (custom7>=0)
{
if (g_StdCommands7[custom7].flags&CStdCommand7::ITEM_SINGLE)
item.settings|=StdMenuItem::MENU_NOEXPAND;
if (g_StdCommands7[custom7].flags&CStdCommand7::ITEM_FOLDER)
item.settings&=~StdMenuItem::MENU_NOEXPAND;
}
}
const wchar_t *g_StartMenuItems7a=L"Items=COLUMN_PADDING, ProgramsMenu, SearchBoxItem, COLUMN_BREAK, ";
const wchar_t *g_StartMenuItems7b=
L" COLUMN_PADDING, ShutdownBoxItem\n"
L"ProgramsMenu.Command=programs\n"
L"ProgramsMenu.Label=$Menu.Programs\n"
L"ProgramsMenu.Tip=$Menu.ProgramsTip\n"
L"ProgramsMenu.Icon=none\n"
L"ProgramsMenu.Items=AppsMenu\n"
L"ProgramsMenu.Settings=ITEMS_FIRST\n"
L"AppsMenu.Command=apps\n"
L"AppsMenu.Label=$Menu.Apps\n"
L"AppsMenu.Icon=,2\n"
L"SearchBoxItem.Command=search_box\n"
L"SearchBoxItem.Label=$Menu.SearchPrograms\n"
L"SearchBoxItem.Icon=none\n"
L"SearchBoxItem.Settings=TRACK_RECENT, OPEN_UP\n"
L"ShutdownBoxItem.Command=shutdown_box\n"
L"ShutdownBoxItem.Label=shutdown\n"
L"ShutdownBoxItem.Icon=none\n"
L"ShutdownBoxItem.Items=SwitchUserItem, SecurityItem, LogOffItem, LockItem, DisconnectItem, UndockItem, SEPARATOR, RestartNUItem, RestartItem, SEPARATOR, SleepItem, HibernateItem, ShutdownNUItem, ShutdownItem\n"
L"ShutdownBoxItem.Settings=SPLIT\n"
L"SwitchUserItem.Command=switch_user\n"
L"SwitchUserItem.Label=$Menu.SwitchUser\n"
L"SwitchUserItem.Tip=$Menu.SwitchUserTip\n"
L"SwitchUserItem.Icon=none\n"
L"SecurityItem.Command=windows_security\n"
L"SecurityItem.Icon=none\n"
L"SecurityItem.Label=$Menu.Security\n"
L"SecurityItem.Tip=$Menu.SecurityTip\n"
L"LogOffItem.Command=logoff\n"
L"LogOffItem.Label=$Menu.LogOffShort\n"
L"LogOffItem.Tip=$Menu.LogOffTip\n"
L"LogOffItem.Icon=none\n"
L"LockItem.Command=lock\n"
L"LockItem.Label=$Menu.Lock\n"
L"LockItem.Tip=$Menu.LockTip\n"
L"LockItem.Icon=none\n"
L"DisconnectItem.Command=disconnect\n"
L"DisconnectItem.Label=$Menu.Disconnect\n"
L"DisconnectItem.Tip=$Menu.DisconnectTip\n"
L"DisconnectItem.Icon=none\n"
L"UndockItem.Command=undock\n"
L"UndockItem.Label=$Menu.Undock\n"
L"UndockItem.Tip=$Menu.UndockTip\n"
L"UndockItem.Icon=none\n"
L"RestartNUItem.Command=restart_noupdate\n"
L"RestartNUItem.Label=$Menu.Restart\n"
L"RestartNUItem.Tip=$Menu.RestartTip\n"
L"RestartNUItem.Icon=none\n"
L"RestartItem.Command=restart\n"
L"RestartItem.Label=$Menu.Restart\n"
L"RestartItem.Tip=$Menu.RestartTip\n"
L"RestartItem.Icon=none\n"
L"SleepItem.Command=sleep\n"
L"SleepItem.Label=$Menu.Sleep\n"
L"SleepItem.Tip=$Menu.SleepTip\n"
L"SleepItem.Icon=none\n"
L"HibernateItem.Command=hibernate\n"
L"HibernateItem.Label=$Menu.Hibernate\n"
L"HibernateItem.Tip=$Menu.HibernateTip\n"
L"HibernateItem.Icon=none\n"
L"ShutdownNUItem.Command=shutdown_noupdate\n"
L"ShutdownNUItem.Label=$Menu.Shutdown\n"
L"ShutdownNUItem.Tip=$Menu.ShutdownTip\n"
L"ShutdownNUItem.Icon=none\n"
L"ShutdownItem.Command=shutdown\n"
L"ShutdownItem.Label=$Menu.Shutdown\n"
L"ShutdownItem.Tip=$Menu.ShutdownTip\n"
L"ShutdownItem.Icon=none\n"
;
const StdMenuItem *ParseCustomMenu( unsigned int &rootSettings )
{
TMenuStyle menuStyle=(TMenuStyle)GetSettingInt(L"MenuStyle");
CString menuText;
if (menuStyle==MENU_CLASSIC1)
menuText=GetSettingString(L"MenuItems1");
else if (menuStyle==MENU_CLASSIC2)
menuText=GetSettingString(L"MenuItems2");
else
menuText=GetSettingString(L"MenuItems7");
unsigned int hash=FNV_HASH0;
if (GetSettingBool(L"ControlPanelCategories")) hash+=1;
if (GetSettingInt(L"ProgramsStyle")==PROGRAMS_INLINE) hash+=2;
if (GetSettingBool(L"AllProgramsMetro")) hash+=4;
hash=CalcFNVHash(menuText,hash);
if (hash!=g_MenuItemsHash)
{
if (GetSettingInt(L"MenuStyle")==MENU_WIN7)
{
wchar_t buf[16384];
int len=Strcpy(buf,_countof(buf),g_StartMenuItems7a);
CSettingsParser parser;
parser.LoadText(menuText,menuText.GetLength());
parser.ParseText();
for (int i=1;;i++)
{
wchar_t item[100];
Sprintf(item,_countof(item),L"Item%d.Settings",i);
const wchar_t *settings=parser.FindSetting(item);
if (settings && wcsstr(settings,L"ITEM_DISABLED"))
continue;
Sprintf(item,_countof(item),L"Item%d.Command",i);
const wchar_t *command=parser.FindSetting(item);
if (!command)
{
Sprintf(item,_countof(item),L"Item%d.Link",i);
if (!parser.FindSetting(item))
break;
}
if (command && (_wcsicmp(command,L"shutdown_box")==0 || _wcsicmp(command,L"recent_programs")==0 || _wcsicmp(command,L"search_box")==0 || _wcsicmp(command,L"programs")==0))
{
// these commands can't be in the right column because they are already in other parts of the menu
continue;
}
if (command && _wcsicmp(command,L"separator")==0)
{
len+=Sprintf(buf+len,_countof(buf)-len,L"SEPARATOR, ");
}
else
{
len+=Sprintf(buf+len,_countof(buf)-len,L"Item%d, ",i);
}
}
len+=Strcat(buf+len,_countof(buf)-len,g_StartMenuItems7b);
len+=Strcat(buf+len,_countof(buf)-len,menuText);
for (int i=1;;i++)
{
wchar_t item[100];
Sprintf(item,_countof(item),L"Item%d.Settings",i);
const wchar_t *settings=parser.FindSetting(item);
if (settings && wcsstr(settings,L"ITEM_DISABLED"))
continue;
Sprintf(item,_countof(item),L"Item%d.Command",i);
const wchar_t *command=parser.FindSetting(item);
Sprintf(item,_countof(item),L"Item%d.Link",i);
const wchar_t *link=parser.FindSetting(item);
if (!command)
{
if (!link)
break;
else
continue;
}
Sprintf(item,_countof(item),L"Item%d.Label",i);
const wchar_t *label=parser.FindSetting(item);
Sprintf(item,_countof(item),L"Item%d.icon",i);
const wchar_t *icon=parser.FindSetting(item);
Sprintf(item,_countof(item),L"Item%d.Tip",i);
const wchar_t *tip=parser.FindSetting(item);
// handle special items
for (int j=1;j<g_StdCommands7Count-1;j++)
{
const CStdCommand7 &stdCommand=g_StdCommands7[j];
if (_wcsicmp(command,stdCommand.command)==0)
{
if (!link && stdCommand.knownLink)
len+=Sprintf(buf+len,_countof(buf)-len,L"Item%d.Link=%s\n",i,stdCommand.knownLink);
if (!label && stdCommand.label)
len+=Sprintf(buf+len,_countof(buf)-len,L"Item%d.Label=%s\n",i,stdCommand.label);
if (!icon && stdCommand.icon)
len+=Sprintf(buf+len,_countof(buf)-len,L"Item%d.Icon=%s\n",i,stdCommand.icon);
if (!tip && stdCommand.tip)
len+=Sprintf(buf+len,_countof(buf)-len,L"Item%d.Tip=%s\n",i,stdCommand.tip);
}
}
}
if (GetWinVersion()<WIN_VER_WIN8 || GetSettingInt(L"ProgramsStyle")==PROGRAMS_INLINE || !GetSettingBool(L"AllProgramsMetro"))
len+=Strcpy(buf+len,_countof(buf)-len,L"ProgramsMenu.Items=\n");
menuText=buf;
}
g_RootSettings=0;
g_MenuItemsHash=hash;
g_CustomMenu.clear();
g_CustomMenuParser.Reset();
g_CustomMenuParser.LoadText(menuText,menuText.GetLength());
g_CustomMenuParser.ParseText();
std::vector<CSettingsParser::TreeItem> items;
g_CustomMenuParser.ParseTree(L"Items",items);
g_CustomMenu.resize(items.size());
for (size_t i=0;i<items.size();i++)
{
const wchar_t *name=items[i].name;
StdMenuItem &item=g_CustomMenu[i];
item.command=0;
item.id=MENU_NO;
item.folder1=item.folder2=NULL;
item.label=item.tip=item.iconPath=item.link=NULL;
item.settings=0;
item.submenu=NULL;
// handle special names
if (!*name)
{
item.id=MENU_LAST;
continue;
}
if (_wcsicmp(name,L"SEPARATOR")==0)
{
item.id=MENU_SEPARATOR;
continue;
}
if (_wcsicmp(name,L"COLUMN_PADDING")==0)
{
item.id=MENU_COLUMN_PADDING;
continue;
}
if (_wcsicmp(name,L"COLUMN_BREAK")==0)
{
item.id=MENU_COLUMN_BREAK;
continue;
}
// handle custom items
item.id=MENU_CUSTOM;
ParseMenuItem(item,name);
if (item.id==MENU_RECENT_PROGRAMS)
g_RootSettings|=StdMenuItem::MENU_NORECENT;
int idx=items[i].children;
if (idx>=0)
item.submenu=&g_CustomMenu[idx];
}
for (std::vector<StdMenuItem>::iterator it=g_CustomMenu.begin();it!=g_CustomMenu.end();++it)
if (it->id==MENU_RECENT_PROGRAMS)
{
g_RootSettings|=StdMenuItem::MENU_NORECENT;
break;
}
// if there is no break, add one after Programs
if (!g_CustomMenu.empty())
{
bool bBreak=false;
int after=-1;
for (int i=0;g_CustomMenu[i].id!=MENU_LAST;i++)
{
if (g_CustomMenu[i].id==MENU_COLUMN_BREAK)
bBreak=true;
if (g_CustomMenu[i].id==MENU_PROGRAMS)
after=i;
}
if (!bBreak && after>=0)
{
// add break
StdMenuItem br={NULL,MENU_COLUMN_BREAK};
const StdMenuItem *pBase=&g_CustomMenu[0];
g_CustomMenu.insert(g_CustomMenu.begin()+after+1,br);
// fix submenu pointers
for (std::vector<StdMenuItem>::iterator it=g_CustomMenu.begin();it!=g_CustomMenu.end();++it)
if (it->submenu)
{
int idx=(int)(it->submenu-pBase);
if (idx>after+1)
idx++;
it->submenu=&g_CustomMenu[idx];
}
}
}
// ignore extra search boxes
bool bSearchBox=false;
for (std::vector<StdMenuItem>::iterator it=g_CustomMenu.begin();it!=g_CustomMenu.end();++it)
{
if (it->id==MENU_SEARCH_BOX)
{
if (!bSearchBox)
bSearchBox=true;
else
it->id=MENU_IGNORE;
}
}
}
rootSettings=g_RootSettings;
return &g_CustomMenu[0];
}
void InitStdCommands7( void )
{
for (int i=0;i<g_StdCommands7Count;i++)
{
CStdCommand7 &command=g_StdCommands7[i];
if (command.nameID)
command.displayName=LoadStringEx(command.nameID);
else if (command.knownFolder)
{
CAbsolutePidl pidl;
if (SUCCEEDED(ShGetKnownFolderIDList(*command.knownFolder,&pidl)))
{
if (_wcsicmp(command.command,L"control_panel")==0)
{
ILRemoveLastID(pidl);
}
CComString pName;
if (SUCCEEDED(SHGetNameFromIDList(pidl,SIGDN_NORMALDISPLAY,&pName)))
command.displayName=pName;
}
}
else if (command.knownLink)
{
CAbsolutePidl pidl;
if (SUCCEEDED(MenuParseDisplayName(command.knownLink,&pidl,NULL,NULL)))
{
CComString pName;
if (SUCCEEDED(SHGetNameFromIDList(pidl,SIGDN_NORMALDISPLAY,&pName)))
command.displayName=pName;
}
}
if (command.displayName.IsEmpty())
command.displayName=command.command;
}
std::sort(g_StdCommands7+1,g_StdCommands7+g_StdCommands7Count-1);
}

View File

@@ -0,0 +1,35 @@
// Classic Shell (c) 2009-2017, Ivo Beltchev
// Classic Start (c) 2017-2018, The Passionate-Coder Team
// Confidential information of Ivo Beltchev. Not for disclosure or distribution without prior written consent from the author
#pragma once
struct StdMenuItem;
const StdMenuItem *ParseCustomMenu( unsigned int &rootSettings );
struct CStdCommand7
{
enum
{
ITEM_SINGLE=1, // this item never has sub-menu
ITEM_FOLDER=2, // this item always has sub-menu
ITEM_COMPUTER=4, // this item can be expanded only one level
};
const wchar_t *command;
int nameID;
const wchar_t *label;
const wchar_t *tip;
const wchar_t *icon;
const KNOWNFOLDERID *knownFolder;
const wchar_t *knownLink;
unsigned int settings;
unsigned int flags;
CString displayName; // for the settings UI
bool operator<( const CStdCommand7 &command ) { return displayName<command.displayName; }
};
extern CStdCommand7 g_StdCommands7[];
extern const int g_StdCommands7Count;
void InitStdCommands7( void );

View File

@@ -0,0 +1,936 @@
// ## MenuContainer.h
// Classic Shell (c) 2009-2017, Ivo Beltchev
// Classic Start (c) 2017-2018, The Passionate-Coder Team
// Confidential information of Ivo Beltchev. Not for disclosure or distribution without prior written consent from the author
// DragDrop.cpp - handles the drag and drop functionality of CMenuContainer
#include "stdafx.h"
#include "MenuContainer.h"
#include "ClassicStartMenuDLL.h"
#include "SettingsUI.h"
#include "FNVHash.h"
#include "Settings.h"
#include "ResourceHelper.h"
#include "Translations.h"
#include "FileHelper.h"
#include <algorithm>
class CMetroDataObject: public IDataObject
{
public:
CMetroDataObject( const wchar_t *path );
~CMetroDataObject( void );
// from IUnknown
virtual HRESULT STDMETHODCALLTYPE QueryInterface( REFIID riid, void **ppvObject );
virtual ULONG STDMETHODCALLTYPE AddRef( void )
{
return ++m_RefCount;
}
virtual ULONG STDMETHODCALLTYPE Release( void )
{
if (m_RefCount==1)
{
delete this;
return 0;
}
return --m_RefCount;
}
// from IDataObject
virtual HRESULT STDMETHODCALLTYPE GetData( FORMATETC *pformatetcIn, STGMEDIUM *pmedium );
virtual HRESULT STDMETHODCALLTYPE SetData( FORMATETC *pformatetc, STGMEDIUM *pmedium, BOOL fRelease ) { return E_NOTIMPL; }
virtual HRESULT STDMETHODCALLTYPE GetDataHere( FORMATETC *pformatetc, STGMEDIUM *pmedium ) { return E_NOTIMPL; }
virtual HRESULT STDMETHODCALLTYPE QueryGetData( FORMATETC *pformatetc );
virtual HRESULT STDMETHODCALLTYPE GetCanonicalFormatEtc( FORMATETC *pformatectIn, FORMATETC *pformatetcOut );
virtual HRESULT STDMETHODCALLTYPE EnumFormatEtc( DWORD dwDirection, IEnumFORMATETC **ppenumFormatEtc );
virtual HRESULT STDMETHODCALLTYPE DAdvise( FORMATETC *pformatetc, DWORD advf, IAdviseSink *pAdvSink, DWORD *pdwConnection ) { return OLE_E_ADVISENOTSUPPORTED; }
virtual HRESULT STDMETHODCALLTYPE DUnadvise( DWORD dwConnection ) { return E_NOTIMPL; }
virtual HRESULT STDMETHODCALLTYPE EnumDAdvise( IEnumSTATDATA **ppenumAdvise ) { return OLE_E_ADVISENOTSUPPORTED; }
private:
int m_RefCount;
std::map<CLIPFORMAT,HGLOBAL> m_Data;
bool m_bContents;
void SetData( CLIPFORMAT format, HGLOBAL data );
};
static CLIPFORMAT g_PreferredEffectFormat;
CMetroDataObject::CMetroDataObject( const wchar_t *path )
{
m_RefCount=0;
m_bContents=false;
SetData(CMenuContainer::s_MetroLinkFormat,NULL);
if (!path) return;
HANDLE file=CreateFile(path,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
if (file!=INVALID_HANDLE_VALUE)
{
DWORD size=GetFileSize(file,NULL);
if (size>0)
{
HGLOBAL hContents=NULL, hDesc=NULL;
hContents=GlobalAlloc(GMEM_MOVEABLE,size);
if (hContents)
hDesc=GlobalAlloc(GMEM_MOVEABLE|GMEM_ZEROINIT,sizeof(FILEGROUPDESCRIPTOR));
if (hDesc)
{
FILEGROUPDESCRIPTOR *desc=(FILEGROUPDESCRIPTOR*)GlobalLock(hDesc);
desc->cItems=1;
desc->fgd->dwFlags=FD_ATTRIBUTES|FD_FILESIZE|FD_LINKUI|FD_UNICODE;
desc->fgd->dwFileAttributes=FILE_ATTRIBUTE_NORMAL;
desc->fgd->nFileSizeLow=size;
Strcpy(desc->fgd->cFileName,_countof(desc->fgd->cFileName),PathFindFileName(path));
GlobalUnlock(hDesc);
SetData(CMenuContainer::s_DescriptorFormat,hDesc);
hDesc=NULL;
DWORD q;
if (!ReadFile(file,GlobalLock(hContents),size,&q,NULL))
q=0;
GlobalUnlock(hContents);
if (q==size)
{
SetData(CMenuContainer::s_ContentsFormat,hContents);
hContents=NULL;
m_bContents=true;
}
}
if (hContents) GlobalFree(hContents);
if (hDesc) GlobalFree(hDesc);
}
CloseHandle(file);
}
}
CMetroDataObject::~CMetroDataObject( void )
{
for (std::map<CLIPFORMAT,HGLOBAL>::iterator it=m_Data.begin();it!=m_Data.end();++it)
if (it->second)
GlobalFree(it->second);
}
HRESULT STDMETHODCALLTYPE CMetroDataObject::QueryInterface( REFIID riid, void **ppvObject )
{
if (riid==IID_IDataObject || riid==IID_IUnknown)
{
AddRef();
*ppvObject=this;
return S_OK;
}
*ppvObject=NULL;
return E_NOINTERFACE;
}
HRESULT STDMETHODCALLTYPE CMetroDataObject::GetData( FORMATETC *pformatetcIn, STGMEDIUM *pmedium )
{
if (!pformatetcIn || !pmedium)
return E_INVALIDARG;
pmedium->hGlobal=NULL;
pmedium->pUnkForRelease=NULL;
if (pformatetcIn->dwAspect!=DVASPECT_CONTENT) return DV_E_DVASPECT;
if (!(pformatetcIn->tymed&TYMED_HGLOBAL)) return DV_E_TYMED;
std::map<CLIPFORMAT,HGLOBAL>::iterator it=m_Data.find(pformatetcIn->cfFormat);
if (it==m_Data.end()) return DV_E_FORMATETC;
wchar_t name[100];
GetClipboardFormatName(pformatetcIn->cfFormat,name,100);
Trace(L"GetData: %s, %d",name,pformatetcIn->cfFormat);
pmedium->tymed=TYMED_HGLOBAL;
SIZE_T size=GlobalSize(it->second);
pmedium->hGlobal=GlobalAlloc(GMEM_MOVEABLE,size);
if (!pmedium->hGlobal) return E_OUTOFMEMORY;
void *src=GlobalLock(it->second);
void *dst=GlobalLock(pmedium->hGlobal);
memcpy(dst,src,size);
GlobalUnlock(pmedium->hGlobal);
GlobalUnlock(it->second);
return S_OK;
}
void CMetroDataObject::SetData( CLIPFORMAT format, HGLOBAL data )
{
Assert(m_Data.find(format)==m_Data.end());
m_Data[format]=data;
}
HRESULT STDMETHODCALLTYPE CMetroDataObject::QueryGetData( FORMATETC *pformatetc )
{
if (!pformatetc) return E_INVALIDARG;
if (pformatetc->dwAspect!=DVASPECT_CONTENT) return DV_E_DVASPECT;
if (!(pformatetc->tymed&TYMED_HGLOBAL)) return DV_E_TYMED;
if (m_Data.find(pformatetc->cfFormat)==m_Data.end()) return DV_E_CLIPFORMAT;
return S_OK;
}
HRESULT STDMETHODCALLTYPE CMetroDataObject::GetCanonicalFormatEtc( FORMATETC *pformatectIn, FORMATETC *pformatetcOut )
{
return pformatetcOut?DATA_S_SAMEFORMATETC:E_INVALIDARG;
}
HRESULT STDMETHODCALLTYPE CMetroDataObject::EnumFormatEtc( DWORD dwDirection, IEnumFORMATETC **ppenumFormatEtc )
{
if (!ppenumFormatEtc) return E_POINTER;
*ppenumFormatEtc=NULL;
if (dwDirection == DATADIR_GET)
{
FORMATETC formats[] =
{
{CMenuContainer::s_MetroLinkFormat,NULL,DVASPECT_CONTENT,-1,TYMED_HGLOBAL},
{CMenuContainer::s_DescriptorFormat,NULL,DVASPECT_CONTENT,-1,TYMED_HGLOBAL},
{CMenuContainer::s_ContentsFormat,NULL,DVASPECT_CONTENT,-1,TYMED_HGLOBAL},
};
HRESULT hr = SHCreateStdEnumFmtEtc(m_bContents?3:1,formats,ppenumFormatEtc);
return hr;
}
return E_NOTIMPL;
}
CComPtr<IDataObject> CMenuContainer::CreateMetroDataObject( const CItemManager::ItemInfo *pInfo )
{
CString path;
if (!pInfo->PATH.IsEmpty())
{
CItemManager::RWLock lock(&g_ItemManager,false,CItemManager::RWLOCK_ITEMS);
path=pInfo->GetPath();
}
IDataObject *pDataObjectIn=new CMetroDataObject(path);
CComPtr<IDataObject> pDataObject;
SHCreateDataObject(NULL,0,NULL,pDataObjectIn,IID_IDataObject,(void**)&pDataObject);
if (pDataObject)
{
if (m_pDragSourceHelper)
{
g_ItemManager.UpdateItemInfo(pInfo,CItemManager::INFO_EXTRA_LARGE_ICON|CItemManager::INFO_REFRESH_NOW,false);
int iconSize=CItemManager::EXTRA_LARGE_ICON_SIZE;
SHDRAGIMAGE di={{iconSize,iconSize},{iconSize/2,iconSize},NULL,CLR_NONE};
di.hbmpDragImage=(HBITMAP)CopyImage(pInfo->extraLargeIcon->bitmap,IMAGE_BITMAP,0,0,0);
m_pDragSourceHelper->SetFlags(DSH_ALLOWDROPDESCRIPTIONTEXT);
if (di.hbmpDragImage)
m_pDragSourceHelper->InitializeFromBitmap(&di,pDataObject);
}
}
else
{
pDataObjectIn->Release();
}
return pDataObject;
}
///////////////////////////////////////////////////////////////////////////////
bool CMenuContainer::DragOutApps( const CItemManager::ItemInfo *pInfo )
{
// drag the Apps tree item for reordering
CComPtr<IDataObject> pDataObj=CreateMetroDataObject(pInfo);
// do drag drop
s_pDragSource=NULL;
s_bDragFromTree=false;
m_DragIndex=-1;
s_bPreventClosing=true;
m_DragTime=GetMessageTime();
SetTimer(TIMER_DRAG,100);
s_bDragClosed=false;
DWORD dwEffect=DROPEFFECT_MOVE;
HRESULT res=SHDoDragDrop(NULL,pDataObj,NULL,dwEffect,&dwEffect);
s_pDragSource=NULL;
s_bDragFromTree=false;
if (!m_bDestroyed)
KillTimer(TIMER_DRAG);
HideTemp(false);
s_bPreventClosing=false;
if (s_bDragClosed)
{
for (std::vector<CMenuContainer*>::iterator it=s_Menus.begin();it!=s_Menus.end();++it)
if (!(*it)->m_bDestroyed)
(*it)->PostMessage(WM_CLOSE);
}
return true;
}
bool CMenuContainer::DragOut( int index, bool bApp )
{
if (!(m_Options&CONTAINER_DRAG) || s_bNoDragDrop) return false;
const MenuItem &item=m_Items[index];
if (!item.pItem1 || (item.id!=MENU_NO && item.id!=MENU_RECENT)) return false;
bool bLeft=(GetKeyState(VK_LBUTTON)<0);
bool bRight=(GetKeyState(VK_RBUTTON)<0);
if (!bLeft && !bRight) return false;
CComPtr<IShellFolder> pFolder;
PCUITEMID_CHILD child;
// get IDataObject for the current item
CComPtr<IDataObject> pDataObj;
bool bProtectedLink=false;
if (bApp && GetWinVersion()<WIN_VER_WIN10)
pDataObj=CreateMetroDataObject(item.pItemInfo);
else
{
bool bMetroLink=false;
if (FAILED(SHBindToParent(item.pItem1,IID_IShellFolder,(void**)&pFolder,&child)))
return true;
if (FAILED(pFolder->GetUIObjectOf(NULL,1,&child,IID_IDataObject,NULL,(void**)&pDataObj)))
return true;
{
CItemManager::RWLock lock(&g_ItemManager,false,CItemManager::RWLOCK_ITEMS);
bProtectedLink=!m_bSubMenu || item.pItemInfo->IsProtectedLink();
bMetroLink=item.pItemInfo->IsMetroLink();
}
if (m_pDragSourceHelper && bMetroLink)
{
g_ItemManager.UpdateItemInfo(item.pItemInfo,CItemManager::INFO_EXTRA_LARGE_ICON|CItemManager::INFO_REFRESH_NOW,false);
int iconSize=CItemManager::EXTRA_LARGE_ICON_SIZE;
SHDRAGIMAGE di={{iconSize,iconSize},{iconSize/2,iconSize},NULL,CLR_NONE};
di.hbmpDragImage=(HBITMAP)CopyImage(item.pItemInfo->extraLargeIcon->bitmap,IMAGE_BITMAP,0,0,0);
m_pDragSourceHelper->SetFlags(DSH_ALLOWDROPDESCRIPTIONTEXT);
if (di.hbmpDragImage)
m_pDragSourceHelper->InitializeFromBitmap(&di,pDataObj);
}
}
if (bProtectedLink)
{
// protected links default to DROPEFFECT_LINK
HGLOBAL hGlobal=GlobalAlloc(GMEM_MOVEABLE,4);
if (hGlobal)
{
*(DWORD*)GlobalLock(hGlobal)=DROPEFFECT_LINK;
GlobalUnlock(hGlobal);
FORMATETC format={s_PreferredEffectFormat,NULL,DVASPECT_CONTENT,-1,TYMED_HGLOBAL};
STGMEDIUM medium={TYMED_HGLOBAL};
medium.hGlobal=hGlobal;
if (FAILED(pDataObj->SetData(&format,&medium,TRUE)))
GlobalFree(hGlobal);
}
}
// force synchronous operation
{
CComQIPtr<IDataObjectAsyncCapability> pAsync=pDataObj;
if (pAsync)
pAsync->SetAsyncMode(FALSE);
}
// do drag drop
s_pDragSource=this;
s_bDragFromTree=(index==m_ProgramTreeIndex);
m_DragIndex=index;
s_bDragMovable=(item.id==MENU_NO && index<m_OriginalCount) || (item.jumpIndex>=0 && s_JumpList.groups[LOWORD(item.jumpIndex)].type==CJumpGroup::TYPE_PINNED);
s_bPreventClosing=true;
m_DragTime=GetMessageTime();
s_bDragClosed=false;
SetTimer(TIMER_DRAG,100);
DWORD dwEffect=DROPEFFECT_COPY|DROPEFFECT_MOVE|DROPEFFECT_LINK;
HRESULT res=SHDoDragDrop(NULL,pDataObj,NULL,dwEffect,&dwEffect);
s_pDragSource=NULL;
s_bDragFromTree=false;
if (!m_bDestroyed)
KillTimer(TIMER_DRAG);
s_bDragMovable=false;
HideTemp(false);
s_bPreventClosing=false;
if (s_bDragClosed)
{
for (std::vector<CMenuContainer*>::iterator it=s_Menus.begin();it!=s_Menus.end();++it)
if (!(*it)->m_bDestroyed)
(*it)->PostMessage(WM_CLOSE);
return true;
}
if (pFolder && res==DRAGDROP_S_DROP && !m_bDestroyed)
{
// check if the item still exists. refresh the menu if it doesn't
SFGAOF flags=SFGAO_VALIDATE;
if (FAILED(pFolder->GetAttributesOf(1,&child,&flags)))
{
SetActiveWindow();
// close all submenus
for (int i=(int)s_Menus.size()-1;s_Menus[i]!=this;i--)
if (!s_Menus[i]->m_bDestroyed)
s_Menus[i]->DestroyWindow();
// update menu
PostRefreshMessage();
}
}
// activate the top non-destroyed menu
for (int i=(int)s_Menus.size()-1;i>=0;i--)
if (!s_Menus[i]->m_bDestroyed)
{
SetForegroundWindow(s_Menus[i]->m_hWnd);
s_Menus[i]->SetActiveWindow();
break;
}
return true;
}
void CMenuContainer::SetDropTip( IDataObject *pDataObj, bool bPin )
{
DROPDESCRIPTION desc={bPin?DROPIMAGE_LINK:DROPIMAGE_INVALID};
Strcpy(desc.szMessage,_countof(desc.szMessage),bPin?FindTranslation(L"Menu.PinStart",L"Pin to Start menu"):L"");
HGLOBAL hDesc=GlobalAlloc(GMEM_MOVEABLE,sizeof(desc));
if (hDesc)
{
memcpy(GlobalLock(hDesc),&desc,sizeof(desc));
GlobalUnlock(hDesc);
FORMATETC fmte={CMenuContainer::s_DropDescriptionFormat,NULL,DVASPECT_CONTENT,-1,TYMED_HGLOBAL};
STGMEDIUM medium={};
medium.tymed=TYMED_HGLOBAL;
medium.hGlobal=hDesc;
if (FAILED(pDataObj->SetData(&fmte,&medium,TRUE)))
{
GlobalFree(hDesc);
}
}
}
void CMenuContainer::GetDragEffect( DWORD &grfKeyState, DWORD *pdwEffect )
{
grfKeyState&=MK_SHIFT|MK_CONTROL|MK_ALT;
if (s_bNoDragDrop || !(m_Options&CONTAINER_DROP))
{
*pdwEffect=DROPEFFECT_NONE; // can't drop here
return;
}
if (!m_pDropFolder[0] && !(s_pDragSource==this && s_bDragMovable && !s_bDragFromTree))
{
*pdwEffect=DROPEFFECT_NONE; // can't drop here
return;
}
// only accept known data formats
FORMATETC format1={s_ShellFormat,NULL,DVASPECT_CONTENT,-1,TYMED_HGLOBAL};
FORMATETC format2={s_ShellUrlFormat,NULL,DVASPECT_CONTENT,-1,TYMED_HGLOBAL};
FORMATETC format3={s_MetroLinkFormat,NULL,DVASPECT_CONTENT,-1,TYMED_HGLOBAL};
if (m_pDragObject->QueryGetData(&format1)!=S_OK && m_pDragObject->QueryGetData(&format2)!=S_OK && m_pDragObject->QueryGetData(&format3)!=S_OK)
{
*pdwEffect=DROPEFFECT_NONE;
return;
}
if (s_pDragSource)
{
if (s_pDragSource->m_Items[s_pDragSource->m_DragIndex].id==MENU_RECENT)
*pdwEffect&=DROPEFFECT_LINK; // dragging a recent item (allow only link)
else if (grfKeyState==0 && !s_bRightDrag && s_pDragSource==this && s_bDragMovable && !s_bDragFromTree)
*pdwEffect&=DROPEFFECT_MOVE; // dragging within the same menu - use move by default
else if (grfKeyState==0 && !s_bRightDrag)
*pdwEffect&=(s_bDragMovable && m_bSubMenu && (s_pDragSource->m_Options&CONTAINER_PROGRAMS))?DROPEFFECT_MOVE:DROPEFFECT_LINK; // dragging normal item to a different menu - default to move or link
}
if (m_pDragObject->QueryGetData(&format3)==S_OK)
{
if (m_Options&CONTAINER_APPS)
*pdwEffect&=(s_pDragSource==this && !s_bDragFromTree)?DROPEFFECT_MOVE:DROPEFFECT_NONE; // dragging a metro link to Apps folder
else
*pdwEffect&=DROPEFFECT_LINK; // dragging a metro link to another folder
}
// handle keys
if (!s_bRightDrag)
{
if (grfKeyState==MK_SHIFT)
*pdwEffect&=DROPEFFECT_MOVE;
if (grfKeyState==MK_CONTROL)
*pdwEffect&=DROPEFFECT_COPY;
if (grfKeyState==(MK_CONTROL|MK_SHIFT) || grfKeyState==MK_ALT)
*pdwEffect&=DROPEFFECT_LINK;
}
else if (!m_bSubMenu && grfKeyState==0 && (*pdwEffect&DROPEFFECT_LINK))
{
// when a file is dragged to the start menu he usually wants to make a shortcut
// so when right-dragging, and linking is allowed, make it the default
grfKeyState=MK_SHIFT|MK_CONTROL;
}
}
HRESULT STDMETHODCALLTYPE CMenuContainer::DragEnter( IDataObject *pDataObj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect )
{
s_bRightDrag=(grfKeyState&MK_RBUTTON)!=0;
m_pDragObject=pDataObj;
if (m_pDropTargetHelper)
{
POINT p={pt.x,pt.y};
m_pDropTargetHelper->DragEnter(m_hWnd,m_pDragObject,&p,*pdwEffect);
}
if (!m_bSubMenu && !s_bShowTopEmpty)
{
// when dragging over the main menu, show an (Empty) item at the top so the user can drop items there
for (size_t i=0;i<m_Items.size();i++)
if (m_Items[i].id==MENU_EMPTY_TOP)
{
s_bShowTopEmpty=true;
if (m_ScrollHeight>0 && m_FolderHash[0])
s_MenuScrolls[m_FolderHash[0]]=m_ScrollOffset;
else
s_MenuScrolls.erase(m_FolderHash[0]);
InitWindow();
break;
}
}
m_DragHoverTime=GetMessageTime()-10000;
m_DragHoverItem=-1;
return S_OK;
}
HRESULT STDMETHODCALLTYPE CMenuContainer::DragOver( DWORD grfKeyState, POINTL pt, DWORD *pdwEffect )
{
POINT p0={pt.x,pt.y};
if (m_pDropTargetHelper)
m_pDropTargetHelper->DragOver(&p0,*pdwEffect);
POINT p=p0;
ScreenToClient(&p);
int index=HitTest(p,NULL,true);
int mark=-1;
bool bAfter=false;
const CItemManager::ItemInfo *pInfo=NULL;
RECT rcItem;
if (index>=0)
{
GetItemRect(index,rcItem);
if (!m_bSubMenu && index<m_OriginalCount && (!s_pDragSource || s_bDragFromTree || s_bDragMovable || m_Items[index].id!=MENU_RECENT))
{
int h=(rcItem.bottom-rcItem.top)/4;
if (m_Items[index].id!=MENU_NO || (p.y>=rcItem.top+h && p.y<rcItem.bottom-h))
pInfo=m_Items[index].pItemInfo;
}
}
int dropTargetIndex=pInfo?index:-1;
if (m_pDropTargetInfo!=pInfo)
{
if (m_pDropTarget)
{
m_pDropTarget->DragLeave();
m_pDropTarget=NULL;
}
if (pInfo && pInfo->GetPidl())
{
m_pDropTargetInfo=pInfo;
CComPtr<IShellItem> pItem;
SHCreateItemFromIDList(pInfo->GetPidl(),IID_IShellItem,(void**)&pItem);
if (pItem)
{
pItem->BindToHandler(NULL,BHID_SFUIObject,IID_IDropTarget,(void**)&m_pDropTarget);
if (m_pDropTarget)
{
m_pDropTarget->DragEnter(m_pDragObject,grfKeyState,pt,pdwEffect);
if (*pdwEffect==0)
m_pDropTargetInfo=NULL;
}
}
}
else
m_pDropTargetInfo=NULL;
}
if (!m_pDropTargetInfo)
{
dropTargetIndex=-1;
m_pDropTarget=NULL;
}
if (dropTargetIndex!=m_DropTargetIndex)
{
InvalidateItem(dropTargetIndex);
InvalidateItem(m_DropTargetIndex);
m_DropTargetIndex=dropTargetIndex;
}
if (m_pDropTarget)
{
SetDropTip(m_pDragObject,false);
SetInsertMark(-1,false);
return m_pDropTarget->DragOver(grfKeyState,pt,pdwEffect);
}
s_bRightDrag=(grfKeyState&MK_RBUTTON)!=0;
GetDragEffect(grfKeyState,pdwEffect);
if (index>=0 && index<m_OriginalCount && m_Items[index].id!=MENU_RECENT)
{
// set the new insert mark
mark=index;
int y=(rcItem.top+rcItem.bottom)/2;
if (p.y<y)
{
// insert above
if (m_Items[index].id!=MENU_NO && m_Items[index].id!=MENU_EMPTY && m_Items[index].id!=MENU_EMPTY_TOP && (index==0 || m_Items[index-1].id!=MENU_NO))
mark=-1;
}
else
{
// insert below
bAfter=true;
if (m_Items[index].id!=MENU_NO && m_Items[index].id!=MENU_EMPTY && m_Items[index].id!=MENU_EMPTY_TOP && (index==m_Items.size()-1 || m_Items[index+1].id!=MENU_NO))
mark=-1;
}
if (mark==-1 && m_Items[index].bFolder && (m_Items[index].bPrograms || m_Items[index].id==MENU_NO))
{
SetHotItem(index);
}
else
{
SetHotItem(-1);
}
if (!*pdwEffect || ((m_Options&CONTAINER_AUTOSORT) && s_pDragSource==this && !s_bDragFromTree && s_bDragMovable))
mark=-1;
}
else if (s_pDragSource==this && !s_bDragFromTree && s_bDragMovable && m_Items[m_DragIndex].jumpIndex>=0 && index>=0 && m_Items[index].jumpIndex>=0)
{
int groupIndex=LOWORD(m_Items[m_DragIndex].jumpIndex);
if (s_JumpList.groups[groupIndex].type==CJumpGroup::TYPE_PINNED && LOWORD(m_Items[index].jumpIndex)==groupIndex && (*pdwEffect&DROPEFFECT_MOVE))
{
// reorder jump list
*pdwEffect=DROPEFFECT_MOVE;
int y=(rcItem.top+rcItem.bottom)/2;
bAfter=p.y>=y;
SetHotItem(-1);
}
else
index=-1;
mark=index;
}
else
{
if (!m_bSubMenu && index<m_OriginalCount && PtInRect(&m_rContent,p) && (s_pDragSource!=this || s_bDragFromTree || !s_bDragMovable || m_Items[m_DragIndex].id==MENU_RECENT))
{
if (s_bWin7Style)
{
for (int i=0;i<m_ScrollCount;i++)
{
if (m_Items[i].id==MENU_NO || m_Items[i].id==MENU_EMPTY || m_Items[i].id==MENU_EMPTY_TOP)
mark=i;
}
}
else
mark=m_ScrollCount-1;
bAfter=true;
}
index=-1;
}
SetInsertMark(mark,bAfter);
UpdateScroll(&p,false);
// check if the hover delay is done and it's time to open the item
if (index>=0 && index==m_DragHoverItem)
{
int hoverTime=(int)s_HoverTime;
if (m_Items[index].id==MENU_PROGRAMS && GetSettingInt(L"ProgramsStyle")==PROGRAMS_INLINE)
hoverTime=(int)s_ProgramsHoverTime;
if ((GetMessageTime()-m_DragHoverTime)>hoverTime && m_Submenu!=m_DragHoverItem)
{
// expand m_DragHoverItem
if (index<m_OriginalCount && !m_Items[index].bHasJumpList && (!m_Items[index].bFolder || m_Items[index].pItem1))
{
ActivateData data;
data.bNoModifiers=GetKeyState(VK_SHIFT)<0;
ActivateItem(index,ACTIVATE_OPEN,NULL,&data);
}
if (!m_Items[index].bFolder)
SetHotItem(-1);
m_DragHoverTime=GetMessageTime();
}
}
else
{
m_DragHoverItem=index;
m_DragHoverTime=GetMessageTime();
}
if (m_InsertMark<0)
*pdwEffect=0;
int before=m_InsertMark;
if (before>=0 && m_bInsertAfter && (before!=0 || (m_Items[0].id!=MENU_EMPTY && m_Items[0].id!=MENU_EMPTY_TOP)))
before++;
if (before>=0 && !m_bSubMenu && (*pdwEffect&DROPEFFECT_LINK) && (s_pDragSource!=this || s_bDragFromTree || !s_bDragMovable))
{
*pdwEffect=DROPEFFECT_LINK;
SetDropTip(m_pDragObject,true);
}
else
SetDropTip(m_pDragObject,false);
return S_OK;
}
HRESULT STDMETHODCALLTYPE CMenuContainer::DragLeave( void )
{
if (m_pDropTarget)
{
m_pDropTarget->DragLeave();
m_pDropTarget=NULL;
}
InvalidateItem(m_DropTargetIndex);
m_DropTargetIndex=-1;
m_pDropTargetInfo=NULL;
if (m_pDropTargetHelper)
m_pDropTargetHelper->DragLeave();
SetDropTip(m_pDragObject,false);
SetInsertMark(-1,false);
m_pDragObject=NULL;
UpdateScroll(NULL,false);
return S_OK;
}
HRESULT STDMETHODCALLTYPE CMenuContainer::Drop( IDataObject *pDataObj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect )
{
if (s_pDragSource)
{
if (!s_pDragSource->m_bDestroyed)
s_pDragSource->KillTimer(TIMER_DRAG);
}
if (m_pDropTargetHelper)
{
POINT p={pt.x,pt.y};
m_pDropTargetHelper->Drop(pDataObj,&p,*pdwEffect);
}
if (m_pDropTarget)
{
m_pDragObject=NULL;
HRESULT res=m_pDropTarget->Drop(pDataObj,grfKeyState,pt,pdwEffect);
m_pDropTarget=NULL;
return res;
}
GetDragEffect(grfKeyState,pdwEffect);
m_pDragObject=NULL;
int before=m_InsertMark;
if (before<0) return S_OK;
if (before>=0 && m_bInsertAfter && (before!=0 || (m_Items[0].id!=MENU_EMPTY && m_Items[0].id!=MENU_EMPTY_TOP)))
before++;
// clear the insert mark
SetInsertMark(-1,false);
int folderIndex=0;
if (before>=0)
folderIndex=m_Items[min(before,(int)m_Items.size()-1)].priority>1?1:0;
if (s_pDragSource==this && !s_bDragFromTree && s_bDragMovable && (*pdwEffect&DROPEFFECT_MOVE) && m_DragIndex!=m_ProgramTreeIndex && m_Items[m_DragIndex].priority==(m_Items[min(before,(int)m_Items.size()-1)].priority&2))
{
if (before==m_DragIndex || before==m_DragIndex+1)
return S_OK;
// dropped in the same menu, just rearrange the items
PlayMenuSound(SOUND_DROP);
if (m_Items[m_DragIndex].jumpIndex>=0 && s_JumpList.groups[LOWORD(m_Items[m_DragIndex].jumpIndex)].type==CJumpGroup::TYPE_PINNED)
{
// reordering pinned item
int groupIdx=LOWORD(m_Items[m_DragIndex].jumpIndex);
int itemIdx=HIWORD(m_Items[m_DragIndex].jumpIndex);
for (int i=0;i<=m_DragIndex;i++)
{
if (m_Items[i].jumpIndex>=0 && LOWORD(m_Items[i].jumpIndex)==groupIdx)
{
// found first pinned index
PinJumpItem(s_JumpAppInfo,s_JumpList,groupIdx,itemIdx,true,before-i);
PostRefreshMessage();
break;
}
}
}
else if (!(m_Options&CONTAINER_AUTOSORT))
{
std::vector<SortMenuItem> items;
int skip1=0, skip2=0;
for (int i=0;i<m_OriginalCount;i++)
{
if (m_Items[i].id==MENU_NO)
{
SortMenuItem item(m_Items[i]);
items.push_back(item);
}
else
{
if (i<m_DragIndex) skip1++;
if (i<before) skip2++;
}
}
SortMenuItem drag=items[m_DragIndex-skip1];
items.erase(items.begin()+(m_DragIndex-skip1));
if (before-skip2>m_DragIndex-skip1)
before--;
items.insert(items.begin()+(before-skip2),drag);
SaveItemOrder(items);
if (m_bTwoColumns && s_MenuMode==MODE_JUMPLIST)
SetMenuMode(MODE_NORMAL);
PostRefreshMessage();
}
}
else if (m_pDropFolder[folderIndex])
{
// simulate dropping the object into the original folder
PlayMenuSound(SOUND_DROP);
if (before>=0 && !m_bSubMenu && (*pdwEffect&DROPEFFECT_LINK) && (s_pDragSource!=this || s_bDragFromTree || !s_bDragMovable))
*pdwEffect=DROPEFFECT_LINK;
bool bDropped=false;
if (!m_bSubMenu && (*pdwEffect&DROPEFFECT_LINK) && !s_bRightDrag)
{
// if dropping a single folder onto the main menu, create a fake folder
CComPtr<IShellItemArray> pArray;
if (SUCCEEDED(SHCreateShellItemArrayFromDataObject(pDataObj,IID_IShellItemArray,(void**)&pArray)))
{
DWORD count;
CComPtr<IShellItem> pItem;
if (SUCCEEDED(pArray->GetCount(&count)) && count==1 && SUCCEEDED(pArray->GetItemAt(0,&pItem)))
{
CComString pPath;
if (pItem->GetDisplayName(SIGDN_FILESYSPATH,&pPath)==S_OK && PathIsDirectory(pPath))
{
wchar_t path[_MAX_PATH];
if (SUCCEEDED(SHGetPathFromIDList(m_Path1[0],path)))
{
wchar_t fname[_MAX_FNAME];
Strcpy(fname,_countof(fname),PathFindFileName(pPath));
int len=Strlen(fname);
while (len>0 && (fname[len-1]=='\\' || fname[len-1]==':'))
len--;
fname[len]=0;
PathAppend(path,fname);
wchar_t finalPath[_MAX_PATH];
PathYetAnotherMakeUniqueName(finalPath,path,NULL,PathFindFileName(path));
if (CreateFakeFolder(pPath,finalPath))
{
bDropped=true;
wchar_t locName[_MAX_PATH];
int locIndex;
if (SHGetLocalizedName(pPath,locName,_countof(locName),&locIndex)==S_OK)
{
SHSetLocalizedName(finalPath,locName,locIndex);
}
}
}
}
}
}
}
if (!bDropped)
{
// must use IShellFolder to get to the drop target because the BindToHandler doesn't support passing the parent window (easily)
CComPtr<IShellFolder> pDesktop;
SHGetDesktopFolder(&pDesktop);
CComPtr<IShellFolder> pFolder;
CComPtr<IDropTarget> pTarget;
if (!pDesktop || FAILED(pDesktop->BindToObject(m_Path1[folderIndex],NULL,IID_IShellFolder,(void**)&pFolder)) || FAILED(pFolder->CreateViewObject(g_OwnerWindow,IID_IDropTarget,(void**)&pTarget)))
return S_OK;
DWORD dwEffect=*pdwEffect;
if (s_bRightDrag)
{
if (FAILED(pTarget->DragEnter(pDataObj,MK_RBUTTON|grfKeyState,pt,&dwEffect)))
return S_OK;
dwEffect=*pdwEffect;
pTarget->DragOver(MK_RBUTTON|grfKeyState,pt,&dwEffect);
}
else
{
if (FAILED(pTarget->DragEnter(pDataObj,MK_LBUTTON|grfKeyState,pt,&dwEffect)))
return S_OK;
dwEffect=*pdwEffect;
pTarget->DragOver(MK_LBUTTON|grfKeyState,pt,pdwEffect);
}
CComQIPtr<IDataObjectAsyncCapability> pAsync=pDataObj;
if (pAsync)
pAsync->SetAsyncMode(FALSE);
for (std::vector<CMenuContainer*>::iterator it=s_Menus.begin();it!=s_Menus.end();++it)
if (!(*it)->m_bDestroyed)
(*it)->EnableWindow(FALSE); // disable all menus
bool bAllPrograms=s_bAllPrograms;
if (bAllPrograms) ::EnableWindow(g_TopWin7Menu,FALSE);
bool bOld=s_bPreventClosing;
s_bPreventClosing=true;
AddRef();
pTarget->Drop(pDataObj,grfKeyState,pt,pdwEffect);
if (!bOld)
HideTemp(false);
s_bPreventClosing=bOld;
for (std::vector<CMenuContainer*>::iterator it=s_Menus.begin();it!=s_Menus.end();++it)
if (!(*it)->m_bDestroyed)
(*it)->EnableWindow(TRUE); // enable all menus
if (bAllPrograms) ::EnableWindow(g_TopWin7Menu,TRUE);
}
else
{
AddRef();
}
if (!m_bDestroyed)
{
SetForegroundWindow(m_hWnd);
SetActiveWindow();
SetFocus();
}
if (before>=0 && !(m_Options&CONTAINER_AUTOSORT))
{
std::vector<SortMenuItem> items;
int skip=0;
for (int i=0;i<m_OriginalCount;i++)
{
if (m_Items[i].id==MENU_NO)
{
SortMenuItem item(m_Items[i]);
items.push_back(item);
}
else if (i<before)
skip++;
}
SortMenuItem ins(L"",FNV_HASH0,false,false,folderIndex*2,0);
items.insert(items.begin()+(before-skip),ins);
SaveItemOrder(items);
}
if (m_bTwoColumns && s_MenuMode==MODE_JUMPLIST)
SetMenuMode(MODE_NORMAL);
PostRefreshMessage();
Release();
}
return S_OK;
}
///////////////////////////////////////////////////////////////////////////////
HRESULT STDMETHODCALLTYPE CDropTargetProxy::DragEnter( IDataObject *pDataObj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect )
{
if (!m_pOwner) return E_FAIL;
return m_pOwner->DragEnter(pDataObj,grfKeyState,pt,pdwEffect);
}
HRESULT STDMETHODCALLTYPE CDropTargetProxy::DragOver( DWORD grfKeyState, POINTL pt, DWORD *pdwEffect )
{
if (!m_pOwner) return E_FAIL;
return m_pOwner->DragOver(grfKeyState,pt,pdwEffect);
}
HRESULT STDMETHODCALLTYPE CDropTargetProxy::DragLeave( void )
{
if (!m_pOwner) return E_FAIL;
return m_pOwner->DragLeave();
}
HRESULT STDMETHODCALLTYPE CDropTargetProxy::Drop( IDataObject *pDataObj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect )
{
if (!m_pOwner) return E_FAIL;
return m_pOwner->Drop(pDataObj,grfKeyState,pt,pdwEffect);
}

View File

@@ -0,0 +1,61 @@
// Classic Shell (c) 2009-2017, Ivo Beltchev
// Classic Start (c) 2017-2018, The Passionate-Coder Team
// Confidential information of Ivo Beltchev. Not for disclosure or distribution without prior written consent from the author
#pragma once
// CDropTargetProxy - a wrapper for another object's IDropTarget. On Windows 8.1 the interface is not properly released
// when the window is destroyed during a drag operation. So the wrapper is used as a decoy to minimize the leaked resources
class CDropTargetProxy: public IDropTarget
{
public:
CDropTargetProxy( IDropTarget *pOwner )
{
m_pOwner=pOwner;
m_RefCount=0;
}
~CDropTargetProxy( void )
{
}
void Reset( void )
{
m_pOwner=NULL;
}
// IUnknown
virtual STDMETHODIMP QueryInterface( REFIID riid, void **ppvObject )
{
*ppvObject=NULL;
if (IID_IUnknown==riid || IID_IDropTarget==riid)
{
AddRef();
*ppvObject=static_cast<IDropTarget*>(this);
return S_OK;
}
return E_NOINTERFACE;
}
virtual ULONG STDMETHODCALLTYPE AddRef( void )
{
return InterlockedIncrement(&m_RefCount);
}
virtual ULONG STDMETHODCALLTYPE Release( void )
{
long nTemp=InterlockedDecrement(&m_RefCount);
if (!nTemp) delete this;
return nTemp;
}
// IDropTarget
virtual HRESULT STDMETHODCALLTYPE DragEnter( IDataObject *pDataObj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect );
virtual HRESULT STDMETHODCALLTYPE DragOver( DWORD grfKeyState, POINTL pt, DWORD *pdwEffect );
virtual HRESULT STDMETHODCALLTYPE DragLeave( void );
virtual HRESULT STDMETHODCALLTYPE Drop( IDataObject *pDataObj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect );
private:
IDropTarget *m_pOwner;
LONG m_RefCount;
};

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,480 @@
// Classic Shell (c) 2009-2017, Ivo Beltchev
// Classic Start (c) 2017-2018, The Passionate-Coder Team
// Confidential information of Ivo Beltchev. Not for disclosure or distribution without prior written consent from the author
#pragma once
#include "ComHelper.h"
#include <map>
#include <set>
#include <list>
#include <vector>
interface IImageList2;
interface IWICImagingFactory;
// CItemManager - global cache for item information
class CItemManager;
extern CItemManager g_ItemManager;
class CItemManager
{
public:
CItemManager( void );
~CItemManager( void );
static int SMALL_ICON_SIZE;
static int LARGE_ICON_SIZE;
static int EXTRA_LARGE_ICON_SIZE;
// Initializes the manager. Called from DllMain
void Init( void );
void Close( void );
void ResetTempIcons( void );
void LoadCacheFile( void );
void SaveCacheFile( void );
void ClearCache( void );
static int GetDPI( bool bOverride ) { return (bOverride && s_DPIOverride)?s_DPIOverride:s_DPI; }
static bool GetDPIOverride( void ) { return s_DPIOverride!=0; }
enum TIconSizeType
{
ICON_SIZE_TYPE_SMALL,
ICON_SIZE_TYPE_LARGE,
ICON_SIZE_TYPE_EXTRA_LARGE,
ICON_SIZE_TYPE_SMALL_METRO,
ICON_SIZE_TYPE_LARGE_METRO,
ICON_SIZE_TYPE_EXTRA_LARGE_METRO,
ICON_SIZE_COUNT
};
struct IconInfo
{
TIconSizeType sizeType;
bool bTemp; // the icon will be destroyed when the menu closes
bool bMetro; // this is a Metro icon. it may depend on the system color
FILETIME timestamp;
HBITMAP bitmap; // bitmaps are guaranteed to be valid on the main thread (if the handle is read atomically)
void SetPath( const wchar_t *path );
const CString &GetPath( void ) const { Assert(RWLock::ThreadHasReadLock(RWLOCK_ICONS)); return PATH; }
private:
CString PATH; // metro icon paths start with # and are not saved to cache file
friend class CItemManager;
};
enum
{
INFO_LINK=1, // bLink, appid, bNoPin, bNoNew, targetPidl, targetPath, arguments
INFO_METRO=2, // bLink, bMetroLink, bMetroApp, appid, metroName, package, packagePath, iconPath, color
INFO_LINK_APPID=4, // the appid is validated by the app resolver (for jumplists and UserAssist items). Can only be used from the main thread
INFO_SMALL_ICON=16,
INFO_LARGE_ICON=32,
INFO_EXTRA_LARGE_ICON=64,
INFO_NO_PATH=8192, // don't trust the parsing name
INFO_VALIDATE_FILE=16384, // if the path doesn't exist returns NULL
INFO_REFRESH_NOW=32768,
INFO_STARTSCREEN_ICON=65536,
INFO_DATA=INFO_LINK|INFO_METRO|INFO_LINK_APPID,
INFO_ICON=INFO_SMALL_ICON|INFO_LARGE_ICON|INFO_EXTRA_LARGE_ICON,
};
enum TLocation
{
LOCATION_UNKNOWN,
LOCATION_START_MENU,
LOCATION_GAMES,
LOCATION_DESKTOP,
LOCATION_TASKBAR,
LOCATION_METRO,
};
struct ItemInfo
{
ItemInfo( void )
{
smallIcon=largeIcon=extraLargeIcon=NULL;
validFlags=refreshFlags=0;
bIconOnly=bTemp=bLink=bExplicitAppId=bNoPin=bNoNew=bMetroLink=bMetroApp=bProtectedLink=false;
writestamp.dwHighDateTime=writestamp.dwLowDateTime=0;
createstamp.dwHighDateTime=createstamp.dwLowDateTime=0;
location=LOCATION_UNKNOWN;
}
// PATH never changes after the item is created. it can be accessed without a lock
CString PATH;
// these are replaced atomically with pointers that are always valid
const IconInfo *smallIcon;
const IconInfo *largeIcon;
const IconInfo *extraLargeIcon;
const CAbsolutePidl &GetPidl( void ) const { Assert(GetCurrentThreadId()==g_ItemManager.m_MainThreadId || RWLock::ThreadHasReadLock(RWLOCK_ITEMS)); return pidl; }
bool IsLink( void ) const { Assert(RWLock::ThreadHasReadLock(RWLOCK_ITEMS)); return bLink; }
bool IsMetroLink( void ) const { Assert(RWLock::ThreadHasReadLock(RWLOCK_ITEMS)); return bMetroLink; }
bool IsMetroApp( void ) const { Assert(RWLock::ThreadHasReadLock(RWLOCK_ITEMS)); return bMetroApp; }
bool IsProtectedLink( void ) const { Assert(RWLock::ThreadHasReadLock(RWLOCK_ITEMS)); return bProtectedLink; }
bool IsNoPin( void ) const { Assert(RWLock::ThreadHasReadLock(RWLOCK_ITEMS)); return bNoPin; }
bool IsNoNew( void ) const { Assert(RWLock::ThreadHasReadLock(RWLOCK_ITEMS)); return bNoNew; }
bool IsExplicitAppId( void ) const { Assert(RWLock::ThreadHasReadLock(RWLOCK_ITEMS)); return bExplicitAppId; }
const CString &GetPath( void ) const { Assert(RWLock::ThreadHasReadLock(RWLOCK_ITEMS)); return path; }
const CString &GetAppid( void ) const { Assert(RWLock::ThreadHasReadLock(RWLOCK_ITEMS)); return appid; }
const CString &GetTargetPATH( void ) const { Assert(RWLock::ThreadHasReadLock(RWLOCK_ITEMS)); return targetPATH; }
const CAbsolutePidl &GetTargetPidl( void ) const { Assert(RWLock::ThreadHasReadLock(RWLOCK_ITEMS)); return targetPidl; }
const CString &GetMetroName( void ) const { Assert(RWLock::ThreadHasReadLock(RWLOCK_ITEMS)); return metroName; }
const CString &GetIconPath( void ) const { Assert(RWLock::ThreadHasReadLock(RWLOCK_ITEMS)); return iconPath; }
const CString &GetPackagePath( void ) const { Assert(RWLock::ThreadHasReadLock(RWLOCK_ITEMS)); return packagePath; }
TLocation GetLocation( void ) const { Assert(RWLock::ThreadHasReadLock(RWLOCK_ITEMS)); return location; }
private:
CAbsolutePidl pidl;
CAbsolutePidl newPidl;
FILETIME writestamp; // valid only for items with paths. the rest are assumed to never change
FILETIME createstamp; // valid only for items with paths. the rest are assumed to never change
bool bIconOnly;
bool bTemp; // the item and its icon will be destroyed when the menu closes (only allowed for small-icon items)
bool bLink;
bool bMetroLink;
bool bMetroApp;
bool bProtectedLink; // Metro link in the common Programs folder
bool bNoPin; // the link shouldn't be pinned
bool bNoNew; // the link shouldn't be new
bool bExplicitAppId;
CString path; // only for a file
CString packagePath; // only for a metro app
TLocation location;
int validFlags;
int refreshFlags; // 0 if not in the queue, the item can't be deleted if this is !=0
CAbsolutePidl targetPidl;
CString targetPATH;
CString appid;
CString metroName;
CString iconPath;
DWORD iconColor;
int iconIndex; // used only if bIconOnly
const CAbsolutePidl &GetLatestPidl( void ) const { Assert(RWLock::ThreadHasReadLock(RWLOCK_ITEMS)); return newPidl?newPidl:pidl; }
friend class CItemManager;
};
const ItemInfo *GetItemInfo( IShellItem *pItem, PIDLIST_ABSOLUTE pidl, int refreshFlags, TLocation location=LOCATION_UNKNOWN );
const ItemInfo *GetItemInfo( CString path, int refreshFlags, TLocation location=LOCATION_UNKNOWN );
const ItemInfo *GetCustomIcon( const wchar_t *location, int index, TIconSizeType iconSizeType, bool bTemp );
const ItemInfo *GetCustomIcon( const wchar_t *path, TIconSizeType iconSizeType );
const ItemInfo *GetMetroAppInfo10( const wchar_t *appid );
void UpdateItemInfo( const ItemInfo *pInfo, int refreshFlags, bool bHasWriteLock=false );
void WaitForShortcuts( const POINT &balloonPos );
bool IsTaskbarPinned( const wchar_t *appid );
void UpdateNewPrograms( const POINT &balloonPos );
bool IsNewProgram( PIDLIST_ABSOLUTE pidl, bool bFolder, bool bMetroApp );
bool HasNewPrograms( bool bReal ) { return m_bHasNewPrograms[bReal?0:1]; }
bool HasNewApps( bool bReal ) { return m_bHasNewApps[bReal?0:1]; }
void RefreshInfos( void );
void RemoveNewItem( PIDLIST_ABSOLUTE pItem1, PIDLIST_ABSOLUTE pItem2, bool bFolder );
void RemoveNewItems( bool bPrograms, bool bMetro );
void SaveOldItems( void );
enum TRWLock
{
RWLOCK_ITEMS,
RWLOCK_ICONS,
RWLOCK_COUNT,
};
class RWLock
{
public:
RWLock( CItemManager *pThis, bool bWrite, TRWLock index )
{
if (index==RWLOCK_COUNT)
{
m_pLock=NULL;
return;
}
#ifdef _DEBUG
m_pState=&g_LockState[index];
Assert(*m_pState==0);
#endif
m_pLock=&pThis->m_RWLocks[index];
m_bWrite=bWrite;
if (bWrite)
AcquireSRWLockExclusive(m_pLock);
else
AcquireSRWLockShared(m_pLock);
#ifdef _DEBUG
*m_pState=bWrite?2:1;
#endif
}
~RWLock( void )
{
if (!m_pLock) return;
#ifdef _DEBUG
Assert(*m_pState==(m_bWrite?2:1));
*m_pState=0;
#endif
if (m_bWrite)
ReleaseSRWLockExclusive(m_pLock);
else
ReleaseSRWLockShared(m_pLock);
}
#ifdef _DEBUG
static bool ThreadHasReadLock( TRWLock index ) { return g_LockState[index]!=0; }
static bool ThreadHasWriteLock( TRWLock index ) { return g_LockState[index]==2; }
#endif
private:
SRWLOCK *m_pLock;
bool m_bWrite;
#ifdef _DEBUG
int *m_pState;
static _declspec(thread) int g_LockState[RWLOCK_COUNT]; // 0 - none, 1 - read, 2 - write
#endif
};
private:
static int s_DPI;
static int s_DPIOverride;
enum TLock
{
LOCK_CLEANUP,
LOCK_COUNT,
};
SRWLOCK m_RWLocks[RWLOCK_COUNT];
CRITICAL_SECTION m_CriticalSections[LOCK_COUNT];
DWORD m_CriticalSectionOwners[LOCK_COUNT];
HANDLE m_StartEvent; // start the refresh thread
HANDLE m_WorkEvent; // kicks off the refresh thread
HANDLE m_ExitEvent; // exit all threads
HANDLE m_DoneEvent; // done preloading start menu items
HANDLE m_PreloadItemsThread;
HANDLE m_RefreshInfoThread;
HANDLE m_SaveCacheThread;
DWORD m_MainThreadId, m_PreloadItemsThreadId, m_RefreshInfoThreadId;
// per-thread info used to load icons
struct LoadIconData
{
int m_IconSizes[ICON_SIZE_COUNT];
HIMAGELIST m_TempLists[ICON_SIZE_COUNT];
CComPtr<IImageList2> m_pTempLists[ICON_SIZE_COUNT];
CComPtr<IWICImagingFactory> m_pFactory;
void Init( void );
void Close( void );
};
LoadIconData m_LoadIconData[3]; // one for each thread (main, preload, refresh)
LoadIconData &GetLoadIconData( void );
class Lock
{
public:
Lock( CItemManager *pThis, TLock index )
{
m_pSection=&pThis->m_CriticalSections[index];
EnterCriticalSection(m_pSection);
m_pOwner=&pThis->m_CriticalSectionOwners[index];
if (!*m_pOwner)
*m_pOwner=GetCurrentThreadId();
else
m_pOwner=NULL;
}
~Lock( void )
{
if (m_pOwner) *m_pOwner=0;
LeaveCriticalSection(m_pSection);
}
private:
CRITICAL_SECTION *m_pSection;
DWORD *m_pOwner;
};
bool ThreadHasLock( TLock index ) { return m_CriticalSectionOwners[index]==GetCurrentThreadId(); }
// requires LOCK_ITEMS to be held
void QueueItemInfo( ItemInfo *pInfo, int refreshFlags );
// doesn't require a lock
void RefreshItemInfo( ItemInfo *pInfo, int refreshFlags, IShellItem *pItem, bool bHasWriteLock );
void FindInCache( unsigned int hash, int &refreshFlags, const IconInfo *&smallIcon, const IconInfo *&largeIcon, const IconInfo *&extraLargeIcon );
void StoreInCache( unsigned int hash, const wchar_t *path, HBITMAP hSmallBitmap, HBITMAP hLargeBitmap, HBITMAP hExtraLargeBitmap, int refreshFlags, const IconInfo *&smallIcon, const IconInfo *&largeIcon, const IconInfo *&extraLargeIcon, bool bTemp, bool bMetro );
void LoadShellIcon( IShellItem *pItem, int refreshFlags, const IconInfo *&smallIcon, const IconInfo *&largeIcon, const IconInfo *&extraLargeIcon, const DWORD *pMetroColor );
void LoadMetroIcon( IShellItem *pItem, int &refreshFlags, const IconInfo *&smallIcon, const IconInfo *&largeIcon, const IconInfo *&extraLargeIcon, const DWORD *pMetroColor );
void LoadCustomIcon( const wchar_t *iconPath, int iconIndex, int refreshFlags, const IconInfo *&smallIcon, const IconInfo *&largeIcon, const IconInfo *&extraLargeIcon, bool bTemp );
HICON LoadShellIcon( int index, int iconSize );
HICON LoadShellIcon( int iconSize, IExtractIcon *pExtractW, const wchar_t *location, IExtractIconA *pExtractA, const char *locationA, int index );
HBITMAP BitmapFromIcon( HICON hIcon, int iconSize, bool bDestroyIcon=true );
bool m_bInitialized;
// sizes for all shell image lists <size, list>
std::vector<std::pair<int,int>> m_ListSizes;
// the key is a hash of the path or the pidl
std::multimap<unsigned int,ItemInfo> m_ItemInfos;
// the key is a hash of the uppercase appid (win10 only)
std::map<unsigned int,const ItemInfo*> m_MetroItemInfos10;
// hashes of appids that are for sure not valid
std::set<unsigned int> m_BlackListInfos10;
// the key is a hash of the location and index
std::multimap<unsigned int,IconInfo> m_IconInfos;
// bitmaps that were replaced but may still be used by the main thread
std::vector<HBITMAP> m_OldBitmaps;
const IconInfo *m_DefaultSmallIcon;
const IconInfo *m_DefaultLargeIcon;
const IconInfo *m_DefaultExtraLargeIcon;
// list of items to process in background
std::list<ItemInfo*> m_ItemQueue;
std::list<ItemInfo*> m_ItemQueueLow; // lower priority
std::vector<const ItemInfo*> m_NewPrograms;
std::vector<const ItemInfo*> m_NewProgramRoots;
unsigned int m_TransientHash;
bool m_bHasNewPrograms[2]; // 0 - for real, 1 - filtered
bool m_bHasNewApps[2]; // 0 - for real, 1 - filtered
bool m_bPreloadIcons;
bool m_bPreloadFavorites;
enum TLoadingStage
{
LOAD_STOPPED, // the loading threads are not running
LOAD_STOPPING, // the loading threads are stopping
LOAD_LOADING, // the loading threads are running
};
volatile TLoadingStage m_LoadingStage;
int m_LastCacheSave;
COLORREF m_OldSysAccentColor;
bool m_bOldInvertIcons;
void LoadFolderItems( IShellItem *pFolder, int refreshFlags, int levels, TLocation location );
void LoadMetroItems( int refreshFlags );
void PreloadItemsThread( void );
void CreateDefaultIcons( void );
static DWORD CALLBACK StaticPreloadItemsThread( void *param );
void RefreshInfoThread( void );
static DWORD CALLBACK StaticRefreshInfoThread( void *param );
static DWORD CALLBACK SaveCacheFileThread( void *param );
// all paths are in caps and end with \
CString m_RootStartMenu1;
CString m_RootStartMenu2;
CString m_RootStartMenu3;
CString m_RootCommonPrograms;
CString m_RootGames;
CString m_RootDesktop;
CString m_RootTaskbar;
CString m_RootMetro;
// can be called from any thread
TLocation DetermineLocation( const wchar_t *PATH );
struct ModuleInfo
{
CString PATH;
FILETIME timestamp;
};
static bool CompareModuleTimeStamp( const CString &PATH, const FILETIME &timestamp, std::vector<ModuleInfo> &modules );
struct KnownPathGuid
{
CComString path;
CComString guid;
int pathLen;
};
struct OldItemInfo
{
unsigned int hash;
FILETIME timestamp;
bool operator<( const OldItemInfo &x ) const { return hash<x.hash; }
};
std::vector<OldItemInfo> m_OldItemInfos;
void LoadOldItems( void );
bool IsPathUsed( CRegKey &regKey, const wchar_t *path, const FILETIME &createstamp, const KnownPathGuid *knownPaths, int knownPathsCount, bool bMetroApp );
void AddOldItems( const std::vector<unsigned> &hashes );
};
CString GetPropertyStoreString( IPropertyStore *pStore, REFPROPERTYKEY key );
class CShellItemEnumerator
{
public:
CShellItemEnumerator( IShellItem *pFolder );
bool IsValid( void ) const;
bool GetNext( CComPtr<IShellItem> &pChild, CAbsolutePidl &childPidl );
private:
CComPtr<IEnumIDList> m_pEnumPidls;
CComPtr<IEnumShellItems> m_pEnumItems;
CAbsolutePidl m_Root;
};
struct UserAssistData
{
int pad1;
int count;
int pad2[2];
float history[10];
int last;
FILETIME timestamp;
int pad3;
};
void EncodeUserAssistPath( wchar_t *path );
void EncodeRot13( wchar_t *text );
enum TNetworkType
{
NETWORK_NONE,
NETWORK_SERVER, // \\server
NETWORK_SHARE, // \\server\share
NETWORK_DRIVE, // Q:
NETWORK_FOLDER, // either \\server\share\folder or Q:\folder
NETWORK_FILE, // something with extension
};
HRESULT MenuParseDisplayName( const wchar_t *path, PIDLIST_ABSOLUTE *pPidl, SFGAOF *pFlags, TNetworkType *pNetworkType );
const wchar_t *GetDefaultNetworkIcon( TNetworkType networkType );
bool MenuGetFileTimestamp( const wchar_t *path, FILETIME *pWriteTime, FILETIME *pCreateTime );
STDAPI ShGetKnownFolderPath( REFKNOWNFOLDERID rfid, PWSTR *pPath );
STDAPI ShGetKnownFolderIDList(REFKNOWNFOLDERID rfid, PIDLIST_ABSOLUTE *pPidl );
STDAPI ShGetKnownFolderItem(REFKNOWNFOLDERID rfid, IShellItem **ppItem );
#define TASKBAR_PINNED_ROOT L"%APPDATA%\\Microsoft\\Internet Explorer\\Quick Launch\\User Pinned\\TaskBar"
#define START_MENU_PINNED_ROOT L"%APPDATA%\\ClassicStart\\Pinned"
#define STARTSCREEN_COMMAND L"startscreen.lnk"
#define USERASSIST_LINKS_KEY L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\UserAssist\\{F4E57C4B-2036-45F0-A9AB-443BCFE33D9F}\\Count"
#define USERASSIST_APPIDS_KEY L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\UserAssist\\{CEBFF5CD-ACE2-4F4F-9178-9926F41749EA}\\Count"
//#define STARTSCREEN_WIN7
#ifdef BUILD_SETUP
#undef STARTSCREEN_WIN7
#endif

View File

@@ -0,0 +1,685 @@
// Classic Shell (c) 2009-2017, Ivo Beltchev
// Classic Start (c) 2017-2018, The Passionate-Coder Team
// Confidential information of Ivo Beltchev. Not for disclosure or distribution without prior written consent from the author
#include "stdafx.h"
#include "JumpLists.h"
#include "ItemManager.h"
#include "ResourceHelper.h"
#include "Translations.h"
#include "FNVHash.h"
#include "LogManager.h"
#include <propkey.h>
#include <StrSafe.h>
static const CLSID CLSID_AutomaticDestinationList={0xf0ae1542, 0xf497, 0x484b, {0xa1, 0x75, 0xa2, 0x0d, 0xb0, 0x91, 0x44, 0xba}};
struct APPDESTCATEGORY
{
int type;
union
{
wchar_t *name;
int subType;
};
int count;
int pad[10]; // just in case
};
static const GUID IID_IDestinationList={0x03f1eed2, 0x8676, 0x430b, {0xab, 0xe1, 0x76, 0x5c, 0x1d, 0x8f, 0xe1, 0x47}};
static const GUID IID_IDestinationList10a={0xfebd543d, 0x1f7b, 0x4b38, {0x94, 0x0b, 0x59, 0x33, 0xbd, 0x2c, 0xb2, 0x1b}}; // 10240
static const GUID IID_IDestinationList10b={0x507101cd, 0xf6ad, 0x46c8, {0x8e, 0x20, 0xee, 0xb9, 0xe6, 0xba, 0xc4, 0x7f}}; // 10547
interface IDestinationList: public IUnknown
{
public:
STDMETHOD(SetMinItems)();
virtual HRESULT STDMETHODCALLTYPE SetApplicationID( LPCWSTR appUserModelId ) = 0;
STDMETHOD(GetSlotCount)();
virtual HRESULT STDMETHODCALLTYPE GetCategoryCount( UINT *pCount ) = 0;
virtual HRESULT STDMETHODCALLTYPE GetCategory( UINT index, int getCatFlags, APPDESTCATEGORY *pCategory ) = 0;
STDMETHOD(DeleteCategory)();
virtual HRESULT STDMETHODCALLTYPE EnumerateCategoryDestinations( UINT index, REFIID riid, void **ppvObject ) = 0;
STDMETHOD(RemoveDestination)( IUnknown *pItem );
STDMETHOD(ResolveDestination)();
};
static const GUID IID_IAutomaticDestinationList={0xbc10dce3, 0x62f2, 0x4bc6, {0xaf, 0x37, 0xdb, 0x46, 0xed, 0x78, 0x73, 0xc4}};
static const GUID IID_IAutomaticDestinationList10b={0xe9c5ef8d, 0xfd41, 0x4f72, {0xba, 0x87, 0xeb, 0x03 ,0xba, 0xd5, 0x81, 0x7c}}; // 10547
interface IAutomaticDestinationList: public IUnknown
{
public:
virtual HRESULT STDMETHODCALLTYPE Initialize( LPCWSTR appUserModelId, LPCWSTR lnkPath, LPCWSTR ) = 0;
virtual HRESULT STDMETHODCALLTYPE HasList( BOOL *pHasList ) = 0;
virtual HRESULT STDMETHODCALLTYPE GetList( int listType, unsigned int maxCount, REFIID riid, void **ppvObject ) = 0;
STDMETHOD(AddUsagePoint)();
virtual HRESULT STDMETHODCALLTYPE PinItem( IUnknown *pItem, int pinIndex ) = 0; // -1 - pin, -2 - unpin
STDMETHOD(IsPinned)();
virtual HRESULT STDMETHODCALLTYPE RemoveDestination( IUnknown *pItem ) = 0;
STDMETHOD(SetUsageData)();
STDMETHOD(GetUsageData)();
STDMETHOD(ResolveDestination)();
virtual HRESULT STDMETHODCALLTYPE ClearList( int listType ) = 0;
};
interface IAutomaticDestinationList10b: public IUnknown
{
public:
virtual HRESULT STDMETHODCALLTYPE Initialize( LPCWSTR appUserModelId, LPCWSTR lnkPath, LPCWSTR ) = 0;
virtual HRESULT STDMETHODCALLTYPE HasList( BOOL *pHasList ) = 0;
virtual HRESULT STDMETHODCALLTYPE GetList( int listType, unsigned int maxCount, unsigned int flags, REFIID riid, void **ppvObject ) = 0;
STDMETHOD(AddUsagePoint)();
virtual HRESULT STDMETHODCALLTYPE PinItem( IUnknown *pItem, int pinIndex ) = 0; // -1 - pin, -2 - unpin
STDMETHOD(IsPinned)();
virtual HRESULT STDMETHODCALLTYPE RemoveDestination( IUnknown *pItem ) = 0;
STDMETHOD(SetUsageData)();
STDMETHOD(GetUsageData)();
STDMETHOD(ResolveDestination)();
virtual HRESULT STDMETHODCALLTYPE ClearList( int listType ) = 0;
};
class CAutomaticList
{
public:
CAutomaticList( const wchar_t *appid );
bool HasList( void );
CComPtr<IObjectCollection> GetList( int listType, unsigned int maxCount );
void PinItem( IUnknown *pItem, int pinIndex );
bool RemoveDestination( IUnknown *pItem );
private:
CComPtr<IAutomaticDestinationList> m_pAutoList;
CComPtr<IAutomaticDestinationList10b> m_pAutoList10b;
};
CAutomaticList::CAutomaticList( const wchar_t *appid )
{
CComPtr<IUnknown> pAutoListUnk;
if (SUCCEEDED(pAutoListUnk.CoCreateInstance(CLSID_AutomaticDestinationList)))
{
pAutoListUnk->QueryInterface(IID_IAutomaticDestinationList,(void**)&m_pAutoList);
if (m_pAutoList)
{
if (FAILED(m_pAutoList->Initialize(appid,NULL,NULL)))
m_pAutoList=NULL;
}
else if (GetWinVersion()>=WIN_VER_WIN10)
{
pAutoListUnk->QueryInterface(IID_IAutomaticDestinationList10b,(void**)&m_pAutoList10b);
if (m_pAutoList10b)
{
if (FAILED(m_pAutoList10b->Initialize(appid,NULL,NULL)))
m_pAutoList10b=NULL;
}
}
}
}
bool CAutomaticList::HasList( void )
{
BOOL hasList;
if (m_pAutoList)
{
if (FAILED(m_pAutoList->HasList(&hasList)) || !hasList)
return false;
}
else if (m_pAutoList10b)
{
if (FAILED(m_pAutoList10b->HasList(&hasList)) || !hasList)
return false;
}
else
return false;
CComPtr<IObjectCollection> pCollection;
UINT count;
pCollection=GetList(1,1);
if (pCollection && SUCCEEDED(pCollection->GetCount(&count)) && count>0)
return true;
pCollection=GetList(0,1);
if (pCollection && SUCCEEDED(pCollection->GetCount(&count)) && count>0)
return true;
return false;
}
CComPtr<IObjectCollection> CAutomaticList::GetList( int listType, unsigned int maxCount )
{
CComPtr<IObjectCollection> pCollection;
if (m_pAutoList)
m_pAutoList->GetList(listType,maxCount,IID_IObjectCollection,(void**)&pCollection);
else if (m_pAutoList10b)
m_pAutoList10b->GetList(listType,maxCount,1,IID_IObjectCollection,(void**)&pCollection);
return pCollection;
}
void CAutomaticList::PinItem( IUnknown *pItem, int pinIndex )
{
if (m_pAutoList)
m_pAutoList->PinItem(pItem,pinIndex);
else if (m_pAutoList10b)
m_pAutoList10b->PinItem(pItem,pinIndex);
}
bool CAutomaticList::RemoveDestination( IUnknown *pItem )
{
if (m_pAutoList)
return SUCCEEDED(m_pAutoList->RemoveDestination(pItem));
else if (m_pAutoList10b)
return SUCCEEDED(m_pAutoList10b->RemoveDestination(pItem));
return false;
}
static CComPtr<IDestinationList> GetCustomList( const wchar_t *appid )
{
CComPtr<IUnknown> pCustomListUnk;
if (SUCCEEDED(pCustomListUnk.CoCreateInstance(CLSID_DestinationList)))
{
CComPtr<IDestinationList> pCustomList;
if (GetWinVersion()<WIN_VER_WIN10)
pCustomListUnk->QueryInterface(IID_IDestinationList,(void**)&pCustomList);
else
{
if (FAILED(pCustomListUnk->QueryInterface(IID_IDestinationList10a,(void**)&pCustomList)))
pCustomListUnk->QueryInterface(IID_IDestinationList10b,(void**)&pCustomList);
}
if (pCustomList && SUCCEEDED(pCustomList->SetApplicationID(appid)))
return pCustomList;
}
return CComPtr<IDestinationList>();
}
// Returns true if the given app has a non-empty jumplist
bool HasJumplist( const wchar_t *appid )
{
Assert(GetWinVersion()>=WIN_VER_WIN7);
CComPtr<IDestinationList> pCustomList=GetCustomList(appid);
if (pCustomList)
{
UINT count;
if (SUCCEEDED(pCustomList->GetCategoryCount(&count)) && count>0)
return true;
}
if (CAutomaticList(appid).HasList())
return true;
return false;
}
static unsigned int CalcLinkHash( IShellLink *pLink )
{
CAbsolutePidl pidl;
if (FAILED(pLink->GetIDList(&pidl)))
return 0;
unsigned int hash=FNV_HASH0;
CComString pName;
if (SUCCEEDED(SHGetNameFromIDList(pidl,SIGDN_DESKTOPABSOLUTEPARSING,&pName)))
{
pName.MakeUpper();
hash=CalcFNVHash(pName);
}
CComQIPtr<IPropertyStore> pStore=pLink;
if (pStore)
hash=CalcFNVHash(GetPropertyStoreString(pStore,PKEY_Link_Arguments),hash);
return hash;
}
static void AddJumpItem( CJumpGroup &group, IUnknown *pUnknown, std::vector<CComPtr<IShellItem>> &ignoreItems, std::vector<unsigned int> &ignoreLinks )
{
CJumpItem item;
item.type=CJumpItem::TYPE_UNKNOWN;
item.pItem=pUnknown;
item.hash=0;
item.bHidden=false;
item.bHasArguments=false;
CComQIPtr<IShellItem> pItem=pUnknown;
if (pItem)
{
for (std::vector<CComPtr<IShellItem>>::const_iterator it=ignoreItems.begin();it!=ignoreItems.end();++it)
{
int order;
if (SUCCEEDED(pItem->Compare(*it,SICHINT_CANONICAL|SICHINT_TEST_FILESYSPATH_IF_NOT_EQUAL,&order)) && order==0)
return;
}
item.type=CJumpItem::TYPE_ITEM;
CComString pName;
if (FAILED(pItem->GetDisplayName(SIGDN_NORMALDISPLAY,&pName)))
return;
item.name=pName;
pName.Clear();
if (SUCCEEDED(pItem->GetDisplayName(SIGDN_DESKTOPABSOLUTEPARSING,&pName)))
{
LOG_MENU(LOG_OPEN,L"Jumplist Item Path: %s",(const wchar_t*)pName);
pName.MakeUpper();
item.hash=CalcFNVHash(pName);
}
LOG_MENU(LOG_OPEN,L"Jumplist Item Name: %s",item.name);
group.items.push_back(item);
return;
}
CComQIPtr<IShellLink> pLink=pUnknown;
if (pLink)
{
unsigned int hash=CalcLinkHash(pLink);
for (std::vector<unsigned int>::const_iterator it=ignoreLinks.begin();it!=ignoreLinks.end();++it)
{
if (hash==*it)
return;
}
item.type=CJumpItem::TYPE_LINK;
CComQIPtr<IPropertyStore> pStore=pLink;
if (pStore)
{
PROPVARIANT val;
PropVariantInit(&val);
if (group.type==CJumpGroup::TYPE_TASKS && SUCCEEDED(pStore->GetValue(PKEY_AppUserModel_IsDestListSeparator,&val)) && val.vt==VT_BOOL && val.boolVal)
{
item.type=CJumpItem::TYPE_SEPARATOR;
PropVariantClear(&val);
}
else
{
CString str=GetPropertyStoreString(pStore,PKEY_Title);
if (!str.IsEmpty())
{
wchar_t name[256];
SHLoadIndirectString(str,name,_countof(name),NULL);
item.name=name;
}
}
}
CAbsolutePidl pidl;
if (SUCCEEDED(pLink->GetIDList(&pidl)))
{
CComString pName;
if (item.name.IsEmpty())
{
if (SUCCEEDED(SHGetNameFromIDList(pidl,SIGDN_NORMALDISPLAY,&pName)))
{
item.name=pName;
}
}
pName.Clear();
if (SUCCEEDED(SHGetNameFromIDList(pidl,SIGDN_DESKTOPABSOLUTEPARSING,&pName)))
{
LOG_MENU(LOG_OPEN,L"Jumplist Link Path: %s",(const wchar_t*)pName);
pName.MakeUpper();
item.hash=CalcFNVHash(pName);
}
CComQIPtr<IPropertyStore> pStore=pLink;
if (pStore)
{
CString args=GetPropertyStoreString(pStore,PKEY_Link_Arguments);
if (!args.IsEmpty())
{
LOG_MENU(LOG_OPEN,L"Jumplist Link Args: %s",args);
item.hash=CalcFNVHash(args,item.hash);
item.bHasArguments=true;
}
}
}
LOG_MENU(LOG_OPEN,L"Jumplist Link Name: %s",item.name);
if (!item.name.IsEmpty())
group.items.push_back(item);
return;
}
}
static void AddJumpCollection( CJumpGroup &group, IObjectCollection *pCollection, std::vector<CComPtr<IShellItem>> &ignoreItems, std::vector<unsigned int> &ignoreLinks )
{
UINT count;
if (SUCCEEDED(pCollection->GetCount(&count)))
{
for (UINT i=0;i<count;i++)
{
CComPtr<IUnknown> pUnknown;
if (SUCCEEDED(pCollection->GetAt(i,IID_IUnknown,(void**)&pUnknown)) && pUnknown)
AddJumpItem(group,pUnknown,ignoreItems,ignoreLinks);
}
}
}
// Returns the jumplist for the given shortcut
bool GetJumplist( const wchar_t *appid, CJumpList &list, int maxCount, int maxHeight, int sepHeight, int itemHeight )
{
Assert(GetWinVersion()>=WIN_VER_WIN7);
list.Clear();
UINT categoryCount=0;
CComPtr<IDestinationList> pCustomList=GetCustomList(appid);
if (pCustomList)
{
if (FAILED(pCustomList->GetCategoryCount(&categoryCount)))
categoryCount=0;
}
list.groups.reserve(categoryCount+2);
std::vector<CComPtr<IShellItem>> ignoreItems;
std::vector<unsigned int> ignoreLinks;
CAutomaticList autoList(appid);
{
// add pinned
CComPtr<IObjectCollection> pPinnedList=autoList.GetList(0,maxCount);
if (pPinnedList)
{
Assert(list.groups.empty());
list.groups.resize(list.groups.size()+1);
CJumpGroup &group=*list.groups.rbegin();
group.type=CJumpGroup::TYPE_PINNED;
group.name=FindTranslation(L"JumpList.Pinned",L"Pinned");
AddJumpCollection(group,pPinnedList,ignoreItems,ignoreLinks);
for (std::vector<CJumpItem>::const_iterator it=group.items.begin();it!=group.items.end();++it)
{
CComQIPtr<IShellItem> pShellItem=it->pItem;
if (pShellItem)
ignoreItems.push_back(pShellItem);
else
{
CComQIPtr<IShellLink> pLink=it->pItem;
if (pLink)
{
unsigned int hash=CalcLinkHash(pLink);
if (hash)
ignoreLinks.push_back(hash);
}
}
}
}
}
int taskIndex=-1;
for (UINT catIndex=0;catIndex<categoryCount;catIndex++)
{
APPDESTCATEGORY category={0};
if (SUCCEEDED(pCustomList->GetCategory(catIndex,1,&category)))
{
if (category.type==0)
{
// custom group
if (category.name)
{
wchar_t name[256];
SHLoadIndirectString(category.name,name,_countof(name),NULL);
CoTaskMemFree(category.name);
CComPtr<IObjectCollection> pCollection;
if (SUCCEEDED(pCustomList->EnumerateCategoryDestinations(catIndex,IID_IObjectCollection,(void**)&pCollection)))
{
list.groups.resize(list.groups.size()+1);
CJumpGroup &group=*list.groups.rbegin();
group.name=name;
group.type=CJumpGroup::TYPE_CUSTOM;
AddJumpCollection(group,pCollection,ignoreItems,ignoreLinks);
}
}
}
else if (category.type==1)
{
// standard group
if (category.subType==1 || category.subType==2)
{
CComPtr<IObjectCollection> pCollection=autoList.GetList(3-category.subType,maxCount);
if (pCollection)
{
list.groups.resize(list.groups.size()+1);
CJumpGroup &group=*list.groups.rbegin();
if (category.subType==1)
{
group.type=CJumpGroup::TYPE_FREQUENT;
group.name=FindTranslation(L"JumpList.Frequent",L"Frequent");
}
else
{
group.type=CJumpGroup::TYPE_RECENT;
group.name=FindTranslation(L"JumpList.Recent",L"Recent");
}
AddJumpCollection(group,pCollection,ignoreItems,ignoreLinks);
}
}
}
else if (category.type==2 && taskIndex==-1)
{
taskIndex=catIndex;
}
}
}
if (taskIndex!=-1)
{
// add tasks
CComPtr<IObjectCollection> pCollection;
if (SUCCEEDED(pCustomList->EnumerateCategoryDestinations(taskIndex,IID_IObjectCollection,(void**)&pCollection)))
{
list.groups.resize(list.groups.size()+1);
CJumpGroup &group=*list.groups.rbegin();
group.name=FindTranslation(L"JumpList.Tasks",L"Tasks");
group.type=CJumpGroup::TYPE_TASKS;
AddJumpCollection(group,pCollection,ignoreItems,ignoreLinks);
}
}
if (categoryCount==0)
{
// add recent
CComPtr<IObjectCollection> pRecentList=autoList.GetList(1,maxCount);
if (pRecentList)
{
list.groups.resize(list.groups.size()+1);
CJumpGroup &group=*list.groups.rbegin();
group.type=CJumpGroup::TYPE_RECENT;
group.name=FindTranslation(L"JumpList.Recent",L"Recent");
AddJumpCollection(group,pRecentList,ignoreItems,ignoreLinks);
}
}
// limit the item count (not tasks or pinned)
for (std::vector<CJumpGroup>::iterator it=list.groups.begin();it!=list.groups.end();++it)
{
CJumpGroup &group=*it;
if (group.type==CJumpGroup::TYPE_TASKS || group.type==CJumpGroup::TYPE_PINNED)
maxHeight-=sepHeight+(int)group.items.size()*itemHeight;
}
for (std::vector<CJumpGroup>::iterator it=list.groups.begin();it!=list.groups.end();++it)
{
CJumpGroup &group=*it;
if (group.type!=CJumpGroup::TYPE_TASKS && group.type!=CJumpGroup::TYPE_PINNED)
{
maxHeight-=sepHeight;
for (std::vector<CJumpItem>::iterator it2=group.items.begin();it2!=group.items.end();++it2)
if (!it2->bHidden)
{
it2->bHidden=(maxCount<=0 || maxHeight<itemHeight);
maxCount--;
maxHeight-=itemHeight;
}
}
}
// hide empty groups
for (std::vector<CJumpGroup>::iterator it=list.groups.begin();it!=list.groups.end();++it)
{
CJumpGroup &group=*it;
group.bHidden=true;
for (std::vector<CJumpItem>::const_iterator it2=group.items.begin();it2!=group.items.end();++it2)
if (!it2->bHidden)
{
group.bHidden=false;
break;
}
}
return true;
}
// Executes the given item using the correct application
bool ExecuteJumpItem( const CItemManager::ItemInfo *pAppInfo, const CJumpItem &item, HWND hwnd )
{
Assert(GetWinVersion()>=WIN_VER_WIN7);
if (!item.pItem) return false;
if (item.type==CJumpItem::TYPE_ITEM)
{
/* CString appid;
{
CItemManager::RWLock lock(&g_ItemManager,false,CItemManager::RWLOCK_ITEMS);
appid=pAppInfo->GetAppid();
}
LOG_MENU(LOG_OPEN,L"Execute Item: name=%s, appid=%s",item.name,appid);*/
CComQIPtr<IShellItem> pItem=item.pItem;
if (!pItem)
return false;
/* CComString pName;
if (FAILED(pItem->GetDisplayName(SIGDN_DESKTOPABSOLUTEPARSING,&pName)))
return false;
wchar_t ext[_MAX_EXT];
Strcpy(ext,_countof(ext),PathFindExtension(pName));
// find the correct association handler by appid and invoke it on the item
CComPtr<IEnumAssocHandlers> pEnumHandlers;
if (ext[0] && SUCCEEDED(SHAssocEnumHandlers(ext,ASSOC_FILTER_RECOMMENDED,&pEnumHandlers)))
{
CComPtr<IAssocHandler> pHandler;
ULONG count;
while (SUCCEEDED(pEnumHandlers->Next(1,&pHandler,&count)) && count==1)
{
CComQIPtr<IObjectWithAppUserModelID> pObject=pHandler;
if (pObject)
{
CComString pID;
if (SUCCEEDED(pObject->GetAppID(&pID)))
{
// found explicit appid
if (_wcsicmp(appid,pID)==0)
{
LOG_MENU(LOG_OPEN,L"Found handler appid");
CComPtr<IDataObject> pDataObject;
if (SUCCEEDED(pItem->BindToHandler(NULL,BHID_DataObject,IID_IDataObject,(void**)&pDataObject)) && SUCCEEDED(pHandler->Invoke(pDataObject)))
return true;
break;
}
}
}
pHandler=NULL;
}
pEnumHandlers=NULL;
// find the correct association handler by exe name and invoke it on the item
wchar_t targetPath[_MAX_PATH];
targetPath[0]=0;
{
CComPtr<IShellItem> pItem;
SHCreateItemFromIDList(pAppInfo->GetPidl(),IID_IShellItem,(void**)&pItem);
CComPtr<IShellLink> pLink;
if (pItem)
pItem->BindToHandler(NULL,BHID_SFUIObject,IID_IShellLink,(void**)&pLink);
CAbsolutePidl target;
if (pLink && SUCCEEDED(pLink->Resolve(NULL,SLR_INVOKE_MSI|SLR_NO_UI|SLR_NOUPDATE)) && SUCCEEDED(pLink->GetIDList(&target)))
{
if (FAILED(SHGetPathFromIDList(target,targetPath)))
targetPath[0]=0;
}
}
if (targetPath[0] && SUCCEEDED(SHAssocEnumHandlers(ext,ASSOC_FILTER_RECOMMENDED,&pEnumHandlers)))
{
while (SUCCEEDED(pEnumHandlers->Next(1,&pHandler,&count)) && count==1)
{
CComString pExe;
if (SUCCEEDED(pHandler->GetName(&pExe)))
{
if (_wcsicmp(targetPath,pExe)==0)
{
LOG_MENU(LOG_OPEN,L"Found handler appexe %s",targetPath);
CComPtr<IDataObject> pDataObject;
if (SUCCEEDED(pItem->BindToHandler(NULL,BHID_DataObject,IID_IDataObject,(void**)&pDataObject)) && SUCCEEDED(pHandler->Invoke(pDataObject)))
return true;
break;
}
}
pHandler=NULL;
}
}
}
*/
// couldn't find a handler, execute the old way
SHELLEXECUTEINFO execute={sizeof(execute),SEE_MASK_IDLIST|SEE_MASK_FLAG_LOG_USAGE};
execute.nShow=SW_SHOWNORMAL;
CAbsolutePidl pidl;
if (SUCCEEDED(SHGetIDListFromObject(pItem,&pidl)))
{
execute.lpIDList=pidl;
ShellExecuteEx(&execute);
}
return true;
}
if (item.type==CJumpItem::TYPE_LINK)
{
// invoke the link through its context menu
CComQIPtr<IContextMenu> pMenu=item.pItem;
if (!pMenu) return false;
HRESULT hr;
HMENU menu=CreatePopupMenu();
hr=pMenu->QueryContextMenu(menu,0,1,1000,CMF_DEFAULTONLY);
if (FAILED(hr))
{
DestroyMenu(menu);
return false;
}
int id=GetMenuDefaultItem(menu,FALSE,0);
if (id>0)
{
CMINVOKECOMMANDINFO command={sizeof(command),CMIC_MASK_FLAG_LOG_USAGE};
command.lpVerb=MAKEINTRESOURCEA(id-1);
wchar_t path[_MAX_PATH];
GetModuleFileName(NULL,path,_countof(path));
if (_wcsicmp(PathFindFileName(path),L"explorer.exe")==0)
command.fMask|=CMIC_MASK_ASYNCOK;
command.hwnd=hwnd;
command.nShow=SW_SHOWNORMAL;
hr=pMenu->InvokeCommand(&command);
}
DestroyMenu(menu);
}
return true;
}
// Removes the given item from the jumplist
void RemoveJumpItem( const CItemManager::ItemInfo *pAppInfo, CJumpList &list, int groupIdx, int itemIdx )
{
CString appid;
{
CItemManager::RWLock lock(&g_ItemManager,false,CItemManager::RWLOCK_ITEMS);
appid=pAppInfo->GetAppid();
}
CJumpGroup &group=list.groups[groupIdx];
if (group.type==CJumpGroup::TYPE_FREQUENT || group.type==CJumpGroup::TYPE_RECENT)
{
if (CAutomaticList(appid).RemoveDestination(group.items[itemIdx].pItem))
group.items.erase(group.items.begin()+itemIdx);
}
else
{
CComPtr<IDestinationList> pCustomList=GetCustomList(appid);
if (pCustomList)
{
if (SUCCEEDED(pCustomList->RemoveDestination(group.items[itemIdx].pItem)))
group.items.erase(group.items.begin()+itemIdx);
}
}
}
// Pins or unpins the given item from the jumplist
void PinJumpItem( const CItemManager::ItemInfo *pAppInfo, const CJumpList &list, int groupIdx, int itemIdx, bool bPin, int pinIndex )
{
CString appid;
{
CItemManager::RWLock lock(&g_ItemManager,false,CItemManager::RWLOCK_ITEMS);
appid=pAppInfo->GetAppid();
}
const CJumpGroup &group=list.groups[groupIdx];
CAutomaticList(appid).PinItem(group.items[itemIdx].pItem,bPin?pinIndex:-2);
}

View File

@@ -0,0 +1,66 @@
// Classic Shell (c) 2009-2017, Ivo Beltchev
// Classic Start (c) 2017-2018, The Passionate-Coder Team
// Confidential information of Ivo Beltchev. Not for disclosure or distribution without prior written consent from the author
#pragma once
#include <vector>
#include "ItemManager.h"
// Returns true if the given app has a non-empty jumplist
bool HasJumplist( const wchar_t *appid );
struct CJumpItem
{
CJumpItem( void ) { type=TYPE_UNKNOWN; hash=0; bHidden=bHasArguments=false; }
enum Type
{
TYPE_UNKNOWN,
TYPE_ITEM, // IShellItem
TYPE_LINK, // IShellLink
TYPE_SEPARATOR,
};
Type type;
unsigned int hash;
bool bHidden;
bool bHasArguments;
CString name;
CComPtr<IUnknown> pItem;
};
struct CJumpGroup
{
CJumpGroup( void ) { type=TYPE_RECENT; bHidden=false; }
enum Type
{
TYPE_RECENT,
TYPE_FREQUENT,
TYPE_TASKS,
TYPE_CUSTOM,
TYPE_PINNED,
};
Type type;
bool bHidden;
CString name;
std::vector<CJumpItem> items;
};
struct CJumpList
{
std::vector<CJumpGroup> groups;
void Clear( void ) { groups.clear(); }
};
// Returns the jumplist for the given shortcut
bool GetJumplist( const wchar_t *appid, CJumpList &list, int maxCount, int maxHeight, int sepHeight, int itemHeight );
// Executes the given item using the correct application
bool ExecuteJumpItem( const CItemManager::ItemInfo *pAppInfo, const CJumpItem &item, HWND hwnd );
// Removes the given item from the jumplist
void RemoveJumpItem( const CItemManager::ItemInfo *pAppInfo, CJumpList &list, int groupIdx, int itemIdx );
// Pins or unpins the given item from the jumplist
void PinJumpItem( const CItemManager::ItemInfo *pAppInfo, const CJumpList &list, int groupIdx, int itemIdx, bool bPin, int pinIndex );

View File

@@ -0,0 +1,53 @@
// Classic Shell (c) 2009-2017, Ivo Beltchev
// Classic Start (c) 2017-2018, The Passionate-Coder Team
// Confidential information of Ivo Beltchev. Not for disclosure or distribution without prior written consent from the author
// LogManager.cpp - logging functionality (for debugging)
#include "stdafx.h"
#include "LogManager.h"
#include "ResourceHelper.h"
int g_LogCategories;
static FILE *g_LogFile;
static int g_LogTime;
void InitLog( int categories, const wchar_t *fname )
{
CloseLog();
if (categories==0) return;
if (_wfopen_s(&g_LogFile,fname,L"wb")==0)
{
wchar_t bom=0xFEFF;
fwrite(&bom,2,1,g_LogFile);
g_LogCategories=categories;
g_LogTime=GetTickCount();
LogMessage(L"version=%x, PID=%d, TID=%d, Categories=%08x\r\n",GetWinVersion(),GetCurrentProcessId(),GetCurrentThreadId(),categories);
}
}
void CloseLog( void )
{
if (g_LogFile) fclose(g_LogFile);
g_LogFile=NULL;
g_LogCategories=0;
}
void LogMessage( const wchar_t *text, ... )
{
if (!g_LogFile) return;
wchar_t buf[2048];
int len=Sprintf(buf,_countof(buf),L"%8d: ",GetTickCount()-g_LogTime);
fwrite(buf,2,len,g_LogFile);
va_list args;
va_start(args,text);
len=Vsprintf(buf,_countof(buf),text,args);
va_end(args);
fwrite(buf,2,len,g_LogFile);
fwrite(L"\r\n",2,2,g_LogFile);
fflush(g_LogFile);
}

View File

@@ -0,0 +1,35 @@
// Classic Shell (c) 2009-2017, Ivo Beltchev
// Classic Start (c) 2017-2018, The Passionate-Coder Team
// Confidential information of Ivo Beltchev. Not for disclosure or distribution without prior written consent from the author
#pragma once
// LogManager.h - logging functionality (for debugging)
// Logs different events in the start menu
// Turn it on by setting the LogLevel setting in the registry
// The logging is consuming very little resources when it is turned off
enum TLogCategory
{
LOG_OPEN= 0x001, // logs opening and closing of menus
LOG_ITEMS= 0x002, // logs the menu items
LOG_EXECUTE= 0x004, // logs when items are executed
LOG_MFU= 0x008, // logs the MFU items and ranks
LOG_NEW= 0x010, // logs the highlighted programs
LOG_APPS= 0x120, // logs the found metro apps
LOG_SEARCH= 0x040, // logs the search results and ranks
LOG_SEARCH_SQL= 0x080, // logs the SQL search queries and results
LOG_MOUSE= 0x100, // logs mouse events (only hovering for now)
LOG_CACHE= 0x200, // logs the contents of the cache file
LOG_ALL= 0xFFF
};
#define LOG_MENU( CATEGORY, TEXT, ... ) if (g_LogCategories&CATEGORY) { LogMessage(TEXT,__VA_ARGS__); }
extern int g_LogCategories;
void InitLog( int categories, const wchar_t *fname );
void CloseLog( void );
void LogMessage( const wchar_t *text, ... );
#define STARTUP_LOG L"Software\\PassionateCoder\\ClassicStartMenu\\Settings|LogStartup|%LOCALAPPDATA%\\ClassicStart\\StartupLog.txt"

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,383 @@
// Classic Shell (c) 2009-2017, Ivo Beltchev
// Classic Start (c) 2017-2018, The Passionate-Coder Team
// Confidential information of Ivo Beltchev. Not for disclosure or distribution without prior written consent from the author
#include "stdafx.h"
#include "MetroLinkManager.h"
#include "ItemManager.h"
#include "LogManager.h"
#include "FNVHash.h"
#include "ResourceHelper.h"
#include "Translations.h"
#include <propkey.h>
#include <map>
PROPERTYKEY PKEY_MetroAppLink={{0x9F4C2855, 0x9F79, 0x4B39, {0xA8, 0xD0, 0xE1, 0xD4, 0x2D, 0xE1, 0xD5, 0xF3}}, 10}; // pidl
PROPERTYKEY PKEY_MetroAppLauncher={{0x9F4C2855, 0x9F79, 0x4B39, {0xA8, 0xD0, 0xE1, 0xD4, 0x2D, 0xE1, 0xD5, 0xF3}}, 14}; // =1 for metro apps
PROPERTYKEY PKEY_MetroIconColor={{0x86D40B4D, 0x9069, 0x443C, {0x81, 0x9A, 0x2A, 0x54, 0x09, 0x0D, 0xCC, 0xEC}}, 4};
PROPERTYKEY PKEY_MetroPackageName={{0x9F4C2855, 0x9F79, 0x4B39, {0xA8, 0xD0, 0xE1, 0xD4, 0x2D, 0xE1, 0xD5, 0xF3}}, 21};
PROPERTYKEY PKEY_MetroPackagePath={{0x9F4C2855, 0x9F79, 0x4B39, {0xA8, 0xD0, 0xE1, 0xD4, 0x2D, 0xE1, 0xD5, 0xF3}}, 15};
PROPERTYKEY PKEY_AppUserModel_ParentID={{0x9F4C2855, 0x9F79, 0x4B39, {0xA8, 0xD0, 0xE1, 0xD4, 0x2D, 0xE1, 0xD5, 0xF3}}, 19}; // non-empty for content tiles
PROPERTYKEY PKEY_AppUserModel_InstalledBy={{0x9F4C2855, 0x9F79, 0x4B39, {0xA8, 0xD0, 0xE1, 0xD4, 0x2D, 0xE1, 0xD5, 0xF3}}, 18};
PROPERTYKEY PKEY_Launcher_AppState={{0x0ded77b3, 0xc614, 0x456c, {0xae, 0x5b, 0x28, 0x5b, 0x38, 0xd7, 0xb0, 0x1b}}, 7};
// FOLDERID_AppsFolder is defined in the 8.0 SDK, but we don't want to require it
KNOWNFOLDERID FOLDERID_AppsFolder2={0x1E87508D,0x89C2,0x42F0,{0x8A,0x7E,0x64,0x5A,0x0F,0x50,0xCA,0x58}}; // similar to shell:::{4234d49b-0245-4df3-b780-3893943456e1}
GUID CLSID_PinExt={0x90AA3A4E,0x1CBA,0x4233,{0xB8,0xBB,0x53,0x57,0x73,0xD4,0x84,0x49}};
const wchar_t *MetroAppClassId=L"Launcher.ImmersiveApplication";
// Returns a list of links for all metro apps
void GetMetroLinks( std::vector<MetroLink> &links, bool bLog, std::vector<CString> *pNonApps10 )
{
LOG_MENU(LOG_APPS,L"Collect Metro Links (start)");
if (bLog && !(g_LogCategories&LOG_APPS))
bLog=false;
CComPtr<IShellItem> pApps;
if (FAILED(ShGetKnownFolderItem(FOLDERID_AppsFolder2,&pApps)))
return;
CComPtr<IEnumShellItems> pEnum;
pApps->BindToHandler(NULL,BHID_EnumItems,IID_IEnumShellItems,(void**)&pEnum);
CComPtr<IShellItem> pChild;
while (pEnum && (pChild=NULL,pEnum->Next(1,&pChild,NULL)==S_OK))
{
if (bLog)
{
CComString pName;
pChild->GetDisplayName(SIGDN_DESKTOPABSOLUTEPARSING,&pName);
LOG_MENU(LOG_APPS,L"App: %s",(const wchar_t*)pName);
}
CComPtr<IPropertyStore> pStore;
if (FAILED(pChild->BindToHandler(NULL,BHID_PropertyStore,IID_IPropertyStore,(void**)&pStore)))
{
LOG_MENU(LOG_APPS,L" No Store");
continue;
}
PROPVARIANT val;
PropVariantInit(&val);
bool bNonApp=false;
if (FAILED(pStore->GetValue(PKEY_MetroAppLauncher,&val)))
{
LOG_MENU(LOG_APPS,L" No launcher");
bNonApp=true;
}
else
{
if ((val.vt!=VT_I4 && val.vt!=VT_UI4) || !val.intVal)
{
LOG_MENU(LOG_APPS,L" No launcher: %d",val.vt);
bNonApp=true;
}
PropVariantClear(&val);
}
if (GetWinVersion()>=WIN_VER_WIN10)
{
PIDLIST_ABSOLUTE pidl;
if (!bNonApp && SUCCEEDED(SHGetIDListFromObject(pChild,&pidl)))
{
links.resize(links.size()+1);
MetroLink &link=*links.rbegin();
link.pidl.Attach(pidl);
link.appid=GetPropertyStoreString(pStore,PKEY_AppUserModel_ID);
link.pItem=pChild;
}
else
bNonApp=true;
if (bNonApp && pNonApps10)
pNonApps10->push_back(GetPropertyStoreString(pStore,PKEY_AppUserModel_ID));
continue;
}
if (bNonApp)
continue;
if (FAILED(pStore->GetValue(PKEY_MetroAppLink,&val)))
{
LOG_MENU(LOG_APPS,L" No link");
continue;
}
if (val.vt!=(VT_VECTOR|VT_UI1) || !val.caub.pElems)
{
LOG_MENU(LOG_APPS,L" No link: %d",val.vt);
PropVariantClear(&val);
continue;
}
PIDLIST_ABSOLUTE pidl=ILCloneFull((PIDLIST_ABSOLUTE)val.caub.pElems);
PropVariantClear(&val);
links.resize(links.size()+1);
MetroLink &link=*links.rbegin();
link.pidl.Attach(pidl);
SHCreateItemFromIDList(pidl,IID_IShellItem,(void**)&link.pItem);
if (bLog && link.pItem)
{
CComString pName;
link.pItem->GetDisplayName(SIGDN_DESKTOPABSOLUTEPARSING,&pName);
LOG_MENU(LOG_APPS,L" Link: %s",(const wchar_t*)pName);
}
}
LOG_MENU(LOG_APPS,L"Collect Metro Links (end)");
}
void ExecuteMetroLink( const CItemManager::ItemInfo *pInfo )
{
SHELLEXECUTEINFO execute={sizeof(execute),SEE_MASK_CLASSNAME|SEE_MASK_INVOKEIDLIST|SEE_MASK_FLAG_LOG_USAGE|SEE_MASK_FLAG_NO_UI};
wchar_t path[_MAX_PATH];
{
CItemManager::RWLock lock(&g_ItemManager,false,CItemManager::RWLOCK_ITEMS);
Strcpy(path,_countof(path),pInfo->GetPath());
}
execute.lpFile=path;
execute.nShow=SW_SHOWNORMAL;
execute.lpClass=MetroAppClassId;
BOOL res=ShellExecuteEx(&execute);
LOG_MENU(LOG_EXECUTE,L"ExecuteMetroLink: 0x%08X 0x%p",res?0:GetLastError(),execute.hInstApp);
// create UserAssist entry
{
CRegKey regKey;
if (regKey.Open(HKEY_CURRENT_USER,L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced")!=ERROR_SUCCESS)
return;
DWORD val;
if (regKey.QueryDWORDValue(L"Start_TrackProgs",val)==ERROR_SUCCESS && !val)
return;
}
CRegKey regKeyLink;
if (regKeyLink.Open(HKEY_CURRENT_USER,USERASSIST_LINKS_KEY,KEY_READ|KEY_WRITE)!=ERROR_SUCCESS)
return;
EncodeUserAssistPath(path);
EncodeRot13(path);
UserAssistData data;
DWORD size=sizeof(data);
if (regKeyLink.QueryBinaryValue(path,&data,&size)!=ERROR_SUCCESS)
memset(&data,0,sizeof(data));
GetSystemTimeAsFileTime(&data.timestamp);
data.count++;
regKeyLink.SetBinaryValue(path,&data,sizeof(data));
}
/*
void ExecutePCSettings( void )
{
const wchar_t *appid=L"windows.immersivecontrolpanel_cw5n1h2txyewy!microsoft.windows.immersivecontrolpanel";
CComPtr<IShellItem> pItem;
if (SUCCEEDED(SHCreateItemInKnownFolder(FOLDERID_AppsFolder2,0,appid,IID_IShellItem,(void**)&pItem)))
{
CAbsolutePidl pidl;
if (SUCCEEDED(SHGetIDListFromObject(pItem,&pidl)))
{
SHELLEXECUTEINFO execute={sizeof(execute),SEE_MASK_IDLIST|SEE_MASK_FLAG_LOG_USAGE};
execute.lpIDList=pidl;
execute.nShow=SW_SHOWNORMAL;
ShellExecuteEx(&execute);
}
}
}
}
*/
CComPtr<IContextMenu> GetMetroPinMenu( const wchar_t *appid )
{
if (GetWinVersion()<WIN_VER_WIN10 && !IsWin81Update1()) return NULL;
CComPtr<IShellFolder> pAppFolder;
{
CAbsolutePidl pidl;
if (SUCCEEDED(SHGetKnownFolderIDList(FOLDERID_AppsFolder2,KF_FLAG_DEFAULT,NULL,&pidl)))
SHBindToObject(NULL,pidl,NULL,IID_IShellFolder,(void **)&pAppFolder);
}
CComPtr<IContextMenu> pPinMenu;
if (pAppFolder)
{
PIDLIST_RELATIVE child;
if (SUCCEEDED(pAppFolder->ParseDisplayName(NULL,NULL,(LPWSTR)appid,NULL,&child,NULL)))
{
CComPtr<IDataObject> pDataObject;
if (SUCCEEDED(pAppFolder->GetUIObjectOf(NULL,1,(PCUITEMID_CHILD*)&child,IID_IDataObject,NULL,(void**)&pDataObject)))
{
CRegKey regKey;
if (regKey.Open(HKEY_CLASSES_ROOT,MetroAppClassId,KEY_READ)==ERROR_SUCCESS)
{
CComPtr<IShellExtInit> pInit;
pInit.CoCreateInstance(CLSID_PinExt);
if (pInit && SUCCEEDED(pInit->Initialize(NULL,pDataObject,regKey)))
pPinMenu=CComQIPtr<IContextMenu>(pInit);
}
}
ILFree(child);
}
}
return pPinMenu;
}
static const wchar_t *g_UninstallableApps[]={
L"windows.immersivecontrolpanel_cw5n1h2txyewy!microsoft.windows.immersivecontrolpanel",
L"Microsoft.WindowsStore_8wekyb3d8bbwe!App",
L"Microsoft.Windows.Cortana_cw5n1h2txyewy!CortanaUI",
};
// Returns true if the app should not be uninstalled
bool IsProtectedApp( const wchar_t *appid )
{
for (int i=0;i<_countof(g_UninstallableApps);i++)
{
if (_wcsicmp(appid,g_UninstallableApps[i])==0)
return true;
}
return false;
}
// Returns true if uninstalling is allowed by the policy
bool GetUninstallPolicy( void )
{
if (GetWinVersion()<WIN_VER_WIN8)
return false;
CRegKey regKey;
if (regKey.Open(HKEY_CURRENT_USER,L"Software\\Policies\\Microsoft\\Windows\\Explorer",KEY_READ)==ERROR_SUCCESS)
{
DWORD val;
if (regKey.QueryDWORDValue(L"NoUninstallFromStart",val)==ERROR_SUCCESS && val)
return false;
}
return true;
}
// Checks if the app can be uninstalled
bool CanUninstallMetroApp( const wchar_t *appid )
{
if (IsProtectedApp(appid) || !GetUninstallPolicy())
return false;
CComPtr<IShellItem2> pAppItem;
if (FAILED(SHCreateItemInKnownFolder(FOLDERID_AppsFolder2,0,appid,IID_IShellItem2,(void**)&pAppItem)))
return false;
CComPtr<IPropertyStore> pStore;
PROPERTYKEY keys[]={
PKEY_MetroPackagePath,
PKEY_AppUserModel_ParentID,
PKEY_AppUserModel_InstalledBy,
PKEY_AppUserModel_IsDualMode,
PKEY_Launcher_AppState,
};
if (FAILED(pAppItem->GetPropertyStoreForKeys(keys,_countof(keys),GPS_FASTPROPERTIESONLY,IID_IPropertyStore,(void**)&pStore)))
return false;
CString parentid=GetPropertyStoreString(pStore,PKEY_AppUserModel_ParentID);
if (!parentid.IsEmpty())
return false; // this is a child tile
CString packagePath=GetPropertyStoreString(pStore,PKEY_MetroPackagePath);
if (packagePath.IsEmpty() || GetFileAttributes(packagePath)==INVALID_FILE_ATTRIBUTES)
return false;
PROPVARIANT val;
PropVariantInit(&val);
bool res=true;
if (SUCCEEDED(pStore->GetValue(PKEY_AppUserModel_InstalledBy,&val)))
{
if (val.vt==VT_UI4 && val.intVal==1)
res=false; // from CAppTileHelper::IsInboxAppTile
}
PropVariantClear(&val);
if (res && SUCCEEDED(pStore->GetValue(PKEY_AppUserModel_IsDualMode,&val)))
{
if (val.vt==VT_BOOL && val.boolVal)
res=false;
}
PropVariantClear(&val);
if (!res) return false;
if (SUCCEEDED(pStore->GetValue(PKEY_Launcher_AppState,&val)))
{
if (val.vt!=VT_UI4 || val.intVal==4 || val.intVal==6)
res=false;
}
else
res=false;
PropVariantClear(&val);
return res;
}
// Uninstalls the app with the given id
void UninstallMetroApp( const wchar_t *appid )
{
CComPtr<IShellItem> pAppItem;
if (SUCCEEDED(SHCreateItemInKnownFolder(FOLDERID_AppsFolder2,0,appid,IID_IShellItem,(void**)&pAppItem)))
{
CComPtr<IPropertyStore> pStore;
pAppItem->BindToHandler(NULL,BHID_PropertyStore,IID_IPropertyStore,(void**)&pStore);
if (pStore)
{
CString packageName=GetPropertyStoreString(pStore,PKEY_MetroPackageName);
if (!packageName.IsEmpty())
{
wchar_t command[1024];
Sprintf(command,_countof(command),L"Remove-AppxPackage %s",packageName);
ShellExecute(NULL,L"open",L"powershell.exe",command,NULL,SW_HIDE);
}
}
}
}
// Asks for confirmation to uninstall the specified app
void UninstallMetroApp( HWND parent, const wchar_t *name, const wchar_t *appid )
{
wchar_t text[1024];
Sprintf(text,_countof(text),FindTranslation(L"Menu.UninstallPrompt",L"Are you sure you want to uninstall %s?"),name);
CString title=FindTranslation(L"Menu.UninstallTitle",L"Uninstall");
HICON hIcon=NULL;
CComPtr<IShellItem> pAppItem;
if (SUCCEEDED(SHCreateItemInKnownFolder(FOLDERID_AppsFolder2,0,appid,IID_IShellItem,(void**)&pAppItem)))
{
CAbsolutePidl pidl;
SHGetIDListFromObject(pAppItem,&pidl);
const CItemManager::ItemInfo *pItemInfo=g_ItemManager.GetItemInfo(pAppItem,pidl,CItemManager::INFO_LINK|CItemManager::INFO_METRO);
g_ItemManager.UpdateItemInfo(pItemInfo,CItemManager::INFO_LARGE_ICON|CItemManager::INFO_REFRESH_NOW);
HBITMAP hMonoBitmap=CreateBitmap(CItemManager::LARGE_ICON_SIZE,CItemManager::LARGE_ICON_SIZE,1,1,NULL);
ICONINFO info={TRUE,0,0,hMonoBitmap,pItemInfo->largeIcon->bitmap};
hIcon=CreateIconIndirect(&info);
DeleteObject(hMonoBitmap);
}
TASKDIALOGCONFIG task={sizeof(task),parent,NULL,TDF_ALLOW_DIALOG_CANCELLATION|TDF_USE_HICON_MAIN,TDCBF_YES_BUTTON|TDCBF_NO_BUTTON};
task.pszWindowTitle=title;
task.pszContent=text;
task.hMainIcon=hIcon?hIcon:LoadIcon(NULL,IDI_QUESTION);
int res;
if (FAILED(TaskDialogIndirect(&task,&res,NULL,NULL)))
res=0;
if (hIcon) DestroyIcon(hIcon);
if (res==IDYES)
UninstallMetroApp(appid);
}
// Determines if Edge is the default browser
bool IsEdgeDefaultBrowser( void )
{
if (GetWinVersion()<WIN_VER_WIN10)
return false;
CRegKey userKey;
if (userKey.Open(HKEY_CURRENT_USER,L"Software\\Microsoft\\Windows\\Shell\\Associations\\UrlAssociations\\http\\UserChoice",KEY_READ)==ERROR_SUCCESS)
{
wchar_t text[_MAX_PATH]=L"";
ULONG size=_countof(text);
if (userKey.QueryStringValue(L"ProgId",text,&size)==ERROR_SUCCESS)
{
wchar_t path[_MAX_PATH];
Sprintf(path,_countof(path),L"%s\\Application",text);
CRegKey appKey;
if (userKey.Open(HKEY_CLASSES_ROOT,path,KEY_READ)==ERROR_SUCCESS)
{
size=_countof(text);
if (userKey.QueryStringValue(L"AppUserModelID",text,&size)==ERROR_SUCCESS)
{
if (_wcsicmp(text,L"Microsoft.MicrosoftEdge_8wekyb3d8bbwe!MicrosoftEdge")==0)
return true;
}
}
}
}
return false;
}

View File

@@ -0,0 +1,55 @@
// Classic Shell (c) 2009-2017, Ivo Beltchev
// Classic Start (c) 2017-2018, The Passionate-Coder Team
// Confidential information of Ivo Beltchev. Not for disclosure or distribution without prior written consent from the author
#pragma once
#include <vector>
#include "ItemManager.h"
#include "LogManager.h"
#define METRO_APP_ROOT L"%LOCALAPPDATA%\\Microsoft\\Windows\\Application Shortcuts"
extern PROPERTYKEY PKEY_MetroAppLink; // pidl
extern PROPERTYKEY PKEY_MetroAppLauncher; // =1 for metro apps
extern PROPERTYKEY PKEY_MetroIconColor;
extern KNOWNFOLDERID FOLDERID_AppsFolder2;
#define DESKTOP_APP_ID L"Microsoft.Windows.Desktop"
#define SEARCH_APP_ID L"Windows.UI.Search"
struct MetroLink
{
CAbsolutePidl pidl;
CString appid; // only for Windows 10
CComPtr<IShellItem> pItem;
};
// Returns a list of links for all metro apps
void GetMetroLinks( std::vector<MetroLink> &links, bool bLog, std::vector<CString> *pNonApps10=NULL );
// Executes the metro link of the given item info
void ExecuteMetroLink( const CItemManager::ItemInfo *pInfo );
// Returns true if the app is still valid
bool IsValidApp( const wchar_t *appid );
// Returns true if the app should not be uninstalled
bool IsProtectedApp( const wchar_t *appid );
// Returns true if uninstalling is allowed by the policy
bool GetUninstallPolicy( void );
// Checks if the app can be uninstalled
bool CanUninstallMetroApp( const wchar_t *appid );
// Uninstalls the app with the given id
void UninstallMetroApp( const wchar_t *appid );
// Asks for confirmation to uninstall the specified app
void UninstallMetroApp( HWND parent, const wchar_t *name, const wchar_t *appid );
// Creates a context menu to pin/unpin the metro app to the taskbar
CComPtr<IContextMenu> GetMetroPinMenu( const wchar_t *appid );
// Determines if Edge is the default browser
bool IsEdgeDefaultBrowser( void );

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,222 @@
// Classic Shell (c) 2009-2017, Ivo Beltchev
// Classic Start (c) 2017-2018, The Passionate-Coder Team
// Confidential information of Ivo Beltchev. Not for disclosure or distribution without prior written consent from the author
#pragma once
#include "ItemManager.h"
#include "DragDrop.h"
class CMenuContainer;
class CProgramsTree: public IDropTarget, public CWindowImpl<CProgramsTree>
{
public:
enum {
TVM_REFRESH=WM_APP+1,
TIMER_HOVER=1,
};
struct CTreeItem
{
CString name;
unsigned int nameHashProg; // hash if the item is directly in the Programs folder
unsigned int nameHash; // hash if the item is not directly in the Programs folder
const CItemManager::ItemInfo *pItemInfo1;
const CItemManager::ItemInfo *pItemInfo2;
bool bFolder;
bool bEmpty;
bool bApps; // the Apps folder item
bool bApp; // App inside the Apps folder
bool bAutoSort;
bool bPrograms; // this item is directly in the Programs folder
bool bNew;
int order;
unsigned int folderHash; // only if bFolder
CTreeItem( void ) { nameHash=nameHashProg=0; pItemInfo1=pItemInfo2=NULL; bFolder=bEmpty=bApps=bApp=bAutoSort=bPrograms=bNew=false; order=0; folderHash=0; }
void SetName( const wchar_t *_name, bool bNoExtensions )
{
if (bNoExtensions)
{
const wchar_t *end=wcsrchr(_name,'.');
if (end)
{
name=CString(_name,(int)(end-_name));
return;
}
}
name=_name;
}
bool operator==( const CTreeItem &item ) const { return pItemInfo1==item.pItemInfo1 && pItemInfo2==item.pItemInfo2 && name==item.name && bFolder==item.bFolder && (bFolder || bNew==item.bNew); }
unsigned int GetNameHash( void ) const { return bPrograms?nameHashProg:nameHash; }
};
BEGIN_MSG_MAP( CProgramsTree )
MESSAGE_HANDLER( WM_DESTROY, OnDestroy )
MESSAGE_HANDLER( WM_KEYDOWN, OnKeyDown )
MESSAGE_HANDLER( WM_SYSKEYDOWN, OnSysKeyDown )
MESSAGE_HANDLER( WM_CHAR, OnChar )
MESSAGE_HANDLER( WM_SETFOCUS, OnSetFocus )
MESSAGE_HANDLER( WM_MOUSEMOVE, OnMouseMove )
MESSAGE_HANDLER( WM_MOUSELEAVE, OnMouseLeave )
MESSAGE_HANDLER( WM_NCMOUSEMOVE, OnNcMouseMove )
MESSAGE_HANDLER( WM_NCMOUSELEAVE, OnNcMouseLeave )
MESSAGE_HANDLER( WM_MOUSEACTIVATE, OnMouseActivate )
MESSAGE_HANDLER( WM_NCLBUTTONDOWN, OnNcLButtonDown)
MESSAGE_HANDLER( WM_TIMER, OnTimer )
MESSAGE_HANDLER( WM_ERASEBKGND, OnEraseBkgnd )
MESSAGE_HANDLER( WM_PAINT, OnPaint )
MESSAGE_HANDLER( WM_CONTEXTMENU, OnContextMenu )
MESSAGE_HANDLER( WM_HSCROLL, OnScroll )
MESSAGE_HANDLER( WM_VSCROLL, OnScroll )
MESSAGE_HANDLER( WM_MOUSEWHEEL, OnScroll )
MESSAGE_HANDLER( TVM_SETINSERTMARK, OnSetInsertMark )
MESSAGE_HANDLER( TVM_REFRESH, OnRefresh )
REFLECTED_NOTIFY_CODE_HANDLER( TVN_DELETEITEM, OnDeleteItem )
REFLECTED_NOTIFY_CODE_HANDLER( TVN_ITEMEXPANDING, OnItemExpanding )
REFLECTED_NOTIFY_CODE_HANDLER( TVN_SINGLEEXPAND, OnSingleExpand )
REFLECTED_NOTIFY_CODE_HANDLER( TVN_BEGINDRAG, OnBeginDrag )
REFLECTED_NOTIFY_CODE_HANDLER( TVN_BEGINRDRAG, OnBeginDrag )
REFLECTED_NOTIFY_CODE_HANDLER( TVN_BEGINLABELEDIT, OnBeginLabelEdit )
REFLECTED_NOTIFY_CODE_HANDLER( TVN_ENDLABELEDIT, OnEndLabelEdit )
REFLECTED_NOTIFY_CODE_HANDLER( TVN_GETINFOTIP, OnGetInfoTip )
REFLECTED_NOTIFY_CODE_HANDLER( NM_CLICK, OnClick )
REFLECTED_NOTIFY_CODE_HANDLER( NM_RCLICK, OnRClick )
END_MSG_MAP()
CProgramsTree( void );
~CProgramsTree( void )
{
Assert(m_RefCount==0);
}
void Create( CMenuContainer *pOwner );
virtual WNDPROC GetWindowProc( void ) { return CustomWindowProc; }
static LRESULT CALLBACK CustomWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
void DeleteAllItems( void );
void CreateItems( void );
void SelectItem( int y );
void SelectFirst( void );
void SelectLast( void );
void ClearAllNew( void );
// reorders the tree elements and saves the order in registry
void OrderElements( HTREEITEM hChild, HTREEITEM hParent, const std::vector<unsigned int> &order, bool bAutoSort, bool bResort );
// saves the item order by replacing the item with the new info
void SaveRenamedOrder( HTREEITEM hItem, const CItemManager::ItemInfo *pNewInfo );
// IUnknown
virtual STDMETHODIMP QueryInterface( REFIID riid, void **ppvObject )
{
Assert(0);
*ppvObject=NULL;
return E_FAIL;
}
virtual ULONG STDMETHODCALLTYPE AddRef( void )
{
return InterlockedIncrement(&m_RefCount);
}
virtual ULONG STDMETHODCALLTYPE Release( void )
{
long nTemp=InterlockedDecrement(&m_RefCount);
if (!nTemp) delete this;
return nTemp;
}
// IDropTarget
virtual HRESULT STDMETHODCALLTYPE DragEnter( IDataObject *pDataObj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect );
virtual HRESULT STDMETHODCALLTYPE DragOver( DWORD grfKeyState, POINTL pt, DWORD *pdwEffect );
virtual HRESULT STDMETHODCALLTYPE DragLeave( void );
virtual HRESULT STDMETHODCALLTYPE Drop( IDataObject *pDataObj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect );
static void DrawScrollbarBackground( HDC hdc, int iPartId, int iStateId, LPCRECT pRect );
void DrawTree( HDC hdc, const RECT &drawRect );
protected:
LRESULT OnDestroy( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled );
LRESULT OnKeyDown( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled );
LRESULT OnSysKeyDown( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled );
LRESULT OnChar( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled );
LRESULT OnSetFocus( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled );
LRESULT OnMouseMove( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled );
LRESULT OnMouseLeave( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled );
LRESULT OnNcMouseMove( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled );
LRESULT OnNcMouseLeave( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled );
LRESULT OnMouseActivate( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled );
LRESULT OnNcLButtonDown( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled );
LRESULT OnTimer( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled );
LRESULT OnPaint( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled );
LRESULT OnEraseBkgnd( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled ) { return 1; }
LRESULT OnContextMenu( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled );
LRESULT OnScroll( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled );
LRESULT OnSetInsertMark( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled );
LRESULT OnRefresh( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled );
LRESULT OnDeleteItem( int idCtrl, LPNMHDR pnmh, BOOL& bHandled );
LRESULT OnItemExpanding( int idCtrl, LPNMHDR pnmh, BOOL& bHandled );
LRESULT OnSingleExpand( int idCtrl, LPNMHDR pnmh, BOOL& bHandled );
LRESULT OnBeginDrag( int idCtrl, LPNMHDR pnmh, BOOL& bHandled );
LRESULT OnBeginLabelEdit( int idCtrl, LPNMHDR pnmh, BOOL& bHandled );
LRESULT OnEndLabelEdit( int idCtrl, LPNMHDR pnmh, BOOL& bHandled );
LRESULT OnGetInfoTip( int idCtrl, LPNMHDR pnmh, BOOL& bHandled );
LRESULT OnClick( int idCtrl, LPNMHDR pnmh, BOOL& bHandled );
LRESULT OnRClick( int idCtrl, LPNMHDR pnmh, BOOL& bHandled );
virtual void OnFinalMessage( HWND ) { Release(); }
private:
DWORD m_RefCount;
CMenuContainer *m_pOwner;
HIMAGELIST m_ImageList;
bool m_bHoverTimer;
bool m_bTrackMouse;
bool m_bRefreshPosted;
bool m_bAutoSort;
bool m_bDragApps;
bool m_bInsertAfter;
POINT m_LastMousePos;
int m_RootX;
int m_MinX;
int m_MaxX;
HTREEITEM m_InsertMark;
HTHEME m_TreeTheme;
HTHEME m_ScrollTheme;
enum TDropLocation
{
DROP_NOWHERE,
DROP_INSIDE,
DROP_BEFORE,
DROP_AFTER,
DROP_LAST,
};
TDropLocation m_DropLocation;
HTREEITEM m_DragItem;
HTREEITEM m_DropTarget;
HTREEITEM m_HoverItem;
CComPtr<CDropTargetProxy> m_pDropTargetProxy;
const CTreeItem *GetSelectedItem( HTREEITEM &hItem );
void AddFirstFolder( std::vector<CTreeItem*> &items, IShellItem *pParent, bool bPrograms );
void AddSecondFolder( std::vector<CTreeItem*> &items, IShellItem *pParent, bool bPrograms );
void AddMetroApps( std::vector<CTreeItem*> &items );
void GetFolderItems( std::vector<CTreeItem*> &items, HTREEITEM hParent );
void CreateFolderItems( IShellItem *pParent1, IShellItem *pParent2, HTREEITEM hParent );
void CreateFolderItems( HTREEITEM hParent );
void PostRefreshMessage( const CItemManager::ItemInfo *pSelectItem=NULL );
void RefreshTree( HTREEITEM hParent, const CItemManager::ItemInfo *pSelectItem );
void GetDragEffect( DWORD &grfKeyState, DWORD *pdwEffect );
void DrawTreeItem( HDC hdc, HDC hsrc, HTREEITEM hItem, const RECT &itemRect, bool bHot ) const;
bool GetInsertRect( RECT &rc ) const;
void ClearAllNewRec( HTREEITEM hParent );
static bool s_bFoldersFirst;
static bool CmpTreeItems( const CTreeItem *item1, const CTreeItem *item2 );
static int CALLBACK CmpTreeItemsCB( LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort );
};

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,263 @@
// Classic Shell (c) 2009-2017, Ivo Beltchev
// Classic Start (c) 2017-2018, The Passionate-Coder Team
// Confidential information of Ivo Beltchev. Not for disclosure or distribution without prior written consent from the author
#pragma once
#include "ItemManager.h"
#include <atldbcli.h>
#include <vector>
#include <list>
const int MAX_SEARCH_RESULTS=100; // per category
class CSearchManager
{
public:
CSearchManager( void );
~CSearchManager( void );
void Init( void );
void Close( void );
enum TItemCategory
{
CATEGORY_INVALID,
CATEGORY_PROGRAM,
CATEGORY_SETTING,
CATEGORY_METROSETTING,
CATEGORY_FILE,
CATEGORY_ITEM,
CATEGORY_INTERNET,
CATEGORY_AUTOCOMPLETE,
CATEGORY_MASK=15
};
struct SearchCategory
{
SearchCategory( void ) {}
SearchCategory( const SearchCategory &cat )
{
search.Clone(cat.search);
categoryHash=cat.categoryHash;
name=cat.name;
items=cat.items;
}
CAbsolutePidl search;
unsigned int categoryHash;
CString name;
struct Item
{
CString name;
CAbsolutePidl pidl;
};
std::vector<Item> items;
};
struct SearchResults
{
bool bSearching;
bool bResults;
CString currentString;
CString autoCompletePath;
std::vector<const CItemManager::ItemInfo*> programs;
std::vector<const CItemManager::ItemInfo*> settings;
std::vector<const CItemManager::ItemInfo*> autocomplete;
std::list<SearchCategory> indexed;
};
void BeginSearch( const CString &searchText );
void GetSearchResults( SearchResults &results );
void AddItemRank( unsigned int hash );
void CloseMenu( void );
void LaunchExternalSearch( PIDLIST_ABSOLUTE root, unsigned int categoryHash, const CString &searchText );
void LaunchInternetSearch( const CString &searchText );
private:
struct ItemRank
{
unsigned int hash; // hash of the item name in caps
int rank; // number of times it was used
int lastTime; // the last time it was updated (hi dword of FILETIME)
ItemRank( unsigned int _hash=0, int _rank=0, int _lastTime=0 ) { hash=_hash; rank=_rank; lastTime=_lastTime; }
bool operator<( const ItemRank &rank ) const { return hash<rank.hash; }
};
bool m_bRanksLoaded;
struct SearchItem
{
TItemCategory category;
CString name; // uppercase
CString keywords; // uppercase
const CItemManager::ItemInfo *pInfo;
int rank; // ignore the item if rank<0
bool bMetroLink;
SearchItem( void ) { category=CATEGORY_INVALID; pInfo=NULL; rank=0; bMetroLink=false; }
// 0 - no match, 1 - match name, 2 - match keywords
int MatchText( const wchar_t *search, bool bSearchSubWord ) const { return MatchTextInt(search,name,bSearchSubWord)?2:(MatchTextInt(search,keywords,bSearchSubWord)?1:0); }
bool operator<( const SearchItem &item ) const { return rank>item.rank || (rank==item.rank && wcscmp(name,item.name)<0); }
private:
static bool MatchTextInt( const wchar_t *search, const CString &text, bool bSearchSubWord );
};
bool m_bInitialized;
CString m_SearchText;
CString m_AutoCompletePath;
volatile int m_LastRequestId;
volatile int m_LastProgramsRequestId;
volatile int m_LastCompletedId;
struct SearchRequest
{
int requestId;
bool bSearchPrograms;
bool bSearchPath;
bool bSearchMetroApps;
bool bSearchMetroSettings;
bool bSearchSettings;
bool bSearchKeywords;
bool bSearchFiles;
bool bSearchMetadata;
bool bSearchTypes;
bool bSearchSubWord;
bool bUseRanks;
bool bNoCommonFolders;
bool bPinnedFolder;
DWORD searchTime;
CString searchText;
CString autoCompletePath;
};
// LOCK_DATA
SearchRequest m_SearchRequest;
std::vector<SearchItem> m_ProgramItems; // also LOCK_PROGRAMS
std::vector<SearchItem> m_SettingsItems; // also LOCK_PROGRAMS
std::vector<SearchItem> m_ProgramItemsOld;
std::vector<SearchItem> m_SettingsItemsOld;
unsigned int m_ProgramsHash;
unsigned int m_ProgramsHashOld;
unsigned int m_SettingsHash;
unsigned int m_SettingsHashOld;
bool m_bProgramsFound;
bool m_bSettingsFound;
std::vector<SearchItem> m_AutoCompleteItems;
std::list<SearchCategory> m_IndexedItems;
std::vector<ItemRank> m_ItemRanks;
CString m_LastAutoCompletePath;
enum
{
COLLECT_RECURSIVE =0x01, // go into subfolders
COLLECT_PROGRAMS =0x02, // only collect programs (.exe, .com, etc)
COLLECT_FOLDERS =0x04, // include folder items
COLLECT_METRO =0x08, // check for metro links (non-recursive)
COLLECT_ONLY_METRO =0x10, // collect only metro links
COLLECT_KEYWORDS =0x20, // include the keywords
COLLECT_LIBRARY =0x40, // the folder is a library
COLLECT_NOREFRESH =0x80, // suppress the refresh message
COLLECT_IS_FOLDER =0x8000
};
bool AddSearchItem( IShellItem *pItem, const wchar_t *name, int flags, TItemCategory category, SearchRequest &searchRequest );
void CollectSearchItems( IShellItem *pFolder, int flags, TItemCategory category, SearchRequest &searchRequest );
void CollectIndexItems( IShellItem *pFolder, int flags, TItemCategory category, const wchar_t *groupName );
enum TLock
{
LOCK_DATA,
LOCK_PROGRAMS,
LOCK_RANKS,
LOCK_COUNT,
};
CRITICAL_SECTION m_CriticalSections[LOCK_COUNT];
DWORD m_CriticalSectionOwners[LOCK_COUNT];
class Lock
{
public:
Lock( CSearchManager *pThis, TLock index )
{
m_pSection=&pThis->m_CriticalSections[index];
EnterCriticalSection(m_pSection);
m_pOwner=&pThis->m_CriticalSectionOwners[index];
if (!*m_pOwner)
*m_pOwner=GetCurrentThreadId();
else
m_pOwner=NULL;
}
~Lock( void )
{
if (m_pOwner) *m_pOwner=0;
LeaveCriticalSection(m_pSection);
}
private:
CRITICAL_SECTION *m_pSection;
DWORD *m_pOwner;
};
bool ThreadHasLock( TLock index ) { return m_CriticalSectionOwners[index]==GetCurrentThreadId(); }
HANDLE m_SearchEvent;
HANDLE m_ExitEvent;
HANDLE m_SearchThreads[8];
volatile long m_SearchThreadCount;
DWORD m_MainThreadId;
void LoadItemRanks( void );
void SearchThread( void );
static DWORD CALLBACK StaticSearchThread( void *param );
static bool CmpRankTime( const CSearchManager::ItemRank &rank1, const CSearchManager::ItemRank &rank2 );
static unsigned int CalcItemsHash( const std::vector<SearchItem> &items );
struct SearchScope
{
SearchScope( void ) { resultCount=0; categoryHash=0; bFiles=true; bCommunications=false; }
CAbsolutePidl search;
unsigned int categoryHash;
CString name;
bool bFiles;
bool bCommunications;
std::vector<CString> roots;
int resultCount;
bool ParseSearchConnector( const wchar_t *fname );
};
class CDataAccessor
{
public:
wchar_t itemUrl[_MAX_PATH];
wchar_t itemType[_MAX_PATH];
wchar_t parsingPath[_MAX_PATH];
wchar_t displayPath[_MAX_PATH];
wchar_t displayName[_MAX_PATH];
//Output Accessor
BEGIN_COLUMN_MAP(CDataAccessor)
COLUMN_ENTRY(1, itemUrl)
COLUMN_ENTRY(2, itemType)
COLUMN_ENTRY(3, parsingPath)
COLUMN_ENTRY(4, displayPath)
COLUMN_ENTRY(5, displayName)
END_COLUMN_MAP()
};
};
extern CSearchManager g_SearchManager;
bool HasSearchService( void );

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,95 @@
// Classic Shell (c) 2009-2017, Ivo Beltchev
// Classic Start (c) 2017-2018, The Passionate-Coder Team
// Confidential information of Ivo Beltchev. Not for disclosure or distribution without prior written consent from the author
#pragma once
#include "ClassicStartMenuDLL.h"
enum TMenuStyle
{
MENU_CLASSIC1,
MENU_CLASSIC2,
MENU_WIN7,
};
enum TProgramsStyle
{
PROGRAMS_CASCADING,
PROGRAMS_INLINE,
PROGRAMS_HIDDEN,
};
enum TRecentPrograms
{
RECENT_PROGRAMS_NONE,
RECENT_PROGRAMS_RECENT,
RECENT_PROGRAMS_FREQUENT,
};
enum TPinnedPrograms
{
PINNED_PROGRAMS_FAST,
PINNED_PROGRAMS_PINNED,
};
enum TRecentKeys
{
RECENT_KEYS_NONE,
RECENT_KEYS_NORMAL,
RECENT_KEYS_DIGITS,
RECENT_KEYS_HIDDEN_DIGITS,
};
enum TShutdownType
{
SHUTDOWN_TYPE_NONE,
SHUTDOWN_TYPE_SHUTDOWN,
SHUTDOWN_TYPE_RESTART,
SHUTDOWN_TYPE_LOGOFF,
SHUTDOWN_TYPE_SLEEP,
SHUTDOWN_TYPE_HIBERNATE,
SHUTDOWN_TYPE_LOCK,
SHUTDOWN_TYPE_SWITCHUSER,
SHUTDOWN_TYPE_SHUTDOWN_BOX,
SHUTDOWN_TYPE_COUNT
};
enum TSearchBoxType
{
SEARCHBOX_HIDDEN,
SEARCHBOX_NORMAL,
SEARCHBOX_TAB,
};
enum TTaskbarLook
{
TASKBAR_OPAQUE,
TASKBAR_TRANSPARENT,
TASKBAR_GLASS,
TASKBAR_AEROGLASS,
};
enum TTaskbarTile
{
TILE_TILE,
TILE_STRETCH,
};
enum
{
COMPATIBILITY_ENUM_SHELLITEM= 1, // use IEnumShellItems to enumerate items
COMPATIBILITY_ENUM_FIX_PIDLS= 2, // regenerate child pidls when enumerating folders (requres COMPATIBILITY_ENUM_SHELLITEM)
COMPATIBILITY_SKIP_DESKTOP= 4, // don't collect items from desktop
COMPATIBILITY_TRIM_HOOKS= 8, // less hooking for Win7
COMPATIBILITY_UPDATE_ITEMS= 16, // update the shell items for all search results
COMPATIBILITY_NO_TOUCH_KBD= 32, // disable the touch keyboard support
COMPATIBILITY_CRASH_TEST= 0x80000000
};
void InitSettings( void );
STARTMENUAPI void EditSettings( bool bModal, int tab );
STARTMENUAPI bool DllImportSettingsXml( const wchar_t *fname );
STARTMENUAPI bool DllExportSettingsXml( const wchar_t *fname );

View File

@@ -0,0 +1,23 @@
; Empty skin - all properties are defaults, except:
About=#7100
AboutIcon=103
Main_padding=2,2,2,2
Main_no_icons2=1
Main_new_selection=#FFBB00
Main_new_text_color=#000000
Main_new_arrow_color=#000000
Submenu_padding=2,2,2,2
Submenu_separator_text_padding=3,4,4,4,100%
Submenu_separator_icon_padding=6,3,3,3,100%
Submenu_separator_split_text_padding=3,4,4,4,100%
Submenu_separator_split_icon_padding=6,3,3,3,100%
Submenu_new_selection=#FFBB00
Submenu_new_text_color=#000000
Submenu_new_arrow_color=#000000
Main2_padding=4,2,2,2
Main2_text_padding=3,4,4,4,100%
Main2_new_selection=#FFBB00
Main2_new_text_color=#000000
Main2_new_arrow_color=#000000
More_bitmap=none

View File

@@ -0,0 +1,32 @@
; Empty skin - all properties are defaults, except:
About=#7100
AboutIcon=103
Main_padding=2,2,4,2
Main_new_selection=#FFBB00
Main_new_text_color=#000000
Main_new_arrow_color=#000000
Submenu_new_selection=#FFBB00
Submenu_new_text_color=#000000
Submenu_new_arrow_color=#000000
Programs_new_selection=#FFBB00
Programs_new_text_color=#000000
Main2_new_selection=#FFBB00
Main2_new_text_color=#000000
Main2_new_arrow_color=#000000
Main2_padding=2,2,2,2
Main_search_padding=2,2,2,2
Main_jump_padding=2,2,2,2
Main_text_padding=1,3,8,4
Main_no_icons2=1
Shutdown_padding=5,5,5,5
Shutdown_text_padding=5,4,8,5
Shutdown_icon_padding=4,3,-2,3
Submenu_padding=2,2,2,2
Submenu_separator_text_padding=3,4,4,4
List_separator_text_padding=3,0,0,0
List_separator_icon_padding=4,3,4,3
List_separator_split_text_padding=3,0,0,0
List_separator_split_icon_padding=4,3,4,3
Main_search_indent=8
More_bitmap=none

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,487 @@
// Classic Shell (c) 2009-2017, Ivo Beltchev
// Classic Start (c) 2017-2018, The Passionate-Coder Team
// Confidential information of Ivo Beltchev. Not for disclosure or distribution without prior written consent from the author
#pragma once
#include <vector>
#include <map>
const int MAX_SKIN_VERSION=3;
class CSkinParser;
enum TSkinOptionType;
struct MenuBitmap
{
bool bIsBitmap;
bool bIsOwned; // only valid if bIsBitmap and bitmap
bool bIs32; // only valid if bIsBitmap and bitmap
MenuBitmap( void ) { bIsBitmap=bIsOwned=bIs32=false; bitmap=NULL; }
void Init( bool bIsColor=false );
void Reset( bool bIsColor=false );
HBITMAP GetBitmap( void ) const { return bIsBitmap?bitmap:NULL; }
COLORREF GetColor( void ) const { return bIsBitmap?0:color; }
void operator=( HBITMAP bmp ) { bIsBitmap=true; bitmap=bmp; }
void operator=( COLORREF col ) { bIsBitmap=false; color=col; }
private:
union
{
COLORREF color;
HBITMAP bitmap;
};
};
struct MenuSkin
{
enum TSkinType
{
// the first 3 values match the MenuStyle setting
SKIN_TYPE_CLASSIC1,
SKIN_TYPE_CLASSIC2,
SKIN_TYPE_WIN7,
SKIN_TYPE_ALL_PROGRAMS,
SKIN_TYPE_COUNT
};
unsigned int Hash;
unsigned int MetroColorHash;
int Dpi;
CString About; // the text to show in the About box
HICON AboutIcon; // the icon to show in the About box
int Version; // 1 - skin 1.0 (default), 2 - skin 2.0 (future skins)
TSkinType SkinType;
bool ForceRTL;
bool TwoColumns;
bool Main_FakeGlass;
bool Submenu_FakeGlass;
bool ForceTouch;
struct Variation
{
CString label;
CString labelEn;
CString tip;
};
std::vector<std::pair<int,Variation>> Variations;
struct Option
{
// from skin
CString name;
TSkinOptionType type;
CString label;
CString tip;
CString condition;
int groupId;
bool bDefValue; // default value when not set by user
CString disValue; // the value when the setting is disabled
// current state
mutable bool bEnabled;
mutable bool bValue;
mutable CString sValue;
};
std::vector<Option> Options;
enum TOpacity
{
OPACITY_SOLID,
OPACITY_REGION,
OPACITY_ALPHA,
OPACITY_GLASS,
OPACITY_FULLALPHA,
OPACITY_FULLGLASS,
};
enum TShadow
{
SHADOW_ON,
SHADOW_OFF,
SHADOW_GLASS, // enabled when glass is available
};
enum
{
USER_CENTER=10000,
USER_CENTER1=10001,
USER_CENTER2=10002,
};
enum THAlign
{
HALIGN_CENTER,
HALIGN_CENTER1,
HALIGN_CENTER2,
HALIGN_LEFT,
HALIGN_LEFT1,
HALIGN_LEFT2,
HALIGN_RIGHT,
HALIGN_RIGHT1,
HALIGN_RIGHT2,
HALIGN_CORNER,
HALIGN_NONE,
};
enum TVAlign
{
VALIGN_CENTER,
VALIGN_TOP,
VALIGN_BOTTOM,
VALIGN_CORNER,
VALIGN_NONE,
};
enum TItemDrawType
{
COLUMN1_ITEM,
COLUMN1_SPLIT,
COLUMN1_NEW,
COLUMN1_SEPARATOR,
COLUMN2_ITEM,
COLUMN2_SPLIT,
COLUMN2_NEW,
COLUMN2_SEPARATOR,
COLUMN2_INLINE,
SUBMENU_ITEM,
SUBMENU_SPLIT,
SUBMENU_NEW,
SUBMENU_SEPARATOR,
SUBMENU_SEPARATOR_SPLIT,
// special items
PROGRAMS_TREE_ITEM,
PROGRAMS_TREE_NEW,
PROGRAMS_BUTTON,
PROGRAMS_BUTTON_NEW,
PROGRAMS_CASCADING,
PROGRAMS_CASCADING_NEW,
SHUTDOWN_BUTTON,
SHUTDOWN_BUTTON_SEARCH,
SHUTDOWN_BUTTON_JUMP,
LIST_ITEM,
LIST_SPLIT,
LIST_SEPARATOR,
LIST_SEPARATOR_SPLIT,
ITEM_TYPE_COUNT
};
enum TIconSize
{
ICON_SIZE_UNDEFINED=-1,
ICON_SIZE_NONE,
ICON_SIZE_SMALL,
ICON_SIZE_LARGE,
ICON_SIZE_PROGRAMS,
};
struct ItemDrawSettings
{
// text
HFONT font;
bool bOwnFont;
int glowSize;
COLORREF textColors[4]; // normal, selected, disabled, disabled+selected
COLORREF textShadowColors[4];
RECT textPadding;
// selection
MenuBitmap bmpSelection;
int selSlicesX[6]; // 3 for normal, 6 for split selection
int selSlicesY[3];
// arrow
MenuBitmap bmpArrow;
SIZE arrSize;
COLORREF arrColors[2]; // normal, selected
SIZE arrPadding;
// icon frame
MenuBitmap bmpIconFrame;
int frameSlicesX[3];
int frameSlicesY[3];
POINT iconFrameOffset;
RECT iconPadding;
// only used by separator items
MenuBitmap bmpSeparator;
int sepSlicesX[3];
int sepHeight;
// calculated
TOpacity opacity;
mutable int itemHeight;
mutable int textTopOffset;
mutable int iconTopOffset;
TIconSize iconSize;
TEXTMETRIC textMetrics;
void Init( void );
void Reset( void );
};
ItemDrawSettings ItemSettings[ITEM_TYPE_COUNT];
// CAPTION SECTION - describes the caption portion of the main menu
HFONT Caption_font;
COLORREF Caption_text_color;
COLORREF Caption_glow_color;
int Caption_glow_size;
RECT Caption_padding0;
// MENU SECTION - describes the menu portion of the main menu
MenuBitmap Main_bitmap;
int Main_bitmap_slices_X[9];
int Main_bitmap_slices_Y[6];
TOpacity Main_opacity;
TOpacity Main2_opacity;
TOpacity Search_opacity;
TOpacity Jumplist_opacity;
TShadow Main_shadow;
MenuBitmap Main_bitmap_search;
int Main_bitmap_search_slices_X[9];
int Main_bitmap_search_slices_Y[6];
MenuBitmap Main_bitmap_jump;
int Main_bitmap_jump_slices_X[9];
int Main_bitmap_jump_slices_Y[6];
RECT Shutdown_padding;
bool bHasNewItem;
bool Main_thin_frame;
TIconSize Main_icon_size;
TIconSize Main2_icon_size;
COLORREF Main_background;
COLORREF Main_background2;
RECT Main_padding0;
RECT Main2_padding0;
RECT Main_search_padding0;
RECT Main_jump_padding0;
int Main_search_indent;
MenuBitmap Main_separatorV;
int Main_separatorWidth;
int Main_separator_slices_Y[3];
RECT Search_padding;
bool Search_frame;
MenuBitmap Search_background;
int Search_background_slices_X[9];
int Search_background_slices_Y[9];
RECT Search_background_padding;
MenuBitmap Search_background_search;
int Search_background_search_slices_X[9];
int Search_background_search_slices_Y[9];
RECT Search_background_search_padding;
MenuBitmap Search_background_jump;
int Search_background_jump_slices_X[9];
int Search_background_jump_slices_Y[9];
RECT Search_background_jump_padding;
MenuBitmap Main_emblems[10];
SIZE Main_emblem_sizes[10];
RECT Main_emblem_paddings[10];
THAlign Main_emblem_alignH1[10];
THAlign Main_emblem_alignH2[10];
TVAlign Main_emblem_alignV[10];
MenuBitmap Main_emblem_mask;
MenuBitmap Main_emblem_search_mask;
MenuBitmap Main_emblem_jump_mask;
MenuBitmap Search_emblem_mask;
MenuBitmap Search_emblem_search_mask;
MenuBitmap Search_emblem_jump_mask;
MenuBitmap Patterns[4];
SIZE Pattern_sizes[4];
std::vector<unsigned int> PatternBits[4];
int PatternPretileWidth;
MenuBitmap Main_pattern_mask;
MenuBitmap Main_pattern_search_mask;
MenuBitmap Main_pattern_jump_mask;
MenuBitmap Search_pattern_mask;
MenuBitmap Search_pattern_search_mask;
MenuBitmap Search_pattern_jump_mask;
// SUB-MENU SECTION - describes the menu portion of the sub-menu
MenuBitmap Submenu_bitmap;
int Submenu_bitmap_slices_X[6];
int Submenu_bitmap_slices_Y[3];
TOpacity Submenu_opacity;
TShadow Submenu_shadow;
COLORREF Submenu_background;
RECT Submenu_padding0;
int Submenu_offset;
int AllPrograms_offset;
bool Submenu_thin_frame;
MenuBitmap Submenu_separatorV;
int Submenu_separatorWidth;
int Submenu_separator_slices_Y[3];
MenuBitmap Submenu_pager;
int Submenu_pager_slices_X[3];
int Submenu_pager_slices_Y[3];
MenuBitmap Submenu_pager_arrows;
SIZE Submenu_pager_arrow_Size;
MenuBitmap Pin_bitmap;
SIZE Pin_bitmap_Size;
MenuBitmap More_bitmap;
SIZE More_bitmap_Size;
MenuBitmap Shutdown_bitmap;
SIZE Shutdown_bitmap_Size;
// SEARCH SECTION
MenuBitmap Search_bitmap;
MenuBitmap Search_arrow;
SIZE Search_arrow_size;
HFONT Search_hint_font;
HFONT Search_underline_font;
bool BOwnHintFont;
COLORREF Search_text_colors[2];
COLORREF Search_text_background;
MenuBitmap Main_pager;
int Main_pager_slices_X[3];
int Main_pager_slices_Y[3];
MenuBitmap Main_pager_arrows;
SIZE Main_pager_arrow_Size;
MenuBitmap User_bitmap;
SIZE User_bitmapSize;
MenuBitmap User_mask;
SIZE User_maskSize;
bool User_bitmap_outside;
POINT User_frame_position;
POINT User_image_offset;
int User_image_size;
int User_image_alpha;
POINT User_image_padding; // top, bottom
RECT User_name_position;
THAlign User_name_align;
HFONT User_font;
COLORREF User_text_color;
COLORREF User_glow_color;
int User_glow_size;
// PROGRAMS SECTION
COLORREF Programs_background;
int Programs_indent;
MenuBitmap Programs_icon;
SIZE Programs_icon_size;
MenuBitmap Programs_icon_selected;
// SCROLLBAR SECTION
MenuBitmap Scrollbar_button;
int Scrollbar_button_slices_X[3];
int Scrollbar_button_slices_Y[3];
MenuBitmap Scrollbar_arrows;
SIZE Scrollbar_arrows_size;
MenuBitmap Scrollbar_background;
int Scrollbar_background_slices_X[3];
int Scrollbar_background_slices_Y[3];
MenuBitmap Scrollbar_thumb;
int Scrollbar_thumb_slices_X[3];
int Scrollbar_thumb_slices_Y[3];
MenuBitmap Scrollbar_gripper;
SIZE Scrollbar_gripper_size;
bool BHasScrollbar;
mutable bool BHasMetroColors;
// calculated
mutable RECT Caption_padding;
mutable RECT Main_padding;
mutable RECT Main2_padding;
mutable RECT Main_search_padding;
mutable RECT Main_jump_padding;
mutable RECT Submenu_padding;
MenuSkin( void );
~MenuSkin( void );
void Reset( void );
static wchar_t s_SkinError[1024]; // parsing error. must end on \r\n
bool LoadMenuSkin( const wchar_t *fname, const wchar_t *variation, const wchar_t *optionsStr, TSkinType skinType, unsigned int flags, int dpi );
void LoadDefaultMenuSkin( TSkinType skinType, unsigned int flags, int dpi );
const POINT *GetArrowsBitmapSizes( void ) const; // insert left, middle size, insert right, right arrow, left arrow, down arrow, total size
void PretilePatterns( int width );
void ParseOptionsString( const wchar_t *optionsStr, std::map<CString,CString> &options ) const;
bool ComputeOptionStates( const std::map<CString,CString> &options, std::vector<const wchar_t*> &values, bool bTranslateValues ) const;
void SerializeOptionStates( std::vector<wchar_t> &buffer ) const;
private:
enum TSkinNumberType
{
NUMBERS_COLORS, // 0xBBGGRR
NUMBERS_COLORS_ABGR, // 0xAABBGGRR
NUMBERS_COLORS_RGB, // 0xRRGGBB
NUMBERS_PADDING, // scaled by %
NUMBERS_SIZE, // scaled by %
NUMBERS_SLICES, // no modification
NUMBERS_OTHER, // no modification
};
struct MetroColor
{
int colorType;
COLORREF color;
};
struct CustomBitmap
{
HBITMAP bitmap;
CString path;
FILETIME timestamp;
};
mutable std::map<unsigned int,MetroColor> MetroColors;
mutable std::vector<CustomBitmap> CustomBitmaps;
COLORREF GetMetroColor( const wchar_t *name ) const;
unsigned int CalcMetroColorHash( int set=-1 ) const;
int LoadSkinNumbers( const wchar_t *str, int *numbers, int count, TSkinNumberType type ) const;
HFONT LoadSkinFont( const wchar_t *str, const wchar_t *name, int weight, float size, bool bScale ) const;
void LoadSkinTintColors( CSkinParser &parser, const wchar_t *name, COLORREF &tintColor1, COLORREF &tintColor2, COLORREF &tintColor3, COLORREF backgroundColor ) const;
bool LoadSkinColors( CSkinParser &parser, const wchar_t *name, COLORREF *colors, int count, COLORREF backgroundColor, TSkinNumberType type=NUMBERS_COLORS ) const;
bool LoadSkinBackground( HMODULE hMod, CSkinParser &parser, const wchar_t *name, MenuBitmap &bitmap, COLORREF bkColor, int *slicesX, int countX, int *slicesY, int countY, bool bMirror, bool bAllowColor=false, bool bPremultiply=true ) const;
MenuBitmap LoadSkinBitmap( HMODULE hMod, int index, int maskIndex, COLORREF tintColor1, COLORREF tintColor2, COLORREF tintColor3, bool bPremultiply=true ) const;
bool LoadSkinBitmap( HMODULE hMod, CSkinParser &parser, const wchar_t *name, MenuBitmap &bitmap, SIZE *size, bool bMirror, bool bPremultiply=true ) const;
bool LoadSkinItem( HMODULE hMod, CSkinParser &parser, const wchar_t *name, MenuSkin::ItemDrawSettings &settings, MenuSkin::ItemDrawSettings *pDefaults, COLORREF background, bool bRTL ) const;
bool LoadSkin( HMODULE hMod, const wchar_t *variation, const wchar_t *optionsStr, TSkinType skinType, unsigned int flags, int dpi );
int ScaleSkinElement( int num, int scale=100 ) const;
RECT ScaleSkinElement( const RECT &rect ) const;
POINT ScaleSkinElement( const POINT &point ) const;
SIZE ScaleSkinElement( const SIZE &size ) const;
static THAlign ParseHAlign( const wchar_t *str );
static TVAlign ParseVAlign( const wchar_t *str );
static TIconSize ParseIconSize( const wchar_t *str );
};
enum
{
LOADMENU_RESOURCES=1,
};
// Returns the path to the skin files. path must be _MAX_PATH characters
void GetSkinsPath( wchar_t *path );
// Returns the system glass color
void GetSystemGlassColor( int &dr, int &dg, int &db, int &da, int &dc );
void GetMetroGlassColor( int &dr, int &dg, int &db );
COLORREF GetMetroTaskbarColor( bool &bTransparent );
COLORREF GetSystemGlassColor8( void );
COLORREF GetSystemAccentColor( void );
extern DWORD g_CustomScrollbarThread;
extern HTHEME g_CustomScrollbarTheme;
void InitializeSkinManager( bool bInitIat );
void CloseSkinManager( bool bCloseIat );

View File

@@ -0,0 +1,53 @@
// Classic Shell (c) 2009-2017, Ivo Beltchev
// Classic Start (c) 2017-2018, The Passionate-Coder Team
// Confidential information of Ivo Beltchev. Not for disclosure or distribution without prior written consent from the author
#include "stdafx.h"
#include "TouchHelper.h"
typedef BOOL (WINAPI *tGetPointerType)( UINT32 pointerId, POINTER_INPUT_TYPE *pointerType );
typedef BOOL (WINAPI *tGetPointerCursorId)( UINT32 pointerId, UINT32 *cursorId );
typedef BOOL (WINAPI *tGetPointerInfo)( UINT32 pointerId, POINTER_INFO *pointerInfo );
typedef BOOL (WINAPI *tGetCurrentInputMessageSource)( INPUT_MESSAGE_SOURCE *inputMessageSource );
typedef BOOL (WINAPI *tGetCIMSSM)( INPUT_MESSAGE_SOURCE *inputMessageSource );
static tGetPointerType fGetPointerType;
static tGetPointerCursorId fGetPointerCursorId;
static tGetPointerInfo fGetPointerInfo;
static tGetCurrentInputMessageSource fGetCurrentInputMessageSource;
static tGetCIMSSM fGetCIMSSM;
void InitTouchHelper( void )
{
HMODULE user32=GetModuleHandle(L"user32.dll");
fGetPointerType=(tGetPointerType)GetProcAddress(user32,"GetPointerType");
fGetPointerCursorId=(tGetPointerCursorId)GetProcAddress(user32,"GetPointerCursorId");
fGetPointerInfo=(tGetPointerInfo)GetProcAddress(user32,"GetPointerInfo");
fGetCurrentInputMessageSource=(tGetCurrentInputMessageSource)GetProcAddress(user32,"GetCurrentInputMessageSource");
fGetCIMSSM=(tGetCIMSSM)GetProcAddress(user32,"GetCIMSSM");
}
BOOL GetPointerType2( UINT32 pointerId, POINTER_INPUT_TYPE *pointerType )
{
return fGetPointerType && fGetPointerType(pointerId,pointerType);
}
BOOL GetPointerCursorId2( UINT32 pointerId, UINT32 *cursorId )
{
return fGetPointerCursorId && fGetPointerCursorId(pointerId,cursorId);
}
BOOL GetPointerInfo2( UINT32 pointerId, POINTER_INFO *pointerInfo )
{
return fGetPointerInfo && fGetPointerInfo(pointerId,pointerInfo);
}
BOOL GetCurrentInputMessageSource2( INPUT_MESSAGE_SOURCE *inputMessageSource )
{
return fGetCurrentInputMessageSource && fGetCurrentInputMessageSource(inputMessageSource);
}
BOOL GetCIMSSM2( INPUT_MESSAGE_SOURCE *inputMessageSource )
{
return fGetCIMSSM && fGetCIMSSM(inputMessageSource);
}

View File

@@ -0,0 +1,131 @@
// Classic Shell (c) 2009-2017, Ivo Beltchev
// Classic Start (c) 2017-2018, The Passionate-Coder Team
// Confidential information of Ivo Beltchev. Not for disclosure or distribution without prior written consent from the author
#pragma once
// define some Windows 8 touch features here so we don't need the Win8 SDK
#ifndef WM_NCPOINTERUPDATE
#define WM_NCPOINTERUPDATE 0x0241
#define WM_NCPOINTERDOWN 0x0242
#define WM_NCPOINTERUP 0x0243
#define WM_POINTERUPDATE 0x0245
#define WM_POINTERDOWN 0x0246
#define WM_POINTERUP 0x0247
#define WM_POINTERENTER 0x0249
#define WM_POINTERLEAVE 0x024A
#define WM_POINTERACTIVATE 0x024B
#define WM_POINTERCAPTURECHANGED 0x024C
#define WM_TOUCHHITTESTING 0x024D
#define WM_POINTERWHEEL 0x024E
#define WM_POINTERHWHEEL 0x024F
/*
* Flags that appear in pointer input message parameters
*/
#define POINTER_MESSAGE_FLAG_NEW 0x00000001 // New pointer
#define POINTER_MESSAGE_FLAG_INRANGE 0x00000002 // Pointer has not departed
#define POINTER_MESSAGE_FLAG_INCONTACT 0x00000004 // Pointer is in contact
#define POINTER_MESSAGE_FLAG_FIRSTBUTTON 0x00000010 // Primary action
#define POINTER_MESSAGE_FLAG_SECONDBUTTON 0x00000020 // Secondary action
#define POINTER_MESSAGE_FLAG_THIRDBUTTON 0x00000040 // Third button
#define POINTER_MESSAGE_FLAG_FOURTHBUTTON 0x00000080 // Fourth button
#define POINTER_MESSAGE_FLAG_FIFTHBUTTON 0x00000100 // Fifth button
#define POINTER_MESSAGE_FLAG_PRIMARY 0x00002000 // Pointer is primary
#define POINTER_MESSAGE_FLAG_CONFIDENCE 0x00004000 // Pointer is considered unlikely to be accidental
#define POINTER_MESSAGE_FLAG_CANCELED 0x00008000 // Pointer is departing in an abnormal manner
/*
* Macros to retrieve information from pointer input message parameters
*/
#define GET_POINTERID_WPARAM(wParam) (LOWORD(wParam))
#define IS_POINTER_FLAG_SET_WPARAM(wParam, flag) (((DWORD)HIWORD(wParam) & (flag)) == (flag))
#define IS_POINTER_NEW_WPARAM(wParam) IS_POINTER_FLAG_SET_WPARAM(wParam, POINTER_MESSAGE_FLAG_NEW)
#define IS_POINTER_INRANGE_WPARAM(wParam) IS_POINTER_FLAG_SET_WPARAM(wParam, POINTER_MESSAGE_FLAG_INRANGE)
#define IS_POINTER_INCONTACT_WPARAM(wParam) IS_POINTER_FLAG_SET_WPARAM(wParam, POINTER_MESSAGE_FLAG_INCONTACT)
#define IS_POINTER_FIRSTBUTTON_WPARAM(wParam) IS_POINTER_FLAG_SET_WPARAM(wParam, POINTER_MESSAGE_FLAG_FIRSTBUTTON)
#define IS_POINTER_SECONDBUTTON_WPARAM(wParam) IS_POINTER_FLAG_SET_WPARAM(wParam, POINTER_MESSAGE_FLAG_SECONDBUTTON)
#define IS_POINTER_THIRDBUTTON_WPARAM(wParam) IS_POINTER_FLAG_SET_WPARAM(wParam, POINTER_MESSAGE_FLAG_THIRDBUTTON)
#define IS_POINTER_FOURTHBUTTON_WPARAM(wParam) IS_POINTER_FLAG_SET_WPARAM(wParam, POINTER_MESSAGE_FLAG_FOURTHBUTTON)
#define IS_POINTER_FIFTHBUTTON_WPARAM(wParam) IS_POINTER_FLAG_SET_WPARAM(wParam, POINTER_MESSAGE_FLAG_FIFTHBUTTON)
#define IS_POINTER_PRIMARY_WPARAM(wParam) IS_POINTER_FLAG_SET_WPARAM(wParam, POINTER_MESSAGE_FLAG_PRIMARY)
#define HAS_POINTER_CONFIDENCE_WPARAM(wParam) IS_POINTER_FLAG_SET_WPARAM(wParam, POINTER_MESSAGE_FLAG_CONFIDENCE)
#define IS_POINTER_CANCELED_WPARAM(wParam) IS_POINTER_FLAG_SET_WPARAM(wParam, POINTER_MESSAGE_FLAG_CANCELED)
enum tagPOINTER_INPUT_TYPE {
PT_POINTER = 0x00000001, // Generic pointer
PT_TOUCH = 0x00000002, // Touch
PT_PEN = 0x00000003, // Pen
PT_MOUSE = 0x00000004, // Mouse
};
typedef enum tagPOINTER_BUTTON_CHANGE_TYPE {
POINTER_CHANGE_NONE,
POINTER_CHANGE_FIRSTBUTTON_DOWN,
POINTER_CHANGE_FIRSTBUTTON_UP,
POINTER_CHANGE_SECONDBUTTON_DOWN,
POINTER_CHANGE_SECONDBUTTON_UP,
POINTER_CHANGE_THIRDBUTTON_DOWN,
POINTER_CHANGE_THIRDBUTTON_UP,
POINTER_CHANGE_FOURTHBUTTON_DOWN,
POINTER_CHANGE_FOURTHBUTTON_UP,
POINTER_CHANGE_FIFTHBUTTON_DOWN,
POINTER_CHANGE_FIFTHBUTTON_UP,
} POINTER_BUTTON_CHANGE_TYPE;
typedef DWORD POINTER_INPUT_TYPE;
typedef UINT32 POINTER_FLAGS;
typedef struct tagPOINTER_INFO {
POINTER_INPUT_TYPE pointerType;
UINT32 pointerId;
UINT32 frameId;
POINTER_FLAGS pointerFlags;
HANDLE sourceDevice;
HWND hwndTarget;
POINT ptPixelLocation;
POINT ptHimetricLocation;
POINT ptPixelLocationRaw;
POINT ptHimetricLocationRaw;
DWORD dwTime;
UINT32 historyCount;
INT32 InputData;
DWORD dwKeyStates;
UINT64 PerformanceCount;
POINTER_BUTTON_CHANGE_TYPE ButtonChangeType;
} POINTER_INFO;
typedef enum tagINPUT_MESSAGE_DEVICE_TYPE {
IMDT_UNAVAILABLE = 0x00000000, // not specified
IMDT_KEYBOARD = 0x00000001, // from keyboard
IMDT_MOUSE = 0x00000002, // from mouse
IMDT_TOUCH = 0x00000004, // from touch
IMDT_PEN = 0x00000008, // from pen
} INPUT_MESSAGE_DEVICE_TYPE;
typedef enum tagINPUT_MESSAGE_ORIGIN_ID {
IMO_UNAVAILABLE = 0x00000000, // not specified
IMO_HARDWARE = 0x00000001, // from a hardware device or injected by a UIAccess app
IMO_INJECTED = 0x00000002, // injected via SendInput() by a non-UIAccess app
IMO_SYSTEM = 0x00000004, // injected by the system
} INPUT_MESSAGE_ORIGIN_ID;
/*
* Input source structure.
*/
typedef struct tagINPUT_MESSAGE_SOURCE {
INPUT_MESSAGE_DEVICE_TYPE deviceType;
INPUT_MESSAGE_ORIGIN_ID originId;
} INPUT_MESSAGE_SOURCE;
#endif
void InitTouchHelper( void );
BOOL GetPointerType2( UINT32 pointerId, POINTER_INPUT_TYPE *pointerType );
BOOL GetPointerCursorId2( UINT32 pointerId, UINT32 *cursorId );
BOOL GetPointerInfo2( UINT32 pointerId, POINTER_INFO *pointerInfo );
BOOL GetCurrentInputMessageSource2( INPUT_MESSAGE_SOURCE *inputMessageSource );
BOOL GetCIMSSM2( INPUT_MESSAGE_SOURCE *inputMessageSource );

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 107 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 170 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

View File

@@ -0,0 +1,100 @@
// Classic Shell (c) 2009-2017, Ivo Beltchev
// Classic Start (c) 2017-2018, The Passionate-Coder Team
// Confidential information of Ivo Beltchev. Not for disclosure or distribution without prior written consent from the author
// dllmain.cpp : Defines the entry point for the DLL application.
#include "stdafx.h"
#include "ClassicStartMenuDLL.h"
#include "Settings.h"
#include "Translations.h"
#include "ResourceHelper.h"
#include "StringSet.h"
#include "resource.h"
#include "..\ClassicStartLib\resource.h"
#include "SettingsUI.h"
#include "SkinManager.h"
#include "uxtheme.h"
#include "FNVHash.h"
#include "MenuContainer.h"
#include "SearchManager.h"
#include "LogManager.h"
#include <dwmapi.h>
#pragma comment(linker, \
"\"/manifestdependency:type='Win32' "\
"name='Microsoft.Windows.Common-Controls' "\
"version='6.0.0.0' "\
"processorArchitecture='*' "\
"publicKeyToken='6595b64144ccf1df' "\
"language='*'\"")
static int g_LoadDialogs[]=
{
IDD_SETTINGS,0x04000000,
IDD_SETTINGSTREE,0x04000000,
IDD_BROWSEFORICON,0x04000000,
IDD_LANGUAGE,0x04000000,
IDD_SKINSETTINGS,0x04000000,
IDD_CUSTOMTREE,0x04000000,
IDD_CUSTOMMENU,0x04000000,
IDD_CUSTOMMENU7,0x04000000,
IDD_STYLESETTINGS,0x04000000,
IDD_CUSTOMLIST,0x04000000,
IDD_PROGRESS,0x04000004,
0
};
const wchar_t *GetDocRelativePath( void )
{
return DOC_PATH;
}
static HANDLE g_DllInitThread;
static DWORD CALLBACK DllInitThread( void* )
{
CoInitialize(NULL);
InitSettings();
wchar_t path[_MAX_PATH];
GetModuleFileName(g_Instance,path,_countof(path));
*PathFindFileName(path)=0;
wchar_t fname[_MAX_PATH];
Sprintf(fname,_countof(fname),L"%s" INI_PATH L"StartMenuL10N.ini",path);
CString language=GetSettingString(L"Language");
ParseTranslations(fname,language);
HINSTANCE resInstance=LoadTranslationDll(language);
LoadTranslationResources(resInstance,g_LoadDialogs);
if (resInstance)
FreeLibrary(resInstance);
CoUninitialize();
return 0;
}
STARTMENUAPI void WaitDllInitThread( void )
{
ATLASSERT(g_DllInitThread);
WaitForSingleObject(g_DllInitThread,INFINITE);
}
extern "C" BOOL WINAPI DllMain( HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved )
{
if (dwReason==DLL_PROCESS_ATTACH)
{
LogToFile(STARTUP_LOG,L"StartMenu DLL: DLL_PROCESS_ATTACH");
g_Instance=hInstance;
g_DllInitThread=CreateThread(NULL,0,DllInitThread,NULL,0,NULL);
}
if (dwReason==DLL_PROCESS_DETACH)
{
LogToFile(STARTUP_LOG,L"StartMenu DLL: DLL_PROCESS_DETACH");
}
return TRUE;
}

View File

@@ -0,0 +1,8 @@
// Classic Shell (c) 2009-2017, Ivo Beltchev
// Classic Start (c) 2017-2018, The Passionate-Coder Team
// Confidential information of Ivo Beltchev. Not for disclosure or distribution without prior written consent from the author
// dllmain.h : Declaration of module
#pragma once
// Some utility functions used by various modules

Binary file not shown.

After

Width:  |  Height:  |  Size: 756 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@@ -0,0 +1,816 @@
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by ClassicStartMenuDLL.rc
//
#define IDI_APPICON 1
#define IDI_APPSICON 2
#define IDD_RENAME 102
#define IDC_EDITNAME 102
#define IDD_RENAMER 103
#define IDD_LOGOFF 104
#define IDD_LOGOFFR 105
#define IDB_SEARCH_ICONS 110
#define IDB_BUTTON96 111
#define IDB_BUTTON120 112
#define IDB_BUTTON144 113
#define IDB_BUTTON180 114
#define IDB_STYLE_CLASSIC1 120
#define IDB_STYLE_CLASSIC2 121
#define IDB_STYLE_WIN7 122
#define IDB_BTN_CLASSIC 124
#define IDI_BTN_CLASSIC 125
#define IDI_START 126
#define IDI_START10 127
#define IDB_STYLE_CLASSIC1150 130
#define IDB_STYLE_CLASSIC2150 131
#define IDB_STYLE_WIN7150 132
#define IDC_STATICICON 209
#define IDC_COMBOCOMMAND 239
#define IDC_EDITLABEL 240
#define IDC_EDITTIP 241
#define IDC_BUTTONLINK 242
#define IDC_BUTTONCOMMAND 243
#define IDC_EDITICON 245
#define IDC_BUTTONICON 246
#define IDC_STATICCOMMAND 251
#define IDC_STATICLINK 252
#define IDC_STATICTEXT 253
#define IDC_STATICINFOTIP 254
#define IDC_ICONN 256
#define IDC_COMBOLINK 258
#define IDC_STATICHINT 259
#define IDC_BUTTONRESET 261
#define IDC_PROMPT 1015
#define IDC_COMBOSKIN 1019
#define IDB_ARROWS 1020
#define IDC_ABOUT 1020
#define IDB_ARROWS150 1021
#define IDC_STATICOPT 1023
#define IDC_STATICVER 1025
#define IDC_LABEL 1047
#define IDC_RADIO2 1049
#define IDC_TREE2 1052
#define IDC_SKINOPTIONS 1052
#define IDC_STATICICON1 1053
#define IDC_CHECKSORTZA 1054
#define IDC_CHECKSORTZAREC 1055
#define IDC_CHECKSORTONCE 1056
#define IDC_CHECKOPENUP 1057
#define IDC_CHECKOPENUPCHILDREN 1058
#define IDC_CHECKOPENUPREC 1058
#define IDC_CHECKNOEXPAND 1059
#define IDC_CHECKMULTICOLUMN 1060
#define IDC_BUTTON1 1060
#define IDC_BUTTONPICK 1060
#define IDC_CHECKTRACK 1061
#define IDC_STATICSKIN 1061
#define IDC_CHECKNOTRACK 1062
#define IDC_STATICALLPROGS 1062
#define IDC_CHECKITEMSFIRST 1063
#define IDC_CHECKINLINE 1064
#define IDC_CHECK2 1065
#define IDC_CHECKNOEXT 1065
#define IDC_CHECKNOEXPAND2 1066
#define IDC_CHECKSPLIT 1066
#define IDC_STATICTITLE 1066
#define IDC_STATIC_CLASSIC 1067
#define IDC_STATIC_XP 1068
#define IDC_STATIC_VISTA 1069
#define IDC_STATIC_WIN7 1069
#define IDC_LINK_CLASSIC 1070
#define IDC_STATIC_WIN8 1070
#define IDC_LINK_XP 1071
#define IDC_RADIO_CLASSIC 1071
#define IDC_RADIO_TWO_COLUMNS 1072
#define IDC_RADIO_WIN7 1073
#define IDC_LISTITEMS 1073
#define IDC_EDITLINK2 1075
#define IDC_STATIC_TWO_COLUMNS 1076
#define IDC_CHECKENABLED 1077
#define IDC_LINKADVANCED 1078
#define IDC_RADIOCLASSIC 1079
#define IDC_RADIOAERO 1080
#define IDC_RADIOCUSTOM 1081
#define IDC_STATICAERO 1082
#define IDC_STATICCUSTOM 1083
#define IDC_STATICEDGE 1084
#define IDC_STATICCLASSIC 1085
#define IDC_SKIN_CLASSIC 1086
#define IDC_SKIN_CLASSIC2 1087
#define IDC_SKIN_WIN7 1088
#define IDC_STATICEDGE2 1089
#define IDD_CUSTOMMENU 3001
#define IDS_APP_TITLE 3001
#define IDD_SKINSETTINGS 3002
#define IDS_SETTINGS_TITLE 3002
#define IDS_SETTINGS_TITLE_VER 3003
#define IDD_STYLESETTINGS 3003
#define IDS_NEW_SETTINGS 3004
#define IDD_CUSTOMMENU7 3004
#define IDD_CUSTOMLIST 3005
#define IDS_NO_TEXT 3005
#define IDS_CTRL_CLASSIC 3006
#define IDS_CTRL_WINDOWS 3007
#define IDS_SETTINGS 3008
#define IDS_SETTINGS_TIP 3009
#define IDS_SKIN_ERR_UNKNOWN 3010
#define IDS_SKIN_ERR_DISABLE 3011
#define IDS_SKIN_ERR 3012
#define IDS_SKIN_WARN 3013
#define IDS_SKIN_ABOUT 3014
#define IDS_SKIN_FAIL 3015
#define IDS_SKIN_ERR_BMPRES 3016
#define IDS_SKIN_ERR_BMPFILE 3017
#define IDS_SKIN_ERR_MASKRES 3018
#define IDS_SKIN_ERR_MASKFILE 3019
#define IDS_SKIN_ERR_MASKSIZE 3020
#define IDS_SKIN_ERR_FIND_RES1 3021
#define IDS_SKIN_ERR_LOAD_RES1 3022
#define IDS_SKIN_ERR_LOAD_FILE1 3023
#define IDS_SKIN_ERR_FIND_RES 3024
#define IDS_SKIN_ERR_LOAD_RES 3025
#define IDS_SKIN_ERR_LOAD_FILE 3026
#define IDS_SKIN_ERR_LOAD 3027
#define IDS_SKIN_ERR_VERSION 3028
#define IDS_MENU_TITLE 3029
#define IDS_DEFAULT_SKIN 3030
#define IDS_CONTROLS_SETTINGS 3031
#define IDS_OPEN_NOTHING 3032
#define IDS_OPEN_NOTHING_TIP 3033
#define IDS_OPEN_CSM 3034
#define IDS_OPEN_CSM_TIP 3035
#define IDS_OPEN_WSM 3036
#define IDS_OPEN_WSM_TIP 3037
#define IDS_LCLICK 3038
#define IDS_LCLICK_TIP 3039
#define IDS_SHIFT_LCLICK 3040
#define IDS_SHIFT_LCLICK_TIP 3041
#define IDS_WIN_KEY 3042
#define IDS_WIN_KEY_TIP 3043
#define IDS_SHIFT_WIN 3044
#define IDS_SHIFT_WIN_TIP 3045
#define IDS_MCLICK 3046
#define IDS_MCLICK_TIP 3047
#define IDS_HOVER 3048
#define IDS_HOVER_TIP 3049
#define IDS_HOVER_DELAY 3050
#define IDS_HOVER_DELAY_TIP 3051
#define IDS_CSM_HOTKEY 3052
#define IDS_CSM_HOTKEY_TIP 3053
#define IDS_WSM_HOTKEY 3054
#define IDS_WSM_HOTKEY_TIP 3055
#define IDS_SHOW_ITEMS 3056
#define IDS_ITEM_HIDE 3057
#define IDS_ITEM_HIDE_TIP 3058
#define IDS_ITEM_SHOW 3059
#define IDS_ITEM_SHOW_TIP 3060
#define IDS_ITEM_MENU 3061
#define IDS_ITEM_MENU_TIP 3062
#define IDS_SHOW_FAVORITES 3063
#define IDS_SHOW_FAVORITES_TIP 3064
#define IDS_SHOW_DOCUMENTS 3065
#define IDS_SHOW_DOCUMENTS_TIP 3066
#define IDS_MAX_DOCS 3067
#define IDS_MAX_DOCS_TIP 3068
#define IDS_SHOW_USERFILES 3069
#define IDS_SHOW_USERFILES_TIP 3070
#define IDS_SHOW_USERDOCS 3071
#define IDS_SHOW_USERDOCS_TIP 3072
#define IDS_SHOW_USERPICS 3073
#define IDS_SHOW_USERPICS_TIP 3074
#define IDS_SHOW_CP 3075
#define IDS_SHOW_CP_TIP 3076
#define IDS_SHOW_NETWORK 3077
#define IDS_SHOW_NETWORK_TIP 3078
#define IDS_SHOW_PRINTERS 3079
#define IDS_SHOW_PRINTERS_TIP 3080
#define IDS_SHOW_SEARCH 3081
#define IDS_SHOW_SEARCH_TIP 3082
#define IDS_SHOW_HELP 3083
#define IDS_SHOW_HELP_TIP 3084
#define IDS_SHOW_RUN 3085
#define IDS_SHOW_RUN_TIP 3086
#define IDS_SHOW_LOGOFF 3087
#define IDS_SHOW_LOGOFF_TIP 3088
#define IDS_CONFIRM_LOGOFF 3089
#define IDS_CONFIRM_LOGOFF_TIP 3090
#define IDS_SHOW_UNDOCK 3091
#define IDS_SHOW_UNDOCK_TIP 3092
#define IDS_SHOW_SHUTDOWN 3093
#define IDS_SHOW_SHUTDOWN_TIP 3094
#define IDS_SHOW_RSHUTDOWN 3095
#define IDS_SHOW_RSHUTDOWN_TIP 3096
#define IDS_SHOW_RECENT_OLD 3097
#define IDS_SHOW_RECENT_TIP_OLD 3098
#define IDS_MAX_PROGS 3099
#define IDS_MAX_PROGS_TIP 3100
#define IDS_RECENT_TOP 3101
#define IDS_RECENT_TOP_TIP 3102
#define IDS_RECENT_KEYS 3103
#define IDS_RECENT_KEYS_TIP 3104
#define IDS_KEY_NOTHING 3105
#define IDS_KEY_NOTHING_TIP 3106
#define IDS_KEY_NORMAL 3107
#define IDS_KEY_NORMAL_TIP 3108
#define IDS_KEY_DIGITS 3109
#define IDS_KEY_DIGITS_TIP 3110
#define IDS_KEY_HIDDEN 3111
#define IDS_KEY_HIDDEN_TIP 3112
#define IDS_BEHAVIOR_SETTINGS 3113
#define IDS_EXPAND_LINKS 3114
#define IDS_EXPAND_LINKS_TIP 3115
#define IDS_MENU_DELAY 3116
#define IDS_MENU_DELAY_TIP 3117
#define IDS_TIP_DELAY 3118
#define IDS_TIP_DELAY_TIP 3119
#define IDS_FTIP_DELAY 3120
#define IDS_FTIP_DELAY_TIP 3121
#define IDS_ANIM_NONE 3122
#define IDS_ANIM_NONE_TIP 3123
#define IDS_ANIM_FADE 3124
#define IDS_ANIM_FADE_TIP 3125
#define IDS_ANIM_SLIDE 3126
#define IDS_ANIM_SLIDE_TIP 3127
#define IDS_ANIMATION 3128
#define IDS_ANIMATION_TIP 3129
#define IDS_ANIM_SPEED 3130
#define IDS_ANIM_SPEED_TIP 3131
#define IDS_SUB_ANIMATION 3132
#define IDS_SUB_ANIMATION_TIP 3133
#define IDS_SUB_ANIM_SPEED 3134
#define IDS_SUB_ANIM_SPEED_TIP 3135
#define IDS_SCROLL_SPEED 3136
#define IDS_SCROLL_SPEED_TIP 3137
#define IDS_SUB_SCROLL_SPEED 3138
#define IDS_SUB_SCROLL_SPEED_TIP 3139
#define IDS_FADE_SPEED 3140
#define IDS_FADE_SPEED_TIP 3141
#define IDS_DRAG_DELAY 3142
#define IDS_DRAG_DELAY_TIP 3143
#define IDS_ACCESSIBILITY 3144
#define IDS_ACCESSIBILITY_TIP 3145
#define IDS_NEXTTASKBAR 3146
#define IDS_NEXTTASKBAR_TIP 3147
#define IDS_SEARCH_COMMAND 3148
#define IDS_SEARCH_COMMAND_TIP 3149
#define IDS_CASCADE_MENU 3150
#define IDS_CASCADE_MENU_TIP 3151
#define IDS_CACHE_ICONS 3152
#define IDS_CACHE_ICONS_TIP 3153
#define IDS_SKIN_ERRORS 3154
#define IDS_SKIN_ERRORS_TIP 3155
#define IDS_LOOK_SETTINGS 3156
#define IDS_MENU_WIDTH 3157
#define IDS_MENU_WIDTH_TIP 3158
#define IDS_SUBMENU_WIDTH 3159
#define IDS_SUBMENU_WIDTH_TIP 3160
#define IDS_SAME_COLUMNS 3161
#define IDS_SAME_COLUMNS_TIP 3162
#define IDS_MENU_CAPTION 3163
#define IDS_MENU_CAPTION_TIP 3164
#define IDS_MENU_USERNAME 3165
#define IDS_MENU_USERNAME_TIP 3166
#define IDS_PIC_COMMAND 3167
#define IDS_PIC_COMMAND_TIP 3168
#define IDS_NAME_COMMAND 3169
#define IDS_NAME_COMMAND_TIP 3170
#define IDS_SMALL_SIZE_SM 3171
#define IDS_SMALL_SIZE_SM_TIP 3172
#define IDS_LARGE_SIZE_SM 3173
#define IDS_LARGE_SIZE_SM_TIP 3174
#define IDS_NUMERIC_SORT 3175
#define IDS_NUMERIC_SORT_TIP 3176
#define IDS_FONT_SMOOTHING 3177
#define IDS_FONT_SMOOTHING_TIP 3178
#define IDS_SMOOTH_DEFAULT 3179
#define IDS_SMOOTH_DEFAULT_TIP 3180
#define IDS_SMOOTH_NONE 3181
#define IDS_SMOOTH_NONE_TIP 3182
#define IDS_SMOOTH_STD 3183
#define IDS_SMOOTH_STD_TIP 3184
#define IDS_SMOOTH_CLEAR 3185
#define IDS_SMOOTH_CLEAR_TIP 3186
#define IDS_CONTEXT_MENU_SETTINGS 3187
#define IDS_DRAG_DROP 3188
#define IDS_DRAG_DROP_TIP 3189
#define IDS_CONTEXT_MENU 3190
#define IDS_CONTEXT_MENU_TIP 3191
#define IDS_NEW_FOLDER 3192
#define IDS_NEW_FOLDER_TIP 3193
#define IDS_EXIT 3194
#define IDS_EXIT_TIP 3195
#define IDS_SOUND_SETTINGS 3196
#define IDS_SOUND_MAIN 3197
#define IDS_SOUND_MAIN_TIP 3198
#define IDS_SOUND_POPUP 3199
#define IDS_SOUND_POPUP_TIP 3200
#define IDS_SOUND_COMMAND 3201
#define IDS_SOUND_COMMAND_TIP 3202
#define IDS_SOUND_DROP 3203
#define IDS_SOUND_DROP_TIP 3204
#define IDS_WSM_SETTINGS 3205
#define IDS_CASCADE_ALL 3206
#define IDS_CASCADE_ALL_TIP 3207
#define IDS_ALL_DELAY 3208
#define IDS_ALL_DELAY_TIP 3209
#define IDS_ALL_SELECT 3210
#define IDS_ALL_SELECT_TIP 3211
#define IDS_SELECT_SEARCH 3212
#define IDS_SELECT_SEARCH_TIP 3213
#define IDS_SELECT_BUTTON 3214
#define IDS_SELECT_BUTTON_TIP 3215
#define IDS_SKIN_SETTINGS 3216
#define IDS_ALL_SKIN_SETTINGS 3217
#define IDS_CUSTOM_SETTINGS 3218
#define IDS_LANGUAGE_SETTINGS_SM 3219
#define IDS_SCROLL_TYPE 3220
#define IDS_SCROLL_TYPE_TIP 3221
#define IDS_SCROLL_NO 3222
#define IDS_SCROLL_NO_TIP 3223
#define IDS_SCROLL_YES 3224
#define IDS_SCROLL_YES_TIP 3225
#define IDS_SCROLL_AUTO 3226
#define IDS_SCROLL_AUTO_TIP 3227
#define IDS_ANIM_RANDOM 3228
#define IDS_ANIM_RANDOM_TIP 3229
#define IDC_SKINVARIATION 3230
#define IDS_COMMAND_TIP 3231
#define IDS_LINK_TIP 3232
#define IDS_TEXT_TIP 3233
#define IDS_TIP_TIP 3234
#define IDS_ICON_TIP 3235
#define IDS_SORTZA_TIP 3236
#define IDS_SORTZAREC_TIP 3237
#define IDS_SORTONCE_TIP 3238
#define IDS_OPENUP_TIP 3239
#define IDS_OPENUPREC_TIP 3240
#define IDS_NOEXPAND_TIP 3241
#define IDS_MULTICOLUMN_TIP 3242
#define IDS_TRACK_TIP 3243
#define IDS_NOTRACK_TIP 3244
#define IDS_ITEMSFIRST_TIP 3245
#define IDS_MAIN_SORTZA 3246
#define IDS_MAIN_SORTONCE 3247
#define IDS_SEPARATOR_TIP 3248
#define IDS_BREAK_TIP 3249
#define IDS_PADDING_TIP 3250
#define IDS_PROGRAMS_TIP 3251
#define IDS_FAVORITES_TIP 3252
#define IDS_DOCUMENTS_TIP 3253
#define IDS_USERFILES_TIP 3254
#define IDS_USERDOCS_TIP 3255
#define IDS_USERPICS_TIP 3256
#define IDS_CONTROLPANEL_TIP 3257
#define IDS_CONTROLPANEL2_TIP 3258
#define IDS_SECURITY_TIP 3259
#define IDS_NETWORK_TIP 3260
#define IDS_PRINTERS_TIP 3261
#define IDS_RUN_TIP 3262
#define IDS_HELP_TIP 3263
#define IDS_LOGOFF_TIP 3264
#define IDS_UNDOCK_TIP 3265
#define IDS_DISCONNECT_TIP 3266
#define IDS_SHUTDOWNBOX_TIP 3267
#define IDS_SEARCHFI_TIP 3268
#define IDS_SEARCHPR_TIP 3269
#define IDS_SEARCHCO_TIP 3270
#define IDS_SEARCHPE_TIP 3271
#define IDS_TASKBAR_TIP 3272
#define IDS_MENU_TIP 3273
#define IDS_RECENT_TIP 3274
#define IDS_SLEEP_TIP 3275
#define IDS_HIBERNATE_TIP 3276
#define IDS_RESTART_TIP 3277
#define IDS_SHUTDOWN_TIP 3278
#define IDS_SWITCH_TIP 3279
#define IDS_CUSTOM_TIP 3280
#define IDS_SEARCH_TIP 3281
#define IDS_SETTINGS_MENU_TIP 3282
#define IDS_FEATURES_TIP 3283
#define IDS_RESTORE_TIP 3284
#define IDS_SEARCH_BOX_TIP 3285
#define IDS_SEARCH_BOX 3286
#define IDS_SHOW_SEARCH_BOX 3287
#define IDS_SHOW_SEARCH_BOX_TIP 3288
#define IDS_SEARCH_BOX_HIDE 3289
#define IDS_SEARCH_BOX_HIDE_TIP 3290
#define IDS_SEARCH_BOX_SHOW 3291
#define IDS_SEARCH_BOX_SHOW_TIP 3292
#define IDS_SEARCH_BOX_TAB 3293
#define IDS_SEARCH_BOX_TAB_TIP 3294
#define IDS_SEARCH_BOX_SEL 3295
#define IDS_SEARCH_BOX_SEL_TIP 3296
#define IDS_SEARCH_PATH 3299
#define IDS_SEARCH_PATH_TIP 3300
#define IDS_SUB_WORD 3301
#define IDS_SUB_WORD_TIP 3302
#define IDS_SEARCH_TRACK 3303
#define IDS_SEARCH_TRACK_TIP 3304
#define IDS_SEARCH_MAX 3305
#define IDS_SEARCH_MAX_TIP 3306
#define IDS_SEARCH_AUTO 3307
#define IDS_SEARCH_AUTO_TIP 3308
#define IDS_INLINE_TIP 3309
#define IDS_NOEXTENSIONS_TIP 3310
#define IDS_DELAY_ICONS 3311
#define IDS_DELAY_ICONS_TIP 3312
#define IDS_SHOW_FAVORITES_TIP2 3313
#define IDS_SHOW_DOCUMENTS_TIP2 3314
#define IDS_SHOW_USERFILES_TIP2 3315
#define IDS_SHOW_USERDOCS_TIP2 3316
#define IDS_SHOW_USERPICS_TIP2 3317
#define IDS_SHOW_CP_TIP2 3318
#define IDS_SHOW_NETWORK_TIP2 3319
#define IDS_SHOW_PRINTERS_TIP2 3320
#define IDS_SHOW_SHUTDOWN_TIP2 3321
#define IDS_SHOW_SEARCH_BOX_TIP2 3322
#define IDS_SHOW_SEARCH_TIP2 3323
#define IDS_SHOW_HELP_TIP2 3324
#define IDS_SHOW_RUN_TIP2 3325
#define IDS_SHOW_LOGOFF_TIP2 3326
#define IDS_SHOW_UNDOCK_TIP2 3327
#define IDS_LOCK_TIP 3328
#define IDS_SUB_ANIM_ALWAYS 3329
#define IDS_SUB_ANIM_ALWAYS_TIP 3330
#define IDS_EXPLORER 3331
#define IDS_EXPLORER_TIP 3332
#define IDS_EXPLORER_PATH 3333
#define IDS_EXPLORER_PATH_TIP 3334
#define IDS_HIDE_PIC 3335
#define IDS_HIDE_PIC_TIP 3336
#define IDS_SORT_DOCS 3337
#define IDS_SORT_DOCS_TIP 3338
#define IDS_SORT_NAME 3339
#define IDS_SORT_NAME_TIP 3340
#define IDS_SORT_EXT 3341
#define IDS_SORT_EXT_TIP 3342
#define IDS_MENU_SHADOW 3343
#define IDS_MENU_SHADOW_TIP 3344
#define IDS_START_BUTTON 3345
#define IDS_ENABLE_BUTTON 3346
#define IDS_ENABLE_BUTTON_TIP 3347
#define IDS_BUTTON_TYPE 3348
#define IDS_BUTTON_TYPE_TIP 3349
#define IDS_CLASSIC_BUTTON 3350
#define IDS_CLASSIC_BUTTON_TIP 3351
#define IDS_AERO_BUTTON 3352
#define IDS_AERO_BUTTON_TIP 3353
#define IDS_CUSTOM_BUTTON 3356
#define IDS_CUSTOM_BUTTON_TIP 3357
#define IDS_BUTTON_IMAGE 3358
#define IDS_BUTTON_IMAGE_TIP 3359
#define IDS_BUTTON_SIZE 3360
#define IDS_BUTTON_SIZE_TIP 3361
#define IDS_HOT_CORNERS 3362
#define IDS_HOT_CORNERS_TIP 3363
#define IDS_SKIP_METRO 3364
#define IDS_SKIP_METRO_TIP 3365
#define IDS_BUTTON_ICON 3366
#define IDS_BUTTON_ICON_TIP 3367
#define IDS_BUTTON_TIP 3368
#define IDS_BUTTON_TIP_TIP 3369
#define IDS_BUTTON_TEXT 3370
#define IDS_BUTTON_TEXT_TIP 3371
#define IDS_METRO_SETTINGS 3372
#define IDS_DISABLE_NONE 3373
#define IDS_DISABLE_NONE_TIP 3374
#define IDS_DISABLE_START 3375
#define IDS_DISABLE_START_TIP 3376
#define IDS_DISABLE_ALL 3377
#define IDS_DISABLE_ALL_TIP 3378
#define IDS_ENABLE_BUTTON2 3379
#define IDS_ENABLE_BUTTON_TIP2 3380
#define IDS_SPLIT_TIP 3381
#define IDS_STYLE_SETTINGS 3382
#define IDS_OPEN_WSS 3384
#define IDS_OPEN_WSS_TIP 3385
#define IDS_WSS_HOTKEY 3386
#define IDS_WSS_HOTKEY_TIP 3387
#define IDS_JUMPLISTS 3388
#define IDS_JUMPLISTS_TIP 3389
#define IDS_MAX_JUMPLISTS 3390
#define IDS_MAX_JUMPLISTS_TIP 3391
#define IDS_JUMPLIST_KEYS 3392
#define IDS_JUMPLISTS_KEY_TIP 3393
#define IDS_KEY_SELECT 3394
#define IDS_KEY_SELECT_TIP 3395
#define IDS_KEY_RUN 3396
#define IDS_KEY_RUN_TIP 3397
#define IDS_KEY_OPEN 3398
#define IDS_KEY_OPEN_TIP 3399
#define IDS_APPS_TIP 3400
#define IDS_SPLIT_DELAY 3401
#define IDS_SPLIT_DELAY_TIP 3402
#define IDS_OPEN_BOTH 3403
#define IDS_OPEN_BOTH_TIP 3404
#define IDS_SHOW_COMPUTER 3405
#define IDS_COMPUTER_TIP 3406
#define IDS_SHOW_COMPUTER_TIP 3407
#define IDS_SHOW_COMPUTER_TIP2 3408
#define IDS_OPEN_DESKTOP 3409
#define IDS_OPEN_DESKTOP_TIP 3410
#define IDS_SORT_DATE 3411
#define IDS_SORT_DATE_TIP 3412
#define IDS_ENABLE_TASKBARS 3413
#define IDS_ENABLE_TASKBARS_TIP 3414
#define IDS_TASKBAR_TRANS 3415
#define IDS_TASKBAR_TRANS_TIP 3416
#define IDS_SEARCH_PROGRAMS 3417
#define IDS_SEARCH_PROGRAMS_TIP 3418
#define IDS_SEARCH_METRO 3419
#define IDS_SEARCH_METRO_TIP 3420
#define IDS_SEARCH_KEYWORDS 3423
#define IDS_SEARCH_KEYWORDS_TIP 3424
#define IDS_SEARCH_FILES 3425
#define IDS_SEARCH_FILES_TIP 3426
#define IDS_SEARCH_FILES_TIP2 3427
#define IDS_SEARCH_CONTENTS 3428
#define IDS_SEARCH_CONTENTS_TIP 3429
#define IDS_SEARCH_CATEGORIES 3430
#define IDS_SEARCH_CATEGORIES_TIP 3431
#define IDS_SEARCH_EVERYWHERE 3432
#define IDS_SEARCH_EVERYWHERE_TIP 3433
#define IDS_SEARCH_INTERNET 3434
#define IDS_SEARCH_INTERNET_TIP 3435
#define IDS_NO_RECENT 3436
#define IDS_NO_RECENT_TIP 3437
#define IDS_RECENT_PROGRAMS 3438
#define IDS_RECENT_PROGRAMS_TIP 3439
#define IDS_SHOW_RECENT 3440
#define IDS_SHOW_RECENT_TIP 3441
#define IDS_SHOW_FREQUENT 3442
#define IDS_SHOW_FREQUENT_TIP 3443
#define IDS_RECENT_METRO 3444
#define IDS_RECENT_METRO_TIP 3445
#define IDS_HIGHLIGHT_NEW 3446
#define IDS_HIGHLIGHT_NEW_TIP 3447
#define IDS_CP_CATEGORIES 3448
#define IDS_CP_CATEGORIES2 3449
#define IDS_CP_CATEGORIES_TIP 3450
#define IDS_CLASSIC_STYLE_TIP 3451
#define IDS_TWO_COLUMN_STYLE_TIP 3452
#define IDS_WIN7_STYLE_TIP 3453
#define IDS_SHUTDOWN_COMMAND 3454
#define IDS_SHUTDOWN_COMMAND_TIP 3455
#define IDS_SHUTDOWN_NONE 3456
#define IDS_SHUTDOWN_NONE_TIP 3457
#define IDS_SHUTDOWN_SHUTDOWN 3458
#define IDS_SHUTDOWN_SHUTDOWN_TIP 3459
#define IDS_SHUTDOWN_RESTART 3460
#define IDS_SHUTDOWN_RESTART_TIP 3461
#define IDS_SHUTDOWN_LOGOFF 3462
#define IDS_SHUTDOWN_LOGOFF_TIP 3463
#define IDS_SHUTDOWN_SLEEP 3464
#define IDS_SHUTDOWN_SLEEP_TIP 3465
#define IDS_SHUTDOWN_HIBERNATE 3466
#define IDS_SHUTDOWN_HIBERNATE_TIP 3467
#define IDS_SHUTDOWN_LOCK 3468
#define IDS_SHUTDOWN_LOCK_TIP 3469
#define IDS_SHUTDOWN_SWITCH 3470
#define IDS_SHUTDOWN_SWITCH_TIP 3471
#define IDS_SHUTDOWN_SHUTDOWN_BOX 3472
#define IDS_SHUTDOWN_SHUTDOWN_BOX_TIP 3473
#define IDS_UNDOCK_ITEM 3474
#define IDS_DISCONNECT_ITEM 3475
#define IDS_ITEM_SHOW2 3476
#define IDS_SEPARATOR_ITEM 3477
#define IDS_COLUMN_BREAK_ITEM 3478
#define IDS_COLUMN_PADDING_ITEM 3479
#define IDS_CUSTOM_ITEM 3480
#define IDS_HELP_ITEM 3481
#define IDS_RUN_ITEM 3482
#define IDS_SECURITY_ITEM 3483
#define IDS_LIB_DOCS_ITEM 3484
#define IDS_LIB_PICS_ITEM 3485
#define IDS_LIB_VIDEOS_ITEM 3486
#define IDS_LIB_MUSIC_ITEM 3487
#define IDS_LIB_TV_ITEM 3488
#define IDS_PROGRAMS_ITEM 3489
#define IDS_APPS_ITEM 3490
#define IDS_SETTINGS_ITEM 3491
#define IDS_SEARCH_MENU_ITEM 3492
#define IDS_SEARCH_BOX_ITEM 3493
#define IDS_TASKBAR_ITEM 3494
#define IDS_FEATURES_ITEM 3495
#define IDS_MENU_SETTINGS_ITEM 3496
#define IDS_SEARCH_FILES_ITEM 3497
#define IDS_SEARCH_PRINTER_ITEM 3498
#define IDS_SEARCH_COMP_ITEM 3499
#define IDS_SEARCH_PEOPLE_ITEM 3500
#define IDS_MONITOR_OFF_ITEM 3501
#define IDS_MENU_MOVE_UP 3502
#define IDS_MENU_MOVE_DOWN 3503
#define IDS_MENU_INSERT 3504
#define IDS_MENU_DUPLICATE 3505
#define IDS_METRO_APPS 3506
#define IDS_PROGRAMS_DELAY 3507
#define IDS_PROGRAMS_DELAY_TIP 3508
#define IDS_SEARCH_MAX2 3509
#define IDS_SEARCH_MAX_TIP2 3510
#define IDS_SEARCH_MAX3 3511
#define IDS_SEARCH_MAX_TIP3 3512
#define IDS_SHOW_APPS 3513
#define IDS_SHOW_APPS_TIP 3514
#define IDS_FOLDERS_FIRST 3515
#define IDS_FOLDERS_FIRST_TIP 3516
#define IDS_PINNED_PROGRAMS 3517
#define IDS_PINNED_PROGRAMS_TIP 3518
#define IDS_FAST_ITEMS 3519
#define IDS_FAST_ITEMS_TIP 3520
#define IDS_PINNED_ITEMS 3521
#define IDS_PINNED_ITEMS_TIP 3522
#define IDS_BUTTON_ICON_SIZE 3523
#define IDS_BUTTON_ICON_SIZE_TIP 3524
#define IDS_BUTTON_SIZE_TIP2 3525
#define IDS_MONITOR_OFF_TIP 3526
#define IDS_AUTOSTART 3527
#define IDS_AUTOSTART_TIP 3528
#define IDS_CHECK_UPDATES 3529
#define IDS_CHECK_UPDATES_TIP 3530
#define IDS_ITEM_DRIVES 3531
#define IDS_ITEM_DRIVES_TIP 3532
#define IDS_MENU_GLASS 3533
#define IDS_MENU_GLASS_TIP 3534
#define IDS_MAIN_MENU_SETTINGS 3535
#define IDS_RIGHT_SHIFT 3538
#define IDS_RIGHT_SHIFT_TIP 3539
#define IDS_RIGHT_SHIFTX 3540
#define IDS_RIGHT_SHIFTX_TIP 3541
#define IDS_STARTSCREEN_ITEM 3542
#define IDS_STARTSCREEN_ITEM_TIP 3543
#define IDS_MIN_HEIGHT 3544
#define IDS_MIN_HEIGHT_TIP 3545
#define IDS_GLASS_OVERRIDE 3546
#define IDS_GLASS_OVERRIDE_TIP 3547
#define IDS_GLASS_COLOR 3548
#define IDS_GLASS_COLOR_TIP 3549
#define IDS_GLASS_INTENSITY 3550
#define IDS_GLASS_INTENSITY_TIP 3551
#define IDS_GLASS_BLENDING 3552
#define IDS_GLASS_BLENDING_TIP 3553
#define IDS_INLINE_PROGS 3554
#define IDS_INLINE_PROGS_TIP 3555
#define IDS_MAIN_INLINE 3556
#define IDS_MAIN_INLINE_TIP 3557
#define IDS_MAIN_CASCADE 3558
#define IDS_MAIN_CASCADE_TIP 3559
#define IDS_ANIMATION7 3560
#define IDS_ANIMATION7_TIP 3561
#define IDS_METRO_SETTINGS81 3562
#define IDS_MENU_BUSY 3563
#define IDS_OPEN_PROGRAMS 3564
#define IDS_OPEN_PROGRAMS_TIP 3565
#define IDS_MOUSE_MONITOR 3566
#define IDS_MOUSE_MONITOR_TIP 3567
#define IDS_COLUMN_ICON 3568
#define IDS_COLUMN_COMMAND 3569
#define IDS_COLUMN_DISPLAY 3570
#define IDS_HIDE_APPS 3571
#define IDS_HIDE_APPS_TIP 3572
#define IDS_HYBRID_SHUTDOWN 3573
#define IDS_HYBRID_SHUTDOWN_TIP 3574
#define IDS_UPGRADE_WIN 3575
#define IDS_UPGRADE_ERROR 3576
#define IDS_UPGRADE_SUCCESS 3577
#define IDS_INVERT_ICONS 3578
#define IDS_INVERT_ICONS_TIP 3579
#define IDS_SHUTDOWN7 3580
#define IDS_SHUTDOWN7_TIP 3581
#define IDS_PROG_WIDTH 3582
#define IDS_PROG_WIDTH_TIP 3583
#define IDS_JUMP_WIDTH 3584
#define IDS_JUMP_WIDTH_TIP 3585
#define IDS_NOPIN 3586
#define IDS_NOPIN_TIP 3587
#define IDS_RECENT_NAME 3588
#define IDS_RECENT_NAME_TIP 3589
#define IDS_DPI_OVERRIDE 3590
#define IDS_DPI_OVERRIDE_TIP 3591
#define IDS_ENABLE_TOUCH 3592
#define IDS_ENABLE_TOUCH_TIP 3593
#define IDS_METRO_SETTINGS10 3594
#define IDS_MOUSE_MONITOR2 3595
#define IDS_MOUSE_MONITOR_TIP2 3596
#define IDS_PIC_PATH 3597
#define IDS_PIC_PATH_TIP 3598
#define IDS_SEARCH_METROS 3599
#define IDS_SEARCH_METROS_TIP 3600
#define IDS_SHOW_APPS_MENU 3601
#define IDS_SHOW_APPS_MENU_TIP 3602
#define IDS_SHOW_APPS_MENU_TIP2 3603
#define IDS_SKIN_ERR_METRO_COLOR 3604
#define IDS_BUTTON_ALIGN 3605
#define IDS_BUTTON_ALIGN_TIP 3606
#define IDS_MENU_GLASS2 3607
#define IDS_MENU_GLASS2_TIP 3608
#define IDS_GLASS_OPACITY 3609
#define IDS_GLASS_OPACITY_TIP 3610
#define IDS_TASK_CUSTOM 3611
#define IDS_TASK_CUSTOM_TIP 3612
#define IDS_TASK_LOOK 3613
#define IDS_TASK_LOOK_TIP 3614
#define IDS_TASK_OPAQUE 3615
#define IDS_TASK_OPAQUE_TIP 3616
#define IDS_TASK_TRANS 3617
#define IDS_TASK_TRANS_TIP 3618
#define IDS_TASK_GLASS 3619
#define IDS_TASK_GLASS_TIP 3620
#define IDS_TASK_AEROGLASS 3621
#define IDS_TASK_AEROGLASS_TIP 3622
#define IDS_TASK_OPACITY 3623
#define IDS_TASK_OPACITY_TIP 3624
#define IDS_TASK_COLOR 3625
#define IDS_TASK_COLOR_TIP 3626
#define IDS_PCSETTINGS 3627
#define IDS_PCSETTINGS_TIP 3628
#define IDS_HIGHLIGHT_NEWAPPS 3629
#define IDS_HIGHLIGHT_NEWAPPS_TIP 3630
#define IDS_OPEN_CORTANA 3631
#define IDS_OPEN_CORTANA_TIP 3632
#define IDS_SKIN_ERR_RECBITMAP 3633
#define IDS_MAIN_HIDDEN 3634
#define IDS_MAIN_HIDDEN_TIP 3635
#define IDS_SOUND_HOVER 3636
#define IDS_SOUND_HOVER_TIP 3637
#define IDS_SHUTDOWN_SHUTDOWN_NU 3638
#define IDS_SHUTDOWN_NU_TIP 3639
#define IDS_SHUTDOWN_RESTART_NU 3640
#define IDS_RESTART_NU_TIP 3641
#define IDS_TASK_TEXTURE 3642
#define IDS_TASK_TEXTURE_TIP 3643
#define IDS_TASK_STRETCHH 3644
#define IDS_TASK_STRETCHH_TIP 3645
#define IDS_TASK_STRETCHV 3646
#define IDS_TASK_STRETCHV_TIP 3647
#define IDS_TASK_STRETCH 3648
#define IDS_TASK_STRETCH_TIP 3649
#define IDS_TASK_TILE 3650
#define IDS_TASK_TILE_TIP 3651
#define IDS_TASK_BORDERS 3652
#define IDS_TASK_BORDERS_TIP 3653
#define IDS_TASKBAR_SETTINGS 3654
#define IDS_TASK_TEXTCOLOR 3655
#define IDS_TASK_TEXTCOLOR_TIP 3656
#define IDS_SELECT_LAST 3657
#define IDS_SELECT_LAST_TIP 3658
#define IDS_CLEAR_CACHE 3659
#define IDS_STRING7001 7001
#define IDS_STRING7002 7002
#define IDS_STRING7003 7003
#define IDS_STRING7004 7004
#define IDS_STRING7005 7005
#define IDS_STRING7006 7006
#define IDS_STRING7007 7007
#define IDS_STRING7008 7008
#define IDS_STRING7009 7009
#define IDS_STRING7010 7010
#define IDS_STRING7011 7011
#define IDS_STRING7012 7012
#define IDS_STRING7013 7013
#define IDS_STRING7014 7014
#define IDS_STRING7015 7015
#define IDS_STRING7016 7016
#define IDS_STRING7017 7017
#define IDS_STRING7018 7018
#define IDS_STRING7019 7019
#define IDS_STRING7020 7020
#define IDS_STRING7021 7021
#define IDS_STRING7022 7022
#define IDS_STRING7023 7023
#define IDS_STRING7024 7024
#define IDS_STRING7025 7025
#define IDS_STRING7026 7026
#define IDS_STRING7027 7027
#define IDS_STRING7028 7028
#define IDS_STRING7029 7029
#define IDS_STRING7030 7030
#define IDS_STRING7031 7031
#define IDS_STRING7032 7032
#define IDS_STRING7033 7033
#define IDS_STRING7034 7034
#define IDS_STRING7035 7035
#define IDS_STRING7036 7036
#define IDS_STRING7037 7037
#define IDS_STRING7038 7038
#define IDS_STRING7100 7100
#define IDS_STRING7101 7101
#define IDS_STRING7102 7102
#define IDS_STRING7103 7103
#define IDS_STRING7104 7104
#define IDS_STRING7105 7105
#define IDS_STRING7106 7106
#define IDS_STRING7107 7107
#define IDS_STRING7108 7108
#define IDS_STRING7109 7109
#define IDS_STRING7110 7110
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 126
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1090
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

View File

@@ -0,0 +1,5 @@
// stdafx.cpp : source file that includes just the standard includes
// ClassicStartMenuDLL.pch will be the pre-compiled header
// stdafx.obj will contain the pre-compiled type information
#include "stdafx.h"

View File

@@ -0,0 +1,34 @@
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//
#pragma once
#include "targetver.h"
#define STRICT_TYPED_ITEMIDS
// Windows Header Files:
#include <windows.h>
#include <commctrl.h>
#include <shlobj.h>
#include <shellapi.h>
#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // some CString constructors will be explicit
#include <atlbase.h>
#include <atltypes.h>
#include <atlstr.h>
#include <atlwin.h>
#ifdef BUILD_SETUP
#define INI_PATH L""
#define DOC_PATH L""
#else
#define INI_PATH L"..\\"
#define DOC_PATH L"..\\..\\Docs\\Help\\"
#endif
#include "StringUtils.h"
#include "TrackResources.h"
#include "Assert.h"

Binary file not shown.

After

Width:  |  Height:  |  Size: 125 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 270 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 182 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 120 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 259 KiB

View File

@@ -0,0 +1,24 @@
#pragma once
// The following macros define the minimum required platform. The minimum required platform
// is the earliest version of Windows, Internet Explorer etc. that has the necessary features to run
// your application. The macros work by enabling all features available on platform versions up to and
// including the version specified.
// Modify the following defines if you have to target a platform prior to the ones specified below.
// Refer to MSDN for the latest info on corresponding values for different platforms.
#ifndef WINVER // Specifies that the minimum required platform is Windows 7.
#define WINVER 0x0602 // Change this to the appropriate value to target other versions of Windows.
#endif
#ifndef _WIN32_WINNT // Specifies that the minimum required platform is Windows 7.
#define _WIN32_WINNT 0x0602 // Change this to the appropriate value to target other versions of Windows.
#endif
#ifndef _WIN32_WINDOWS // Specifies that the minimum required platform is Windows 98.
#define _WIN32_WINDOWS 0x0410 // Change this to the appropriate value to target Windows Me or later.
#endif
#ifndef _WIN32_IE // Specifies that the minimum required platform is Internet Explorer 7.0.
#define _WIN32_IE 0x0700 // Change this to the appropriate value to target other versions of IE.
#endif