ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

shlview.cpp
Go to the documentation of this file.
00001 /*
00002  *    ShellView
00003  *
00004  *    Copyright 1998,1999    <juergen.schmied@debitel.net>
00005  *
00006  * This is the view visualizing the data provided by the shellfolder.
00007  * No direct access to data from pidls should be done from here.
00008  *
00009  * This library is free software; you can redistribute it and/or
00010  * modify it under the terms of the GNU Lesser General Public
00011  * License as published by the Free Software Foundation; either
00012  * version 2.1 of the License, or (at your option) any later version.
00013  *
00014  * This library is distributed in the hope that it will be useful,
00015  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00017  * Lesser General Public License for more details.
00018  *
00019  * You should have received a copy of the GNU Lesser General Public
00020  * License along with this library; if not, write to the Free Software
00021  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
00022  *
00023  * FIXME: The order by part of the background context menu should be
00024  * built according to the columns shown.
00025  *
00026  * FIXME: CheckToolbar: handle the "new folder" and "folder up" button
00027  *
00028  * FIXME: ShellView_FillList: consider sort orders
00029  */
00030 
00031 /*
00032 TODO:
00033 1. Load/Save the view state from/into the stream provided by the ShellBrowser.
00034 2. Let the shell folder sort items.
00035 3. Code to merge menus in the shellbrowser is incorrect.
00036 4. Move the background context menu creation into shell view. It should store the
00037     shell view HWND to send commands.
00038 5. Send init, measure, and draw messages to context menu during tracking.
00039 6. Shell view should do SetCommandTarget on internet toolbar.
00040 7. When editing starts on item, set edit text to for editing value.
00041 8. When shell view is called back for item info, let listview save the value.
00042 9. Shell view should update status bar.
00043 10. Fix shell view to handle view mode popup exec.
00044 11. The background context menu should have a pidl just like foreground menus. This
00045     causes crashes when dynamic handlers try to use the NULL pidl.
00046 12. The SHELLDLL_DefView should not be filled with blue unconditionally. This causes
00047     annoying flashing of blue even on XP, and is not correct.
00048 13. Reorder of columns doesn't work - might be bug in comctl32
00049 */
00050 
00051 #include <precomp.h>
00052 
00053 WINE_DEFAULT_DEBUG_CHANNEL(shell);
00054 
00055 #undef SV_CLASS_NAME
00056 
00057 static const WCHAR SV_CLASS_NAME[] = {'S', 'H', 'E', 'L', 'L', 'D', 'L', 'L', '_', 'D', 'e', 'f', 'V', 'i', 'e', 'w', 0};
00058 
00059 typedef struct
00060 {   BOOL    bIsAscending;
00061     INT     nHeaderID;
00062     INT     nLastHeaderID;
00063 } LISTVIEW_SORT_INFO, *LPLISTVIEW_SORT_INFO;
00064 
00065 #define SHV_CHANGE_NOTIFY WM_USER + 0x1111
00066 
00067 class CDefView :
00068     public CWindowImpl<CDefView, CWindow, CControlWinTraits>,
00069     public CComObjectRootEx<CComMultiThreadModelNoCS>,
00070     public IShellView,
00071     public IFolderView,
00072     public IOleCommandTarget,
00073     public IDropTarget,
00074     public IDropSource,
00075     public IViewObject,
00076     public IServiceProvider
00077 {
00078     private:
00079         CComPtr<IShellFolder>                pSFParent;
00080         CComPtr<IShellFolder2>                pSF2Parent;
00081         CComPtr<IShellBrowser>                pShellBrowser;
00082         CComPtr<ICommDlgBrowser>            pCommDlgBrowser;
00083         HWND                                hWndList;            /* ListView control */
00084         HWND                                hWndParent;
00085         FOLDERSETTINGS                        FolderSettings;
00086         HMENU                                hMenu;
00087         UINT                                uState;
00088         UINT                                cidl;
00089         LPITEMIDLIST                        *apidl;
00090         LISTVIEW_SORT_INFO                    ListViewSortInfo;
00091         ULONG                                hNotify;            /* change notification handle */
00092         HANDLE                                hAccel;
00093         DWORD                                dwAspects;
00094         DWORD                                dwAdvf;
00095         CComPtr<IAdviseSink>                pAdvSink;
00096         // for drag and drop
00097         CComPtr<IDropTarget>                pCurDropTarget;        /* The sub-item, which is currently dragged over */
00098         CComPtr<IDataObject>                pCurDataObject;        /* The dragged data-object */
00099         LONG                                iDragOverItem;        /* Dragged over item's index, iff pCurDropTarget != NULL */
00100         UINT                                cScrollDelay;        /* Send a WM_*SCROLL msg every 250 ms during drag-scroll */
00101         POINT                                ptLastMousePos;        /* Mouse position at last DragOver call */
00102         //
00103         CComPtr<IContextMenu2>                pCM;
00104     public:
00105         CDefView();
00106         ~CDefView();
00107         HRESULT WINAPI Initialize(IShellFolder *shellFolder);
00108         HRESULT IncludeObject(LPCITEMIDLIST pidl);
00109         HRESULT OnDefaultCommand();
00110         HRESULT OnStateChange(UINT uFlags);
00111         void CheckToolbar();
00112         void SetStyle(DWORD dwAdd, DWORD dwRemove);
00113         BOOL CreateList();
00114         void UpdateListColors();
00115         BOOL InitList();
00116         static INT CALLBACK CompareItems(LPVOID lParam1, LPVOID lParam2, LPARAM lpData);
00117         static INT CALLBACK ListViewCompareItems(LPVOID lParam1, LPVOID lParam2, LPARAM lpData);
00118         int LV_FindItemByPidl(LPCITEMIDLIST pidl);
00119         BOOLEAN LV_AddItem(LPCITEMIDLIST pidl);
00120         BOOLEAN LV_DeleteItem(LPCITEMIDLIST pidl);
00121         BOOLEAN LV_RenameItem(LPCITEMIDLIST pidlOld, LPCITEMIDLIST pidlNew);
00122         static INT CALLBACK fill_list(LPVOID ptr, LPVOID arg);
00123         HRESULT FillList();
00124         HMENU BuildFileMenu();
00125         void MergeFileMenu(HMENU hSubMenu);
00126         void MergeViewMenu(HMENU hSubMenu);
00127         UINT GetSelections();
00128         HRESULT OpenSelectedItems();
00129         void OnDeactivate();
00130         void DoActivate(UINT uState);
00131         HRESULT drag_notify_subitem(DWORD grfKeyState, POINTL pt, DWORD *pdwEffect);
00132 
00133         // *** IOleWindow methods ***
00134         virtual HRESULT STDMETHODCALLTYPE GetWindow(HWND *lphwnd);
00135         virtual HRESULT STDMETHODCALLTYPE ContextSensitiveHelp(BOOL fEnterMode);
00136 
00137         // *** IShellView methods ***
00138         virtual HRESULT STDMETHODCALLTYPE TranslateAccelerator(MSG *pmsg);
00139         virtual HRESULT STDMETHODCALLTYPE EnableModeless(BOOL fEnable);
00140         virtual HRESULT STDMETHODCALLTYPE UIActivate(UINT uState);
00141         virtual HRESULT STDMETHODCALLTYPE Refresh();
00142         virtual HRESULT STDMETHODCALLTYPE CreateViewWindow(IShellView *psvPrevious, LPCFOLDERSETTINGS pfs, IShellBrowser *psb, RECT *prcView, HWND *phWnd);
00143         virtual HRESULT STDMETHODCALLTYPE DestroyViewWindow();
00144         virtual HRESULT STDMETHODCALLTYPE GetCurrentInfo(LPFOLDERSETTINGS pfs);
00145         virtual HRESULT STDMETHODCALLTYPE AddPropertySheetPages(DWORD dwReserved, LPFNSVADDPROPSHEETPAGE pfn, LPARAM lparam);
00146         virtual HRESULT STDMETHODCALLTYPE SaveViewState();
00147         virtual HRESULT STDMETHODCALLTYPE SelectItem(LPCITEMIDLIST pidlItem, SVSIF uFlags);
00148         virtual HRESULT STDMETHODCALLTYPE GetItemObject(UINT uItem, REFIID riid, void **ppv);
00149 
00150         // *** IFolderView methods ***
00151         virtual HRESULT STDMETHODCALLTYPE GetCurrentViewMode(UINT *pViewMode);
00152         virtual HRESULT STDMETHODCALLTYPE SetCurrentViewMode(UINT ViewMode);
00153         virtual HRESULT STDMETHODCALLTYPE GetFolder(REFIID riid, void **ppv);
00154         virtual HRESULT STDMETHODCALLTYPE Item(int iItemIndex, LPITEMIDLIST *ppidl);
00155         virtual HRESULT STDMETHODCALLTYPE ItemCount(UINT uFlags, int *pcItems);
00156         virtual HRESULT STDMETHODCALLTYPE Items(UINT uFlags, REFIID riid, void **ppv);
00157         virtual HRESULT STDMETHODCALLTYPE GetSelectionMarkedItem(int *piItem);
00158         virtual HRESULT STDMETHODCALLTYPE GetFocusedItem(int *piItem);
00159         virtual HRESULT STDMETHODCALLTYPE GetItemPosition(LPCITEMIDLIST pidl, POINT *ppt);
00160         virtual HRESULT STDMETHODCALLTYPE GetSpacing(POINT *ppt);
00161         virtual HRESULT STDMETHODCALLTYPE GetDefaultSpacing(POINT *ppt);
00162         virtual HRESULT STDMETHODCALLTYPE GetAutoArrange();
00163         virtual HRESULT STDMETHODCALLTYPE SelectItem(int iItem, DWORD dwFlags);
00164         virtual HRESULT STDMETHODCALLTYPE SelectAndPositionItems(UINT cidl, LPCITEMIDLIST *apidl, POINT *apt, DWORD dwFlags);
00165 
00166         // *** IOleCommandTarget methods ***
00167         virtual HRESULT STDMETHODCALLTYPE QueryStatus(const GUID *pguidCmdGroup, ULONG cCmds, OLECMD prgCmds[  ], OLECMDTEXT *pCmdText);
00168         virtual HRESULT STDMETHODCALLTYPE Exec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut);
00169 
00170         // *** IDropTarget methods ***
00171         virtual HRESULT STDMETHODCALLTYPE DragEnter(IDataObject *pDataObj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect);
00172         virtual HRESULT STDMETHODCALLTYPE DragOver(DWORD grfKeyState, POINTL pt, DWORD *pdwEffect);
00173         virtual HRESULT STDMETHODCALLTYPE DragLeave();
00174         virtual HRESULT STDMETHODCALLTYPE Drop(IDataObject *pDataObj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect);
00175 
00176         // *** IDropSource methods ***
00177         virtual HRESULT STDMETHODCALLTYPE QueryContinueDrag(BOOL fEscapePressed, DWORD grfKeyState);
00178         virtual HRESULT STDMETHODCALLTYPE GiveFeedback(DWORD dwEffect);
00179 
00180         // *** IViewObject methods ***
00181         virtual HRESULT STDMETHODCALLTYPE Draw(DWORD dwDrawAspect, LONG lindex, void *pvAspect, DVTARGETDEVICE *ptd,
00182                                                HDC hdcTargetDev, HDC hdcDraw, LPCRECTL lprcBounds, LPCRECTL lprcWBounds,
00183                                                BOOL ( STDMETHODCALLTYPE *pfnContinue )(ULONG_PTR dwContinue), ULONG_PTR dwContinue);
00184         virtual HRESULT STDMETHODCALLTYPE GetColorSet(DWORD dwDrawAspect, LONG lindex, void *pvAspect,
00185                 DVTARGETDEVICE *ptd, HDC hicTargetDev, LOGPALETTE **ppColorSet);
00186         virtual HRESULT STDMETHODCALLTYPE Freeze(DWORD dwDrawAspect, LONG lindex, void *pvAspect, DWORD *pdwFreeze);
00187         virtual HRESULT STDMETHODCALLTYPE Unfreeze(DWORD dwFreeze);
00188         virtual HRESULT STDMETHODCALLTYPE SetAdvise(DWORD aspects, DWORD advf, IAdviseSink *pAdvSink);
00189         virtual HRESULT STDMETHODCALLTYPE GetAdvise(DWORD *pAspects, DWORD *pAdvf, IAdviseSink **ppAdvSink);
00190 
00191         // *** IServiceProvider methods ***
00192         virtual HRESULT STDMETHODCALLTYPE QueryService(REFGUID guidService, REFIID riid, void **ppvObject);
00193 
00194         // message handlers
00195         LRESULT OnShowWindow(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
00196         LRESULT OnGetDlgCode(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
00197         LRESULT OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
00198         LRESULT OnEraseBackground(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
00199         LRESULT OnSysColorChange(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
00200         LRESULT OnGetShellBrowser(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
00201         LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
00202         LRESULT OnContextMenu(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
00203         LRESULT OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
00204         LRESULT OnActivate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
00205         LRESULT OnSetFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
00206         LRESULT OnKillFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
00207         LRESULT OnCommand(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
00208         LRESULT OnNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
00209         LRESULT OnChangeNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
00210         LRESULT OnCustomItem(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
00211         LRESULT OnSettingChange(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
00212 
00213         static ATL::CWndClassInfo& GetWndClassInfo()
00214         {
00215             static ATL::CWndClassInfo wc =
00216             {
00217                 {   sizeof(WNDCLASSEX), 0, StartWindowProc,
00218                     0, 0, NULL, NULL,
00219                     LoadCursor(NULL, IDC_ARROW), (HBRUSH)(COLOR_BACKGROUND + 1), NULL, SV_CLASS_NAME, NULL
00220                 },
00221                 NULL, NULL, IDC_ARROW, TRUE, 0, _T("")
00222             };
00223             return wc;
00224         }
00225 
00226         virtual WNDPROC GetWindowProc()
00227         {
00228             return WindowProc;
00229         }
00230 
00231         static LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
00232         {
00233             CDefView                        *pThis;
00234             LRESULT                            result;
00235 
00236             // must hold a reference during message handling
00237             pThis = reinterpret_cast<CDefView *>(hWnd);
00238             pThis->AddRef();
00239             result = CWindowImpl<CDefView, CWindow, CControlWinTraits>::WindowProc(hWnd, uMsg, wParam, lParam);
00240             pThis->Release();
00241             return result;
00242         }
00243 
00244         BEGIN_MSG_MAP(CDefView)
00245         MESSAGE_HANDLER(WM_SIZE, OnSize)
00246         MESSAGE_HANDLER(WM_SETFOCUS, OnSetFocus)
00247         MESSAGE_HANDLER(WM_KILLFOCUS, OnKillFocus)
00248         MESSAGE_HANDLER(WM_CREATE, OnCreate)
00249         MESSAGE_HANDLER(WM_ACTIVATE, OnActivate)
00250         MESSAGE_HANDLER(WM_NOTIFY, OnNotify)
00251         MESSAGE_HANDLER(WM_COMMAND, OnCommand)
00252         MESSAGE_HANDLER(SHV_CHANGE_NOTIFY, OnChangeNotify)
00253         MESSAGE_HANDLER(WM_CONTEXTMENU, OnContextMenu)
00254         MESSAGE_HANDLER(WM_DRAWITEM, OnCustomItem)
00255         MESSAGE_HANDLER(WM_MEASUREITEM, OnCustomItem)
00256         MESSAGE_HANDLER(WM_SHOWWINDOW, OnShowWindow)
00257         MESSAGE_HANDLER(WM_GETDLGCODE, OnGetDlgCode)
00258         MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
00259         MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBackground)
00260         MESSAGE_HANDLER(WM_SYSCOLORCHANGE, OnSysColorChange)
00261         MESSAGE_HANDLER(CWM_GETISHELLBROWSER, OnGetShellBrowser)
00262         MESSAGE_HANDLER(WM_SETTINGCHANGE, OnSettingChange)
00263         END_MSG_MAP()
00264 
00265         BEGIN_COM_MAP(CDefView)
00266         COM_INTERFACE_ENTRY_IID(IID_IOleWindow, IOleWindow)
00267         COM_INTERFACE_ENTRY_IID(IID_IShellView, IShellView)
00268         COM_INTERFACE_ENTRY_IID(IID_IFolderView, IFolderView)
00269         COM_INTERFACE_ENTRY_IID(IID_IOleCommandTarget, IOleCommandTarget)
00270         COM_INTERFACE_ENTRY_IID(IID_IDropTarget, IDropTarget)
00271         COM_INTERFACE_ENTRY_IID(IID_IDropSource, IDropSource)
00272         COM_INTERFACE_ENTRY_IID(IID_IViewObject, IViewObject)
00273         COM_INTERFACE_ENTRY_IID(IID_IServiceProvider, IServiceProvider)
00274         END_COM_MAP()
00275 };
00276 
00277 /* ListView Header ID's */
00278 #define LISTVIEW_COLUMN_NAME 0
00279 #define LISTVIEW_COLUMN_SIZE 1
00280 #define LISTVIEW_COLUMN_TYPE 2
00281 #define LISTVIEW_COLUMN_TIME 3
00282 #define LISTVIEW_COLUMN_ATTRIB 4
00283 
00284 /*menu items */
00285 #define IDM_VIEW_FILES  (FCIDM_SHVIEWFIRST + 0x500)
00286 #define IDM_VIEW_IDW    (FCIDM_SHVIEWFIRST + 0x501)
00287 #define IDM_MYFILEITEM  (FCIDM_SHVIEWFIRST + 0x502)
00288 
00289 #define ID_LISTVIEW     1
00290 
00291 /*windowsx.h */
00292 #define GET_WM_COMMAND_ID(wp, lp)               LOWORD(wp)
00293 #define GET_WM_COMMAND_HWND(wp, lp)             (HWND)(lp)
00294 #define GET_WM_COMMAND_CMD(wp, lp)              HIWORD(wp)
00295 
00296 /*
00297   Items merged into the toolbar and the filemenu
00298 */
00299 typedef struct
00300 {   int   idCommand;
00301     int   iImage;
00302     int   idButtonString;
00303     int   idMenuString;
00304     BYTE  bState;
00305     BYTE  bStyle;
00306 } MYTOOLINFO, *LPMYTOOLINFO;
00307 
00308 static const MYTOOLINFO Tools[] =
00309 {
00310     { FCIDM_SHVIEW_BIGICON,    0, 0, IDS_VIEW_LARGE,   TBSTATE_ENABLED, BTNS_BUTTON },
00311     { FCIDM_SHVIEW_SMALLICON,  0, 0, IDS_VIEW_SMALL,   TBSTATE_ENABLED, BTNS_BUTTON },
00312     { FCIDM_SHVIEW_LISTVIEW,   0, 0, IDS_VIEW_LIST,    TBSTATE_ENABLED, BTNS_BUTTON },
00313     { FCIDM_SHVIEW_REPORTVIEW, 0, 0, IDS_VIEW_DETAILS, TBSTATE_ENABLED, BTNS_BUTTON },
00314     { -1, 0, 0, 0, 0, 0}
00315 };
00316 
00317 typedef void (CALLBACK *PFNSHGETSETTINGSPROC)(LPSHELLFLAGSTATE lpsfs, DWORD dwMask);
00318 
00319 CDefView::CDefView()
00320 {
00321     hWndList = NULL;
00322     hWndParent = NULL;
00323     FolderSettings.fFlags = 0;
00324     FolderSettings.ViewMode = 0;
00325     hMenu = NULL;
00326     uState = 0;
00327     cidl = 0;
00328     apidl = NULL;
00329     ListViewSortInfo.bIsAscending = FALSE;
00330     ListViewSortInfo.nHeaderID = 0;
00331     ListViewSortInfo.nLastHeaderID = 0;
00332     hNotify = 0;
00333     hAccel = NULL;
00334     dwAspects = 0;
00335     dwAdvf = 0;
00336     iDragOverItem = 0;
00337     cScrollDelay = 0;
00338     ptLastMousePos.x = 0;
00339     ptLastMousePos.y = 0;
00340 }
00341 
00342 CDefView::~CDefView()
00343 {
00344     TRACE(" destroying IShellView(%p)\n", this);
00345 
00346     SHFree(apidl);
00347 }
00348 
00349 HRESULT WINAPI CDefView::Initialize(IShellFolder *shellFolder)
00350 {
00351     pSFParent = shellFolder;
00352     shellFolder->QueryInterface(IID_IShellFolder2, (LPVOID *)&pSF2Parent);
00353 
00354     return S_OK;
00355 }
00356 
00357 /**********************************************************
00358  *
00359  * ##### helperfunctions for communication with ICommDlgBrowser #####
00360  */
00361 HRESULT CDefView::IncludeObject(LPCITEMIDLIST pidl)
00362 {
00363     HRESULT ret = S_OK;
00364 
00365     if (pCommDlgBrowser.p != NULL)
00366     {
00367         TRACE("ICommDlgBrowser::IncludeObject pidl=%p\n", pidl);
00368         ret = pCommDlgBrowser->IncludeObject((IShellView *)this, pidl);
00369         TRACE("--0x%08x\n", ret);
00370     }
00371 
00372     return ret;
00373 }
00374 
00375 HRESULT CDefView::OnDefaultCommand()
00376 {
00377     HRESULT ret = S_FALSE;
00378 
00379     if (pCommDlgBrowser.p != NULL)
00380     {
00381         TRACE("ICommDlgBrowser::OnDefaultCommand\n");
00382         ret = pCommDlgBrowser->OnDefaultCommand((IShellView *)this);
00383         TRACE("-- returns %08x\n", ret);
00384     }
00385 
00386     return ret;
00387 }
00388 
00389 HRESULT CDefView::OnStateChange(UINT uFlags)
00390 {
00391     HRESULT ret = S_FALSE;
00392 
00393     if (pCommDlgBrowser.p != NULL)
00394     {
00395         TRACE("ICommDlgBrowser::OnStateChange flags=%x\n", uFlags);
00396         ret = pCommDlgBrowser->OnStateChange((IShellView *)this, uFlags);
00397         TRACE("--\n");
00398     }
00399 
00400     return ret;
00401 }
00402 /**********************************************************
00403  *    set the toolbar of the filedialog buttons
00404  *
00405  * - activates the buttons from the shellbrowser according to
00406  *   the view state
00407  */
00408 void CDefView::CheckToolbar()
00409 {
00410     LRESULT result;
00411 
00412     TRACE("\n");
00413 
00414     if (pCommDlgBrowser != NULL)
00415     {
00416         pShellBrowser->SendControlMsg(FCW_TOOLBAR, TB_CHECKBUTTON,
00417                                       FCIDM_TB_SMALLICON, (FolderSettings.ViewMode == FVM_LIST) ? TRUE : FALSE, &result);
00418         pShellBrowser->SendControlMsg(FCW_TOOLBAR, TB_CHECKBUTTON,
00419                                       FCIDM_TB_REPORTVIEW, (FolderSettings.ViewMode == FVM_DETAILS) ? TRUE : FALSE, &result);
00420         pShellBrowser->SendControlMsg(FCW_TOOLBAR, TB_ENABLEBUTTON,
00421                                       FCIDM_TB_SMALLICON, TRUE, &result);
00422         pShellBrowser->SendControlMsg(FCW_TOOLBAR, TB_ENABLEBUTTON,
00423                                       FCIDM_TB_REPORTVIEW, TRUE, &result);
00424     }
00425 }
00426 
00427 /**********************************************************
00428  *
00429  * ##### helperfunctions for initializing the view #####
00430  */
00431 /**********************************************************
00432  *    change the style of the listview control
00433  */
00434 void CDefView::SetStyle(DWORD dwAdd, DWORD dwRemove)
00435 {
00436     DWORD tmpstyle;
00437 
00438     TRACE("(%p)\n", this);
00439 
00440     tmpstyle = ::GetWindowLongPtrW(hWndList, GWL_STYLE);
00441     ::SetWindowLongPtrW(hWndList, GWL_STYLE, dwAdd | (tmpstyle & ~dwRemove));
00442 }
00443 
00444 /**********************************************************
00445 * ShellView_CreateList()
00446 *
00447 * - creates the list view window
00448 */
00449 BOOL CDefView::CreateList()
00450 {   DWORD dwStyle, dwExStyle;
00451 
00452     TRACE("%p\n", this);
00453 
00454     dwStyle = WS_TABSTOP | WS_VISIBLE | WS_CHILDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN |
00455               LVS_SHAREIMAGELISTS | LVS_EDITLABELS | LVS_AUTOARRANGE;
00456     dwExStyle = WS_EX_CLIENTEDGE;
00457 
00458     if (FolderSettings.fFlags & FWF_DESKTOP)
00459         dwStyle |= LVS_ALIGNLEFT;
00460     else
00461         dwStyle |= LVS_ALIGNTOP;
00462 
00463     switch (FolderSettings.ViewMode)
00464     {
00465         case FVM_ICON:
00466             dwStyle |= LVS_ICON;
00467             break;
00468 
00469         case FVM_DETAILS:
00470             dwStyle |= LVS_REPORT;
00471             break;
00472 
00473         case FVM_SMALLICON:
00474             dwStyle |= LVS_SMALLICON;
00475             break;
00476 
00477         case FVM_LIST:
00478             dwStyle |= LVS_LIST;
00479             break;
00480 
00481         default:
00482             dwStyle |= LVS_LIST;
00483             break;
00484     }
00485 
00486     if (FolderSettings.fFlags & FWF_AUTOARRANGE)
00487         dwStyle |= LVS_AUTOARRANGE;
00488 
00489     if (FolderSettings.fFlags & FWF_DESKTOP)
00490         FolderSettings.fFlags |= FWF_NOCLIENTEDGE | FWF_NOSCROLL;
00491 
00492     if (FolderSettings.fFlags & FWF_SINGLESEL)
00493         dwStyle |= LVS_SINGLESEL;
00494 
00495     if (FolderSettings.fFlags & FWF_NOCLIENTEDGE)
00496         dwExStyle &= ~WS_EX_CLIENTEDGE;
00497 
00498     hWndList = CreateWindowExW( dwExStyle,
00499                                 WC_LISTVIEWW,
00500                                 NULL,
00501                                 dwStyle,
00502                                 0, 0, 0, 0,
00503                                 m_hWnd,
00504                                 (HMENU)ID_LISTVIEW,
00505                                 shell32_hInstance,
00506                                 NULL);
00507 
00508     if (!hWndList)
00509         return FALSE;
00510 
00511     ListViewSortInfo.bIsAscending = TRUE;
00512     ListViewSortInfo.nHeaderID = -1;
00513     ListViewSortInfo.nLastHeaderID = -1;
00514 
00515     UpdateListColors();
00516 
00517     /*  UpdateShellSettings(); */
00518     return TRUE;
00519 }
00520 
00521 void CDefView::UpdateListColors()
00522 {
00523     if (FolderSettings.fFlags & FWF_DESKTOP)
00524     {
00525         /* Check if drop shadows option is enabled */
00526         BOOL bDropShadow = FALSE;
00527         DWORD cbDropShadow = sizeof(bDropShadow);
00528         WCHAR wszBuf[16] = L"";
00529 
00530         RegGetValueW(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced",
00531                      L"ListviewShadow", RRF_RT_DWORD, NULL, &bDropShadow, &cbDropShadow);
00532         if (bDropShadow && SystemParametersInfoW(SPI_GETDESKWALLPAPER, _countof(wszBuf), wszBuf, 0) && wszBuf[0])
00533         {
00534             SendMessageW(hWndList, LVM_SETTEXTBKCOLOR, 0, CLR_NONE);
00535             SendMessageW(hWndList, LVM_SETBKCOLOR, 0, CLR_NONE);
00536             SendMessageW(hWndList, LVM_SETTEXTCOLOR, 0, RGB(255, 255, 255));
00537             SendMessageW(hWndList, LVM_SETEXTENDEDLISTVIEWSTYLE, LVS_EX_TRANSPARENTSHADOWTEXT, LVS_EX_TRANSPARENTSHADOWTEXT);
00538         }
00539         else
00540         {
00541             COLORREF crDesktop = GetSysColor(COLOR_DESKTOP);
00542             SendMessageW(hWndList, LVM_SETTEXTBKCOLOR, 0, crDesktop);
00543             SendMessageW(hWndList, LVM_SETBKCOLOR, 0, crDesktop);
00544             if (GetRValue(crDesktop) + GetGValue(crDesktop) + GetBValue(crDesktop) > 128 * 3)
00545                 SendMessageW(hWndList, LVM_SETTEXTCOLOR, 0, RGB(0, 0, 0));
00546             else
00547                 SendMessageW(hWndList, LVM_SETTEXTCOLOR, 0, RGB(255, 255, 255));
00548             SendMessageW(hWndList, LVM_SETEXTENDEDLISTVIEWSTYLE, LVS_EX_TRANSPARENTSHADOWTEXT, 0);
00549         }
00550     }
00551 }
00552 
00553 /**********************************************************
00554 * ShellView_InitList()
00555 *
00556 * - adds all needed columns to the shellview
00557 */
00558 BOOL CDefView::InitList()
00559 {
00560     LVCOLUMNW    lvColumn;
00561     SHELLDETAILS    sd;
00562     WCHAR    szTemp[50];
00563 
00564     TRACE("%p\n", this);
00565 
00566     SendMessageW(hWndList, LVM_DELETEALLITEMS, 0, 0);
00567 
00568     lvColumn.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT;
00569     lvColumn.pszText = szTemp;
00570 
00571     if (pSF2Parent)
00572     {
00573         for (int i = 0; 1; i++)
00574         {
00575             if (FAILED(pSF2Parent->GetDetailsOf(NULL, i, &sd)))
00576                 break;
00577 
00578             lvColumn.fmt = sd.fmt;
00579             lvColumn.cx = sd.cxChar * 8; /* chars->pixel */
00580             StrRetToStrNW( szTemp, 50, &sd.str, NULL);
00581             SendMessageW(hWndList, LVM_INSERTCOLUMNW, i, (LPARAM) &lvColumn);
00582         }
00583     }
00584     else
00585     {
00586         FIXME("no SF2\n");
00587     }
00588 
00589     SendMessageW(hWndList, LVM_SETIMAGELIST, LVSIL_SMALL, (LPARAM)ShellSmallIconList);
00590     SendMessageW(hWndList, LVM_SETIMAGELIST, LVSIL_NORMAL, (LPARAM)ShellBigIconList);
00591 
00592     return TRUE;
00593 }
00594 
00595 /**********************************************************
00596 * ShellView_CompareItems()
00597 *
00598 * NOTES
00599 *  internal, CALLBACK for DSA_Sort
00600 */
00601 INT CALLBACK CDefView::CompareItems(LPVOID lParam1, LPVOID lParam2, LPARAM lpData)
00602 {
00603     int ret;
00604     TRACE("pidl1=%p pidl2=%p lpsf=%p\n", lParam1, lParam2, (LPVOID) lpData);
00605 
00606     if (!lpData)
00607         return 0;
00608 
00609     ret = (SHORT)SCODE_CODE(((IShellFolder *)lpData)->CompareIDs(0, (LPITEMIDLIST)lParam1, (LPITEMIDLIST)lParam2));
00610     TRACE("ret=%i\n", ret);
00611 
00612     return ret;
00613 }
00614 
00615 /*************************************************************************
00616  * ShellView_ListViewCompareItems
00617  *
00618  * Compare Function for the Listview (FileOpen Dialog)
00619  *
00620  * PARAMS
00621  *     lParam1       [I] the first ItemIdList to compare with
00622  *     lParam2       [I] the second ItemIdList to compare with
00623  *     lpData        [I] The column ID for the header Ctrl to process
00624  *
00625  * RETURNS
00626  *     A negative value if the first item should precede the second,
00627  *     a positive value if the first item should follow the second,
00628  *     or zero if the two items are equivalent
00629  *
00630  * NOTES
00631  *    FIXME: function does what ShellView_CompareItems is supposed to do.
00632  *    unify it and figure out how to use the undocumented first parameter
00633  *    of IShellFolder_CompareIDs to do the job this function does and
00634  *    move this code to IShellFolder.
00635  *    make LISTVIEW_SORT_INFO obsolete
00636  *    the way this function works is only usable if we had only
00637  *    filesystemfolders  (25/10/99 jsch)
00638  */
00639 INT CALLBACK CDefView::ListViewCompareItems(LPVOID lParam1, LPVOID lParam2, LPARAM lpData)
00640 {
00641     INT nDiff = 0;
00642     FILETIME fd1, fd2;
00643     char strName1[MAX_PATH], strName2[MAX_PATH];
00644     BOOL bIsFolder1, bIsFolder2, bIsBothFolder;
00645     LPITEMIDLIST pItemIdList1 = (LPITEMIDLIST) lParam1;
00646     LPITEMIDLIST pItemIdList2 = (LPITEMIDLIST) lParam2;
00647     LISTVIEW_SORT_INFO *pSortInfo = (LPLISTVIEW_SORT_INFO) lpData;
00648 
00649 
00650     bIsFolder1 = _ILIsFolder(pItemIdList1);
00651     bIsFolder2 = _ILIsFolder(pItemIdList2);
00652     bIsBothFolder = bIsFolder1 && bIsFolder2;
00653 
00654     /* When sorting between a File and a Folder, the Folder gets sorted first */
00655     if ( (bIsFolder1 || bIsFolder2) && !bIsBothFolder)
00656     {
00657         nDiff = bIsFolder1 ? -1 : 1;
00658     }
00659     else
00660     {
00661         /* Sort by Time: Folders or Files can be sorted */
00662 
00663         if(pSortInfo->nHeaderID == LISTVIEW_COLUMN_TIME)
00664         {
00665             _ILGetFileDateTime(pItemIdList1, &fd1);
00666             _ILGetFileDateTime(pItemIdList2, &fd2);
00667             nDiff = CompareFileTime(&fd2, &fd1);
00668         }
00669         /* Sort by Attribute: Folder or Files can be sorted */
00670         else if(pSortInfo->nHeaderID == LISTVIEW_COLUMN_ATTRIB)
00671         {
00672             _ILGetFileAttributes(pItemIdList1, strName1, MAX_PATH);
00673             _ILGetFileAttributes(pItemIdList2, strName2, MAX_PATH);
00674             nDiff = lstrcmpiA(strName1, strName2);
00675         }
00676         /* Sort by FileName: Folder or Files can be sorted */
00677         else if (pSortInfo->nHeaderID == LISTVIEW_COLUMN_NAME || bIsBothFolder)
00678         {
00679             /* Sort by Text */
00680             _ILSimpleGetText(pItemIdList1, strName1, MAX_PATH);
00681             _ILSimpleGetText(pItemIdList2, strName2, MAX_PATH);
00682             nDiff = lstrcmpiA(strName1, strName2);
00683         }
00684         /* Sort by File Size, Only valid for Files */
00685         else if (pSortInfo->nHeaderID == LISTVIEW_COLUMN_SIZE)
00686         {
00687             nDiff = (INT)(_ILGetFileSize(pItemIdList1, NULL, 0) - _ILGetFileSize(pItemIdList2, NULL, 0));
00688         }
00689         /* Sort by File Type, Only valid for Files */
00690         else if (pSortInfo->nHeaderID == LISTVIEW_COLUMN_TYPE)
00691         {
00692             /* Sort by Type */
00693             _ILGetFileType(pItemIdList1, strName1, MAX_PATH);
00694             _ILGetFileType(pItemIdList2, strName2, MAX_PATH);
00695             nDiff = lstrcmpiA(strName1, strName2);
00696         }
00697     }
00698     /*  If the Date, FileSize, FileType, Attrib was the same, sort by FileName */
00699 
00700     if (nDiff == 0)
00701     {
00702         _ILSimpleGetText(pItemIdList1, strName1, MAX_PATH);
00703         _ILSimpleGetText(pItemIdList2, strName2, MAX_PATH);
00704         nDiff = lstrcmpiA(strName1, strName2);
00705     }
00706 
00707     if (!pSortInfo->bIsAscending)
00708     {
00709         nDiff = -nDiff;
00710     }
00711 
00712     return nDiff;
00713 }
00714 
00715 /**********************************************************
00716 *  LV_FindItemByPidl()
00717 */
00718 int CDefView::LV_FindItemByPidl(LPCITEMIDLIST pidl)
00719 {
00720     LVITEMW lvItem;
00721     lvItem.iSubItem = 0;
00722     lvItem.mask = LVIF_PARAM;
00723 
00724     for (lvItem.iItem = 0;
00725             SendMessageW(hWndList, LVM_GETITEMW, 0, (LPARAM) &lvItem);
00726             lvItem.iItem++)
00727     {
00728         LPITEMIDLIST currentpidl = (LPITEMIDLIST) lvItem.lParam;
00729         HRESULT hr = pSFParent->CompareIDs(0, pidl, currentpidl);
00730 
00731         if (SUCCEEDED(hr) && !HRESULT_CODE(hr))
00732         {
00733             return lvItem.iItem;
00734         }
00735     }
00736     return -1;
00737 }
00738 
00739 /**********************************************************
00740 * LV_AddItem()
00741 */
00742 BOOLEAN CDefView::LV_AddItem(LPCITEMIDLIST pidl)
00743 {
00744     LVITEMW    lvItem;
00745 
00746     TRACE("(%p)(pidl=%p)\n", this, pidl);
00747 
00748     lvItem.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM;    /*set the mask*/
00749     lvItem.iItem = ListView_GetItemCount(hWndList);    /*add the item to the end of the list*/
00750     lvItem.iSubItem = 0;
00751     lvItem.lParam = (LPARAM) ILClone(ILFindLastID(pidl));                /*set the item's data*/
00752     lvItem.pszText = LPSTR_TEXTCALLBACKW;            /*get text on a callback basis*/
00753     lvItem.iImage = I_IMAGECALLBACK;            /*get the image on a callback basis*/
00754 
00755     if (SendMessageW(hWndList, LVM_INSERTITEMW, 0, (LPARAM)&lvItem) == -1)
00756         return FALSE;
00757     else
00758         return TRUE;
00759 }
00760 
00761 /**********************************************************
00762 * LV_DeleteItem()
00763 */
00764 BOOLEAN CDefView::LV_DeleteItem(LPCITEMIDLIST pidl)
00765 {
00766     int nIndex;
00767 
00768     TRACE("(%p)(pidl=%p)\n", this, pidl);
00769 
00770     nIndex = LV_FindItemByPidl(ILFindLastID(pidl));
00771 
00772     return (-1 == ListView_DeleteItem(hWndList, nIndex)) ? FALSE : TRUE;
00773 }
00774 
00775 /**********************************************************
00776 * LV_RenameItem()
00777 */
00778 BOOLEAN CDefView::LV_RenameItem(LPCITEMIDLIST pidlOld, LPCITEMIDLIST pidlNew)
00779 {
00780     int nItem;
00781     LVITEMW lvItem;
00782 
00783     TRACE("(%p)(pidlold=%p pidlnew=%p)\n", this, pidlOld, pidlNew);
00784 
00785     nItem = LV_FindItemByPidl(ILFindLastID(pidlOld));
00786 
00787     if ( -1 != nItem )
00788     {
00789         lvItem.mask = LVIF_PARAM;        /* only the pidl */
00790         lvItem.iItem = nItem;
00791         SendMessageW(hWndList, LVM_GETITEMW, 0, (LPARAM) &lvItem);
00792 
00793         SHFree((LPITEMIDLIST)lvItem.lParam);
00794         lvItem.mask = LVIF_PARAM|LVIF_IMAGE;
00795         lvItem.iItem = nItem;
00796         lvItem.lParam = (LPARAM) ILClone(ILFindLastID(pidlNew));    /* set the item's data */
00797         lvItem.iImage = SHMapPIDLToSystemImageListIndex(pSFParent, pidlNew, 0);
00798         SendMessageW(hWndList, LVM_SETITEMW, 0, (LPARAM) &lvItem);
00799         SendMessageW(hWndList, LVM_UPDATE, nItem, 0);
00800         return TRUE;                    /* FIXME: better handling */
00801     }
00802 
00803     return FALSE;
00804 }
00805 
00806 /**********************************************************
00807 * ShellView_FillList()
00808 *
00809 * - gets the objectlist from the shellfolder
00810 * - sorts the list
00811 * - fills the list into the view
00812 */
00813 INT CALLBACK CDefView::fill_list( LPVOID ptr, LPVOID arg )
00814 {
00815     LPITEMIDLIST pidl = (LPITEMIDLIST)ptr;
00816     CDefView *pThis = (CDefView *)arg;
00817     /* in a commdlg This works as a filemask*/
00818     if (pThis->IncludeObject(pidl) == S_OK)
00819         pThis->LV_AddItem(pidl);
00820 
00821     SHFree(pidl);
00822     return TRUE;
00823 }
00824 
00825 HRESULT CDefView::FillList()
00826 {
00827     LPENUMIDLIST    pEnumIDList;
00828     LPITEMIDLIST    pidl;
00829     DWORD        dwFetched;
00830     HRESULT        hRes;
00831     HDPA        hdpa;
00832 
00833     TRACE("%p\n", this);
00834 
00835     /* get the itemlist from the shfolder*/
00836     hRes = pSFParent->EnumObjects(m_hWnd, SHCONTF_NONFOLDERS | SHCONTF_FOLDERS, &pEnumIDList);
00837     if (hRes != S_OK)
00838     {
00839         if (hRes == S_FALSE)
00840             return(NOERROR);
00841         return(hRes);
00842     }
00843 
00844     /* create a pointer array */
00845     hdpa = DPA_Create(16);
00846     if (!hdpa)
00847     {
00848         return(E_OUTOFMEMORY);
00849     }
00850 
00851     /* copy the items into the array*/
00852     while((S_OK == pEnumIDList->Next(1, &pidl, &dwFetched)) && dwFetched)
00853     {
00854         if (DPA_InsertPtr(hdpa, 0x7fff, pidl) == -1)
00855         {
00856             SHFree(pidl);
00857         }
00858     }
00859 
00860     /* sort the array */
00861     DPA_Sort(hdpa, CompareItems, (LPARAM)pSFParent.p);
00862 
00863     /*turn the listview's redrawing off*/
00864     SendMessageA(hWndList, WM_SETREDRAW, FALSE, 0);
00865 
00866     DPA_DestroyCallback( hdpa, fill_list, (void *)this);
00867 
00868     /*turn the listview's redrawing back on and force it to draw*/
00869     SendMessageA(hWndList, WM_SETREDRAW, TRUE, 0);
00870 
00871     pEnumIDList->Release(); /* destroy the list*/
00872 
00873     return S_OK;
00874 }
00875 
00876 LRESULT CDefView::OnShowWindow(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
00877 {
00878     ::UpdateWindow(hWndList);
00879     bHandled = FALSE;
00880     return 0;
00881 }
00882 
00883 LRESULT CDefView::OnGetDlgCode(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
00884 {
00885     return SendMessageW(hWndList, uMsg, 0, 0);
00886 }
00887 
00888 LRESULT CDefView::OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
00889 {
00890     RevokeDragDrop(m_hWnd);
00891     SHChangeNotifyDeregister(hNotify);
00892     bHandled = FALSE;
00893     return 0;
00894 }
00895 
00896 LRESULT CDefView::OnEraseBackground(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
00897 {
00898     if (FolderSettings.fFlags & (FWF_DESKTOP | FWF_TRANSPARENT))
00899         return SendMessageW(GetParent(), WM_ERASEBKGND, wParam, lParam); /* redirect to parent */
00900 
00901     bHandled = FALSE;
00902     return 0;
00903 }
00904 
00905 LRESULT CDefView::OnSysColorChange(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
00906 {
00907     /* Update desktop labels color */
00908     UpdateListColors();
00909 
00910     /* Forward WM_SYSCOLORCHANGE to common controls */
00911     return SendMessageW(hWndList, uMsg, 0, 0);
00912 }
00913 
00914 LRESULT CDefView::OnGetShellBrowser(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
00915 {
00916     return (LRESULT)pShellBrowser.p;
00917 }
00918 
00919 /**********************************************************
00920 *  ShellView_OnCreate()
00921 */
00922 LRESULT CDefView::OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
00923 {
00924     CComPtr<IDropTarget>                pdt;
00925     SHChangeNotifyEntry ntreg;
00926     CComPtr<IPersistFolder2>            ppf2;
00927 
00928     TRACE("%p\n", this);
00929 
00930     if(CreateList())
00931     {
00932         if(InitList())
00933         {
00934             FillList();
00935         }
00936     }
00937 
00938     if (SUCCEEDED(this->QueryInterface(IID_IDropTarget, (LPVOID*)&pdt)))
00939         RegisterDragDrop(m_hWnd, pdt);
00940 
00941     /* register for receiving notifications */
00942     pSFParent->QueryInterface(IID_IPersistFolder2, (LPVOID*)&ppf2);
00943     if (ppf2)
00944     {
00945         ppf2->GetCurFolder((LPITEMIDLIST*)&ntreg.pidl);
00946         ntreg.fRecursive = TRUE;
00947         hNotify = SHChangeNotifyRegister(m_hWnd, SHCNF_IDLIST, SHCNE_ALLEVENTS, SHV_CHANGE_NOTIFY, 1, &ntreg);
00948         SHFree((LPITEMIDLIST)ntreg.pidl);
00949     }
00950 
00951     hAccel = LoadAcceleratorsA(shell32_hInstance, "shv_accel");
00952 
00953     return S_OK;
00954 }
00955 
00956 /**********************************************************
00957  *    #### Handling of the menus ####
00958  */
00959 
00960 /**********************************************************
00961 * ShellView_BuildFileMenu()
00962 */
00963 HMENU CDefView::BuildFileMenu()
00964 {   WCHAR    szText[MAX_PATH];
00965     MENUITEMINFOW    mii;
00966     int    nTools, i;
00967     HMENU    hSubMenu;
00968 
00969     TRACE("(%p)\n", this);
00970 
00971     hSubMenu = CreatePopupMenu();
00972     if (hSubMenu)
00973     {
00974         /*get the number of items in our global array*/
00975         for(nTools = 0; Tools[nTools].idCommand != -1; nTools++) {}
00976 
00977         /*add the menu items*/
00978         for(i = 0; i < nTools; i++)
00979         {
00980             LoadStringW(shell32_hInstance, Tools[i].idMenuString, szText, MAX_PATH);
00981 
00982             ZeroMemory(&mii, sizeof(mii));
00983             mii.cbSize = sizeof(mii);
00984             mii.fMask = MIIM_TYPE | MIIM_ID | MIIM_STATE;
00985 
00986             if(BTNS_SEP != Tools[i].bStyle) /* no separator*/
00987             {
00988                 mii.fType = MFT_STRING;
00989                 mii.fState = MFS_ENABLED;
00990                 mii.dwTypeData = szText;
00991                 mii.wID = Tools[i].idCommand;
00992             }
00993             else
00994             {
00995                 mii.fType = MFT_SEPARATOR;
00996             }
00997             /* tack This item onto the end of the menu */
00998             InsertMenuItemW(hSubMenu, (UINT) - 1, TRUE, &mii);
00999         }
01000     }
01001 
01002     TRACE("-- return (menu=%p)\n", hSubMenu);
01003     return hSubMenu;
01004 }
01005 
01006 /**********************************************************
01007 * ShellView_MergeFileMenu()
01008 */
01009 void CDefView::MergeFileMenu(HMENU hSubMenu)
01010 {
01011     TRACE("(%p)->(submenu=%p) stub\n", this, hSubMenu);
01012 
01013     if (hSubMenu)
01014     {   /*insert This item at the beginning of the menu */
01015         _InsertMenuItemW(hSubMenu, 0, TRUE, 0, MFT_SEPARATOR, NULL, MFS_ENABLED);
01016         _InsertMenuItemW(hSubMenu, 0, TRUE, IDM_MYFILEITEM, MFT_STRING, L"dummy45", MFS_ENABLED);
01017     }
01018 
01019     TRACE("--\n");
01020 }
01021 
01022 /**********************************************************
01023 * ShellView_MergeViewMenu()
01024 */
01025 void CDefView::MergeViewMenu(HMENU hSubMenu)
01026 {
01027     TRACE("(%p)->(submenu=%p)\n", this, hSubMenu);
01028 
01029     if (hSubMenu)
01030     {
01031         /*add a separator at the correct position in the menu*/
01032         MENUITEMINFOW mii;
01033         static WCHAR view[] = L"View";
01034 
01035         _InsertMenuItemW(hSubMenu, FCIDM_MENU_VIEW_SEP_OPTIONS, FALSE, 0, MFT_SEPARATOR, NULL, MFS_ENABLED);
01036 
01037         ZeroMemory(&mii, sizeof(mii));
01038         mii.cbSize = sizeof(mii);
01039         mii.fMask = MIIM_SUBMENU | MIIM_TYPE | MIIM_DATA;
01040         mii.fType = MFT_STRING;
01041         mii.dwTypeData = view;
01042         mii.hSubMenu = LoadMenuW(shell32_hInstance, L"MENU_001");
01043         InsertMenuItemW(hSubMenu, FCIDM_MENU_VIEW_SEP_OPTIONS, FALSE, &mii);
01044     }
01045 }
01046 
01047 /**********************************************************
01048 *   ShellView_GetSelections()
01049 *
01050 * - fills the this->apidl list with the selected objects
01051 *
01052 * RETURNS
01053 *  number of selected items
01054 */
01055 UINT CDefView::GetSelections()
01056 {
01057     LVITEMW    lvItem;
01058     UINT    i = 0;
01059 
01060     SHFree(apidl);
01061 
01062     cidl = ListView_GetSelectedCount(hWndList);
01063     apidl = (LPITEMIDLIST*)SHAlloc(cidl * sizeof(LPITEMIDLIST));
01064 
01065     TRACE("selected=%i\n", cidl);
01066 
01067     if (apidl)
01068     {
01069         TRACE("-- Items selected =%u\n", cidl);
01070 
01071         lvItem.mask = LVIF_STATE | LVIF_PARAM;
01072         lvItem.stateMask = LVIS_SELECTED;
01073         lvItem.iItem = 0;
01074         lvItem.iSubItem = 0;
01075         lvItem.state = 0;
01076 
01077         while(SendMessageW(hWndList, LVM_GETITEMW, 0, (LPARAM)&lvItem) && (i < cidl))
01078         {
01079             if(lvItem.state & LVIS_SELECTED)
01080             {
01081                 apidl[i] = (LPITEMIDLIST)lvItem.lParam;
01082                 i++;
01083                 if (i == cidl)
01084                     break;
01085                 TRACE("-- selected Item found\n");
01086             }
01087             lvItem.iItem++;
01088         }
01089     }
01090 
01091     return cidl;
01092 }
01093 
01094 /**********************************************************
01095  *    ShellView_OpenSelectedItems()
01096  */
01097 HRESULT CDefView::OpenSelectedItems()
01098 {
01099     static UINT CF_IDLIST = 0;
01100     HRESULT hr;
01101     CComPtr<IDataObject>                selection;
01102     CComPtr<IContextMenu>                cm;
01103     HMENU hmenu;
01104     FORMATETC fetc;
01105     STGMEDIUM stgm;
01106     LPIDA pIDList;
01107     LPCITEMIDLIST parent_pidl;
01108     WCHAR parent_path[MAX_PATH];
01109     LPCWSTR parent_dir = NULL;
01110     SFGAOF attribs;
01111     int i;
01112     CMINVOKECOMMANDINFOEX ici;
01113     MENUITEMINFOW info;
01114 
01115     if (0 == GetSelections())
01116     {
01117         return S_OK;
01118     }
01119 
01120     hr = pSFParent->GetUIObjectOf(m_hWnd, cidl,
01121                                   (LPCITEMIDLIST*)apidl, IID_IContextMenu,
01122                                   0, (LPVOID *)&cm);
01123 
01124     if (SUCCEEDED(hr))
01125     {
01126         hmenu = CreatePopupMenu();
01127         if (hmenu)
01128         {
01129             hr = IUnknown_SetSite(cm, (IShellView *)this);
01130             if (SUCCEEDED(cm->QueryContextMenu(hmenu, 0, 0x20, 0x7fff, CMF_DEFAULTONLY)))
01131             {
01132                 INT def = -1, n = GetMenuItemCount(hmenu);
01133 
01134                 for ( i = 0; i < n; i++ )
01135                 {
01136                     memset( &info, 0, sizeof info );
01137                     info.cbSize = sizeof info;
01138                     info.fMask = MIIM_FTYPE | MIIM_STATE | MIIM_ID;
01139                     if (GetMenuItemInfoW( hmenu, i, TRUE, &info))
01140                     {
01141                         if (info.fState & MFS_DEFAULT)
01142                         {
01143                             def = info.wID;
01144                             break;
01145                         }
01146                     }
01147                 }
01148                 if (def != -1)
01149                 {
01150                     memset( &ici, 0, sizeof ici );
01151                     ici.cbSize = sizeof ici;
01152                     ici.lpVerb = MAKEINTRESOURCEA( def );
01153                     ici.hwnd = m_hWnd;
01154 
01155                     hr = cm->InvokeCommand((LPCMINVOKECOMMANDINFO)&ici);
01156                     if (hr == S_OK)
01157                     {
01158                         DestroyMenu(hmenu);
01159                         hr = IUnknown_SetSite(cm, NULL);
01160                         return S_OK;
01161                     }
01162                     else
01163                         ERR("InvokeCommand failed: %x\n", hr);
01164                 }
01165                 else
01166                     ERR("No default context menu item\n");
01167 
01168             }
01169             DestroyMenu( hmenu );
01170             hr = IUnknown_SetSite(cm, NULL);
01171         }
01172     }
01173 
01174 
01175 
01176     hr = pSFParent->GetUIObjectOf(m_hWnd, cidl,
01177                                   (LPCITEMIDLIST*)apidl, IID_IDataObject,
01178                                   0, (LPVOID *)&selection);
01179 
01180 
01181 
01182     if (FAILED(hr))
01183         return hr;
01184 
01185     if (0 == CF_IDLIST)
01186     {
01187         CF_IDLIST = RegisterClipboardFormatW(CFSTR_SHELLIDLIST);
01188     }
01189 
01190     fetc.cfFormat = CF_IDLIST;
01191     fetc.ptd = NULL;
01192     fetc.dwAspect = DVASPECT_CONTENT;
01193     fetc.lindex = -1;
01194     fetc.tymed = TYMED_HGLOBAL;
01195 
01196     hr = selection->QueryGetData(&fetc);
01197     if (FAILED(hr))
01198         return hr;
01199 
01200     hr = selection->GetData(&fetc, &stgm);
01201     if (FAILED(hr))
01202         return hr;
01203 
01204     pIDList = (LPIDA)GlobalLock(stgm.hGlobal);
01205 
01206     parent_pidl = (LPCITEMIDLIST) ((LPBYTE)pIDList + pIDList->aoffset[0]);
01207     hr = pSFParent->GetAttributesOf(1, &parent_pidl, &attribs);
01208     if (SUCCEEDED(hr) && (attribs & SFGAO_FILESYSTEM) &&
01209             SHGetPathFromIDListW(parent_pidl, parent_path))
01210     {
01211         parent_dir = parent_path;
01212     }
01213 
01214     for (i = pIDList->cidl; i > 0; --i)
01215     {
01216         LPCITEMIDLIST pidl;
01217 
01218         pidl = (LPCITEMIDLIST)((LPBYTE)pIDList + pIDList->aoffset[i]);
01219 
01220         attribs = SFGAO_FOLDER;
01221         hr = pSFParent->GetAttributesOf(1, &pidl, &attribs);
01222 
01223         if (SUCCEEDED(hr) && ! (attribs & SFGAO_FOLDER))
01224         {
01225             SHELLEXECUTEINFOW shexinfo;
01226 
01227             shexinfo.cbSize = sizeof(SHELLEXECUTEINFOW);
01228             shexinfo.fMask = SEE_MASK_INVOKEIDLIST;    /* SEE_MASK_IDLIST is also possible. */
01229             shexinfo.hwnd = NULL;
01230             shexinfo.lpVerb = NULL;
01231             shexinfo.lpFile = NULL;
01232             shexinfo.lpParameters = NULL;
01233             shexinfo.lpDirectory = parent_dir;
01234             shexinfo.nShow = SW_NORMAL;
01235             shexinfo.lpIDList = ILCombine(parent_pidl, pidl);
01236 
01237             ShellExecuteExW(&shexinfo);    /* Discard error/success info */
01238 
01239             ILFree((LPITEMIDLIST)shexinfo.lpIDList);
01240         }
01241     }
01242 
01243     GlobalUnlock(stgm.hGlobal);
01244     ReleaseStgMedium(&stgm);
01245 
01246     return S_OK;
01247 }
01248 
01249 /**********************************************************
01250  *    ShellView_DoContextMenu()
01251  */
01252 LRESULT CDefView::OnContextMenu(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
01253 {
01254     WORD                 x;
01255     WORD                 y;
01256     UINT                 uCommand;
01257     DWORD                wFlags;
01258     HMENU                hMenu;
01259     BOOL                 fExplore;
01260     HWND                 hwndTree;
01261     CMINVOKECOMMANDINFO  cmi;
01262     HRESULT              hResult;
01263 
01264     // for some reason I haven't figured out, we sometimes recurse into this method
01265     if (pCM != NULL)
01266         return 0;
01267 
01268     x = LOWORD(lParam);
01269     y = HIWORD(lParam);
01270 
01271     TRACE("(%p)->(0x%08x 0x%08x) stub\n", this, x, y);
01272 
01273     fExplore = FALSE;
01274     hwndTree = NULL;
01275 
01276     /* look, what's selected and create a context menu object of it*/
01277     if (GetSelections())
01278     {
01279         pSFParent->GetUIObjectOf(hWndParent, cidl, (LPCITEMIDLIST*)apidl, IID_IContextMenu, NULL, (LPVOID *)&pCM);
01280 
01281         if (pCM)
01282         {
01283             TRACE("-- pContextMenu\n");
01284             hMenu = CreatePopupMenu();
01285 
01286             if (hMenu)
01287             {
01288                 hResult = IUnknown_SetSite(pCM, (IShellView *)this);
01289 
01290                 /* See if we are in Explore or Open mode. If the browser's tree is present, we are in Explore mode.*/
01291                 if (SUCCEEDED(pShellBrowser->GetControlWindow(FCW_TREE, &hwndTree)) && hwndTree)
01292                 {
01293                     TRACE("-- explore mode\n");
01294                     fExplore = TRUE;
01295                 }
01296 
01297                 /* build the flags depending on what we can do with the selected item */
01298                 wFlags = CMF_NORMAL | (cidl != 1 ? 0 : CMF_CANRENAME) | (fExplore ? CMF_EXPLORE : 0);
01299 
01300                 /* let the ContextMenu merge its items in */
01301                 if (SUCCEEDED(pCM->QueryContextMenu(hMenu, 0, FCIDM_SHVIEWFIRST, FCIDM_SHVIEWLAST, wFlags )))
01302                 {
01303                     if (FolderSettings.fFlags & FWF_DESKTOP)
01304                         SetMenuDefaultItem(hMenu, FCIDM_SHVIEW_OPEN, MF_BYCOMMAND);
01305 
01306                     TRACE("-- track popup\n");
01307                     uCommand = TrackPopupMenu(hMenu,
01308                                               TPM_LEFTALIGN | TPM_RETURNCMD | TPM_LEFTBUTTON | TPM_RIGHTBUTTON,
01309                                               x, y, 0, m_hWnd, NULL);
01310 
01311                     if (uCommand > 0)
01312                     {
01313                         TRACE("-- uCommand=%u\n", uCommand);
01314 
01315                         if (uCommand == FCIDM_SHVIEW_OPEN && pCommDlgBrowser.p != NULL)
01316                         {
01317                             TRACE("-- dlg: OnDefaultCommand\n");
01318                             if (OnDefaultCommand() != S_OK)
01319                                 OpenSelectedItems();
01320                         }
01321                         else
01322                         {
01323                             TRACE("-- explore -- invoke command\n");
01324                             ZeroMemory(&cmi, sizeof(cmi));
01325                             cmi.cbSize = sizeof(cmi);
01326                             cmi.hwnd = hWndParent; /* this window has to answer CWM_GETISHELLBROWSER */
01327                             cmi.lpVerb = (LPCSTR)MAKEINTRESOURCEA(uCommand);
01328                             pCM->InvokeCommand(&cmi);
01329                         }
01330                     }
01331 
01332                     hResult = IUnknown_SetSite(pCM, NULL);
01333                     DestroyMenu(hMenu);
01334                 }
01335             }
01336             pCM.Release();
01337         }
01338     }
01339     else    /* background context menu */
01340     {
01341         hMenu = CreatePopupMenu();
01342 
01343         CDefFolderMenu_Create2(NULL, NULL, cidl, (LPCITEMIDLIST*)apidl, pSFParent, NULL, 0, NULL, (IContextMenu**)&pCM);
01344         pCM->QueryContextMenu(hMenu, 0, FCIDM_SHVIEWFIRST, FCIDM_SHVIEWLAST, 0);
01345 
01346         uCommand = TrackPopupMenu(hMenu,
01347                                   TPM_LEFTALIGN | TPM_RETURNCMD | TPM_LEFTBUTTON | TPM_RIGHTBUTTON,
01348                                   x, y, 0, m_hWnd, NULL);
01349         DestroyMenu(hMenu);
01350 
01351         TRACE("-- (%p)->(uCommand=0x%08x )\n", this, uCommand);
01352 
01353         ZeroMemory(&cmi, sizeof(cmi));
01354         cmi.cbSize = sizeof(cmi);
01355         cmi.lpVerb = (LPCSTR)MAKEINTRESOURCEA(uCommand);
01356         cmi.hwnd = hWndParent;
01357         pCM->InvokeCommand(&cmi);
01358 
01359         pCM.Release();
01360     }
01361 
01362     return 0;
01363 }
01364 
01365 /**********************************************************
01366  *    ##### message handling #####
01367  */
01368 
01369 /**********************************************************
01370 *  ShellView_OnSize()
01371 */
01372 LRESULT CDefView::OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
01373 {
01374     WORD                                wWidth;
01375     WORD                                wHeight;
01376 
01377     wWidth = LOWORD(lParam);
01378     wHeight = HIWORD(lParam);
01379 
01380     TRACE("%p width=%u height=%u\n", this, wWidth, wHeight);
01381 
01382     /*resize the ListView to fit our window*/
01383     if (hWndList)
01384     {
01385         ::MoveWindow(hWndList, 0, 0, wWidth, wHeight, TRUE);
01386     }
01387 
01388     return 0;
01389 }
01390 
01391 /**********************************************************
01392 * ShellView_OnDeactivate()
01393 *
01394 * NOTES
01395 *  internal
01396 */
01397 void CDefView::OnDeactivate()
01398 {
01399     TRACE("%p\n", this);
01400 
01401     if (uState != SVUIA_DEACTIVATE)
01402     {
01403         if (hMenu)
01404         {
01405             pShellBrowser->SetMenuSB(0, 0, 0);
01406             pShellBrowser->RemoveMenusSB(hMenu);
01407             DestroyMenu(hMenu);
01408             hMenu = 0;
01409         }
01410 
01411         uState = SVUIA_DEACTIVATE;
01412     }
01413 }
01414 
01415 void CDefView::DoActivate(UINT uState)
01416 {
01417     OLEMENUGROUPWIDTHS                    omw = { {0, 0, 0, 0, 0, 0} };
01418     MENUITEMINFOA                        mii;
01419     CHAR                                szText[MAX_PATH];
01420 
01421     TRACE("%p uState=%x\n", this, uState);
01422 
01423     /*don't do anything if the state isn't really changing */
01424     if (this->uState == uState)
01425     {
01426         return;
01427     }
01428 
01429     OnDeactivate();
01430 
01431     /*only do This if we are active */
01432     if(uState != SVUIA_DEACTIVATE)
01433     {
01434         /*merge the menus */
01435         hMenu = CreateMenu();
01436 
01437         if(hMenu)
01438         {
01439             pShellBrowser->InsertMenusSB(hMenu, &omw);
01440             TRACE("-- after fnInsertMenusSB\n");
01441 
01442             /*build the top level menu get the menu item's text*/
01443             strcpy(szText, "dummy 31");
01444 
01445             ZeroMemory(&mii, sizeof(mii));
01446             mii.cbSize = sizeof(mii);
01447             mii.fMask = MIIM_SUBMENU | MIIM_TYPE | MIIM_STATE;
01448             mii.fType = MFT_STRING;
01449             mii.fState = MFS_ENABLED;
01450             mii.dwTypeData = szText;
01451             mii.hSubMenu = BuildFileMenu();
01452 
01453             /*insert our menu into the menu bar*/
01454             if (mii.hSubMenu)
01455             {
01456                 InsertMenuItemA(hMenu, FCIDM_MENU_HELP, FALSE, &mii);
01457             }
01458 
01459             /*get the view menu so we can merge with it*/
01460             ZeroMemory(&mii, sizeof(mii));
01461             mii.cbSize = sizeof(mii);
01462             mii.fMask = MIIM_SUBMENU;
01463 
01464             if (GetMenuItemInfoA(hMenu, FCIDM_MENU_VIEW, FALSE, &mii))
01465             {
01466                 MergeViewMenu(mii.hSubMenu);
01467             }
01468 
01469             /*add the items that should only be added if we have the focus*/
01470             if (SVUIA_ACTIVATE_FOCUS == uState)
01471             {
01472                 /*get the file menu so we can merge with it */
01473                 ZeroMemory(&mii, sizeof(mii));
01474                 mii.cbSize = sizeof(mii);
01475                 mii.fMask = MIIM_SUBMENU;
01476 
01477                 if (GetMenuItemInfoA(hMenu, FCIDM_MENU_FILE, FALSE, &mii))
01478                 {
01479                     MergeFileMenu(mii.hSubMenu);
01480                 }
01481             }
01482 
01483             TRACE("-- before fnSetMenuSB\n");
01484             pShellBrowser->SetMenuSB(hMenu, 0, m_hWnd);
01485         }
01486     }
01487     this->uState = uState;
01488     TRACE("--\n");
01489 }
01490 
01491 /**********************************************************
01492 * ShellView_OnActivate()
01493 */
01494 LRESULT CDefView::OnActivate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
01495 {
01496     DoActivate(SVUIA_ACTIVATE_FOCUS);
01497     return 0;
01498 }
01499 
01500 /**********************************************************
01501 *  ShellView_OnSetFocus()
01502 *
01503 */
01504 LRESULT CDefView::OnSetFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
01505 {
01506     TRACE("%p\n", this);
01507 
01508     /* Tell the browser one of our windows has received the focus. This
01509     should always be done before merging menus (OnActivate merges the
01510     menus) if one of our windows has the focus.*/
01511 
01512     pShellBrowser->OnViewWindowActive((IShellView *)this);
01513     DoActivate(SVUIA_ACTIVATE_FOCUS);
01514 
01515     /* Set the focus to the listview */
01516     ::SetFocus(hWndList);
01517 
01518     /* Notify the ICommDlgBrowser interface */
01519     OnStateChange(CDBOSC_SETFOCUS);
01520 
01521     return 0;
01522 }
01523 
01524 /**********************************************************
01525 * ShellView_OnKillFocus()
01526 */
01527 LRESULT CDefView::OnKillFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
01528 {
01529     TRACE("(%p) stub\n", this);
01530 
01531     DoActivate(SVUIA_ACTIVATE_NOFOCUS);
01532     /* Notify the ICommDlgBrowser */
01533     OnStateChange(CDBOSC_KILLFOCUS);
01534 
01535     return 0;
01536 }
01537 
01538 /**********************************************************
01539 * ShellView_OnCommand()
01540 *
01541 * NOTES
01542 *    the CmdID's are the ones from the context menu
01543 */
01544 LRESULT CDefView::OnCommand(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
01545 {
01546     DWORD                                dwCmdID;
01547     DWORD                                dwCmd;
01548     HWND                                hwndCmd;
01549 
01550     dwCmdID = GET_WM_COMMAND_ID(wParam, lParam);
01551     dwCmd = GET_WM_COMMAND_CMD(wParam, lParam);
01552     hwndCmd = GET_WM_COMMAND_HWND(wParam, lParam);
01553 
01554     TRACE("(%p)->(0x%08x 0x%08x %p) stub\n", this, dwCmdID, dwCmd, hwndCmd);
01555 
01556     switch (dwCmdID)
01557     {
01558         case FCIDM_SHVIEW_SMALLICON:
01559             FolderSettings.ViewMode = FVM_SMALLICON;
01560             SetStyle (LVS_SMALLICON, LVS_TYPEMASK);
01561             CheckToolbar();
01562             break;
01563 
01564         case FCIDM_SHVIEW_BIGICON:
01565             FolderSettings.ViewMode = FVM_ICON;
01566             SetStyle (LVS_ICON, LVS_TYPEMASK);
01567             CheckToolbar();
01568             break;
01569 
01570         case FCIDM_SHVIEW_LISTVIEW:
01571             FolderSettings.ViewMode = FVM_LIST;
01572             SetStyle (LVS_LIST, LVS_TYPEMASK);
01573             CheckToolbar();
01574             break;
01575 
01576         case FCIDM_SHVIEW_REPORTVIEW:
01577             FolderSettings.ViewMode = FVM_DETAILS;
01578             SetStyle (LVS_REPORT, LVS_TYPEMASK);
01579             CheckToolbar();
01580             break;
01581 
01582             /* the menu-ID's for sorting are 0x30... see shrec.rc */
01583         case 0x30:
01584         case 0x31:
01585         case 0x32:
01586         case 0x33:
01587             ListViewSortInfo.nHeaderID = (LPARAM) (dwCmdID - 0x30);
01588             ListViewSortInfo.bIsAscending = TRUE;
01589             ListViewSortInfo.nLastHeaderID = ListViewSortInfo.nHeaderID;
01590             SendMessageA(hWndList, LVM_SORTITEMS, (WPARAM) &ListViewSortInfo, (LPARAM)ListViewCompareItems);
01591             break;
01592 
01593         default:
01594             TRACE("-- COMMAND 0x%04x unhandled\n", dwCmdID);
01595     }
01596 
01597     return 0;
01598 }
01599 
01600 /**********************************************************
01601 * ShellView_OnNotify()
01602 */
01603 
01604 LRESULT CDefView::OnNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
01605 {
01606     UINT                                CtlID;
01607     LPNMHDR                                lpnmh;
01608     LPNMLISTVIEW                        lpnmlv;
01609     NMLVDISPINFOW                        *lpdi;
01610     LPITEMIDLIST                        pidl;
01611     BOOL                                unused;
01612 
01613     CtlID = wParam;
01614     lpnmh = (LPNMHDR)lParam;
01615     lpnmlv = (LPNMLISTVIEW)lpnmh;
01616     lpdi = (NMLVDISPINFOW *)lpnmh;
01617 
01618     TRACE("%p CtlID=%u lpnmh->code=%x\n", this, CtlID, lpnmh->code);
01619 
01620     switch (lpnmh->code)
01621     {
01622         case NM_SETFOCUS:
01623             TRACE("-- NM_SETFOCUS %p\n", this);
01624             OnSetFocus(0, 0, 0, unused);
01625             break;
01626 
01627         case NM_KILLFOCUS:
01628             TRACE("-- NM_KILLFOCUS %p\n", this);
01629             OnDeactivate();
01630             /* Notify the ICommDlgBrowser interface */
01631             OnStateChange(CDBOSC_KILLFOCUS);
01632             break;
01633 
01634         case NM_CUSTOMDRAW:
01635             TRACE("-- NM_CUSTOMDRAW %p\n", this);
01636             return CDRF_DODEFAULT;
01637 
01638         case NM_RELEASEDCAPTURE:
01639             TRACE("-- NM_RELEASEDCAPTURE %p\n", this);
01640             break;
01641 
01642         case NM_CLICK:
01643             TRACE("-- NM_CLICK %p\n", this);
01644             break;
01645 
01646         case NM_RCLICK:
01647             TRACE("-- NM_RCLICK %p\n", this);
01648             break;
01649 
01650         case NM_DBLCLK:
01651             TRACE("-- NM_DBLCLK %p\n", this);
01652             if (OnDefaultCommand() != S_OK) OpenSelectedItems();
01653             break;
01654 
01655         case NM_RETURN:
01656             TRACE("-- NM_RETURN %p\n", this);
01657             if (OnDefaultCommand() != S_OK) OpenSelectedItems();
01658             break;
01659 
01660         case HDN_ENDTRACKW:
01661             TRACE("-- HDN_ENDTRACKW %p\n", this);
01662             /*nColumn1 = ListView_GetColumnWidth(hWndList, 0);
01663             nColumn2 = ListView_GetColumnWidth(hWndList, 1);*/
01664             break;
01665 
01666         case LVN_DELETEITEM:
01667             TRACE("-- LVN_DELETEITEM %p\n", this);
01668             SHFree((LPITEMIDLIST)lpnmlv->lParam);     /*delete the pidl because we made a copy of it*/
01669             break;
01670 
01671         case LVN_DELETEALLITEMS:
01672             TRACE("-- LVN_DELETEALLITEMS %p\n", this);
01673             return FALSE;
01674 
01675         case LVN_INSERTITEM:
01676             TRACE("-- LVN_INSERTITEM (STUB)%p\n", this);
01677             break;
01678 
01679         case LVN_ITEMACTIVATE:
01680             TRACE("-- LVN_ITEMACTIVATE %p\n", this);
01681             OnStateChange(CDBOSC_SELCHANGE);  /* the browser will get the IDataObject now */
01682             break;
01683 
01684         case LVN_COLUMNCLICK:
01685             ListViewSortInfo.nHeaderID = lpnmlv->iSubItem;
01686             if (ListViewSortInfo.nLastHeaderID == ListViewSortInfo.nHeaderID)
01687             {
01688                 ListViewSortInfo.bIsAscending = !ListViewSortInfo.bIsAscending;
01689             }
01690             else
01691             {
01692                 ListViewSortInfo.bIsAscending = TRUE;
01693             }
01694             ListViewSortInfo.nLastHeaderID = ListViewSortInfo.nHeaderID;
01695 
01696             SendMessageW(lpnmlv->hdr.hwndFrom, LVM_SORTITEMS, (WPARAM) &ListViewSortInfo, (LPARAM)ListViewCompareItems);
01697             break;
01698 
01699         case LVN_GETDISPINFOA:
01700         case LVN_GETDISPINFOW:
01701             TRACE("-- LVN_GETDISPINFO %p\n", this);
01702             pidl = (LPITEMIDLIST)lpdi->item.lParam;
01703 
01704             if (lpdi->item.mask & LVIF_TEXT)    /* text requested */
01705             {
01706                 if (pSF2Parent)
01707                 {
01708                     SHELLDETAILS sd;
01709                     if (FAILED(pSF2Parent->GetDetailsOf(pidl, lpdi->item.iSubItem, &sd)))
01710                     {
01711                         FIXME("failed to get details\n");
01712                         break;
01713                     }
01714 
01715                     if (lpnmh->code == LVN_GETDISPINFOA)
01716                     {
01717                         /* shouldn't happen */
01718                         NMLVDISPINFOA *lpdiA = (NMLVDISPINFOA *)lpnmh;
01719                         StrRetToStrNA( lpdiA->item.pszText, lpdiA->item.cchTextMax, &sd.str, NULL);
01720                         TRACE("-- text=%s\n", lpdiA->item.pszText);
01721                     }
01722                     else /* LVN_GETDISPINFOW */
01723                     {
01724                         StrRetToStrNW( lpdi->item.pszText, lpdi->item.cchTextMax, &sd.str, NULL);
01725                         TRACE("-- text=%s\n", debugstr_w(lpdi->item.pszText));
01726                     }
01727                 }
01728                 else
01729                 {
01730                     FIXME("no SF2\n");
01731                 }
01732             }
01733             if(lpdi->item.mask & LVIF_IMAGE)    /* image requested */
01734             {
01735                 lpdi->item.iImage = SHMapPIDLToSystemImageListIndex(pSFParent, pidl, 0);
01736             }
01737             lpdi->item.mask |= LVIF_DI_SETITEM;
01738             break;
01739 
01740         case LVN_ITEMCHANGED:
01741             TRACE("-- LVN_ITEMCHANGED %p\n", this);
01742             OnStateChange(CDBOSC_SELCHANGE);  /* the browser will get the IDataObject now */
01743             break;
01744 
01745         case LVN_BEGINDRAG:
01746         case LVN_BEGINRDRAG:
01747             TRACE("-- LVN_BEGINDRAG\n");
01748 
01749             if (GetSelections())
01750             {
01751                 IDataObject * pda;
01752                 DWORD dwAttributes = SFGAO_CANLINK;
01753                 DWORD dwEffect = DROPEFFECT_COPY | DROPEFFECT_MOVE;
01754 
01755                 if (SUCCEEDED(pSFParent->GetUIObjectOf(m_hWnd, cidl, (LPCITEMIDLIST*)apidl, IID_IDataObject, 0, (LPVOID *)&pda)))
01756                 {
01757                     IDropSource * pds = (IDropSource *)this;    /* own DropSource interface */
01758 
01759                     if (SUCCEEDED(pSFParent->GetAttributesOf(cidl, (LPCITEMIDLIST*)apidl, &dwAttributes)))
01760                     {
01761                         if (dwAttributes & SFGAO_CANLINK)
01762                         {
01763                             dwEffect |= DROPEFFECT_LINK;
01764                         }
01765                     }
01766 
01767                     if (pds)
01768                     {
01769                         DWORD dwEffect2;
01770                         DoDragDrop(pda, pds, dwEffect, &dwEffect2);
01771                     }
01772                     pda->Release();
01773                 }
01774             }
01775             break;
01776 
01777         case LVN_BEGINLABELEDITW:
01778         {
01779             DWORD dwAttr = SFGAO_CANRENAME;
01780             pidl = (LPITEMIDLIST)lpdi->item.lParam;
01781 
01782             TRACE("-- LVN_BEGINLABELEDITW %p\n", this);
01783 
01784             pSFParent->GetAttributesOf(1, (LPCITEMIDLIST*)&pidl, &dwAttr);
01785             if (SFGAO_CANRENAME & dwAttr)
01786             {
01787                 return FALSE;
01788             }
01789             return TRUE;
01790         }
01791 
01792         case LVN_ENDLABELEDITW:
01793         {
01794             TRACE("-- LVN_ENDLABELEDITW %p\n", this);
01795             if (lpdi->item.pszText)
01796             {
01797                 HRESULT hr;
01798                 LVITEMW lvItem;
01799 
01800                 lvItem.iItem = lpdi->item.iItem;
01801                 lvItem.iSubItem = 0;
01802                 lvItem.mask = LVIF_PARAM;
01803                 SendMessageW(hWndList, LVM_GETITEMW, 0, (LPARAM) &lvItem);
01804 
01805                 pidl = (LPITEMIDLIST)lpdi->item.lParam;
01806                 hr = pSFParent->SetNameOf(0, pidl, lpdi->item.pszText, SHGDN_INFOLDER, &pidl);
01807 
01808                 if (SUCCEEDED(hr) && pidl)
01809                 {
01810                     lvItem.mask = LVIF_PARAM|LVIF_IMAGE;
01811                     lvItem.lParam = (LPARAM)pidl;
01812                     lvItem.iImage = SHMapPIDLToSystemImageListIndex(pSFParent, pidl, 0);
01813                     SendMessageW(hWndList, LVM_SETITEMW, 0, (LPARAM) &lvItem);
01814                     SendMessageW(hWndList, LVM_UPDATE, lpdi->item.iItem, 0);
01815 
01816                     return TRUE;
01817                 }
01818             }
01819 
01820             return FALSE;
01821         }
01822 
01823         case LVN_KEYDOWN:
01824         {
01825             /*  MSG msg;
01826                 msg.hwnd = m_hWnd;
01827                 msg.message = WM_KEYDOWN;
01828                 msg.wParam = plvKeyDown->wVKey;
01829                 msg.lParam = 0;
01830                 msg.time = 0;
01831                 msg.pt = 0;*/
01832 
01833             LPNMLVKEYDOWN plvKeyDown = (LPNMLVKEYDOWN) lpnmh;
01834             SHORT ctrl = GetKeyState(VK_CONTROL) & 0x8000;
01835 
01836             /* initiate a rename of the selected file or directory */
01837             if (plvKeyDown->wVKey == VK_F2)
01838             {
01839                 /* see how many files are selected */
01840                 int i = ListView_GetSelectedCount(hWndList);
01841 
01842                 /* get selected item */
01843                 if (i == 1)
01844                 {
01845                     /* get selected item */
01846                     i = ListView_GetNextItem(hWndList, -1, LVNI_SELECTED);
01847 
01848                     SendMessageW(hWndList, LVM_ENSUREVISIBLE, i, 0);
01849                     SendMessageW(hWndList, LVM_EDITLABELW, i, 0);
01850                 }
01851             }
01852 #if 0
01853             TranslateAccelerator(m_hWnd, hAccel, &msg)
01854 #endif
01855             else if(plvKeyDown->wVKey == VK_DELETE)
01856             {
01857                 UINT i;
01858                 int item_index;
01859                 LVITEMA item;
01860                 LPITEMIDLIST* pItems;
01861                 ISFHelper *psfhlp;
01862 
01863                 pSFParent->QueryInterface(IID_ISFHelper,
01864                                           (LPVOID*)&psfhlp);
01865 
01866                 if (psfhlp == NULL)
01867                     break;
01868 
01869                 if (!(i = ListView_GetSelectedCount(hWndList)))
01870                     break;
01871 
01872                 /* allocate memory for the pidl array */
01873                 pItems = (LPITEMIDLIST *)HeapAlloc(GetProcessHeap(), 0,
01874                                                    sizeof(LPITEMIDLIST) * i);
01875 
01876                 /* retrieve all selected items */
01877                 i = 0;
01878                 item_index = -1;
01879                 while (ListView_GetSelectedCount(hWndList) > i)
01880                 {
01881                     /* get selected item */
01882                     item_index = ListView_GetNextItem(hWndList,
01883                                                       item_index, LVNI_SELECTED);
01884                     item.iItem = item_index;
01885                     item.mask = LVIF_PARAM;
01886                     SendMessageA(hWndList, LVM_GETITEMA, 0, (LPARAM) &item);
01887 
01888                     /* get item pidl */
01889                     pItems[i] = (LPITEMIDLIST)item.lParam;
01890 
01891                     i++;
01892                 }
01893 
01894                 /* perform the item deletion */
01895                 psfhlp->DeleteItems(i, (LPCITEMIDLIST*)pItems);
01896 
01897                 /* free pidl array memory */
01898                 HeapFree(GetProcessHeap(), 0, pItems);
01899             }
01900             /* Initiate a refresh */
01901             else if (plvKeyDown->wVKey == VK_F5)
01902             {
01903                 Refresh();
01904             }
01905             else if (plvKeyDown->wVKey == VK_BACK)
01906             {
01907                 LPSHELLBROWSER lpSb;
01908                 if ((lpSb = (LPSHELLBROWSER)SendMessageW(hWndParent, CWM_GETISHELLBROWSER, 0, 0)))
01909                 {
01910                     lpSb->BrowseObject(NULL, SBSP_PARENT);
01911                 }
01912             }
01913             else if (plvKeyDown->wVKey == 'C' && ctrl)
01914             {
01915                 if (GetSelections())
01916                 {
01917                     CComPtr<IDataObject> pda;
01918 
01919                     if (SUCCEEDED(pSFParent->GetUIObjectOf(m_hWnd, cidl, (LPCITEMIDLIST*)apidl, IID_IDataObject, 0, (LPVOID *)&pda)))
01920                     {
01921                         HRESULT hr = OleSetClipboard(pda);
01922                         if (FAILED(hr))
01923                         {
01924                             WARN("OleSetClipboard failed");
01925                         }
01926                     }
01927                 }
01928                 break;
01929             }
01930             else if(plvKeyDown->wVKey == 'V' && ctrl)
01931             {
01932                 CComPtr<IDataObject> pda;
01933                 STGMEDIUM medium;
01934                 FORMATETC formatetc;
01935                 LPITEMIDLIST * apidl;
01936                 LPITEMIDLIST pidl;
01937                 CComPtr<IShellFolder> psfFrom;
01938                 CComPtr<IShellFolder> psfDesktop;
01939                 CComPtr<IShellFolder> psfTarget;
01940                 LPIDA lpcida;
01941                 CComPtr<ISFHelper> psfhlpdst;
01942                 CComPtr<ISFHelper> psfhlpsrc;
01943                 HRESULT hr;
01944 
01945                 hr = OleGetClipboard(&pda);
01946                 if (hr != S_OK)
01947                 {
01948                     ERR("Failed to get clipboard with %lx\n", hr);
01949                     return E_FAIL;
01950                 }
01951 
01952                 InitFormatEtc(formatetc, RegisterClipboardFormatW(CFSTR_SHELLIDLIST), TYMED_HGLOBAL);
01953                 hr = pda->GetData(&formatetc, &medium);
01954 
01955                 if (FAILED(hr))
01956                 {
01957                     ERR("Failed to get clipboard data with %lx\n", hr);
01958                     return E_FAIL;
01959                 }
01960 
01961                 /* lock the handle */
01962                 lpcida = (LPIDA)GlobalLock(medium.hGlobal);
01963                 if (!lpcida)
01964                 {
01965                     ERR("failed to lock pidl\n");
01966                     ReleaseStgMedium(&medium);
01967                     return E_FAIL;
01968                 }
01969 
01970                 /* convert the data into pidl */
01971                 apidl = _ILCopyCidaToaPidl(&pidl, lpcida);
01972 
01973                 if (!apidl)
01974                 {
01975                     ERR("failed to copy pidl\n");
01976                     return E_FAIL;
01977                 }
01978 
01979                 if (FAILED(SHGetDesktopFolder(&psfDesktop)))
01980                 {
01981                     ERR("failed to get desktop folder\n");
01982                     SHFree(pidl);
01983                     _ILFreeaPidl(apidl, lpcida->cidl);
01984                     ReleaseStgMedium(&medium);
01985                     return E_FAIL;
01986                 }
01987 
01988                 if (_ILIsDesktop(pidl))
01989                 {
01990                     /* use desktop shellfolder */
01991                     psfFrom = psfDesktop;
01992                 }
01993                 else if (FAILED(psfDesktop->BindToObject(pidl, NULL, IID_IShellFolder, (LPVOID*)&psfFrom)))
01994                 {
01995                     ERR("no IShellFolder\n");
01996 
01997                     SHFree(pidl);
01998                     _ILFreeaPidl(apidl, lpcida->cidl);
01999                     ReleaseStgMedium(&medium);
02000 
02001                     return E_FAIL;
02002                 }
02003 
02004                 psfTarget = pSFParent;
02005 
02006 
02007                 /* get source and destination shellfolder */
02008                 if (FAILED(psfTarget->QueryInterface(IID_ISFHelper, (LPVOID*)&psfhlpdst)))
02009                 {
02010                     ERR("no IID_ISFHelper for destination\n");
02011 
02012                     SHFree(pidl);
02013                     _ILFreeaPidl(apidl, lpcida->cidl);
02014                     ReleaseStgMedium(&medium);
02015 
02016                     return E_FAIL;
02017                 }
02018 
02019                 if (FAILED(psfFrom->QueryInterface(IID_ISFHelper, (LPVOID*)&psfhlpsrc)))
02020                 {
02021                     ERR("no IID_ISFHelper for source\n");
02022 
02023                     SHFree(pidl);
02024                     _ILFreeaPidl(apidl, lpcida->cidl);
02025                     ReleaseStgMedium(&medium);
02026                     return E_FAIL;
02027                 }
02028 
02029                 /* FIXXME
02030                 * do we want to perform a copy or move ???
02031                 */
02032                 hr = psfhlpdst->CopyItems(psfFrom, lpcida->cidl, (LPCITEMIDLIST*)apidl);
02033 
02034                 SHFree(pidl);
02035                 _ILFreeaPidl(apidl, lpcida->cidl);
02036                 ReleaseStgMedium(&medium);
02037 
02038                 TRACE("paste end hr %x\n", hr);
02039                 break;
02040             }
02041             else
02042                 FIXME("LVN_KEYDOWN key=0x%08x\n", plvKeyDown->wVKey);
02043         }
02044         break;
02045 
02046         default:
02047             TRACE("-- %p WM_COMMAND %x unhandled\n", this, lpnmh->code);
02048             break;
02049     }
02050 
02051     return 0;
02052 }
02053 
02054 /**********************************************************
02055 * ShellView_OnChange()
02056 */
02057 LRESULT CDefView::OnChangeNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
02058 {
02059     LPITEMIDLIST                        *Pidls;
02060 
02061     Pidls = (LPITEMIDLIST *)wParam;
02062 
02063     TRACE("(%p)(%p,%p,0x%08x)\n", this, Pidls[0], Pidls[1], lParam);
02064 
02065     switch (lParam)
02066     {
02067         case SHCNE_MKDIR:
02068         case SHCNE_CREATE:
02069             LV_AddItem(Pidls[0]);
02070             break;
02071 
02072         case SHCNE_RMDIR:
02073         case SHCNE_DELETE:
02074             LV_DeleteItem(Pidls[0]);
02075             break;
02076 
02077         case SHCNE_RENAMEFOLDER:
02078         case SHCNE_RENAMEITEM:
02079             LV_RenameItem(Pidls[0], Pidls[1]);
02080             break;
02081 
02082         case SHCNE_UPDATEITEM:
02083             break;
02084     }
02085 
02086     return TRUE;
02087 }
02088 
02089 /**********************************************************
02090 *  CDefView::OnCustomItem
02091 */
02092 LRESULT CDefView::OnCustomItem(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
02093 {
02094     if (!pCM.p)
02095     {
02096         /* no menu */
02097         ERR("no menu!!!\n");
02098         return FALSE;
02099     }
02100 
02101     if (pCM.p->HandleMenuMsg(uMsg, (WPARAM)m_hWnd, lParam) == S_OK)
02102         return TRUE;
02103     else
02104         return FALSE;
02105 }
02106 
02107 LRESULT CDefView::OnSettingChange(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
02108 {
02109     /* Wallpaper setting affects drop shadows effect */
02110     if (wParam == SPI_SETDESKWALLPAPER || wParam == 0)
02111         UpdateListColors();
02112 
02113     return S_OK;
02114 }
02115 
02116 /**********************************************************
02117 *
02118 *
02119 *  The INTERFACE of the IShellView object
02120 *
02121 *
02122 **********************************************************
02123 */
02124 
02125 /**********************************************************
02126 *  ShellView_GetWindow
02127 */
02128 HRESULT WINAPI CDefView::GetWindow(HWND *phWnd)
02129 {
02130     TRACE("(%p)\n", this);
02131 
02132     *phWnd = m_hWnd;
02133 
02134     return S_OK;
02135 }
02136 
02137 HRESULT WINAPI CDefView::ContextSensitiveHelp(BOOL fEnterMode)
02138 {
02139     FIXME("(%p) stub\n", this);
02140 
02141     return E_NOTIMPL;
02142 }
02143 
02144 /**********************************************************
02145 * IShellView_TranslateAccelerator
02146 *
02147 * FIXME:
02148 *  use the accel functions
02149 */
02150 HRESULT WINAPI CDefView::TranslateAccelerator(LPMSG lpmsg)
02151 {
02152 #if 0
02153     FIXME("(%p)->(%p: hwnd=%x msg=%x lp=%x wp=%x) stub\n", this, lpmsg, lpmsg->hwnd, lpmsg->message, lpmsg->lParam, lpmsg->wParam);
02154 #endif
02155 
02156     if (lpmsg->message >= WM_KEYFIRST && lpmsg->message >= WM_KEYLAST)
02157     {
02158         TRACE("-- key=0x04%lx\n", lpmsg->wParam) ;
02159     }
02160 
02161     return S_FALSE; /* not handled */
02162 }
02163 
02164 HRESULT WINAPI CDefView::EnableModeless(BOOL fEnable)
02165 {
02166     FIXME("(%p) stub\n", this);
02167 
02168     return E_NOTIMPL;
02169 }
02170 
02171 HRESULT WINAPI CDefView::UIActivate(UINT uState)
02172 {
02173     /*
02174         CHAR    szName[MAX_PATH];
02175     */
02176     LRESULT    lResult;
02177     int    nPartArray[1] = { -1};
02178 
02179     TRACE("(%p)->(state=%x) stub\n", this, uState);
02180 
02181     /*don't do anything if the state isn't really changing*/
02182     if (this->uState == uState)
02183     {
02184         return S_OK;
02185     }
02186 
02187     /*OnActivate handles the menu merging and internal state*/
02188     DoActivate(uState);
02189 
02190     /*only do This if we are active*/
02191     if (uState != SVUIA_DEACTIVATE)
02192     {
02193 
02194         /*
02195             GetFolderPath is not a method of IShellFolder
02196             IShellFolder_GetFolderPath( pSFParent, szName, sizeof(szName) );
02197         */
02198         /* set the number of parts */
02199         pShellBrowser->SendControlMsg(FCW_STATUS, SB_SETPARTS, 1, (LPARAM)nPartArray, &lResult);
02200 
02201         /* set the text for the parts */
02202         /*
02203             pShellBrowser->SendControlMsg(FCW_STATUS, SB_SETTEXTA, 0, (LPARAM)szName, &lResult);
02204         */
02205     }
02206 
02207     return S_OK;
02208 }
02209 
02210 HRESULT WINAPI CDefView::Refresh()
02211 {
02212     TRACE("(%p)\n", this);
02213 
02214     SendMessageW(hWndList, LVM_DELETEALLITEMS, 0, 0);
02215     FillList();
02216 
02217     return S_OK;
02218 }
02219 
02220 HRESULT WINAPI CDefView::CreateViewWindow(IShellView *lpPrevView, LPCFOLDERSETTINGS lpfs, IShellBrowser *psb, RECT *prcView, HWND *phWnd)
02221 {
02222     *phWnd = 0;
02223 
02224     TRACE("(%p)->(shlview=%p set=%p shlbrs=%p rec=%p hwnd=%p) incomplete\n", this, lpPrevView, lpfs, psb, prcView, phWnd);
02225 
02226     if (lpfs != NULL)
02227         TRACE("-- vmode=%x flags=%x\n", lpfs->ViewMode, lpfs->fFlags);
02228     if (prcView != NULL)
02229         TRACE("-- left=%i top=%i right=%i bottom=%i\n", prcView->left, prcView->top, prcView->right, prcView->bottom);
02230 
02231     /* Validate the Shell Browser */
02232     if (psb == NULL)
02233         return E_UNEXPECTED;
02234 
02235     /*set up the member variables*/
02236     pShellBrowser = psb;
02237     FolderSettings = *lpfs;
02238 
02239     /*get our parent window*/
02240     pShellBrowser->GetWindow(&hWndParent);
02241 
02242     /* try to get the ICommDlgBrowserInterface, adds a reference !!! */
02243     pCommDlgBrowser = NULL;
02244     if (SUCCEEDED(pShellBrowser->QueryInterface(IID_ICommDlgBrowser, (LPVOID *)&pCommDlgBrowser)))
02245     {
02246         TRACE("-- CommDlgBrowser\n");
02247     }
02248 
02249     Create(hWndParent, prcView, NULL, WS_CHILD | WS_TABSTOP, 0, 0U);
02250     if (m_hWnd == NULL)
02251         return E_FAIL;
02252 
02253     *phWnd = m_hWnd;
02254 
02255     CheckToolbar();
02256 
02257     if (!*phWnd)
02258         return E_FAIL;
02259 
02260     SetWindowPos(HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
02261     UpdateWindow();
02262 
02263     return S_OK;
02264 }
02265 
02266 HRESULT WINAPI CDefView::DestroyViewWindow()
02267 {
02268     TRACE("(%p)\n", this);
02269 
02270     /*Make absolutely sure all our UI is cleaned up.*/
02271     UIActivate(SVUIA_DEACTIVATE);
02272 
02273     if (hMenu)
02274     {
02275         DestroyMenu(hMenu);
02276     }
02277 
02278     DestroyWindow();
02279     pShellBrowser.Release();
02280     pCommDlgBrowser.Release();
02281 
02282     return S_OK;
02283 }
02284 
02285 HRESULT WINAPI CDefView::GetCurrentInfo(LPFOLDERSETTINGS lpfs)
02286 {
02287     TRACE("(%p)->(%p) vmode=%x flags=%x\n", this, lpfs,
02288           FolderSettings.ViewMode, FolderSettings.fFlags);
02289 
02290     if (!lpfs)
02291         return E_INVALIDARG;
02292 
02293     *lpfs = FolderSettings;
02294     return NOERROR;
02295 }
02296 
02297 HRESULT WINAPI CDefView::AddPropertySheetPages(DWORD dwReserved, LPFNADDPROPSHEETPAGE lpfn, LPARAM lparam)
02298 {
02299     FIXME("(%p) stub\n", this);
02300 
02301     return E_NOTIMPL;
02302 }
02303 
02304 HRESULT WINAPI CDefView::SaveViewState()
02305 {
02306     FIXME("(%p) stub\n", this);
02307 
02308     return S_OK;
02309 }
02310 
02311 HRESULT WINAPI CDefView::SelectItem(LPCITEMIDLIST pidl, UINT uFlags)
02312 {
02313     int i;
02314 
02315     TRACE("(%p)->(pidl=%p, 0x%08x) stub\n", this, pidl, uFlags);
02316 
02317     i = LV_FindItemByPidl(pidl);
02318 
02319     if (i != -1)
02320     {
02321         LVITEMW lvItem;
02322 
02323         if(uFlags & SVSI_ENSUREVISIBLE)
02324             SendMessageW(hWndList, LVM_ENSUREVISIBLE, i, 0);
02325 
02326         lvItem.mask = LVIF_STATE;
02327         lvItem.stateMask = LVIS_SELECTED | LVIS_FOCUSED;
02328         lvItem.iItem = 0;
02329         lvItem.iSubItem = 0;
02330 
02331         while (SendMessageW(hWndList, LVM_GETITEMW, 0, (LPARAM) &lvItem))
02332         {
02333             if (lvItem.iItem == i)
02334             {
02335                 if (uFlags & SVSI_SELECT)
02336                     lvItem.state |= LVIS_SELECTED;
02337                 else
02338                     lvItem.state &= ~LVIS_SELECTED;
02339 
02340                 if (uFlags & SVSI_FOCUSED)
02341                     lvItem.state &= ~LVIS_FOCUSED;
02342             }
02343             else
02344             {
02345                 if (uFlags & SVSI_DESELECTOTHERS)
02346                     lvItem.state &= ~LVIS_SELECTED;
02347             }
02348 
02349             SendMessageW(hWndList, LVM_SETITEMW, 0, (LPARAM) &lvItem);
02350             lvItem.iItem++;
02351         }
02352 
02353 
02354         if(uFlags & SVSI_EDIT)
02355             SendMessageW(hWndList, LVM_EDITLABELW, i, 0);
02356     }
02357 
02358     return S_OK;
02359 }
02360 
02361 HRESULT WINAPI CDefView::GetItemObject(UINT uItem, REFIID riid, LPVOID *ppvOut)
02362 {
02363     HRESULT hr = E_NOINTERFACE;
02364 
02365     TRACE("(%p)->(uItem=0x%08x,\n\tIID=%s, ppv=%p)\n", this, uItem, debugstr_guid(&riid), ppvOut);
02366 
02367     *ppvOut = NULL;
02368 
02369     switch (uItem)
02370     {
02371         case SVGIO_BACKGROUND:
02372             if (IsEqualIID(riid, IID_IContextMenu))
02373             {
02374                 //*ppvOut = ISvBgCm_Constructor(pSFParent, FALSE);
02375                 CDefFolderMenu_Create2(NULL, NULL, cidl, (LPCITEMIDLIST*)apidl, pSFParent, NULL, 0, NULL, (IContextMenu**)ppvOut);
02376                 if (!ppvOut)
02377                     hr = E_OUTOFMEMORY;
02378                 else
02379                     hr = S_OK;
02380             }
02381             break;
02382 
02383         case SVGIO_SELECTION:
02384             GetSelections();
02385             hr = pSFParent->GetUIObjectOf(m_hWnd, cidl, (LPCITEMIDLIST*)apidl, riid, 0, ppvOut);
02386             break;
02387     }
02388 
02389     TRACE("-- (%p)->(interface=%p)\n", this, *ppvOut);
02390 
02391     return hr;
02392 }
02393 
02394 HRESULT STDMETHODCALLTYPE CDefView::GetCurrentViewMode(UINT *pViewMode)
02395 {
02396     TRACE("(%p)->(%p), stub\n", this, pViewMode);
02397 
02398     if (!pViewMode)
02399         return E_INVALIDARG;
02400 
02401     *pViewMode = this->FolderSettings.ViewMode;
02402     return S_OK;
02403 }
02404 
02405 HRESULT STDMETHODCALLTYPE CDefView::SetCurrentViewMode(UINT ViewMode)
02406 {
02407     DWORD dwStyle;
02408     TRACE("(%p)->(%u), stub\n", this, ViewMode);
02409 
02410     if ((ViewMode < FVM_FIRST || ViewMode > FVM_LAST) /* && (ViewMode != FVM_AUTO) */ )
02411         return E_INVALIDARG;
02412 
02413     /* Windows before Vista uses LVM_SETVIEW and possibly
02414        LVM_SETEXTENDEDLISTVIEWSTYLE to set the style of the listview,
02415        while later versions seem to accomplish this through other
02416        means. */
02417     switch (ViewMode)
02418     {
02419         case FVM_ICON:
02420             dwStyle = LVS_ICON;
02421             break;
02422         case FVM_DETAILS:
02423             dwStyle = LVS_REPORT;
02424             break;
02425         case FVM_SMALLICON:
02426             dwStyle = LVS_SMALLICON;
02427             break;
02428         case FVM_LIST:
02429             dwStyle = LVS_LIST;
02430             break;
02431         default:
02432         {
02433             FIXME("ViewMode %d not implemented\n", ViewMode);
02434             dwStyle = LVS_LIST;
02435             break;
02436         }
02437     }
02438 
02439     SetStyle(dwStyle, LVS_TYPEMASK);
02440 
02441     /* This will not necessarily be the actual mode set above.
02442        This mimics the behavior of Windows XP. */
02443     this->FolderSettings.ViewMode = ViewMode;
02444 
02445     return S_OK;
02446 }
02447 
02448 HRESULT STDMETHODCALLTYPE CDefView::GetFolder(REFIID riid, void **ppv)
02449 {
02450     if (pSFParent == NULL)
02451         return E_FAIL;
02452 
02453     return pSFParent->QueryInterface(riid, ppv);
02454 }
02455 
02456 HRESULT STDMETHODCALLTYPE CDefView::Item(int iItemIndex, LPITEMIDLIST *ppidl)
02457 {
02458     LVITEMW item;
02459 
02460     TRACE("(%p)->(%d %p)\n", this, iItemIndex, ppidl);
02461 
02462     item.mask = LVIF_PARAM;
02463     item.iItem = iItemIndex;
02464 
02465     if (SendMessageW(this->hWndList, LVM_GETITEMW, 0, (LPARAM)&item))
02466     {
02467         *ppidl = ILClone((PITEMID_CHILD)item.lParam);
02468         return S_OK;
02469     }
02470 
02471     *ppidl = 0;
02472 
02473     return E_INVALIDARG;
02474 }
02475 
02476 HRESULT STDMETHODCALLTYPE CDefView::ItemCount(UINT uFlags, int *pcItems)
02477 {
02478     TRACE("(%p)->(%u %p)\n", this, uFlags, pcItems);
02479 
02480     if (uFlags != SVGIO_ALLVIEW)
02481         FIXME("some flags unsupported, %x\n", uFlags & ~SVGIO_ALLVIEW);
02482 
02483     *pcItems = SendMessageW(this->hWndList, LVM_GETITEMCOUNT, 0, 0);
02484 
02485     return S_OK;
02486 }
02487 
02488 HRESULT STDMETHODCALLTYPE CDefView::Items(UINT uFlags, REFIID riid, void **ppv)
02489 {
02490     return E_NOTIMPL;
02491 }
02492 
02493 HRESULT STDMETHODCALLTYPE CDefView::GetSelectionMarkedItem(int *piItem)
02494 {
02495     TRACE("(%p)->(%p)\n", this, piItem);
02496 
02497     *piItem = SendMessageW(this->hWndList, LVM_GETSELECTIONMARK, 0, 0);
02498 
02499     return S_OK;
02500 }
02501 
02502 HRESULT STDMETHODCALLTYPE CDefView::GetFocusedItem(int *piItem)
02503 {
02504     TRACE("(%p)->(%p)\n", this, piItem);
02505 
02506     *piItem = SendMessageW(this->hWndList, LVM_GETNEXTITEM, -1, LVNI_FOCUSED);
02507 
02508     return S_OK;
02509 }
02510 
02511 HRESULT STDMETHODCALLTYPE CDefView::GetItemPosition(LPCITEMIDLIST pidl, POINT *ppt)
02512 {
02513     return E_NOTIMPL;
02514 }
02515 
02516 HRESULT STDMETHODCALLTYPE CDefView::GetSpacing(POINT *ppt)
02517 {
02518     TRACE("(%p)->(%p)\n", this, ppt);
02519 
02520     if (NULL == this->hWndList) return S_FALSE;
02521 
02522     if (ppt)
02523     {
02524         const DWORD ret = SendMessageW(this->hWndList, LVM_GETITEMSPACING, 0, 0);
02525 
02526         ppt->x = LOWORD(ret);
02527         ppt->y = HIWORD(ret);
02528     }
02529 
02530     return S_OK;
02531 }
02532 
02533 HRESULT STDMETHODCALLTYPE CDefView::GetDefaultSpacing(POINT *ppt)
02534 {
02535     return E_NOTIMPL;
02536 }
02537 
02538 HRESULT STDMETHODCALLTYPE CDefView::GetAutoArrange()
02539 {
02540     return E_NOTIMPL;
02541 }
02542 
02543 HRESULT STDMETHODCALLTYPE CDefView::SelectItem(int iItem, DWORD dwFlags)
02544 {
02545     LVITEMW lvItem;
02546 
02547     TRACE("(%p)->(%d, %x)\n", this, iItem, dwFlags);
02548 
02549     lvItem.state = 0;
02550     lvItem.stateMask = LVIS_SELECTED;
02551 
02552     if (dwFlags & SVSI_ENSUREVISIBLE)
02553         SendMessageW(this->hWndList, LVM_ENSUREVISIBLE, iItem, 0);
02554 
02555     /* all items */
02556     if (dwFlags & SVSI_DESELECTOTHERS)
02557         SendMessageW(this->hWndList, LVM_SETITEMSTATE, -1, (LPARAM)&lvItem);
02558 
02559     /* this item */
02560     if (dwFlags & SVSI_SELECT)
02561         lvItem.state |= LVIS_SELECTED;
02562 
02563     if (dwFlags & SVSI_FOCUSED)
02564         lvItem.stateMask |= LVIS_FOCUSED;
02565 
02566     SendMessageW(this->hWndList, LVM_SETITEMSTATE, iItem, (LPARAM)&lvItem);
02567 
02568     if (dwFlags & SVSI_EDIT)
02569         SendMessageW(this->hWndList, LVM_EDITLABELW, iItem, 0);
02570 
02571     return S_OK;
02572 }
02573 
02574 HRESULT STDMETHODCALLTYPE CDefView::SelectAndPositionItems(UINT cidl, LPCITEMIDLIST *apidl, POINT *apt, DWORD dwFlags)
02575 {
02576     return E_NOTIMPL;
02577 }
02578 
02579 /**********************************************************
02580  * ISVOleCmdTarget_QueryStatus (IOleCommandTarget)
02581  */
02582 HRESULT WINAPI CDefView::QueryStatus(const GUID *pguidCmdGroup, ULONG cCmds, OLECMD *prgCmds, OLECMDTEXT *pCmdText)
02583 {
02584     FIXME("(%p)->(%p(%s) 0x%08x %p %p\n",
02585           this, pguidCmdGroup, debugstr_guid(pguidCmdGroup), cCmds, prgCmds, pCmdText);
02586 
02587     if (!prgCmds)
02588         return E_INVALIDARG;
02589 
02590     for (UINT i = 0; i < cCmds; i++)
02591     {
02592         FIXME("\tprgCmds[%d].cmdID = %d\n", i, prgCmds[i].cmdID);
02593         prgCmds[i].cmdf = 0;
02594     }
02595 
02596     return OLECMDERR_E_UNKNOWNGROUP;
02597 }
02598 
02599 /**********************************************************
02600  * ISVOleCmdTarget_Exec (IOleCommandTarget)
02601  *
02602  * nCmdID is the OLECMDID_* enumeration
02603  */
02604 HRESULT WINAPI CDefView::Exec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
02605 {
02606     FIXME("(%p)->(\n\tTarget GUID:%s Command:0x%08x Opt:0x%08x %p %p)\n",
02607           this, debugstr_guid(pguidCmdGroup), nCmdID, nCmdexecopt, pvaIn, pvaOut);
02608 
02609     if (!pguidCmdGroup)
02610         return OLECMDERR_E_UNKNOWNGROUP;
02611 
02612     if (IsEqualIID(*pguidCmdGroup, CGID_Explorer) &&
02613             (nCmdID == 0x29) &&
02614             (nCmdexecopt == 4) && pvaOut)
02615         return S_OK;
02616 
02617     if (IsEqualIID(*pguidCmdGroup, CGID_ShellDocView) &&
02618             (nCmdID == 9) &&
02619             (nCmdexecopt == 0))
02620         return 1;
02621 
02622     return OLECMDERR_E_UNKNOWNGROUP;
02623 }
02624 
02625 /**********************************************************
02626  * ISVDropTarget implementation
02627  */
02628 
02629 /******************************************************************************
02630  * drag_notify_subitem [Internal]
02631  *
02632  * Figure out the shellfolder object, which is currently under the mouse cursor
02633  * and notify it via the IDropTarget interface.
02634  */
02635 
02636 #define SCROLLAREAWIDTH 20
02637 
02638 HRESULT CDefView::drag_notify_subitem(DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
02639 {
02640     LVHITTESTINFO htinfo;
02641     LVITEMW lvItem;
02642     LONG lResult;
02643     HRESULT hr;
02644     RECT clientRect;
02645 
02646     /* Map from global to client coordinates and query the index of the listview-item, which is
02647      * currently under the mouse cursor. */
02648     htinfo.pt.x = pt.x;
02649     htinfo.pt.y = pt.y;
02650     htinfo.flags = LVHT_ONITEM;
02651     ::ScreenToClient(hWndList, &htinfo.pt);
02652     lResult = SendMessageW(hWndList, LVM_HITTEST, 0, (LPARAM)&htinfo);
02653 
02654     /* Send WM_*SCROLL messages every 250 ms during drag-scrolling */
02655     ::GetClientRect(hWndList, &clientRect);
02656     if (htinfo.pt.x == ptLastMousePos.x && htinfo.pt.y == ptLastMousePos.y &&
02657             (htinfo.pt.x < SCROLLAREAWIDTH || htinfo.pt.x > clientRect.right - SCROLLAREAWIDTH ||
02658              htinfo.pt.y < SCROLLAREAWIDTH || htinfo.pt.y > clientRect.bottom - SCROLLAREAWIDTH ))
02659     {
02660         cScrollDelay = (cScrollDelay + 1) % 5; /* DragOver is called every 50 ms */
02661         if (cScrollDelay == 0)
02662         {
02663             /* Mouse did hover another 250 ms over the scroll-area */
02664             if (htinfo.pt.x < SCROLLAREAWIDTH)
02665                 SendMessageW(hWndList, WM_HSCROLL, SB_LINEUP, 0);
02666 
02667             if (htinfo.pt.x > clientRect.right - SCROLLAREAWIDTH)
02668                 SendMessageW(hWndList, WM_HSCROLL, SB_LINEDOWN, 0);
02669 
02670             if (htinfo.pt.y < SCROLLAREAWIDTH)
02671                 SendMessageW(hWndList, WM_VSCROLL, SB_LINEUP, 0);
02672 
02673             if (htinfo.pt.y > clientRect.bottom - SCROLLAREAWIDTH)
02674                 SendMessageW(hWndList, WM_VSCROLL, SB_LINEDOWN, 0);
02675         }
02676     }
02677     else
02678     {
02679         cScrollDelay = 0; /* Reset, if the cursor is not over the listview's scroll-area */
02680     }
02681 
02682     ptLastMousePos = htinfo.pt;
02683 
02684     /* If we are still over the previous sub-item, notify it via DragOver and return. */
02685     if (pCurDropTarget && lResult == iDragOverItem)
02686         return pCurDropTarget->DragOver(grfKeyState, pt, pdwEffect);
02687 
02688     /* We've left the previous sub-item, notify it via DragLeave and Release it. */
02689     if (pCurDropTarget)
02690     {
02691         pCurDropTarget->DragLeave();
02692         pCurDropTarget.Release();
02693     }
02694 
02695     iDragOverItem = lResult;
02696     if (lResult == -1)
02697     {
02698         /* We are not above one of the listview's subitems. Bind to the parent folder's
02699          * DropTarget interface. */
02700         hr = pSFParent->QueryInterface(IID_IDropTarget,
02701                                        (LPVOID*)&pCurDropTarget);
02702     }
02703     else
02704     {
02705         /* Query the relative PIDL of the shellfolder object represented by the currently
02706          * dragged over listview-item ... */
02707         lvItem.mask = LVIF_PARAM;
02708         lvItem.iItem = lResult;
02709         lvItem.iSubItem = 0;
02710         SendMessageW(hWndList, LVM_GETITEMW, 0, (LPARAM) &lvItem);
02711 
02712         /* ... and bind pCurDropTarget to the IDropTarget interface of an UIObject of this object */
02713         hr = pSFParent->GetUIObjectOf(hWndList, 1,
02714                                       (LPCITEMIDLIST*)&lvItem.lParam, IID_IDropTarget, NULL, (LPVOID*)&pCurDropTarget);
02715     }
02716 
02717     /* If anything failed, pCurDropTarget should be NULL now, which ought to be a save state. */
02718     if (FAILED(hr))
02719         return hr;
02720 
02721     /* Notify the item just entered via DragEnter. */
02722     return pCurDropTarget->DragEnter(pCurDataObject, grfKeyState, pt, pdwEffect);
02723 }
02724 
02725 HRESULT WINAPI CDefView::DragEnter(IDataObject *pDataObject, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
02726 {
02727     /* Get a hold on the data object for later calls to DragEnter on the sub-folders */
02728     pCurDataObject = pDataObject;
02729     pDataObject->AddRef();
02730 
02731     return drag_notify_subitem(grfKeyState, pt, pdwEffect);
02732 }
02733 
02734 HRESULT WINAPI CDefView::DragOver(DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
02735 {
02736     return drag_notify_subitem(grfKeyState, pt, pdwEffect);
02737 }
02738 
02739 HRESULT WINAPI CDefView::DragLeave()
02740 {
02741     if (pCurDropTarget)
02742     {
02743         pCurDropTarget->DragLeave();
02744         pCurDropTarget.Release();
02745     }
02746 
02747     if (pCurDataObject != NULL)
02748     {
02749         pCurDataObject.Release();
02750     }
02751 
02752     iDragOverItem = 0;
02753 
02754     return S_OK;
02755 }
02756 
02757 HRESULT WINAPI CDefView::Drop(IDataObject* pDataObject, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
02758 {
02759     if (pCurDropTarget)
02760     {
02761         pCurDropTarget->Drop(pDataObject, grfKeyState, pt, pdwEffect);
02762         pCurDropTarget.Release();
02763     }
02764 
02765     pCurDataObject.Release();
02766     iDragOverItem = 0;
02767 
02768     return S_OK;
02769 }
02770 
02771 /**********************************************************
02772  * ISVDropSource implementation
02773  */
02774 
02775 HRESULT WINAPI CDefView::QueryContinueDrag(BOOL fEscapePressed, DWORD grfKeyState)
02776 {
02777     TRACE("(%p)\n", this);
02778 
02779     if (fEscapePressed)
02780         return DRAGDROP_S_CANCEL;
02781     else if (!(grfKeyState & MK_LBUTTON) && !(grfKeyState & MK_RBUTTON))
02782         return DRAGDROP_S_DROP;
02783     else
02784         return NOERROR;
02785 }
02786 
02787 HRESULT WINAPI CDefView::GiveFeedback(DWORD dwEffect)
02788 {
02789     TRACE("(%p)\n", this);
02790 
02791     return DRAGDROP_S_USEDEFAULTCURSORS;
02792 }
02793 
02794 /**********************************************************
02795  * ISVViewObject implementation
02796  */
02797 
02798 HRESULT WINAPI CDefView::Draw(DWORD dwDrawAspect, LONG lindex, void *pvAspect, DVTARGETDEVICE *ptd, HDC hdcTargetDev, HDC hdcDraw, LPCRECTL lprcBounds, LPCRECTL lprcWBounds, BOOL (CALLBACK *pfnContinue)(ULONG_PTR dwContinue), ULONG_PTR dwContinue)
02799 {
02800     FIXME("Stub: this=%p\n", this);
02801 
02802     return E_NOTIMPL;
02803 }
02804 
02805 HRESULT WINAPI CDefView::GetColorSet(DWORD dwDrawAspect, LONG lindex, void *pvAspect, DVTARGETDEVICE *ptd, HDC hicTargetDevice, LOGPALETTE **ppColorSet)
02806 {
02807     FIXME("Stub: this=%p\n", this);
02808 
02809     return E_NOTIMPL;
02810 }
02811 
02812 HRESULT WINAPI CDefView::Freeze(DWORD dwDrawAspect, LONG lindex, void *pvAspect, DWORD *pdwFreeze)
02813 {
02814     FIXME("Stub: this=%p\n", this);
02815 
02816     return E_NOTIMPL;
02817 }
02818 
02819 HRESULT WINAPI CDefView::Unfreeze(DWORD dwFreeze)
02820 {
02821     FIXME("Stub: this=%p\n", this);
02822 
02823     return E_NOTIMPL;
02824 }
02825 
02826 HRESULT WINAPI CDefView::SetAdvise(DWORD aspects, DWORD advf, IAdviseSink *pAdvSink)
02827 {
02828     FIXME("partial stub: %p %08x %08x %p\n", this, aspects, advf, pAdvSink);
02829 
02830     /* FIXME: we set the AdviseSink, but never use it to send any advice */
02831     pAdvSink = pAdvSink;
02832     dwAspects = aspects;
02833     dwAdvf = advf;
02834 
02835     return S_OK;
02836 }
02837 
02838 HRESULT WINAPI CDefView::GetAdvise(DWORD *pAspects, DWORD *pAdvf, IAdviseSink **ppAdvSink)
02839 {
02840     TRACE("this=%p pAspects=%p pAdvf=%p ppAdvSink=%p\n", this, pAspects, pAdvf, ppAdvSink);
02841 
02842     if (ppAdvSink)
02843     {
02844         *ppAdvSink = pAdvSink;
02845         pAdvSink.p->AddRef();
02846     }
02847 
02848     if (pAspects)
02849         *pAspects = dwAspects;
02850 
02851     if (pAdvf)
02852         *pAdvf = dwAdvf;
02853 
02854     return S_OK;
02855 }
02856 
02857 HRESULT STDMETHODCALLTYPE CDefView::QueryService(REFGUID guidService, REFIID riid, void **ppvObject)
02858 {
02859     if (IsEqualIID(guidService, SID_IShellBrowser))
02860         return pShellBrowser->QueryInterface(riid, ppvObject);
02861     else if(IsEqualIID(guidService, SID_IFolderView))
02862         return QueryInterface(riid, ppvObject);
02863 
02864     return E_NOINTERFACE;
02865 }
02866 
02867 /**********************************************************
02868  *    IShellView_Constructor
02869  */
02870 HRESULT WINAPI IShellView_Constructor(IShellFolder *pFolder, IShellView **newView)
02871 {
02872     CComObject<CDefView>                    *theView;
02873     CComPtr<IShellView>                        result;
02874     HRESULT                                    hResult;
02875 
02876     if (newView == NULL)
02877         return E_POINTER;
02878 
02879     *newView = NULL;
02880     ATLTRY (theView = new CComObject<CDefView>);
02881 
02882     if (theView == NULL)
02883         return E_OUTOFMEMORY;
02884 
02885     hResult = theView->QueryInterface (IID_IShellView, (void **)&result);
02886     if (FAILED (hResult))
02887     {
02888         delete theView;
02889         return hResult;
02890     }
02891 
02892     hResult = theView->Initialize (pFolder);
02893     if (FAILED (hResult))
02894         return hResult;
02895     *newView = result.Detach ();
02896 
02897     return S_OK;
02898 }

Generated on Sun May 27 2012 04:26:28 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.