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.
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
};
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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;
|
||||
@@ -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 );
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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 );
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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;
|
||||
};
|
||||
3814
ClassicStartSrc/ClassicStartMenu/ClassicStartMenuDLL/ItemManager.cpp
Normal 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 ×tamp, 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 ®Key, 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
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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 );
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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"
|
||||
1133
ClassicStartSrc/ClassicStartMenu/ClassicStartMenuDLL/MenuContainer.h
Normal file
3163
ClassicStartSrc/ClassicStartMenu/ClassicStartMenuDLL/MenuPaint.cpp
Normal 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;
|
||||
}
|
||||
@@ -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 );
|
||||
@@ -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 );
|
||||
};
|
||||
@@ -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 );
|
||||
5197
ClassicStartSrc/ClassicStartMenu/ClassicStartMenuDLL/SettingsUI.cpp
Normal 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 );
|
||||
@@ -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
|
||||
@@ -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
|
||||
3299
ClassicStartSrc/ClassicStartMenu/ClassicStartMenuDLL/SkinManager.cpp
Normal 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 );
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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 );
|
||||
BIN
ClassicStartSrc/ClassicStartMenu/ClassicStartMenuDLL/apps.ico
Normal file
|
After Width: | Height: | Size: 71 KiB |
|
After Width: | Height: | Size: 6.6 KiB |
|
After Width: | Height: | Size: 4.1 KiB |
|
After Width: | Height: | Size: 86 KiB |
|
After Width: | Height: | Size: 107 KiB |
|
After Width: | Height: | Size: 170 KiB |
|
After Width: | Height: | Size: 66 KiB |
100
ClassicStartSrc/ClassicStartMenu/ClassicStartMenuDLL/dllmain.cpp
Normal 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;
|
||||
}
|
||||
@@ -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
|
||||
|
After Width: | Height: | Size: 756 B |
|
After Width: | Height: | Size: 1.6 KiB |
816
ClassicStartSrc/ClassicStartMenu/ClassicStartMenuDLL/resource.h
Normal 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
|
||||
|
After Width: | Height: | Size: 11 KiB |
BIN
ClassicStartSrc/ClassicStartMenu/ClassicStartMenuDLL/start.ico
Normal file
|
After Width: | Height: | Size: 34 KiB |
BIN
ClassicStartSrc/ClassicStartMenu/ClassicStartMenuDLL/start10.ico
Normal file
|
After Width: | Height: | Size: 34 KiB |
BIN
ClassicStartSrc/ClassicStartMenu/ClassicStartMenuDLL/startb.ico
Normal file
|
After Width: | Height: | Size: 34 KiB |
|
After Width: | Height: | Size: 34 KiB |
@@ -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"
|
||||
@@ -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"
|
||||
BIN
ClassicStartSrc/ClassicStartMenu/ClassicStartMenuDLL/style_7.bmp
Normal file
|
After Width: | Height: | Size: 125 KiB |
|
After Width: | Height: | Size: 270 KiB |
|
After Width: | Height: | Size: 84 KiB |
|
After Width: | Height: | Size: 182 KiB |
|
After Width: | Height: | Size: 120 KiB |
|
After Width: | Height: | Size: 259 KiB |
@@ -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
|
||||