Changed some treeview related definitions.
[wine] / dlls / shell32 / shlview.c
1 /*
2  *      ShellView
3  *
4  *      Copyright 1998  <juergen.schmied@metronet.de>
5  *
6  *  FIXME: when the ShellView_WndProc gets a WM_NCDESTROY should we do a
7  *  Release() ??? 
8  *
9  */
10
11 #include <stdlib.h>
12 #include <string.h>
13 #include "debug.h"
14 #include "winerror.h"
15
16 #include "pidl.h"
17 #include "shlguid.h"
18 #include "shlobj.h"
19 #include "servprov.h"
20 #include "objbase.h"
21 #include "if_macros.h"
22 #include "shell32_main.h"
23 #include "shresdef.h"
24
25 /***********************************************************************
26 *   IShellView implementation
27 */
28 static HRESULT WINAPI IShellView_QueryInterface(LPSHELLVIEW,REFIID, LPVOID *);
29 static ULONG WINAPI IShellView_AddRef(LPSHELLVIEW) ;
30 static ULONG WINAPI IShellView_Release(LPSHELLVIEW);
31     /* IOleWindow methods */
32 static HRESULT WINAPI IShellView_GetWindow(LPSHELLVIEW,HWND32 * lphwnd);
33 static HRESULT WINAPI IShellView_ContextSensitiveHelp(LPSHELLVIEW,BOOL32 fEnterMode);
34     /* IShellView methods */
35 static HRESULT WINAPI IShellView_TranslateAccelerator(LPSHELLVIEW,LPMSG32 lpmsg);
36 static HRESULT WINAPI IShellView_EnableModeless(LPSHELLVIEW,BOOL32 fEnable);
37 static HRESULT WINAPI IShellView_UIActivate(LPSHELLVIEW,UINT32 uState);
38 static HRESULT WINAPI IShellView_Refresh(LPSHELLVIEW);
39 static HRESULT WINAPI IShellView_CreateViewWindow(LPSHELLVIEW, IShellView *lpPrevView,LPCFOLDERSETTINGS lpfs, IShellBrowser * psb,RECT32 * prcView, HWND32  *phWnd);
40 static HRESULT WINAPI IShellView_DestroyViewWindow(LPSHELLVIEW);
41 static HRESULT WINAPI IShellView_GetCurrentInfo(LPSHELLVIEW, LPFOLDERSETTINGS lpfs);
42 static HRESULT WINAPI IShellView_AddPropertySheetPages(LPSHELLVIEW, DWORD dwReserved,LPFNADDPROPSHEETPAGE lpfn, LPARAM lparam);
43 static HRESULT WINAPI IShellView_SaveViewState(LPSHELLVIEW);
44 static HRESULT WINAPI IShellView_SelectItem(LPSHELLVIEW, LPCITEMIDLIST pidlItem, UINT32 uFlags);
45 static HRESULT WINAPI IShellView_GetItemObject(LPSHELLVIEW, UINT32 uItem, REFIID riid,LPVOID *ppv);
46
47 static BOOL32 ShellView_CanDoIDockingWindow(LPSHELLVIEW);
48
49 static struct IShellView_VTable svvt = 
50 { IShellView_QueryInterface,
51   IShellView_AddRef,
52   IShellView_Release,
53   IShellView_GetWindow,
54   IShellView_ContextSensitiveHelp,
55   IShellView_TranslateAccelerator,
56   IShellView_EnableModeless,
57   IShellView_UIActivate,
58   IShellView_Refresh,
59   IShellView_CreateViewWindow,
60   IShellView_DestroyViewWindow,
61   IShellView_GetCurrentInfo,
62   IShellView_AddPropertySheetPages,
63   IShellView_SaveViewState,
64   IShellView_SelectItem,
65   IShellView_GetItemObject
66 };
67
68 /*menu items */
69 #define IDM_VIEW_FILES  (FCIDM_SHVIEWFIRST + 0x500)
70 #define IDM_VIEW_IDW    (FCIDM_SHVIEWFIRST + 0x501)
71 #define IDM_MYFILEITEM  (FCIDM_SHVIEWFIRST + 0x502)
72
73 #define ID_LISTVIEW     2000
74
75 #define MENU_OFFSET  1
76 #define MENU_MAX     100
77
78 #define TOOLBAR_ID   (L"SHELLDLL_DefView")
79 /*windowsx.h */
80 #define GET_WM_COMMAND_ID(wp, lp)               LOWORD(wp)
81 #define GET_WM_COMMAND_HWND(wp, lp)             (HWND32)(lp)
82 #define GET_WM_COMMAND_CMD(wp, lp)              HIWORD(wp)
83 /* winuser.h */
84 #define WM_SETTINGCHANGE                WM_WININICHANGE
85 extern void WINAPI _InsertMenuItem (HMENU32 hmenu, UINT32 indexMenu, BOOL32 fByPosition, 
86                         UINT32 wID, UINT32 fType, LPSTR dwTypeData, UINT32 fState);
87
88 typedef struct
89 {  int   idCommand;
90    int   iImage;
91    int   idButtonString;
92    int   idMenuString;
93    int   nStringOffset;
94    BYTE  bState;
95    BYTE  bStyle;
96 } MYTOOLINFO, *LPMYTOOLINFO;
97
98 extern  LPCVOID _Resource_Men_MENU_001_0_data;
99 extern  LPCVOID _Resource_Men_MENU_002_0_data;
100
101 MYTOOLINFO g_Tools[] = 
102 { {IDM_VIEW_FILES, 0, IDS_TB_VIEW_FILES, IDS_MI_VIEW_FILES, 0, TBSTATE_ENABLED, TBSTYLE_BUTTON},
103   {-1, 0, 0, 0, 0, 0, 0}   
104 };
105 BOOL32 g_bViewKeys;
106 BOOL32 g_bShowIDW;
107
108 typedef void (CALLBACK *PFNSHGETSETTINGSPROC)(LPSHELLFLAGSTATE lpsfs, DWORD dwMask);
109
110 /**************************************************************************
111 *  IShellView_Constructor
112 */
113 LPSHELLVIEW IShellView_Constructor( LPSHELLFOLDER pFolder, LPCITEMIDLIST pidl)
114 {       LPSHELLVIEW sv;
115         sv=(LPSHELLVIEW)HeapAlloc(GetProcessHeap(),0,sizeof(IShellView));
116         sv->ref=1;
117         sv->lpvtbl=&svvt;
118   
119         sv->mpidl       = ILClone(pidl);
120         sv->hMenu       = 0;
121         sv->pSFParent   = pFolder;
122         sv->uSelected = 0;
123         sv->aSelectedItems = NULL;
124
125         if(sv->pSFParent)
126           sv->pSFParent->lpvtbl->fnAddRef(sv->pSFParent);
127
128         TRACE(shell,"(%p)->(%p pidl=%p)\n",sv, pFolder, pidl);
129         shell32_ObjCount++;
130         return sv;
131 }
132 /**************************************************************************
133 *  helperfunctions for communication with ICommDlgBrowser
134 *
135 */
136 static BOOL32 IsInCommDlg(LPSHELLVIEW this)
137 {       return(this->pCommDlgBrowser != NULL);
138 }
139 static HRESULT IncludeObject(LPSHELLVIEW this, LPCITEMIDLIST pidl)
140 {       if ( IsInCommDlg(this) )
141         { TRACE(shell,"ICommDlgBrowser::IncludeObject pidl=%p\n", pidl);
142           return (this->pCommDlgBrowser->lpvtbl->fnIncludeObject(this->pCommDlgBrowser, this, pidl));
143         }
144         return S_OK;
145 }
146 static HRESULT OnDefaultCommand(LPSHELLVIEW this)
147 {       if (IsInCommDlg(this))
148         { TRACE(shell,"ICommDlgBrowser::OnDefaultCommand\n");
149           return (this->pCommDlgBrowser->lpvtbl->fnOnDefaultCommand(this->pCommDlgBrowser, this));
150         }
151         return S_FALSE;
152 }
153 static HRESULT OnStateChange(LPSHELLVIEW this, UINT32 uFlags)
154 {       if (IsInCommDlg(this))
155         { TRACE(shell,"ICommDlgBrowser::OnStateChange flags=%x\n", uFlags);
156           return (this->pCommDlgBrowser->lpvtbl->fnOnStateChange(this->pCommDlgBrowser, this, uFlags));
157         }
158         return S_FALSE;
159 }
160 static void SetStyle(LPSHELLVIEW this, DWORD dwAdd, DWORD dwRemove)
161 {       DWORD tmpstyle;
162
163         TRACE(shell,"(%p)\n", this);
164
165         tmpstyle = GetWindowLong32A(this->hWndList, GWL_STYLE);
166         SetWindowLong32A(this->hWndList, GWL_STYLE, dwAdd | (tmpstyle & ~dwRemove));
167 }
168
169 static void CheckToolbar(LPSHELLVIEW this)
170 {       LRESULT result;
171
172         TRACE(shell,"\n");
173         
174         IShellBrowser_SendControlMsg(this->pShellBrowser, FCW_TOOLBAR, TB_CHECKBUTTON,
175                 FCIDM_TB_SMALLICON, (this->FolderSettings.ViewMode==FVM_LIST)? TRUE : FALSE, &result);
176         IShellBrowser_SendControlMsg(this->pShellBrowser, FCW_TOOLBAR, TB_CHECKBUTTON,
177                 FCIDM_TB_REPORTVIEW, (this->FolderSettings.ViewMode==FVM_DETAILS)? TRUE : FALSE, &result);
178         IShellBrowser_SendControlMsg(this->pShellBrowser, FCW_TOOLBAR, TB_ENABLEBUTTON,
179                 FCIDM_TB_SMALLICON, TRUE, &result);
180         IShellBrowser_SendControlMsg(this->pShellBrowser, FCW_TOOLBAR, TB_ENABLEBUTTON,
181                 FCIDM_TB_REPORTVIEW, TRUE, &result);
182         TRACE(shell,"--\n");
183 }
184
185 static void MergeToolBar(LPSHELLVIEW this)
186 {       LRESULT iStdBMOffset;
187         LRESULT iViewBMOffset;
188         TBADDBITMAP ab;
189         TBBUTTON tbActual[6];
190         int i;
191         enum
192         { IN_STD_BMP = 0x4000,
193           IN_VIEW_BMP = 0x8000,
194         } ;
195         static const TBBUTTON c_tbDefault[] =
196         { { STD_COPY | IN_STD_BMP, FCIDM_SHVIEW_COPY, TBSTATE_ENABLED, TBSTYLE_BUTTON, {0,0}, 0, -1},
197           { 0,  0,      TBSTATE_ENABLED, TBSTYLE_SEP, {0,0}, 0, -1 },
198           { VIEW_LARGEICONS | IN_VIEW_BMP, FCIDM_SHVIEW_BIGICON,        TBSTATE_ENABLED, TBSTYLE_BUTTON, {0,0}, 0L, -1 },
199           { VIEW_SMALLICONS | IN_VIEW_BMP, FCIDM_SHVIEW_SMALLICON,      TBSTATE_ENABLED, TBSTYLE_BUTTON, {0,0}, 0L, -1 },
200           { VIEW_LIST       | IN_VIEW_BMP, FCIDM_SHVIEW_LISTVIEW,       TBSTATE_ENABLED, TBSTYLE_BUTTON, {0,0}, 0L, -1 },
201           { VIEW_DETAILS    | IN_VIEW_BMP, FCIDM_SHVIEW_REPORTVIEW,     TBSTATE_ENABLED, TBSTYLE_BUTTON, {0,0}, 0L, -1 },
202         } ;
203
204         TRACE(shell,"\n");
205
206         ab.hInst = HINST_COMMCTRL;              /* hinstCommctrl */
207         ab.nID   = IDB_STD_SMALL_COLOR; /* std bitmaps */
208         IShellBrowser_SendControlMsg(this->pShellBrowser,FCW_TOOLBAR,
209                                  TB_ADDBITMAP, 8, (LPARAM)&ab, &iStdBMOffset);
210
211         TRACE(shell,"TB_ADDBITMAP returns %lx\n", iStdBMOffset);
212
213         ab.nID   = IDB_VIEW_SMALL_COLOR;        /* std view bitmaps */
214         IShellBrowser_SendControlMsg(this->pShellBrowser,FCW_TOOLBAR,
215                                  TB_ADDBITMAP, 8, (LPARAM)&ab, &iViewBMOffset);
216
217         TRACE(shell,"TB_ADDBITMAP returns %lx\n", iViewBMOffset);
218
219         for (i=0; i<6; ++i)
220         { tbActual[i] = c_tbDefault[i];
221           if (!(tbActual[i].fsStyle & TBSTYLE_SEP))
222           { if (tbActual[i].iBitmap & IN_VIEW_BMP)
223             { tbActual[i].iBitmap = (tbActual[i].iBitmap & ~IN_VIEW_BMP) + iViewBMOffset;
224             }
225             else if (tbActual[i].iBitmap & IN_STD_BMP)
226             { tbActual[i].iBitmap = (tbActual[i].iBitmap & ~IN_STD_BMP) + iStdBMOffset;
227             }
228           }
229         }
230
231         IShellBrowser_SetToolbarItems(this->pShellBrowser,tbActual, 6, FCT_MERGE);
232
233         CheckToolbar(this);
234         TRACE(shell,"--\n");
235
236 }
237
238 /**************************************************************************
239 * ShellView_CreateList()
240 *
241 */
242
243 BOOL32 ShellView_CreateList (LPSHELLVIEW this)
244 {       DWORD dwStyle;
245
246         TRACE(shell,"%p\n",this);
247
248         dwStyle = WS_TABSTOP | WS_VISIBLE | WS_CHILD | WS_BORDER |
249                   LVS_SHAREIMAGELISTS | LVS_EDITLABELS | LVS_ALIGNLEFT;
250         switch (this->FolderSettings.ViewMode)
251         { case FVM_ICON:        dwStyle |= LVS_ICON;            break;
252           case FVM_DETAILS:     dwStyle |= LVS_REPORT;          break;
253           case FVM_SMALLICON:   dwStyle |= LVS_SMALLICON;       break;
254           case FVM_LIST:        dwStyle |= LVS_LIST;            break;
255           default:              dwStyle |= LVS_LIST;            break;
256         }
257         if (this->FolderSettings.fFlags && FWF_AUTOARRANGE)     dwStyle |= LVS_AUTOARRANGE;
258         /*if (this->FolderSettings.fFlags && FWF_DESKTOP); used from explorer*/
259         if (this->FolderSettings.fFlags && FWF_SINGLESEL)       dwStyle |= LVS_SINGLESEL;
260
261         this->hWndList=CreateWindowEx32A( WS_EX_CLIENTEDGE,
262                                           WC_LISTVIEW32A,
263                                           NULL,
264                                           dwStyle,
265                                           0,0,0,0,
266                                           this->hWnd,
267                                           (HMENU32)ID_LISTVIEW,
268                                           shell32_hInstance,
269                                           NULL);
270
271         if(!this->hWndList)
272           return FALSE;
273
274         /*  UpdateShellSettings(); */
275         return TRUE;
276 }
277 /**************************************************************************
278 * ShellView_InitList()
279 *
280 * NOTES
281 *  internal
282 */
283 int  nColumn1=120; /* width of column */
284 int  nColumn2=80;
285 int  nColumn3=170;
286 int  nColumn4=60;
287
288 BOOL32 ShellView_InitList(LPSHELLVIEW this)
289 {       LVCOLUMN32A lvColumn;
290         CHAR        szString[50];
291
292         TRACE(shell,"%p\n",this);
293
294         ListView_DeleteAllItems(this->hWndList);
295
296         /*initialize the columns */
297         lvColumn.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT;      /*  |  LVCF_SUBITEM;*/
298         lvColumn.fmt = LVCFMT_LEFT;
299         lvColumn.pszText = szString;
300
301         lvColumn.cx = nColumn1;
302         strcpy(szString,"File");
303         /*LoadString32A(shell32_hInstance, IDS_COLUMN1, szString, sizeof(szString));*/
304         ListView_InsertColumn32A(this->hWndList, 0, &lvColumn);
305
306         lvColumn.cx = nColumn2;
307         strcpy(szString,"Size");
308         ListView_InsertColumn32A(this->hWndList, 1, &lvColumn);
309
310         lvColumn.cx = nColumn3;
311         strcpy(szString,"Type");
312         ListView_InsertColumn32A(this->hWndList, 2, &lvColumn);
313
314         lvColumn.cx = nColumn4;
315         strcpy(szString,"Modified");
316         ListView_InsertColumn32A(this->hWndList, 3, &lvColumn);
317
318         ListView_SetImageList(this->hWndList, ShellSmallIconList, LVSIL_SMALL);
319         ListView_SetImageList(this->hWndList, ShellBigIconList, LVSIL_NORMAL);
320   
321         return TRUE;
322 }
323 /**************************************************************************
324 * ShellView_CompareItems() 
325 *
326 * NOTES
327 *  internal, CALLBACK for DSA_Sort
328 */   
329 INT32 CALLBACK ShellView_CompareItems(LPVOID lParam1, LPVOID lParam2, LPARAM lpData)
330 {       int ret;
331         TRACE(shell,"pidl1=%p pidl2=%p lpsf=%p\n", lParam1, lParam2, (LPVOID) lpData);
332
333         if(!lpData)
334           return 0;
335           
336         ret =  (int)((LPSHELLFOLDER)lpData)->lpvtbl->fnCompareIDs((LPSHELLFOLDER)lpData, 0, (LPITEMIDLIST)lParam1, (LPITEMIDLIST)lParam2);  
337         TRACE(shell,"ret=%i\n",ret);
338         return ret;
339 }
340
341 /**************************************************************************
342 * ShellView_FillList()
343 *
344 * NOTES
345 *  internal
346 */   
347
348 static HRESULT ShellView_FillList(LPSHELLVIEW this)
349 {       LPENUMIDLIST    pEnumIDList;
350         LPITEMIDLIST    pidl;
351         DWORD           dwFetched;
352         UINT32          i;
353         LVITEM32A       lvItem;
354         HRESULT         hRes;
355         HDPA            hdpa;
356
357         TRACE(shell,"%p\n",this);
358
359         /* get the itemlist from the shfolder*/  
360         hRes = this->pSFParent->lpvtbl->fnEnumObjects(this->pSFParent,this->hWnd, SHCONTF_NONFOLDERS | SHCONTF_FOLDERS, &pEnumIDList);
361         if (hRes != S_OK)
362         { if (hRes==S_FALSE)
363             return(NOERROR);
364           return(hRes);
365         }
366
367         /* create a pointer array */    
368         hdpa = pDPA_Create(16);
369         if (!hdpa)
370         { return(E_OUTOFMEMORY);
371         }
372
373         /* copy the items into the array*/
374         while((S_OK == pEnumIDList->lpvtbl->fnNext(pEnumIDList,1, &pidl, &dwFetched)) && dwFetched)
375         { if (pDPA_InsertPtr(hdpa, 0x7fff, pidl) == -1)
376           { SHFree(pidl);
377           } 
378         }
379
380         /*sort the array*/
381         pDPA_Sort(hdpa, ShellView_CompareItems, (LPARAM)this->pSFParent);
382
383         /*turn the listview's redrawing off*/
384         SendMessage32A(this->hWndList, WM_SETREDRAW, FALSE, 0); 
385
386         for (i=0; i < DPA_GetPtrCount(hdpa); ++i)       /* DPA_GetPtrCount is a macro*/
387         { pidl = (LPITEMIDLIST)DPA_GetPtr(hdpa, i);
388           if (IncludeObject(this, pidl) == S_OK)        /* in a commdlg this works as a filemask*/
389           { ZeroMemory(&lvItem, sizeof(lvItem));        /* create the listviewitem*/
390             lvItem.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM;          /*set the mask*/
391             lvItem.iItem = ListView_GetItemCount(this->hWndList);       /*add the item to the end of the list*/
392             lvItem.lParam = (LPARAM) pidl;                              /*set the item's data*/
393             lvItem.pszText = LPSTR_TEXTCALLBACK32A;                     /*get text on a callback basis*/
394             lvItem.iImage = I_IMAGECALLBACK;                            /*get the image on a callback basis*/
395             ListView_InsertItem32A(this->hWndList, &lvItem);
396           }
397           else
398             SHFree(pidl);       /* the listview has the COPY*/
399         }
400
401         /*turn the listview's redrawing back on and force it to draw*/
402         SendMessage32A(this->hWndList, WM_SETREDRAW, TRUE, 0);
403         InvalidateRect32(this->hWndList, NULL, TRUE);
404         UpdateWindow32(this->hWndList);
405
406         pEnumIDList->lpvtbl->fnRelease(pEnumIDList); /* destroy the list*/
407         pDPA_Destroy(hdpa);
408         
409         return S_OK;
410 }
411
412 /**************************************************************************
413 *  ShellView_OnCreate()
414 *
415 * NOTES
416 *  internal
417 */   
418 LRESULT ShellView_OnCreate(LPSHELLVIEW this)
419 { TRACE(shell,"%p\n",this);
420
421   if(ShellView_CreateList(this))
422   {  if(ShellView_InitList(this))
423      { ShellView_FillList(this);
424      }
425   }
426
427   return S_OK;
428 }
429 /**************************************************************************
430 *  ShellView_OnSize()
431 */   
432 LRESULT ShellView_OnSize(LPSHELLVIEW this, WORD wWidth, WORD wHeight)
433 {       TRACE(shell,"%p width=%u height=%u\n",this, wWidth,wHeight);
434
435         /*resize the ListView to fit our window*/
436         if(this->hWndList)
437         { MoveWindow32(this->hWndList, 0, 0, wWidth, wHeight, TRUE);
438         }
439
440         return S_OK;
441 }
442 /**************************************************************************
443 * ShellView_BuildFileMenu()
444 */   
445 HMENU32 ShellView_BuildFileMenu(LPSHELLVIEW this)
446 {       CHAR    szText[MAX_PATH];
447         MENUITEMINFO32A mii;
448         int     nTools,i;
449         HMENU32 hSubMenu;
450
451         TRACE(shell,"(%p) semi-stub\n",this);
452
453         hSubMenu = CreatePopupMenu32();
454         if(hSubMenu)
455         { /*get the number of items in our global array*/
456           for(nTools = 0; g_Tools[nTools].idCommand != -1; nTools++){}
457
458           /*add the menu items*/
459           for(i = 0; i < nTools; i++)
460           { strcpy(szText, "dummy BuildFileMenu");
461       
462             ZeroMemory(&mii, sizeof(mii));
463             mii.cbSize = sizeof(mii);
464             mii.fMask = MIIM_TYPE | MIIM_ID | MIIM_STATE;
465
466             if(TBSTYLE_SEP != g_Tools[i].bStyle) /* no seperator*/
467             { mii.fType = MFT_STRING;
468               mii.fState = MFS_ENABLED;
469               mii.dwTypeData = szText;
470               mii.wID = g_Tools[i].idCommand;
471             }
472             else
473             { mii.fType = MFT_SEPARATOR;
474             }
475             /* tack this item onto the end of the menu */
476             InsertMenuItem32A(hSubMenu, (UINT32)-1, TRUE, &mii);
477           }
478         }
479         TRACE(shell,"-- return (menu=0x%x)\n",hSubMenu);
480         return hSubMenu;
481 }
482 /**************************************************************************
483 * ShellView_MergeFileMenu()
484 */   
485 void ShellView_MergeFileMenu(LPSHELLVIEW this, HMENU32 hSubMenu)
486 {       TRACE(shell,"(%p)->(submenu=0x%08x) stub\n",this,hSubMenu);
487
488         if(hSubMenu)
489         { /*insert this item at the beginning of the menu */
490           _InsertMenuItem(hSubMenu, 0, TRUE, 0, MFT_SEPARATOR, NULL, MFS_ENABLED);
491           _InsertMenuItem(hSubMenu, 0, TRUE, IDM_MYFILEITEM, MFT_STRING, "dummy45", MFS_ENABLED);
492
493         }
494         TRACE(shell,"--\n");    
495 }
496
497 /**************************************************************************
498 * ShellView_MergeViewMenu()
499 */   
500
501 void ShellView_MergeViewMenu(LPSHELLVIEW this, HMENU32 hSubMenu)
502 {       MENUITEMINFO32A mii;
503
504         TRACE(shell,"(%p)->(submenu=0x%08x)\n",this,hSubMenu);
505
506         if(hSubMenu)
507         { /*add a separator at the correct position in the menu*/
508           _InsertMenuItem(hSubMenu, FCIDM_MENU_VIEW_SEP_OPTIONS, FALSE, 0, MFT_SEPARATOR, NULL, MFS_ENABLED);
509
510           ZeroMemory(&mii, sizeof(mii));
511           mii.cbSize = sizeof(mii);
512           mii.fMask = MIIM_SUBMENU | MIIM_TYPE | MIIM_DATA;;
513           mii.fType = MFT_STRING;
514           mii.dwTypeData = "View";
515           mii.hSubMenu = LoadMenuIndirect32A(&_Resource_Men_MENU_001_0_data);
516           InsertMenuItem32A(hSubMenu, FCIDM_MENU_VIEW_SEP_OPTIONS, FALSE, &mii);
517         }
518 }
519 /**************************************************************************
520 * ShellView_UpdateMenu()
521 */
522 LRESULT ShellView_UpdateMenu(LPSHELLVIEW this, HMENU32 hMenu)
523 {       TRACE(shell,"(%p)->(menu=0x%08x)\n",this,hMenu);
524         CheckMenuItem32(hMenu, IDM_VIEW_FILES, MF_BYCOMMAND | (g_bViewKeys ? MF_CHECKED: MF_UNCHECKED));
525
526         if(ShellView_CanDoIDockingWindow(this))
527         { EnableMenuItem32(hMenu, IDM_VIEW_IDW, MF_BYCOMMAND | MF_ENABLED);
528           CheckMenuItem32(hMenu, IDM_VIEW_IDW, MF_BYCOMMAND | (g_bShowIDW ? MF_CHECKED: MF_UNCHECKED));
529         }
530         else
531         { EnableMenuItem32(hMenu, IDM_VIEW_IDW, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
532           CheckMenuItem32(hMenu, IDM_VIEW_IDW, MF_BYCOMMAND | MF_UNCHECKED);
533         }
534         return S_OK;
535 }
536
537 /**************************************************************************
538 * ShellView_OnDeactivate()
539 *
540 * NOTES
541 *  internal
542 */   
543 void ShellView_OnDeactivate(LPSHELLVIEW this)
544 { TRACE(shell,"%p\n",this);
545   if(this->uState != SVUIA_DEACTIVATE)
546   { if(this->hMenu)
547     { IShellBrowser_SetMenuSB(this->pShellBrowser,0, 0, 0);
548       IShellBrowser_RemoveMenusSB(this->pShellBrowser,this->hMenu);
549       DestroyMenu32(this->hMenu);
550       this->hMenu = 0;
551       }
552
553    this->uState = SVUIA_DEACTIVATE;
554    }
555 }
556
557 /**************************************************************************
558 * ShellView_OnActivate()
559 */   
560 LRESULT ShellView_OnActivate(LPSHELLVIEW this, UINT32 uState)
561 {       OLEMENUGROUPWIDTHS32   omw = { {0, 0, 0, 0, 0, 0} };
562         MENUITEMINFO32A         mii;
563         CHAR                szText[MAX_PATH];
564
565         TRACE(shell,"%p uState=%x\n",this,uState);    
566
567         /*don't do anything if the state isn't really changing */
568         if(this->uState == uState)
569         { return S_OK;
570         }
571
572         ShellView_OnDeactivate(this);
573
574         /*only do this if we are active */
575         if(uState != SVUIA_DEACTIVATE)
576         { /*merge the menus */
577           this->hMenu = CreateMenu32();
578    
579           if(this->hMenu)
580           { IShellBrowser_InsertMenusSB(this->pShellBrowser, this->hMenu, &omw);
581             TRACE(shell,"-- after fnInsertMenusSB\n");    
582             /*build the top level menu get the menu item's text*/
583             strcpy(szText,"dummy 31");
584       
585             ZeroMemory(&mii, sizeof(mii));
586             mii.cbSize = sizeof(mii);
587             mii.fMask = MIIM_SUBMENU | MIIM_TYPE | MIIM_STATE;
588             mii.fType = MFT_STRING;
589             mii.fState = MFS_ENABLED;
590             mii.dwTypeData = szText;
591             mii.hSubMenu = ShellView_BuildFileMenu(this);
592
593             /*insert our menu into the menu bar*/
594             if(mii.hSubMenu)
595             { InsertMenuItem32A(this->hMenu, FCIDM_MENU_HELP, FALSE, &mii);
596             }
597
598             /*get the view menu so we can merge with it*/
599             ZeroMemory(&mii, sizeof(mii));
600             mii.cbSize = sizeof(mii);
601             mii.fMask = MIIM_SUBMENU;
602       
603             if(GetMenuItemInfo32A(this->hMenu, FCIDM_MENU_VIEW, FALSE, &mii))
604             { ShellView_MergeViewMenu(this, mii.hSubMenu);
605             }
606
607             /*add the items that should only be added if we have the focus*/
608             if(SVUIA_ACTIVATE_FOCUS == uState)
609             { /*get the file menu so we can merge with it */
610               ZeroMemory(&mii, sizeof(mii));
611               mii.cbSize = sizeof(mii);
612               mii.fMask = MIIM_SUBMENU;
613       
614               if(GetMenuItemInfo32A(this->hMenu, FCIDM_MENU_FILE, FALSE, &mii))
615               { ShellView_MergeFileMenu(this, mii.hSubMenu);
616               }
617             }
618           TRACE(shell,"-- before fnSetMenuSB\n");      
619           IShellBrowser_SetMenuSB(this->pShellBrowser, this->hMenu, 0, this->hWnd);
620           }
621         }
622         this->uState = uState;
623         TRACE(shell,"--\n");    
624         return S_OK;
625 }
626
627 /**************************************************************************
628 *  ShellView_OnSetFocus()
629 *
630 * NOTES
631 *  internal
632 */
633 LRESULT ShellView_OnSetFocus(LPSHELLVIEW this)
634 {       TRACE(shell,"%p\n",this);
635         /* Tell the browser one of our windows has received the focus. This should always 
636         be done before merging menus (OnActivate merges the menus) if one of our 
637         windows has the focus.*/
638         IShellBrowser_OnViewWindowActive(this->pShellBrowser,this);
639         ShellView_OnActivate(this, SVUIA_ACTIVATE_FOCUS);
640
641         return 0;
642 }
643
644 /**************************************************************************
645 * ShellView_OnKillFocus()
646 */   
647 LRESULT ShellView_OnKillFocus(LPSHELLVIEW this)
648 {       TRACE(shell,"(%p) stub\n",this);
649         ShellView_OnActivate(this, SVUIA_ACTIVATE_NOFOCUS);
650         return 0;
651 }
652
653 /**************************************************************************
654 * ShellView_AddRemoveDockingWindow()
655 */   
656 BOOL32 ShellView_AddRemoveDockingWindow(LPSHELLVIEW this, BOOL32 bAdd)
657 {       BOOL32  bReturn = FALSE;
658         HRESULT hr;
659         LPSERVICEPROVIDER       pSP;
660         LPDOCKINGWINDOWFRAME    pFrame;
661         
662         WARN(shell,"(%p)->(badd=0x%08x) semi-stub\n",this,bAdd);
663
664         /* get the browser's IServiceProvider */
665         hr = IShellBrowser_QueryInterface(this->pShellBrowser, (REFIID)&IID_IServiceProvider, (LPVOID*)&pSP);
666         if(SUCCEEDED(hr))
667         { /*get the IDockingWindowFrame pointer*/
668           hr = IServiceProvider_QueryService(pSP, (REFGUID)&SID_SShellBrowser, (REFIID)&IID_IDockingWindowFrame, (LPVOID*)&pFrame);
669           if(SUCCEEDED(hr))
670           { if(bAdd)
671             { hr = S_OK;
672               FIXME(shell,"no docking implemented\n");
673 #if 0
674               if(!this->pDockingWindow)
675               { /* create the toolbar object */
676                 this->pDockingWindow = DockingWindow_Constructor(this, this->hWnd);
677               }
678
679               if(this->pDockingWindow)
680               { /*add the toolbar object */
681                 hr = pFrame->lpvtbl->fnAddToolbar(pFrame, (IDockingWindow*)this->pDockingWindow, TOOLBAR_ID, 0);
682
683                 if(SUCCEEDED(hr))
684                 { bReturn = TRUE;
685                 }
686               }
687 #endif
688             }
689             else
690             { FIXME(shell,"no docking implemented\n");
691 #if 0
692               if(this->pDockingWindow)
693               { hr = pFrame->lpvtbl->fnRemoveToolbar(pFrame, (IDockingWindow*)this->pDockingWindow, DWFRF_NORMAL);
694
695                 if(SUCCEEDED(hr))
696                 { /* RemoveToolbar should release the toolbar object which will cause  */
697                   /*it to destroy itself. Our toolbar object is no longer valid at  */
698                   /*this point. */
699             
700                   this->pDockingWindow = NULL;
701                   bReturn = TRUE;
702                 }
703               }
704 #endif
705             }
706             pFrame->lpvtbl->fnRelease(pFrame);
707           }
708           IServiceProvider_Release(pSP);
709         }
710         return bReturn;
711 }
712
713 /**************************************************************************
714 * ShellView_CanDoIDockingWindow()
715 */   
716 BOOL32 ShellView_CanDoIDockingWindow(LPSHELLVIEW this)
717 {       BOOL32 bReturn = FALSE;
718         HRESULT hr;
719         LPSERVICEPROVIDER pSP;
720         LPDOCKINGWINDOWFRAME pFrame;
721         
722         FIXME(shell,"(%p) stub\n",this);
723         
724         /*get the browser's IServiceProvider*/
725         hr = IShellBrowser_QueryInterface(this->pShellBrowser, (REFIID)&IID_IServiceProvider, (LPVOID*)&pSP);
726         if(hr==S_OK)
727         { hr = IServiceProvider_QueryService(pSP, (REFGUID)&SID_SShellBrowser, (REFIID)&IID_IDockingWindowFrame, (LPVOID*)&pFrame);
728           if(SUCCEEDED(hr))
729           { bReturn = TRUE;
730             pFrame->lpvtbl->fnRelease(pFrame);
731           }
732           IServiceProvider_Release(pSP);
733         }
734         return bReturn;
735 }
736
737 /**************************************************************************
738 *  ShellView_UpdateShellSettings()
739 */
740 void ShellView_UpdateShellSettings(LPSHELLVIEW this)
741 {       FIXME(shell,"(%p) stub\n",this);
742         return ;
743 /*
744         SHELLFLAGSTATE       sfs;
745         HINSTANCE            hinstShell32;
746 */
747         /* Since SHGetSettings is not implemented in all versions of the shell, get the 
748         function address manually at run time. This allows the code to run on all 
749         platforms.*/
750 /*
751         ZeroMemory(&sfs, sizeof(sfs));
752 */
753         /* The default, in case any of the following steps fails, is classic Windows 95 
754         style.*/
755 /*
756         sfs.fWin95Classic = TRUE;
757
758         hinstShell32 = LoadLibrary("shell32.dll");
759         if(hinstShell32)
760         { PFNSHGETSETTINGSPROC pfnSHGetSettings;
761
762       pfnSHGetSettings = (PFNSHGETSETTINGSPROC)GetProcAddress(hinstShell32, "SHGetSettings");
763           if(pfnSHGetSettings)
764       { (*pfnSHGetSettings)(&sfs, SSF_DOUBLECLICKINWEBVIEW | SSF_WIN95CLASSIC);
765       }
766           FreeLibrary(hinstShell32);
767         }
768
769         DWORD dwExStyles = 0;
770
771         if(!sfs.fWin95Classic && !sfs.fDoubleClickInWebView)
772           dwExStyles |= LVS_EX_ONECLICKACTIVATE | LVS_EX_TRACKSELECT | LVS_EX_UNDERLINEHOT;
773
774         ListView_SetExtendedListViewStyle(this->hWndList, dwExStyles);
775 */
776 }
777
778 /**************************************************************************
779 *   ShellView_OnSettingChange()
780 */   
781 LRESULT ShellView_OnSettingChange(LPSHELLVIEW this, LPCSTR lpszSection)
782 {       TRACE(shell,"(%p) stub\n",this);
783 /*if(0 == lstrcmpi(lpszSection, "ShellState"))*/
784         { ShellView_UpdateShellSettings(this);
785           return 0;
786         }
787         return 0;
788 }
789 /**************************************************************************
790 * ShellView_OnCommand()
791 */   
792 LRESULT ShellView_OnCommand(LPSHELLVIEW this,DWORD dwCmdID, DWORD dwCmd, HWND32 hwndCmd)
793 {       TRACE(shell,"(%p)->(0x%08lx 0x%08lx 0x%08x) stub\n",this, dwCmdID, dwCmd, hwndCmd);
794         switch(dwCmdID)
795         { case IDM_VIEW_FILES:
796             g_bViewKeys = ! g_bViewKeys;
797             IShellView_Refresh(this);
798             break;
799
800           case IDM_VIEW_IDW:
801             g_bShowIDW = ! g_bShowIDW;
802             ShellView_AddRemoveDockingWindow(this, g_bShowIDW);
803             break;
804    
805           case IDM_MYFILEITEM:
806             MessageBeep32(MB_OK);
807             break;
808
809           case FCIDM_SHVIEW_SMALLICON:
810             this->FolderSettings.ViewMode = FVM_SMALLICON;
811             SetStyle (this, LVS_SMALLICON, LVS_TYPEMASK);
812             break;
813
814           case FCIDM_SHVIEW_BIGICON:
815             this->FolderSettings.ViewMode = FVM_ICON;
816             SetStyle (this, LVS_ICON, LVS_TYPEMASK);
817             break;
818
819           case FCIDM_SHVIEW_LISTVIEW:
820             this->FolderSettings.ViewMode = FVM_LIST;
821             SetStyle (this, LVS_LIST, LVS_TYPEMASK);
822             break;
823
824           case FCIDM_SHVIEW_REPORTVIEW:
825             this->FolderSettings.ViewMode = FVM_DETAILS;
826             SetStyle (this, LVS_REPORT, LVS_TYPEMASK);
827             break;
828
829           default:
830             FIXME(shell,"-- COMMAND unhandled\n");
831         }
832         return 0;
833 }
834
835 /**************************************************************************
836 *   ShellView_GetSelections()
837 *
838 * RETURNS
839 *  number of selected items
840 */   
841 UINT32 ShellView_GetSelections(LPSHELLVIEW this)
842 {       LVITEM32A       lvItem;
843         UINT32  i;
844
845
846         if (this->aSelectedItems)
847         { SHFree(this->aSelectedItems);
848         }
849
850         this->uSelected = ListView_GetSelectedCount(this->hWndList);
851         this->aSelectedItems = (LPITEMIDLIST*)SHAlloc(this->uSelected * sizeof(LPITEMIDLIST));
852
853         TRACE(shell,"selected=%i\n", this->uSelected);
854         
855         if(this->aSelectedItems)
856         { TRACE(shell,"-- Items selected =%u\n", this->uSelected);
857           ZeroMemory(&lvItem, sizeof(lvItem));
858           lvItem.mask = LVIF_STATE | LVIF_PARAM;
859           lvItem.stateMask = LVIS_SELECTED;
860           lvItem.iItem = 0;
861
862           i = 0;
863    
864           while(ListView_GetItem32A(this->hWndList, &lvItem) && (i < this->uSelected))
865           { if(lvItem.state & LVIS_SELECTED)
866             { this->aSelectedItems[i] = (LPITEMIDLIST)lvItem.lParam;
867               i++;
868               TRACE(shell,"-- selected Item found\n");
869             }
870             lvItem.iItem++;
871           }
872         }
873         return this->uSelected;
874
875 }
876 /**************************************************************************
877 *   ShellView_DoContextMenu()
878 */   
879 void ShellView_DoContextMenu(LPSHELLVIEW this, WORD x, WORD y, BOOL32 fDefault)
880 {       UINT32  uCommand;
881         DWORD   wFlags;
882         HMENU32 hMenu;
883         BOOL32  fExplore = FALSE;
884         HWND32  hwndTree = 0;
885         INT32           nMenuIndex;
886         MENUITEMINFO32A mii;
887         LPCONTEXTMENU   pContextMenu = NULL;
888         CMINVOKECOMMANDINFO32  cmi;
889         
890         TRACE(shell,"(%p)->(0x%08x 0x%08x 0x%08x) stub\n",this, x, y, fDefault);
891
892         /* look, what's selected and create a context menu object of it*/
893         if(ShellView_GetSelections(this))
894         { this->pSFParent->lpvtbl->fnGetUIObjectOf( this->pSFParent, this->hWndParent, this->uSelected,
895                                                     this->aSelectedItems, (REFIID)&IID_IContextMenu,
896                                                     NULL, (LPVOID *)&pContextMenu);
897    
898           if(pContextMenu)
899           { TRACE(shell,"-- pContextMenu\n");
900             hMenu = CreatePopupMenu32();
901
902             if( hMenu )
903             { /* See if we are in Explore or Open mode. If the browser's tree
904                  is present, then we are in Explore mode.*/
905         
906               if(SUCCEEDED(IShellBrowser_GetControlWindow(this->pShellBrowser,FCW_TREE, &hwndTree)) && hwndTree)
907               { TRACE(shell,"-- explore mode\n");
908                 fExplore = TRUE;
909               }
910
911               wFlags = CMF_NORMAL | (this->uSelected != 1 ? 0 : CMF_CANRENAME) | (fExplore ? CMF_EXPLORE : 0);
912
913               if (SUCCEEDED(pContextMenu->lpvtbl->fnQueryContextMenu( pContextMenu, hMenu, 0, MENU_OFFSET, MENU_MAX, wFlags )))
914               { if( fDefault )
915                 { TRACE(shell,"-- get menu default command\n");
916
917                   uCommand = nMenuIndex = 0;
918                   ZeroMemory(&mii, sizeof(mii));
919                   mii.cbSize = sizeof(mii);
920                   mii.fMask = MIIM_STATE | MIIM_ID;
921
922                   while(GetMenuItemInfo32A(hMenu, nMenuIndex, TRUE, &mii))      /*find the default item in the menu*/
923                   { if(mii.fState & MFS_DEFAULT)
924                     { uCommand = mii.wID;
925                       break;
926                     }
927                     nMenuIndex++;
928                   }
929                 }
930                 else
931                 { TRACE(shell,"-- track popup\n");
932                   uCommand = TrackPopupMenu32( hMenu,TPM_LEFTALIGN | TPM_RETURNCMD,x,y,0,this->hWnd,NULL);
933                 }               
934          
935                 if(uCommand > 0)
936                 { TRACE(shell,"-- uCommand=%u\n", uCommand);
937                   if (IsInCommDlg(this) && (((uCommand-MENU_OFFSET)==IDM_EXPLORE) || ((uCommand-MENU_OFFSET)==IDM_OPEN)))
938                   { TRACE(shell,"-- dlg: OnDefaultCommand\n");
939                     OnDefaultCommand(this);
940                   }
941                   else
942                   { TRACE(shell,"-- explore -- invoke command\n");
943                       ZeroMemory(&cmi, sizeof(cmi));
944                       cmi.cbSize = sizeof(cmi);
945                       cmi.hwnd = this->hWndParent;
946                       cmi.lpVerb = (LPCSTR)MAKEINTRESOURCE32A(uCommand - MENU_OFFSET);
947                       pContextMenu->lpvtbl->fnInvokeCommand(pContextMenu, &cmi);
948                   }
949                 }
950                 DestroyMenu32(hMenu);
951               }
952             }
953             if (pContextMenu)
954               pContextMenu->lpvtbl->fnRelease(pContextMenu);
955           }
956         }
957         else    /* background context menu */
958         { hMenu = LoadMenuIndirect32A(&_Resource_Men_MENU_002_0_data);
959           uCommand = TrackPopupMenu32( GetSubMenu32(hMenu,0),TPM_LEFTALIGN | TPM_RETURNCMD,x,y,0,this->hWnd,NULL);
960           ShellView_OnCommand(this, uCommand, 0,0);
961           DestroyMenu32(hMenu);
962         }
963 }
964
965 /**************************************************************************
966 * ShellView_OnNotify()
967 */
968    
969 LRESULT ShellView_OnNotify(LPSHELLVIEW this, UINT32 CtlID, LPNMHDR lpnmh)
970 {       NM_LISTVIEW *lpnmlv = (NM_LISTVIEW*)lpnmh;
971         NMLVDISPINFO32A *lpdi = (NMLVDISPINFO32A *)lpnmh;
972         LPITEMIDLIST pidl;
973         DWORD dwCursor; 
974         STRRET   str;  
975         UINT32  uFlags;
976         IExtractIcon *pei;
977   
978         TRACE(shell,"%p CtlID=%u lpnmh->code=%x\n",this,CtlID,lpnmh->code);
979   
980         switch(lpnmh->code)
981         { case NM_SETFOCUS:
982             TRACE(shell,"-- NM_SETFOCUS %p\n",this);
983             ShellView_OnSetFocus(this);
984             break;
985
986           case NM_KILLFOCUS:
987             TRACE(shell,"-- NM_KILLFOCUS %p\n",this);
988             ShellView_OnDeactivate(this);
989             break;
990
991           case HDN_ENDTRACK32A:
992             TRACE(shell,"-- HDN_ENDTRACK32A %p\n",this);
993             /*nColumn1 = ListView_GetColumnWidth(this->hWndList, 0);
994             nColumn2 = ListView_GetColumnWidth(this->hWndList, 1);*/
995             break;
996    
997           case LVN_DELETEITEM:
998             TRACE(shell,"-- LVN_DELETEITEM %p\n",this);
999             SHFree((LPITEMIDLIST)lpnmlv->lParam);     /*delete the pidl because we made a copy of it*/
1000             break;
1001    
1002           case NM_DBLCLK:
1003           case NM_RETURN:
1004             TRACE(shell,"-- NM_RETURN|NM_DBLCLK ignored, waiting for LVN_ITEMACTIVATE\n");
1005             break;
1006
1007           case LVN_ITEMACTIVATE:
1008             TRACE(shell,"-- LVN_ITEMACTIVATE %p\n",this);
1009             OnStateChange(this, CDBOSC_SELCHANGE);  /* the browser will get the IDataObject now */
1010             ShellView_DoContextMenu(this, 0, 0, TRUE);
1011             break;
1012    
1013           case NM_RCLICK:
1014             TRACE(shell,"-- NM_RCLICK %p\n",this);
1015             dwCursor = GetMessagePos();
1016             ShellView_DoContextMenu(this, LOWORD(dwCursor), HIWORD(dwCursor), FALSE);
1017             break;
1018
1019           case LVN_GETDISPINFO32A:
1020             TRACE(shell,"-- LVN_GETDISPINFO32A %p\n",this);
1021             pidl = (LPITEMIDLIST)lpdi->item.lParam;
1022
1023
1024             if(lpdi->item.iSubItem)               /*is the sub-item information being requested?*/
1025             { if(lpdi->item.mask & LVIF_TEXT)    /*is the text being requested?*/
1026               { if(_ILIsValue(pidl))    /*is this a value or a folder?*/
1027                 { switch (lpdi->item.iSubItem)
1028                   { case 1:     /* size */
1029                       _ILGetFileSize (pidl, lpdi->item.pszText, lpdi->item.cchTextMax);
1030                       break;
1031                     case 2:     /* extension */
1032                       { char sTemp[64];
1033                         if (_ILGetExtension (pidl, sTemp, 64))
1034                         { if (!( HCR_MapTypeToValue(sTemp, sTemp, 64)
1035                                  && HCR_MapTypeToValue(sTemp, lpdi->item.pszText, lpdi->item.cchTextMax )))
1036                           { strncpy (lpdi->item.pszText, sTemp, lpdi->item.cchTextMax);
1037                             strncat (lpdi->item.pszText, "-file", lpdi->item.cchTextMax);
1038                           }
1039                         }
1040                         else    /* no extension found */
1041                         { lpdi->item.pszText[0]=0x00;
1042                         }    
1043                       }
1044                       break;
1045                     case 3:     /* date */
1046                       _ILGetFileDate (pidl, lpdi->item.pszText, lpdi->item.cchTextMax);
1047                       break;
1048                   }
1049                 }
1050                 else  /*its a folder*/
1051                 { switch (lpdi->item.iSubItem)
1052                   { case 1:
1053                       strcpy(lpdi->item.pszText, "");
1054                       break;
1055                     case 2:
1056                       strncpy (lpdi->item.pszText, "Folder", lpdi->item.cchTextMax);
1057                       break;
1058                     case 3:  
1059                       _ILGetFileDate (pidl, lpdi->item.pszText, lpdi->item.cchTextMax);
1060                       break;
1061                   }
1062                 }
1063                 TRACE(shell,"-- text=%s\n",lpdi->item.pszText);         
1064               }
1065             }
1066             else           /*the item text is being requested*/
1067             { if(lpdi->item.mask & LVIF_TEXT)      /*is the text being requested?*/
1068               { if(SUCCEEDED(this->pSFParent->lpvtbl->fnGetDisplayNameOf(this->pSFParent,pidl, SHGDN_NORMAL | SHGDN_INFOLDER, &str)))
1069                 { if(STRRET_WSTR == str.uType)
1070                   { WideCharToLocal32(lpdi->item.pszText, str.u.pOleStr, lpdi->item.cchTextMax);
1071                     SHFree(str.u.pOleStr);
1072                   }
1073                   else if(STRRET_CSTRA == str.uType)
1074                   { strncpy(lpdi->item.pszText, str.u.cStr, lpdi->item.cchTextMax);
1075                   }
1076                   else
1077                   { FIXME(shell,"type wrong\n");
1078                   }
1079                 }
1080                 TRACE(shell,"-- text=%s\n",lpdi->item.pszText);
1081               }
1082
1083               if(lpdi->item.mask & LVIF_IMAGE)          /*is the image being requested?*/
1084               { if(SUCCEEDED(this->pSFParent->lpvtbl->fnGetUIObjectOf(this->pSFParent,this->hWnd,1,
1085                                 (LPCITEMIDLIST*)&pidl, (REFIID)&IID_IExtractIcon, NULL, (LPVOID*)&pei)))
1086                 { pei->lpvtbl->fnGetIconLocation(pei, GIL_FORSHELL, NULL, 0, &lpdi->item.iImage, &uFlags);
1087                   pei->lpvtbl->fnRelease(pei);
1088                   TRACE(shell,"-- image=%x\n",lpdi->item.iImage);
1089                 }
1090               }
1091             }
1092             break;
1093
1094           case NM_CLICK:
1095             WARN(shell,"-- NM_CLICK %p\n",this);
1096             break;
1097
1098           case LVN_ITEMCHANGING:
1099             WARN(shell,"-- LVN_ITEMCHANGING %p\n",this);
1100             break;
1101
1102           case LVN_ITEMCHANGED:
1103             TRACE(shell,"-- LVN_ITEMCHANGED %p\n",this);
1104             ShellView_GetSelections(this);
1105             OnStateChange(this, CDBOSC_SELCHANGE);  /* the browser will get the IDataObject now */
1106             break;
1107
1108           case LVN_DELETEALLITEMS:
1109             WARN(shell,"-- LVN_DELETEALLITEMS %p\n",this);
1110             break;
1111
1112           case LVN_INSERTITEM:
1113             WARN(shell,"-- LVN_INSERTITEM %p\n",this);
1114             break;
1115
1116           case LVN_BEGINDRAG:
1117             WARN(shell,"-- LVN_BEGINDRAG %p\n",this);
1118             break;
1119
1120           case NM_CUSTOMDRAW:
1121             WARN(shell,"NM_CUSTOMDRAW %p\n",this);
1122             break;
1123
1124           default:
1125             FIXME (shell,"-- WM_NOTIFY unhandled\n");
1126             break;;
1127         }
1128         return 0;
1129 }
1130
1131 /**************************************************************************
1132 *  ShellView_WndProc
1133 */
1134
1135 LRESULT CALLBACK ShellView_WndProc(HWND32 hWnd, UINT32 uMessage, WPARAM32 wParam, LPARAM lParam)
1136 { LPSHELLVIEW pThis = (LPSHELLVIEW)GetWindowLong32A(hWnd, GWL_USERDATA);
1137   LPCREATESTRUCT32A lpcs;
1138   DWORD dwCursor;
1139   
1140   TRACE(shell,"(hwnd=%x msg=%x wparm=%x lparm=%lx)\n",hWnd, uMessage, wParam, lParam);
1141     
1142   switch (uMessage)
1143   { case WM_NCCREATE:
1144       { TRACE(shell,"-- WM_NCCREATE\n");
1145         lpcs = (LPCREATESTRUCT32A)lParam;
1146         pThis = (LPSHELLVIEW)(lpcs->lpCreateParams);
1147         SetWindowLong32A(hWnd, GWL_USERDATA, (LONG)pThis);
1148         pThis->hWnd = hWnd;        /*set the window handle*/
1149       }
1150       break;
1151    
1152    case WM_SIZE:
1153       TRACE(shell,"-- WM_SIZE\n");
1154       return ShellView_OnSize(pThis,LOWORD(lParam), HIWORD(lParam));
1155    
1156    case WM_SETFOCUS:
1157       TRACE(shell,"-- WM_SETFOCUS\n");   
1158       return ShellView_OnSetFocus(pThis);
1159  
1160    case WM_KILLFOCUS:
1161       TRACE(shell,"-- WM_KILLFOCUS\n");
1162           return ShellView_OnKillFocus(pThis);
1163
1164    case WM_CREATE:
1165       TRACE(shell,"-- WM_CREATE\n");
1166       return ShellView_OnCreate(pThis);
1167
1168    case WM_SHOWWINDOW:
1169       TRACE(shell,"-- WM_SHOWWINDOW\n");
1170       UpdateWindow32(pThis->hWndList);
1171       break;
1172
1173    case WM_ACTIVATE:
1174       TRACE(shell,"-- WM_ACTIVATE\n");
1175       return ShellView_OnActivate(pThis, SVUIA_ACTIVATE_FOCUS);
1176    
1177    case WM_COMMAND:
1178       TRACE(shell,"-- WM_COMMAND\n");
1179       return ShellView_OnCommand(pThis, GET_WM_COMMAND_ID(wParam, lParam), 
1180                                   GET_WM_COMMAND_CMD(wParam, lParam), 
1181                                   GET_WM_COMMAND_HWND(wParam, lParam));
1182    
1183    case WM_INITMENUPOPUP:
1184       TRACE(shell,"-- WM_INITMENUPOPUP\n");
1185       return ShellView_UpdateMenu(pThis, (HMENU32)wParam);
1186    
1187    case WM_NOTIFY:
1188       TRACE(shell,"-- WM_NOTIFY\n");
1189       return ShellView_OnNotify(pThis,(UINT32)wParam, (LPNMHDR)lParam);
1190
1191    case WM_SETTINGCHANGE:
1192       TRACE(shell,"-- WM_SETTINGCHANGE\n");
1193       return ShellView_OnSettingChange(pThis,(LPCSTR)lParam);
1194
1195    case WM_PARENTNOTIFY:
1196       TRACE(shell,"-- WM_PARENTNOTIFY\n");
1197       if ( LOWORD(wParam) == WM_RBUTTONDOWN ) /* fixme: should not be handled here*/
1198       { dwCursor = GetMessagePos();
1199         ShellView_DoContextMenu(pThis, LOWORD(dwCursor), HIWORD(dwCursor), FALSE);
1200         return TRUE;
1201       }
1202       break;
1203
1204 /* -------------*/
1205    case WM_MOVE:
1206       WARN(shell,"-- WM_MOVE\n");   
1207       break;
1208    
1209    case WM_ACTIVATEAPP:
1210       WARN(shell,"-- WM_ACTIVATEAPP\n");
1211       break;
1212
1213    case WM_NOTIFYFORMAT:
1214       WARN(shell,"-- WM_NOTIFYFORMAT\n");
1215       break;
1216
1217    case WM_NCPAINT:
1218       WARN(shell,"-- WM_NCPAINT\n");
1219       break;
1220
1221    case WM_ERASEBKGND:
1222       WARN(shell,"-- WM_ERASEBKGND\n");
1223       break;
1224
1225    case WM_PAINT:
1226       WARN(shell,"-- WM_PAINT\n");
1227       break;
1228
1229    case WM_NCCALCSIZE:
1230       WARN(shell,"-- WM_NCCALCSIZE\n");
1231       break;
1232
1233    case WM_WINDOWPOSCHANGING:
1234       WARN(shell,"-- WM_WINDOWPOSCHANGING\n");
1235       break;
1236
1237    case WM_WINDOWPOSCHANGED:
1238       WARN(shell,"-- WM_WINDOWPOSCHANGED\n");
1239       break;
1240
1241    case WM_MOUSEACTIVATE:
1242       WARN(shell,"-- WM_MOUSEACTIVATE\n");
1243       break;
1244
1245    case WM_SETCURSOR:
1246       WARN(shell,"-- WM_SETCURSOR\n");
1247       break;
1248
1249    case WM_DESTROY:
1250       WARN(shell,"-- WM_DESTROY\n");
1251       break;
1252
1253    case WM_NCDESTROY:
1254       WARN(shell,"-- WM_NCDESTROY\n");
1255       break;
1256
1257    case WM_CONTEXTMENU:
1258       WARN(shell,"-- WM_CONTEXTMENU\n");
1259       break;
1260
1261    case WM_MENUSELECT:
1262       WARN(shell,"-- WM_MENUSELECT\n");
1263       break;
1264
1265    case WM_CAPTURECHANGED:
1266       WARN(shell,"-- WM_CAPTURECHANGED\n");
1267       break;
1268
1269    case WM_CHILDACTIVATE:
1270       WARN(shell,"-- WM_CHILDACTIVATE\n");
1271       break;
1272
1273    case WM_ENTERIDLE:
1274       WARN(shell,"-- WM_ENTERIDLE\n");
1275       break;
1276
1277    default:
1278       FIXME(shell,"-- MESSAGE unhandled\n");
1279       break;
1280   }
1281   return DefWindowProc32A (hWnd, uMessage, wParam, lParam);
1282 }
1283 /**************************************************************************
1284 *
1285 *
1286 *  The INTERFACE of the IShellView object
1287 *
1288 *
1289 ***************************************************************************
1290 *  IShellView_QueryInterface
1291 */
1292 static HRESULT WINAPI IShellView_QueryInterface(LPSHELLVIEW this,REFIID riid, LPVOID *ppvObj)
1293 { char    xriid[50];
1294   WINE_StringFromCLSID((LPCLSID)riid,xriid);
1295   TRACE(shell,"(%p)->(\n\tIID:\t%s,%p)\n",this,xriid,ppvObj);
1296
1297   *ppvObj = NULL;
1298
1299   if(IsEqualIID(riid, &IID_IUnknown))          /*IUnknown*/
1300   { *ppvObj = this; 
1301   }
1302   else if(IsEqualIID(riid, &IID_IShellView))  /*IShellView*/
1303   { *ppvObj = (IShellView*)this;
1304   }   
1305
1306   if(*ppvObj)
1307   { (*(LPSHELLVIEW*)ppvObj)->lpvtbl->fnAddRef(this);      
1308     TRACE(shell,"-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
1309     return S_OK;
1310   }
1311   TRACE(shell,"-- Interface: E_NOINTERFACE\n");
1312   return E_NOINTERFACE;
1313 }   
1314 /**************************************************************************
1315 *  IShellView::AddRef
1316 */
1317 static ULONG WINAPI IShellView_AddRef(LPSHELLVIEW this)
1318 {       TRACE(shell,"(%p)->(count=%lu)\n",this,(this->ref)+1);
1319
1320         shell32_ObjCount++;
1321         return ++(this->ref);
1322 }
1323 /**************************************************************************
1324 *  IShellView_Release
1325 */
1326 static ULONG WINAPI IShellView_Release(LPSHELLVIEW this)
1327 {       TRACE(shell,"(%p)->()\n",this);
1328
1329         shell32_ObjCount--;
1330         if (!--(this->ref)) 
1331         { TRACE(shell," destroying IShellView(%p)\n",this);
1332
1333           if(this->pSFParent)
1334             this->pSFParent->lpvtbl->fnRelease(this->pSFParent);
1335
1336           if (this->aSelectedItems)
1337             SHFree(this->aSelectedItems);
1338
1339           if (this->pCommDlgBrowser)
1340             this->pCommDlgBrowser->lpvtbl->fnRelease(this->pCommDlgBrowser);
1341
1342           HeapFree(GetProcessHeap(),0,this);
1343           return 0;
1344         }
1345         return this->ref;
1346 }
1347 /**************************************************************************
1348 *  ShellView_GetWindow
1349 */
1350 static HRESULT WINAPI IShellView_GetWindow(LPSHELLVIEW this,HWND32 * phWnd)
1351 {       TRACE(shell,"(%p)\n",this);
1352         *phWnd = this->hWnd;
1353
1354         return S_OK;
1355 }
1356 static HRESULT WINAPI IShellView_ContextSensitiveHelp(LPSHELLVIEW this,BOOL32 fEnterMode)
1357 { FIXME(shell,"(%p) stub\n",this);
1358   return E_NOTIMPL;
1359 }
1360 /**************************************************************************
1361 * IShellView_TranslateAccelerator
1362 *
1363 * FIXME:
1364 *  use the accel functions
1365 */
1366 static HRESULT WINAPI IShellView_TranslateAccelerator(LPSHELLVIEW this,LPMSG32 lpmsg)
1367 {       FIXME(shell,"(%p)->(%p: hwnd=%x msg=%x lp=%lx wp=%x) stub\n",this,lpmsg, lpmsg->hwnd, lpmsg->message, lpmsg->lParam, lpmsg->wParam);
1368
1369         
1370         switch (lpmsg->message)
1371         { case WM_KEYDOWN:      TRACE(shell,"-- key=0x04%x",lpmsg->wParam) ;
1372         }
1373         return S_FALSE;
1374 }
1375 static HRESULT WINAPI IShellView_EnableModeless(LPSHELLVIEW this,BOOL32 fEnable)
1376 { FIXME(shell,"(%p) stub\n",this);
1377   return E_NOTIMPL;
1378 }
1379 static HRESULT WINAPI IShellView_UIActivate(LPSHELLVIEW this,UINT32 uState)
1380 {       CHAR    szName[MAX_PATH];
1381         LRESULT lResult;
1382         int     nPartArray[1] = {-1};
1383
1384         TRACE(shell,"(%p)->(state=%x) stub\n",this, uState);
1385         /*don't do anything if the state isn't really changing*/
1386         if(this->uState == uState)
1387         { return S_OK;
1388         }
1389
1390         /*OnActivate handles the menu merging and internal state*/
1391         ShellView_OnActivate(this, uState);
1392
1393         /*remove the docking window*/
1394         if(g_bShowIDW)
1395         { ShellView_AddRemoveDockingWindow(this, FALSE);
1396         }
1397
1398         /*only do this if we are active*/
1399         if(uState != SVUIA_DEACTIVATE)
1400         { /*update the status bar */
1401            strcpy(szName, "dummy32");
1402    
1403           this->pSFParent->lpvtbl->fnGetFolderPath( this->pSFParent,
1404                                                     szName + strlen(szName),
1405                                                     sizeof(szName) - strlen(szName));
1406
1407           /* set the number of parts */
1408           IShellBrowser_SendControlMsg(this->pShellBrowser, FCW_STATUS, SB_SETPARTS, 1,
1409                                                         (LPARAM)nPartArray, &lResult);
1410
1411           /* set the text for the parts */
1412           IShellBrowser_SendControlMsg(this->pShellBrowser, FCW_STATUS, SB_SETTEXT32A,
1413                                                         0, (LPARAM)szName, &lResult);
1414
1415           /*add the docking window if necessary */
1416           if(g_bShowIDW)
1417           { ShellView_AddRemoveDockingWindow(this, TRUE);
1418           }
1419         }
1420         return S_OK;
1421 }
1422 static HRESULT WINAPI IShellView_Refresh(LPSHELLVIEW this)
1423 {       TRACE(shell,"(%p)\n",this);
1424
1425         ListView_DeleteAllItems(this->hWndList);
1426         ShellView_FillList(this);
1427
1428         return S_OK;
1429 }
1430 static HRESULT WINAPI IShellView_CreateViewWindow(LPSHELLVIEW this, IShellView *lpPrevView,
1431                      LPCFOLDERSETTINGS lpfs, IShellBrowser * psb, RECT32 * prcView, HWND32  *phWnd)
1432 {       WNDCLASS32A wc;
1433 /*      LRESULT dwResult;*/
1434         *phWnd = 0;
1435
1436         
1437         TRACE(shell,"(%p)->(shlview=%p set=%p shlbrs=%p rec=%p hwnd=%p) incomplete\n",this, lpPrevView,lpfs, psb, prcView, phWnd);
1438         TRACE(shell,"-- 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);
1439
1440         /*set up the member variables*/
1441         this->pShellBrowser = psb;
1442         this->FolderSettings = *lpfs;
1443
1444         /*get our parent window*/
1445         IShellBrowser_AddRef(this->pShellBrowser);
1446         IShellBrowser_GetWindow(this->pShellBrowser, &(this->hWndParent));
1447
1448         /* try to get the ICommDlgBrowserInterface, adds a reference !!! */
1449         this->pCommDlgBrowser=NULL;
1450         if ( SUCCEEDED (IShellBrowser_QueryInterface( this->pShellBrowser, 
1451                         (REFIID)&IID_ICommDlgBrowser, (LPVOID*) &this->pCommDlgBrowser)))
1452         { TRACE(shell,"-- CommDlgBrowser\n");
1453         }
1454            
1455         /*if our window class has not been registered, then do so*/
1456         if(!GetClassInfo32A(shell32_hInstance, SV_CLASS_NAME, &wc))
1457         { ZeroMemory(&wc, sizeof(wc));
1458           wc.style          = CS_HREDRAW | CS_VREDRAW;
1459           wc.lpfnWndProc    = (WNDPROC32) ShellView_WndProc;
1460           wc.cbClsExtra     = 0;
1461           wc.cbWndExtra     = 0;
1462           wc.hInstance      = shell32_hInstance;
1463           wc.hIcon          = 0;
1464           wc.hCursor        = LoadCursor32A (0, IDC_ARROW32A);
1465           wc.hbrBackground  = (HBRUSH32) (COLOR_WINDOW + 1);
1466           wc.lpszMenuName   = NULL;
1467           wc.lpszClassName  = SV_CLASS_NAME;
1468    
1469           if(!RegisterClass32A(&wc))
1470             return E_FAIL;
1471         }
1472
1473         *phWnd = CreateWindowEx32A(0, SV_CLASS_NAME, NULL, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS,
1474                            prcView->left, prcView->top, prcView->right - prcView->left, prcView->bottom - prcView->top,
1475                            this->hWndParent, 0, shell32_hInstance, (LPVOID)this);
1476                            
1477         MergeToolBar(this);
1478         
1479         if(!*phWnd)
1480           return E_FAIL;
1481
1482         return S_OK;
1483 }
1484
1485 static HRESULT WINAPI IShellView_DestroyViewWindow(LPSHELLVIEW this)
1486 {       TRACE(shell,"(%p)\n",this);
1487
1488         /*Make absolutely sure all our UI is cleaned up.*/
1489         IShellView_UIActivate(this, SVUIA_DEACTIVATE);
1490         if(this->hMenu)
1491         { DestroyMenu32(this->hMenu);
1492         }
1493         DestroyWindow32(this->hWnd);
1494         IShellBrowser_Release(this->pShellBrowser);
1495         return S_OK;
1496 }
1497 static HRESULT WINAPI IShellView_GetCurrentInfo(LPSHELLVIEW this, LPFOLDERSETTINGS lpfs)
1498 {       TRACE(shell,"(%p)->(%p) vmode=%x flags=%x\n",this, lpfs, 
1499                 this->FolderSettings.ViewMode, this->FolderSettings.fFlags);
1500   
1501         if (lpfs)
1502         { *lpfs = this->FolderSettings;
1503           return NOERROR;
1504         }
1505         else
1506           return E_INVALIDARG;
1507 }
1508 static HRESULT WINAPI IShellView_AddPropertySheetPages(LPSHELLVIEW this, DWORD dwReserved,LPFNADDPROPSHEETPAGE lpfn, LPARAM lparam)
1509 { FIXME(shell,"(%p) stub\n",this);
1510   return E_NOTIMPL;
1511 }
1512 static HRESULT WINAPI IShellView_SaveViewState(LPSHELLVIEW this)
1513 { FIXME(shell,"(%p) stub\n",this);
1514   return S_OK;
1515 }
1516 static HRESULT WINAPI IShellView_SelectItem(LPSHELLVIEW this, LPCITEMIDLIST pidlItem, UINT32 uFlags)
1517 { FIXME(shell,"(%p)->(pidl=%p, 0x%08x) stub\n",this, pidlItem, uFlags);
1518   return E_NOTIMPL;
1519 }
1520 static HRESULT WINAPI IShellView_GetItemObject(LPSHELLVIEW this, UINT32 uItem, REFIID riid, LPVOID *ppvOut)
1521 {       LPUNKNOWN       pObj = NULL; 
1522         char    xriid[50];
1523         
1524         WINE_StringFromCLSID((LPCLSID)riid,xriid);
1525         TRACE(shell,"(%p)->(uItem=0x%08x,\n\tIID=%s, ppv=%p)\n",this, uItem, xriid, ppvOut);
1526
1527         *ppvOut = NULL;
1528         if(IsEqualIID(riid, &IID_IContextMenu))
1529         { ShellView_GetSelections(this);
1530           pObj =(LPUNKNOWN)IContextMenu_Constructor(this->pSFParent,this->aSelectedItems,this->uSelected);      
1531         }
1532         else if (IsEqualIID(riid, &IID_IDataObject))
1533         { ShellView_GetSelections(this);
1534           pObj =(LPUNKNOWN)IDataObject_Constructor(this->hWndParent, this->pSFParent,this->aSelectedItems,this->uSelected);
1535         }
1536
1537         TRACE(shell,"-- (%p)->(interface=%p)\n",this, ppvOut);
1538
1539         if(!pObj)
1540           return E_OUTOFMEMORY;
1541         *ppvOut = pObj;
1542         return S_OK;
1543 }