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