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