- implemented sorting the listview by clicking on the column header
[wine/gsoc_dplay.git] / dlls / shell32 / shlview.c
blobe8802dcbf9552d42f1bed5fd3bbb14d3b955ab02
1 /*
2 * ShellView
4 * Copyright 1998,1999 <juergen.schmied@metronet.de>
6 * FIXME: when the ShellView_WndProc gets a WM_NCDESTROY should we do a
7 * Release() ???
9 */
11 #include <stdlib.h>
12 #include <string.h>
14 #include "servprov.h"
15 #include "wine/obj_base.h"
16 #include "wine/obj_shellfolder.h"
17 #include "wine/obj_shellview.h"
18 #include "wine/obj_oleview.h"
19 #include "wine/obj_commdlgbrowser.h"
20 #include "wine/obj_shellbrowser.h"
21 #include "wine/obj_dockingwindowframe.h"
22 #include "wine/obj_extracticon.h"
23 #include "wine/obj_dragdrop.h"
24 #include "wine/undocshell.h"
25 #include "shresdef.h"
26 #include "spy.h"
27 #include "debugtools.h"
28 #include "winerror.h"
30 #include "docobj.h"
31 #include "pidl.h"
32 #include "shell32_main.h"
34 DEFAULT_DEBUG_CHANNEL(shell)
36 typedef struct
37 { ICOM_VTABLE(IShellView)* lpvtbl;
38 DWORD ref;
39 ICOM_VTABLE(IOleCommandTarget)* lpvtblOleCommandTarget;
40 ICOM_VTABLE(IDropTarget)* lpvtblDropTarget;
41 ICOM_VTABLE(IDropSource)* lpvtblDropSource;
42 ICOM_VTABLE(IViewObject)* lpvtblViewObject;
43 IShellFolder* pSFParent;
44 IShellBrowser* pShellBrowser;
45 ICommDlgBrowser* pCommDlgBrowser;
46 HWND hWnd;
47 HWND hWndList;
48 HWND hWndParent;
49 FOLDERSETTINGS FolderSettings;
50 HMENU hMenu;
51 UINT uState;
52 UINT cidl;
53 LPITEMIDLIST *apidl;
54 } IShellViewImpl;
56 static struct ICOM_VTABLE(IShellView) svvt;
58 static struct ICOM_VTABLE(IOleCommandTarget) ctvt;
59 #define _IOleCommandTarget_Offset ((int)(&(((IShellViewImpl*)0)->lpvtblOleCommandTarget)))
60 #define _ICOM_THIS_From_IOleCommandTarget(class, name) class* This = (class*)(((char*)name)-_IOleCommandTarget_Offset);
62 static struct ICOM_VTABLE(IDropTarget) dtvt;
63 #define _IDropTarget_Offset ((int)(&(((IShellViewImpl*)0)->lpvtblDropTarget)))
64 #define _ICOM_THIS_From_IDropTarget(class, name) class* This = (class*)(((char*)name)-_IDropTarget_Offset);
66 static struct ICOM_VTABLE(IDropSource) dsvt;
67 #define _IDropSource_Offset ((int)(&(((IShellViewImpl*)0)->lpvtblDropSource)))
68 #define _ICOM_THIS_From_IDropSource(class, name) class* This = (class*)(((char*)name)-_IDropSource_Offset);
70 static struct ICOM_VTABLE(IViewObject) vovt;
71 #define _IViewObject_Offset ((int)(&(((IShellViewImpl*)0)->lpvtblViewObject)))
72 #define _ICOM_THIS_From_IViewObject(class, name) class* This = (class*)(((char*)name)-_IViewObject_Offset);
74 /* ListView Header ID's */
75 #define LISTVIEW_COLUMN_NAME 0
76 #define LISTVIEW_COLUMN_SIZE 1
77 #define LISTVIEW_COLUMN_TYPE 2
78 #define LISTVIEW_COLUMN_TIME 3
79 #define LISTVIEW_COLUMN_ATTRIB 4
81 /*menu items */
82 #define IDM_VIEW_FILES (FCIDM_SHVIEWFIRST + 0x500)
83 #define IDM_VIEW_IDW (FCIDM_SHVIEWFIRST + 0x501)
84 #define IDM_MYFILEITEM (FCIDM_SHVIEWFIRST + 0x502)
86 #define ID_LISTVIEW 2000
88 #define TOOLBAR_ID (L"SHELLDLL_DefView")
89 /*windowsx.h */
90 #define GET_WM_COMMAND_ID(wp, lp) LOWORD(wp)
91 #define GET_WM_COMMAND_HWND(wp, lp) (HWND)(lp)
92 #define GET_WM_COMMAND_CMD(wp, lp) HIWORD(wp)
93 /* winuser.h */
94 #define WM_SETTINGCHANGE WM_WININICHANGE
95 extern void WINAPI _InsertMenuItem (HMENU hmenu, UINT indexMenu, BOOL fByPosition,
96 UINT wID, UINT fType, LPSTR dwTypeData, UINT fState);
99 Items merged into the toolbar and and the filemenu
101 typedef struct
102 { int idCommand;
103 int iImage;
104 int idButtonString;
105 int idMenuString;
106 BYTE bState;
107 BYTE bStyle;
108 } MYTOOLINFO, *LPMYTOOLINFO;
110 MYTOOLINFO Tools[] =
112 { FCIDM_SHVIEW_BIGICON, 0, 0, IDS_VIEW_LARGE, TBSTATE_ENABLED, TBSTYLE_BUTTON },
113 { FCIDM_SHVIEW_SMALLICON, 0, 0, IDS_VIEW_SMALL, TBSTATE_ENABLED, TBSTYLE_BUTTON },
114 { FCIDM_SHVIEW_LISTVIEW, 0, 0, IDS_VIEW_LIST, TBSTATE_ENABLED, TBSTYLE_BUTTON },
115 { FCIDM_SHVIEW_REPORTVIEW, 0, 0, IDS_VIEW_DETAILS, TBSTATE_ENABLED, TBSTYLE_BUTTON },
116 { -1, 0, 0, 0, 0, 0}
119 typedef void (CALLBACK *PFNSHGETSETTINGSPROC)(LPSHELLFLAGSTATE lpsfs, DWORD dwMask);
121 /**********************************************************
122 * IShellView_Constructor
124 IShellView * IShellView_Constructor( IShellFolder * pFolder)
125 { IShellViewImpl * sv;
126 sv=(IShellViewImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IShellViewImpl));
127 sv->ref=1;
128 sv->lpvtbl=&svvt;
129 sv->lpvtblOleCommandTarget=&ctvt;
130 sv->lpvtblDropTarget=&dtvt;
131 sv->lpvtblDropSource=&dsvt;
132 sv->lpvtblViewObject=&vovt;
134 sv->pSFParent = pFolder;
136 if(pFolder)
137 IShellFolder_AddRef(pFolder);
139 TRACE("(%p)->(%p)\n",sv, pFolder);
140 shell32_ObjCount++;
141 return (IShellView *) sv;
144 /**********************************************************
146 * ##### helperfunctions for communication with ICommDlgBrowser #####
148 static BOOL IsInCommDlg(IShellViewImpl * This)
149 { return(This->pCommDlgBrowser != NULL);
152 static HRESULT IncludeObject(IShellViewImpl * This, LPCITEMIDLIST pidl)
154 HRESULT ret = S_OK;
156 if ( IsInCommDlg(This) )
158 TRACE("ICommDlgBrowser::IncludeObject pidl=%p\n", pidl);
159 ret = ICommDlgBrowser_IncludeObject(This->pCommDlgBrowser, (IShellView*)This, pidl);
160 TRACE("--0x%08lx\n", ret);
162 return ret;
165 static HRESULT OnDefaultCommand(IShellViewImpl * This)
167 HRESULT ret = S_FALSE;
169 if (IsInCommDlg(This))
171 TRACE("ICommDlgBrowser::OnDefaultCommand\n");
172 ret = ICommDlgBrowser_OnDefaultCommand(This->pCommDlgBrowser, (IShellView*)This);
173 TRACE("--\n");
175 return ret;
178 static HRESULT OnStateChange(IShellViewImpl * This, UINT uFlags)
180 HRESULT ret = S_FALSE;
182 if (IsInCommDlg(This))
184 TRACE("ICommDlgBrowser::OnStateChange flags=%x\n", uFlags);
185 ret = ICommDlgBrowser_OnStateChange(This->pCommDlgBrowser, (IShellView*)This, uFlags);
186 TRACE("--\n");
188 return ret;
190 /**********************************************************
192 * ##### helperfunctions for initializing the view #####
194 /**********************************************************
195 * set the toolbar buttons
197 static void CheckToolbar(IShellViewImpl * This)
199 LRESULT result;
201 TRACE("\n");
203 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_TOOLBAR, TB_CHECKBUTTON,
204 FCIDM_TB_SMALLICON, (This->FolderSettings.ViewMode==FVM_LIST)? TRUE : FALSE, &result);
205 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_TOOLBAR, TB_CHECKBUTTON,
206 FCIDM_TB_REPORTVIEW, (This->FolderSettings.ViewMode==FVM_DETAILS)? TRUE : FALSE, &result);
207 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_TOOLBAR, TB_ENABLEBUTTON,
208 FCIDM_TB_SMALLICON, TRUE, &result);
209 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_TOOLBAR, TB_ENABLEBUTTON,
210 FCIDM_TB_REPORTVIEW, TRUE, &result);
213 /**********************************************************
214 * change the style of the listview control
217 static void SetStyle(IShellViewImpl * This, DWORD dwAdd, DWORD dwRemove)
219 DWORD tmpstyle;
221 TRACE("(%p)\n", This);
223 tmpstyle = GetWindowLongA(This->hWndList, GWL_STYLE);
224 SetWindowLongA(This->hWndList, GWL_STYLE, dwAdd | (tmpstyle & ~dwRemove));
227 /**********************************************************
228 * ShellView_CreateList()
231 static BOOL ShellView_CreateList (IShellViewImpl * This)
232 { DWORD dwStyle;
234 TRACE("%p\n",This);
236 dwStyle = WS_TABSTOP | WS_VISIBLE | WS_CHILD | WS_BORDER | WS_CHILDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN |
237 LVS_SHAREIMAGELISTS | LVS_EDITLABELS | LVS_ALIGNLEFT | LVS_AUTOARRANGE;
239 switch (This->FolderSettings.ViewMode)
241 case FVM_ICON: dwStyle |= LVS_ICON; break;
242 case FVM_DETAILS: dwStyle |= LVS_REPORT; break;
243 case FVM_SMALLICON: dwStyle |= LVS_SMALLICON; break;
244 case FVM_LIST: dwStyle |= LVS_LIST; break;
245 default: dwStyle |= LVS_LIST; break;
248 if (This->FolderSettings.fFlags && FWF_AUTOARRANGE) dwStyle |= LVS_AUTOARRANGE;
249 /*if (This->FolderSettings.fFlags && FWF_DESKTOP); used from explorer*/
250 if (This->FolderSettings.fFlags && FWF_SINGLESEL) dwStyle |= LVS_SINGLESEL;
252 This->hWndList=CreateWindowExA( WS_EX_CLIENTEDGE,
253 WC_LISTVIEWA,
254 NULL,
255 dwStyle,
256 0,0,0,0,
257 This->hWnd,
258 (HMENU)ID_LISTVIEW,
259 shell32_hInstance,
260 NULL);
262 if(!This->hWndList)
263 return FALSE;
265 /* UpdateShellSettings(); */
266 return TRUE;
268 /**********************************************************
269 * ShellView_InitList()
271 static BOOL ShellView_InitList(IShellViewImpl * This)
273 LVCOLUMNA lvColumn;
274 CHAR szString[50];
276 TRACE("%p\n",This);
278 ListView_DeleteAllItems(This->hWndList);
280 /*initialize the columns */
281 lvColumn.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT; /* | LVCF_SUBITEM;*/
282 lvColumn.fmt = LVCFMT_LEFT;
283 lvColumn.pszText = szString;
285 lvColumn.cx = 120;
286 LoadStringA(shell32_hInstance, IDS_SHV_COLUMN1, szString, sizeof(szString));
287 ListView_InsertColumnA(This->hWndList, 0, &lvColumn);
289 lvColumn.cx = 80;
290 LoadStringA(shell32_hInstance, IDS_SHV_COLUMN2, szString, sizeof(szString));
291 ListView_InsertColumnA(This->hWndList, 1, &lvColumn);
293 lvColumn.cx = 170;
294 LoadStringA(shell32_hInstance, IDS_SHV_COLUMN3, szString, sizeof(szString));
295 ListView_InsertColumnA(This->hWndList, 2, &lvColumn);
297 lvColumn.cx = 60;
298 LoadStringA(shell32_hInstance, IDS_SHV_COLUMN4, szString, sizeof(szString));
299 ListView_InsertColumnA(This->hWndList, 3, &lvColumn);
301 ListView_SetImageList(This->hWndList, ShellSmallIconList, LVSIL_SMALL);
302 ListView_SetImageList(This->hWndList, ShellBigIconList, LVSIL_NORMAL);
304 return TRUE;
306 /**********************************************************
307 * ShellView_CompareItems()
309 * NOTES
310 * internal, CALLBACK for DSA_Sort
312 static INT CALLBACK ShellView_CompareItems(LPVOID lParam1, LPVOID lParam2, LPARAM lpData)
314 int ret;
315 TRACE("pidl1=%p pidl2=%p lpsf=%p\n", lParam1, lParam2, (LPVOID) lpData);
317 if(!lpData) return 0;
319 ret = (SHORT) SCODE_CODE(IShellFolder_CompareIDs((LPSHELLFOLDER)lpData, 0, (LPITEMIDLIST)lParam1, (LPITEMIDLIST)lParam2));
320 TRACE("ret=%i\n",ret);
321 return ret;
325 /*************************************************************************
326 * ShellView_ListViewCompareItems
328 * Compare Function for the Listview (FileOpen Dialog)
330 * PARAMS
331 * lParam1 [I] the first ItemIdList to compare with
332 * lParam2 [I] the second ItemIdList to compare with
333 * lpData [I] The column ID for the header Ctrl to process
335 * RETURNS
336 * A negative value if the first item should precede the second,
337 * a positive value if the first item should follow the second,
338 * or zero if the two items are equivalent
340 * NOTES
343 static INT CALLBACK ShellView_ListViewCompareItems(LPVOID lParam1, LPVOID lParam2, LPARAM lpData)
345 INT nDiff=0;
346 FILETIME fd1, fd2;
347 char strName1[MAX_PATH], strName2[MAX_PATH];
348 BOOL bIsFolder1, bIsFolder2,bIsBothFolder;
349 LPITEMIDLIST pItemIdList1 = (LPITEMIDLIST) lParam1;
350 LPITEMIDLIST pItemIdList2 = (LPITEMIDLIST) lParam2;
353 bIsFolder1 = _ILIsFolder(pItemIdList1);
354 bIsFolder2 = _ILIsFolder(pItemIdList2);
355 bIsBothFolder = bIsFolder1 && bIsFolder2;
357 /* When sorting between a File and a Folder, the Folder gets sorted first */
358 if( (bIsFolder1 || bIsFolder2) && !bIsBothFolder)
360 nDiff = bIsFolder1 ? -1 : 1;
362 else
364 /* Sort by Time: Folders or Files can be sorted */
366 if(lpData == LISTVIEW_COLUMN_TIME)
368 _ILGetFileDateTime(pItemIdList1, &fd1);
369 _ILGetFileDateTime(pItemIdList2, &fd2);
370 nDiff = CompareFileTime(&fd2, &fd1);
372 /* Sort by Attribute: Folder or Files can be sorted */
373 else if(lpData == LISTVIEW_COLUMN_ATTRIB)
375 _ILGetAttributeStr(pItemIdList1, strName1, MAX_PATH);
376 _ILGetAttributeStr(pItemIdList2, strName2, MAX_PATH);
377 nDiff = strcasecmp(strName1, strName2);
379 /* Sort by FileName: Folder or Files can be sorted */
380 else if(lpData == LISTVIEW_COLUMN_NAME || bIsBothFolder)
382 /* Sort by Text */
383 _ILSimpleGetText(pItemIdList1, strName1, MAX_PATH);
384 _ILSimpleGetText(pItemIdList2, strName2, MAX_PATH);
385 nDiff = strcasecmp(strName1, strName2);
387 /* Sort by File Size, Only valid for Files */
388 else if(lpData == LISTVIEW_COLUMN_SIZE)
390 nDiff = _ILGetFileSize(pItemIdList1, NULL, 0) - _ILGetFileSize(pItemIdList2, NULL, 0);
392 /* Sort by File Type, Only valid for Files */
393 else if(lpData == LISTVIEW_COLUMN_TYPE)
395 /* Sort by Type */
396 _ILGetFileType(pItemIdList1, strName1, MAX_PATH);
397 _ILGetFileType(pItemIdList2, strName2, MAX_PATH);
398 nDiff = strcasecmp(strName1, strName2);
401 /* If the Date, FileSize, FileType, Attrib was the same, sort by FileName */
403 if(nDiff == 0)
405 _ILSimpleGetText(pItemIdList1, strName1, MAX_PATH);
406 _ILSimpleGetText(pItemIdList2, strName2, MAX_PATH);
407 nDiff = strcasecmp(strName1, strName2);
410 return nDiff;
414 /**********************************************************
415 * ShellView_FillList()
417 * NOTES
418 * internal
421 static HRESULT ShellView_FillList(IShellViewImpl * This)
423 LPENUMIDLIST pEnumIDList;
424 LPITEMIDLIST pidl;
425 DWORD dwFetched;
426 UINT i;
427 LVITEMA lvItem;
428 HRESULT hRes;
429 HDPA hdpa;
431 TRACE("%p\n",This);
433 /* get the itemlist from the shfolder*/
434 hRes = IShellFolder_EnumObjects(This->pSFParent,This->hWnd, SHCONTF_NONFOLDERS | SHCONTF_FOLDERS, &pEnumIDList);
435 if (hRes != S_OK)
437 if (hRes==S_FALSE)
438 return(NOERROR);
439 return(hRes);
442 /* create a pointer array */
443 hdpa = pDPA_Create(16);
444 if (!hdpa)
446 return(E_OUTOFMEMORY);
449 /* copy the items into the array*/
450 while((S_OK == IEnumIDList_Next(pEnumIDList,1, &pidl, &dwFetched)) && dwFetched)
452 if (pDPA_InsertPtr(hdpa, 0x7fff, pidl) == -1)
454 SHFree(pidl);
458 /*sort the array*/
459 pDPA_Sort(hdpa, ShellView_CompareItems, (LPARAM)This->pSFParent);
461 /*turn the listview's redrawing off*/
462 SendMessageA(This->hWndList, WM_SETREDRAW, FALSE, 0);
464 for (i=0; i < DPA_GetPtrCount(hdpa); ++i) /* DPA_GetPtrCount is a macro*/
466 pidl = (LPITEMIDLIST)DPA_GetPtr(hdpa, i);
467 if (IncludeObject(This, pidl) == S_OK) /* in a commdlg This works as a filemask*/
469 ZeroMemory(&lvItem, sizeof(lvItem)); /* create the listviewitem*/
470 lvItem.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM; /*set the mask*/
471 lvItem.iItem = ListView_GetItemCount(This->hWndList); /*add the item to the end of the list*/
472 lvItem.lParam = (LPARAM) pidl; /*set the item's data*/
473 lvItem.pszText = LPSTR_TEXTCALLBACKA; /*get text on a callback basis*/
474 lvItem.iImage = I_IMAGECALLBACK; /*get the image on a callback basis*/
475 ListView_InsertItemA(This->hWndList, &lvItem);
477 else
478 SHFree(pidl); /* the listview has the COPY*/
481 /*turn the listview's redrawing back on and force it to draw*/
482 SendMessageA(This->hWndList, WM_SETREDRAW, TRUE, 0);
483 InvalidateRect(This->hWndList, NULL, TRUE);
484 UpdateWindow(This->hWndList);
486 IEnumIDList_Release(pEnumIDList); /* destroy the list*/
487 pDPA_Destroy(hdpa);
489 return S_OK;
492 /**********************************************************
493 * ShellView_OnCreate()
495 static LRESULT ShellView_OnCreate(IShellViewImpl * This)
497 #if 0
498 IDropTarget* pdt;
499 #endif
500 TRACE("%p\n",This);
502 if(ShellView_CreateList(This))
504 if(ShellView_InitList(This))
506 ShellView_FillList(This);
510 #if 0
511 /* This makes a chrash since we havn't called OleInititialize. But if we
512 do this call in DllMain it breaks some apps. The native shell32 does not
513 call OleInitialize and not even depend on ole32.dll.
514 But for some apps it works...*/
515 if (SUCCEEDED(IShellFolder_CreateViewObject(This->pSFParent, This->hWnd, &IID_IDropTarget, (LPVOID*)&pdt)))
517 pRegisterDragDrop(This->hWnd, pdt);
518 IDropTarget_Release(pdt);
520 #endif
521 return S_OK;
524 /**********************************************************
525 * #### Handling of the menus ####
528 /**********************************************************
529 * ShellView_BuildFileMenu()
531 static HMENU ShellView_BuildFileMenu(IShellViewImpl * This)
532 { CHAR szText[MAX_PATH];
533 MENUITEMINFOA mii;
534 int nTools,i;
535 HMENU hSubMenu;
537 TRACE("(%p)\n",This);
539 hSubMenu = CreatePopupMenu();
540 if(hSubMenu)
541 { /*get the number of items in our global array*/
542 for(nTools = 0; Tools[nTools].idCommand != -1; nTools++){}
544 /*add the menu items*/
545 for(i = 0; i < nTools; i++)
547 LoadStringA(shell32_hInstance, Tools[i].idMenuString, szText, MAX_PATH);
549 ZeroMemory(&mii, sizeof(mii));
550 mii.cbSize = sizeof(mii);
551 mii.fMask = MIIM_TYPE | MIIM_ID | MIIM_STATE;
553 if(TBSTYLE_SEP != Tools[i].bStyle) /* no seperator*/
555 mii.fType = MFT_STRING;
556 mii.fState = MFS_ENABLED;
557 mii.dwTypeData = szText;
558 mii.wID = Tools[i].idCommand;
560 else
562 mii.fType = MFT_SEPARATOR;
564 /* tack This item onto the end of the menu */
565 InsertMenuItemA(hSubMenu, (UINT)-1, TRUE, &mii);
568 TRACE("-- return (menu=0x%x)\n",hSubMenu);
569 return hSubMenu;
571 /**********************************************************
572 * ShellView_MergeFileMenu()
574 static void ShellView_MergeFileMenu(IShellViewImpl * This, HMENU hSubMenu)
575 { TRACE("(%p)->(submenu=0x%08x) stub\n",This,hSubMenu);
577 if(hSubMenu)
578 { /*insert This item at the beginning of the menu */
579 _InsertMenuItem(hSubMenu, 0, TRUE, 0, MFT_SEPARATOR, NULL, MFS_ENABLED);
580 _InsertMenuItem(hSubMenu, 0, TRUE, IDM_MYFILEITEM, MFT_STRING, "dummy45", MFS_ENABLED);
583 TRACE("--\n");
586 /**********************************************************
587 * ShellView_MergeViewMenu()
590 static void ShellView_MergeViewMenu(IShellViewImpl * This, HMENU hSubMenu)
591 { MENUITEMINFOA mii;
593 TRACE("(%p)->(submenu=0x%08x)\n",This,hSubMenu);
595 if(hSubMenu)
596 { /*add a separator at the correct position in the menu*/
597 _InsertMenuItem(hSubMenu, FCIDM_MENU_VIEW_SEP_OPTIONS, FALSE, 0, MFT_SEPARATOR, NULL, MFS_ENABLED);
599 ZeroMemory(&mii, sizeof(mii));
600 mii.cbSize = sizeof(mii);
601 mii.fMask = MIIM_SUBMENU | MIIM_TYPE | MIIM_DATA;;
602 mii.fType = MFT_STRING;
603 mii.dwTypeData = "View";
604 mii.hSubMenu = LoadMenuA(shell32_hInstance, "MENU_001");
605 InsertMenuItemA(hSubMenu, FCIDM_MENU_VIEW_SEP_OPTIONS, FALSE, &mii);
609 /**********************************************************
610 * ShellView_GetSelections()
612 * RETURNS
613 * number of selected items
615 static UINT ShellView_GetSelections(IShellViewImpl * This)
617 LVITEMA lvItem;
618 UINT i = 0;
620 if (This->apidl)
622 SHFree(This->apidl);
625 This->cidl = ListView_GetSelectedCount(This->hWndList);
626 This->apidl = (LPITEMIDLIST*)SHAlloc(This->cidl * sizeof(LPITEMIDLIST));
628 TRACE("selected=%i\n", This->cidl);
630 if(This->apidl)
632 TRACE("-- Items selected =%u\n", This->cidl);
634 ZeroMemory(&lvItem, sizeof(lvItem));
635 lvItem.mask = LVIF_STATE | LVIF_PARAM;
636 lvItem.stateMask = LVIS_SELECTED;
638 while(ListView_GetItemA(This->hWndList, &lvItem) && (i < This->cidl))
640 if(lvItem.state & LVIS_SELECTED)
642 This->apidl[i] = (LPITEMIDLIST)lvItem.lParam;
643 i++;
644 TRACE("-- selected Item found\n");
646 lvItem.iItem++;
649 return This->cidl;
652 /**********************************************************
653 * ShellView_DoContextMenu()
655 static void ShellView_DoContextMenu(IShellViewImpl * This, WORD x, WORD y, BOOL bDefault)
656 { UINT uCommand;
657 DWORD wFlags;
658 HMENU hMenu;
659 BOOL fExplore = FALSE;
660 HWND hwndTree = 0;
661 LPCONTEXTMENU pContextMenu = NULL;
662 IContextMenu * pCM = NULL;
663 CMINVOKECOMMANDINFO cmi;
665 TRACE("(%p)->(0x%08x 0x%08x 0x%08x) stub\n",This, x, y, bDefault);
667 /* look, what's selected and create a context menu object of it*/
668 if( ShellView_GetSelections(This) )
670 IShellFolder_GetUIObjectOf( This->pSFParent, This->hWndParent, This->cidl, This->apidl,
671 (REFIID)&IID_IContextMenu, NULL, (LPVOID *)&pContextMenu);
673 if(pContextMenu)
675 TRACE("-- pContextMenu\n");
676 hMenu = CreatePopupMenu();
678 if( hMenu )
680 /* See if we are in Explore or Open mode. If the browser's tree is present, we are in Explore mode.*/
681 if(SUCCEEDED(IShellBrowser_GetControlWindow(This->pShellBrowser,FCW_TREE, &hwndTree)) && hwndTree)
683 TRACE("-- explore mode\n");
684 fExplore = TRUE;
687 /* build the flags depending on what we can do with the selected item */
688 wFlags = CMF_NORMAL | (This->cidl != 1 ? 0 : CMF_CANRENAME) | (fExplore ? CMF_EXPLORE : 0);
690 /* let the ContextMenu merge its items in */
691 if (SUCCEEDED(IContextMenu_QueryContextMenu( pContextMenu, hMenu, 0, FCIDM_SHVIEWFIRST, FCIDM_SHVIEWLAST, wFlags )))
693 if( bDefault )
695 TRACE("-- get menu default command\n");
696 uCommand = GetMenuDefaultItem(hMenu, FALSE, GMDI_GOINTOPOPUPS);
698 else
700 TRACE("-- track popup\n");
701 uCommand = TrackPopupMenu( hMenu,TPM_LEFTALIGN | TPM_RETURNCMD,x,y,0,This->hWnd,NULL);
704 if(uCommand > 0)
706 TRACE("-- uCommand=%u\n", uCommand);
707 if (IsInCommDlg(This) && ((uCommand==IDM_EXPLORE) || (uCommand==IDM_OPEN)))
709 TRACE("-- dlg: OnDefaultCommand\n");
710 OnDefaultCommand(This);
712 else
714 TRACE("-- explore -- invoke command\n");
715 ZeroMemory(&cmi, sizeof(cmi));
716 cmi.cbSize = sizeof(cmi);
717 cmi.hwnd = This->hWndParent;
718 cmi.lpVerb = (LPCSTR)MAKEINTRESOURCEA(uCommand);
719 IContextMenu_InvokeCommand(pContextMenu, &cmi);
722 DestroyMenu(hMenu);
725 if (pContextMenu)
726 IContextMenu_Release(pContextMenu);
729 else /* background context menu */
731 hMenu = CreatePopupMenu();
733 pCM = ISvBgCm_Constructor();
734 IContextMenu_QueryContextMenu(pCM, hMenu, 0, FCIDM_SHVIEWFIRST, FCIDM_SHVIEWLAST, 0);
736 uCommand = TrackPopupMenu( hMenu, TPM_LEFTALIGN | TPM_RETURNCMD,x,y,0,This->hWnd,NULL);
737 DestroyMenu(hMenu);
739 TRACE("-- (%p)->(uCommand=0x%08x )\n",This, uCommand);
741 ZeroMemory(&cmi, sizeof(cmi));
742 cmi.cbSize = sizeof(cmi);
743 cmi.lpVerb = (LPCSTR)MAKEINTRESOURCEA(uCommand);
744 cmi.hwnd = This->hWndParent;
745 IContextMenu_InvokeCommand(pCM, &cmi);
747 IContextMenu_Release(pCM);
751 /**********************************************************
752 * ##### message handling #####
755 /**********************************************************
756 * ShellView_OnSize()
758 static LRESULT ShellView_OnSize(IShellViewImpl * This, WORD wWidth, WORD wHeight)
760 TRACE("%p width=%u height=%u\n",This, wWidth,wHeight);
762 /*resize the ListView to fit our window*/
763 if(This->hWndList)
765 MoveWindow(This->hWndList, 0, 0, wWidth, wHeight, TRUE);
768 return S_OK;
770 /**********************************************************
771 * ShellView_OnDeactivate()
773 * NOTES
774 * internal
776 static void ShellView_OnDeactivate(IShellViewImpl * This)
778 TRACE("%p\n",This);
780 if(This->uState != SVUIA_DEACTIVATE)
782 if(This->hMenu)
784 IShellBrowser_SetMenuSB(This->pShellBrowser,0, 0, 0);
785 IShellBrowser_RemoveMenusSB(This->pShellBrowser,This->hMenu);
786 DestroyMenu(This->hMenu);
787 This->hMenu = 0;
790 This->uState = SVUIA_DEACTIVATE;
794 /**********************************************************
795 * ShellView_OnActivate()
797 static LRESULT ShellView_OnActivate(IShellViewImpl * This, UINT uState)
798 { OLEMENUGROUPWIDTHS omw = { {0, 0, 0, 0, 0, 0} };
799 MENUITEMINFOA mii;
800 CHAR szText[MAX_PATH];
802 TRACE("%p uState=%x\n",This,uState);
804 /*don't do anything if the state isn't really changing */
805 if(This->uState == uState)
807 return S_OK;
810 ShellView_OnDeactivate(This);
812 /*only do This if we are active */
813 if(uState != SVUIA_DEACTIVATE)
815 /*merge the menus */
816 This->hMenu = CreateMenu();
818 if(This->hMenu)
820 IShellBrowser_InsertMenusSB(This->pShellBrowser, This->hMenu, &omw);
821 TRACE("-- after fnInsertMenusSB\n");
823 /*build the top level menu get the menu item's text*/
824 strcpy(szText,"dummy 31");
826 ZeroMemory(&mii, sizeof(mii));
827 mii.cbSize = sizeof(mii);
828 mii.fMask = MIIM_SUBMENU | MIIM_TYPE | MIIM_STATE;
829 mii.fType = MFT_STRING;
830 mii.fState = MFS_ENABLED;
831 mii.dwTypeData = szText;
832 mii.hSubMenu = ShellView_BuildFileMenu(This);
834 /*insert our menu into the menu bar*/
835 if(mii.hSubMenu)
837 InsertMenuItemA(This->hMenu, FCIDM_MENU_HELP, FALSE, &mii);
840 /*get the view menu so we can merge with it*/
841 ZeroMemory(&mii, sizeof(mii));
842 mii.cbSize = sizeof(mii);
843 mii.fMask = MIIM_SUBMENU;
845 if(GetMenuItemInfoA(This->hMenu, FCIDM_MENU_VIEW, FALSE, &mii))
847 ShellView_MergeViewMenu(This, mii.hSubMenu);
850 /*add the items that should only be added if we have the focus*/
851 if(SVUIA_ACTIVATE_FOCUS == uState)
853 /*get the file menu so we can merge with it */
854 ZeroMemory(&mii, sizeof(mii));
855 mii.cbSize = sizeof(mii);
856 mii.fMask = MIIM_SUBMENU;
858 if(GetMenuItemInfoA(This->hMenu, FCIDM_MENU_FILE, FALSE, &mii))
860 ShellView_MergeFileMenu(This, mii.hSubMenu);
863 TRACE("-- before fnSetMenuSB\n");
864 IShellBrowser_SetMenuSB(This->pShellBrowser, This->hMenu, 0, This->hWnd);
867 This->uState = uState;
868 TRACE("--\n");
869 return S_OK;
872 /**********************************************************
873 * ShellView_OnSetFocus()
876 static LRESULT ShellView_OnSetFocus(IShellViewImpl * This)
878 TRACE("%p\n",This);
880 /* Tell the browser one of our windows has received the focus. This
881 should always be done before merging menus (OnActivate merges the
882 menus) if one of our windows has the focus.*/
884 IShellBrowser_OnViewWindowActive(This->pShellBrowser,(IShellView*) This);
885 ShellView_OnActivate(This, SVUIA_ACTIVATE_FOCUS);
887 /* Set the focus to the listview */
888 SetFocus(This->hWndList);
890 /* Notify the ICommDlgBrowser interface */
891 OnStateChange(This,CDBOSC_SETFOCUS);
893 return 0;
896 /**********************************************************
897 * ShellView_OnKillFocus()
899 static LRESULT ShellView_OnKillFocus(IShellViewImpl * This)
901 TRACE("(%p) stub\n",This);
903 ShellView_OnActivate(This, SVUIA_ACTIVATE_NOFOCUS);
904 /* Notify the ICommDlgBrowser */
905 OnStateChange(This,CDBOSC_KILLFOCUS);
907 return 0;
910 /**********************************************************
911 * ShellView_OnCommand()
913 * NOTES
914 * the CmdID's are the ones from the context menu
916 static LRESULT ShellView_OnCommand(IShellViewImpl * This,DWORD dwCmdID, DWORD dwCmd, HWND hwndCmd)
918 TRACE("(%p)->(0x%08lx 0x%08lx 0x%08x) stub\n",This, dwCmdID, dwCmd, hwndCmd);
920 switch(dwCmdID)
922 case FCIDM_SHVIEW_SMALLICON:
923 This->FolderSettings.ViewMode = FVM_SMALLICON;
924 SetStyle (This, LVS_SMALLICON, LVS_TYPEMASK);
925 break;
927 case FCIDM_SHVIEW_BIGICON:
928 This->FolderSettings.ViewMode = FVM_ICON;
929 SetStyle (This, LVS_ICON, LVS_TYPEMASK);
930 break;
932 case FCIDM_SHVIEW_LISTVIEW:
933 This->FolderSettings.ViewMode = FVM_LIST;
934 SetStyle (This, LVS_LIST, LVS_TYPEMASK);
935 break;
937 case FCIDM_SHVIEW_REPORTVIEW:
938 This->FolderSettings.ViewMode = FVM_DETAILS;
939 SetStyle (This, LVS_REPORT, LVS_TYPEMASK);
940 break;
942 /* the menu-ID's for sorting are 0x30... see shrec.rc */
943 case 0x30:
944 case 0x31:
945 case 0x32:
946 case 0x33:
947 ListView_SortItems(This->hWndList, ShellView_ListViewCompareItems, (LPARAM) (dwCmdID - 0x30));
948 break;
950 default:
951 TRACE("-- COMMAND 0x%04lx unhandled\n", dwCmdID);
953 return 0;
956 /**********************************************************
957 * ShellView_OnNotify()
960 static LRESULT ShellView_OnNotify(IShellViewImpl * This, UINT CtlID, LPNMHDR lpnmh)
961 { LPNMLISTVIEW lpnmlv = (LPNMLISTVIEW)lpnmh;
962 NMLVDISPINFOA *lpdi = (NMLVDISPINFOA *)lpnmh;
963 LPITEMIDLIST pidl;
964 STRRET str;
966 TRACE("%p CtlID=%u lpnmh->code=%x\n",This,CtlID,lpnmh->code);
968 switch(lpnmh->code)
970 case NM_SETFOCUS:
971 TRACE("-- NM_SETFOCUS %p\n",This);
972 ShellView_OnSetFocus(This);
973 break;
975 case NM_KILLFOCUS:
976 TRACE("-- NM_KILLFOCUS %p\n",This);
977 ShellView_OnDeactivate(This);
978 /* Notify the ICommDlgBrowser interface */
979 OnStateChange(This,CDBOSC_KILLFOCUS);
980 break;
982 case HDN_ENDTRACKA:
983 TRACE("-- HDN_ENDTRACKA %p\n",This);
984 /*nColumn1 = ListView_GetColumnWidth(This->hWndList, 0);
985 nColumn2 = ListView_GetColumnWidth(This->hWndList, 1);*/
986 break;
988 case LVN_DELETEITEM:
989 TRACE("-- LVN_DELETEITEM %p\n",This);
990 SHFree((LPITEMIDLIST)lpnmlv->lParam); /*delete the pidl because we made a copy of it*/
991 break;
993 case LVN_ITEMACTIVATE:
994 TRACE("-- LVN_ITEMACTIVATE %p\n",This);
995 OnStateChange(This, CDBOSC_SELCHANGE); /* the browser will get the IDataObject now */
996 ShellView_DoContextMenu(This, 0, 0, TRUE);
997 break;
999 case LVN_COLUMNCLICK:
1001 ListView_SortItems(lpnmlv->hdr.hwndFrom, ShellView_ListViewCompareItems, (LPARAM) (lpnmlv->iSubItem));
1002 break;
1005 case LVN_GETDISPINFOA:
1006 TRACE("-- LVN_GETDISPINFOA %p\n",This);
1007 pidl = (LPITEMIDLIST)lpdi->item.lParam;
1010 if(lpdi->item.iSubItem) /*is the sub-item information being requested?*/
1011 { if(lpdi->item.mask & LVIF_TEXT) /*is the text being requested?*/
1012 { if(_ILIsValue(pidl)) /*is This a value or a folder?*/
1013 { switch (lpdi->item.iSubItem)
1014 { case 1: /* size */
1015 _ILGetFileSize (pidl, lpdi->item.pszText, lpdi->item.cchTextMax);
1016 break;
1017 case 2: /* extension */
1018 { char sTemp[64];
1019 if (_ILGetExtension (pidl, sTemp, 64))
1020 { if (!( HCR_MapTypeToValue(sTemp, sTemp, 64, TRUE)
1021 && HCR_MapTypeToValue(sTemp, lpdi->item.pszText, lpdi->item.cchTextMax, FALSE )))
1022 { lstrcpynA (lpdi->item.pszText, sTemp, lpdi->item.cchTextMax);
1023 strncat (lpdi->item.pszText, "-file", lpdi->item.cchTextMax);
1026 else /* no extension found */
1027 { lpdi->item.pszText[0]=0x00;
1030 break;
1031 case 3: /* date */
1032 _ILGetFileDate (pidl, lpdi->item.pszText, lpdi->item.cchTextMax);
1033 break;
1036 else /*its a folder*/
1037 { switch (lpdi->item.iSubItem)
1038 { case 1:
1039 strcpy(lpdi->item.pszText, "");
1040 break;
1041 case 2:
1042 lstrcpynA (lpdi->item.pszText, "Folder", lpdi->item.cchTextMax);
1043 break;
1044 case 3:
1045 _ILGetFileDate (pidl, lpdi->item.pszText, lpdi->item.cchTextMax);
1046 break;
1049 TRACE("-- text=%s\n",lpdi->item.pszText);
1052 else /*the item text is being requested*/
1054 if(lpdi->item.mask & LVIF_TEXT) /*is the text being requested?*/
1056 if(SUCCEEDED(IShellFolder_GetDisplayNameOf(This->pSFParent,pidl, SHGDN_NORMAL | SHGDN_INFOLDER, &str)))
1058 StrRetToStrNA(lpdi->item.pszText, lpdi->item.cchTextMax, &str, pidl);
1060 TRACE("-- text=%s\n",lpdi->item.pszText);
1063 if(lpdi->item.mask & LVIF_IMAGE) /*is the image being requested?*/
1065 lpdi->item.iImage = SHMapPIDLToSystemImageListIndex(This->pSFParent, pidl, 0);
1068 break;
1070 case LVN_ITEMCHANGED:
1071 TRACE("-- LVN_ITEMCHANGED %p\n",This);
1072 OnStateChange(This, CDBOSC_SELCHANGE); /* the browser will get the IDataObject now */
1073 break;
1075 case LVN_BEGINDRAG:
1076 case LVN_BEGINRDRAG:
1078 if (ShellView_GetSelections(This))
1080 IDataObject * pda;
1081 DWORD dwAttributes;
1082 DWORD dwEffect = DROPEFFECT_COPY | DROPEFFECT_MOVE;
1084 if (SUCCEEDED(IShellFolder_GetUIObjectOf(This->pSFParent, This->hWnd, This->cidl, This->apidl, &IID_IDataObject,0,(LPVOID *)&pda)))
1086 IDropSource * pds = (IDropSource*)&(This->lpvtblDropSource); /* own DropSource interface */
1088 if (SUCCEEDED(IShellFolder_GetAttributesOf(This->pSFParent, This->cidl, This->apidl, &dwAttributes)))
1090 if (dwAttributes & SFGAO_CANLINK)
1092 dwEffect |= DROPEFFECT_LINK;
1096 if (pds)
1098 DWORD dwEffect;
1099 pDoDragDrop(pda, pds, dwEffect, &dwEffect);
1102 IDataObject_Release(pda);
1105 break;
1107 case LVN_BEGINLABELEDITA:
1108 case LVN_ENDLABELEDITA:
1109 FIXME("labeledit\n");
1110 break;
1112 default:
1113 TRACE("-- %p WM_COMMAND %s unhandled\n", This, SPY_GetMsgName(lpnmh->code));
1114 break;;
1116 return 0;
1119 /**********************************************************
1120 * ShellView_WndProc
1123 static LRESULT CALLBACK ShellView_WndProc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
1125 IShellViewImpl * pThis = (IShellViewImpl*)GetWindowLongA(hWnd, GWL_USERDATA);
1126 LPCREATESTRUCTA lpcs;
1128 TRACE("(hwnd=%x msg=%x wparm=%x lparm=%lx)\n",hWnd, uMessage, wParam, lParam);
1130 switch (uMessage)
1132 case WM_NCCREATE:
1133 lpcs = (LPCREATESTRUCTA)lParam;
1134 pThis = (IShellViewImpl*)(lpcs->lpCreateParams);
1135 SetWindowLongA(hWnd, GWL_USERDATA, (LONG)pThis);
1136 pThis->hWnd = hWnd; /*set the window handle*/
1137 break;
1139 case WM_SIZE: return ShellView_OnSize(pThis,LOWORD(lParam), HIWORD(lParam));
1140 case WM_SETFOCUS: return ShellView_OnSetFocus(pThis);
1141 case WM_KILLFOCUS: return ShellView_OnKillFocus(pThis);
1142 case WM_CREATE: return ShellView_OnCreate(pThis);
1143 case WM_ACTIVATE: return ShellView_OnActivate(pThis, SVUIA_ACTIVATE_FOCUS);
1144 case WM_NOTIFY: return ShellView_OnNotify(pThis,(UINT)wParam, (LPNMHDR)lParam);
1145 case WM_COMMAND: return ShellView_OnCommand(pThis,
1146 GET_WM_COMMAND_ID(wParam, lParam),
1147 GET_WM_COMMAND_CMD(wParam, lParam),
1148 GET_WM_COMMAND_HWND(wParam, lParam));
1150 case WM_CONTEXTMENU: ShellView_DoContextMenu(pThis, LOWORD(lParam), HIWORD(lParam), FALSE);
1151 return 0;
1153 case WM_SHOWWINDOW: UpdateWindow(pThis->hWndList);
1154 break;
1156 case WM_GETDLGCODE: return SendMessageA(pThis->hWndList,uMessage,0,0);
1158 case WM_DESTROY: pRevokeDragDrop(pThis->hWnd);
1159 break;
1162 return DefWindowProcA (hWnd, uMessage, wParam, lParam);
1164 /**********************************************************
1167 * The INTERFACE of the IShellView object
1170 **********************************************************
1171 * IShellView_QueryInterface
1173 static HRESULT WINAPI IShellView_fnQueryInterface(IShellView * iface,REFIID riid, LPVOID *ppvObj)
1175 ICOM_THIS(IShellViewImpl, iface);
1177 char xriid[50];
1178 WINE_StringFromCLSID((LPCLSID)riid,xriid);
1179 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,xriid,ppvObj);
1181 *ppvObj = NULL;
1183 if(IsEqualIID(riid, &IID_IUnknown))
1185 *ppvObj = This;
1187 else if(IsEqualIID(riid, &IID_IShellView))
1189 *ppvObj = (IShellView*)This;
1191 else if(IsEqualIID(riid, &IID_IOleCommandTarget))
1193 *ppvObj = (IOleCommandTarget*)&(This->lpvtblOleCommandTarget);
1195 else if(IsEqualIID(riid, &IID_IDropTarget))
1197 *ppvObj = (IDropTarget*)&(This->lpvtblDropTarget);
1199 else if(IsEqualIID(riid, &IID_IDropSource))
1201 *ppvObj = (IDropSource*)&(This->lpvtblDropSource);
1203 else if(IsEqualIID(riid, &IID_IViewObject))
1205 *ppvObj = (IViewObject*)&(This->lpvtblViewObject);
1208 if(*ppvObj)
1210 IUnknown_AddRef( (IUnknown*)*ppvObj );
1211 TRACE("-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
1212 return S_OK;
1214 TRACE("-- Interface: E_NOINTERFACE\n");
1215 return E_NOINTERFACE;
1218 /**********************************************************
1219 * IShellView_AddRef
1221 static ULONG WINAPI IShellView_fnAddRef(IShellView * iface)
1223 ICOM_THIS(IShellViewImpl, iface);
1225 TRACE("(%p)->(count=%lu)\n",This,This->ref);
1227 shell32_ObjCount++;
1228 return ++(This->ref);
1230 /**********************************************************
1231 * IShellView_Release
1233 static ULONG WINAPI IShellView_fnRelease(IShellView * iface)
1235 ICOM_THIS(IShellViewImpl, iface);
1237 TRACE("(%p)->()\n",This);
1239 shell32_ObjCount--;
1241 if (!--(This->ref))
1243 TRACE(" destroying IShellView(%p)\n",This);
1245 if(This->pSFParent)
1246 IShellFolder_Release(This->pSFParent);
1248 if (This->apidl)
1249 SHFree(This->apidl);
1251 if (This->pCommDlgBrowser)
1252 ICommDlgBrowser_Release(This->pCommDlgBrowser);
1254 HeapFree(GetProcessHeap(),0,This);
1255 return 0;
1257 return This->ref;
1260 /**********************************************************
1261 * ShellView_GetWindow
1263 static HRESULT WINAPI IShellView_fnGetWindow(IShellView * iface,HWND * phWnd)
1265 ICOM_THIS(IShellViewImpl, iface);
1267 TRACE("(%p)\n",This);
1269 *phWnd = This->hWnd;
1271 return S_OK;
1274 static HRESULT WINAPI IShellView_fnContextSensitiveHelp(IShellView * iface,BOOL fEnterMode)
1276 ICOM_THIS(IShellViewImpl, iface);
1278 FIXME("(%p) stub\n",This);
1280 return E_NOTIMPL;
1283 /**********************************************************
1284 * IShellView_TranslateAccelerator
1286 * FIXME:
1287 * use the accel functions
1289 static HRESULT WINAPI IShellView_fnTranslateAccelerator(IShellView * iface,LPMSG lpmsg)
1291 ICOM_THIS(IShellViewImpl, iface);
1293 FIXME("(%p)->(%p: hwnd=%x msg=%x lp=%lx wp=%x) stub\n",This,lpmsg, lpmsg->hwnd, lpmsg->message, lpmsg->lParam, lpmsg->wParam);
1296 switch (lpmsg->message)
1297 { case WM_KEYDOWN: TRACE("-- key=0x04%x",lpmsg->wParam) ;
1299 return NOERROR;
1302 static HRESULT WINAPI IShellView_fnEnableModeless(IShellView * iface,BOOL fEnable)
1304 ICOM_THIS(IShellViewImpl, iface);
1306 FIXME("(%p) stub\n",This);
1308 return E_NOTIMPL;
1311 static HRESULT WINAPI IShellView_fnUIActivate(IShellView * iface,UINT uState)
1313 ICOM_THIS(IShellViewImpl, iface);
1315 CHAR szName[MAX_PATH];
1316 LRESULT lResult;
1317 int nPartArray[1] = {-1};
1319 TRACE("(%p)->(state=%x) stub\n",This, uState);
1321 /*don't do anything if the state isn't really changing*/
1322 if(This->uState == uState)
1324 return S_OK;
1327 /*OnActivate handles the menu merging and internal state*/
1328 ShellView_OnActivate(This, uState);
1330 /*only do This if we are active*/
1331 if(uState != SVUIA_DEACTIVATE)
1334 IShellFolder_GetFolderPath( This->pSFParent, szName, sizeof(szName) );
1336 /* set the number of parts */
1337 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_STATUS, SB_SETPARTS, 1,
1338 (LPARAM)nPartArray, &lResult);
1340 /* set the text for the parts */
1341 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_STATUS, SB_SETTEXTA,
1342 0, (LPARAM)szName, &lResult);
1345 return S_OK;
1348 static HRESULT WINAPI IShellView_fnRefresh(IShellView * iface)
1350 ICOM_THIS(IShellViewImpl, iface);
1352 TRACE("(%p)\n",This);
1354 ListView_DeleteAllItems(This->hWndList);
1355 ShellView_FillList(This);
1357 return S_OK;
1360 static HRESULT WINAPI IShellView_fnCreateViewWindow(
1361 IShellView * iface,
1362 IShellView *lpPrevView,
1363 LPCFOLDERSETTINGS lpfs,
1364 IShellBrowser * psb,
1365 RECT * prcView,
1366 HWND *phWnd)
1368 ICOM_THIS(IShellViewImpl, iface);
1370 WNDCLASSA wc;
1371 *phWnd = 0;
1374 TRACE("(%p)->(shlview=%p set=%p shlbrs=%p rec=%p hwnd=%p) incomplete\n",This, lpPrevView,lpfs, psb, prcView, phWnd);
1375 TRACE("-- vmode=%x flags=%x left=%i top=%i right=%i bottom=%i\n",lpfs->ViewMode, lpfs->fFlags ,prcView->left,prcView->top, prcView->right, prcView->bottom);
1377 /*set up the member variables*/
1378 This->pShellBrowser = psb;
1379 This->FolderSettings = *lpfs;
1381 /*get our parent window*/
1382 IShellBrowser_AddRef(This->pShellBrowser);
1383 IShellBrowser_GetWindow(This->pShellBrowser, &(This->hWndParent));
1385 /* try to get the ICommDlgBrowserInterface, adds a reference !!! */
1386 This->pCommDlgBrowser=NULL;
1387 if ( SUCCEEDED (IShellBrowser_QueryInterface( This->pShellBrowser,
1388 (REFIID)&IID_ICommDlgBrowser, (LPVOID*) &This->pCommDlgBrowser)))
1390 TRACE("-- CommDlgBrowser\n");
1393 /*if our window class has not been registered, then do so*/
1394 if(!GetClassInfoA(shell32_hInstance, SV_CLASS_NAME, &wc))
1396 ZeroMemory(&wc, sizeof(wc));
1397 wc.style = CS_HREDRAW | CS_VREDRAW;
1398 wc.lpfnWndProc = (WNDPROC) ShellView_WndProc;
1399 wc.cbClsExtra = 0;
1400 wc.cbWndExtra = 0;
1401 wc.hInstance = shell32_hInstance;
1402 wc.hIcon = 0;
1403 wc.hCursor = LoadCursorA (0, IDC_ARROWA);
1404 wc.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);
1405 wc.lpszMenuName = NULL;
1406 wc.lpszClassName = SV_CLASS_NAME;
1408 if(!RegisterClassA(&wc))
1409 return E_FAIL;
1412 *phWnd = CreateWindowExA(0,
1413 SV_CLASS_NAME,
1414 NULL,
1415 WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_TABSTOP,
1416 prcView->left,
1417 prcView->top,
1418 prcView->right - prcView->left,
1419 prcView->bottom - prcView->top,
1420 This->hWndParent,
1422 shell32_hInstance,
1423 (LPVOID)This);
1425 CheckToolbar(This);
1427 if(!*phWnd)
1428 return E_FAIL;
1430 return S_OK;
1433 static HRESULT WINAPI IShellView_fnDestroyViewWindow(IShellView * iface)
1435 ICOM_THIS(IShellViewImpl, iface);
1437 TRACE("(%p)\n",This);
1439 /*Make absolutely sure all our UI is cleaned up.*/
1440 IShellView_UIActivate((IShellView*)This, SVUIA_DEACTIVATE);
1442 if(This->hMenu)
1444 DestroyMenu(This->hMenu);
1447 DestroyWindow(This->hWnd);
1448 IShellBrowser_Release(This->pShellBrowser);
1450 return S_OK;
1453 static HRESULT WINAPI IShellView_fnGetCurrentInfo(IShellView * iface, LPFOLDERSETTINGS lpfs)
1455 ICOM_THIS(IShellViewImpl, iface);
1457 TRACE("(%p)->(%p) vmode=%x flags=%x\n",This, lpfs,
1458 This->FolderSettings.ViewMode, This->FolderSettings.fFlags);
1460 if (!lpfs) return E_INVALIDARG;
1462 *lpfs = This->FolderSettings;
1463 return NOERROR;
1466 static HRESULT WINAPI IShellView_fnAddPropertySheetPages(IShellView * iface, DWORD dwReserved,LPFNADDPROPSHEETPAGE lpfn, LPARAM lparam)
1468 ICOM_THIS(IShellViewImpl, iface);
1470 FIXME("(%p) stub\n",This);
1472 return E_NOTIMPL;
1475 static HRESULT WINAPI IShellView_fnSaveViewState(IShellView * iface)
1477 ICOM_THIS(IShellViewImpl, iface);
1479 FIXME("(%p) stub\n",This);
1481 return S_OK;
1484 static HRESULT WINAPI IShellView_fnSelectItem(IShellView * iface, LPCITEMIDLIST pidlItem, UINT uFlags)
1485 { ICOM_THIS(IShellViewImpl, iface);
1487 FIXME("(%p)->(pidl=%p, 0x%08x) stub\n",This, pidlItem, uFlags);
1489 return E_NOTIMPL;
1492 static HRESULT WINAPI IShellView_fnGetItemObject(IShellView * iface, UINT uItem, REFIID riid, LPVOID *ppvOut)
1494 ICOM_THIS(IShellViewImpl, iface);
1496 char xriid[50];
1498 WINE_StringFromCLSID((LPCLSID)riid,xriid);
1499 TRACE("(%p)->(uItem=0x%08x,\n\tIID=%s, ppv=%p)\n",This, uItem, xriid, ppvOut);
1501 *ppvOut = NULL;
1503 switch(uItem)
1505 case SVGIO_BACKGROUND:
1506 *ppvOut = ISvBgCm_Constructor();
1507 break;
1509 case SVGIO_SELECTION:
1510 ShellView_GetSelections(This);
1511 IShellFolder_GetUIObjectOf(This->pSFParent, This->hWnd, This->cidl, This->apidl, riid, 0, ppvOut);
1512 break;
1514 TRACE("-- (%p)->(interface=%p)\n",This, *ppvOut);
1516 if(!*ppvOut) return E_OUTOFMEMORY;
1518 return S_OK;
1521 static struct ICOM_VTABLE(IShellView) svvt =
1523 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1524 IShellView_fnQueryInterface,
1525 IShellView_fnAddRef,
1526 IShellView_fnRelease,
1527 IShellView_fnGetWindow,
1528 IShellView_fnContextSensitiveHelp,
1529 IShellView_fnTranslateAccelerator,
1530 IShellView_fnEnableModeless,
1531 IShellView_fnUIActivate,
1532 IShellView_fnRefresh,
1533 IShellView_fnCreateViewWindow,
1534 IShellView_fnDestroyViewWindow,
1535 IShellView_fnGetCurrentInfo,
1536 IShellView_fnAddPropertySheetPages,
1537 IShellView_fnSaveViewState,
1538 IShellView_fnSelectItem,
1539 IShellView_fnGetItemObject
1543 /**********************************************************
1544 * ISVOleCmdTarget_QueryInterface (IUnknown)
1546 static HRESULT WINAPI ISVOleCmdTarget_QueryInterface(
1547 IOleCommandTarget * iface,
1548 REFIID iid,
1549 LPVOID* ppvObj)
1551 _ICOM_THIS_From_IOleCommandTarget(IShellViewImpl, iface);
1553 return IShellFolder_QueryInterface((IShellFolder*)This, iid, ppvObj);
1556 /**********************************************************
1557 * ISVOleCmdTarget_AddRef (IUnknown)
1559 static ULONG WINAPI ISVOleCmdTarget_AddRef(
1560 IOleCommandTarget * iface)
1562 _ICOM_THIS_From_IOleCommandTarget(IShellFolder, iface);
1564 return IShellFolder_AddRef((IShellFolder*)This);
1567 /**********************************************************
1568 * ISVOleCmdTarget_Release (IUnknown)
1570 static ULONG WINAPI ISVOleCmdTarget_Release(
1571 IOleCommandTarget * iface)
1573 _ICOM_THIS_From_IOleCommandTarget(IShellViewImpl, iface);
1575 return IShellFolder_Release((IShellFolder*)This);
1578 /**********************************************************
1579 * ISVOleCmdTarget_QueryStatus (IOleCommandTarget)
1581 static HRESULT WINAPI ISVOleCmdTarget_QueryStatus(
1582 IOleCommandTarget *iface,
1583 const GUID* pguidCmdGroup,
1584 ULONG cCmds,
1585 OLECMD * prgCmds,
1586 OLECMDTEXT* pCmdText)
1588 char xguid[50];
1590 _ICOM_THIS_From_IOleCommandTarget(IShellViewImpl, iface);
1592 WINE_StringFromCLSID((LPCLSID)pguidCmdGroup,xguid);
1594 FIXME("(%p)->(%p(%s) 0x%08lx %p %p\n", This, pguidCmdGroup, xguid, cCmds, prgCmds, pCmdText);
1595 return E_NOTIMPL;
1598 /**********************************************************
1599 * ISVOleCmdTarget_Exec (IOleCommandTarget)
1601 * nCmdID is the OLECMDID_* enumeration
1603 static HRESULT WINAPI ISVOleCmdTarget_Exec(
1604 IOleCommandTarget *iface,
1605 const GUID* pguidCmdGroup,
1606 DWORD nCmdID,
1607 DWORD nCmdexecopt,
1608 VARIANT* pvaIn,
1609 VARIANT* pvaOut)
1611 char xguid[50];
1613 _ICOM_THIS_From_IOleCommandTarget(IShellViewImpl, iface);
1615 WINE_StringFromCLSID((LPCLSID)pguidCmdGroup,xguid);
1617 FIXME("(%p)->(\n\tTarget GUID:%s Command:0x%08lx Opt:0x%08lx %p %p)\n", This, xguid, nCmdID, nCmdexecopt, pvaIn, pvaOut);
1618 return E_NOTIMPL;
1621 static ICOM_VTABLE(IOleCommandTarget) ctvt =
1623 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1624 ISVOleCmdTarget_QueryInterface,
1625 ISVOleCmdTarget_AddRef,
1626 ISVOleCmdTarget_Release,
1627 ISVOleCmdTarget_QueryStatus,
1628 ISVOleCmdTarget_Exec
1631 /**********************************************************
1632 * ISVDropTarget implementation
1635 static HRESULT WINAPI ISVDropTarget_QueryInterface(
1636 IDropTarget *iface,
1637 REFIID riid,
1638 LPVOID *ppvObj)
1640 char xriid[50];
1642 _ICOM_THIS_From_IDropTarget(IShellViewImpl, iface);
1644 WINE_StringFromCLSID((LPCLSID)riid,xriid);
1646 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,xriid,ppvObj);
1648 return IShellFolder_QueryInterface((IShellFolder*)This, riid, ppvObj);
1651 static ULONG WINAPI ISVDropTarget_AddRef( IDropTarget *iface)
1653 _ICOM_THIS_From_IDropTarget(IShellViewImpl, iface);
1655 TRACE("(%p)->(count=%lu)\n",This,This->ref);
1657 return IShellFolder_AddRef((IShellFolder*)This);
1660 static ULONG WINAPI ISVDropTarget_Release( IDropTarget *iface)
1662 _ICOM_THIS_From_IDropTarget(IShellViewImpl, iface);
1664 TRACE("(%p)->(count=%lu)\n",This,This->ref);
1666 return IShellFolder_Release((IShellFolder*)This);
1669 static HRESULT WINAPI ISVDropTarget_DragEnter(
1670 IDropTarget *iface,
1671 IDataObject *pDataObject,
1672 DWORD grfKeyState,
1673 POINTL pt,
1674 DWORD *pdwEffect)
1677 _ICOM_THIS_From_IDropTarget(IShellViewImpl, iface);
1679 FIXME("Stub: This=%p, DataObject=%p\n",This,pDataObject);
1681 return E_NOTIMPL;
1684 static HRESULT WINAPI ISVDropTarget_DragOver(
1685 IDropTarget *iface,
1686 DWORD grfKeyState,
1687 POINTL pt,
1688 DWORD *pdwEffect)
1690 _ICOM_THIS_From_IDropTarget(IShellViewImpl, iface);
1692 FIXME("Stub: This=%p\n",This);
1694 return E_NOTIMPL;
1697 static HRESULT WINAPI ISVDropTarget_DragLeave(
1698 IDropTarget *iface)
1700 _ICOM_THIS_From_IDropTarget(IShellViewImpl, iface);
1702 FIXME("Stub: This=%p\n",This);
1704 return E_NOTIMPL;
1707 static HRESULT WINAPI ISVDropTarget_Drop(
1708 IDropTarget *iface,
1709 IDataObject* pDataObject,
1710 DWORD grfKeyState,
1711 POINTL pt,
1712 DWORD *pdwEffect)
1714 _ICOM_THIS_From_IDropTarget(IShellViewImpl, iface);
1716 FIXME("Stub: This=%p\n",This);
1718 return E_NOTIMPL;
1721 static struct ICOM_VTABLE(IDropTarget) dtvt =
1723 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1724 ISVDropTarget_QueryInterface,
1725 ISVDropTarget_AddRef,
1726 ISVDropTarget_Release,
1727 ISVDropTarget_DragEnter,
1728 ISVDropTarget_DragOver,
1729 ISVDropTarget_DragLeave,
1730 ISVDropTarget_Drop
1733 /**********************************************************
1734 * ISVDropSource implementation
1737 static HRESULT WINAPI ISVDropSource_QueryInterface(
1738 IDropSource *iface,
1739 REFIID riid,
1740 LPVOID *ppvObj)
1742 char xriid[50];
1744 _ICOM_THIS_From_IDropSource(IShellViewImpl, iface);
1746 WINE_StringFromCLSID((LPCLSID)riid,xriid);
1748 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,xriid,ppvObj);
1750 return IShellFolder_QueryInterface((IShellFolder*)This, riid, ppvObj);
1753 static ULONG WINAPI ISVDropSource_AddRef( IDropSource *iface)
1755 _ICOM_THIS_From_IDropSource(IShellViewImpl, iface);
1757 TRACE("(%p)->(count=%lu)\n",This,This->ref);
1759 return IShellFolder_AddRef((IShellFolder*)This);
1762 static ULONG WINAPI ISVDropSource_Release( IDropSource *iface)
1764 _ICOM_THIS_From_IDropSource(IShellViewImpl, iface);
1766 TRACE("(%p)->(count=%lu)\n",This,This->ref);
1768 return IShellFolder_Release((IShellFolder*)This);
1770 static HRESULT WINAPI ISVDropSource_QueryContinueDrag(
1771 IDropSource *iface,
1772 BOOL fEscapePressed,
1773 DWORD grfKeyState)
1775 _ICOM_THIS_From_IDropSource(IShellViewImpl, iface);
1776 TRACE("(%p)\n",This);
1778 if (fEscapePressed)
1779 return DRAGDROP_S_CANCEL;
1780 else if (!(grfKeyState & MK_LBUTTON) && !(grfKeyState & MK_RBUTTON))
1781 return DRAGDROP_S_DROP;
1782 else
1783 return NOERROR;
1786 static HRESULT WINAPI ISVDropSource_GiveFeedback(
1787 IDropSource *iface,
1788 DWORD dwEffect)
1790 _ICOM_THIS_From_IDropSource(IShellViewImpl, iface);
1791 TRACE("(%p)\n",This);
1793 return DRAGDROP_S_USEDEFAULTCURSORS;
1796 static struct ICOM_VTABLE(IDropSource) dsvt =
1798 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1799 ISVDropSource_QueryInterface,
1800 ISVDropSource_AddRef,
1801 ISVDropSource_Release,
1802 ISVDropSource_QueryContinueDrag,
1803 ISVDropSource_GiveFeedback
1805 /**********************************************************
1806 * ISVViewObject implementation
1809 static HRESULT WINAPI ISVViewObject_QueryInterface(
1810 IViewObject *iface,
1811 REFIID riid,
1812 LPVOID *ppvObj)
1814 char xriid[50];
1816 _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
1818 WINE_StringFromCLSID((LPCLSID)riid,xriid);
1820 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,xriid,ppvObj);
1822 return IShellFolder_QueryInterface((IShellFolder*)This, riid, ppvObj);
1825 static ULONG WINAPI ISVViewObject_AddRef( IViewObject *iface)
1827 _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
1829 TRACE("(%p)->(count=%lu)\n",This,This->ref);
1831 return IShellFolder_AddRef((IShellFolder*)This);
1834 static ULONG WINAPI ISVViewObject_Release( IViewObject *iface)
1836 _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
1838 TRACE("(%p)->(count=%lu)\n",This,This->ref);
1840 return IShellFolder_Release((IShellFolder*)This);
1843 static HRESULT WINAPI ISVViewObject_Draw(
1844 IViewObject *iface,
1845 DWORD dwDrawAspect,
1846 LONG lindex,
1847 void* pvAspect,
1848 DVTARGETDEVICE* ptd,
1849 HDC hdcTargetDev,
1850 HDC hdcDraw,
1851 LPCRECTL lprcBounds,
1852 LPCRECTL lprcWBounds,
1853 IVO_ContCallback pfnContinue,
1854 DWORD dwContinue)
1857 _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
1859 FIXME("Stub: This=%p\n",This);
1861 return E_NOTIMPL;
1863 static HRESULT WINAPI ISVViewObject_GetColorSet(
1864 IViewObject *iface,
1865 DWORD dwDrawAspect,
1866 LONG lindex,
1867 void *pvAspect,
1868 DVTARGETDEVICE* ptd,
1869 HDC hicTargetDevice,
1870 LOGPALETTE** ppColorSet)
1873 _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
1875 FIXME("Stub: This=%p\n",This);
1877 return E_NOTIMPL;
1879 static HRESULT WINAPI ISVViewObject_Freeze(
1880 IViewObject *iface,
1881 DWORD dwDrawAspect,
1882 LONG lindex,
1883 void* pvAspect,
1884 DWORD* pdwFreeze)
1887 _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
1889 FIXME("Stub: This=%p\n",This);
1891 return E_NOTIMPL;
1893 static HRESULT WINAPI ISVViewObject_Unfreeze(
1894 IViewObject *iface,
1895 DWORD dwFreeze)
1898 _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
1900 FIXME("Stub: This=%p\n",This);
1902 return E_NOTIMPL;
1904 static HRESULT WINAPI ISVViewObject_SetAdvise(
1905 IViewObject *iface,
1906 DWORD aspects,
1907 DWORD advf,
1908 IAdviseSink* pAdvSink)
1911 _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
1913 FIXME("Stub: This=%p\n",This);
1915 return E_NOTIMPL;
1917 static HRESULT WINAPI ISVViewObject_GetAdvise(
1918 IViewObject *iface,
1919 DWORD* pAspects,
1920 DWORD* pAdvf,
1921 IAdviseSink** ppAdvSink)
1924 _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
1926 FIXME("Stub: This=%p\n",This);
1928 return E_NOTIMPL;
1932 static struct ICOM_VTABLE(IViewObject) vovt =
1934 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1935 ISVViewObject_QueryInterface,
1936 ISVViewObject_AddRef,
1937 ISVViewObject_Release,
1938 ISVViewObject_Draw,
1939 ISVViewObject_GetColorSet,
1940 ISVViewObject_Freeze,
1941 ISVViewObject_Unfreeze,
1942 ISVViewObject_SetAdvise,
1943 ISVViewObject_GetAdvise