1214 lines
35 KiB
C++
1214 lines
35 KiB
C++
|
// Start.cpp : DirectUI
|
||
|
//
|
||
|
|
||
|
#include "stdafx.h"
|
||
|
|
||
|
#ifdef FEATURE_STARTPAGE
|
||
|
|
||
|
#include <lmcons.h> // for UNLEN
|
||
|
#include <shlapip.h>
|
||
|
#include <DUserCtrl.h>
|
||
|
|
||
|
#include "pidlbutton.h"
|
||
|
|
||
|
#include "ProgList.h"
|
||
|
#include "hostutil.h"
|
||
|
|
||
|
#include "..\rcids.h"
|
||
|
|
||
|
using namespace DirectUI;
|
||
|
|
||
|
// Using ALL controls
|
||
|
UsingDUIClass(Element);
|
||
|
UsingDUIClass(HWNDElement);
|
||
|
|
||
|
UsingDUIClass(Button);
|
||
|
UsingDUIClass(Edit);
|
||
|
UsingDUIClass(Progress);
|
||
|
UsingDUIClass(RefPointElement);
|
||
|
UsingDUIClass(RepeatButton);
|
||
|
UsingDUIClass(ScrollBar);
|
||
|
UsingDUIClass(ScrollViewer);
|
||
|
UsingDUIClass(Selector);
|
||
|
UsingDUIClass(Thumb);
|
||
|
UsingDUIClass(Viewer);
|
||
|
|
||
|
|
||
|
EXTERN_C void Tray_OnStartMenuDismissed();
|
||
|
EXTERN_C void Tray_OnStartPageDismissed();
|
||
|
EXTERN_C void Tray_MenuInvoke(int idCmd);
|
||
|
EXTERN_C void Tray_SetStartPaneActive(BOOL fActive);
|
||
|
EXTERN_C void Tray_DoProperties(DWORD nStartPage);
|
||
|
|
||
|
HBITMAP GetBitmapForIDList(IShellFolder *psf, LPCITEMIDLIST pidlLast, UINT cx, UINT cy)
|
||
|
{
|
||
|
HBITMAP hBitmap = NULL;
|
||
|
IExtractImage *pei;
|
||
|
HRESULT hr = psf->GetUIObjectOf(NULL, 1, &pidlLast, IID_PPV_ARG_NULL(IExtractImage, &pei));
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
DWORD dwPriority;
|
||
|
DWORD dwFlags = IEIFLAG_SCREEN | IEIFLAG_OFFLINE;
|
||
|
SIZEL rgSize = {cx, cy};
|
||
|
|
||
|
WCHAR szBufferW[MAX_PATH];
|
||
|
hr = pei->GetLocation(szBufferW, ARRAYSIZE(szBufferW), &dwPriority, &rgSize, SHGetCurColorRes(), &dwFlags);
|
||
|
if (S_OK == hr)
|
||
|
{
|
||
|
hr = pei->Extract(&hBitmap);
|
||
|
}
|
||
|
}
|
||
|
return hBitmap;
|
||
|
}
|
||
|
|
||
|
|
||
|
HBITMAP GetBitmapForFile(LPCITEMIDLIST pidl, LPWSTR pszFile, UINT cx, UINT cy)
|
||
|
{
|
||
|
HBITMAP hbmp = NULL;
|
||
|
if (pidl)
|
||
|
{
|
||
|
IShellFolder *psf;
|
||
|
HRESULT hr = SHBindToObjectEx(NULL, pidl, NULL, IID_PPV_ARG(IShellFolder, &psf));
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
LPITEMIDLIST pidlChild;
|
||
|
hr = psf->ParseDisplayName(NULL, NULL, pszFile, NULL, &pidlChild, NULL);
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
hbmp = GetBitmapForIDList(psf, pidlChild, cx, cy);
|
||
|
ILFree(pidlChild);
|
||
|
}
|
||
|
psf->Release();
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
LPITEMIDLIST pidlFull = ILCreateFromPath(pszFile);
|
||
|
if (pidlFull)
|
||
|
{
|
||
|
IShellFolder *psf;
|
||
|
LPCITEMIDLIST pidlChild;
|
||
|
HRESULT hr = SHBindToParent(pidlFull, IID_PPV_ARG(IShellFolder, &psf), &pidlChild);
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
hbmp = GetBitmapForIDList(psf, pidlChild, cx, cy);
|
||
|
psf->Release();
|
||
|
}
|
||
|
|
||
|
ILFree(pidlFull);
|
||
|
}
|
||
|
}
|
||
|
return hbmp;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
////////////////////////////////////////////////////////
|
||
|
// StartFrame
|
||
|
////////////////////////////////////////////////////////
|
||
|
|
||
|
////////////////////////////////////////////////////////
|
||
|
// Frame declaration
|
||
|
|
||
|
class StartFrame : public HWNDElement, public ByUsageDUI
|
||
|
{
|
||
|
public:
|
||
|
static HRESULT Create(OUT Element** ppElement);
|
||
|
static HRESULT Create(HWND hwnd, HINSTANCE hInst, OUT Element** ppElement);
|
||
|
|
||
|
virtual void OnInput(InputEvent* pie);
|
||
|
virtual void OnEvent(Event* pEvent);
|
||
|
virtual LRESULT WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
||
|
virtual void OnKeyFocusMoved(Element* peFrom, Element* peTo);
|
||
|
|
||
|
|
||
|
HRESULT Populate();
|
||
|
|
||
|
static void CALLBACK ParseError(LPCWSTR pszError, LPCWSTR pszToken, int dLine);
|
||
|
static int CALLBACK _SortItemsAfterEnum(PaneItem *p1, PaneItem *p2, ByUsage *pbu);
|
||
|
|
||
|
// ByUsageDUI
|
||
|
virtual BOOL AddItem(PaneItem *pitem, IShellFolder *psf, LPCITEMIDLIST pidlChild);
|
||
|
virtual BOOL RegisterNotify(UINT id, LONG lEvents, LPITEMIDLIST pidl, BOOL fRecursive);
|
||
|
virtual BOOL UnregisterNotify(UINT id);
|
||
|
virtual HRESULT Register();
|
||
|
|
||
|
|
||
|
enum {TIMER_RECENT, TIMER_PROGRAMS, TIMER_ANIMATE};
|
||
|
StartFrame();
|
||
|
|
||
|
protected:
|
||
|
virtual ~StartFrame();
|
||
|
HRESULT Initialize(HWND hwnd) { return HWNDElement::Initialize(hwnd, true /* false */, 0); }
|
||
|
|
||
|
IShellFolder *GetRecentFilesFolder(LPITEMIDLIST *ppidl);
|
||
|
HRESULT InvokePidl(LPITEMIDLIST pidl);
|
||
|
|
||
|
LRESULT _OnMenuMessage(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
||
|
LRESULT _OnSetMenuForward(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
||
|
LRESULT _OnDestroy(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
||
|
LRESULT _OnChangeNotify(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
||
|
LRESULT _OnTimer(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
||
|
LRESULT _OnSize(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
||
|
LRESULT _OnActivate(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
||
|
|
||
|
void OnChangeNotify(UINT id, LONG lEvent, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2);
|
||
|
|
||
|
private:
|
||
|
|
||
|
BOOL _IsShortcutToFolder(IShellFolder *psf, LPCITEMIDLIST pidl);
|
||
|
HRESULT _PopulateSpecialFolders();
|
||
|
HRESULT _PopulateRecentDocuments();
|
||
|
HRESULT _PopulateRecentPrograms();
|
||
|
HRESULT _PopulatePictures();
|
||
|
|
||
|
HRESULT _SetPicture(Element *pe);
|
||
|
|
||
|
|
||
|
HINSTANCE _hInstance;
|
||
|
|
||
|
LPITEMIDLIST _pidlBrowser;
|
||
|
LPITEMIDLIST _pidlEmail;
|
||
|
LPITEMIDLIST _pidlSearch;
|
||
|
|
||
|
Element * _peAnimating;
|
||
|
int _iAnimationColor;
|
||
|
//
|
||
|
// Context menu handling
|
||
|
//
|
||
|
PIDLButton * _pPidlButtonPop; /* has currently popped-up context menu */
|
||
|
|
||
|
// Handler for the recent programs list
|
||
|
ByUsage * _pByUsage;
|
||
|
//
|
||
|
// _dpaEnum is the DPA of enumerated items, sorted in the
|
||
|
// _SortItemsAfterEnum sense, which prepares them for _RepopulateList.
|
||
|
// When _dpaEnum is destroyed, its pointers must be delete'd.
|
||
|
//
|
||
|
CDPA<PaneItem> _dpaEnum;
|
||
|
|
||
|
enum { DUI_MAXNOTIFY = 5 };
|
||
|
ULONG _rguChangeNotify[DUI_MAXNOTIFY];
|
||
|
|
||
|
enum { IDCN_LASTMOD = DUI_MAXNOTIFY -1 };
|
||
|
|
||
|
/* Outstanding change notification (if any) */
|
||
|
enum {
|
||
|
SPM_CHANGENOTIFY = WM_USER + 2, // WM_USER+1 is already being used by the pidl gadgets, WM_USER is used by DirectUI
|
||
|
SPM_SET_THUMBNAIL = SPM_CHANGENOTIFY + DUI_MAXNOTIFY
|
||
|
};
|
||
|
|
||
|
enum { SPM_ACTIVATE = WM_USER + 107 }; // Bad HACK to get activation loss info
|
||
|
|
||
|
static WCHAR _szParseError[];
|
||
|
static int _dParseError;
|
||
|
|
||
|
int _iMaxShow; // How many items we should show in the recent lists
|
||
|
|
||
|
public:
|
||
|
// ClassInfo accessors (static and virtual instance-based)
|
||
|
static IClassInfo* Class;
|
||
|
virtual IClassInfo* GetClassInfo() { return Class; }
|
||
|
};
|
||
|
|
||
|
////////////////////////////////////////////////////////
|
||
|
// Frame construction
|
||
|
StartFrame::StartFrame()
|
||
|
{
|
||
|
_pidlBrowser = ILCreateFromPath(TEXT("shell:::{2559a1f4-21d7-11d4-bdaf-00c04f60b9f0}"));
|
||
|
_pidlEmail = ILCreateFromPath(TEXT("shell:::{2559a1f5-21d7-11d4-bdaf-00c04f60b9f0}"));
|
||
|
_pidlSearch = ILCreateFromPath(TEXT("shell:::{2559a1f0-21d7-11d4-bdaf-00c04f60b9f0}"));
|
||
|
}
|
||
|
|
||
|
StartFrame::~StartFrame()
|
||
|
{
|
||
|
ILFree(_pidlBrowser);
|
||
|
ILFree(_pidlEmail);
|
||
|
ILFree(_pidlSearch);
|
||
|
}
|
||
|
|
||
|
HRESULT StartFrame::Create(OUT Element** ppElement)
|
||
|
{
|
||
|
UNREFERENCED_PARAMETER(ppElement);
|
||
|
DUIAssertForce("Cannot instantiate an HWND host derived Element via parser. Must use substitution.");
|
||
|
return E_NOTIMPL;
|
||
|
}
|
||
|
|
||
|
HRESULT StartFrame::Create(HWND hwnd, HINSTANCE hInst, OUT Element** ppElement)
|
||
|
{
|
||
|
*ppElement = NULL;
|
||
|
|
||
|
StartFrame* ppf = HNew<StartFrame>();
|
||
|
if (!ppf)
|
||
|
return E_OUTOFMEMORY;
|
||
|
|
||
|
HRESULT hr = ppf->Initialize(hwnd);
|
||
|
if (FAILED(hr))
|
||
|
return hr;
|
||
|
|
||
|
hr = ppf->SetActive(AE_MouseAndKeyboard);
|
||
|
ppf->_hInstance = hInst;
|
||
|
|
||
|
*ppElement = ppf;
|
||
|
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
HRESULT AddPidlToList(LPITEMIDLIST pidl, Element *peList, BOOL fInsert)
|
||
|
{
|
||
|
Element *pPidlButton;
|
||
|
HRESULT hr = PIDLButton::Create(pidl, &pPidlButton);
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
if (fInsert)
|
||
|
hr = peList->Insert(pPidlButton, 0);
|
||
|
else
|
||
|
hr = peList->Add(pPidlButton);
|
||
|
|
||
|
if (FAILED(hr))
|
||
|
{
|
||
|
pPidlButton->Destroy();
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
ILFree(pidl);
|
||
|
}
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
|
||
|
HRESULT InsertCSIDLIntoList(int csidl, Element *peList)
|
||
|
{
|
||
|
LPITEMIDLIST pidl;
|
||
|
HRESULT hr = SHGetFolderLocation(NULL, csidl, NULL, 0, &pidl);
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
hr = AddPidlToList(pidl, peList, TRUE); // Insert
|
||
|
}
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
BOOL StartFrame::AddItem(PaneItem *pitem, IShellFolder *psf, LPCITEMIDLIST pidlChild)
|
||
|
{
|
||
|
BOOL fRet = TRUE;
|
||
|
if (_dpaEnum.AppendPtr(pitem) < 0)
|
||
|
{
|
||
|
fRet = FALSE;
|
||
|
delete pitem;
|
||
|
}
|
||
|
return fRet;
|
||
|
}
|
||
|
|
||
|
BOOL StartFrame::_IsShortcutToFolder(IShellFolder *psf, LPCITEMIDLIST pidl)
|
||
|
{
|
||
|
BOOL fRc = FALSE; // assume not
|
||
|
IShellLink *psl;
|
||
|
HRESULT hr;
|
||
|
|
||
|
hr = psf->GetUIObjectOf(GetHWND(), 1, &pidl, IID_PPV_ARG_NULL(IShellLink, &psl));
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
LPITEMIDLIST pidlTarget;
|
||
|
if (SUCCEEDED(psl->GetIDList(&pidlTarget)))
|
||
|
{
|
||
|
DWORD dwAttr = SFGAO_FOLDER | SFGAO_BROWSABLE;
|
||
|
if (SUCCEEDED(SHGetAttributesOf(pidlTarget, &dwAttr)))
|
||
|
{
|
||
|
fRc = dwAttr & SFGAO_FOLDER;
|
||
|
}
|
||
|
ILFree(pidlTarget);
|
||
|
}
|
||
|
psl->Release();
|
||
|
}
|
||
|
return fRc;
|
||
|
}
|
||
|
|
||
|
IShellFolder *StartFrame::GetRecentFilesFolder(LPITEMIDLIST *ppidl)
|
||
|
{
|
||
|
HRESULT hr;
|
||
|
IShellFolder *psf = NULL;
|
||
|
|
||
|
hr = SHGetSpecialFolderLocation(GetHWND(), CSIDL_RECENT, ppidl);
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
hr = SHBindToObjectEx(NULL, *ppidl, NULL, IID_PPV_ARG(IShellFolder, &psf));
|
||
|
if (FAILED(hr))
|
||
|
{
|
||
|
ILFree(*ppidl);
|
||
|
*ppidl = NULL;
|
||
|
}
|
||
|
}
|
||
|
return psf;
|
||
|
}
|
||
|
|
||
|
|
||
|
HRESULT StartFrame::_PopulateSpecialFolders()
|
||
|
{
|
||
|
Element *peList;
|
||
|
peList = FindDescendent(StrToID(L"DocList"));
|
||
|
if (peList)
|
||
|
{
|
||
|
PIDLButton::SetImageSize(SHGFI_LARGEICON);
|
||
|
InsertCSIDLIntoList(CSIDL_BITBUCKET, peList);
|
||
|
InsertCSIDLIntoList(CSIDL_NETWORK, peList);
|
||
|
InsertCSIDLIntoList(CSIDL_MYMUSIC, peList);
|
||
|
InsertCSIDLIntoList(CSIDL_MYPICTURES, peList);
|
||
|
InsertCSIDLIntoList(CSIDL_PERSONAL, peList);
|
||
|
}
|
||
|
|
||
|
peList = FindDescendent(StrToID(L"SystemDocList"));
|
||
|
if (peList)
|
||
|
{
|
||
|
LPITEMIDLIST pidlHelp = ILCreateFromPath(TEXT("shell:::{2559a1f1-21d7-11d4-bdaf-00c04f60b9f0}")); // Help and support
|
||
|
if (pidlHelp)
|
||
|
AddPidlToList(pidlHelp, peList, TRUE); // Insert
|
||
|
|
||
|
InsertCSIDLIntoList(CSIDL_CONTROLS, peList);
|
||
|
InsertCSIDLIntoList(CSIDL_DRIVES, peList);
|
||
|
}
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
HRESULT StartFrame::_PopulateRecentDocuments()
|
||
|
{
|
||
|
Selector *peList;
|
||
|
|
||
|
peList = (Selector*)FindDescendent(StrToID(L"Documents"));
|
||
|
if (peList)
|
||
|
{
|
||
|
PIDLButton::SetImageSize(SHGFI_LARGEICON);
|
||
|
peList->DestroyAll();
|
||
|
|
||
|
IEnumIDList *peidl;
|
||
|
LPITEMIDLIST pidlRoot;
|
||
|
|
||
|
IShellFolder *psfRecentFiles = GetRecentFilesFolder(&pidlRoot);
|
||
|
|
||
|
// The CSIDL_RECENT folder is magic: The items are enumerated
|
||
|
// out of it in MRU order!
|
||
|
|
||
|
if (psfRecentFiles)
|
||
|
{
|
||
|
if (SUCCEEDED(psfRecentFiles->EnumObjects(GetHWND(), SHCONTF_NONFOLDERS, &peidl)))
|
||
|
{
|
||
|
LPITEMIDLIST pidl;
|
||
|
int cAdded = 0;
|
||
|
|
||
|
while (cAdded < _iMaxShow && peidl->Next(1, &pidl, NULL) == S_OK)
|
||
|
{
|
||
|
// Filter out shortcuts to folders
|
||
|
if (!_IsShortcutToFolder(psfRecentFiles, pidl))
|
||
|
{
|
||
|
LPITEMIDLIST pidlFull = ILCombine(pidlRoot, pidl);
|
||
|
if (pidlFull)
|
||
|
{
|
||
|
// AddPidlToList takes ownership of the pidl
|
||
|
AddPidlToList(pidlFull, peList, FALSE);
|
||
|
cAdded++;
|
||
|
}
|
||
|
}
|
||
|
ILFree(pidl);
|
||
|
}
|
||
|
peidl->Release();
|
||
|
}
|
||
|
RegisterNotify(IDCN_LASTMOD, SHCNE_DISKEVENTS | SHCNE_UPDATEIMAGE, pidlRoot, FALSE);
|
||
|
ILFree(pidlRoot);
|
||
|
psfRecentFiles->Release();
|
||
|
}
|
||
|
}
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
int CALLBACK StartFrame::_SortItemsAfterEnum(PaneItem *p1, PaneItem *p2, ByUsage *pbu)
|
||
|
{
|
||
|
//
|
||
|
// Put all pinned items (sorted by pin position) ahead of unpinned items.
|
||
|
//
|
||
|
if (p1->IsPinned())
|
||
|
{
|
||
|
if (p2->IsPinned())
|
||
|
{
|
||
|
return p1->GetPinPos() - p2->GetPinPos();
|
||
|
}
|
||
|
return -1;
|
||
|
}
|
||
|
else if (p2->IsPinned())
|
||
|
{
|
||
|
return +1;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Both unpinned - let the client decide.
|
||
|
//
|
||
|
return pbu->CompareItems(p1, p2);
|
||
|
}
|
||
|
|
||
|
HRESULT StartFrame::_PopulateRecentPrograms()
|
||
|
{
|
||
|
Element *peList;
|
||
|
|
||
|
peList = FindDescendent(StrToID(L"Programs"));
|
||
|
if (peList)
|
||
|
{
|
||
|
PIDLButton::SetImageSize(SHGFI_LARGEICON);
|
||
|
|
||
|
peList->DestroyAll();
|
||
|
|
||
|
if (!_pByUsage)
|
||
|
{
|
||
|
_pByUsage = new ByUsage(NULL, static_cast<ByUsageDUI *>(this));
|
||
|
if (_pByUsage)
|
||
|
{
|
||
|
IPropertyBag *pbag;
|
||
|
if(SUCCEEDED(CreatePropBagFromReg(TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\StartPage\\Normal\\W32Control1"), &pbag)))
|
||
|
{
|
||
|
if (SUCCEEDED(_pByUsage->Initialize()) && _dpaEnum.Create(4))
|
||
|
{
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
delete _pByUsage;
|
||
|
_pByUsage = NULL;
|
||
|
}
|
||
|
|
||
|
pbag->Release();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (_pByUsage)
|
||
|
{
|
||
|
_pByUsage->EnumItems();
|
||
|
_dpaEnum.SortEx(_SortItemsAfterEnum, _pByUsage);
|
||
|
|
||
|
int iPos; // the slot we are trying to fill
|
||
|
int iEnum; // the item index we will fill it from
|
||
|
PaneItem *pitem; // the item that will fill it
|
||
|
|
||
|
// Note that the loop control must be a _dpaEnum.GetPtr(), not a
|
||
|
// _dpaEnum.FastGetPtr(), because iEnum can go past the end of the
|
||
|
// array if we do't have _iMaxShow items in the first place.
|
||
|
//
|
||
|
|
||
|
for (iPos = iEnum = 0;
|
||
|
iEnum < _iMaxShow && (pitem = _dpaEnum.GetPtr(iEnum)) != NULL;
|
||
|
iEnum++)
|
||
|
{
|
||
|
LPITEMIDLIST pidl = _pByUsage->GetFullPidl(pitem);
|
||
|
if (pidl)
|
||
|
{
|
||
|
AddPidlToList(pidl, peList, FALSE);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Clear out the DPA
|
||
|
|
||
|
_dpaEnum.EnumCallbackEx(PaneItem::DPAEnumCallback, (LPVOID)NULL);
|
||
|
_dpaEnum.DeleteAllPtrs();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
LPWSTR GetStrPictureFromID(int nImageID)
|
||
|
{
|
||
|
LPWSTR pszPic = NULL;
|
||
|
switch (nImageID)
|
||
|
{
|
||
|
case 1: pszPic = L"Picture1";
|
||
|
break;
|
||
|
case 2: pszPic = L"Picture2";
|
||
|
break;
|
||
|
case 3: pszPic = L"Picture3";
|
||
|
break;
|
||
|
}
|
||
|
return pszPic;
|
||
|
}
|
||
|
|
||
|
BOOL IsValidExtension(LPWSTR pszPath)
|
||
|
{
|
||
|
if (pszPath)
|
||
|
{
|
||
|
WCHAR *pszExt = PathFindExtension(pszPath);
|
||
|
if (pszExt && (lstrcmpi(pszExt, TEXT(".bmp")) == 0 || lstrcmpi(pszExt, TEXT(".jpg")) == 0 ||
|
||
|
lstrcmpi(pszExt, TEXT(".jpeg")) == 0))
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
HRESULT StartFrame::_PopulatePictures()
|
||
|
{
|
||
|
LPITEMIDLIST pidl;
|
||
|
HRESULT hr = SHGetFolderLocation(NULL, CSIDL_MYPICTURES, NULL, 0, &pidl);
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
WCHAR szPath[MAX_PATH];
|
||
|
hr = SHGetPathFromIDList(pidl, szPath);
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
WIN32_FIND_DATA fd;
|
||
|
HKEY hkey = NULL;
|
||
|
RegOpenKey(HKEY_CURRENT_USER, TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\StartPage"), &hkey);
|
||
|
|
||
|
StrCatBuff(szPath, TEXT("\\*"), ARRAYSIZE(szPath));
|
||
|
|
||
|
int nImageID = 1;
|
||
|
HANDLE hFind = FindFirstFile(szPath, &fd);
|
||
|
while (nImageID <= 3)
|
||
|
{
|
||
|
LPWSTR pszPic = GetStrPictureFromID(nImageID);
|
||
|
LPWSTR pszPathToImage = NULL;
|
||
|
LPITEMIDLIST pidlFolder = NULL;
|
||
|
if (hkey)
|
||
|
{
|
||
|
DWORD dwType;
|
||
|
DWORD cb = sizeof(szPath);
|
||
|
if (RegQueryValueEx(hkey, pszPic, NULL, &dwType, (LPBYTE)szPath, &cb) == ERROR_SUCCESS
|
||
|
&& dwType == REG_SZ && PathFileExists(szPath) && IsValidExtension(szPath))
|
||
|
pszPathToImage = szPath;
|
||
|
}
|
||
|
|
||
|
while (!pszPathToImage && hFind != INVALID_HANDLE_VALUE)
|
||
|
{
|
||
|
pidlFolder = pidl;
|
||
|
pszPathToImage = fd.cFileName;
|
||
|
|
||
|
if (!FindNextFile(hFind, &fd))
|
||
|
{
|
||
|
FindClose(hFind);
|
||
|
hFind = INVALID_HANDLE_VALUE;
|
||
|
}
|
||
|
// Skip the stupid sample
|
||
|
if (lstrcmpi(pszPathToImage, TEXT("sample.jpg")) == 0 || !IsValidExtension(pszPathToImage))
|
||
|
pszPathToImage = NULL;
|
||
|
}
|
||
|
|
||
|
if (pszPathToImage)
|
||
|
{
|
||
|
HBITMAP hbmp = GetBitmapForFile(pidlFolder, pszPathToImage, 150, 113);
|
||
|
if (hbmp)
|
||
|
{
|
||
|
Element *pe = FindDescendent(StrToID(pszPic));
|
||
|
if (pe)
|
||
|
{
|
||
|
Value *pvalIcon = Value::CreateGraphic(hbmp);
|
||
|
if (pvalIcon)
|
||
|
{
|
||
|
pe->SetValue(ContentProp, PI_Local, pvalIcon);
|
||
|
pvalIcon->Release();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
DeleteObject(hbmp);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
nImageID++;
|
||
|
}
|
||
|
if (hFind != INVALID_HANDLE_VALUE)
|
||
|
FindClose(hFind);
|
||
|
if (hkey)
|
||
|
RegCloseKey(hkey);
|
||
|
}
|
||
|
}
|
||
|
ILFree(pidl);
|
||
|
}
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
HRESULT StartFrame::_SetPicture(Element *pe)
|
||
|
{
|
||
|
LPITEMIDLIST pidl;
|
||
|
HRESULT hr = SHGetFolderLocation(NULL, CSIDL_MYPICTURES, NULL, 0, &pidl);
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
WCHAR szPath[MAX_PATH];
|
||
|
hr = SHGetPathFromIDList(pidl, szPath);
|
||
|
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
OPENFILENAME ofn; // common dialog box structure
|
||
|
WCHAR szFile[MAX_PATH]; // buffer for file name
|
||
|
|
||
|
*szFile = L'\0';
|
||
|
|
||
|
// Initialize OPENFILENAME
|
||
|
ZeroMemory(&ofn, sizeof(OPENFILENAME));
|
||
|
ofn.lStructSize = sizeof(OPENFILENAME);
|
||
|
ofn.hwndOwner = GetHWND();
|
||
|
ofn.lpstrFile = szFile;
|
||
|
ofn.nMaxFile = sizeof(szFile);
|
||
|
ofn.lpstrFilter = TEXT("Pictures\0*.JPG;*.JPEG;*.BMP\0");
|
||
|
ofn.nFilterIndex = 1;
|
||
|
ofn.lpstrFileTitle = NULL;
|
||
|
ofn.nMaxFileTitle = 0;
|
||
|
ofn.lpstrInitialDir = szPath;
|
||
|
ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_DONTADDTORECENT;
|
||
|
|
||
|
// Display the Open dialog box.
|
||
|
|
||
|
if (GetOpenFileName(&ofn)==TRUE)
|
||
|
{
|
||
|
WCHAR *pszExt = PathFindExtension(ofn.lpstrFile);
|
||
|
if (pszExt && (lstrcmpi(pszExt, TEXT(".bmp")) == 0 || lstrcmpi(pszExt, TEXT(".jpg")) == 0 ||
|
||
|
lstrcmpi(pszExt, TEXT(".jpg")) == 0))
|
||
|
{
|
||
|
HBITMAP hbmp = GetBitmapForFile(NULL, ofn.lpstrFile, 150, 113);
|
||
|
if (hbmp)
|
||
|
{
|
||
|
Value *pvalIcon = Value::CreateGraphic(hbmp);
|
||
|
if (pvalIcon)
|
||
|
{
|
||
|
pe->SetValue(ContentProp, PI_Local, pvalIcon);
|
||
|
pvalIcon->Release();
|
||
|
HKEY hkey = NULL;
|
||
|
RegOpenKey(HKEY_CURRENT_USER, TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\StartPage"), &hkey);
|
||
|
if (hkey)
|
||
|
{
|
||
|
LPWSTR pszPic;
|
||
|
for (int i=1; i<=3; i++)
|
||
|
{
|
||
|
pszPic = GetStrPictureFromID(i);
|
||
|
if (FindDescendent(StrToID(pszPic)) == pe)
|
||
|
break;
|
||
|
pszPic = NULL;
|
||
|
}
|
||
|
if (pszPic)
|
||
|
RegSetValueEx(hkey, pszPic, NULL, REG_SZ, (LPBYTE)ofn.lpstrFile, (lstrlen(ofn.lpstrFile)+1) * sizeof(TCHAR));
|
||
|
RegCloseKey(hkey);
|
||
|
}
|
||
|
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
DeleteObject(hbmp);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
HRESULT StartFrame::Populate()
|
||
|
{
|
||
|
Element *pe = FindDescendent(StrToID(L"name"));
|
||
|
|
||
|
if (pe)
|
||
|
{
|
||
|
WCHAR szUserName[UNLEN + 1];
|
||
|
ULONG uLen = ARRAYSIZE(szUserName);
|
||
|
*szUserName = _T('\0');
|
||
|
SHGetUserDisplayName(szUserName, &uLen);
|
||
|
pe->SetContentString(szUserName);
|
||
|
}
|
||
|
|
||
|
pe = FindDescendent(StrToID(L"UserPicture"));
|
||
|
if (pe)
|
||
|
{
|
||
|
TCHAR szUserPicturePath[MAX_PATH];
|
||
|
if (SUCCEEDED(SHGetUserPicturePath(NULL, SHGUPP_FLAG_CREATE, szUserPicturePath)))
|
||
|
{
|
||
|
HBITMAP hbmUserPicture = (HBITMAP)LoadImage(NULL, szUserPicturePath, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
|
||
|
if (hbmUserPicture)
|
||
|
{
|
||
|
Value *pvalIcon = Value::CreateGraphic(hbmUserPicture);
|
||
|
if (pvalIcon)
|
||
|
{
|
||
|
pe->SetValue(ContentProp, PI_Local, pvalIcon);
|
||
|
pvalIcon->Release();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
DeleteObject(hbmUserPicture);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
_PopulatePictures();
|
||
|
|
||
|
_PopulateSpecialFolders();
|
||
|
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
|
||
|
void StartFrame::OnChangeNotify(UINT id, LONG lEvent, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2)
|
||
|
{
|
||
|
if (id == IDCN_LASTMOD) // Change in last documents
|
||
|
{
|
||
|
UnregisterNotify(id);
|
||
|
KillTimer(GetHWND(), TIMER_RECENT);
|
||
|
SetTimer(GetHWND(), TIMER_RECENT, 2000, NULL);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
ASSERT(_pByUsage);
|
||
|
if(_pByUsage)
|
||
|
{
|
||
|
_pByUsage->GetMenuCache()->OnChangeNotify(id, lEvent, pidl1, pidl2);
|
||
|
KillTimer(GetHWND(), TIMER_PROGRAMS);
|
||
|
SetTimer(GetHWND(), TIMER_PROGRAMS, 10 * 1000, NULL);
|
||
|
}
|
||
|
|
||
|
}
|
||
|
}
|
||
|
|
||
|
LRESULT StartFrame::_OnTimer(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||
|
{
|
||
|
if (wParam == TIMER_RECENT)
|
||
|
{
|
||
|
KillTimer(hwnd, wParam);
|
||
|
StartDefer();
|
||
|
_PopulateRecentDocuments();
|
||
|
EndDefer();
|
||
|
}
|
||
|
else if (wParam == TIMER_PROGRAMS)
|
||
|
{
|
||
|
KillTimer(hwnd, wParam);
|
||
|
StartDefer();
|
||
|
_PopulateRecentPrograms();
|
||
|
EndDefer();
|
||
|
SetTimer(GetHWND(), TIMER_PROGRAMS, 1 * 60 * 1000, NULL); // 1 minute
|
||
|
}
|
||
|
else if (wParam == TIMER_ANIMATE)
|
||
|
{
|
||
|
if (_iAnimationColor & 1)
|
||
|
{
|
||
|
_iAnimationColor += 16;
|
||
|
if (_iAnimationColor == 255)
|
||
|
KillTimer(hwnd, wParam);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (_iAnimationColor > 16)
|
||
|
_iAnimationColor -= 16;
|
||
|
else
|
||
|
_iAnimationColor = 15;
|
||
|
}
|
||
|
_peAnimating->SetForegroundColor(RGB(_iAnimationColor, _iAnimationColor, (3*_iAnimationColor + 255) /4));
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
BOOL StartFrame::RegisterNotify(UINT id, LONG lEvents, LPITEMIDLIST pidl, BOOL fRecursive)
|
||
|
{
|
||
|
ASSERT(id < DUI_MAXNOTIFY);
|
||
|
|
||
|
if (id < DUI_MAXNOTIFY)
|
||
|
{
|
||
|
UnregisterNotify(id);
|
||
|
|
||
|
SHChangeNotifyEntry fsne;
|
||
|
fsne.fRecursive = fRecursive;
|
||
|
fsne.pidl = pidl;
|
||
|
|
||
|
int fSources = SHCNRF_NewDelivery | SHCNRF_ShellLevel | SHCNRF_InterruptLevel;
|
||
|
_rguChangeNotify[id] = SHChangeNotifyRegister(GetHWND(), fSources, lEvents,
|
||
|
SPM_CHANGENOTIFY + id, 1, &fsne);
|
||
|
return _rguChangeNotify[id];
|
||
|
}
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
BOOL StartFrame::UnregisterNotify(UINT id)
|
||
|
{
|
||
|
ASSERT(id < DUI_MAXNOTIFY);
|
||
|
|
||
|
if (id < DUI_MAXNOTIFY && _rguChangeNotify[id])
|
||
|
{
|
||
|
UINT uChangeNotify = _rguChangeNotify[id];
|
||
|
_rguChangeNotify[id] = 0;
|
||
|
return SHChangeNotifyDeregister(uChangeNotify);
|
||
|
}
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
|
||
|
////////////////////////////////////////////////////////
|
||
|
// System events
|
||
|
|
||
|
void StartFrame::OnInput(InputEvent* pie)
|
||
|
{
|
||
|
HWNDElement::OnInput(pie);
|
||
|
}
|
||
|
|
||
|
void StartFrame::OnEvent(Event* pEvent)
|
||
|
{
|
||
|
if (pEvent->nStage == GMF_BUBBLED)
|
||
|
{
|
||
|
if (pEvent->uidType == Button::Click)
|
||
|
{
|
||
|
if (pEvent->peTarget->GetID() == StrToID(L"email"))
|
||
|
{
|
||
|
InvokePidl(_pidlEmail);
|
||
|
}
|
||
|
else if (pEvent->peTarget->GetID() == StrToID(L"internet"))
|
||
|
{
|
||
|
InvokePidl(_pidlBrowser);
|
||
|
}
|
||
|
else if (pEvent->peTarget->GetID() == StrToID(L"search"))
|
||
|
{
|
||
|
InvokePidl(_pidlSearch);
|
||
|
}
|
||
|
else if (pEvent->peTarget->GetID() == StrToID(L"MorePrograms"))
|
||
|
{
|
||
|
LPITEMIDLIST pidl = ILCreateFromPath(TEXT("shell:::{7be9d83c-a729-4d97-b5a7-1b7313c39e0a}"));
|
||
|
if (pidl)
|
||
|
{
|
||
|
InvokePidl(pidl);
|
||
|
ILFree(pidl);
|
||
|
}
|
||
|
}
|
||
|
else if (pEvent->peTarget->GetID() == StrToID(L"MoreDocuments"))
|
||
|
{
|
||
|
LPITEMIDLIST pidl = ILCreateFromPath(TEXT("shell:::{9387ae38-d19b-4de5-baf5-1f7767a1cf04}"));
|
||
|
if (pidl)
|
||
|
{
|
||
|
InvokePidl(pidl);
|
||
|
ILFree(pidl);
|
||
|
}
|
||
|
}
|
||
|
else if (pEvent->peTarget->GetID() == StrToID(L"turnoff"))
|
||
|
{
|
||
|
Tray_MenuInvoke(IDM_EXITWIN);
|
||
|
}
|
||
|
else if (pEvent->peTarget->GetID() == StrToID(L"logoff"))
|
||
|
{
|
||
|
Tray_MenuInvoke(IDM_LOGOFF);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
HMENU hmenu = LoadMenu(_hInstance, MAKEINTRESOURCE(IDM_PICTMENU));
|
||
|
if (hmenu)
|
||
|
{
|
||
|
HMENU hMenuTrack = GetSubMenu(hmenu, 0);
|
||
|
ButtonClickEvent *peButton = reinterpret_cast<ButtonClickEvent *>(pEvent);
|
||
|
|
||
|
if (peButton->pt.x == -1) // Keyboard context menu
|
||
|
{
|
||
|
Value *pv;
|
||
|
const SIZE *psize = pEvent->peTarget->GetExtent(&pv);
|
||
|
peButton->pt.x = psize->cx/2;
|
||
|
peButton->pt.y = psize->cy/2;
|
||
|
pv->Release();
|
||
|
}
|
||
|
POINT pt;
|
||
|
MapElementPoint(pEvent->peTarget, &peButton->pt, &pt);
|
||
|
ClientToScreen(GetHWND(), &pt);
|
||
|
|
||
|
int idCmd = TrackPopupMenuEx(hMenuTrack, TPM_RETURNCMD | TPM_RIGHTBUTTON | TPM_LEFTALIGN, pt.x, pt.y, GetHWND(), NULL);
|
||
|
|
||
|
DestroyMenu(hmenu);
|
||
|
|
||
|
if (idCmd == ID_CMD_CHANGE_PICTURE)
|
||
|
{
|
||
|
_SetPicture(pEvent->peTarget);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
HWNDElement::OnEvent(pEvent);
|
||
|
}
|
||
|
|
||
|
HRESULT StartFrame::InvokePidl(LPITEMIDLIST pidl)
|
||
|
{
|
||
|
HRESULT hr = E_FAIL;
|
||
|
IShellFolder *psf;
|
||
|
LPCITEMIDLIST pidlShort;
|
||
|
// Multi-level child pidl
|
||
|
if (SUCCEEDED(SHBindToFolderIDListParent(NULL, pidl, IID_PPV_ARG(IShellFolder, &psf), &pidlShort)))
|
||
|
{
|
||
|
hr = SHInvokeDefaultCommand(GetHWND(), psf, pidlShort);
|
||
|
psf->Release();
|
||
|
}
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
WCHAR StartFrame::_szParseError[201];
|
||
|
int StartFrame::_dParseError;
|
||
|
|
||
|
void StartFrame::ParseError(LPCWSTR pszError, LPCWSTR pszToken, int dLine)
|
||
|
{
|
||
|
if (dLine != -1)
|
||
|
swprintf(_szParseError, L"%s '%s' at line %d", pszError, pszToken, dLine);
|
||
|
else
|
||
|
swprintf(_szParseError, L"%s '%s'", pszError, pszToken);
|
||
|
|
||
|
_dParseError = dLine;
|
||
|
}
|
||
|
|
||
|
LRESULT StartFrame::_OnSetMenuForward(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||
|
{
|
||
|
_pPidlButtonPop = (PIDLButton *)lParam;
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
LRESULT StartFrame::_OnMenuMessage(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||
|
{
|
||
|
if (_pPidlButtonPop)
|
||
|
return _pPidlButtonPop->OnMenuMessage(hwnd, uMsg, wParam, lParam);
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
LRESULT StartFrame::_OnChangeNotify(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||
|
{
|
||
|
LPITEMIDLIST *ppidl;
|
||
|
LONG lEvent;
|
||
|
LPSHChangeNotificationLock pshcnl;
|
||
|
pshcnl = SHChangeNotification_Lock((HANDLE)wParam, (DWORD)lParam, &ppidl, &lEvent);
|
||
|
|
||
|
if (pshcnl)
|
||
|
{
|
||
|
OnChangeNotify(uMsg - SPM_CHANGENOTIFY, lEvent, ppidl[0], ppidl[1]);
|
||
|
SHChangeNotification_Unlock(pshcnl);
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
LRESULT StartFrame::_OnDestroy(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||
|
{
|
||
|
UINT id;
|
||
|
for (id = 0; id < DUI_MAXNOTIFY; id++)
|
||
|
{
|
||
|
UnregisterNotify(id);
|
||
|
}
|
||
|
|
||
|
delete _pByUsage;
|
||
|
_pByUsage = NULL;
|
||
|
|
||
|
#if 0 // REVIEW fabriced
|
||
|
if (_hwndList)
|
||
|
{
|
||
|
RevokeDragDrop(_hwndList);
|
||
|
}
|
||
|
if (_psched)
|
||
|
{
|
||
|
_psched->RemoveTasks(TOID_SFTBarHostBackgroundEnum, (DWORD_PTR)this, FALSE);
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
return HWNDElement::WndProc(hwnd, uMsg, wParam, lParam);
|
||
|
}
|
||
|
|
||
|
LRESULT StartFrame::_OnActivate(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||
|
{
|
||
|
if (WA_ACTIVE == LOWORD(wParam))
|
||
|
{
|
||
|
// Run a little animation when we come up
|
||
|
_peAnimating = FindDescendent(StrToID(L"name"));
|
||
|
_iAnimationColor = 64;
|
||
|
SetTimer(GetHWND(), TIMER_ANIMATE, 20, NULL);
|
||
|
}
|
||
|
// If we are loosing focus, reset the start button.
|
||
|
else if (WA_INACTIVE == LOWORD(wParam))
|
||
|
{
|
||
|
if (_peAnimating)
|
||
|
_peAnimating->SetForegroundColor(RGB(255, 255, 255));
|
||
|
|
||
|
KillTimer(GetHWND(), TIMER_ANIMATE);
|
||
|
Tray_SetStartPaneActive(FALSE);
|
||
|
Tray_OnStartPageDismissed();
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
LRESULT StartFrame::_OnSize(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||
|
{
|
||
|
Element::StartDefer();
|
||
|
SetWidth(LOWORD(lParam));
|
||
|
SetHeight(HIWORD(lParam));
|
||
|
if (HIWORD(lParam) < 590)
|
||
|
{
|
||
|
_iMaxShow = 7;
|
||
|
Element *pe = FindDescendent(StrToID(L"CurveZone"));
|
||
|
if (pe)
|
||
|
pe->SetPadding(0, 0, 0, 74);
|
||
|
pe = FindDescendent(StrToID(L"LogoffZone"));
|
||
|
if (pe)
|
||
|
pe->SetPadding(50, 0, 50, 10);
|
||
|
}
|
||
|
else if (HIWORD(lParam) < 700)
|
||
|
{
|
||
|
_iMaxShow = 7;
|
||
|
Element *pe = FindDescendent(StrToID(L"CurveZone"));
|
||
|
if (pe)
|
||
|
pe->SetPadding(0, 0, 0, 105);
|
||
|
pe = FindDescendent(StrToID(L"LogoffZone"));
|
||
|
if (pe)
|
||
|
pe->SetPadding(50, 0, 50, 41);
|
||
|
}
|
||
|
else if (HIWORD(lParam) < 760)
|
||
|
{
|
||
|
_iMaxShow = 10;
|
||
|
Element *pe = FindDescendent(StrToID(L"CurveZone"));
|
||
|
if (pe)
|
||
|
pe->SetPadding(0, 0, 0, 74);
|
||
|
pe = FindDescendent(StrToID(L"LogoffZone"));
|
||
|
if (pe)
|
||
|
pe->SetPadding(50, 0, 50, 10);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
_iMaxShow = 10;
|
||
|
Element *pe = FindDescendent(StrToID(L"CurveZone"));
|
||
|
if (pe)
|
||
|
pe->SetPadding(0, 0, 0, 105);
|
||
|
pe = FindDescendent(StrToID(L"LogoffZone"));
|
||
|
if (pe)
|
||
|
pe->SetPadding(50, 0, 50, 41);
|
||
|
}
|
||
|
|
||
|
_PopulateRecentDocuments();
|
||
|
_PopulateRecentPrograms();
|
||
|
|
||
|
Element::EndDefer();
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
void StartFrame::OnKeyFocusMoved(Element* peFrom, Element* peTo)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
LRESULT StartFrame::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||
|
{
|
||
|
#define HANDLE_SF_MESSAGE(wm, fn) case wm: return fn(hWnd, uMsg, wParam, lParam)
|
||
|
|
||
|
if (SPM_CHANGENOTIFY <= uMsg && uMsg < SPM_CHANGENOTIFY + DUI_MAXNOTIFY)
|
||
|
return _OnChangeNotify(hWnd, uMsg, wParam, lParam);
|
||
|
|
||
|
switch (uMsg)
|
||
|
{
|
||
|
HANDLE_SF_MESSAGE(WM_DESTROY, _OnDestroy);
|
||
|
HANDLE_SF_MESSAGE(WM_TIMER, _OnTimer);
|
||
|
HANDLE_SF_MESSAGE(WM_SIZE, _OnSize);
|
||
|
HANDLE_SF_MESSAGE(SPM_ACTIVATE, _OnActivate);
|
||
|
|
||
|
// Context menus handlers
|
||
|
HANDLE_SF_MESSAGE(WM_INITMENUPOPUP,_OnMenuMessage);
|
||
|
HANDLE_SF_MESSAGE(WM_DRAWITEM, _OnMenuMessage);
|
||
|
HANDLE_SF_MESSAGE(WM_MENUCHAR, _OnMenuMessage);
|
||
|
HANDLE_SF_MESSAGE(WM_MEASUREITEM, _OnMenuMessage);
|
||
|
HANDLE_SF_MESSAGE(PIDLButton::PBM_SETMENUFORWARD, _OnSetMenuForward);
|
||
|
}
|
||
|
|
||
|
return HWNDElement::WndProc(hWnd, uMsg, wParam, lParam);
|
||
|
}
|
||
|
|
||
|
////////////////////////////////////////////////////////
|
||
|
// ClassInfo (must appear after property definitions)
|
||
|
|
||
|
// Define class info with type and base type, set static class pointer
|
||
|
|
||
|
IClassInfo* StartFrame::Class = NULL;
|
||
|
HRESULT StartFrame::Register()
|
||
|
{
|
||
|
return ClassInfo<StartFrame,HWNDElement>::Register(L"StartFrame", NULL, 0);
|
||
|
}
|
||
|
|
||
|
|
||
|
////////////////////////////////////////////////////////
|
||
|
// Parser
|
||
|
////////////////////////////////////////////////////////
|
||
|
|
||
|
void CALLBACK ParseError(LPCWSTR pszError, LPCWSTR pszToken, int dLine)
|
||
|
{
|
||
|
WCHAR buf[201];
|
||
|
|
||
|
if (dLine != -1)
|
||
|
swprintf(buf, L"%s '%s' at line %d", pszError, pszToken, dLine);
|
||
|
else
|
||
|
swprintf(buf, L"%s '%s'", pszError, pszToken);
|
||
|
|
||
|
MessageBoxW(NULL, buf, L"Parser Message", MB_OK);
|
||
|
}
|
||
|
|
||
|
|
||
|
// Privates from Shell32.
|
||
|
STDAPI_(HWND) SetPeekMsgEx(FARPROC fp, HANDLE hDesktop);
|
||
|
STDAPI_(BOOL) SetStartPageHWND(HANDLE hDesktop, HWND hwnd);
|
||
|
|
||
|
typedef HWND (*SetPeek)(FARPROC fp, HANDLE hDesktop);
|
||
|
|
||
|
/////////////////////////////////////
|
||
|
// Creation of the Start Page
|
||
|
void CreateStartPage(HINSTANCE hInstance, HANDLE hDesktop)
|
||
|
{
|
||
|
HWND hwndParent = NULL;
|
||
|
|
||
|
CoInitialize(NULL);
|
||
|
// DirectUI init thread in caller
|
||
|
InitThread();
|
||
|
|
||
|
hwndParent = SetPeekMsgEx((FARPROC)PeekMessageEx, hDesktop);
|
||
|
|
||
|
Element::StartDefer();
|
||
|
|
||
|
// HWND Root
|
||
|
StartFrame* psf;
|
||
|
HRESULT hr = StartFrame::Create(hwndParent, hInstance, (Element**)&psf);
|
||
|
if (FAILED(hr))
|
||
|
return;
|
||
|
|
||
|
// Fill content of frame (using substitution)
|
||
|
Parser* pParser;
|
||
|
Parser::Create(IDR_STARTUI, hInstance, ParseError, &pParser);
|
||
|
if (!pParser)
|
||
|
return;
|
||
|
|
||
|
if (pParser->WasParseError())
|
||
|
{
|
||
|
ASSERTMSG(FALSE, "Parse error!");
|
||
|
pParser->Destroy();
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
Element* pe;
|
||
|
pParser->CreateElement(L"main", psf, &pe);
|
||
|
|
||
|
// Done with parser
|
||
|
pParser->Destroy();
|
||
|
|
||
|
// Disable Drag-drop for now.
|
||
|
BuildDropTarget( psf->GetDisplayNode(), psf->GetHWND());
|
||
|
|
||
|
psf->Populate();
|
||
|
// Set visible and host
|
||
|
psf->SetVisible(true);
|
||
|
|
||
|
RECT rect;
|
||
|
GetWindowRect(hwndParent, &rect);
|
||
|
|
||
|
psf->SetWidth(RECTWIDTH(rect));
|
||
|
psf->SetHeight(RECTHEIGHT(rect));
|
||
|
|
||
|
Element::EndDefer();
|
||
|
|
||
|
SetStartPageHWND(hDesktop, psf->GetHWND());
|
||
|
|
||
|
SetTimer(psf->GetHWND(), StartFrame::TIMER_PROGRAMS, 1 * 60 * 1000, NULL); // 1 minute
|
||
|
|
||
|
HWND hwndDesktop = GetParent(GetParent(hwndParent));
|
||
|
|
||
|
ShowWindow(hwndDesktop, SW_SHOW);
|
||
|
UpdateWindow(hwndDesktop);
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
#endif // FEATURE_STARTPAGE
|