diff --git a/dlls/shell32/pidl.c b/dlls/shell32/pidl.c index c1d63e96092..545e238fe1d 100644 --- a/dlls/shell32/pidl.c +++ b/dlls/shell32/pidl.c @@ -765,10 +765,10 @@ LPITEMIDLIST WINAPI SHLogILFromFSIL(LPITEMIDLIST pidl) * NOTES * exported by ordinal */ -DWORD WINAPI ILGetSize(LPCITEMIDLIST pidl) +UINT WINAPI ILGetSize(LPCITEMIDLIST pidl) { LPCSHITEMID si = &(pidl->mkid); - DWORD len=0; + UINT len=0; if (pidl) { while (si->cb) @@ -777,7 +777,7 @@ DWORD WINAPI ILGetSize(LPCITEMIDLIST pidl) } len += 2; } - TRACE("pidl=%p size=%lu\n",pidl, len); + TRACE("pidl=%p size=%u\n",pidl, len); return len; } @@ -872,13 +872,10 @@ LPITEMIDLIST WINAPI ILAppend(LPITEMIDLIST pidl, LPCITEMIDLIST item, BOOL bEnd) * NOTES * exported by ordinal */ -DWORD WINAPI ILFree(LPITEMIDLIST pidl) +void WINAPI ILFree(LPITEMIDLIST pidl) { - TRACE("(pidl=0x%08lx)\n",(DWORD)pidl); - - if(!pidl) return FALSE; - SHFree(pidl); - return TRUE; + TRACE("(pidl=%p)\n",pidl); + if(pidl) SHFree(pidl); } /************************************************************************* diff --git a/dlls/shell32/undocshell.h b/dlls/shell32/undocshell.h index 4abd2ebe9bd..1ac6a7a890d 100644 --- a/dlls/shell32/undocshell.h +++ b/dlls/shell32/undocshell.h @@ -34,37 +34,6 @@ extern "C" { /**************************************************************************** * IDList Functions */ -LPITEMIDLIST WINAPI ILClone (LPCITEMIDLIST pidl); -LPITEMIDLIST WINAPI ILCloneFirst(LPCITEMIDLIST pidl); - -LPITEMIDLIST WINAPI ILCombine( - LPCITEMIDLIST iil1, - LPCITEMIDLIST iil2); - -DWORD WINAPI ILGetSize(LPCITEMIDLIST pidl); - -LPITEMIDLIST WINAPI ILGetNext(LPCITEMIDLIST pidl); -LPITEMIDLIST WINAPI ILFindLastID(LPCITEMIDLIST pidl); -BOOL WINAPI ILRemoveLastID(LPCITEMIDLIST pidl); - -LPITEMIDLIST WINAPI ILFindChild( - LPCITEMIDLIST pidl1, - LPCITEMIDLIST pidl2); - -LPITEMIDLIST WINAPI ILAppendID( - LPITEMIDLIST pidl, - LPCSHITEMID lpItemID, - BOOL bAddToEnd); - -BOOL WINAPI ILIsEqual( - LPCITEMIDLIST pidl1, - LPCITEMIDLIST pidl2); - -BOOL WINAPI ILIsParent( - LPCITEMIDLIST pidlParent, - LPCITEMIDLIST pidlChild, - BOOL bImmediate); - BOOL WINAPI ILGetDisplayName( LPCITEMIDLIST pidl, LPVOID path); @@ -80,8 +49,6 @@ BOOL WINAPI ILGetDisplayNameEx( LPVOID path, DWORD type); -DWORD WINAPI ILFree(LPITEMIDLIST pidl); - HRESULT WINAPI ILSaveToStream( LPSTREAM pstrm, LPCITEMIDLIST pidl); diff --git a/include/shlobj.h b/include/shlobj.h index 7f96b51673c..de5e3e5e3ad 100644 --- a/include/shlobj.h +++ b/include/shlobj.h @@ -937,6 +937,18 @@ struct IFileSystemBindDataVtbl { #endif /* __IFileSystemBindData_INTERFACE_DEFINED__ */ +LPITEMIDLIST WINAPI ILAppendID(LPITEMIDLIST,LPCSHITEMID,BOOL); +LPITEMIDLIST WINAPI ILClone(LPCITEMIDLIST); +LPITEMIDLIST WINAPI ILCloneFirst(LPCITEMIDLIST); +LPITEMIDLIST WINAPI ILCombine(LPCITEMIDLIST,LPCITEMIDLIST); +LPITEMIDLIST WINAPI ILFindChild(LPCITEMIDLIST,LPCITEMIDLIST); +LPITEMIDLIST WINAPI ILFindLastID(LPCITEMIDLIST); +void WINAPI ILFree(LPITEMIDLIST); +LPITEMIDLIST WINAPI ILGetNext(LPCITEMIDLIST); +UINT WINAPI ILGetSize(LPCITEMIDLIST); +BOOL WINAPI ILIsEqual(LPCITEMIDLIST,LPCITEMIDLIST); +BOOL WINAPI ILIsParent(LPCITEMIDLIST,LPCITEMIDLIST,BOOL); +BOOL WINAPI ILRemoveLastID(LPCITEMIDLIST); #ifdef __cplusplus } /* extern "C" */ diff --git a/programs/winefile/winefile.c b/programs/winefile/winefile.c index b3ed774b420..4e775dbab81 100644 --- a/programs/winefile/winefile.c +++ b/programs/winefile/winefile.c @@ -170,6 +170,7 @@ typedef struct { static void read_directory(Entry* dir, LPCTSTR path, SORT_ORDER sortOrder, HWND hwnd); static void set_curdir(ChildWnd* child, Entry* entry, HWND hwnd); +static void get_path(Entry* dir, PTSTR path); LRESULT CALLBACK FrameWndProc(HWND hwnd, UINT nmsg, WPARAM wparam, LPARAM lparam); LRESULT CALLBACK ChildWndProc(HWND hwnd, UINT nmsg, WPARAM wparam, LPARAM lparam); @@ -705,9 +706,16 @@ static LPITEMIDLIST get_to_absolute_pidl(Entry* entry, HWND hwnd) if (SUCCEEDED(hr)) return pidl; } - } + } else if (entry->etype == ET_WINDOWS) { + TCHAR path[MAX_PATH]; - return entry->pidl; + get_path(entry, path); + + return get_path_pidl(path, hwnd); + } else if (entry->pidl) + return ILClone(entry->pidl); + + return NULL; } @@ -3188,6 +3196,47 @@ static BOOL pane_command(Pane* pane, UINT cmd) } +static HRESULT ShellFolderContextMenu(IShellFolder* shell_folder, HWND hwndParent, int cidl, LPCITEMIDLIST* apidl, int x, int y) +{ + IContextMenu* pcm; + + HRESULT hr = (*shell_folder->lpVtbl->GetUIObjectOf)(shell_folder, hwndParent, cidl, apidl, &IID_IContextMenu, NULL, (LPVOID*)&pcm); +/* HRESULT hr = CDefFolderMenu_Create2(dir?dir->_pidl:DesktopFolder(), hwndParent, 1, &pidl, shell_folder, NULL, 0, NULL, &pcm); */ + + if (SUCCEEDED(hr)) { + HMENU hmenu = CreatePopupMenu(); + + if (hmenu) { + hr = (*pcm->lpVtbl->QueryContextMenu)(pcm, hmenu, 0, FCIDM_SHVIEWFIRST, FCIDM_SHVIEWLAST, CMF_NORMAL); + + if (SUCCEEDED(hr)) { + UINT idCmd = TrackPopupMenu(hmenu, TPM_LEFTALIGN|TPM_RETURNCMD|TPM_RIGHTBUTTON, x, y, 0, hwndParent, NULL); + + if (idCmd) { + CMINVOKECOMMANDINFO cmi; + + cmi.cbSize = sizeof(CMINVOKECOMMANDINFO); + cmi.fMask = 0; + cmi.hwnd = hwndParent; + cmi.lpVerb = (LPCSTR)(INT_PTR)(idCmd - FCIDM_SHVIEWFIRST); + cmi.lpParameters = NULL; + cmi.lpDirectory = NULL; + cmi.nShow = SW_SHOWNORMAL; + cmi.dwHotKey = 0; + cmi.hIcon = 0; + + hr = (*pcm->lpVtbl->InvokeCommand)(pcm, &cmi); + } + } + } + + (*pcm->lpVtbl->Release)(pcm); + } + + return hr; +} + + LRESULT CALLBACK ChildWndProc(HWND hwnd, UINT nmsg, WPARAM wparam, LPARAM lparam) { static int last_split; @@ -3406,6 +3455,46 @@ LRESULT CALLBACK ChildWndProc(HWND hwnd, UINT nmsg, WPARAM wparam, LPARAM lparam return pane_notify(pnmh->idFrom==IDW_HEADER_LEFT? &child->left: &child->right, pnmh);} #endif +#ifdef _SHELL_FOLDERS + case WM_CONTEXTMENU: { + Pane* pane; + int idx; + + /* first select the current item in the listbox */ + HWND hpanel = (HWND) wparam; + POINTS* ppos = &MAKEPOINTS(lparam); + POINT pt; POINTSTOPOINT(pt, *ppos); + ScreenToClient(hpanel, &pt); + SendMessage(hpanel, WM_LBUTTONDOWN, 0, MAKELONG(pt.x, pt.y)); + SendMessage(hpanel, WM_LBUTTONUP, 0, MAKELONG(pt.x, pt.y)); + + /* now create the popup menu using shell namespace and IContextMenu */ + pane = GetFocus()==child->left.hwnd? &child->left: &child->right; + idx = ListBox_GetCurSel(pane->hwnd); + + if (idx != -1) { + HRESULT hr; + Entry* entry = (Entry*) ListBox_GetItemData(pane->hwnd, idx); + + LPITEMIDLIST pidl_abs = get_to_absolute_pidl(entry, hwnd); + + if (pidl_abs) { + IShellFolder* parentFolder; + LPCITEMIDLIST pidlLast; + + /* get and use the parent folder to display correct context menu in all cases */ + if (SUCCEEDED(SHBindToParent(pidl_abs, &IID_IShellFolder, (LPVOID*)&parentFolder, &pidlLast))) { + hr = ShellFolderContextMenu(parentFolder, hwnd, 1, &pidlLast, ppos->x, ppos->y); + + (*parentFolder->lpVtbl->Release)(parentFolder); + } + + (*Globals.iMalloc->lpVtbl->Free)(Globals.iMalloc, pidl_abs); + } + } + break;} +#endif + case WM_SIZE: if (wparam != SIZE_MINIMIZED) resize_tree(child, LOWORD(lparam), HIWORD(lparam));