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