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