* The Shell.. for a long time we dreamed of having a compatible, properly working...
[reactos.git] / reactos / dll / win32 / shell32 / CDefView.cpp
similarity index 68%
rename from reactos/dll/win32/shell32/shlview.cpp
rename to reactos/dll/win32/shell32/CDefView.cpp
index 00db983..1d0264b 100644 (file)
@@ -51,6 +51,7 @@ TODO:
 #include "precomp.h"
 
 #include <atlwin.h>
+#include <rosctrls.h>
 
 WINE_DEFAULT_DEBUG_CHANNEL(shell);
 
@@ -59,7 +60,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(shell);
 static const WCHAR SV_CLASS_NAME[] = {'S', 'H', 'E', 'L', 'L', 'D', 'L', 'L', '_', 'D', 'e', 'f', 'V', 'i', 'e', 'w', 0};
 
 typedef struct
-{   BOOL    bIsAscending;
+{
+    BOOL    bIsAscending;
     INT     nHeaderID;
     INT     nLastHeaderID;
 } LISTVIEW_SORT_INFO, *LPLISTVIEW_SORT_INFO;
@@ -71,6 +73,7 @@ class CDefView :
     public CComObjectRootEx<CComMultiThreadModelNoCS>,
     public IShellView,
     public IFolderView,
+    public IShellFolderView,
     public IOleCommandTarget,
     public IDropTarget,
     public IDropSource,
@@ -82,13 +85,14 @@ class CDefView :
         CComPtr<IShellFolder2>    m_pSF2Parent;
         CComPtr<IShellBrowser>    m_pShellBrowser;
         CComPtr<ICommDlgBrowser>  m_pCommDlgBrowser;
-        HWND                      m_hWndList;            /* ListView control */
+        CListView                 m_ListView;
         HWND                      m_hWndParent;
         FOLDERSETTINGS            m_FolderSettings;
         HMENU                     m_hMenu;
+        BOOL                      m_menusLoaded;
         UINT                      m_uState;
         UINT                      m_cidl;
-        LPITEMIDLIST              *m_apidl;
+        PCUITEMID_CHILD_ARRAY     m_apidl;
         LISTVIEW_SORT_INFO        m_sortInfo;
         ULONG                     m_hNotify;            /* change notification handle */
         HACCEL                    m_hAccel;
@@ -103,11 +107,20 @@ class CDefView :
         POINT                     m_ptLastMousePos;        /* Mouse position at last DragOver call */
         //
         CComPtr<IContextMenu>     m_pCM;
+
+        BOOL                      m_isEditing;
+
+        CLSID m_Category;
+        HMENU m_hView;
+    private:
+
+        HRESULT _MergeToolbar();
+
     public:
         CDefView();
         ~CDefView();
         HRESULT WINAPI Initialize(IShellFolder *shellFolder);
-        HRESULT IncludeObject(LPCITEMIDLIST pidl);
+        HRESULT IncludeObject(PCUITEMID_CHILD pidl);
         HRESULT OnDefaultCommand();
         HRESULT OnStateChange(UINT uFlags);
         void CheckToolbar();
@@ -116,16 +129,19 @@ class CDefView :
         void UpdateListColors();
         BOOL InitList();
         static INT CALLBACK CompareItems(LPVOID lParam1, LPVOID lParam2, LPARAM lpData);
-        static INT CALLBACK ListViewCompareItems(LPVOID lParam1, LPVOID lParam2, LPARAM lpData);
-        int LV_FindItemByPidl(LPCITEMIDLIST pidl);
-        BOOLEAN LV_AddItem(LPCITEMIDLIST pidl);
-        BOOLEAN LV_DeleteItem(LPCITEMIDLIST pidl);
-        BOOLEAN LV_RenameItem(LPCITEMIDLIST pidlOld, LPCITEMIDLIST pidlNew);
+        static INT CALLBACK ListViewCompareItems(LPARAM lParam1, LPARAM lParam2, LPARAM lpData);
+
+        PCUITEMID_CHILD _PidlByItem(int i);
+        PCUITEMID_CHILD _PidlByItem(LVITEM& lvItem);
+        int LV_FindItemByPidl(PCUITEMID_CHILD pidl);
+        BOOLEAN LV_AddItem(PCUITEMID_CHILD pidl);
+        BOOLEAN LV_DeleteItem(PCUITEMID_CHILD pidl);
+        BOOLEAN LV_RenameItem(PCUITEMID_CHILD pidlOld, PCUITEMID_CHILD pidlNew);
         static INT CALLBACK fill_list(LPVOID ptr, LPVOID arg);
         HRESULT FillList();
         HMENU BuildFileMenu();
-        void MergeFileMenu(HMENU hSubMenu);
-        void MergeViewMenu(HMENU hSubMenu);
+        void PrepareShowFileMenu(HMENU hSubMenu);
+        void PrepareShowViewMenu(HMENU hSubMenu);
         UINT GetSelections();
         HRESULT OpenSelectedItems();
         void OnDeactivate();
@@ -147,25 +163,54 @@ class CDefView :
         virtual HRESULT STDMETHODCALLTYPE GetCurrentInfo(LPFOLDERSETTINGS pfs);
         virtual HRESULT STDMETHODCALLTYPE AddPropertySheetPages(DWORD dwReserved, LPFNSVADDPROPSHEETPAGE pfn, LPARAM lparam);
         virtual HRESULT STDMETHODCALLTYPE SaveViewState();
-        virtual HRESULT STDMETHODCALLTYPE SelectItem(LPCITEMIDLIST pidlItem, SVSIF uFlags);
+        virtual HRESULT STDMETHODCALLTYPE SelectItem(PCUITEMID_CHILD pidlItem, SVSIF uFlags);
         virtual HRESULT STDMETHODCALLTYPE GetItemObject(UINT uItem, REFIID riid, void **ppv);
 
         // *** IFolderView methods ***
         virtual HRESULT STDMETHODCALLTYPE GetCurrentViewMode(UINT *pViewMode);
         virtual HRESULT STDMETHODCALLTYPE SetCurrentViewMode(UINT ViewMode);
         virtual HRESULT STDMETHODCALLTYPE GetFolder(REFIID riid, void **ppv);
-        virtual HRESULT STDMETHODCALLTYPE Item(int iItemIndex, LPITEMIDLIST *ppidl);
+        virtual HRESULT STDMETHODCALLTYPE Item(int iItemIndex, PITEMID_CHILD *ppidl);
         virtual HRESULT STDMETHODCALLTYPE ItemCount(UINT uFlags, int *pcItems);
         virtual HRESULT STDMETHODCALLTYPE Items(UINT uFlags, REFIID riid, void **ppv);
         virtual HRESULT STDMETHODCALLTYPE GetSelectionMarkedItem(int *piItem);
         virtual HRESULT STDMETHODCALLTYPE GetFocusedItem(int *piItem);
-        virtual HRESULT STDMETHODCALLTYPE GetItemPosition(LPCITEMIDLIST pidl, POINT *ppt);
+        virtual HRESULT STDMETHODCALLTYPE GetItemPosition(PCUITEMID_CHILD pidl, POINT *ppt);
         virtual HRESULT STDMETHODCALLTYPE GetSpacing(POINT *ppt);
         virtual HRESULT STDMETHODCALLTYPE GetDefaultSpacing(POINT *ppt);
         virtual HRESULT STDMETHODCALLTYPE GetAutoArrange();
         virtual HRESULT STDMETHODCALLTYPE SelectItem(int iItem, DWORD dwFlags);
         virtual HRESULT STDMETHODCALLTYPE SelectAndPositionItems(UINT cidl, PCUITEMID_CHILD_ARRAY apidl, POINT *apt, DWORD dwFlags);
 
+        // *** IShellFolderView methods ***
+        virtual HRESULT STDMETHODCALLTYPE Rearrange(LPARAM sort);
+        virtual HRESULT STDMETHODCALLTYPE GetArrangeParam(LPARAM *sort);
+        virtual HRESULT STDMETHODCALLTYPE ArrangeGrid();
+        virtual HRESULT STDMETHODCALLTYPE AutoArrange();
+        virtual HRESULT STDMETHODCALLTYPE AddObject(PITEMID_CHILD pidl, UINT *item);
+        virtual HRESULT STDMETHODCALLTYPE GetObject(PITEMID_CHILD *pidl, UINT item);
+        virtual HRESULT STDMETHODCALLTYPE RemoveObject(PITEMID_CHILD pidl, UINT *item);
+        virtual HRESULT STDMETHODCALLTYPE GetObjectCount(UINT *count);
+        virtual HRESULT STDMETHODCALLTYPE SetObjectCount(UINT count, UINT flags);
+        virtual HRESULT STDMETHODCALLTYPE UpdateObject(PITEMID_CHILD pidl_old, PITEMID_CHILD pidl_new, UINT *item);
+        virtual HRESULT STDMETHODCALLTYPE RefreshObject(PITEMID_CHILD pidl, UINT *item);
+        virtual HRESULT STDMETHODCALLTYPE SetRedraw(BOOL redraw);
+        virtual HRESULT STDMETHODCALLTYPE GetSelectedCount(UINT *count);
+        virtual HRESULT STDMETHODCALLTYPE GetSelectedObjects(PCUITEMID_CHILD **pidl, UINT *items);
+        virtual HRESULT STDMETHODCALLTYPE IsDropOnSource(IDropTarget *drop_target);
+        virtual HRESULT STDMETHODCALLTYPE GetDragPoint(POINT *pt);
+        virtual HRESULT STDMETHODCALLTYPE GetDropPoint(POINT *pt);
+        virtual HRESULT STDMETHODCALLTYPE MoveIcons(IDataObject *obj);
+        virtual HRESULT STDMETHODCALLTYPE SetItemPos(PCUITEMID_CHILD pidl, POINT *pt);
+        virtual HRESULT STDMETHODCALLTYPE IsBkDropTarget(IDropTarget *drop_target);
+        virtual HRESULT STDMETHODCALLTYPE SetClipboard(BOOL move);
+        virtual HRESULT STDMETHODCALLTYPE SetPoints(IDataObject *obj);
+        virtual HRESULT STDMETHODCALLTYPE GetItemSpacing(ITEMSPACING *spacing);
+        virtual HRESULT STDMETHODCALLTYPE SetCallback(IShellFolderViewCB *new_cb, IShellFolderViewCB **old_cb);
+        virtual HRESULT STDMETHODCALLTYPE Select(UINT flags);
+        virtual HRESULT STDMETHODCALLTYPE QuerySupport(UINT *support);
+        virtual HRESULT STDMETHODCALLTYPE SetAutomationObject(IDispatch *disp);
+
         // *** IOleCommandTarget methods ***
         virtual HRESULT STDMETHODCALLTYPE QueryStatus(const GUID *pguidCmdGroup, ULONG cCmds, OLECMD prgCmds[  ], OLECMDTEXT *pCmdText);
         virtual HRESULT STDMETHODCALLTYPE Exec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut);
@@ -212,6 +257,7 @@ class CDefView :
         LRESULT OnChangeNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
         LRESULT OnCustomItem(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
         LRESULT OnSettingChange(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
+        LRESULT OnInitMenuPopup(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
 
         static ATL::CWndClassInfo& GetWndClassInfo()
         {
@@ -263,12 +309,14 @@ class CDefView :
         MESSAGE_HANDLER(WM_SYSCOLORCHANGE, OnSysColorChange)
         MESSAGE_HANDLER(CWM_GETISHELLBROWSER, OnGetShellBrowser)
         MESSAGE_HANDLER(WM_SETTINGCHANGE, OnSettingChange)
+        MESSAGE_HANDLER(WM_INITMENUPOPUP, OnInitMenuPopup)
         END_MSG_MAP()
 
         BEGIN_COM_MAP(CDefView)
         COM_INTERFACE_ENTRY_IID(IID_IOleWindow, IOleWindow)
         COM_INTERFACE_ENTRY_IID(IID_IShellView, IShellView)
         COM_INTERFACE_ENTRY_IID(IID_IFolderView, IFolderView)
+        COM_INTERFACE_ENTRY_IID(IID_IShellFolderView, IShellFolderView)
         COM_INTERFACE_ENTRY_IID(IID_IOleCommandTarget, IOleCommandTarget)
         COM_INTERFACE_ENTRY_IID(IID_IDropTarget, IDropTarget)
         COM_INTERFACE_ENTRY_IID(IID_IDropSource, IDropSource)
@@ -296,56 +344,40 @@ class CDefView :
 #define GET_WM_COMMAND_HWND(wp, lp)             (HWND)(lp)
 #define GET_WM_COMMAND_CMD(wp, lp)              HIWORD(wp)
 
-/*
-  Items merged into the toolbar and the filemenu
-*/
-typedef struct
-{   int   idCommand;
-    int   iImage;
-    int   idButtonString;
-    int   idMenuString;
-    BYTE  bState;
-    BYTE  bStyle;
-} MYTOOLINFO, *LPMYTOOLINFO;
-
-static const MYTOOLINFO Tools[] =
-{
-    { FCIDM_SHVIEW_BIGICON,    0, 0, IDS_VIEW_LARGE,   TBSTATE_ENABLED, BTNS_BUTTON },
-    { FCIDM_SHVIEW_SMALLICON,  0, 0, IDS_VIEW_SMALL,   TBSTATE_ENABLED, BTNS_BUTTON },
-    { FCIDM_SHVIEW_LISTVIEW,   0, 0, IDS_VIEW_LIST,    TBSTATE_ENABLED, BTNS_BUTTON },
-    { FCIDM_SHVIEW_REPORTVIEW, 0, 0, IDS_VIEW_DETAILS, TBSTATE_ENABLED, BTNS_BUTTON },
-    { -1, 0, 0, 0, 0, 0}
-};
-
 typedef void (CALLBACK *PFNSHGETSETTINGSPROC)(LPSHELLFLAGSTATE lpsfs, DWORD dwMask);
 
-CDefView::CDefView()
-{
-    m_hWndList = NULL;
-    m_hWndParent = NULL;
-    m_FolderSettings.fFlags = 0;
-    m_FolderSettings.ViewMode = 0;
-    m_hMenu = NULL;
-    m_uState = 0;
-    m_cidl = 0;
-    m_apidl = NULL;
-    m_sortInfo.bIsAscending = FALSE;
-    m_sortInfo.nHeaderID = 0;
-    m_sortInfo.nLastHeaderID = 0;
-    m_hNotify = 0;
-    m_hAccel = NULL;
-    m_dwAspects = 0;
-    m_dwAdvf = 0;
-    m_iDragOverItem = 0;
-    m_cScrollDelay = 0;
-    m_ptLastMousePos.x = 0;
-    m_ptLastMousePos.y = 0;
+CDefView::CDefView() :
+    m_ListView(),
+    m_hWndParent(NULL),
+    m_hMenu(NULL),
+    m_menusLoaded(FALSE),
+    m_uState(0),
+    m_cidl(0),
+    m_apidl(NULL),
+    m_hNotify(0),
+    m_hAccel(NULL),
+    m_dwAspects(0),
+    m_dwAdvf(0),
+    m_iDragOverItem(0),
+    m_cScrollDelay(0),
+    m_isEditing(FALSE),
+    m_hView(NULL)
+{
+    ZeroMemory(&m_FolderSettings, sizeof(m_FolderSettings));
+    ZeroMemory(&m_sortInfo, sizeof(m_sortInfo));
+    ZeroMemory(&m_ptLastMousePos, sizeof(m_ptLastMousePos));
+    ZeroMemory(&m_Category, sizeof(m_Category));
 }
 
 CDefView::~CDefView()
 {
     TRACE(" destroying IShellView(%p)\n", this);
 
+    if (m_hWnd)
+    {
+        DestroyViewWindow();
+    }
+
     SHFree(m_apidl);
 }
 
@@ -361,14 +393,14 @@ HRESULT WINAPI CDefView::Initialize(IShellFolder *shellFolder)
  *
  * ##### helperfunctions for communication with ICommDlgBrowser #####
  */
-HRESULT CDefView::IncludeObject(LPCITEMIDLIST pidl)
+HRESULT CDefView::IncludeObject(PCUITEMID_CHILD pidl)
 {
     HRESULT ret = S_OK;
 
     if (m_pCommDlgBrowser.p != NULL)
     {
         TRACE("ICommDlgBrowser::IncludeObject pidl=%p\n", pidl);
-        ret = m_pCommDlgBrowser->IncludeObject((IShellView *)this, pidl);
+        ret = m_pCommDlgBrowser->IncludeObject(this, pidl);
         TRACE("--0x%08x\n", ret);
     }
 
@@ -382,7 +414,7 @@ HRESULT CDefView::OnDefaultCommand()
     if (m_pCommDlgBrowser.p != NULL)
     {
         TRACE("ICommDlgBrowser::OnDefaultCommand\n");
-        ret = m_pCommDlgBrowser->OnDefaultCommand((IShellView *)this);
+        ret = m_pCommDlgBrowser->OnDefaultCommand(this);
         TRACE("-- returns %08x\n", ret);
     }
 
@@ -396,7 +428,7 @@ HRESULT CDefView::OnStateChange(UINT uFlags)
     if (m_pCommDlgBrowser.p != NULL)
     {
         TRACE("ICommDlgBrowser::OnStateChange flags=%x\n", uFlags);
-        ret = m_pCommDlgBrowser->OnStateChange((IShellView *)this, uFlags);
+        ret = m_pCommDlgBrowser->OnStateChange(this, uFlags);
         TRACE("--\n");
     }
 
@@ -440,8 +472,8 @@ void CDefView::SetStyle(DWORD dwAdd, DWORD dwRemove)
 
     TRACE("(%p)\n", this);
 
-    tmpstyle = ::GetWindowLongPtrW(m_hWndList, GWL_STYLE);
-    ::SetWindowLongPtrW(m_hWndList, GWL_STYLE, dwAdd | (tmpstyle & ~dwRemove));
+    tmpstyle = ::GetWindowLongPtrW(m_ListView, GWL_STYLE);
+    ::SetWindowLongPtrW(m_ListView, GWL_STYLE, dwAdd | (tmpstyle & ~dwRemove));
 }
 
 /**********************************************************
@@ -461,7 +493,7 @@ BOOL CDefView::CreateList()
     if (m_FolderSettings.fFlags & FWF_DESKTOP)
         dwStyle |= LVS_ALIGNLEFT;
     else
-        dwStyle |= LVS_ALIGNTOP;
+        dwStyle |= LVS_ALIGNTOP | LVS_SHOWSELALWAYS;
 
     switch (m_FolderSettings.ViewMode)
     {
@@ -498,17 +530,10 @@ BOOL CDefView::CreateList()
     if (m_FolderSettings.fFlags & FWF_NOCLIENTEDGE)
         dwExStyle &= ~WS_EX_CLIENTEDGE;
 
-    m_hWndList = CreateWindowExW( dwExStyle,
-                                  WC_LISTVIEWW,
-                                  NULL,
-                                  dwStyle,
-                                  0, 0, 0, 0,
-                                  m_hWnd,
-                                  (HMENU)ID_LISTVIEW,
-                                  shell32_hInstance,
-                                  NULL);
-
-    if (!m_hWndList)
+    RECT rcListView = {0,0,0,0};
+    m_ListView.Create(m_hWnd, rcListView, NULL,dwStyle, dwExStyle, ID_LISTVIEW);
+
+    if (!m_ListView)
         return FALSE;
 
     m_sortInfo.bIsAscending = TRUE;
@@ -534,21 +559,21 @@ void CDefView::UpdateListColors()
                      L"ListviewShadow", RRF_RT_DWORD, NULL, &bDropShadow, &cbDropShadow);
         if (bDropShadow && SystemParametersInfoW(SPI_GETDESKWALLPAPER, _countof(wszBuf), wszBuf, 0) && wszBuf[0])
         {
-            SendMessageW(m_hWndList, LVM_SETTEXTBKCOLOR, 0, CLR_NONE);
-            SendMessageW(m_hWndList, LVM_SETBKCOLOR, 0, CLR_NONE);
-            SendMessageW(m_hWndList, LVM_SETTEXTCOLOR, 0, RGB(255, 255, 255));
-            SendMessageW(m_hWndList, LVM_SETEXTENDEDLISTVIEWSTYLE, LVS_EX_TRANSPARENTSHADOWTEXT, LVS_EX_TRANSPARENTSHADOWTEXT);
+            m_ListView.SetTextBkColor(CLR_NONE);
+            m_ListView.SetBkColor(CLR_NONE);
+            m_ListView.SetTextColor(RGB(255, 255, 255));
+            m_ListView.SetExtendedListViewStyle(LVS_EX_TRANSPARENTSHADOWTEXT, LVS_EX_TRANSPARENTSHADOWTEXT);
         }
         else
         {
             COLORREF crDesktop = GetSysColor(COLOR_DESKTOP);
-            SendMessageW(m_hWndList, LVM_SETTEXTBKCOLOR, 0, crDesktop);
-            SendMessageW(m_hWndList, LVM_SETBKCOLOR, 0, crDesktop);
+            m_ListView.SetTextBkColor(crDesktop);
+            m_ListView.SetBkColor(crDesktop);
             if (GetRValue(crDesktop) + GetGValue(crDesktop) + GetBValue(crDesktop) > 128 * 3)
-                SendMessageW(m_hWndList, LVM_SETTEXTCOLOR, 0, RGB(0, 0, 0));
+                m_ListView.SetTextColor(RGB(0, 0, 0));
             else
-                SendMessageW(m_hWndList, LVM_SETTEXTCOLOR, 0, RGB(255, 255, 255));
-            SendMessageW(m_hWndList, LVM_SETEXTENDEDLISTVIEWSTYLE, LVS_EX_TRANSPARENTSHADOWTEXT, 0);
+                m_ListView.SetTextColor(RGB(255, 255, 255));
+            m_ListView.SetExtendedListViewStyle(LVS_EX_TRANSPARENTSHADOWTEXT);
         }
     }
 }
@@ -560,16 +585,13 @@ void CDefView::UpdateListColors()
 */
 BOOL CDefView::InitList()
 {
-    LVCOLUMNW    lvColumn;
     SHELLDETAILS    sd;
     WCHAR    szTemp[50];
+    HIMAGELIST big_icons, small_icons;
 
     TRACE("%p\n", this);
 
-    SendMessageW(m_hWndList, LVM_DELETEALLITEMS, 0, 0);
-
-    lvColumn.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT;
-    lvColumn.pszText = szTemp;
+    m_ListView.DeleteAllItems();
 
     if (m_pSF2Parent)
     {
@@ -577,11 +599,9 @@ BOOL CDefView::InitList()
         {
             if (FAILED(m_pSF2Parent->GetDetailsOf(NULL, i, &sd)))
                 break;
-
-            lvColumn.fmt = sd.fmt;
-            lvColumn.cx = sd.cxChar * 8; /* chars->pixel */
             StrRetToStrNW( szTemp, 50, &sd.str, NULL);
-            SendMessageW(m_hWndList, LVM_INSERTCOLUMNW, i, (LPARAM) &lvColumn);
+            m_ListView.InsertColumn(i, szTemp, sd.fmt, sd.cxChar * 8);
+
         }
     }
     else
@@ -589,8 +609,9 @@ BOOL CDefView::InitList()
         FIXME("no SF2\n");
     }
 
-    SendMessageW(m_hWndList, LVM_SETIMAGELIST, LVSIL_SMALL, (LPARAM)ShellSmallIconList);
-    SendMessageW(m_hWndList, LVM_SETIMAGELIST, LVSIL_NORMAL, (LPARAM)ShellBigIconList);
+    Shell_GetImageLists(&big_icons, &small_icons);
+    m_ListView.SetImageList(big_icons, LVSIL_NORMAL);
+    m_ListView.SetImageList(small_icons, LVSIL_SMALL);
 
     return TRUE;
 }
@@ -609,7 +630,11 @@ INT CALLBACK CDefView::CompareItems(LPVOID lParam1, LPVOID lParam2, LPARAM lpDat
     if (!lpData)
         return 0;
 
-    ret = (SHORT)SCODE_CODE(((IShellFolder *)lpData)->CompareIDs(0, (LPITEMIDLIST)lParam1, (LPITEMIDLIST)lParam2));
+    IShellFolder* psf = reinterpret_cast<IShellFolder*>(lpData);
+    PCUIDLIST_RELATIVE pidl1 = reinterpret_cast<PCUIDLIST_RELATIVE>(lParam1);
+    PCUIDLIST_RELATIVE pidl2 = reinterpret_cast<PCUIDLIST_RELATIVE>(lParam2);
+
+    ret = (SHORT)SCODE_CODE(psf->CompareIDs(0, pidl1, pidl2));
     TRACE("ret=%i\n", ret);
 
     return ret;
@@ -639,19 +664,19 @@ INT CALLBACK CDefView::CompareItems(LPVOID lParam1, LPVOID lParam2, LPARAM lpDat
  *    the way this function works is only usable if we had only
  *    filesystemfolders  (25/10/99 jsch)
  */
-INT CALLBACK CDefView::ListViewCompareItems(LPVOID lParam1, LPVOID lParam2, LPARAM lpData)
+INT CALLBACK CDefView::ListViewCompareItems(LPARAM lParam1, LPARAM lParam2, LPARAM lpData)
 {
     INT nDiff = 0;
     FILETIME fd1, fd2;
     char strName1[MAX_PATH], strName2[MAX_PATH];
     BOOL bIsFolder1, bIsFolder2, bIsBothFolder;
-    LPITEMIDLIST pItemIdList1 = (LPITEMIDLIST) lParam1;
-    LPITEMIDLIST pItemIdList2 = (LPITEMIDLIST) lParam2;
-    LISTVIEW_SORT_INFO *pSortInfo = (LPLISTVIEW_SORT_INFO) lpData;
+    PCUIDLIST_RELATIVE pidl1 = reinterpret_cast<PCUIDLIST_RELATIVE>(lParam1);
+    PCUIDLIST_RELATIVE pidl2 = reinterpret_cast<PCUIDLIST_RELATIVE>(lParam2);
+    LISTVIEW_SORT_INFO *pSortInfo = reinterpret_cast<LPLISTVIEW_SORT_INFO>(lpData);
 
 
-    bIsFolder1 = _ILIsFolder(pItemIdList1);
-    bIsFolder2 = _ILIsFolder(pItemIdList2);
+    bIsFolder1 = _ILIsFolder(pidl1);
+    bIsFolder2 = _ILIsFolder(pidl2);
     bIsBothFolder = bIsFolder1 && bIsFolder2;
 
     /* When sorting between a File and a Folder, the Folder gets sorted first */
@@ -665,36 +690,36 @@ INT CALLBACK CDefView::ListViewCompareItems(LPVOID lParam1, LPVOID lParam2, LPAR
 
         if(pSortInfo->nHeaderID == LISTVIEW_COLUMN_TIME)
         {
-            _ILGetFileDateTime(pItemIdList1, &fd1);
-            _ILGetFileDateTime(pItemIdList2, &fd2);
+            _ILGetFileDateTime(pidl1, &fd1);
+            _ILGetFileDateTime(pidl2, &fd2);
             nDiff = CompareFileTime(&fd2, &fd1);
         }
         /* Sort by Attribute: Folder or Files can be sorted */
         else if(pSortInfo->nHeaderID == LISTVIEW_COLUMN_ATTRIB)
         {
-            _ILGetFileAttributes(pItemIdList1, strName1, MAX_PATH);
-            _ILGetFileAttributes(pItemIdList2, strName2, MAX_PATH);
+            _ILGetFileAttributes(pidl1, strName1, MAX_PATH);
+            _ILGetFileAttributes(pidl2, strName2, MAX_PATH);
             nDiff = lstrcmpiA(strName1, strName2);
         }
         /* Sort by FileName: Folder or Files can be sorted */
         else if (pSortInfo->nHeaderID == LISTVIEW_COLUMN_NAME || bIsBothFolder)
         {
             /* Sort by Text */
-            _ILSimpleGetText(pItemIdList1, strName1, MAX_PATH);
-            _ILSimpleGetText(pItemIdList2, strName2, MAX_PATH);
+            _ILSimpleGetText(pidl1, strName1, MAX_PATH);
+            _ILSimpleGetText(pidl2, strName2, MAX_PATH);
             nDiff = lstrcmpiA(strName1, strName2);
         }
         /* Sort by File Size, Only valid for Files */
         else if (pSortInfo->nHeaderID == LISTVIEW_COLUMN_SIZE)
         {
-            nDiff = (INT)(_ILGetFileSize(pItemIdList1, NULL, 0) - _ILGetFileSize(pItemIdList2, NULL, 0));
+            nDiff = (INT)(_ILGetFileSize(pidl1, NULL, 0) - _ILGetFileSize(pidl2, NULL, 0));
         }
         /* Sort by File Type, Only valid for Files */
         else if (pSortInfo->nHeaderID == LISTVIEW_COLUMN_TYPE)
         {
             /* Sort by Type */
-            _ILGetFileType(pItemIdList1, strName1, MAX_PATH);
-            _ILGetFileType(pItemIdList2, strName2, MAX_PATH);
+            _ILGetFileType(pidl1, strName1, MAX_PATH);
+            _ILGetFileType(pidl2, strName2, MAX_PATH);
             nDiff = lstrcmpiA(strName1, strName2);
         }
     }
@@ -702,8 +727,8 @@ INT CALLBACK CDefView::ListViewCompareItems(LPVOID lParam1, LPVOID lParam2, LPAR
 
     if (nDiff == 0)
     {
-        _ILSimpleGetText(pItemIdList1, strName1, MAX_PATH);
-        _ILSimpleGetText(pItemIdList2, strName2, MAX_PATH);
+        _ILSimpleGetText(pidl1, strName1, MAX_PATH);
+        _ILSimpleGetText(pidl2, strName2, MAX_PATH);
         nDiff = lstrcmpiA(strName1, strName2);
     }
 
@@ -715,25 +740,31 @@ INT CALLBACK CDefView::ListViewCompareItems(LPVOID lParam1, LPVOID lParam2, LPAR
     return nDiff;
 }
 
+PCUITEMID_CHILD CDefView::_PidlByItem(int i)
+{
+    return reinterpret_cast<PCUITEMID_CHILD>(m_ListView.GetItemData(i));
+}
+
+PCUITEMID_CHILD CDefView::_PidlByItem(LVITEM& lvItem)
+{
+    return reinterpret_cast<PCUITEMID_CHILD>(lvItem.lParam);
+}
+
 /**********************************************************
 *  LV_FindItemByPidl()
 */
-int CDefView::LV_FindItemByPidl(LPCITEMIDLIST pidl)
+int CDefView::LV_FindItemByPidl(PCUITEMID_CHILD pidl)
 {
-    LVITEMW lvItem;
-    lvItem.iSubItem = 0;
-    lvItem.mask = LVIF_PARAM;
+    int cItems = m_ListView.GetItemCount();
 
-    for (lvItem.iItem = 0;
-            SendMessageW(m_hWndList, LVM_GETITEMW, 0, (LPARAM) &lvItem);
-            lvItem.iItem++)
+    for (int i = 0; i<cItems; i++)
     {
-        LPITEMIDLIST currentpidl = (LPITEMIDLIST) lvItem.lParam;
+        PCUITEMID_CHILD currentpidl = _PidlByItem(i);
         HRESULT hr = m_pSFParent->CompareIDs(0, pidl, currentpidl);
 
         if (SUCCEEDED(hr) && !HRESULT_CODE(hr))
         {
-            return lvItem.iItem;
+            return i;
         }
     }
     return -1;
@@ -742,20 +773,20 @@ int CDefView::LV_FindItemByPidl(LPCITEMIDLIST pidl)
 /**********************************************************
 * LV_AddItem()
 */
-BOOLEAN CDefView::LV_AddItem(LPCITEMIDLIST pidl)
+BOOLEAN CDefView::LV_AddItem(PCUITEMID_CHILD pidl)
 {
     LVITEMW    lvItem;
 
     TRACE("(%p)(pidl=%p)\n", this, pidl);
 
     lvItem.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM;    /*set the mask*/
-    lvItem.iItem = ListView_GetItemCount(m_hWndList);    /*add the item to the end of the list*/
+    lvItem.iItem = m_ListView.GetItemCount();             /*add the item to the end of the list*/
     lvItem.iSubItem = 0;
-    lvItem.lParam = (LPARAM) ILClone(ILFindLastID(pidl));                /*set the item's data*/
-    lvItem.pszText = LPSTR_TEXTCALLBACKW;            /*get text on a callback basis*/
-    lvItem.iImage = I_IMAGECALLBACK;            /*get the image on a callback basis*/
+    lvItem.lParam = reinterpret_cast<LPARAM>(ILClone(pidl)); /*set the item's data*/
+    lvItem.pszText = LPSTR_TEXTCALLBACKW;                 /*get text on a callback basis*/
+    lvItem.iImage = I_IMAGECALLBACK;                      /*get the image on a callback basis*/
 
-    if (SendMessageW(m_hWndList, LVM_INSERTITEMW, 0, (LPARAM)&lvItem) == -1)
+    if (m_ListView.InsertItem(&lvItem) == -1)
         return FALSE;
     else
         return TRUE;
@@ -764,42 +795,42 @@ BOOLEAN CDefView::LV_AddItem(LPCITEMIDLIST pidl)
 /**********************************************************
 * LV_DeleteItem()
 */
-BOOLEAN CDefView::LV_DeleteItem(LPCITEMIDLIST pidl)
+BOOLEAN CDefView::LV_DeleteItem(PCUITEMID_CHILD pidl)
 {
     int nIndex;
 
     TRACE("(%p)(pidl=%p)\n", this, pidl);
 
-    nIndex = LV_FindItemByPidl(ILFindLastID(pidl));
+    nIndex = LV_FindItemByPidl(pidl);
 
-    return (-1 == ListView_DeleteItem(m_hWndList, nIndex)) ? FALSE : TRUE;
+    return (-1 == m_ListView.DeleteItem(nIndex)) ? FALSE : TRUE;
 }
 
 /**********************************************************
 * LV_RenameItem()
 */
-BOOLEAN CDefView::LV_RenameItem(LPCITEMIDLIST pidlOld, LPCITEMIDLIST pidlNew)
+BOOLEAN CDefView::LV_RenameItem(PCUITEMID_CHILD pidlOld, PCUITEMID_CHILD pidlNew)
 {
     int nItem;
     LVITEMW lvItem;
 
     TRACE("(%p)(pidlold=%p pidlnew=%p)\n", this, pidlOld, pidlNew);
 
-    nItem = LV_FindItemByPidl(ILFindLastID(pidlOld));
+    nItem = LV_FindItemByPidl(pidlOld);
 
     if ( -1 != nItem )
     {
         lvItem.mask = LVIF_PARAM;        /* only the pidl */
         lvItem.iItem = nItem;
-        SendMessageW(m_hWndList, LVM_GETITEMW, 0, (LPARAM) &lvItem);
+        m_ListView.GetItem(&lvItem);
 
-        SHFree((LPITEMIDLIST)lvItem.lParam);
+        SHFree(reinterpret_cast<LPVOID>(lvItem.lParam));
         lvItem.mask = LVIF_PARAM|LVIF_IMAGE;
         lvItem.iItem = nItem;
-        lvItem.lParam = (LPARAM) ILClone(ILFindLastID(pidlNew));    /* set the item's data */
+        lvItem.lParam = reinterpret_cast<LPARAM>(ILClone(pidlNew));    /* set the item's data */
         lvItem.iImage = SHMapPIDLToSystemImageListIndex(m_pSFParent, pidlNew, 0);
-        SendMessageW(m_hWndList, LVM_SETITEMW, 0, (LPARAM) &lvItem);
-        SendMessageW(m_hWndList, LVM_UPDATE, nItem, 0);
+        m_ListView.SetItem(&lvItem);
+        m_ListView.Update(nItem);
         return TRUE;                    /* FIXME: better handling */
     }
 
@@ -815,8 +846,9 @@ BOOLEAN CDefView::LV_RenameItem(LPCITEMIDLIST pidlOld, LPCITEMIDLIST pidlNew)
 */
 INT CALLBACK CDefView::fill_list( LPVOID ptr, LPVOID arg )
 {
-    LPITEMIDLIST pidl = (LPITEMIDLIST)ptr;
+    PITEMID_CHILD pidl = static_cast<PITEMID_CHILD>(ptr);
     CDefView *pThis = static_cast<CDefView *>(arg);
+
     /* in a commdlg This works as a filemask*/
     if (pThis->IncludeObject(pidl) == S_OK)
         pThis->LV_AddItem(pidl);
@@ -827,8 +859,8 @@ INT CALLBACK CDefView::fill_list( LPVOID ptr, LPVOID arg )
 
 HRESULT CDefView::FillList()
 {
-    LPENUMIDLIST    pEnumIDList;
-    LPITEMIDLIST    pidl;
+    CComPtr<IEnumIDList> pEnumIDList;
+    PITEMID_CHILD    pidl;
     DWORD        dwFetched;
     HRESULT        hRes;
     HDPA        hdpa;
@@ -861,35 +893,35 @@ HRESULT CDefView::FillList()
     }
 
     /* sort the array */
-    DPA_Sort(hdpa, CompareItems, (LPARAM)m_pSFParent.p);
+    DPA_Sort(hdpa, CompareItems, reinterpret_cast<LPARAM>(m_pSFParent.p));
 
     /*turn the listview's redrawing off*/
-    SendMessageA(m_hWndList, WM_SETREDRAW, FALSE, 0);
+    m_ListView.SetRedraw(FALSE);
 
-    DPA_DestroyCallback( hdpa, fill_list, (void *)this);
+    DPA_DestroyCallback( hdpa, fill_list, this);
 
     /*turn the listview's redrawing back on and force it to draw*/
-    SendMessageA(m_hWndList, WM_SETREDRAW, TRUE, 0);
-
-    pEnumIDList->Release(); /* destroy the list*/
+    m_ListView.SetRedraw(TRUE);
 
     return S_OK;
 }
 
 LRESULT CDefView::OnShowWindow(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
 {
-    ::UpdateWindow(m_hWndList);
+    m_ListView.UpdateWindow();
     bHandled = FALSE;
     return 0;
 }
 
 LRESULT CDefView::OnGetDlgCode(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
 {
-    return SendMessageW(m_hWndList, uMsg, 0, 0);
+    return m_ListView.SendMessageW(uMsg, 0, 0);
 }
 
 LRESULT CDefView::OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
 {
+    if (m_hMenu)
+        DestroyMenu(m_hMenu);
     RevokeDragDrop(m_hWnd);
     SHChangeNotifyDeregister(m_hNotify);
     bHandled = FALSE;
@@ -898,8 +930,9 @@ LRESULT CDefView::OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHand
 
 LRESULT CDefView::OnEraseBackground(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
 {
+    /* redirect to parent */
     if (m_FolderSettings.fFlags & (FWF_DESKTOP | FWF_TRANSPARENT))
-        return SendMessageW(GetParent(), WM_ERASEBKGND, wParam, lParam); /* redirect to parent */
+        return SendMessageW(GetParent(), WM_ERASEBKGND, wParam, lParam);
 
     bHandled = FALSE;
     return 0;
@@ -911,12 +944,12 @@ LRESULT CDefView::OnSysColorChange(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL
     UpdateListColors();
 
     /* Forward WM_SYSCOLORCHANGE to common controls */
-    return SendMessageW(m_hWndList, uMsg, 0, 0);
+    return m_ListView.SendMessageW(uMsg, 0, 0);
 }
 
 LRESULT CDefView::OnGetShellBrowser(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
 {
-    return (LRESULT)m_pShellBrowser.p;
+    return reinterpret_cast<LRESULT>(m_pShellBrowser.p);
 }
 
 /**********************************************************
@@ -948,13 +981,15 @@ LRESULT CDefView::OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandl
     m_pSFParent->QueryInterface(IID_PPV_ARG(IPersistFolder2, &ppf2));
     if (ppf2)
     {
-        ppf2->GetCurFolder((LPITEMIDLIST*)&ntreg.pidl);
+        PIDLIST_ABSOLUTE pidlParent;
+        ppf2->GetCurFolder(&pidlParent);
         ntreg.fRecursive = TRUE;
+        ntreg.pidl = pidlParent;
         m_hNotify = SHChangeNotifyRegister(m_hWnd, SHCNF_IDLIST, SHCNE_ALLEVENTS, SHV_CHANGE_NOTIFY, 1, &ntreg);
-        SHFree((LPITEMIDLIST)ntreg.pidl);
+        SHFree(pidlParent);
     }
 
-    m_hAccel = LoadAcceleratorsA(shell32_hInstance, MAKEINTRESOURCEA( IDA_SHELLVIEW));
+    m_hAccel = LoadAcceleratorsW(shell32_hInstance, MAKEINTRESOURCEW(IDA_SHELLVIEW));
 
     return S_OK;
 }
@@ -963,90 +998,108 @@ LRESULT CDefView::OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandl
  *    #### Handling of the menus ####
  */
 
-/**********************************************************
-* ShellView_BuildFileMenu()
-*/
 HMENU CDefView::BuildFileMenu()
-{   WCHAR    szText[MAX_PATH];
-    MENUITEMINFOW    mii;
-    int    nTools, i;
-    HMENU    hSubMenu;
+{
+    HRESULT hr;
+    CComPtr<IContextMenu> cm;
 
-    TRACE("(%p)\n", this);
+    GetSelections();
 
-    hSubMenu = CreatePopupMenu();
-    if (hSubMenu)
-    {
-        /*get the number of items in our global array*/
-        for(nTools = 0; Tools[nTools].idCommand != -1; nTools++) {}
+    hr = m_pSFParent->GetUIObjectOf(m_hWnd, m_cidl, m_apidl, IID_NULL_PPV_ARG(IContextMenu, &cm));
+    if (FAILED(hr))
+        return NULL;
 
-        /*add the menu items*/
-        for(i = 0; i < nTools; i++)
-        {
-            LoadStringW(shell32_hInstance, Tools[i].idMenuString, szText, MAX_PATH);
+    HMENU hmenu = CreatePopupMenu();
 
-            ZeroMemory(&mii, sizeof(mii));
-            mii.cbSize = sizeof(mii);
-            mii.fMask = MIIM_TYPE | MIIM_ID | MIIM_STATE;
+    //FIXME: get proper numbers ?
+    const UINT first = 0x7800;
+    const UINT last  = 0x7A00;
+    hr = cm->QueryContextMenu(hmenu, 0, first, last, 0);
+    if (FAILED(hr))
+        return NULL;
 
-            if(BTNS_SEP != Tools[i].bStyle) /* no separator*/
-            {
-                mii.fType = MFT_STRING;
-                mii.fState = MFS_ENABLED;
-                mii.dwTypeData = szText;
-                mii.wID = Tools[i].idCommand;
-            }
-            else
-            {
-                mii.fType = MFT_SEPARATOR;
-            }
-            /* tack This item onto the end of the menu */
-            InsertMenuItemW(hSubMenu, (UINT) - 1, TRUE, &mii);
-        }
-    }
+    // TODO: filter or something
 
-    TRACE("-- return (menu=%p)\n", hSubMenu);
-    return hSubMenu;
+    return hmenu;
 }
 
-/**********************************************************
-* ShellView_MergeFileMenu()
-*/
-void CDefView::MergeFileMenu(HMENU hSubMenu)
+void CDefView::PrepareShowFileMenu(HMENU hSubMenu)
 {
     TRACE("(%p)->(submenu=%p) stub\n", this, hSubMenu);
 
-    if (hSubMenu)
-    {   /*insert This item at the beginning of the menu */
-        _InsertMenuItemW(hSubMenu, 0, TRUE, 0, MFT_SEPARATOR, NULL, MFS_ENABLED);
-        _InsertMenuItemW(hSubMenu, 0, TRUE, IDM_MYFILEITEM, MFT_STRING, L"dummy45", MFS_ENABLED);
+    if (!hSubMenu)
+        return;
+
+    /* Cleanup the items added previously */
+    for (int i = 0; i < GetMenuItemCount(hSubMenu); )
+    {
+        MENUITEMINFOW mii;
+        mii.cbSize = sizeof(mii);
+        mii.fMask = MIIM_ID;
+        GetMenuItemInfoW(hSubMenu, i, TRUE, &mii);
+
+        if (mii.wID < 0x8000)
+        {
+            DeleteMenu(hSubMenu, i, MF_BYPOSITION);
+        }
+        else
+        {
+            i++;
+        }
     }
 
+    /* Insert This item at the beginning of the menu. */
+    _InsertMenuItemW(hSubMenu, 0, TRUE, 0, MFT_SEPARATOR, NULL, MFS_ENABLED);
+    _InsertMenuItemW(hSubMenu, 0, TRUE, IDM_MYFILEITEM + 4, MFT_STRING, L"Properties", MFS_DISABLED);
+    _InsertMenuItemW(hSubMenu, 0, TRUE, IDM_MYFILEITEM + 3, MFT_STRING, L"Rename", MFS_DISABLED);
+    _InsertMenuItemW(hSubMenu, 0, TRUE, IDM_MYFILEITEM + 2, MFT_STRING, L"Delete", MFS_DISABLED);
+    _InsertMenuItemW(hSubMenu, 0, TRUE, IDM_MYFILEITEM + 1, MFT_STRING, L"Create Shortcut", MFS_DISABLED);
+    _InsertMenuItemW(hSubMenu, 0, TRUE, 0, MFT_SEPARATOR, NULL, MFS_ENABLED);
+    _InsertMenuItemW(hSubMenu, 0, TRUE, IDM_MYFILEITEM, MFT_STRING, L"New", MFS_ENABLED);
+
+    HMENU menubase = BuildFileMenu();
+    if (menubase)
+    {
+        int count = ::GetMenuItemCount(menubase);
+
+        for (int i = 0; i < count; i++)
+        {
+            WCHAR label[128];
+
+            MENUITEMINFOW mii = { 0 };
+            mii.cbSize = sizeof(mii);
+            mii.fMask = MIIM_STATE | MIIM_ID | MIIM_SUBMENU | MIIM_CHECKMARKS | MIIM_DATA | MIIM_STRING | MIIM_BITMAP | MIIM_FTYPE;
+            mii.dwTypeData = label;
+            mii.cch = _countof(label);
+            ::GetMenuItemInfoW(menubase, i, TRUE, &mii);
+
+            TRACE("Adding item %d label %S type %d\n", mii.wID, mii.dwTypeData, mii.fType);
+
+            mii.fType |= MFT_RADIOCHECK;
+
+            ::InsertMenuItemW(hSubMenu, IDM_MYFILEITEM, FALSE, &mii);
+        }
+
+        _InsertMenuItemW(hSubMenu, IDM_MYFILEITEM, FALSE, 0, MFT_SEPARATOR, NULL, MFS_ENABLED);
+
+        ::DestroyMenu(menubase);
+    }
     TRACE("--\n");
 }
 
-/**********************************************************
-* ShellView_MergeViewMenu()
-*/
-void CDefView::MergeViewMenu(HMENU hSubMenu)
+void CDefView::PrepareShowViewMenu(HMENU hSubMenu)
 {
     TRACE("(%p)->(submenu=%p)\n", this, hSubMenu);
 
-    if (hSubMenu)
-    {
-        /*add a separator at the correct position in the menu*/
-        MENUITEMINFOW mii;
-        static WCHAR view[] = L"View";
-
-        _InsertMenuItemW(hSubMenu, FCIDM_MENU_VIEW_SEP_OPTIONS, FALSE, 0, MFT_SEPARATOR, NULL, MFS_ENABLED);
+    if (!hSubMenu)
+        return;
 
-        ZeroMemory(&mii, sizeof(mii));
-        mii.cbSize = sizeof(mii);
-        mii.fMask = MIIM_SUBMENU | MIIM_TYPE | MIIM_DATA;
-        mii.fType = MFT_STRING;
-        mii.dwTypeData = view;
-        mii.hSubMenu = LoadMenuW(shell32_hInstance, L"MENU_001");
-        InsertMenuItemW(hSubMenu, FCIDM_MENU_VIEW_SEP_OPTIONS, FALSE, &mii);
+    if (m_FolderSettings.ViewMode >= FVM_FIRST && m_FolderSettings.ViewMode <= FVM_LAST)
+    {
+        UINT iItemFirst = FCIDM_SHVIEW_BIGICON;
+        UINT iItemLast = iItemFirst + FVM_LAST - FVM_FIRST;
+        UINT iItem = iItemFirst + m_FolderSettings.ViewMode - FVM_FIRST;
+        CheckMenuRadioItem(hSubMenu, iItemFirst, iItemLast, iItem, MF_BYCOMMAND);
     }
 }
 
@@ -1060,38 +1113,27 @@ void CDefView::MergeViewMenu(HMENU hSubMenu)
 */
 UINT CDefView::GetSelections()
 {
-    LVITEMW    lvItem;
-    UINT    i = 0;
-
     SHFree(m_apidl);
 
-    m_cidl = ListView_GetSelectedCount(m_hWndList);
-    m_apidl = (LPITEMIDLIST*)SHAlloc(m_cidl * sizeof(LPITEMIDLIST));
-
-    TRACE("selected=%i\n", m_cidl);
-
-    if (m_apidl)
+    m_cidl = m_ListView.GetSelectedCount();
+    m_apidl = reinterpret_cast<PCUITEMID_CHILD_ARRAY>(SHAlloc(m_cidl * sizeof(PCUITEMID_CHILD)));
+    if (!m_apidl)
     {
-        TRACE("-- Items selected =%u\n", m_cidl);
+        m_cidl = 0;
+        return 0;
+    }
 
-        lvItem.mask = LVIF_STATE | LVIF_PARAM;
-        lvItem.stateMask = LVIS_SELECTED;
-        lvItem.iItem = 0;
-        lvItem.iSubItem = 0;
-        lvItem.state = 0;
+    TRACE("-- Items selected =%u\n", m_cidl);
 
-        while(SendMessageW(m_hWndList, LVM_GETITEMW, 0, (LPARAM)&lvItem) && (i < m_cidl))
-        {
-            if(lvItem.state & LVIS_SELECTED)
-            {
-                m_apidl[i] = (LPITEMIDLIST)lvItem.lParam;
-                i++;
-                if (i == m_cidl)
-                    break;
-                TRACE("-- selected Item found\n");
-            }
-            lvItem.iItem++;
-        }
+    UINT i = 0;
+    int lvIndex = -1;
+    while ((lvIndex = m_ListView.GetNextItem(lvIndex,  LVNI_SELECTED)) > -1)
+    {
+        m_apidl[i] = _PidlByItem(lvIndex);
+        i++;
+        if (i == m_cidl)
+             break;
+        TRACE("-- selected Item found\n");
     }
 
     return m_cidl;
@@ -1107,7 +1149,7 @@ HRESULT CDefView::OpenSelectedItems()
     UINT uCommand;
     HRESULT hResult;
 
-    m_cidl = ListView_GetSelectedCount(m_hWndList);
+    m_cidl = m_ListView.GetSelectedCount();
     if (m_cidl == 0)
         return S_OK;
 
@@ -1119,7 +1161,7 @@ HRESULT CDefView::OpenSelectedItems()
     if (!hMenu) 
         return E_FAIL;
 
-    hResult = GetItemObject( SVGIO_SELECTION, IID_PPV_ARG(IContextMenu, &m_pCM));
+    hResult = GetItemObject(SVGIO_SELECTION, IID_PPV_ARG(IContextMenu, &m_pCM));
     if (FAILED(hResult))
         goto cleanup;
 
@@ -1184,7 +1226,7 @@ LRESULT CDefView::OnContextMenu(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &b
     if (!hMenu) 
         return E_FAIL;
 
-    m_cidl = ListView_GetSelectedCount(m_hWndList);
+    m_cidl = m_ListView.GetSelectedCount();
 
     hResult = GetItemObject( m_cidl ? SVGIO_SELECTION : SVGIO_BACKGROUND, IID_PPV_ARG(IContextMenu, &m_pCM));
     if (FAILED( hResult))
@@ -1212,7 +1254,7 @@ LRESULT CDefView::OnContextMenu(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &b
 
     ZeroMemory(&cmi, sizeof(cmi));
     cmi.cbSize = sizeof(cmi);
-    cmi.lpVerb = (LPCSTR)MAKEINTRESOURCEA(uCommand);
+    cmi.lpVerb = MAKEINTRESOURCEA(uCommand);
     cmi.hwnd = m_hWnd;
     m_pCM->InvokeCommand(&cmi);
 
@@ -1254,7 +1296,7 @@ LRESULT CDefView::OnExplorerCommand(UINT uCommand, BOOL bUseSelection)
 
     ZeroMemory(&cmi, sizeof(cmi));
     cmi.cbSize = sizeof(cmi);
-    cmi.lpVerb = (LPCSTR)MAKEINTRESOURCEA(uCommand);
+    cmi.lpVerb = MAKEINTRESOURCEA(uCommand);
     cmi.hwnd = m_hWnd;
     m_pCM->InvokeCommand(&cmi);
 
@@ -1290,9 +1332,9 @@ LRESULT CDefView::OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled
     TRACE("%p width=%u height=%u\n", this, wWidth, wHeight);
 
     /*resize the ListView to fit our window*/
-    if (m_hWndList)
+    if (m_ListView)
     {
-        ::MoveWindow(m_hWndList, 0, 0, wWidth, wHeight, TRUE);
+        ::MoveWindow(m_ListView, 0, 0, wWidth, wHeight, TRUE);
     }
 
     return 0;
@@ -1310,13 +1352,7 @@ void CDefView::OnDeactivate()
 
     if (m_uState != SVUIA_DEACTIVATE)
     {
-        if (m_hMenu)
-        {
-            m_pShellBrowser->SetMenuSB(0, 0, 0);
-            m_pShellBrowser->RemoveMenusSB(m_hMenu);
-            DestroyMenu(m_hMenu);
-            m_hMenu = 0;
-        }
+        // TODO: cleanup menu after deactivation
 
         m_uState = SVUIA_DEACTIVATE;
     }
@@ -1324,10 +1360,6 @@ void CDefView::OnDeactivate()
 
 void CDefView::DoActivate(UINT uState)
 {
-    OLEMENUGROUPWIDTHS                    omw = { {0, 0, 0, 0, 0, 0} };
-    MENUITEMINFOA                        mii;
-    CHAR                                szText[MAX_PATH];
-
     TRACE("%p uState=%x\n", this, uState);
 
     /*don't do anything if the state isn't really changing */
@@ -1336,64 +1368,101 @@ void CDefView::DoActivate(UINT uState)
         return;
     }
 
-    OnDeactivate();
-
-    /*only do This if we are active */
-    if(uState != SVUIA_DEACTIVATE)
+    if (uState == SVUIA_DEACTIVATE)
+    {
+        OnDeactivate();
+    }
+    else
     {
-        /*merge the menus */
-        m_hMenu = CreateMenu();
-
         if(m_hMenu)
         {
-            m_pShellBrowser->InsertMenusSB(m_hMenu, &omw);
-            TRACE("-- after fnInsertMenusSB\n");
+            if (!m_menusLoaded)
+            {
+                MENUITEMINFOW mii = { 0 };
 
-            /*build the top level menu get the menu item's text*/
-            strcpy(szText, "dummy 31");
+                /* initialize EDIT menu */
+                mii.cbSize = sizeof(mii);
+                mii.fMask = MIIM_SUBMENU;
+                if (::GetMenuItemInfoW(m_hMenu, FCIDM_MENU_EDIT, FALSE, &mii))
+                {
+                    HMENU hSubMenu = mii.hSubMenu;
 
-            ZeroMemory(&mii, sizeof(mii));
-            mii.cbSize = sizeof(mii);
-            mii.fMask = MIIM_SUBMENU | MIIM_TYPE | MIIM_STATE;
-            mii.fType = MFT_STRING;
-            mii.fState = MFS_ENABLED;
-            mii.dwTypeData = szText;
-            mii.hSubMenu = BuildFileMenu();
-
-            /*insert our menu into the menu bar*/
-            if (mii.hSubMenu)
-            {
-                InsertMenuItemA(m_hMenu, FCIDM_MENU_HELP, FALSE, &mii);
-            }
+                    HMENU menubase = ::LoadMenuW(shell32_hInstance, L"MENU_003");
 
-            /*get the view menu so we can merge with it*/
-            ZeroMemory(&mii, sizeof(mii));
-            mii.cbSize = sizeof(mii);
-            mii.fMask = MIIM_SUBMENU;
+                    int count = ::GetMenuItemCount(menubase);
+                    for (int i = 0; i < count; i++)
+                    {
+                        WCHAR label[128];
 
-            if (GetMenuItemInfoA(m_hMenu, FCIDM_MENU_VIEW, FALSE, &mii))
-            {
-                MergeViewMenu(mii.hSubMenu);
-            }
+                        ZeroMemory(&mii, sizeof(mii));
+                        mii.cbSize = sizeof(mii);
+                        mii.fMask = MIIM_STATE | MIIM_ID | MIIM_SUBMENU | MIIM_CHECKMARKS | MIIM_DATA | MIIM_STRING | MIIM_BITMAP | MIIM_FTYPE;
+                        mii.dwTypeData = label;
+                        mii.cch = _countof(label);
+                        ::GetMenuItemInfoW(menubase, i, TRUE, &mii);
+
+                        TRACE("Adding item %d label %S type %d\n", mii.wID, mii.dwTypeData, mii.fType);
+
+                        mii.fType |= MFT_RADIOCHECK;
+
+                        ::InsertMenuItemW(hSubMenu, FCIDM_MENU_VIEW_SEP_OPTIONS, FALSE, &mii);
+                    }
+
+                    ::DestroyMenu(menubase);
+                }
+
+                /* initialize VIEW menu */
 
-            /*add the items that should only be added if we have the focus*/
-            if (SVUIA_ACTIVATE_FOCUS == uState)
-            {
-                /*get the file menu so we can merge with it */
-                ZeroMemory(&mii, sizeof(mii));
                 mii.cbSize = sizeof(mii);
                 mii.fMask = MIIM_SUBMENU;
-
-                if (GetMenuItemInfoA(m_hMenu, FCIDM_MENU_FILE, FALSE, &mii))
+                if (::GetMenuItemInfoW(m_hMenu, FCIDM_MENU_VIEW, FALSE, &mii))
                 {
-                    MergeFileMenu(mii.hSubMenu);
+                    HMENU menubase = ::LoadMenuW(shell32_hInstance, L"MENU_001");
+
+                    HMENU hSubMenu = mii.hSubMenu;
+
+                    m_hView = CreatePopupMenu();
+
+                    _InsertMenuItemW(hSubMenu, FCIDM_MENU_VIEW_SEP_OPTIONS, FALSE, 0, MFT_SEPARATOR, NULL, MFS_ENABLED);
+
+                    int count = ::GetMenuItemCount(menubase);
+                    for (int i = 0; i < count; i++)
+                    {
+                        WCHAR label[128];
+
+                        ZeroMemory(&mii, sizeof(mii));
+                        mii.cbSize = sizeof(mii);
+                        mii.fMask = MIIM_STATE | MIIM_ID | MIIM_SUBMENU | MIIM_CHECKMARKS | MIIM_DATA | MIIM_STRING | MIIM_BITMAP | MIIM_FTYPE;
+                        mii.dwTypeData = label;
+                        mii.cch = _countof(label);
+                        ::GetMenuItemInfoW(menubase, i, TRUE, &mii);
+
+                        ::AppendMenuW(m_hView, mii.fType, mii.wID, mii.dwTypeData);
+
+                        TRACE("Adding item %d label %S type %d\n", mii.wID, mii.dwTypeData, mii.fType);
+
+                        mii.fType |= MFT_RADIOCHECK;
+
+                        ::InsertMenuItemW(hSubMenu, FCIDM_MENU_VIEW_SEP_OPTIONS, FALSE, &mii);
+                    }
+
+                    ::DestroyMenu(menubase);
                 }
+
+
+                TRACE("-- before fnSetMenuSB\n");
+                m_pShellBrowser->SetMenuSB(m_hMenu, 0, m_hWnd);
+
+                m_menusLoaded = TRUE;
             }
+        }
 
-            TRACE("-- before fnSetMenuSB\n");
-            m_pShellBrowser->SetMenuSB(m_hMenu, 0, m_hWnd);
+        if (SVUIA_ACTIVATE_FOCUS == uState)
+        {
+            m_ListView.SetFocus();
         }
     }
+
     m_uState = uState;
     TRACE("--\n");
 }
@@ -1419,11 +1488,11 @@ LRESULT CDefView::OnSetFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHan
     should always be done before merging menus (OnActivate merges the
     menus) if one of our windows has the focus.*/
 
-    m_pShellBrowser->OnViewWindowActive((IShellView *)this);
+    m_pShellBrowser->OnViewWindowActive(this);
     DoActivate(SVUIA_ACTIVATE_FOCUS);
 
     /* Set the focus to the listview */
-    ::SetFocus(m_hWndList);
+    m_ListView.SetFocus();
 
     /* Notify the ICommDlgBrowser interface */
     OnStateChange(CDBOSC_SETFOCUS);
@@ -1494,10 +1563,10 @@ LRESULT CDefView::OnCommand(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHand
         case 0x31:
         case 0x32:
         case 0x33:
-            m_sortInfo.nHeaderID = (LPARAM) (dwCmdID - 0x30);
+            m_sortInfo.nHeaderID = dwCmdID - 0x30;
             m_sortInfo.bIsAscending = TRUE;
             m_sortInfo.nLastHeaderID = m_sortInfo.nHeaderID;
-            SendMessageA(m_hWndList, LVM_SORTITEMS, (WPARAM) &m_sortInfo, (LPARAM)ListViewCompareItems);
+            m_ListView.SortItems(ListViewCompareItems, &m_sortInfo);
             break;
 
         case FCIDM_SHVIEW_REFRESH:
@@ -1532,7 +1601,7 @@ LRESULT CDefView::OnNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandl
     LPNMHDR                                lpnmh;
     LPNMLISTVIEW                        lpnmlv;
     NMLVDISPINFOW                        *lpdi;
-    LPITEMIDLIST                        pidl;
+    PCUITEMID_CHILD                     pidl;
     BOOL                                unused;
 
     CtlID = wParam;
@@ -1584,13 +1653,16 @@ LRESULT CDefView::OnNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandl
 
         case HDN_ENDTRACKW:
             TRACE("-- HDN_ENDTRACKW %p\n", this);
-            /*nColumn1 = ListView_GetColumnWidth(m_hWndList, 0);
-            nColumn2 = ListView_GetColumnWidth(m_hWndList, 1);*/
+            /*nColumn1 = m_ListView.GetColumnWidth(0);
+            nColumn2 = m_ListView.GetColumnWidth(1);*/
             break;
 
         case LVN_DELETEITEM:
             TRACE("-- LVN_DELETEITEM %p\n", this);
-            SHFree((LPITEMIDLIST)lpnmlv->lParam);     /*delete the pidl because we made a copy of it*/
+
+            /*delete the pidl because we made a copy of it*/
+            SHFree(reinterpret_cast<LPVOID>(lpnmlv->lParam));
+
             break;
 
         case LVN_DELETEALLITEMS:
@@ -1609,22 +1681,18 @@ LRESULT CDefView::OnNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandl
         case LVN_COLUMNCLICK:
             m_sortInfo.nHeaderID = lpnmlv->iSubItem;
             if (m_sortInfo.nLastHeaderID == m_sortInfo.nHeaderID)
-            {
                 m_sortInfo.bIsAscending = !m_sortInfo.bIsAscending;
-            }
             else
-            {
                 m_sortInfo.bIsAscending = TRUE;
-            }
             m_sortInfo.nLastHeaderID = m_sortInfo.nHeaderID;
 
-            SendMessageW(lpnmlv->hdr.hwndFrom, LVM_SORTITEMS, (WPARAM) &m_sortInfo, (LPARAM)ListViewCompareItems);
+            m_ListView.SortItems(ListViewCompareItems, &m_sortInfo);
             break;
 
         case LVN_GETDISPINFOA:
         case LVN_GETDISPINFOW:
             TRACE("-- LVN_GETDISPINFO %p\n", this);
-            pidl = (LPITEMIDLIST)lpdi->item.lParam;
+            pidl = _PidlByItem(lpdi->item);
 
             if (lpdi->item.mask & LVIF_TEXT)    /* text requested */
             {
@@ -1673,15 +1741,13 @@ LRESULT CDefView::OnNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandl
 
             if (GetSelections())
             {
-                IDataObject * pda;
+                CComPtr<IDataObject> pda;
                 DWORD dwAttributes = SFGAO_CANLINK;
                 DWORD dwEffect = DROPEFFECT_COPY | DROPEFFECT_MOVE;
 
-                if (SUCCEEDED(m_pSFParent->GetUIObjectOf(m_hWnd, m_cidl, (LPCITEMIDLIST*)m_apidl, IID_IDataObject, 0, (LPVOID *)&pda)))
+                if (SUCCEEDED(m_pSFParent->GetUIObjectOf(m_hWnd, m_cidl, m_apidl, IID_NULL_PPV_ARG(IDataObject, &pda))))
                 {
-                    IDropSource * pds = (IDropSource *)this;    /* own DropSource interface */
-
-                    if (SUCCEEDED(m_pSFParent->GetAttributesOf(m_cidl, (LPCITEMIDLIST*)m_apidl, &dwAttributes)))
+                    if (SUCCEEDED(m_pSFParent->GetAttributesOf(m_cidl, m_apidl, &dwAttributes)))
                     {
                         if (dwAttributes & SFGAO_CANLINK)
                         {
@@ -1693,14 +1759,10 @@ LRESULT CDefView::OnNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandl
                     if (SUCCEEDED(pda->QueryInterface(IID_PPV_ARG(IAsyncOperation, &piaso))))
                     {
                         piaso->SetAsyncMode(TRUE);
-                        piaso->Release();
                     }
 
-                    if (pds)
-                    {                        DWORD dwEffect2;
-                        DoDragDrop(pda, pds, dwEffect, &dwEffect2);
-                    }
-                    pda->Release();
+                    DWORD dwEffect2;
+                    DoDragDrop(pda, this, dwEffect, &dwEffect2);
                 }
             }
             break;
@@ -1708,13 +1770,14 @@ LRESULT CDefView::OnNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandl
         case LVN_BEGINLABELEDITW:
         {
             DWORD dwAttr = SFGAO_CANRENAME;
-            pidl = (LPITEMIDLIST)lpdi->item.lParam;
+            pidl = _PidlByItem(lpdi->item);
 
             TRACE("-- LVN_BEGINLABELEDITW %p\n", this);
 
-            m_pSFParent->GetAttributesOf(1, (LPCITEMIDLIST*)&pidl, &dwAttr);
+            m_pSFParent->GetAttributesOf(1, &pidl, &dwAttr);
             if (SFGAO_CANRENAME & dwAttr)
             {
+                m_isEditing = TRUE;
                 return FALSE;
             }
             return TRUE;
@@ -1723,27 +1786,26 @@ LRESULT CDefView::OnNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandl
         case LVN_ENDLABELEDITW:
         {
             TRACE("-- LVN_ENDLABELEDITW %p\n", this);
+
+            m_isEditing = FALSE;
+
             if (lpdi->item.pszText)
             {
                 HRESULT hr;
                 LVITEMW lvItem;
 
-                lvItem.iItem = lpdi->item.iItem;
-                lvItem.iSubItem = 0;
-                lvItem.mask = LVIF_PARAM;
-                SendMessageW(m_hWndList, LVM_GETITEMW, 0, (LPARAM) &lvItem);
-
-                pidl = (LPITEMIDLIST)lpdi->item.lParam;
-                hr = m_pSFParent->SetNameOf(0, pidl, lpdi->item.pszText, SHGDN_INFOLDER, &pidl);
+                pidl = _PidlByItem(lpdi->item);
+                PITEMID_CHILD pidlNew;
+                hr = m_pSFParent->SetNameOf(0, pidl, lpdi->item.pszText, SHGDN_INFOLDER, &pidlNew);
 
-                if (SUCCEEDED(hr) && pidl)
+                if (SUCCEEDED(hr) && pidlNew)
                 {
                     lvItem.mask = LVIF_PARAM|LVIF_IMAGE;
-                    lvItem.lParam = (LPARAM)pidl;
-                    lvItem.iImage = SHMapPIDLToSystemImageListIndex(m_pSFParent, pidl, 0);
-                    SendMessageW(m_hWndList, LVM_SETITEMW, 0, (LPARAM) &lvItem);
-                    SendMessageW(m_hWndList, LVM_UPDATE, lpdi->item.iItem, 0);
-
+                    lvItem.iItem = lpdi->item.iItem;
+                    lvItem.lParam = reinterpret_cast<LPARAM>(pidlNew);
+                    lvItem.iImage = SHMapPIDLToSystemImageListIndex(m_pSFParent, pidlNew, 0);
+                    m_ListView.SetItem(&lvItem);
+                    m_ListView.Update(lpdi->item.iItem);
                     return TRUE;
                 }
             }
@@ -1751,25 +1813,6 @@ LRESULT CDefView::OnNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandl
             return FALSE;
         }
 
-        case LVN_KEYDOWN:
-        {
-            LPNMLVKEYDOWN plvKeyDown = (LPNMLVKEYDOWN) lpnmh;
-
-            /* initiate a rename of the selected file or directory */
-            if (plvKeyDown->wVKey == VK_BACK)
-            {
-                LPSHELLBROWSER lpSb;
-                if ((lpSb = (LPSHELLBROWSER)SendMessageW(m_hWndParent, CWM_GETISHELLBROWSER, 0, 0)))
-                {
-                    lpSb->BrowseObject(NULL, SBSP_PARENT);
-                }
-            }
-           
-            else
-                FIXME("LVN_KEYDOWN key=0x%08x\n", plvKeyDown->wVKey);
-        }
-        break;
-
         default:
             TRACE("-- %p WM_COMMAND %x unhandled\n", this, lpnmh->code);
             break;
@@ -1783,9 +1826,7 @@ LRESULT CDefView::OnNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandl
 */
 LRESULT CDefView::OnChangeNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
 {
-    LPITEMIDLIST                        *Pidls;
-
-    Pidls = (LPITEMIDLIST *)wParam;
+    PCIDLIST_ABSOLUTE *Pidls = reinterpret_cast<PCIDLIST_ABSOLUTE*>(wParam);
 
     TRACE("(%p)(%p,%p,0x%08x)\n", this, Pidls[0], Pidls[1], lParam);
 
@@ -1793,21 +1834,21 @@ LRESULT CDefView::OnChangeNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &
     {
         case SHCNE_MKDIR:
         case SHCNE_CREATE:
-            LV_AddItem(Pidls[0]);
+            LV_AddItem(ILFindLastID(Pidls[0]));
             break;
 
         case SHCNE_RMDIR:
         case SHCNE_DELETE:
-            LV_DeleteItem(Pidls[0]);
+            LV_DeleteItem(ILFindLastID(Pidls[0]));
             break;
 
         case SHCNE_RENAMEFOLDER:
         case SHCNE_RENAMEITEM:
-            LV_RenameItem(Pidls[0], Pidls[1]);
+            LV_RenameItem(ILFindLastID(Pidls[0]), ILFindLastID(Pidls[1]));
             break;
 
         case SHCNE_UPDATEITEM:
-            LV_RenameItem(Pidls[0], Pidls[0]);
+            LV_RenameItem(ILFindLastID(Pidls[0]), ILFindLastID(Pidls[0]));
             break;
 
         case SHCNE_UPDATEDIR:
@@ -1849,6 +1890,51 @@ LRESULT CDefView::OnSettingChange(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL
     return S_OK;
 }
 
+/**********************************************************
+*  CDefView::OnInitMenuPopup
+*/
+LRESULT CDefView::OnInitMenuPopup(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
+{
+    MENUITEMINFOW mii = { 0 };
+    HMENU hSubmenu = (HMENU) wParam;
+
+    DbgPrint("OnInitMenuPopup lParam=%d\n", lParam);
+    
+    mii.cbSize = sizeof(mii);
+    mii.fMask = MIIM_ID | MIIM_SUBMENU;
+
+    if (!GetMenuItemInfoW(this->m_hMenu, lParam, TRUE, &mii))
+    {
+        DbgPrint("OnInitMenuPopup GetMenuItemInfoW failed!\n");
+        return FALSE;
+    }
+
+    UINT  menuItemId = mii.wID;
+
+    if (mii.hSubMenu != hSubmenu)
+    {
+        DbgPrint("OnInitMenuPopup submenu does not match!!!!\n");
+        return FALSE;
+    }
+
+    DbgPrint("OnInitMenuPopup id=%d\n", menuItemId);
+
+    switch (menuItemId)
+    {
+    case FCIDM_MENU_FILE:
+        PrepareShowFileMenu(hSubmenu);
+        break;
+    case FCIDM_MENU_EDIT:
+        //PrepareShowEditMenu(hSubmenu);
+        break;
+    case FCIDM_MENU_VIEW:
+        PrepareShowViewMenu(hSubmenu);
+        break;
+    }
+
+    return FALSE;
+}
+
 /**********************************************************
 *
 *
@@ -1885,17 +1971,18 @@ HRESULT WINAPI CDefView::ContextSensitiveHelp(BOOL fEnterMode)
 */
 HRESULT WINAPI CDefView::TranslateAccelerator(LPMSG lpmsg)
 {
+    if (m_isEditing)
+        return S_FALSE;
+
     if (lpmsg->message >= WM_KEYFIRST && lpmsg->message <= WM_KEYLAST)
     {
         if (::TranslateAcceleratorW(m_hWnd, m_hAccel, lpmsg) != 0)
             return S_OK;
 
-        /* FIXME: should call TranslateAcceleratorSB */
-
         TRACE("-- key=0x04%lx\n", lpmsg->wParam) ;
     }
 
-    return S_FALSE; /* not handled */
+    return m_pShellBrowser->TranslateAcceleratorSB(lpmsg, 0);
 }
 
 HRESULT WINAPI CDefView::EnableModeless(BOOL fEnable)
@@ -1948,7 +2035,7 @@ HRESULT WINAPI CDefView::Refresh()
 {
     TRACE("(%p)\n", this);
 
-    SendMessageW(m_hWndList, LVM_DELETEALLITEMS, 0, 0);
+    m_ListView.DeleteAllItems();
     FillList();
 
     return S_OK;
@@ -1956,6 +2043,8 @@ HRESULT WINAPI CDefView::Refresh()
 
 HRESULT WINAPI CDefView::CreateViewWindow(IShellView *lpPrevView, LPCFOLDERSETTINGS lpfs, IShellBrowser *psb, RECT *prcView, HWND *phWnd)
 {
+    OLEMENUGROUPWIDTHS                    omw = { { 0, 0, 0, 0, 0, 0 } };
+
     *phWnd = 0;
 
     TRACE("(%p)->(shlview=%p set=%p shlbrs=%p rec=%p hwnd=%p) incomplete\n", this, lpPrevView, lpfs, psb, prcView, phWnd);
@@ -1997,6 +2086,15 @@ HRESULT WINAPI CDefView::CreateViewWindow(IShellView *lpPrevView, LPCFOLDERSETTI
     SetWindowPos(HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
     UpdateWindow();
 
+    if (!m_hMenu)
+    {
+        m_hMenu = CreateMenu();
+        m_pShellBrowser->InsertMenusSB(m_hMenu, &omw);
+        TRACE("-- after fnInsertMenusSB\n");
+    }
+
+    _MergeToolbar();
+
     return S_OK;
 }
 
@@ -2007,12 +2105,34 @@ HRESULT WINAPI CDefView::DestroyViewWindow()
     /*Make absolutely sure all our UI is cleaned up.*/
     UIActivate(SVUIA_DEACTIVATE);
 
+    if (m_hAccel)
+    {
+        // "Accelerator tables loaded from resources are freed automatically when the application terminates." -- MSDN
+        m_hAccel = NULL;
+    }
+
+    if (m_hView)
+    {
+        DestroyMenu(m_hView);
+        m_hView = NULL;
+    }
+
     if (m_hMenu)
     {
         DestroyMenu(m_hMenu);
+        m_hView = NULL;
+    }
+
+    if (m_ListView)
+    {
+        m_ListView.DestroyWindow();
+    }
+
+    if (m_hWnd)
+    {
+        DestroyWindow();
     }
 
-    DestroyWindow();
     m_pShellBrowser.Release();
     m_pCommDlgBrowser.Release();
 
@@ -2045,53 +2165,48 @@ HRESULT WINAPI CDefView::SaveViewState()
     return S_OK;
 }
 
-HRESULT WINAPI CDefView::SelectItem(LPCITEMIDLIST pidl, UINT uFlags)
+HRESULT WINAPI CDefView::SelectItem(PCUITEMID_CHILD pidl, UINT uFlags)
 {
     int i;
 
     TRACE("(%p)->(pidl=%p, 0x%08x) stub\n", this, pidl, uFlags);
 
     i = LV_FindItemByPidl(pidl);
+    if (i == -1)
+        return S_OK;
 
-    if (i != -1)
-    {
-        LVITEMW lvItem;
-
-        if(uFlags & SVSI_ENSUREVISIBLE)
-            SendMessageW(m_hWndList, LVM_ENSUREVISIBLE, i, 0);
+    if(uFlags & SVSI_ENSUREVISIBLE)
+        m_ListView.EnsureVisible(i, FALSE);
 
-        lvItem.mask = LVIF_STATE;
-        lvItem.stateMask = LVIS_SELECTED | LVIS_FOCUSED;
-        lvItem.iItem = 0;
-        lvItem.iSubItem = 0;
+    LVITEMW lvItem = {0};
+    lvItem.mask = LVIF_STATE;
+    lvItem.stateMask = LVIS_SELECTED | LVIS_FOCUSED;
 
-        while (SendMessageW(m_hWndList, LVM_GETITEMW, 0, (LPARAM) &lvItem))
+    while (m_ListView.GetItem(&lvItem))
+    {
+        if (lvItem.iItem == i)
         {
-            if (lvItem.iItem == i)
-            {
-                if (uFlags & SVSI_SELECT)
-                    lvItem.state |= LVIS_SELECTED;
-                else
-                    lvItem.state &= ~LVIS_SELECTED;
-
-                if (uFlags & SVSI_FOCUSED)
-                    lvItem.state &= ~LVIS_FOCUSED;
-            }
+            if (uFlags & SVSI_SELECT)
+                lvItem.state |= LVIS_SELECTED;
             else
-            {
-                if (uFlags & SVSI_DESELECTOTHERS)
-                    lvItem.state &= ~LVIS_SELECTED;
-            }
+                lvItem.state &= ~LVIS_SELECTED;
 
-            SendMessageW(m_hWndList, LVM_SETITEMW, 0, (LPARAM) &lvItem);
-            lvItem.iItem++;
+            if (uFlags & SVSI_FOCUSED)
+                lvItem.state &= ~LVIS_FOCUSED;
+        }
+        else
+        {
+            if (uFlags & SVSI_DESELECTOTHERS)
+                lvItem.state &= ~LVIS_SELECTED;
         }
 
-
-        if(uFlags & SVSI_EDIT)
-            SendMessageW(m_hWndList, LVM_EDITLABELW, i, 0);
+        m_ListView.SetItem(&lvItem);
+        lvItem.iItem++;
     }
 
+    if(uFlags & SVSI_EDIT)
+        m_ListView.EditLabel(i);
+
     return S_OK;
 }
 
@@ -2109,17 +2224,20 @@ HRESULT WINAPI CDefView::GetItemObject(UINT uItem, REFIID riid, LPVOID *ppvOut)
             if (IsEqualIID(riid, IID_IContextMenu))
             {
                 //*ppvOut = ISvBgCm_Constructor(m_pSFParent, FALSE);
-                CDefFolderMenu_Create2(NULL, NULL, 0, NULL, m_pSFParent, NULL, 0, NULL, (IContextMenu**)ppvOut);
                 if (!ppvOut)
                     hr = E_OUTOFMEMORY;
-                else
-                    hr = S_OK;
+
+                IContextMenu* pcm;
+                hr = CDefFolderMenu_Create2(NULL, NULL, 0, NULL, m_pSFParent, NULL, 0, NULL, &pcm);
+                if (FAILED(hr))
+                    return hr;
+                *ppvOut = pcm;
             }
             break;
 
         case SVGIO_SELECTION:
             GetSelections();
-            hr = m_pSFParent->GetUIObjectOf(m_hWnd, m_cidl, (LPCITEMIDLIST*)m_apidl, riid, 0, ppvOut);
+            hr = m_pSFParent->GetUIObjectOf(m_hWnd, m_cidl, m_apidl, riid, 0, ppvOut);
             break;
     }
 
@@ -2145,7 +2263,7 @@ HRESULT STDMETHODCALLTYPE CDefView::SetCurrentViewMode(UINT ViewMode)
     TRACE("(%p)->(%u), stub\n", this, ViewMode);
 
     /* It's not redundant to check FVM_AUTO because it's a (UINT)-1 */
-    if ((ViewMode < FVM_FIRST || ViewMode > FVM_LAST) && (ViewMode != (UINT)FVM_AUTO))
+    if (((INT)ViewMode < FVM_FIRST || (INT)ViewMode > FVM_LAST) && ((INT)ViewMode != FVM_AUTO))
         return E_INVALIDARG;
 
     /* Windows before Vista uses LVM_SETVIEW and possibly
@@ -2191,23 +2309,16 @@ HRESULT STDMETHODCALLTYPE CDefView::GetFolder(REFIID riid, void **ppv)
     return m_pSFParent->QueryInterface(riid, ppv);
 }
 
-HRESULT STDMETHODCALLTYPE CDefView::Item(int iItemIndex, LPITEMIDLIST *ppidl)
+HRESULT STDMETHODCALLTYPE CDefView::Item(int iItemIndex, PITEMID_CHILD *ppidl)
 {
-    LVITEMW item;
-
-    TRACE("(%p)->(%d %p)\n", this, iItemIndex, ppidl);
-
-    item.mask = LVIF_PARAM;
-    item.iItem = iItemIndex;
-
-    if (SendMessageW(m_hWndList, LVM_GETITEMW, 0, (LPARAM)&item))
+    PCUITEMID_CHILD pidl = _PidlByItem(iItemIndex);
+    if (pidl)
     {
-        *ppidl = ILClone((PITEMID_CHILD)item.lParam);
+        *ppidl = ILClone(pidl);
         return S_OK;
     }
 
     *ppidl = 0;
-
     return E_INVALIDARG;
 }
 
@@ -2218,7 +2329,7 @@ HRESULT STDMETHODCALLTYPE CDefView::ItemCount(UINT uFlags, int *pcItems)
     if (uFlags != SVGIO_ALLVIEW)
         FIXME("some flags unsupported, %x\n", uFlags & ~SVGIO_ALLVIEW);
 
-    *pcItems = SendMessageW(m_hWndList, LVM_GETITEMCOUNT, 0, 0);
+    *pcItems = m_ListView.GetItemCount();
 
     return S_OK;
 }
@@ -2232,7 +2343,7 @@ HRESULT STDMETHODCALLTYPE CDefView::GetSelectionMarkedItem(int *piItem)
 {
     TRACE("(%p)->(%p)\n", this, piItem);
 
-    *piItem = SendMessageW(m_hWndList, LVM_GETSELECTIONMARK, 0, 0);
+    *piItem = m_ListView.GetSelectionMark();
 
     return S_OK;
 }
@@ -2241,12 +2352,12 @@ HRESULT STDMETHODCALLTYPE CDefView::GetFocusedItem(int *piItem)
 {
     TRACE("(%p)->(%p)\n", this, piItem);
 
-    *piItem = SendMessageW(m_hWndList, LVM_GETNEXTITEM, -1, LVNI_FOCUSED);
+    *piItem = m_ListView.GetNextItem(-1, LVNI_FOCUSED);
 
     return S_OK;
 }
 
-HRESULT STDMETHODCALLTYPE CDefView::GetItemPosition(LPCITEMIDLIST pidl, POINT *ppt)
+HRESULT STDMETHODCALLTYPE CDefView::GetItemPosition(PCUITEMID_CHILD pidl, POINT *ppt)
 {
     return E_NOTIMPL;
 }
@@ -2255,14 +2366,16 @@ HRESULT STDMETHODCALLTYPE CDefView::GetSpacing(POINT *ppt)
 {
     TRACE("(%p)->(%p)\n", this, ppt);
 
-    if (NULL == m_hWndList) return S_FALSE;
+    if (!m_ListView) 
+        return S_FALSE;
 
     if (ppt)
     {
-        const DWORD ret = SendMessageW(m_hWndList, LVM_GETITEMSPACING, 0, 0);
+        SIZE spacing;
+        m_ListView.GetItemSpacing(spacing);
 
-        ppt->x = LOWORD(ret);
-        ppt->y = HIWORD(ret);
+        ppt->x = spacing.cx;
+        ppt->y = spacing.cy;
     }
 
     return S_OK;
@@ -2288,11 +2401,11 @@ HRESULT STDMETHODCALLTYPE CDefView::SelectItem(int iItem, DWORD dwFlags)
     lvItem.stateMask = LVIS_SELECTED;
 
     if (dwFlags & SVSI_ENSUREVISIBLE)
-        SendMessageW(m_hWndList, LVM_ENSUREVISIBLE, iItem, 0);
+        m_ListView.EnsureVisible(iItem, 0);
 
     /* all items */
     if (dwFlags & SVSI_DESELECTOTHERS)
-        SendMessageW(m_hWndList, LVM_SETITEMSTATE, -1, (LPARAM)&lvItem);
+        m_ListView.SetItemState(-1, 0, LVIS_SELECTED);
 
     /* this item */
     if (dwFlags & SVSI_SELECT)
@@ -2301,10 +2414,10 @@ HRESULT STDMETHODCALLTYPE CDefView::SelectItem(int iItem, DWORD dwFlags)
     if (dwFlags & SVSI_FOCUSED)
         lvItem.stateMask |= LVIS_FOCUSED;
 
-    SendMessageW(m_hWndList, LVM_SETITEMSTATE, iItem, (LPARAM)&lvItem);
+    m_ListView.SetItemState(iItem, lvItem.state, lvItem.stateMask);
 
     if (dwFlags & SVSI_EDIT)
-        SendMessageW(m_hWndList, LVM_EDITLABELW, iItem, 0);
+        m_ListView.EditLabel(iItem);
 
     return S_OK;
 }
@@ -2314,6 +2427,201 @@ HRESULT STDMETHODCALLTYPE CDefView::SelectAndPositionItems(UINT cidl, PCUITEMID_
     return E_NOTIMPL;
 }
 
+/**********************************************************
+ * IShellFolderView implementation
+ */
+HRESULT STDMETHODCALLTYPE CDefView::Rearrange(LPARAM sort)
+{
+    FIXME("(%p)->(%ld) stub\n", this, sort);
+    return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CDefView::GetArrangeParam(LPARAM *sort)
+{
+    FIXME("(%p)->(%p) stub\n", this, sort);
+    return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CDefView::ArrangeGrid()
+{
+    FIXME("(%p) stub\n", this);
+    return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CDefView::AutoArrange()
+{
+    FIXME("(%p) stub\n", this);
+    return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CDefView::AddObject(PITEMID_CHILD pidl, UINT *item)
+{
+    FIXME("(%p)->(%p %p) stub\n", this, pidl, item);
+    return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CDefView::GetObject(PITEMID_CHILD *pidl, UINT item)
+{
+    TRACE("(%p)->(%p %d)\n", this, pidl, item);
+    return Item(item, pidl);
+}
+
+HRESULT STDMETHODCALLTYPE CDefView::RemoveObject(PITEMID_CHILD pidl, UINT *item)
+{
+
+    TRACE("(%p)->(%p %p)\n", this, pidl, item);
+
+    if (pidl)
+    {
+        *item = LV_FindItemByPidl(ILFindLastID(pidl));
+        m_ListView.DeleteItem(*item);
+    }
+    else
+    {
+        *item = 0;
+        m_ListView.DeleteAllItems();
+    }
+
+    return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE CDefView::GetObjectCount(UINT *count)
+{
+    TRACE("(%p)->(%p)\n", this, count);
+    *count = m_ListView.GetItemCount();
+    return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE CDefView::SetObjectCount(UINT count, UINT flags)
+{
+    FIXME("(%p)->(%d %x) stub\n", this, count, flags);
+    return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CDefView::UpdateObject(PITEMID_CHILD pidl_old, PITEMID_CHILD pidl_new, UINT *item)
+{
+    FIXME("(%p)->(%p %p %p) stub\n", this, pidl_old, pidl_new, item);
+    return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CDefView::RefreshObject(PITEMID_CHILD pidl, UINT *item)
+{
+    FIXME("(%p)->(%p %p) stub\n", this, pidl, item);
+    return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CDefView::SetRedraw(BOOL redraw)
+{
+    TRACE("(%p)->(%d)\n", this, redraw);
+    m_ListView.SetRedraw(redraw);
+    return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE CDefView::GetSelectedCount(UINT *count)
+{
+    FIXME("(%p)->(%p) stub\n", this, count);
+    return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CDefView::GetSelectedObjects(PCUITEMID_CHILD **pidl, UINT *items)
+{
+    TRACE("(%p)->(%p %p)\n", this, pidl, items);
+
+    *items = GetSelections();
+
+    if (*items)
+    {
+        *pidl = static_cast<PCUITEMID_CHILD *>(LocalAlloc(0, *items * sizeof(PCUITEMID_CHILD)));
+        if (!*pidl)
+        {
+            return E_OUTOFMEMORY;
+        }
+        
+        /* it's documented that caller shouldn't PIDLs, only array itself */
+        memcpy(*pidl, m_apidl, *items * sizeof(PCUITEMID_CHILD));
+    }
+
+    return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE CDefView::IsDropOnSource(IDropTarget *drop_target)
+{
+    FIXME("(%p)->(%p) stub\n", this, drop_target);
+    return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CDefView::GetDragPoint(POINT *pt)
+{
+    FIXME("(%p)->(%p) stub\n", this, pt);
+    return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CDefView::GetDropPoint(POINT *pt)
+{
+    FIXME("(%p)->(%p) stub\n", this, pt);
+    return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CDefView::MoveIcons(IDataObject *obj)
+{
+    TRACE("(%p)->(%p)\n", this, obj);
+    return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CDefView::SetItemPos(PCUITEMID_CHILD pidl, POINT *pt)
+{
+    FIXME("(%p)->(%p %p) stub\n", this, pidl, pt);
+    return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CDefView::IsBkDropTarget(IDropTarget *drop_target)
+{
+    FIXME("(%p)->(%p) stub\n", this, drop_target);
+    return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CDefView::SetClipboard(BOOL move)
+{
+    FIXME("(%p)->(%d) stub\n", this, move);
+    return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CDefView::SetPoints(IDataObject *obj)
+{
+    FIXME("(%p)->(%p) stub\n", this, obj);
+    return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CDefView::GetItemSpacing(ITEMSPACING *spacing)
+{
+    FIXME("(%p)->(%p) stub\n", this, spacing);
+    return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CDefView::SetCallback(IShellFolderViewCB  *new_cb, IShellFolderViewCB **old_cb)
+{
+    FIXME("(%p)->(%p %p) stub\n", this, new_cb, old_cb);
+    return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CDefView::Select(UINT flags)
+{
+    FIXME("(%p)->(%d) stub\n", this, flags);
+    return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CDefView::QuerySupport(UINT *support)
+{
+    TRACE("(%p)->(%p)\n", this, support);
+    return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE CDefView::SetAutomationObject(IDispatch *disp)
+{
+    FIXME("(%p)->(%p) stub\n", this, disp);
+    return E_NOTIMPL;
+}
 /**********************************************************
  * ISVOleCmdTarget_QueryStatus (IOleCommandTarget)
  */
@@ -2347,6 +2655,40 @@ HRESULT WINAPI CDefView::Exec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCm
     if (!pguidCmdGroup)
         return OLECMDERR_E_UNKNOWNGROUP;
 
+    if (IsEqualCLSID(*pguidCmdGroup, m_Category))
+    {
+        if (nCmdID == FCIDM_SHVIEW_AUTOARRANGE)
+        {
+            if (V_VT(pvaIn) != VT_INT_PTR)
+                return OLECMDERR_E_NOTSUPPORTED;
+
+
+            TPMPARAMS params;
+            params.cbSize = sizeof(params);
+            params.rcExclude = *(RECT*) V_INTREF(pvaIn);
+
+            HMENU hView = m_hView;
+#if 0
+            hView = CreatePopupMenu();
+            AppendMenuW(hView, MF_STRING, FCIDM_SHVIEW_BIGICON, L"Big!");
+            AppendMenuW(hView, MF_STRING, FCIDM_SHVIEW_SMALLICON, L"Small!");
+            AppendMenuW(hView, MF_STRING, FCIDM_SHVIEW_LISTVIEW, L"List!");
+            AppendMenuW(hView, MF_STRING, FCIDM_SHVIEW_REPORTVIEW, L"Report!");
+#endif
+
+            if (hView)
+            {
+                PrepareShowViewMenu(hView);
+
+                TrackPopupMenuEx(hView, TPM_LEFTALIGN | TPM_TOPALIGN, params.rcExclude.left, params.rcExclude.bottom, m_hWndParent, &params);
+            }
+
+            // pvaOut is VT_I4 with value 0x403 (cmd id of the new mode maybe?)
+            V_VT(pvaOut) = VT_I4;
+            V_I4(pvaOut) = 0x403;
+        }
+    }
+
     if (IsEqualIID(*pguidCmdGroup, CGID_Explorer) &&
             (nCmdID == 0x29) &&
             (nCmdexecopt == 4) && pvaOut)
@@ -2376,7 +2718,6 @@ HRESULT WINAPI CDefView::Exec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCm
 HRESULT CDefView::drag_notify_subitem(DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
 {
     LVHITTESTINFO htinfo;
-    LVITEMW lvItem;
     LONG lResult;
     HRESULT hr;
     RECT clientRect;
@@ -2386,11 +2727,11 @@ HRESULT CDefView::drag_notify_subitem(DWORD grfKeyState, POINTL pt, DWORD *pdwEf
     htinfo.pt.x = pt.x;
     htinfo.pt.y = pt.y;
     htinfo.flags = LVHT_ONITEM;
-    ::ScreenToClient(m_hWndList, &htinfo.pt);
-    lResult = SendMessageW(m_hWndList, LVM_HITTEST, 0, (LPARAM)&htinfo);
+    ::ScreenToClient(m_ListView, &htinfo.pt);
+    lResult = m_ListView.HitTest(&htinfo);
 
     /* Send WM_*SCROLL messages every 250 ms during drag-scrolling */
-    ::GetClientRect(m_hWndList, &clientRect);
+    ::GetClientRect(m_ListView, &clientRect);
     if (htinfo.pt.x == m_ptLastMousePos.x && htinfo.pt.y == m_ptLastMousePos.y &&
             (htinfo.pt.x < SCROLLAREAWIDTH || htinfo.pt.x > clientRect.right - SCROLLAREAWIDTH ||
              htinfo.pt.y < SCROLLAREAWIDTH || htinfo.pt.y > clientRect.bottom - SCROLLAREAWIDTH ))
@@ -2400,16 +2741,16 @@ HRESULT CDefView::drag_notify_subitem(DWORD grfKeyState, POINTL pt, DWORD *pdwEf
         {
             /* Mouse did hover another 250 ms over the scroll-area */
             if (htinfo.pt.x < SCROLLAREAWIDTH)
-                SendMessageW(m_hWndList, WM_HSCROLL, SB_LINEUP, 0);
+                m_ListView.SendMessageW(WM_HSCROLL, SB_LINEUP, 0);
 
             if (htinfo.pt.x > clientRect.right - SCROLLAREAWIDTH)
-                SendMessageW(m_hWndList, WM_HSCROLL, SB_LINEDOWN, 0);
+                m_ListView.SendMessageW(WM_HSCROLL, SB_LINEDOWN, 0);
 
             if (htinfo.pt.y < SCROLLAREAWIDTH)
-                SendMessageW(m_hWndList, WM_VSCROLL, SB_LINEUP, 0);
+                m_ListView.SendMessageW(WM_VSCROLL, SB_LINEUP, 0);
 
             if (htinfo.pt.y > clientRect.bottom - SCROLLAREAWIDTH)
-                SendMessageW(m_hWndList, WM_VSCROLL, SB_LINEDOWN, 0);
+                m_ListView.SendMessageW(WM_VSCROLL, SB_LINEDOWN, 0);
         }
     }
     else
@@ -2441,14 +2782,10 @@ HRESULT CDefView::drag_notify_subitem(DWORD grfKeyState, POINTL pt, DWORD *pdwEf
     {
         /* Query the relative PIDL of the shellfolder object represented by the currently
          * dragged over listview-item ... */
-        lvItem.mask = LVIF_PARAM;
-        lvItem.iItem = lResult;
-        lvItem.iSubItem = 0;
-        SendMessageW(m_hWndList, LVM_GETITEMW, 0, (LPARAM) &lvItem);
+        PCUITEMID_CHILD pidl = _PidlByItem(lResult);
 
         /* ... and bind m_pCurDropTarget to the IDropTarget interface of an UIObject of this object */
-        hr = m_pSFParent->GetUIObjectOf(m_hWndList, 1,
-                                      (LPCITEMIDLIST*)&lvItem.lParam, IID_IDropTarget, NULL, (LPVOID*)&m_pCurDropTarget);
+        hr = m_pSFParent->GetUIObjectOf(m_ListView, 1, &pidl, IID_NULL_PPV_ARG(IDropTarget, &m_pCurDropTarget));
     }
 
     /* If anything failed, m_pCurDropTarget should be NULL now, which ought to be a save state. */
@@ -2600,35 +2937,37 @@ HRESULT STDMETHODCALLTYPE CDefView::QueryService(REFGUID guidService, REFIID rii
     return E_NOINTERFACE;
 }
 
-/**********************************************************
- *    IShellView_Constructor
- */
-HRESULT WINAPI IShellView_Constructor(IShellFolder *pFolder, IShellView **newView)
+HRESULT CDefView::_MergeToolbar()
 {
-    CComObject<CDefView>                    *theView;
-    CComPtr<IShellView>                        result;
-    HRESULT                                    hResult;
+    CComPtr<IExplorerToolbar> ptb; // [sp+8h] [bp-4h]@1
 
-    if (newView == NULL)
-        return E_POINTER;
+    HRESULT hr = S_OK;
 
-    *newView = NULL;
-    ATLTRY (theView = new CComObject<CDefView>);
+    hr = IUnknown_QueryService(m_pShellBrowser, IID_IExplorerToolbar, IID_PPV_ARG(IExplorerToolbar, &ptb));
+    if (FAILED(hr))
+        return hr;
 
-    if (theView == NULL)
-        return E_OUTOFMEMORY;
+    m_Category = CGID_DefViewFrame;
 
-    hResult = theView->QueryInterface(IID_PPV_ARG(IShellView, &result));
-    if (FAILED (hResult))
-    {
-        delete theView;
-        return hResult;
-    }
+    hr = ptb->SetCommandTarget(static_cast<IOleCommandTarget*>(this), &m_Category, 0);
+    if (FAILED(hr))
+        return hr;
 
-    hResult = theView->Initialize (pFolder);
-    if (FAILED (hResult))
-        return hResult;
-    *newView = result.Detach ();
+    if (hr == S_FALSE)
+        return S_OK;
+
+#if 0
+    hr = ptb->AddButtons(&m_Category, buttonsCount, buttons);
+    if (FAILED(hr))
+        return hr;
+#endif
 
     return S_OK;
 }
+/**********************************************************
+ *    IShellView_Constructor
+ */
+HRESULT WINAPI IShellView_Constructor(IShellFolder *pFolder, IShellView **newView)
+{
+    return ShellObjectCreatorInit<CDefView>(pFolder, IID_IShellView, newView);
+}