explorer: Add dropdown entries to explorer's combobox.
This commit is contained in:
parent
cfa89e7e32
commit
c1b6d91c5b
|
@ -62,6 +62,7 @@ typedef struct
|
||||||
HWND main_window,path_box;
|
HWND main_window,path_box;
|
||||||
INT rebar_height;
|
INT rebar_height;
|
||||||
LPCITEMIDLIST pidl;
|
LPCITEMIDLIST pidl;
|
||||||
|
IImageList *icon_list;
|
||||||
} explorer_info;
|
} explorer_info;
|
||||||
|
|
||||||
enum
|
enum
|
||||||
|
@ -101,11 +102,153 @@ static ULONG WINAPI IExplorerBrowserEventsImpl_fnRelease(IExplorerBrowserEvents
|
||||||
return ref;
|
return ref;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static BOOL create_combobox_item(IShellFolder *folder, LPCITEMIDLIST pidl, IImageList *icon_list, COMBOBOXEXITEMW *item)
|
||||||
|
{
|
||||||
|
STRRET strret;
|
||||||
|
HRESULT hres;
|
||||||
|
IExtractIconW *extract_icon;
|
||||||
|
UINT reserved;
|
||||||
|
WCHAR icon_file[MAX_PATH];
|
||||||
|
INT icon_index;
|
||||||
|
UINT icon_flags;
|
||||||
|
HICON icon;
|
||||||
|
strret.uType=STRRET_WSTR;
|
||||||
|
hres = IShellFolder_GetDisplayNameOf(folder,pidl,SHGDN_FORADDRESSBAR,&strret);
|
||||||
|
if(FAILED(hres))
|
||||||
|
{
|
||||||
|
WINE_WARN("Could not get name for pidl\n");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
switch(strret.uType)
|
||||||
|
{
|
||||||
|
case STRRET_WSTR:
|
||||||
|
item->pszText = strret.pOleStr;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
WINE_FIXME("Unimplemented STRRET type:%u\n",strret.uType);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
hres = IShellFolder_GetUIObjectOf(folder,NULL,1,&pidl,&IID_IExtractIconW,
|
||||||
|
&reserved,(void**)&extract_icon);
|
||||||
|
if(SUCCEEDED(hres))
|
||||||
|
{
|
||||||
|
item->mask |= CBEIF_IMAGE;
|
||||||
|
IExtractIconW_GetIconLocation(extract_icon,GIL_FORSHELL,icon_file,
|
||||||
|
sizeof(icon_file)/sizeof(WCHAR),
|
||||||
|
&icon_index,&icon_flags);
|
||||||
|
IExtractIconW_Extract(extract_icon,icon_file,icon_index,NULL,&icon,20);
|
||||||
|
item->iImage = ImageList_AddIcon((HIMAGELIST)icon_list,icon);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
item->mask &= ~CBEIF_IMAGE;
|
||||||
|
WINE_WARN("Could not get an icon for %s\n",wine_dbgstr_w(item->pszText));
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
static void update_path_box(explorer_info *info)
|
static void update_path_box(explorer_info *info)
|
||||||
{
|
{
|
||||||
WCHAR path[MAX_PATH];
|
COMBOBOXEXITEMW item;
|
||||||
SHGetPathFromIDListW(info->pidl,path);
|
COMBOBOXEXITEMW main_item;
|
||||||
SetWindowTextW(info->path_box,path);
|
IShellFolder *desktop;
|
||||||
|
IPersistFolder2 *persist;
|
||||||
|
LPITEMIDLIST desktop_pidl;
|
||||||
|
IEnumIDList *ids;
|
||||||
|
|
||||||
|
ImageList_Remove((HIMAGELIST)info->icon_list,-1);
|
||||||
|
SendMessageW(info->path_box,CB_RESETCONTENT,0,0);
|
||||||
|
SHGetDesktopFolder(&desktop);
|
||||||
|
IShellFolder_QueryInterface(desktop,&IID_IPersistFolder2,(void**)&persist);
|
||||||
|
IPersistFolder2_GetCurFolder(persist,&desktop_pidl);
|
||||||
|
IPersistFolder2_Release(persist);
|
||||||
|
persist = NULL;
|
||||||
|
/*Add Desktop*/
|
||||||
|
item.iItem = -1;
|
||||||
|
item.mask = CBEIF_TEXT | CBEIF_INDENT | CBEIF_LPARAM;
|
||||||
|
item.iIndent = 0;
|
||||||
|
create_combobox_item(desktop,desktop_pidl,info->icon_list,&item);
|
||||||
|
item.lParam = (LPARAM)desktop_pidl;
|
||||||
|
SendMessageW(info->path_box,CBEM_INSERTITEMW,0,(LPARAM)&item);
|
||||||
|
if(ILIsEqual(info->pidl,desktop_pidl))
|
||||||
|
main_item = item;
|
||||||
|
else
|
||||||
|
CoTaskMemFree(item.pszText);
|
||||||
|
/*Add all direct subfolders of Desktop*/
|
||||||
|
if(SUCCEEDED(IShellFolder_EnumObjects(desktop,NULL,SHCONTF_FOLDERS,&ids))
|
||||||
|
&& ids!=NULL)
|
||||||
|
{
|
||||||
|
LPITEMIDLIST curr_pidl;
|
||||||
|
HRESULT hres;
|
||||||
|
|
||||||
|
item.iIndent = 1;
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
hres = IEnumIDList_Next(ids,1,&curr_pidl,NULL);
|
||||||
|
if(FAILED(hres) || hres == S_FALSE)
|
||||||
|
break;
|
||||||
|
if(!create_combobox_item(desktop,curr_pidl,info->icon_list,&item))
|
||||||
|
WINE_WARN("Could not create a combobox item\n");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LPITEMIDLIST full_pidl = ILCombine(desktop_pidl,curr_pidl);
|
||||||
|
item.lParam = (LPARAM)full_pidl;
|
||||||
|
SendMessageW(info->path_box,CBEM_INSERTITEMW,0,(LPARAM)&item);
|
||||||
|
if(ILIsEqual(full_pidl,info->pidl))
|
||||||
|
main_item = item;
|
||||||
|
else if(ILIsParent(full_pidl,info->pidl,FALSE))
|
||||||
|
{
|
||||||
|
/*add all parents of the pidl passed in*/
|
||||||
|
LPITEMIDLIST next_pidl = ILFindChild(full_pidl,info->pidl);
|
||||||
|
IShellFolder *curr_folder = NULL, *temp;
|
||||||
|
hres = IShellFolder_BindToObject(desktop,curr_pidl,NULL,
|
||||||
|
&IID_IShellFolder,
|
||||||
|
(void**)&curr_folder);
|
||||||
|
if(FAILED(hres))
|
||||||
|
WINE_WARN("Could not get an IShellFolder\n");
|
||||||
|
while(!ILIsEmpty(next_pidl))
|
||||||
|
{
|
||||||
|
LPITEMIDLIST first = ILCloneFirst(next_pidl);
|
||||||
|
CoTaskMemFree(item.pszText);
|
||||||
|
if(!create_combobox_item(curr_folder,first,
|
||||||
|
info->icon_list,&item))
|
||||||
|
{
|
||||||
|
WINE_WARN("Could not create a combobox item\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
++item.iIndent;
|
||||||
|
full_pidl = ILCombine(full_pidl,first);
|
||||||
|
item.lParam = (LPARAM)full_pidl;
|
||||||
|
SendMessageW(info->path_box,CBEM_INSERTITEMW,0,(LPARAM)&item);
|
||||||
|
temp=NULL;
|
||||||
|
hres = IShellFolder_BindToObject(curr_folder,first,NULL,
|
||||||
|
&IID_IShellFolder,
|
||||||
|
(void**)&temp);
|
||||||
|
if(FAILED(hres))
|
||||||
|
{
|
||||||
|
WINE_WARN("Could not get an IShellFolder\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
IShellFolder_Release(curr_folder);
|
||||||
|
curr_folder = temp;
|
||||||
|
|
||||||
|
ILFree(first);
|
||||||
|
next_pidl = ILGetNext(next_pidl);
|
||||||
|
}
|
||||||
|
memcpy(&main_item,&item,sizeof(item));
|
||||||
|
if(curr_folder)
|
||||||
|
IShellFolder_Release(curr_folder);
|
||||||
|
item.iIndent = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
CoTaskMemFree(item.pszText);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
WINE_WARN("Could not enumerate the desktop\n");
|
||||||
|
SendMessageW(info->path_box,CBEM_SETITEMW,0,(LPARAM)&main_item);
|
||||||
|
CoTaskMemFree(main_item.pszText);
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI IExplorerBrowserEventsImpl_fnOnNavigationComplete(IExplorerBrowserEvents *iface, PCIDLIST_ABSOLUTE pidl)
|
static HRESULT WINAPI IExplorerBrowserEventsImpl_fnOnNavigationComplete(IExplorerBrowserEvents *iface, PCIDLIST_ABSOLUTE pidl)
|
||||||
|
@ -148,6 +291,8 @@ static IExplorerBrowserEvents *make_explorer_events(explorer_info *info)
|
||||||
= HeapAlloc(GetProcessHeap(), 0, sizeof(IExplorerBrowserEventsImpl));
|
= HeapAlloc(GetProcessHeap(), 0, sizeof(IExplorerBrowserEventsImpl));
|
||||||
ret->IExplorerBrowserEvents_iface.lpVtbl = &vt_IExplorerBrowserEvents;
|
ret->IExplorerBrowserEvents_iface.lpVtbl = &vt_IExplorerBrowserEvents;
|
||||||
ret->info = info;
|
ret->info = info;
|
||||||
|
SHGetImageList(SHIL_SMALL,&IID_IImageList,(void**)&(ret->info->icon_list));
|
||||||
|
SendMessageW(info->path_box,CBEM_SETIMAGELIST,0,(LPARAM)ret->info->icon_list);
|
||||||
IExplorerBrowserEvents_AddRef(&ret->IExplorerBrowserEvents_iface);
|
IExplorerBrowserEvents_AddRef(&ret->IExplorerBrowserEvents_iface);
|
||||||
return &ret->IExplorerBrowserEvents_iface;
|
return &ret->IExplorerBrowserEvents_iface;
|
||||||
}
|
}
|
||||||
|
@ -287,6 +432,12 @@ static LRESULT explorer_on_end_edit(explorer_info *info,NMCBEENDEDITW *edit_info
|
||||||
WINE_TRACE("iWhy=%x\n",edit_info->iWhy);
|
WINE_TRACE("iWhy=%x\n",edit_info->iWhy);
|
||||||
switch(edit_info->iWhy)
|
switch(edit_info->iWhy)
|
||||||
{
|
{
|
||||||
|
case CBENF_DROPDOWN:
|
||||||
|
if(edit_info->iNewSelection!=CB_ERR)
|
||||||
|
pidl = (LPITEMIDLIST)SendMessageW(edit_info->hdr.hwndFrom,
|
||||||
|
CB_GETITEMDATA,
|
||||||
|
edit_info->iNewSelection,0);
|
||||||
|
break;
|
||||||
case CBENF_RETURN:
|
case CBENF_RETURN:
|
||||||
{
|
{
|
||||||
WCHAR path[MAX_PATH];
|
WCHAR path[MAX_PATH];
|
||||||
|
@ -330,8 +481,36 @@ static LRESULT explorer_on_notify(explorer_info* info,NMHDR* notification)
|
||||||
WINE_TRACE("code=%i\n",notification->code);
|
WINE_TRACE("code=%i\n",notification->code);
|
||||||
switch(notification->code)
|
switch(notification->code)
|
||||||
{
|
{
|
||||||
|
case CBEN_BEGINEDIT:
|
||||||
|
{
|
||||||
|
WCHAR path[MAX_PATH];
|
||||||
|
HWND edit_ctrl = (HWND)SendMessageW(notification->hwndFrom,
|
||||||
|
CBEM_GETEDITCONTROL,0,0);
|
||||||
|
SHGetPathFromIDListW(info->pidl,path);
|
||||||
|
SetWindowTextW(edit_ctrl,path);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CBEN_ENDEDITA:
|
||||||
|
{
|
||||||
|
NMCBEENDEDITA *edit_info_a = (NMCBEENDEDITA*)notification;
|
||||||
|
NMCBEENDEDITW edit_info_w;
|
||||||
|
edit_info_w.hdr = edit_info_a->hdr;
|
||||||
|
edit_info_w.fChanged = edit_info_a->fChanged;
|
||||||
|
edit_info_w.iNewSelection = edit_info_a->iNewSelection;
|
||||||
|
MultiByteToWideChar(CP_ACP,0,edit_info_a->szText,-1,
|
||||||
|
edit_info_w.szText,CBEMAXSTRLEN);
|
||||||
|
edit_info_w.iWhy = edit_info_a->iWhy;
|
||||||
|
return explorer_on_end_edit(info,&edit_info_w);
|
||||||
|
}
|
||||||
case CBEN_ENDEDITW:
|
case CBEN_ENDEDITW:
|
||||||
return explorer_on_end_edit(info,(NMCBEENDEDITW*)notification);
|
return explorer_on_end_edit(info,(NMCBEENDEDITW*)notification);
|
||||||
|
case CBEN_DELETEITEM:
|
||||||
|
{
|
||||||
|
NMCOMBOBOXEXW *entry = (NMCOMBOBOXEXW*)notification;
|
||||||
|
if(entry->ceItem.lParam)
|
||||||
|
ILFree((LPITEMIDLIST)entry->ceItem.lParam);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case RBN_AUTOSIZE:
|
case RBN_AUTOSIZE:
|
||||||
return update_rebar_size(info,(NMRBAUTOSIZE*)notification);
|
return update_rebar_size(info,(NMRBAUTOSIZE*)notification);
|
||||||
default:
|
default:
|
||||||
|
|
Loading…
Reference in New Issue