private:
CComPtr<IShellFolder> m_pSFParent;
CComPtr<IShellFolder2> m_pSF2Parent;
+ CComPtr<IShellFolderViewCB> m_pShellFolderViewCB;
CComPtr<IShellBrowser> m_pShellBrowser;
CComPtr<ICommDlgBrowser> m_pCommDlgBrowser;
CComPtr<IShellFolderViewDual> m_pShellFolderViewDual;
UINT m_cScrollDelay; /* Send a WM_*SCROLL msg every 250 ms during drag-scroll */
POINT m_ptLastMousePos; /* Mouse position at last DragOver call */
POINT m_ptFirstMousePos; /* Mouse position when the drag operation started */
+ DWORD m_grfKeyState;
//
CComPtr<IContextMenu> m_pCM;
CLSID m_Category;
BOOL m_Destroyed;
+ SFVM_CUSTOMVIEWINFO_DATA m_viewinfo_data;
private:
HRESULT _MergeToolbar();
BOOL _Sort();
+ HRESULT _DoFolderViewCB(UINT uMsg, WPARAM wParam, LPARAM lParam);
public:
CDefView();
HRESULT OnStateChange(UINT uFlags);
void UpdateStatusbar();
void CheckToolbar();
- void SetStyle(DWORD dwAdd, DWORD dwRemove);
BOOL CreateList();
void UpdateListColors();
BOOL InitList();
+ HRESULT DefMessageSFVCB(UINT uMsg, WPARAM wParam, LPARAM lParam);
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);
+ int LV_AddItem(PCUITEMID_CHILD pidl);
BOOLEAN LV_DeleteItem(PCUITEMID_CHILD pidl);
BOOLEAN LV_RenameItem(PCUITEMID_CHILD pidlOld, PCUITEMID_CHILD pidlNew);
BOOLEAN LV_ProdItem(PCUITEMID_CHILD pidl);
LRESULT OnGetDlgCode(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
LRESULT OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
LRESULT OnEraseBackground(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
+ LRESULT OnPrintClient(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
LRESULT OnSysColorChange(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
LRESULT OnGetShellBrowser(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
LRESULT OnNCCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
{
{ sizeof(WNDCLASSEX), CS_PARENTDC, StartWindowProc,
0, 0, NULL, NULL,
- LoadCursor(NULL, IDC_ARROW), (HBRUSH)(COLOR_WINDOW + 1), NULL, SV_CLASS_NAME, NULL
+ LoadCursor(NULL, IDC_ARROW), NULL, NULL, SV_CLASS_NAME, NULL
},
NULL, NULL, IDC_ARROW, TRUE, 0, _T("")
};
MESSAGE_HANDLER(WM_GETDLGCODE, OnGetDlgCode)
MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBackground)
+ MESSAGE_HANDLER(WM_PRINTCLIENT, OnPrintClient)
MESSAGE_HANDLER(WM_SYSCOLORCHANGE, OnSysColorChange)
MESSAGE_HANDLER(CWM_GETISHELLBROWSER, OnGetShellBrowser)
MESSAGE_HANDLER(WM_SETTINGCHANGE, OnSettingChange)
ZeroMemory(&m_sortInfo, sizeof(m_sortInfo));
ZeroMemory(&m_ptLastMousePos, sizeof(m_ptLastMousePos));
ZeroMemory(&m_Category, sizeof(m_Category));
+ m_viewinfo_data.clrText = GetSysColor(COLOR_WINDOWTEXT);
+ m_viewinfo_data.clrTextBack = GetSysColor(COLOR_WINDOW);
+ m_viewinfo_data.hbmBack = NULL;
}
CDefView::~CDefView()
{
TRACE(" destroying IShellView(%p)\n", this);
+ if (m_viewinfo_data.hbmBack)
+ {
+ ::DeleteObject(m_viewinfo_data.hbmBack);
+ m_viewinfo_data.hbmBack = NULL;
+ }
+
if (m_hWnd)
{
DestroyViewWindow();
{
TRACE("ICommDlgBrowser::IncludeObject pidl=%p\n", pidl);
ret = m_pCommDlgBrowser->IncludeObject(this, pidl);
- TRACE("--0x%08x\n", ret);
+ TRACE("-- returns 0x%08x\n", ret);
}
return ret;
{
TRACE("ICommDlgBrowser::OnDefaultCommand\n");
ret = m_pCommDlgBrowser->OnDefaultCommand(this);
- TRACE("-- returns %08x\n", ret);
+ TRACE("-- returns 0x%08x\n", ret);
}
return ret;
*
* ##### helperfunctions for initializing the view #####
*/
-/**********************************************************
- * change the style of the listview control
- */
-void CDefView::SetStyle(DWORD dwAdd, DWORD dwRemove)
-{
- DWORD tmpstyle;
-
- TRACE("(%p)\n", this);
-
- tmpstyle = ::GetWindowLongPtrW(m_ListView, GWL_STYLE);
- ::SetWindowLongPtrW(m_ListView, GWL_STYLE, dwAdd | (tmpstyle & ~dwRemove));
-}
/**********************************************************
* ShellView_CreateList()
*/
BOOL CDefView::CreateList()
{
+ HRESULT hr;
DWORD dwStyle, dwExStyle;
+ UINT ViewMode;
TRACE("%p\n", this);
else
dwStyle |= LVS_ALIGNTOP | LVS_SHOWSELALWAYS;
+ ViewMode = m_FolderSettings.ViewMode;
+ hr = _DoFolderViewCB(SFVM_DEFVIEWMODE, NULL, (LPARAM)&ViewMode);
+ if (SUCCEEDED(hr))
+ {
+ if (ViewMode >= FVM_FIRST && ViewMode <= FVM_LAST)
+ m_FolderSettings.ViewMode = ViewMode;
+ else
+ ERR("Ignoring invalid ViewMode from SFVM_DEFVIEWMODE: %u (was: %u)\n", ViewMode, m_FolderSettings.ViewMode);
+ }
+
switch (m_FolderSettings.ViewMode)
{
case FVM_ICON:
m_sortInfo.nHeaderID = -1;
m_sortInfo.nLastHeaderID = -1;
- UpdateListColors();
-
/* UpdateShellSettings(); */
return TRUE;
}
m_ListView.SetExtendedListViewStyle(0, LVS_EX_TRANSPARENTSHADOWTEXT);
}
}
+ else
+ {
+ // text background color
+ COLORREF clrTextBack = m_viewinfo_data.clrTextBack;
+ m_ListView.SetTextBkColor(clrTextBack);
+
+ // text color
+ COLORREF clrText;
+ if (m_viewinfo_data.clrText != CLR_INVALID)
+ clrText = m_viewinfo_data.clrText;
+ else
+ clrText = GetSysColor(COLOR_WINDOWTEXT);
+
+ m_ListView.SetTextColor(clrText);
+
+ // Background is painted by the parent via WM_PRINTCLIENT.
+ m_ListView.SetExtendedListViewStyle(LVS_EX_TRANSPARENTBKGND, LVS_EX_TRANSPARENTBKGND);
+ }
}
/**********************************************************
/**********************************************************
* LV_AddItem()
*/
-BOOLEAN CDefView::LV_AddItem(PCUITEMID_CHILD pidl)
+int CDefView::LV_AddItem(PCUITEMID_CHILD pidl)
{
LVITEMW lvItem;
lvItem.iImage = I_IMAGECALLBACK; /*get the image on a callback basis*/
lvItem.stateMask = LVIS_CUT;
- if (m_ListView.InsertItem(&lvItem) == -1)
- return FALSE;
- else
- return TRUE;
+ return m_ListView.InsertItem(&lvItem);
}
/**********************************************************
DWORD dwFetched;
HRESULT hRes;
HDPA hdpa;
- HKEY hKey;
DWORD dFlags = SHCONTF_NONFOLDERS | SHCONTF_FOLDERS;
+ DWORD dwValue, cbValue;
TRACE("%p\n", this);
/* determine if there is a setting to show all the hidden files/folders */
- if (RegOpenKeyExW(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced", 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS)
+ dwValue = 1;
+ cbValue = sizeof(dwValue);
+ SHGetValueW(HKEY_CURRENT_USER,
+ L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced",
+ L"Hidden", NULL, &dwValue, &cbValue);
+ if (dwValue == 1)
{
- DWORD dataLength, flagVal;
-
- dataLength = sizeof(flagVal);
- if (RegQueryValueExW(hKey, L"Hidden", NULL, NULL, (LPBYTE)&flagVal, &dataLength) == ERROR_SUCCESS)
- {
- /* if the value is 1, then show all hidden files/folders */
- if (flagVal == 1)
- {
- dFlags |= SHCONTF_INCLUDEHIDDEN;
- m_ListView.SendMessageW(LVM_SETCALLBACKMASK, LVIS_CUT, 0);
- }
- }
+ dFlags |= SHCONTF_INCLUDEHIDDEN;
+ m_ListView.SendMessageW(LVM_SETCALLBACKMASK, LVIS_CUT, 0);
+ }
- /* close the key */
- RegCloseKey(hKey);
+ dwValue = 0;
+ cbValue = sizeof(dwValue);
+ SHGetValueW(HKEY_CURRENT_USER,
+ L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced",
+ L"ShowSuperHidden", NULL, &dwValue, &cbValue);
+ if (dwValue)
+ {
+ dFlags |= SHCONTF_INCLUDESUPERHIDDEN;
+ m_ListView.SendMessageW(LVM_SETCALLBACKMASK, LVIS_CUT, 0);
}
/* get the itemlist from the shfolder */
m_sortInfo.bIsAscending = TRUE;
_Sort();
+ if (m_viewinfo_data.hbmBack)
+ {
+ ::DeleteObject(m_viewinfo_data.hbmBack);
+ m_viewinfo_data.hbmBack = NULL;
+ }
+
+ // load custom background image and custom text color
+ m_viewinfo_data.cbSize = sizeof(m_viewinfo_data);
+ _DoFolderViewCB(SFVM_GET_CUSTOMVIEWINFO, 0, (LPARAM)&m_viewinfo_data);
+
/*turn the listview's redrawing back on and force it to draw*/
m_ListView.SetRedraw(TRUE);
+ UpdateListColors();
+
+ if (!(m_FolderSettings.fFlags & FWF_DESKTOP))
+ {
+ // redraw now
+ m_ListView.InvalidateRect(NULL, TRUE);
+ }
+
+ _DoFolderViewCB(SFVM_LISTREFRESHED, NULL, NULL);
+
return S_OK;
}
return 0;
}
+static VOID
+DrawTileBitmap(HDC hDC, LPCRECT prc, HBITMAP hbm, INT nWidth, INT nHeight, INT dx, INT dy)
+{
+ INT x0 = prc->left, y0 = prc->top, x1 = prc->right, y1 = prc->bottom;
+ x0 += dx;
+ y0 += dy;
+
+ HDC hMemDC = CreateCompatibleDC(hDC);
+ HGDIOBJ hbmOld = SelectObject(hMemDC, hbm);
+
+ for (INT y = y0; y < y1; y += nHeight)
+ {
+ for (INT x = x0; x < x1; x += nWidth)
+ {
+ BitBlt(hDC, x, y, nWidth, nHeight, hMemDC, 0, 0, SRCCOPY);
+ }
+ }
+
+ SelectObject(hMemDC, hbmOld);
+ DeleteDC(hMemDC);
+}
+
+LRESULT CDefView::OnPrintClient(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
+{
+ HDC hDC = (HDC)wParam;
+
+ RECT rc;
+ ::GetClientRect(m_ListView, &rc);
+
+ if (m_viewinfo_data.hbmBack)
+ {
+ BITMAP bm;
+ if (::GetObject(m_viewinfo_data.hbmBack, sizeof(BITMAP), &bm))
+ {
+ INT dx = -(::GetScrollPos(m_ListView, SB_HORZ) % bm.bmWidth);
+ INT dy = -(::GetScrollPos(m_ListView, SB_VERT) % bm.bmHeight);
+ DrawTileBitmap(hDC, &rc, m_viewinfo_data.hbmBack, bm.bmWidth, bm.bmHeight, dx, dy);
+ }
+ }
+ else
+ {
+ FillRect(hDC, &rc, GetSysColorBrush(COLOR_WINDOW));
+ }
+
+ bHandled = TRUE;
+
+ return TRUE;
+}
+
LRESULT CDefView::OnSysColorChange(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
{
/* Update desktop labels color */
TRACE("%p\n", this);
- if (CreateList())
- {
- if (InitList())
- {
- FillList();
- }
- }
-
if (SUCCEEDED(QueryInterface(IID_PPV_ARG(IDropTarget, &pdt))))
{
if (FAILED(RegisterDragDrop(m_hWnd, pdt)))
m_hNotify = SHChangeNotifyRegister(m_hWnd, SHCNRF_InterruptLevel | SHCNRF_ShellLevel, SHCNE_ALLEVENTS, SHV_CHANGE_NOTIFY, 1, &ntreg);
}
+ if (CreateList())
+ {
+ if (InitList())
+ {
+ FillList();
+ }
+ }
+
+ /* _DoFolderViewCB(SFVM_GETNOTIFY, ?? ??) */
+
m_hAccel = LoadAcceleratorsW(shell32_hInstance, MAKEINTRESOURCEW(IDA_SHELLVIEW));
UpdateStatusbar();
DeleteMenu(hFileMenu, i, MF_BYPOSITION);
}
+ m_cidl = m_ListView.GetSelectedCount();
+
/* Store the context menu in m_pCM and keep it in order to invoke the selected command later on */
- HRESULT hr = GetItemObject(SVGIO_SELECTION, IID_PPV_ARG(IContextMenu, &m_pCM));
+ HRESULT hr = GetItemObject((m_cidl ? SVGIO_SELECTION : SVGIO_BACKGROUND),
+ IID_PPV_ARG(IContextMenu, &m_pCM));
if (FAILED_UNEXPECTEDLY(hr))
return hr;
- IUnknown_SetSite(m_pCM, (IShellView *)this);
-
HMENU hmenu = CreatePopupMenu();
hr = m_pCM->QueryContextMenu(hmenu, 0, FCIDM_SHVIEWFIRST, FCIDM_SHVIEWLAST, 0);
m_sortInfo.nHeaderID + 0x30,
MF_BYCOMMAND);
+ if (m_FolderSettings.ViewMode == FVM_DETAILS || m_FolderSettings.ViewMode == FVM_LIST)
+ {
+ EnableMenuItem(hmenuArrange, FCIDM_SHVIEW_AUTOARRANGE, MF_BYCOMMAND | MF_GRAYED);
+ }
+ else
+ {
+ EnableMenuItem(hmenuArrange, FCIDM_SHVIEW_AUTOARRANGE, MF_BYCOMMAND);
+
+ if (GetAutoArrange() == S_OK)
+ CheckMenuItem(hmenuArrange, FCIDM_SHVIEW_AUTOARRANGE, MF_CHECKED);
+ }
+
+
return S_OK;
}
if (FAILED_UNEXPECTEDLY(hResult))
goto cleanup;
- IUnknown_SetSite(m_pCM, (IShellView *)this);
-
hResult = m_pCM->QueryContextMenu(hMenu, 0, FCIDM_SHVIEWFIRST, FCIDM_SHVIEWLAST, CMF_DEFAULTONLY);
if (FAILED_UNEXPECTEDLY(hResult))
goto cleanup;
*/
LRESULT CDefView::OnContextMenu(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
{
- WORD x, y;
+ int x, y;
UINT uCommand;
HRESULT hResult;
- x = LOWORD(lParam);
- y = HIWORD(lParam);
-
- TRACE("(%p)->(0x%08x 0x%08x) stub\n", this, x, y);
+ TRACE("(%p)\n", this);
m_hContextMenu = CreatePopupMenu();
if (!m_hContextMenu)
return E_FAIL;
+ if (lParam != ~0) // unless app key (menu key) was pressed
+ {
+ x = GET_X_LPARAM(lParam);
+ y = GET_Y_LPARAM(lParam);
+
+ LV_HITTESTINFO hittest = { { x, y } };
+ ScreenToClient(&hittest.pt);
+ m_ListView.HitTest(&hittest);
+
+ // Right-Clicked item is selected? If selected, no selection change.
+ // If not selected, then reset the selection and select the item.
+ if ((hittest.flags & LVHT_ONITEM) &&
+ m_ListView.GetItemState(hittest.iItem, LVIS_SELECTED) != LVIS_SELECTED)
+ {
+ SelectItem(hittest.iItem, SVSI_SELECT | SVSI_DESELECTOTHERS | SVSI_ENSUREVISIBLE);
+ }
+ }
+
m_cidl = m_ListView.GetSelectedCount();
hResult = GetItemObject( m_cidl ? SVGIO_SELECTION : SVGIO_BACKGROUND, IID_PPV_ARG(IContextMenu, &m_pCM));
if (FAILED_UNEXPECTEDLY(hResult))
goto cleanup;
- IUnknown_SetSite(m_pCM, (IShellView *)this);
-
/* Use 1 as the first id as we want 0 the mean that the user canceled the menu */
hResult = m_pCM->QueryContextMenu(m_hContextMenu, 0, CONTEXT_MENU_BASE_ID, FCIDM_SHVIEWLAST, CMF_NORMAL);
if (FAILED_UNEXPECTEDLY(hResult))
goto cleanup;
+ /* There is no position requested, so try to find one */
+ if (lParam == ~0)
+ {
+ HWND hFocus = ::GetFocus();
+ int lvIndex = -1;
+ POINT pt;
+
+ if (hFocus == m_ListView.m_hWnd || m_ListView.IsChild(hFocus))
+ {
+ /* Is there an item focused and selected? */
+ lvIndex = m_ListView.GetNextItem(-1, LVIS_SELECTED|LVIS_FOCUSED);
+ /* If not, find the first selected item */
+ if (lvIndex < 0)
+ lvIndex = m_ListView.GetNextItem(-1, LVIS_SELECTED);
+ }
+
+ /* We got something */
+ if (lvIndex > -1)
+ {
+ /* Let's find the center of the icon */
+ RECT rc = { LVIR_ICON };
+ m_ListView.SendMessage(LVM_GETITEMRECT, lvIndex, (LPARAM)&rc);
+ pt.x = (rc.right + rc.left) / 2;
+ pt.y = (rc.bottom + rc.top) / 2;
+ }
+ else
+ {
+ /* We have to drop it somewhere.. */
+ pt.x = pt.y = 0;
+ }
+
+ m_ListView.ClientToScreen(&pt);
+ x = pt.x;
+ y = pt.y;
+ }
+
uCommand = TrackPopupMenu(m_hContextMenu,
TPM_LEFTALIGN | TPM_RETURNCMD | TPM_LEFTBUTTON | TPM_RIGHTBUTTON,
x, y, 0, m_hWnd, NULL);
if (FAILED_UNEXPECTEDLY( hResult))
goto cleanup;
- IUnknown_SetSite(m_pCM, (IShellView *)this);
-
hResult = m_pCM->QueryContextMenu(hMenu, 0, FCIDM_SHVIEWFIRST, FCIDM_SHVIEWLAST, CMF_NORMAL);
if (FAILED_UNEXPECTEDLY( hResult))
goto cleanup;
::MoveWindow(m_ListView, 0, 0, wWidth, wHeight, TRUE);
}
+ _DoFolderViewCB(SFVM_SIZE, 0, 0);
+
return 0;
}
{
case FCIDM_SHVIEW_SMALLICON:
m_FolderSettings.ViewMode = FVM_SMALLICON;
- SetStyle (LVS_SMALLICON, LVS_TYPEMASK);
+ m_ListView.ModifyStyle(LVS_TYPEMASK, LVS_SMALLICON);
CheckToolbar();
break;
case FCIDM_SHVIEW_BIGICON:
m_FolderSettings.ViewMode = FVM_ICON;
- SetStyle (LVS_ICON, LVS_TYPEMASK);
+ m_ListView.ModifyStyle(LVS_TYPEMASK, LVS_ICON);
CheckToolbar();
break;
case FCIDM_SHVIEW_LISTVIEW:
m_FolderSettings.ViewMode = FVM_LIST;
- SetStyle (LVS_LIST, LVS_TYPEMASK);
+ m_ListView.ModifyStyle(LVS_TYPEMASK, LVS_LIST);
CheckToolbar();
break;
case FCIDM_SHVIEW_REPORTVIEW:
m_FolderSettings.ViewMode = FVM_DETAILS;
- SetStyle (LVS_REPORT, LVS_TYPEMASK);
+ m_ListView.ModifyStyle(LVS_TYPEMASK, LVS_REPORT);
CheckToolbar();
break;
break;
case FCIDM_SHVIEW_SNAPTOGRID:
- case FCIDM_SHVIEW_AUTOARRANGE:
//FIXME
break;
+ case FCIDM_SHVIEW_AUTOARRANGE:
+ if (GetAutoArrange() == S_OK)
+ m_ListView.ModifyStyle(LVS_AUTOARRANGE, 0);
+ else
+ AutoArrange();
+ break;
case FCIDM_SHVIEW_SELECTALL:
m_ListView.SetItemState(-1, LVIS_SELECTED, LVIS_SELECTED);
break;
return 0;
}
+static BOOL
+SelectExtOnRename(void)
+{
+ HKEY hKey;
+ LONG error;
+ DWORD dwValue = FALSE, cbValue;
+
+ error = RegOpenKeyExW(HKEY_CURRENT_USER,
+ L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer",
+ 0, KEY_READ, &hKey);
+ if (error)
+ return dwValue;
+
+ cbValue = sizeof(dwValue);
+ RegQueryValueExW(hKey, L"SelectExtOnRename", NULL, NULL, (LPBYTE)&dwValue, &cbValue);
+
+ RegCloseKey(hKey);
+ return !!dwValue;
+}
+
/**********************************************************
* ShellView_OnNotify()
*/
TRACE("-- LVN_ITEMCHANGED %p\n", this);
OnStateChange(CDBOSC_SELCHANGE); /* the browser will get the IDataObject now */
UpdateStatusbar();
+ _DoFolderViewCB(SFVM_SELECTIONCHANGED, NULL/* FIXME */, NULL/* FIXME */);
break;
case LVN_BEGINDRAG:
if (GetSelections())
{
CComPtr<IDataObject> pda;
- DWORD dwAttributes = SFGAO_CANLINK;
- DWORD dwEffect = DROPEFFECT_COPY | DROPEFFECT_MOVE;
+ DWORD dwAttributes = SFGAO_CANCOPY | SFGAO_CANLINK;
+ DWORD dwEffect = DROPEFFECT_MOVE;
if (SUCCEEDED(m_pSFParent->GetUIObjectOf(m_hWnd, m_cidl, m_apidl, IID_NULL_PPV_ARG(IDataObject, &pda))))
{
if (SUCCEEDED(m_pSFParent->GetAttributesOf(m_cidl, m_apidl, &dwAttributes)))
{
- if (dwAttributes & SFGAO_CANLINK)
- {
- dwEffect |= DROPEFFECT_LINK;
- }
+ dwEffect |= dwAttributes & (SFGAO_CANCOPY | SFGAO_CANLINK);
}
CComPtr<IAsyncOperation> piaso;
m_pSFParent->GetAttributesOf(1, &pidl, &dwAttr);
if (SFGAO_CANRENAME & dwAttr)
{
+ HWND hEdit = reinterpret_cast<HWND>(m_ListView.SendMessage(LVM_GETEDITCONTROL));
+ SHLimitInputEdit(hEdit, m_pSFParent);
+
+ if (!(dwAttr & SFGAO_LINK) && (lpdi->item.mask & LVIF_TEXT) && !SelectExtOnRename())
+ {
+ LPWSTR pszText = lpdi->item.pszText;
+ LPWSTR pchDotExt = PathFindExtensionW(pszText);
+ ::PostMessageW(hEdit, EM_SETSEL, 0, pchDotExt - pszText);
+ ::PostMessageW(hEdit, EM_SCROLLCARET, 0, 0);
+ }
+
m_isEditing = TRUE;
return FALSE;
}
+
return TRUE;
}
LVITEMW lvItem;
pidl = _PidlByItem(lpdi->item);
- PITEMID_CHILD pidlNew;
+ PITEMID_CHILD pidlNew = NULL;
hr = m_pSFParent->SetNameOf(0, pidl, lpdi->item.pszText, SHGDN_INFOLDER, &pidlNew);
if (SUCCEEDED(hr) && pidlNew)
if (::TranslateAcceleratorW(m_hWnd, m_hAccel, lpmsg) != 0)
return S_OK;
- TRACE("-- key=0x04%lx\n", lpmsg->wParam) ;
+ TRACE("-- key=0x%04lx\n", lpmsg->wParam) ;
}
return m_pShellBrowser->TranslateAcceleratorSB(lpmsg, 0);
if (i == -1)
return S_OK;
- if(uFlags & SVSI_ENSUREVISIBLE)
- m_ListView.EnsureVisible(i, FALSE);
-
LVITEMW lvItem = {0};
lvItem.mask = LVIF_STATE;
lvItem.stateMask = LVIS_SELECTED | LVIS_FOCUSED;
lvItem.state &= ~LVIS_SELECTED;
if (uFlags & SVSI_FOCUSED)
+ lvItem.state |= LVIS_FOCUSED;
+ else
lvItem.state &= ~LVIS_FOCUSED;
}
else
{
if (uFlags & SVSI_DESELECTOTHERS)
+ {
lvItem.state &= ~LVIS_SELECTED;
+ }
+ lvItem.state &= ~LVIS_FOCUSED;
}
m_ListView.SetItem(&lvItem);
lvItem.iItem++;
}
+ if (uFlags & SVSI_ENSUREVISIBLE)
+ m_ListView.EnsureVisible(i, FALSE);
+
if((uFlags & SVSI_EDIT) == SVSI_EDIT)
m_ListView.EditLabel(i);
TRACE("(%p)->(uItem=0x%08x,\n\tIID=%s, ppv=%p)\n", this, uItem, debugstr_guid(&riid), ppvOut);
+ if (!ppvOut)
+ return E_INVALIDARG;
+
*ppvOut = NULL;
switch (uItem)
case SVGIO_BACKGROUND:
if (IsEqualIID(riid, IID_IContextMenu))
{
- if (!ppvOut)
- hr = E_OUTOFMEMORY;
-
hr = CDefViewBckgrndMenu_CreateInstance(m_pSF2Parent, riid, ppvOut);
if (FAILED_UNEXPECTEDLY(hr))
return hr;
+ IUnknown_SetSite(*((IUnknown**)ppvOut), (IShellView *)this);
}
else if (IsEqualIID(riid, IID_IDispatch))
{
hr = m_pSFParent->GetUIObjectOf(m_hWnd, m_cidl, m_apidl, riid, 0, ppvOut);
if (FAILED_UNEXPECTEDLY(hr))
return hr;
+
+ if (IsEqualIID(riid, IID_IContextMenu))
+ IUnknown_SetSite(*((IUnknown**)ppvOut), (IShellView *)this);
+
break;
}
}
}
- SetStyle(dwStyle, LVS_TYPEMASK);
+ m_ListView.ModifyStyle(LVS_TYPEMASK, dwStyle);
/* This will not necessarily be the actual mode set above.
This mimics the behavior of Windows XP. */
HRESULT STDMETHODCALLTYPE CDefView::GetItemPosition(PCUITEMID_CHILD pidl, POINT *ppt)
{
- return E_NOTIMPL;
+ int lvIndex = LV_FindItemByPidl(pidl);
+ if (lvIndex == -1 || ppt == NULL)
+ return E_INVALIDARG;
+
+ m_ListView.GetItemPosition(lvIndex, ppt);
+ return S_OK;
}
HRESULT STDMETHODCALLTYPE CDefView::GetSpacing(POINT *ppt)
HRESULT STDMETHODCALLTYPE CDefView::GetAutoArrange()
{
- return E_NOTIMPL;
+ return ((m_ListView.GetStyle() & LVS_AUTOARRANGE) ? S_OK : S_FALSE);
}
HRESULT STDMETHODCALLTYPE CDefView::SelectItem(int iItem, DWORD dwFlags)
HRESULT STDMETHODCALLTYPE CDefView::SelectAndPositionItems(UINT cidl, PCUITEMID_CHILD_ARRAY apidl, POINT *apt, DWORD dwFlags)
{
- return E_NOTIMPL;
+ /* Reset the selection */
+ m_ListView.SetItemState(-1, 0, LVIS_SELECTED);
+
+ int lvIndex;
+ for (UINT i = 0 ; i < m_cidl; i++)
+ {
+ lvIndex = LV_FindItemByPidl(apidl[i]);
+ if (lvIndex != -1)
+ {
+ SelectItem(lvIndex, dwFlags);
+ m_ListView.SetItemPosition(lvIndex, &apt[i]);
+ }
+ }
+
+ return S_OK;
}
/**********************************************************
if (!*hwnd)
return E_FAIL;
+ _DoFolderViewCB(SFVM_WINDOWCREATED, (WPARAM)m_hWnd, NULL);
+
SetWindowPos(HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
UpdateWindow();
HRESULT STDMETHODCALLTYPE CDefView::AutoArrange()
{
- FIXME("(%p) stub\n", this);
- return E_NOTIMPL;
+ m_ListView.ModifyStyle(0, LVS_AUTOARRANGE);
+ m_ListView.Arrange(LVA_DEFAULT);
+ return S_OK;
}
HRESULT STDMETHODCALLTYPE CDefView::AddObject(PITEMID_CHILD pidl, UINT *item)
{
- FIXME("(%p)->(%p %p) stub\n", this, pidl, item);
- return E_NOTIMPL;
+ TRACE("(%p)->(%p %p)\n", this, pidl, item);
+ *item = LV_AddItem(pidl);
+ return (int)*item >= 0 ? S_OK : E_OUTOFMEMORY;
}
HRESULT STDMETHODCALLTYPE CDefView::GetObject(PITEMID_CHILD *pidl, UINT item)
HRESULT STDMETHODCALLTYPE CDefView::IsDropOnSource(IDropTarget *drop_target)
{
- FIXME("(%p)->(%p) stub\n", this, drop_target);
- return E_NOTIMPL;
+ if ((m_iDragOverItem == -1 || m_pCurDropTarget == NULL) &&
+ (m_pSourceDataObject.p))
+ {
+ return S_OK;
+ }
+
+ return S_FALSE;
}
HRESULT STDMETHODCALLTYPE CDefView::GetDragPoint(POINT *pt)
{
- FIXME("(%p)->(%p) stub\n", this, pt);
- return E_NOTIMPL;
+ if (!pt)
+ return E_INVALIDARG;
+
+ *pt = m_ptFirstMousePos;
+ return S_OK;
}
HRESULT STDMETHODCALLTYPE CDefView::GetDropPoint(POINT *pt)
HRESULT STDMETHODCALLTYPE CDefView::SetCallback(IShellFolderViewCB *new_cb, IShellFolderViewCB **old_cb)
{
- FIXME("(%p)->(%p %p) stub\n", this, new_cb, old_cb);
- return E_NOTIMPL;
+ if (old_cb)
+ *old_cb = m_pShellFolderViewCB.Detach();
+
+ m_pShellFolderViewCB = new_cb;
+ return S_OK;
}
HRESULT STDMETHODCALLTYPE CDefView::Select(UINT flags)
HRESULT hr;
RECT clientRect;
+ /* The key state on drop doesn't have MK_LBUTTON or MK_RBUTTON because it
+ reflects the key state after the user released the button, so we need
+ to remember the last key state when the button was pressed */
+ m_grfKeyState = grfKeyState;
+
/* Map from global to client coordinates and query the index of the listview-item, which is
* currently under the mouse cursor. */
LVHITTESTINFO htinfo = {{pt.x, pt.y}, LVHT_ONITEM};
hr = m_pSFParent->GetUIObjectOf(m_ListView, 1, &pidl, IID_NULL_PPV_ARG(IDropTarget, &m_pCurDropTarget));
}
+ IUnknown_SetSite(m_pCurDropTarget, (IShellView *)this);
+
/* If anything failed, m_pCurDropTarget should be NULL now, which ought to be a save state. */
if (FAILED(hr))
{
HRESULT WINAPI CDefView::DragEnter(IDataObject *pDataObject, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
{
+ if (*pdwEffect == DROPEFFECT_NONE)
+ return S_OK;
+
/* Get a hold on the data object for later calls to DragEnter on the sub-folders */
m_pCurDataObject = pDataObject;
HRESULT WINAPI CDefView::Drop(IDataObject* pDataObject, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
{
- ERR("GetKeyState(VK_LBUTTON): %d\n", GetKeyState(VK_LBUTTON));
-
ImageList_DragLeave(m_hWnd);
ImageList_EndDrag();
- if ((m_iDragOverItem == -1 || m_pCurDropTarget == NULL) &&
+ if ((IsDropOnSource(NULL) == S_OK) &&
(*pdwEffect & DROPEFFECT_MOVE) &&
- /*(GetKeyState(VK_LBUTTON) != 0) &&*/
- (m_pSourceDataObject.p) &&
- (SHIsSameObject(pDataObject, m_pSourceDataObject)))
+ (m_grfKeyState & MK_LBUTTON))
{
if (m_pCurDropTarget)
{
HRESULT WINAPI CDefView::SetAdvise(DWORD aspects, DWORD advf, IAdviseSink *pAdvSink)
{
- FIXME("partial stub: %p %08x %08x %p\n", this, aspects, advf, pAdvSink);
+ FIXME("partial stub: %p 0x%08x 0x%08x %p\n", this, aspects, advf, pAdvSink);
/* FIXME: we set the AdviseSink, but never use it to send any advice */
m_pAdvSink = pAdvSink;
return S_OK;
}
+// The default processing of IShellFolderView callbacks
+HRESULT CDefView::DefMessageSFVCB(UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ // TODO: SFVM_GET_CUSTOMVIEWINFO, SFVM_WINDOWCREATED
+ TRACE("CDefView::DefMessageSFVCB uMsg=%u\n", uMsg);
+ return E_NOTIMPL;
+}
+
+HRESULT CDefView::_DoFolderViewCB(UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ HRESULT hr = E_NOTIMPL;
+
+ if (m_pShellFolderViewCB)
+ {
+ hr = m_pShellFolderViewCB->MessageSFVCB(uMsg, wParam, lParam);
+ }
+
+ if (hr == E_NOTIMPL)
+ {
+ hr = DefMessageSFVCB(uMsg, wParam, lParam);
+ }
+
+ return hr;
+}
+
HRESULT CDefView_CreateInstance(IShellFolder *pFolder, REFIID riid, LPVOID * ppvOut)
{
return ShellObjectCreatorInit<CDefView>(pFolder, riid, ppvOut);
CComPtr<IShellView> psv;
HRESULT hRes;
+ if (!ppsv)
+ return E_INVALIDARG;
+
*ppsv = NULL;
+
if (!pcsfv || pcsfv->cbSize != sizeof(*pcsfv))
return E_INVALIDARG;
if (FAILED(hRes))
return hRes;
+ if (pcsfv->psfvcb)
+ {
+ CComPtr<IShellFolderView> sfv;
+ if (SUCCEEDED(psv->QueryInterface(IID_PPV_ARG(IShellFolderView, &sfv))))
+ {
+ sfv->SetCallback(pcsfv->psfvcb, NULL);
+ }
+ }
+
*ppsv = psv.Detach();
return hRes;
}