// // Win32 window that hosts a pane on the desktop. // // You are expected to derive from this class and implement the virtual // methods. // #ifndef __SFTHOST_H__ #define __SFTHOST_H__ #include "uemapp.h" #include "runtask.h" #include "hostutil.h" #include "dobjutil.h" //**************************************************************************** // // Miscellaneous helper functions // STDAPI_(HFONT) LoadControlFont(HTHEME hTheme, int iPart, BOOL fUnderline, DWORD dwSizePercentage); STDAPI_(HRESULT) IDataObject_DragQueryFile(IDataObject *pdto, UINT iFile, LPTSTR pszBuf, UINT cch, UINT *puFiles); STDAPI_(LPITEMIDLIST) ConvertToLogIL(LPITEMIDLIST pidl); LRESULT _SendNotify(HWND hwndFrom, UINT code, OPTIONAL NMHDR *pnm = NULL); BOOL GetFileCreationTime(LPCTSTR pszFile, LPFILETIME pftCreate); /* Simple wrapper - the string needs to be freed with SHFree */ LPTSTR _DisplayNameOf(IShellFolder *psf, LPCITEMIDLIST pidl, UINT shgno); HICON _IconOf(IShellFolder *psf, LPCITEMIDLIST pidl, int cxIcon); BOOL ShowInfoTip(); //**************************************************************************** // The base class uses the following properties in the initializing // property bag: // // // "type" - type of host to use (see HOSTTYPE array) // "asyncEnum" - 1 = enumerate in background; 0 = foreground // "iconSize" - 0 = small, 1 = large // "horizontal" - 0 = vertical (default), n = horizontal // n = number of items to show class PaneItem; class PaneItem { public: PaneItem() : _iPos(-1), _iPinPos(PINPOS_UNPINNED) {} virtual ~PaneItem() { SHFree(_pszAccelerator); } static int CALLBACK DPAEnumCallback(PaneItem *self, LPVOID pData) { delete self; return TRUE; } BOOL IsPinned() const { return _iPinPos >= 0; } BOOL IsSeparator() const { return _iPinPos == PINPOS_SEPARATOR; } BOOL GetPinPos() const { return _iPinPos; } BOOL IsCascade() const { return _dwFlags & ITEMFLAG_CASCADE; } void EnableCascade() { _dwFlags |= ITEMFLAG_CASCADE; } BOOL HasSubtitle() const { return _dwFlags & ITEMFLAG_SUBTITLE; } void EnableSubtitle() { _dwFlags |= ITEMFLAG_SUBTITLE; } BOOL IsDropTarget() const { return _dwFlags & ITEMFLAG_DROPTARGET; } void EnableDropTarget() { _dwFlags |= ITEMFLAG_DROPTARGET; } BOOL HasAccelerator() { return _pszAccelerator != NULL; } virtual BOOL IsEqual(PaneItem *pItem) const { return FALSE; } enum { PINPOS_UNPINNED = -1, PINPOS_SEPARATOR = -2, }; enum { ITEMFLAG_CASCADE = 0x0001, ITEMFLAG_SUBTITLE = 0x0002, ITEMFLAG_DROPTARGET = 0x0004, }; private: friend class SFTBarHost; int _iPos; /* Position on screen (or garbage if not on screen) */ public: int _iPinPos; /* Pin position (or special PINPOS value) */ DWORD _dwFlags; /* ITEMFLAG_* values */ LPTSTR _pszAccelerator;/* Text with ampersand (for keyboard accelerator) */ }; // // Note: Since this is a base class, we can't use ATL because the base // class's CreateInstance won't know how to construct the derived classes. // class SFTBarHost : public IDropTarget , public IDropSource , public CAccessible { public: static BOOL Register(); static BOOL Unregister(); // Would normally be "protected" except that proglist.cpp actually implements // in a separate class and forwards. public: /* * Classes which derive from this class are expected to implement * the following methods. */ /* Constructor with return code */ virtual HRESULT Initialize() PURE; /* Destructor */ virtual ~SFTBarHost(); /* Enumerate the objects and call AddItem for each one you find */ // TODO: Maybe the EnumItems should be moved to a background thread virtual void EnumItems() PURE; virtual BOOL NeedBackgroundEnum() { return FALSE; } virtual BOOL HasDynamicContent() { return FALSE; } /* Compare two objects, tell me which one should come first */ virtual int CompareItems(PaneItem *p1, PaneItem *p2) PURE; /* * Given a PaneItem, produce the pidl and IShellFolder associated with it. * The IShellFolder will be Release()d when no longer needed. */ virtual HRESULT GetFolderAndPidl(PaneItem *pitem, IShellFolder **ppsfOut, LPCITEMIDLIST *ppidlOut) PURE; // An over-ridable method to add an image to our private imagelist for an item (virtual but not pure) virtual int AddImageForItem(PaneItem *pitem, IShellFolder *psf, LPCITEMIDLIST pidl, int iPos); /* * Dispatch a shell notification. Default handler ignores. */ virtual void OnChangeNotify(UINT id, LONG lEvent, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2) { } /* * Allows derived classes to control their own icon size. */ enum ICONSIZE { ICONSIZE_SMALL, // typically 16x16 ICONSIZE_LARGE, // typically 32x32 ICONSIZE_MEDIUM, // typically 24x24 }; virtual int ReadIconSize() PURE; /* * Optional hook into window procedure. * * Default behavior is just to call DefWindowProc. */ virtual LRESULT OnWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { return ::DefWindowProc(hwnd, uMsg, wParam, lParam); } /* * Required if AdjustDeleteMenuItem is customized. * Invoked when a context menu command is invoked. * Host must intercept the * "delete" command. Other commands can also be intercepted as * necessary. */ virtual HRESULT ContextMenuInvokeItem(PaneItem *pitem, IContextMenu *pcm, CMINVOKECOMMANDINFOEX *pici, LPCTSTR pszVerb); /* * Required if HOSTF_CANRENAME is passed: Invoked when an item * is renamed. * * Note: The client is allowed to change the pidl associated with an * item during a rename. (In fact, it's expected to!) So callers * which have called GetFolderAndPidl need to call it again after the * rename to get the correct post-rename pidl. */ virtual HRESULT ContextMenuRenameItem(PaneItem *pitem, LPCTSTR ptszNewName) { return E_NOTIMPL; } /* * Optional hook for obtaining the display name of an item. * The default implementation calls IShellFolder::GetDisplayNameOf. * If hooked, the returned string should be allocated by SHAlloc(). */ virtual LPTSTR DisplayNameOfItem(PaneItem *pitem, IShellFolder *psf, LPCITEMIDLIST pidlItem, SHGNO shgno) { return _DisplayNameOf(psf, pidlItem, shgno); } /* * Required if pinnned items are created. Invoked when the user moves * a pinned item. */ virtual HRESULT MovePinnedItem(PaneItem *pitem, int iInsert) { return E_NOTIMPL; } /* * Optional hook into the SMN_INITIALUPDATE notification. */ virtual void PrePopulate() { } /* * Optional handler that says whether an item is still valid. */ virtual BOOL IsItemStillValid(PaneItem *pitem) { return TRUE; } /* * Required if HOSTF_CASCADEMENU. Invoked when user wants to view * a cascaded menu. */ virtual HRESULT GetCascadeMenu(PaneItem *pitem, IShellMenu **ppsm) { return E_FAIL; } /* * Required if any items have subtitles. Returns the subtitle of the item. */ virtual LPTSTR SubtitleOfItem(PaneItem *pitem, IShellFolder *psf, LPCITEMIDLIST pidlItem) { return NULL; } /* * Optionally over-ridable method to ge the infotip for an item. Default does a GetFolderAndPidl/GetInfoTip. */ virtual void GetItemInfoTip(PaneItem *pitem, LPTSTR pszText, DWORD cch); /* * Specify whether the data object can be inserted into the pin list. * (Default: No.) */ virtual BOOL IsInsertable(IDataObject *pdto) { return FALSE; } /* * If you say that something is insertable, they you may be asked to * insert it. */ virtual HRESULT InsertPinnedItem(IDataObject *pdto, int iInsert) { ASSERT(FALSE); // You must implement this if you implement IsInsertable return E_FAIL; } /* * An over-ridable method to allow hooking into keyboard accelerators. */ virtual TCHAR GetItemAccelerator(PaneItem *pitem, int iItemStart); /* * Specify whether the item should be displayed as bold. * Default is to boldface if pinned. */ virtual BOOL IsBold(PaneItem *pitem) { return pitem->IsPinned(); } /* * Notify the client that a system imagelist index has changed. * Default is to re-extract icons for any matching listview items. */ virtual void UpdateImage(int iImage); /* * Optional method to allow clients to specify how "Delete" * should be exposed (if at all). Return 0 to disallow "Delete". * Return the string ID of the string to show for the command. * Set *puiFlags to any additional flags to pass to ModifyMenu. * Default is to disallow delete. */ virtual UINT AdjustDeleteMenuItem(PaneItem *pitem, UINT *puiFlags) { return 0; } /* * Allow client to reject/over-ride the IContextMenu on a per-item basis */ virtual HRESULT _GetUIObjectOfItem(PaneItem *pitem, REFIID riid, LPVOID *ppv); protected: /* * Classes which derive from this class may call the following * helper methods. */ /* * Add a PaneItem to the list - if add fails, item will be delete'd. * * CLEANUP psf must be NULL; pidl must be the absolute pidl to the item * being added. Leftover from dead HOSTF_PINITEMSBYFOLDER feature. * Needs to be cleaned up. * * Passing psf and pidlChild are for perf. */ BOOL AddItem(PaneItem *pitem, IShellFolder *psf, LPCITEMIDLIST pidlChild); /* * Use AddImage when you already have a HICON that needs to go to the private image list. */ int AddImage(HICON hIcon); /* * Hooking into change notifications */ enum { SFTHOST_MAXCLIENTNOTIFY = 7, // Clients get this many notifications SFTHOST_MAXHOSTNOTIFY = 1, // We use this many ourselves SFTHOST_HOSTNOTIFY_UPDATEIMAGE = SFTHOST_MAXCLIENTNOTIFY, SFTHOST_MAXNOTIFY = SFTHOST_MAXCLIENTNOTIFY + SFTHOST_MAXHOSTNOTIFY, }; BOOL RegisterNotify(UINT id, LONG lEvents, LPCITEMIDLIST pidl, BOOL fRecursive) { ASSERT(id < SFTHOST_MAXCLIENTNOTIFY); return _RegisterNotify(id, lEvents, pidl, fRecursive); } BOOL UnregisterNotify(UINT id); /* * Forcing a re-enumeration. */ void Invalidate() { _fEnumValid = FALSE; } /* * Informing host of desired size. */ void SetDesiredSize(int cPinned, int cNormal) { _cPinnedDesired = cPinned; _cNormalDesired = cNormal; } BOOL AreNonPinnedItemsDesired() { return _cNormalDesired; } void StartRefreshTimer() { SetTimer(_hwnd, IDT_REFRESH, 5000, NULL); } void ForceChange() { _fForceChange = TRUE; } protected: /* * The constructor must be marked "protected" so people can derive * from us. */ enum { HOSTF_FIREUEMEVENTS = 0x00000001, HOSTF_CANDELETE = 0x00000002, HOSTF_Unused = 0x00000004, // recycle me! HOSTF_CANRENAME = 0x00000008, HOSTF_REVALIDATE = 0x00000010, HOSTF_RELOADTEXT = 0x00000020, // requires HOSTF_REVALIDATE HOSTF_CASCADEMENU = 0x00000040, }; SFTBarHost(DWORD dwFlags = 0) : _dwFlags(dwFlags) , _lRef(1) , _iInsert(-1) , _clrBG(CLR_INVALID) , _iCascading(-1) { } enum { SFTBM_REPOPULATE = WM_USER, SFTBM_CHANGENOTIFY, SFTBM_REFRESH = SFTBM_CHANGENOTIFY + SFTHOST_MAXNOTIFY, SFTBM_CASCADE, SFTBM_ICONUPDATE, }; public: /* * Interface stuff... */ // *** IUnknown *** STDMETHODIMP QueryInterface(REFIID riid, LPVOID *ppvOut); STDMETHODIMP_(ULONG) AddRef(); STDMETHODIMP_(ULONG) Release(); // *** IDropTarget *** STDMETHODIMP DragEnter(IDataObject *pdto, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect); STDMETHODIMP DragOver(DWORD grfKeyState, POINTL pt, DWORD *pdwEffect); STDMETHODIMP DragLeave(); STDMETHODIMP Drop(IDataObject *pdto, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect); // *** IDropSource *** STDMETHODIMP GiveFeedback(DWORD dwEffect); STDMETHODIMP QueryContinueDrag(BOOL fEscapePressed, DWORD grfKeyState); // *** IAccessible overridden methods *** STDMETHODIMP get_accRole(VARIANT varChild, VARIANT *pvarRole); STDMETHODIMP get_accState(VARIANT varChild, VARIANT *pvarState); STDMETHODIMP get_accKeyboardShortcut(VARIANT varChild, BSTR *pszKeyboardShortcut); STDMETHODIMP get_accDefaultAction(VARIANT varChild, BSTR *pszDefAction); STDMETHODIMP accDoDefaultAction(VARIANT varChild); // Helpers // // It is pointless to move an object to a place adjacent to itself, // because the end result is that nothing happens. // inline IsInsertMarkPointless(int iInsert) { return _fDragToSelf && IsInRange(iInsert, _iPosDragOut, _iPosDragOut + 1); } void _PurgeDragDropData(); HRESULT _DragEnter(IDataObject *pdto, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect); HRESULT _TryInnerDropTarget(int iItem, DWORD grfKeyState, POINTL ptl, DWORD *pdwEffect); void _ClearInnerDropTarget(); void _SetDragOver(int iItem); // Insert mark stuff void _SetInsertMarkPosition(int iInsert); void _InvalidateInsertMark(); BOOL _GetInsertMarkRect(LPRECT prc); BOOL _IsInsertionMarkActive() { return _iInsert >= 0; } void _DrawInsertionMark(LPNMLVCUSTOMDRAW plvcd); /* * End of drag/drop stuff... */ private: /* * Background enumeration stuff... */ class CBGEnum : public CRunnableTask { public: CBGEnum(SFTBarHost *phost, BOOL fUrgent) : CRunnableTask(RTF_DEFAULT) , _fUrgent(fUrgent) , _phost(phost) { phost->AddRef(); } ~CBGEnum() { // We should not be the last release or else we are going to deadlock here, when _phost // tries to release the scheduler ASSERT(_phost->_lRef > 1); _phost->Release(); } STDMETHODIMP RunInitRT() { _phost->_EnumerateContentsBackground(); if (_phost->_hwnd) PostMessage(_phost->_hwnd, SFTBM_REPOPULATE, _fUrgent, 0); return S_OK; } private: SFTBarHost *_phost; BOOL _fUrgent; }; friend class SFTBarHost::CBGEnum; private: /* Window procedure helpers */ static LRESULT CALLBACK _WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); static LRESULT _OnNcCreate(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); LRESULT _OnCreate(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); LRESULT _OnDestroy(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); LRESULT _OnNcDestroy(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); LRESULT _OnNotify(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); LRESULT _OnSize(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); LRESULT _OnContextMenu(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); LRESULT _OnCtlColorStatic(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); LRESULT _OnMenuMessage(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); LRESULT _OnEraseBackground(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); LRESULT _OnTimer(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); LRESULT _OnSetFocus(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); LRESULT _OnSysColorChange(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); LRESULT _OnForwardMessage(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); LRESULT _OnUpdateUIState(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); LRESULT _OnRepopulate(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); LRESULT _OnChangeNotify(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); LRESULT _OnRefresh(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); LRESULT _OnCascade(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); LRESULT _OnIconUpdate(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); LRESULT _OnLVCustomDraw(LPNMLVCUSTOMDRAW plvcd); LRESULT _OnLVNItemActivate(LPNMITEMACTIVATE pnmia); LRESULT _OnLVNGetInfoTip(LPNMLVGETINFOTIP plvn); LRESULT _OnLVNGetEmptyText(NMLVDISPINFO *plvdi); LRESULT _OnLVNBeginDrag(LPNMLISTVIEW plv); LRESULT _OnLVNBeginLabelEdit(NMLVDISPINFO *pldvi); LRESULT _OnLVNEndLabelEdit(NMLVDISPINFO *pldvi); LRESULT _OnLVNKeyDown(LPNMLVKEYDOWN pkd); LRESULT _OnSMNGetMinSize(PSMNGETMINSIZE pgms); LRESULT _OnSMNFindItem(PSMNDIALOGMESSAGE pdm); LRESULT _OnSMNFindItemWorker(PSMNDIALOGMESSAGE pdm); LRESULT _OnSMNDismiss(); LRESULT _OnHover(); /* Custom draw helpers */ LRESULT _OnLVPrePaint(LPNMLVCUSTOMDRAW plvcd); LRESULT _OnLVItemPrePaint(LPNMLVCUSTOMDRAW plvcd); LRESULT _OnLVSubItemPrePaint(LPNMLVCUSTOMDRAW plvcd); LRESULT _OnLVItemPostPaint(LPNMLVCUSTOMDRAW plvcd); LRESULT _OnLVPostPaint(LPNMLVCUSTOMDRAW plvcd); /* Custom draw push/pop */ void _CustomDrawPush(BOOL fReal); BOOL _IsRealCustomDraw(); void _CustomDrawPop(); static LRESULT CALLBACK s_DropTargetSubclassProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData); /* Other helpers */ void _SetMaxShow(int cx, int cy); void _EnumerateContents(BOOL fUrgent); void _EnumerateContentsBackground(); void _RevalidateItems(); void _RevalidatePostPopup(); void _ReloadText(); static int CALLBACK _SortItemsAfterEnum(PaneItem *p1, PaneItem *p2, SFTBarHost *self); void _RepopulateList(); void _InternalRepopulateList(); int _InsertListViewItem(int iPos, PaneItem *pitem); void _ComputeListViewItemPosition(int iItem, POINT *pptOut); int _AppendEnumPaneItem(PaneItem *pitem); void _RepositionItems(); void _ComputeTileMetrics(); void _SetTileWidth(int cxTile); BOOL _CreateMarlett(); void _CreateBoldFont(); int _GetLVCurSel() { return ListView_GetNextItem(_hwndList, -1, LVNI_FOCUSED); } BOOL _OnCascade(int iItem, DWORD dwFlags); BOOL _IsPrivateImageList() const { return _iconsize == ICONSIZE_MEDIUM; } BOOL _CanHaveSubtitles() const { return _iconsize == ICONSIZE_LARGE; } int _ExtractImageForItem(PaneItem *pitem, IShellFolder *psf, LPCITEMIDLIST pidl); void _ClearListView(); void _EditLabel(int iItem); BOOL _RegisterNotify(UINT id, LONG lEvents, LPCITEMIDLIST pidl, BOOL fRecursive); void _OnUpdateImage(LPCITEMIDLIST pidl, LPCITEMIDLIST pidlExtra); /* Returns E_FAIL for separators; otherwise calls client */ HRESULT _GetFolderAndPidl(PaneItem *pitem, IShellFolder **ppsfOut, LPCITEMIDLIST *ppidlOut); /* Simple wrappers - the string needs to be freed with SHFree */ LPTSTR _DisplayNameOfItem(PaneItem *pitem, UINT shgno); HRESULT _GetUIObjectOfItem(int iItem, REFIID riid, LPVOID *ppv); inline PaneItem *_GetItemFromLVLParam(LPARAM lParam) { return reinterpret_cast(lParam); } PaneItem *_GetItemFromLV(int iItem); enum { AIF_KEYBOARD = 1, }; int _ContextMenuCoordsToItem(LPARAM lParam, POINT *pptOut); LRESULT _ActivateItem(int iItem, DWORD dwFlags); // AIF_* values HRESULT _InvokeDefaultCommand(int iItem, IShellFolder *psf, LPCITEMIDLIST pidl); void _OfferDeleteBrokenItem(PaneItem *pitem, IShellFolder *psf, LPCITEMIDLIST pidl); // If you hover the mouse for this much time, we will open it if it // cascades. This is the same value that USER uses for auto-cascading // menus. DWORD _GetCascadeHoverTime() { return GetDoubleClickTime() * 4 / 5; } static void CALLBACK SetIconAsync(LPCITEMIDLIST pidl, LPVOID pvData, LPVOID pvHint, INT iIconIndex, INT iOpenIconIndex); /* * Custom commands we add to the context menu. */ enum { IDM_REMOVEFROMLIST = 1, // Insert private menu items here // range used for client QueryContextMenu IDM_QCM_MIN = 0x0100, IDM_QCM_MAX = 0x7000, }; /* * Timer IDs */ enum { IDT_ASYNCENUM = 1, IDT_RELOADTEXT = 2, IDT_REFRESH = 3, }; /* * Miscellaneous settings. */ enum { MAX_SEPARATORS = 3, /* Maximum number of separators allowed */ }; /* * Pinning helpers... */ BOOL NeedSeparator() const { return _cPinned; } BOOL _HasSeparators() const { return _rgiSep[0] >= 0; } void _DrawSeparator(HDC hdc, int x, int y); void _DrawSeparators(LPNMLVCUSTOMDRAW plvcd); /* * Bookkeeping. */ int _PosToItemNo(int iPos); int _ItemNoToPos(int iItem); /* * Accessibility helpers... */ PaneItem *_GetItemFromAccessibility(const VARIANT& varChild); /* * Debugging helpers... */ #if defined(DEBUG) && defined(FULL_DEBUG) void _DebugConsistencyCheck(); #else inline void _DebugConsistencyCheck() { } #endif BOOL _AreChangesRestricted() { return (IsRestrictedOrUserSetting(HKEY_CURRENT_USER, REST_NOCHANGESTARMENU, TEXT("Advanced"), TEXT("Start_EnableDragDrop"), ROUS_DEFAULTALLOW | ROUS_KEYALLOWS)); } protected: HTHEME _hTheme; // theme handle, can be NULL int _iThemePart; // SPP_PROGLIST SPP_PLACESLIST int _iThemePartSep; // theme part for the separator HWND _hwnd; /* Our window handle */ HIMAGELIST _himl; // Imagelist handle int _cxIcon; /* Icon size for imagelist */ int _cyIcon; /* Icon size for imagelist */ ICONSIZE _iconsize; /* ICONSIZE_* value */ private: HWND _hwndList; /* Handle of inner listview */ MARGINS _margins; // margins for children (listview and oobe static) valid in theme and non-theme case int _cPinned; /* Number of those items that are pinned */ DWORD _dwFlags; /* Misc flags that derived classes can set */ // _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 _dpaEnum; CDPA _dpaEnumNew; // Used during background enumerations int _rgiSep[MAX_SEPARATORS]; /* Only _cSep elements are meaningful */ int _cSep; /* Number of separators */ // // Context menu handling // IContextMenu2 * _pcm2Pop; /* Currently popped-up context menu */ IContextMenu3 * _pcm3Pop; /* Currently popped-up context menu */ IDropTargetHelper * _pdth; /* For cool-looking drag/drop */ IDragSourceHelper * _pdsh; /* For cool-looking drag/drop */ IDataObject * _pdtoDragOut; /* Data object being dragged out */ IDataObject * _pdtoDragIn; /* Data object being dragged in */ IDropTarget * _pdtDragOver; /* Object being dragged over (if any) */ IShellTaskScheduler * _psched; /* Task scheduler */ int _iDragOut; /* The item being dragged out (-1 if none) */ int _iPosDragOut; /* The position of item _iDragOut */ int _iDragOver; /* The item being dragged over (-1 if none) */ DWORD _tmDragOver; /* Time the dragover started (to see if we need to auto-open) */ int _iInsert; /* Where the insert mark should be drawn (-1 if none) */ BOOL _fForceArrowCursor; /* Should we force a regular cursor during drag/drop? */ BOOL _fDragToSelf; /* Are we dragging an object to ourselves? */ BOOL _fInsertable; /* Is item being dragged pinnable? */ DWORD _grfKeyStateLast; /* Last grfKeyState passed to DragOver */ int _cyTile; /* Height of a tile */ int _cxTile; /* Width of a tile */ int _cyTilePadding; /* Extra vertical space between tiles */ int _cySepTile; /* Height of a separator tile */ int _cySep; /* Height of a separator line */ int _cxMargin; /* Left margin */ int _cyMargin; /* Top margin */ int _cxIndent; /* So bonus texts line up with listview text */ COLORREF _clrBG; /* Color for background */ COLORREF _clrHot; /* Color for hot text*/ COLORREF _clrSubtitle; /* Color for subtitle text*/ LONG _lRef; /* Reference count */ BOOL _fBGTask; /* Is a background task already scheduled? */ BOOL _fRestartEnum; /* Should in-progress enumeration be restarted? */ BOOL _fRestartUrgent;/* Is the _fRestartEnum urgent? */ BOOL _fEnumValid; /* Is the list of items all fine? */ BOOL _fNeedsRepopulate; /* Do we need to call _RepopulateList ? */ BOOL _fForceChange; /* Should we act as if there was a change even if there didn't seem to be one? */ ULONG _rguChangeNotify[SFTHOST_MAXNOTIFY]; /* Outstanding change notification (if any) */ BOOL _fAllowEditLabel; /* Is this an approved label-editing state? */ HFONT _hfList; /* Custom listview font (if required) */ HFONT _hfBold; /* Bold listview font (if required) */ HFONT _hfMarlett; /* Marlett font (if required) */ int _cxMarlett; /* Width of the menu cascade glyph */ int _tmAscentMarlett; /* Font ascent for Marlett */ HWND _hwndAni; /* Handle of flashlight animation, if present */ UINT _idtAni; /* Animation timer handle */ HBRUSH _hBrushAni; /* Background brush for the Ani window */ int _cPinnedDesired;/* SetDesiredSize */ int _cNormalDesired;/* SetDesiredSize */ int _iCascading; /* Which item is the cascade menu appearing over? */ DWORD _dwCustomDrawState; /* Keeps track of whether customdraw is real or fake */ int _cPaint; /* How many (nested) paint messages are we handling? */ #ifdef DEBUG BOOL _fEnumerating; /* Are we enumerating client items? */ BOOL _fPopulating; /* Are we populating the listview? */ BOOL _fListUnstable; /* The listview is unstable; don't get upset */ // // To verify that we manage the inner drop target correctly. // enum { DRAGSTATE_UNINITIALIZED = 0, DRAGSTATE_ENTERED = 1, }; int _iDragState; /* for debugging */ #endif /* Large structures go at the end */ }; _inline SMPANEDATA* PaneDataFromCreateStruct(LPARAM lParam) { LPCREATESTRUCT lpcs = reinterpret_cast(lParam); return reinterpret_cast(lpcs->lpCreateParams); } //**************************************************************************** // // Helper functions for messing with UEM info // void _GetUEMInfo(const GUID *pguidGrp, int eCmd, WPARAM wParam, LPARAM lParam, UEMINFO *pueiOut); #define _GetUEMPidlInfo(psf, pidl, pueiOut) \ _GetUEMInfo(&UEMIID_SHELL, UEME_RUNPIDL, \ reinterpret_cast(psf), \ reinterpret_cast(pidl), pueiOut) #define _GetUEMPathInfo(pszPath, pueiOut) \ _GetUEMInfo(&UEMIID_SHELL, UEME_RUNPATH, (WPARAM)-1, \ reinterpret_cast(pszPath), pueiOut) #define _SetUEMPidlInfo(psf, pidl, pueiInOut) \ UEMSetEvent(&UEMIID_SHELL, UEME_RUNPIDL, \ reinterpret_cast(psf), \ reinterpret_cast(pidl), pueiInOut) #define _SetUEMPathInfo(pszPath, pueiInOut) \ UEMSetEvent(&UEMIID_SHELL, UEME_RUNPATH, (WPARAM)-1, \ reinterpret_cast(pszPath), pueiInOut) // SOMEDAY: Figure out what UEMF_XEVENT means. I just stole the code // from startmnu.cpp. #define _FireUEMPidlEvent(psf, pidl) \ UEMFireEvent(&UEMIID_SHELL, UEME_RUNPIDL, UEMF_XEVENT, \ reinterpret_cast(psf), \ reinterpret_cast(pidl)) //**************************************************************************** // // Constructors for derived classes // typedef SFTBarHost *(CALLBACK *PFNHOSTCONSTRUCTOR)(void); STDAPI_(SFTBarHost *) ByUsage_CreateInstance(); STDAPI_(SFTBarHost *) SpecList_CreateInstance(); STDAPI_(SFTBarHost *) RecentDocs_CreateInstance(); #define RECTWIDTH(rc) ((rc).right-(rc).left) #define RECTHEIGHT(rc) ((rc).bottom-(rc).top) #endif // __SFTHOST_H__