- adjusted printing of refcounts to be equal
[wine/wine-kai.git] / dlls / shell32 / shlview.c
blob3827ac91804fca235eb01431097758c5b729b4eb
1 /*
2 * ShellView
4 * Copyright 1998 <juergen.schmied@metronet.de>
6 * FIXME: when the ShellView_WndProc gets a WM_NCDESTROY should we do a
7 * Release() ???
9 */
11 #include <stdlib.h>
12 #include <string.h>
14 #include "servprov.h"
15 #include "wine/obj_base.h"
16 #include "wine/obj_shellfolder.h"
17 #include "wine/obj_shellview.h"
18 #include "wine/obj_commdlgbrowser.h"
19 #include "wine/obj_shellbrowser.h"
20 #include "wine/obj_dockingwindowframe.h"
21 #include "wine/obj_extracticon.h"
23 #include "shresdef.h"
24 #include "spy.h"
25 #include "debug.h"
26 #include "winerror.h"
28 #include "pidl.h"
29 #include "shell32_main.h"
31 typedef struct
32 { ICOM_VTABLE(IShellView)* lpvtbl;
33 DWORD ref;
34 IShellFolder* pSFParent;
35 IShellBrowser* pShellBrowser;
36 ICommDlgBrowser* pCommDlgBrowser;
37 HWND hWnd;
38 HWND hWndList;
39 HWND hWndParent;
40 FOLDERSETTINGS FolderSettings;
41 HMENU hMenu;
42 UINT uState;
43 UINT uSelected;
44 LPITEMIDLIST *aSelectedItems;
45 } IShellViewImpl;
47 static struct ICOM_VTABLE(IShellView) svvt;
49 /***********************************************************************
50 * IShellView implementation
53 static HRESULT WINAPI IShellView_QueryInterface(LPSHELLVIEW,REFIID, LPVOID *);
54 static ULONG WINAPI IShellView_AddRef(LPSHELLVIEW) ;
55 static ULONG WINAPI IShellView_Release(LPSHELLVIEW);
57 /* IOleWindow methods */
59 static HRESULT WINAPI IShellView_GetWindow(LPSHELLVIEW,HWND * lphwnd);
60 static HRESULT WINAPI IShellView_ContextSensitiveHelp(LPSHELLVIEW,BOOL fEnterMode);
62 /* IShellView methods */
64 static HRESULT WINAPI IShellView_TranslateAccelerator(LPSHELLVIEW,LPMSG lpmsg);
65 static HRESULT WINAPI IShellView_EnableModeless(LPSHELLVIEW,BOOL fEnable);
66 static HRESULT WINAPI IShellView_UIActivate(LPSHELLVIEW,UINT uState);
67 static HRESULT WINAPI IShellView_Refresh(LPSHELLVIEW);
68 static HRESULT WINAPI IShellView_CreateViewWindow(LPSHELLVIEW, IShellView *lpPrevView,LPCFOLDERSETTINGS lpfs, IShellBrowser * psb,RECT * prcView, HWND *phWnd);
69 static HRESULT WINAPI IShellView_DestroyViewWindow(LPSHELLVIEW);
70 static HRESULT WINAPI IShellView_GetCurrentInfo(LPSHELLVIEW, LPFOLDERSETTINGS lpfs);
71 static HRESULT WINAPI IShellView_AddPropertySheetPages(LPSHELLVIEW, DWORD dwReserved,LPFNADDPROPSHEETPAGE lpfn, LPARAM lparam);
72 static HRESULT WINAPI IShellView_SaveViewState(LPSHELLVIEW);
73 static HRESULT WINAPI IShellView_SelectItem(LPSHELLVIEW, LPCITEMIDLIST pidlItem, UINT uFlags);
74 static HRESULT WINAPI IShellView_GetItemObject(LPSHELLVIEW, UINT uItem, REFIID riid,LPVOID *ppv);
76 static BOOL ShellView_CanDoIDockingWindow(LPSHELLVIEW);
78 /*menu items */
79 #define IDM_VIEW_FILES (FCIDM_SHVIEWFIRST + 0x500)
80 #define IDM_VIEW_IDW (FCIDM_SHVIEWFIRST + 0x501)
81 #define IDM_MYFILEITEM (FCIDM_SHVIEWFIRST + 0x502)
83 #define ID_LISTVIEW 2000
85 #define MENU_OFFSET 1
86 #define MENU_MAX 100
88 #define TOOLBAR_ID (L"SHELLDLL_DefView")
89 /*windowsx.h */
90 #define GET_WM_COMMAND_ID(wp, lp) LOWORD(wp)
91 #define GET_WM_COMMAND_HWND(wp, lp) (HWND)(lp)
92 #define GET_WM_COMMAND_CMD(wp, lp) HIWORD(wp)
93 /* winuser.h */
94 #define WM_SETTINGCHANGE WM_WININICHANGE
95 extern void WINAPI _InsertMenuItem (HMENU hmenu, UINT indexMenu, BOOL fByPosition,
96 UINT wID, UINT fType, LPSTR dwTypeData, UINT fState);
98 typedef struct
99 { int idCommand;
100 int iImage;
101 int idButtonString;
102 int idMenuString;
103 int nStringOffset;
104 BYTE bState;
105 BYTE bStyle;
106 } MYTOOLINFO, *LPMYTOOLINFO;
108 extern LPCVOID _Resource_Men_MENU_001_0_data;
109 extern LPCVOID _Resource_Men_MENU_002_0_data;
111 MYTOOLINFO g_Tools[] =
112 { {IDM_VIEW_FILES, 0, IDS_TB_VIEW_FILES, IDS_MI_VIEW_FILES, 0, TBSTATE_ENABLED, TBSTYLE_BUTTON},
113 {-1, 0, 0, 0, 0, 0, 0}
115 BOOL g_bViewKeys;
116 BOOL g_bShowIDW;
118 typedef void (CALLBACK *PFNSHGETSETTINGSPROC)(LPSHELLFLAGSTATE lpsfs, DWORD dwMask);
120 /**************************************************************************
121 * IShellView_Constructor
123 IShellView * IShellView_Constructor( IShellFolder * pFolder, LPCITEMIDLIST pidl)
124 { IShellViewImpl * sv;
125 sv=(IShellViewImpl*)HeapAlloc(GetProcessHeap(),0,sizeof(IShellViewImpl));
126 sv->ref=1;
127 sv->lpvtbl=&svvt;
129 sv->hMenu = 0;
130 sv->pSFParent = pFolder;
131 sv->uSelected = 0;
132 sv->aSelectedItems = NULL;
134 if(pFolder)
135 IShellFolder_AddRef(pFolder);
137 TRACE(shell,"(%p)->(%p pidl=%p)\n",sv, pFolder, pidl);
138 shell32_ObjCount++;
139 return (IShellView *) sv;
141 /**************************************************************************
142 * helperfunctions for communication with ICommDlgBrowser
145 static BOOL IsInCommDlg(IShellViewImpl * This)
146 { return(This->pCommDlgBrowser != NULL);
148 static HRESULT IncludeObject(IShellViewImpl * This, LPCITEMIDLIST pidl)
150 if ( IsInCommDlg(This) )
151 { TRACE(shell,"ICommDlgBrowser::IncludeObject pidl=%p\n", pidl);
152 return (ICommDlgBrowser_IncludeObject(This->pCommDlgBrowser, (IShellView*)This, pidl));
154 return S_OK;
157 static HRESULT OnDefaultCommand(IShellViewImpl * This)
159 if (IsInCommDlg(This))
160 { TRACE(shell,"ICommDlgBrowser::OnDefaultCommand\n");
161 return (ICommDlgBrowser_OnDefaultCommand(This->pCommDlgBrowser, (IShellView*)This));
163 return S_FALSE;
166 static HRESULT OnStateChange(IShellViewImpl * This, UINT uFlags)
168 if (IsInCommDlg(This))
169 { TRACE(shell,"ICommDlgBrowser::OnStateChange flags=%x\n", uFlags);
170 return (ICommDlgBrowser_OnStateChange(This->pCommDlgBrowser, (IShellView*)This, uFlags));
172 return S_FALSE;
174 static void SetStyle(IShellViewImpl * This, DWORD dwAdd, DWORD dwRemove)
175 { DWORD tmpstyle;
177 TRACE(shell,"(%p)\n", This);
179 tmpstyle = GetWindowLongA(This->hWndList, GWL_STYLE);
180 SetWindowLongA(This->hWndList, GWL_STYLE, dwAdd | (tmpstyle & ~dwRemove));
183 static void CheckToolbar(IShellViewImpl * This)
184 { LRESULT result;
186 TRACE(shell,"\n");
188 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_TOOLBAR, TB_CHECKBUTTON,
189 FCIDM_TB_SMALLICON, (This->FolderSettings.ViewMode==FVM_LIST)? TRUE : FALSE, &result);
190 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_TOOLBAR, TB_CHECKBUTTON,
191 FCIDM_TB_REPORTVIEW, (This->FolderSettings.ViewMode==FVM_DETAILS)? TRUE : FALSE, &result);
192 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_TOOLBAR, TB_ENABLEBUTTON,
193 FCIDM_TB_SMALLICON, TRUE, &result);
194 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_TOOLBAR, TB_ENABLEBUTTON,
195 FCIDM_TB_REPORTVIEW, TRUE, &result);
196 TRACE(shell,"--\n");
199 static void MergeToolBar(IShellViewImpl * This)
200 { LRESULT iStdBMOffset;
201 LRESULT iViewBMOffset;
202 TBADDBITMAP ab;
203 TBBUTTON tbActual[6];
204 int i;
205 enum
206 { IN_STD_BMP = 0x4000,
207 IN_VIEW_BMP = 0x8000,
209 static const TBBUTTON c_tbDefault[] =
210 { { STD_COPY | IN_STD_BMP, FCIDM_SHVIEW_COPY, TBSTATE_ENABLED, TBSTYLE_BUTTON, {0,0}, 0, -1},
211 { 0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, {0,0}, 0, -1 },
212 { VIEW_LARGEICONS | IN_VIEW_BMP, FCIDM_SHVIEW_BIGICON, TBSTATE_ENABLED, TBSTYLE_BUTTON, {0,0}, 0L, -1 },
213 { VIEW_SMALLICONS | IN_VIEW_BMP, FCIDM_SHVIEW_SMALLICON, TBSTATE_ENABLED, TBSTYLE_BUTTON, {0,0}, 0L, -1 },
214 { VIEW_LIST | IN_VIEW_BMP, FCIDM_SHVIEW_LISTVIEW, TBSTATE_ENABLED, TBSTYLE_BUTTON, {0,0}, 0L, -1 },
215 { VIEW_DETAILS | IN_VIEW_BMP, FCIDM_SHVIEW_REPORTVIEW, TBSTATE_ENABLED, TBSTYLE_BUTTON, {0,0}, 0L, -1 },
218 TRACE(shell,"\n");
220 ab.hInst = HINST_COMMCTRL; /* hinstCommctrl */
221 ab.nID = IDB_STD_SMALL_COLOR; /* std bitmaps */
222 IShellBrowser_SendControlMsg(This->pShellBrowser,FCW_TOOLBAR,
223 TB_ADDBITMAP, 8, (LPARAM)&ab, &iStdBMOffset);
225 TRACE(shell,"TB_ADDBITMAP returns %lx\n", iStdBMOffset);
227 ab.nID = IDB_VIEW_SMALL_COLOR; /* std view bitmaps */
228 IShellBrowser_SendControlMsg(This->pShellBrowser,FCW_TOOLBAR,
229 TB_ADDBITMAP, 8, (LPARAM)&ab, &iViewBMOffset);
231 TRACE(shell,"TB_ADDBITMAP returns %lx\n", iViewBMOffset);
233 for (i=0; i<6; ++i)
234 { tbActual[i] = c_tbDefault[i];
235 if (!(tbActual[i].fsStyle & TBSTYLE_SEP))
236 { if (tbActual[i].iBitmap & IN_VIEW_BMP)
237 { tbActual[i].iBitmap = (tbActual[i].iBitmap & ~IN_VIEW_BMP) + iViewBMOffset;
239 else if (tbActual[i].iBitmap & IN_STD_BMP)
240 { tbActual[i].iBitmap = (tbActual[i].iBitmap & ~IN_STD_BMP) + iStdBMOffset;
245 IShellBrowser_SetToolbarItems(This->pShellBrowser,tbActual, 6, FCT_MERGE);
247 CheckToolbar(This);
248 TRACE(shell,"--\n");
252 /**************************************************************************
253 * ShellView_CreateList()
257 BOOL ShellView_CreateList (IShellViewImpl * This)
258 { DWORD dwStyle;
260 TRACE(shell,"%p\n",This);
262 dwStyle = WS_TABSTOP | WS_VISIBLE | WS_CHILD | WS_BORDER |
263 LVS_SHAREIMAGELISTS | LVS_EDITLABELS | LVS_ALIGNLEFT;
264 switch (This->FolderSettings.ViewMode)
265 { case FVM_ICON: dwStyle |= LVS_ICON; break;
266 case FVM_DETAILS: dwStyle |= LVS_REPORT; break;
267 case FVM_SMALLICON: dwStyle |= LVS_SMALLICON; break;
268 case FVM_LIST: dwStyle |= LVS_LIST; break;
269 default: dwStyle |= LVS_LIST; break;
271 if (This->FolderSettings.fFlags && FWF_AUTOARRANGE) dwStyle |= LVS_AUTOARRANGE;
272 /*if (This->FolderSettings.fFlags && FWF_DESKTOP); used from explorer*/
273 if (This->FolderSettings.fFlags && FWF_SINGLESEL) dwStyle |= LVS_SINGLESEL;
275 This->hWndList=CreateWindowExA( WS_EX_CLIENTEDGE,
276 WC_LISTVIEWA,
277 NULL,
278 dwStyle,
279 0,0,0,0,
280 This->hWnd,
281 (HMENU)ID_LISTVIEW,
282 shell32_hInstance,
283 NULL);
285 if(!This->hWndList)
286 return FALSE;
288 /* UpdateShellSettings(); */
289 return TRUE;
291 /**************************************************************************
292 * ShellView_InitList()
294 * NOTES
295 * internal
297 int nColumn1=120; /* width of column */
298 int nColumn2=80;
299 int nColumn3=170;
300 int nColumn4=60;
302 BOOL ShellView_InitList(IShellViewImpl * This)
303 { LVCOLUMNA lvColumn;
304 CHAR szString[50];
306 TRACE(shell,"%p\n",This);
308 ListView_DeleteAllItems(This->hWndList);
310 /*initialize the columns */
311 lvColumn.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT; /* | LVCF_SUBITEM;*/
312 lvColumn.fmt = LVCFMT_LEFT;
313 lvColumn.pszText = szString;
315 lvColumn.cx = nColumn1;
316 strcpy(szString,"File");
317 /*LoadStringA(shell32_hInstance, IDS_COLUMN1, szString, sizeof(szString));*/
318 ListView_InsertColumnA(This->hWndList, 0, &lvColumn);
320 lvColumn.cx = nColumn2;
321 strcpy(szString,"Size");
322 ListView_InsertColumnA(This->hWndList, 1, &lvColumn);
324 lvColumn.cx = nColumn3;
325 strcpy(szString,"Type");
326 ListView_InsertColumnA(This->hWndList, 2, &lvColumn);
328 lvColumn.cx = nColumn4;
329 strcpy(szString,"Modified");
330 ListView_InsertColumnA(This->hWndList, 3, &lvColumn);
332 ListView_SetImageList(This->hWndList, ShellSmallIconList, LVSIL_SMALL);
333 ListView_SetImageList(This->hWndList, ShellBigIconList, LVSIL_NORMAL);
335 return TRUE;
337 /**************************************************************************
338 * ShellView_CompareItems()
340 * NOTES
341 * internal, CALLBACK for DSA_Sort
343 INT CALLBACK ShellView_CompareItems(LPVOID lParam1, LPVOID lParam2, LPARAM lpData)
344 { int ret;
345 TRACE(shell,"pidl1=%p pidl2=%p lpsf=%p\n", lParam1, lParam2, (LPVOID) lpData);
347 if(!lpData)
348 return 0;
350 ret = (int)((LPSHELLFOLDER)lpData)->lpvtbl->fnCompareIDs((LPSHELLFOLDER)lpData, 0, (LPITEMIDLIST)lParam1, (LPITEMIDLIST)lParam2);
351 TRACE(shell,"ret=%i\n",ret);
352 return ret;
355 /**************************************************************************
356 * ShellView_FillList()
358 * NOTES
359 * internal
362 static HRESULT ShellView_FillList(IShellViewImpl * This)
363 { LPENUMIDLIST pEnumIDList;
364 LPITEMIDLIST pidl;
365 DWORD dwFetched;
366 UINT i;
367 LVITEMA lvItem;
368 HRESULT hRes;
369 HDPA hdpa;
371 TRACE(shell,"%p\n",This);
373 /* get the itemlist from the shfolder*/
374 hRes = IShellFolder_EnumObjects(This->pSFParent,This->hWnd, SHCONTF_NONFOLDERS | SHCONTF_FOLDERS, &pEnumIDList);
375 if (hRes != S_OK)
376 { if (hRes==S_FALSE)
377 return(NOERROR);
378 return(hRes);
381 /* create a pointer array */
382 hdpa = pDPA_Create(16);
383 if (!hdpa)
384 { return(E_OUTOFMEMORY);
387 /* copy the items into the array*/
388 while((S_OK == IEnumIDList_Next(pEnumIDList,1, &pidl, &dwFetched)) && dwFetched)
389 { if (pDPA_InsertPtr(hdpa, 0x7fff, pidl) == -1)
390 { SHFree(pidl);
394 /*sort the array*/
395 pDPA_Sort(hdpa, ShellView_CompareItems, (LPARAM)This->pSFParent);
397 /*turn the listview's redrawing off*/
398 SendMessageA(This->hWndList, WM_SETREDRAW, FALSE, 0);
400 for (i=0; i < DPA_GetPtrCount(hdpa); ++i) /* DPA_GetPtrCount is a macro*/
401 { pidl = (LPITEMIDLIST)DPA_GetPtr(hdpa, i);
402 if (IncludeObject(This, pidl) == S_OK) /* in a commdlg This works as a filemask*/
403 { ZeroMemory(&lvItem, sizeof(lvItem)); /* create the listviewitem*/
404 lvItem.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM; /*set the mask*/
405 lvItem.iItem = ListView_GetItemCount(This->hWndList); /*add the item to the end of the list*/
406 lvItem.lParam = (LPARAM) pidl; /*set the item's data*/
407 lvItem.pszText = LPSTR_TEXTCALLBACKA; /*get text on a callback basis*/
408 lvItem.iImage = I_IMAGECALLBACK; /*get the image on a callback basis*/
409 ListView_InsertItemA(This->hWndList, &lvItem);
411 else
412 SHFree(pidl); /* the listview has the COPY*/
415 /*turn the listview's redrawing back on and force it to draw*/
416 SendMessageA(This->hWndList, WM_SETREDRAW, TRUE, 0);
417 InvalidateRect(This->hWndList, NULL, TRUE);
418 UpdateWindow(This->hWndList);
420 IEnumIDList_Release(pEnumIDList); /* destroy the list*/
421 pDPA_Destroy(hdpa);
423 return S_OK;
426 /**************************************************************************
427 * ShellView_OnCreate()
429 * NOTES
430 * internal
432 LRESULT ShellView_OnCreate(IShellViewImpl * This)
433 { TRACE(shell,"%p\n",This);
435 if(ShellView_CreateList(This))
436 { if(ShellView_InitList(This))
437 { ShellView_FillList(This);
441 return S_OK;
443 /**************************************************************************
444 * ShellView_OnSize()
446 LRESULT ShellView_OnSize(IShellViewImpl * This, WORD wWidth, WORD wHeight)
447 { TRACE(shell,"%p width=%u height=%u\n",This, wWidth,wHeight);
449 /*resize the ListView to fit our window*/
450 if(This->hWndList)
451 { MoveWindow(This->hWndList, 0, 0, wWidth, wHeight, TRUE);
454 return S_OK;
456 /**************************************************************************
457 * ShellView_BuildFileMenu()
459 HMENU ShellView_BuildFileMenu(IShellViewImpl * This)
460 { CHAR szText[MAX_PATH];
461 MENUITEMINFOA mii;
462 int nTools,i;
463 HMENU hSubMenu;
465 TRACE(shell,"(%p) semi-stub\n",This);
467 hSubMenu = CreatePopupMenu();
468 if(hSubMenu)
469 { /*get the number of items in our global array*/
470 for(nTools = 0; g_Tools[nTools].idCommand != -1; nTools++){}
472 /*add the menu items*/
473 for(i = 0; i < nTools; i++)
474 { strcpy(szText, "dummy BuildFileMenu");
476 ZeroMemory(&mii, sizeof(mii));
477 mii.cbSize = sizeof(mii);
478 mii.fMask = MIIM_TYPE | MIIM_ID | MIIM_STATE;
480 if(TBSTYLE_SEP != g_Tools[i].bStyle) /* no seperator*/
481 { mii.fType = MFT_STRING;
482 mii.fState = MFS_ENABLED;
483 mii.dwTypeData = szText;
484 mii.wID = g_Tools[i].idCommand;
486 else
487 { mii.fType = MFT_SEPARATOR;
489 /* tack This item onto the end of the menu */
490 InsertMenuItemA(hSubMenu, (UINT)-1, TRUE, &mii);
493 TRACE(shell,"-- return (menu=0x%x)\n",hSubMenu);
494 return hSubMenu;
496 /**************************************************************************
497 * ShellView_MergeFileMenu()
499 void ShellView_MergeFileMenu(IShellViewImpl * This, HMENU hSubMenu)
500 { TRACE(shell,"(%p)->(submenu=0x%08x) stub\n",This,hSubMenu);
502 if(hSubMenu)
503 { /*insert This item at the beginning of the menu */
504 _InsertMenuItem(hSubMenu, 0, TRUE, 0, MFT_SEPARATOR, NULL, MFS_ENABLED);
505 _InsertMenuItem(hSubMenu, 0, TRUE, IDM_MYFILEITEM, MFT_STRING, "dummy45", MFS_ENABLED);
508 TRACE(shell,"--\n");
511 /**************************************************************************
512 * ShellView_MergeViewMenu()
515 void ShellView_MergeViewMenu(IShellViewImpl * This, HMENU hSubMenu)
516 { MENUITEMINFOA mii;
518 TRACE(shell,"(%p)->(submenu=0x%08x)\n",This,hSubMenu);
520 if(hSubMenu)
521 { /*add a separator at the correct position in the menu*/
522 _InsertMenuItem(hSubMenu, FCIDM_MENU_VIEW_SEP_OPTIONS, FALSE, 0, MFT_SEPARATOR, NULL, MFS_ENABLED);
524 ZeroMemory(&mii, sizeof(mii));
525 mii.cbSize = sizeof(mii);
526 mii.fMask = MIIM_SUBMENU | MIIM_TYPE | MIIM_DATA;;
527 mii.fType = MFT_STRING;
528 mii.dwTypeData = "View";
529 mii.hSubMenu = LoadMenuIndirectA(&_Resource_Men_MENU_001_0_data);
530 InsertMenuItemA(hSubMenu, FCIDM_MENU_VIEW_SEP_OPTIONS, FALSE, &mii);
534 /**************************************************************************
535 * ShellView_CanDoIDockingWindow()
537 BOOL ShellView_CanDoIDockingWindow(IShellViewImpl * This)
538 { BOOL bReturn = FALSE;
539 HRESULT hr;
540 LPSERVICEPROVIDER pSP;
541 LPDOCKINGWINDOWFRAME pFrame;
543 FIXME(shell,"(%p) stub\n",This);
545 /*get the browser's IServiceProvider*/
546 hr = IShellBrowser_QueryInterface(This->pShellBrowser, (REFIID)&IID_IServiceProvider, (LPVOID*)&pSP);
547 if(hr==S_OK)
548 { hr = IServiceProvider_QueryService(pSP, (REFGUID)&SID_SShellBrowser, (REFIID)&IID_IDockingWindowFrame, (LPVOID*)&pFrame);
549 if(SUCCEEDED(hr))
550 { bReturn = TRUE;
551 pFrame->lpvtbl->fnRelease(pFrame);
553 IServiceProvider_Release(pSP);
555 return bReturn;
558 /**************************************************************************
559 * ShellView_UpdateMenu()
561 LRESULT ShellView_UpdateMenu(IShellViewImpl * This, HMENU hMenu)
562 { TRACE(shell,"(%p)->(menu=0x%08x)\n",This,hMenu);
563 CheckMenuItem(hMenu, IDM_VIEW_FILES, MF_BYCOMMAND | (g_bViewKeys ? MF_CHECKED: MF_UNCHECKED));
565 if(ShellView_CanDoIDockingWindow(This))
566 { EnableMenuItem(hMenu, IDM_VIEW_IDW, MF_BYCOMMAND | MF_ENABLED);
567 CheckMenuItem(hMenu, IDM_VIEW_IDW, MF_BYCOMMAND | (g_bShowIDW ? MF_CHECKED: MF_UNCHECKED));
569 else
570 { EnableMenuItem(hMenu, IDM_VIEW_IDW, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
571 CheckMenuItem(hMenu, IDM_VIEW_IDW, MF_BYCOMMAND | MF_UNCHECKED);
573 return S_OK;
576 /**************************************************************************
577 * ShellView_OnDeactivate()
579 * NOTES
580 * internal
582 void ShellView_OnDeactivate(IShellViewImpl * This)
583 { TRACE(shell,"%p\n",This);
584 if(This->uState != SVUIA_DEACTIVATE)
585 { if(This->hMenu)
586 { IShellBrowser_SetMenuSB(This->pShellBrowser,0, 0, 0);
587 IShellBrowser_RemoveMenusSB(This->pShellBrowser,This->hMenu);
588 DestroyMenu(This->hMenu);
589 This->hMenu = 0;
592 This->uState = SVUIA_DEACTIVATE;
596 /**************************************************************************
597 * ShellView_OnActivate()
599 LRESULT ShellView_OnActivate(IShellViewImpl * This, UINT uState)
600 { OLEMENUGROUPWIDTHS omw = { {0, 0, 0, 0, 0, 0} };
601 MENUITEMINFOA mii;
602 CHAR szText[MAX_PATH];
604 TRACE(shell,"%p uState=%x\n",This,uState);
606 /*don't do anything if the state isn't really changing */
607 if(This->uState == uState)
608 { return S_OK;
611 ShellView_OnDeactivate(This);
613 /*only do This if we are active */
614 if(uState != SVUIA_DEACTIVATE)
615 { /*merge the menus */
616 This->hMenu = CreateMenu();
618 if(This->hMenu)
619 { IShellBrowser_InsertMenusSB(This->pShellBrowser, This->hMenu, &omw);
620 TRACE(shell,"-- after fnInsertMenusSB\n");
621 /*build the top level menu get the menu item's text*/
622 strcpy(szText,"dummy 31");
624 ZeroMemory(&mii, sizeof(mii));
625 mii.cbSize = sizeof(mii);
626 mii.fMask = MIIM_SUBMENU | MIIM_TYPE | MIIM_STATE;
627 mii.fType = MFT_STRING;
628 mii.fState = MFS_ENABLED;
629 mii.dwTypeData = szText;
630 mii.hSubMenu = ShellView_BuildFileMenu(This);
632 /*insert our menu into the menu bar*/
633 if(mii.hSubMenu)
634 { InsertMenuItemA(This->hMenu, FCIDM_MENU_HELP, FALSE, &mii);
637 /*get the view menu so we can merge with it*/
638 ZeroMemory(&mii, sizeof(mii));
639 mii.cbSize = sizeof(mii);
640 mii.fMask = MIIM_SUBMENU;
642 if(GetMenuItemInfoA(This->hMenu, FCIDM_MENU_VIEW, FALSE, &mii))
643 { ShellView_MergeViewMenu(This, mii.hSubMenu);
646 /*add the items that should only be added if we have the focus*/
647 if(SVUIA_ACTIVATE_FOCUS == uState)
648 { /*get the file menu so we can merge with it */
649 ZeroMemory(&mii, sizeof(mii));
650 mii.cbSize = sizeof(mii);
651 mii.fMask = MIIM_SUBMENU;
653 if(GetMenuItemInfoA(This->hMenu, FCIDM_MENU_FILE, FALSE, &mii))
654 { ShellView_MergeFileMenu(This, mii.hSubMenu);
657 TRACE(shell,"-- before fnSetMenuSB\n");
658 IShellBrowser_SetMenuSB(This->pShellBrowser, This->hMenu, 0, This->hWnd);
661 This->uState = uState;
662 TRACE(shell,"--\n");
663 return S_OK;
666 /**************************************************************************
667 * ShellView_OnSetFocus()
669 * NOTES
670 * internal
672 LRESULT ShellView_OnSetFocus(IShellViewImpl * This)
673 { TRACE(shell,"%p\n",This);
674 /* Tell the browser one of our windows has received the focus. This should always
675 be done before merging menus (OnActivate merges the menus) if one of our
676 windows has the focus.*/
677 IShellBrowser_OnViewWindowActive(This->pShellBrowser,(IShellView*) This);
678 ShellView_OnActivate(This, SVUIA_ACTIVATE_FOCUS);
680 return 0;
683 /**************************************************************************
684 * ShellView_OnKillFocus()
686 LRESULT ShellView_OnKillFocus(IShellViewImpl * This)
687 { TRACE(shell,"(%p) stub\n",This);
688 ShellView_OnActivate(This, SVUIA_ACTIVATE_NOFOCUS);
689 return 0;
692 /**************************************************************************
693 * ShellView_AddRemoveDockingWindow()
695 BOOL ShellView_AddRemoveDockingWindow(IShellViewImpl * This, BOOL bAdd)
696 { BOOL bReturn = FALSE;
697 HRESULT hr;
698 LPSERVICEPROVIDER pSP;
699 LPDOCKINGWINDOWFRAME pFrame;
701 WARN(shell,"(%p)->(badd=0x%08x) semi-stub\n",This,bAdd);
703 /* get the browser's IServiceProvider */
704 hr = IShellBrowser_QueryInterface(This->pShellBrowser, (REFIID)&IID_IServiceProvider, (LPVOID*)&pSP);
705 if(SUCCEEDED(hr))
706 { /*get the IDockingWindowFrame pointer*/
707 hr = IServiceProvider_QueryService(pSP, (REFGUID)&SID_SShellBrowser, (REFIID)&IID_IDockingWindowFrame, (LPVOID*)&pFrame);
708 if(SUCCEEDED(hr))
709 { if(bAdd)
710 { hr = S_OK;
711 FIXME(shell,"no docking implemented\n");
712 #if 0
713 if(!This->pDockingWindow)
714 { /* create the toolbar object */
715 This->pDockingWindow = DockingWindow_Constructor(This, This->hWnd);
718 if(This->pDockingWindow)
719 { /*add the toolbar object */
720 hr = pFrame->lpvtbl->fnAddToolbar(pFrame, (IDockingWindow*)This->pDockingWindow, TOOLBAR_ID, 0);
722 if(SUCCEEDED(hr))
723 { bReturn = TRUE;
726 #endif
728 else
729 { FIXME(shell,"no docking implemented\n");
730 #if 0
731 if(This->pDockingWindow)
732 { hr = pFrame->lpvtbl->fnRemoveToolbar(pFrame, (IDockingWindow*)This->pDockingWindow, DWFRF_NORMAL);
734 if(SUCCEEDED(hr))
735 { /* RemoveToolbar should release the toolbar object which will cause */
736 /*it to destroy itself. Our toolbar object is no longer valid at */
737 /*This point. */
739 This->pDockingWindow = NULL;
740 bReturn = TRUE;
743 #endif
745 pFrame->lpvtbl->fnRelease(pFrame);
747 IServiceProvider_Release(pSP);
749 return bReturn;
752 /**************************************************************************
753 * ShellView_UpdateShellSettings()
755 void ShellView_UpdateShellSettings(IShellViewImpl * This)
756 { FIXME(shell,"(%p) stub\n",This);
757 return ;
759 SHELLFLAGSTATE sfs;
760 HINSTANCE hinstShell32;
762 /* Since SHGetSettings is not implemented in all versions of the shell, get the
763 function address manually at run time. This allows the code to run on all
764 platforms.*/
766 ZeroMemory(&sfs, sizeof(sfs));
768 /* The default, in case any of the following steps fails, is classic Windows 95
769 style.*/
771 sfs.fWin95Classic = TRUE;
773 hinstShell32 = LoadLibrary("shell32.dll");
774 if(hinstShell32)
775 { PFNSHGETSETTINGSPROC pfnSHGetSettings;
777 pfnSHGetSettings = (PFNSHGETSETTINGSPROC)GetProcAddress(hinstShell32, "SHGetSettings");
778 if(pfnSHGetSettings)
779 { (*pfnSHGetSettings)(&sfs, SSF_DOUBLECLICKINWEBVIEW | SSF_WIN95CLASSIC);
781 FreeLibrary(hinstShell32);
784 DWORD dwExStyles = 0;
786 if(!sfs.fWin95Classic && !sfs.fDoubleClickInWebView)
787 dwExStyles |= LVS_EX_ONECLICKACTIVATE | LVS_EX_TRACKSELECT | LVS_EX_UNDERLINEHOT;
789 ListView_SetExtendedListViewStyle(This->hWndList, dwExStyles);
793 /**************************************************************************
794 * ShellView_OnSettingChange()
796 LRESULT ShellView_OnSettingChange(IShellViewImpl * This, LPCSTR lpszSection)
797 { TRACE(shell,"(%p) stub\n",This);
798 /*if(0 == lstrcmpi(lpszSection, "ShellState"))*/
799 { ShellView_UpdateShellSettings(This);
800 return 0;
802 return 0;
804 /**************************************************************************
805 * ShellView_OnCommand()
807 LRESULT ShellView_OnCommand(IShellViewImpl * This,DWORD dwCmdID, DWORD dwCmd, HWND hwndCmd)
808 { TRACE(shell,"(%p)->(0x%08lx 0x%08lx 0x%08x) stub\n",This, dwCmdID, dwCmd, hwndCmd);
809 switch(dwCmdID)
810 { case IDM_VIEW_FILES:
811 g_bViewKeys = ! g_bViewKeys;
812 IShellView_Refresh((IShellView*) This);
813 break;
815 case IDM_VIEW_IDW:
816 g_bShowIDW = ! g_bShowIDW;
817 ShellView_AddRemoveDockingWindow(This, g_bShowIDW);
818 break;
820 case IDM_MYFILEITEM:
821 MessageBeep(MB_OK);
822 break;
824 case FCIDM_SHVIEW_SMALLICON:
825 This->FolderSettings.ViewMode = FVM_SMALLICON;
826 SetStyle (This, LVS_SMALLICON, LVS_TYPEMASK);
827 break;
829 case FCIDM_SHVIEW_BIGICON:
830 This->FolderSettings.ViewMode = FVM_ICON;
831 SetStyle (This, LVS_ICON, LVS_TYPEMASK);
832 break;
834 case FCIDM_SHVIEW_LISTVIEW:
835 This->FolderSettings.ViewMode = FVM_LIST;
836 SetStyle (This, LVS_LIST, LVS_TYPEMASK);
837 break;
839 case FCIDM_SHVIEW_REPORTVIEW:
840 This->FolderSettings.ViewMode = FVM_DETAILS;
841 SetStyle (This, LVS_REPORT, LVS_TYPEMASK);
842 break;
844 default:
845 TRACE(shell,"-- COMMAND 0x%04lx unhandled\n", dwCmdID);
847 return 0;
850 /**************************************************************************
851 * ShellView_GetSelections()
853 * RETURNS
854 * number of selected items
856 UINT ShellView_GetSelections(IShellViewImpl * This)
857 { LVITEMA lvItem;
858 UINT i;
861 if (This->aSelectedItems)
862 { SHFree(This->aSelectedItems);
865 This->uSelected = ListView_GetSelectedCount(This->hWndList);
866 This->aSelectedItems = (LPITEMIDLIST*)SHAlloc(This->uSelected * sizeof(LPITEMIDLIST));
868 TRACE(shell,"selected=%i\n", This->uSelected);
870 if(This->aSelectedItems)
871 { TRACE(shell,"-- Items selected =%u\n", This->uSelected);
872 ZeroMemory(&lvItem, sizeof(lvItem));
873 lvItem.mask = LVIF_STATE | LVIF_PARAM;
874 lvItem.stateMask = LVIS_SELECTED;
875 lvItem.iItem = 0;
877 i = 0;
879 while(ListView_GetItemA(This->hWndList, &lvItem) && (i < This->uSelected))
880 { if(lvItem.state & LVIS_SELECTED)
881 { This->aSelectedItems[i] = (LPITEMIDLIST)lvItem.lParam;
882 i++;
883 TRACE(shell,"-- selected Item found\n");
885 lvItem.iItem++;
888 return This->uSelected;
891 /**************************************************************************
892 * ShellView_DoContextMenu()
894 void ShellView_DoContextMenu(IShellViewImpl * This, WORD x, WORD y, BOOL fDefault)
895 { UINT uCommand;
896 DWORD wFlags;
897 HMENU hMenu;
898 BOOL fExplore = FALSE;
899 HWND hwndTree = 0;
900 INT nMenuIndex;
901 MENUITEMINFOA mii;
902 LPCONTEXTMENU pContextMenu = NULL;
903 CMINVOKECOMMANDINFO cmi;
905 TRACE(shell,"(%p)->(0x%08x 0x%08x 0x%08x) stub\n",This, x, y, fDefault);
907 /* look, what's selected and create a context menu object of it*/
908 if(ShellView_GetSelections(This))
909 { This->pSFParent->lpvtbl->fnGetUIObjectOf( This->pSFParent, This->hWndParent, This->uSelected,
910 This->aSelectedItems, (REFIID)&IID_IContextMenu,
911 NULL, (LPVOID *)&pContextMenu);
913 if(pContextMenu)
914 { TRACE(shell,"-- pContextMenu\n");
915 hMenu = CreatePopupMenu();
917 if( hMenu )
918 { /* See if we are in Explore or Open mode. If the browser's tree
919 is present, then we are in Explore mode.*/
921 if(SUCCEEDED(IShellBrowser_GetControlWindow(This->pShellBrowser,FCW_TREE, &hwndTree)) && hwndTree)
922 { TRACE(shell,"-- explore mode\n");
923 fExplore = TRUE;
926 wFlags = CMF_NORMAL | (This->uSelected != 1 ? 0 : CMF_CANRENAME) | (fExplore ? CMF_EXPLORE : 0);
928 if (SUCCEEDED(pContextMenu->lpvtbl->fnQueryContextMenu( pContextMenu, hMenu, 0, MENU_OFFSET, MENU_MAX, wFlags )))
929 { if( fDefault )
930 { TRACE(shell,"-- get menu default command\n");
932 uCommand = nMenuIndex = 0;
933 ZeroMemory(&mii, sizeof(mii));
934 mii.cbSize = sizeof(mii);
935 mii.fMask = MIIM_STATE | MIIM_ID;
937 while(GetMenuItemInfoA(hMenu, nMenuIndex, TRUE, &mii)) /*find the default item in the menu*/
938 { if(mii.fState & MFS_DEFAULT)
939 { uCommand = mii.wID;
940 break;
942 nMenuIndex++;
945 else
946 { TRACE(shell,"-- track popup\n");
947 uCommand = TrackPopupMenu( hMenu,TPM_LEFTALIGN | TPM_RETURNCMD,x,y,0,This->hWnd,NULL);
950 if(uCommand > 0)
951 { TRACE(shell,"-- uCommand=%u\n", uCommand);
952 if (IsInCommDlg(This) && (((uCommand-MENU_OFFSET)==IDM_EXPLORE) || ((uCommand-MENU_OFFSET)==IDM_OPEN)))
953 { TRACE(shell,"-- dlg: OnDefaultCommand\n");
954 OnDefaultCommand(This);
956 else
957 { TRACE(shell,"-- explore -- invoke command\n");
958 ZeroMemory(&cmi, sizeof(cmi));
959 cmi.cbSize = sizeof(cmi);
960 cmi.hwnd = This->hWndParent;
961 cmi.lpVerb = (LPCSTR)MAKEINTRESOURCEA(uCommand - MENU_OFFSET);
962 pContextMenu->lpvtbl->fnInvokeCommand(pContextMenu, &cmi);
965 DestroyMenu(hMenu);
968 if (pContextMenu)
969 pContextMenu->lpvtbl->fnRelease(pContextMenu);
972 else /* background context menu */
973 { hMenu = LoadMenuIndirectA(&_Resource_Men_MENU_002_0_data);
974 uCommand = TrackPopupMenu( GetSubMenu(hMenu,0),TPM_LEFTALIGN | TPM_RETURNCMD,x,y,0,This->hWnd,NULL);
975 ShellView_OnCommand(This, uCommand, 0,0);
976 DestroyMenu(hMenu);
980 /**************************************************************************
981 * ShellView_OnNotify()
984 LRESULT ShellView_OnNotify(IShellViewImpl * This, UINT CtlID, LPNMHDR lpnmh)
985 { NM_LISTVIEW *lpnmlv = (NM_LISTVIEW*)lpnmh;
986 NMLVDISPINFOA *lpdi = (NMLVDISPINFOA *)lpnmh;
987 LPITEMIDLIST pidl;
988 DWORD dwCursor;
989 STRRET str;
990 UINT uFlags;
991 IExtractIcon *pei;
993 TRACE(shell,"%p CtlID=%u lpnmh->code=%x\n",This,CtlID,lpnmh->code);
995 switch(lpnmh->code)
996 { case NM_SETFOCUS:
997 TRACE(shell,"-- NM_SETFOCUS %p\n",This);
998 ShellView_OnSetFocus(This);
999 break;
1001 case NM_KILLFOCUS:
1002 TRACE(shell,"-- NM_KILLFOCUS %p\n",This);
1003 ShellView_OnDeactivate(This);
1004 break;
1006 case HDN_ENDTRACKA:
1007 TRACE(shell,"-- HDN_ENDTRACKA %p\n",This);
1008 /*nColumn1 = ListView_GetColumnWidth(This->hWndList, 0);
1009 nColumn2 = ListView_GetColumnWidth(This->hWndList, 1);*/
1010 break;
1012 case LVN_DELETEITEM:
1013 TRACE(shell,"-- LVN_DELETEITEM %p\n",This);
1014 SHFree((LPITEMIDLIST)lpnmlv->lParam); /*delete the pidl because we made a copy of it*/
1015 break;
1017 case LVN_ITEMACTIVATE:
1018 TRACE(shell,"-- LVN_ITEMACTIVATE %p\n",This);
1019 OnStateChange(This, CDBOSC_SELCHANGE); /* the browser will get the IDataObject now */
1020 ShellView_DoContextMenu(This, 0, 0, TRUE);
1021 break;
1023 case NM_RCLICK:
1024 TRACE(shell,"-- NM_RCLICK %p\n",This);
1025 dwCursor = GetMessagePos();
1026 ShellView_DoContextMenu(This, LOWORD(dwCursor), HIWORD(dwCursor), FALSE);
1027 break;
1029 case LVN_GETDISPINFOA:
1030 TRACE(shell,"-- LVN_GETDISPINFOA %p\n",This);
1031 pidl = (LPITEMIDLIST)lpdi->item.lParam;
1034 if(lpdi->item.iSubItem) /*is the sub-item information being requested?*/
1035 { if(lpdi->item.mask & LVIF_TEXT) /*is the text being requested?*/
1036 { if(_ILIsValue(pidl)) /*is This a value or a folder?*/
1037 { switch (lpdi->item.iSubItem)
1038 { case 1: /* size */
1039 _ILGetFileSize (pidl, lpdi->item.pszText, lpdi->item.cchTextMax);
1040 break;
1041 case 2: /* extension */
1042 { char sTemp[64];
1043 if (_ILGetExtension (pidl, sTemp, 64))
1044 { if (!( HCR_MapTypeToValue(sTemp, sTemp, 64)
1045 && HCR_MapTypeToValue(sTemp, lpdi->item.pszText, lpdi->item.cchTextMax )))
1046 { strncpy (lpdi->item.pszText, sTemp, lpdi->item.cchTextMax);
1047 strncat (lpdi->item.pszText, "-file", lpdi->item.cchTextMax);
1050 else /* no extension found */
1051 { lpdi->item.pszText[0]=0x00;
1054 break;
1055 case 3: /* date */
1056 _ILGetFileDate (pidl, lpdi->item.pszText, lpdi->item.cchTextMax);
1057 break;
1060 else /*its a folder*/
1061 { switch (lpdi->item.iSubItem)
1062 { case 1:
1063 strcpy(lpdi->item.pszText, "");
1064 break;
1065 case 2:
1066 strncpy (lpdi->item.pszText, "Folder", lpdi->item.cchTextMax);
1067 break;
1068 case 3:
1069 _ILGetFileDate (pidl, lpdi->item.pszText, lpdi->item.cchTextMax);
1070 break;
1073 TRACE(shell,"-- text=%s\n",lpdi->item.pszText);
1076 else /*the item text is being requested*/
1077 { if(lpdi->item.mask & LVIF_TEXT) /*is the text being requested?*/
1078 { if(SUCCEEDED(IShellFolder_GetDisplayNameOf(This->pSFParent,pidl, SHGDN_NORMAL | SHGDN_INFOLDER, &str)))
1079 { if(STRRET_WSTR == str.uType)
1080 { WideCharToLocal(lpdi->item.pszText, str.u.pOleStr, lpdi->item.cchTextMax);
1081 SHFree(str.u.pOleStr);
1083 else if(STRRET_CSTRA == str.uType)
1084 { strncpy(lpdi->item.pszText, str.u.cStr, lpdi->item.cchTextMax);
1086 else
1087 { FIXME(shell,"type wrong\n");
1090 TRACE(shell,"-- text=%s\n",lpdi->item.pszText);
1093 if(lpdi->item.mask & LVIF_IMAGE) /*is the image being requested?*/
1094 { if(SUCCEEDED(IShellFolder_GetUIObjectOf(This->pSFParent,This->hWnd,1,
1095 (LPCITEMIDLIST*)&pidl, (REFIID)&IID_IExtractIconA, NULL, (LPVOID*)&pei)))
1096 { IExtractIconA_GetIconLocation(pei, GIL_FORSHELL, NULL, 0, &lpdi->item.iImage, &uFlags);
1097 IExtractIconA_Release(pei);
1098 TRACE(shell,"-- image=%x\n",lpdi->item.iImage);
1102 break;
1104 case LVN_ITEMCHANGED:
1105 TRACE(shell,"-- LVN_ITEMCHANGED %p\n",This);
1106 ShellView_GetSelections(This);
1107 OnStateChange(This, CDBOSC_SELCHANGE); /* the browser will get the IDataObject now */
1108 break;
1110 default:
1111 TRACE (shell,"-- %p WM_COMMAND %s unhandled\n", This, SPY_GetMsgName(lpnmh->code));
1112 break;;
1114 return 0;
1117 /**************************************************************************
1118 * ShellView_WndProc
1121 LRESULT CALLBACK ShellView_WndProc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
1122 { IShellViewImpl * pThis = (IShellViewImpl*)GetWindowLongA(hWnd, GWL_USERDATA);
1123 LPCREATESTRUCTA lpcs;
1124 DWORD dwCursor;
1126 TRACE(shell,"(hwnd=%x msg=%x wparm=%x lparm=%lx)\n",hWnd, uMessage, wParam, lParam);
1128 switch (uMessage)
1129 { case WM_NCCREATE:
1130 { TRACE(shell,"-- WM_NCCREATE\n");
1131 lpcs = (LPCREATESTRUCTA)lParam;
1132 pThis = (IShellViewImpl*)(lpcs->lpCreateParams);
1133 SetWindowLongA(hWnd, GWL_USERDATA, (LONG)pThis);
1134 pThis->hWnd = hWnd; /*set the window handle*/
1136 break;
1138 case WM_SIZE:
1139 TRACE(shell,"-- WM_SIZE\n");
1140 return ShellView_OnSize(pThis,LOWORD(lParam), HIWORD(lParam));
1142 case WM_SETFOCUS:
1143 TRACE(shell,"-- WM_SETFOCUS\n");
1144 return ShellView_OnSetFocus(pThis);
1146 case WM_KILLFOCUS:
1147 TRACE(shell,"-- WM_KILLFOCUS\n");
1148 return ShellView_OnKillFocus(pThis);
1150 case WM_CREATE:
1151 TRACE(shell,"-- WM_CREATE\n");
1152 return ShellView_OnCreate(pThis);
1154 case WM_SHOWWINDOW:
1155 TRACE(shell,"-- WM_SHOWWINDOW\n");
1156 UpdateWindow(pThis->hWndList);
1157 break;
1159 case WM_ACTIVATE:
1160 TRACE(shell,"-- WM_ACTIVATE\n");
1161 return ShellView_OnActivate(pThis, SVUIA_ACTIVATE_FOCUS);
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));
1169 case WM_INITMENUPOPUP:
1170 TRACE(shell,"-- WM_INITMENUPOPUP\n");
1171 return ShellView_UpdateMenu(pThis, (HMENU)wParam);
1173 case WM_NOTIFY:
1174 TRACE(shell,"-- WM_NOTIFY\n");
1175 return ShellView_OnNotify(pThis,(UINT)wParam, (LPNMHDR)lParam);
1177 case WM_SETTINGCHANGE:
1178 TRACE(shell,"-- WM_SETTINGCHANGE\n");
1179 return ShellView_OnSettingChange(pThis,(LPCSTR)lParam);
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;
1188 break;
1190 default:
1191 TRACE(shell,"-- message %s unhandled\n", SPY_GetMsgName(uMessage));
1192 break;
1194 return DefWindowProcA (hWnd, uMessage, wParam, lParam);
1196 /**************************************************************************
1199 * The INTERFACE of the IShellView object
1202 ***************************************************************************
1203 * IShellView_QueryInterface
1205 static HRESULT WINAPI IShellView_fnQueryInterface(IShellView * iface,REFIID riid, LPVOID *ppvObj)
1207 ICOM_THIS(IShellViewImpl, iface);
1209 char xriid[50];
1210 WINE_StringFromCLSID((LPCLSID)riid,xriid);
1211 TRACE(shell,"(%p)->(\n\tIID:\t%s,%p)\n",This,xriid,ppvObj);
1213 *ppvObj = NULL;
1215 if(IsEqualIID(riid, &IID_IUnknown)) /*IUnknown*/
1216 { *ppvObj = This;
1218 else if(IsEqualIID(riid, &IID_IShellView)) /*IShellView*/
1219 { *ppvObj = (IShellView*)This;
1222 if(*ppvObj)
1223 { IShellView_AddRef( (IShellView*) *ppvObj);
1224 TRACE(shell,"-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
1225 return S_OK;
1227 TRACE(shell,"-- Interface: E_NOINTERFACE\n");
1228 return E_NOINTERFACE;
1231 /**************************************************************************
1232 * IShellView::AddRef
1234 static ULONG WINAPI IShellView_fnAddRef(IShellView * iface)
1236 ICOM_THIS(IShellViewImpl, iface);
1238 TRACE(shell,"(%p)->(count=%lu)\n",This,This->ref);
1240 shell32_ObjCount++;
1241 return ++(This->ref);
1243 /**************************************************************************
1244 * IShellView_Release
1246 static ULONG WINAPI IShellView_fnRelease(IShellView * iface)
1248 ICOM_THIS(IShellViewImpl, iface);
1250 TRACE(shell,"(%p)->()\n",This);
1252 shell32_ObjCount--;
1253 if (!--(This->ref))
1254 { TRACE(shell," destroying IShellView(%p)\n",This);
1256 if(This->pSFParent)
1257 IShellFolder_Release(This->pSFParent);
1259 if (This->aSelectedItems)
1260 SHFree(This->aSelectedItems);
1262 if (This->pCommDlgBrowser)
1263 ICommDlgBrowser_Release(This->pCommDlgBrowser);
1265 HeapFree(GetProcessHeap(),0,This);
1266 return 0;
1268 return This->ref;
1270 /**************************************************************************
1271 * ShellView_GetWindow
1273 static HRESULT WINAPI IShellView_fnGetWindow(IShellView * iface,HWND * phWnd)
1275 ICOM_THIS(IShellViewImpl, iface);
1277 TRACE(shell,"(%p)\n",This);
1279 *phWnd = This->hWnd;
1281 return S_OK;
1284 static HRESULT WINAPI IShellView_fnContextSensitiveHelp(IShellView * iface,BOOL fEnterMode)
1286 ICOM_THIS(IShellViewImpl, iface);
1288 FIXME(shell,"(%p) stub\n",This);
1290 return E_NOTIMPL;
1292 /**************************************************************************
1293 * IShellView_TranslateAccelerator
1295 * FIXME:
1296 * use the accel functions
1298 static HRESULT WINAPI IShellView_fnTranslateAccelerator(IShellView * iface,LPMSG lpmsg)
1300 ICOM_THIS(IShellViewImpl, iface);
1302 FIXME(shell,"(%p)->(%p: hwnd=%x msg=%x lp=%lx wp=%x) stub\n",This,lpmsg, lpmsg->hwnd, lpmsg->message, lpmsg->lParam, lpmsg->wParam);
1305 switch (lpmsg->message)
1306 { case WM_KEYDOWN: TRACE(shell,"-- key=0x04%x",lpmsg->wParam) ;
1308 return S_FALSE;
1311 static HRESULT WINAPI IShellView_fnEnableModeless(IShellView * iface,BOOL fEnable)
1313 ICOM_THIS(IShellViewImpl, iface);
1315 FIXME(shell,"(%p) stub\n",This);
1317 return E_NOTIMPL;
1320 static HRESULT WINAPI IShellView_fnUIActivate(IShellView * iface,UINT uState)
1322 ICOM_THIS(IShellViewImpl, iface);
1324 CHAR szName[MAX_PATH];
1325 LRESULT lResult;
1326 int nPartArray[1] = {-1};
1328 TRACE(shell,"(%p)->(state=%x) stub\n",This, uState);
1329 /*don't do anything if the state isn't really changing*/
1330 if(This->uState == uState)
1331 { return S_OK;
1334 /*OnActivate handles the menu merging and internal state*/
1335 ShellView_OnActivate(This, uState);
1337 /*remove the docking window*/
1338 if(g_bShowIDW)
1339 { ShellView_AddRemoveDockingWindow(This, FALSE);
1342 /*only do This if we are active*/
1343 if(uState != SVUIA_DEACTIVATE)
1344 { /*update the status bar */
1345 strcpy(szName, "dummy32");
1347 IShellFolder_GetFolderPath( This->pSFParent, szName + strlen(szName), sizeof(szName) - strlen(szName));
1349 /* set the number of parts */
1350 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_STATUS, SB_SETPARTS, 1,
1351 (LPARAM)nPartArray, &lResult);
1353 /* set the text for the parts */
1354 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_STATUS, SB_SETTEXTA,
1355 0, (LPARAM)szName, &lResult);
1357 /*add the docking window if necessary */
1358 if(g_bShowIDW)
1359 { ShellView_AddRemoveDockingWindow(This, TRUE);
1362 return S_OK;
1364 static HRESULT WINAPI IShellView_fnRefresh(IShellView * iface)
1366 ICOM_THIS(IShellViewImpl, iface);
1368 TRACE(shell,"(%p)\n",This);
1370 ListView_DeleteAllItems(This->hWndList);
1371 ShellView_FillList(This);
1373 return S_OK;
1375 static HRESULT WINAPI IShellView_fnCreateViewWindow(IShellView * iface, IShellView *lpPrevView,
1376 LPCFOLDERSETTINGS lpfs, IShellBrowser * psb, RECT * prcView, HWND *phWnd)
1378 ICOM_THIS(IShellViewImpl, iface);
1380 WNDCLASSA wc;
1381 *phWnd = 0;
1384 TRACE(shell,"(%p)->(shlview=%p set=%p shlbrs=%p rec=%p hwnd=%p) incomplete\n",This, lpPrevView,lpfs, psb, prcView, phWnd);
1385 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);
1387 /*set up the member variables*/
1388 This->pShellBrowser = psb;
1389 This->FolderSettings = *lpfs;
1391 /*get our parent window*/
1392 IShellBrowser_AddRef(This->pShellBrowser);
1393 IShellBrowser_GetWindow(This->pShellBrowser, &(This->hWndParent));
1395 /* try to get the ICommDlgBrowserInterface, adds a reference !!! */
1396 This->pCommDlgBrowser=NULL;
1397 if ( SUCCEEDED (IShellBrowser_QueryInterface( This->pShellBrowser,
1398 (REFIID)&IID_ICommDlgBrowser, (LPVOID*) &This->pCommDlgBrowser)))
1399 { TRACE(shell,"-- CommDlgBrowser\n");
1402 /*if our window class has not been registered, then do so*/
1403 if(!GetClassInfoA(shell32_hInstance, SV_CLASS_NAME, &wc))
1404 { ZeroMemory(&wc, sizeof(wc));
1405 wc.style = CS_HREDRAW | CS_VREDRAW;
1406 wc.lpfnWndProc = (WNDPROC) ShellView_WndProc;
1407 wc.cbClsExtra = 0;
1408 wc.cbWndExtra = 0;
1409 wc.hInstance = shell32_hInstance;
1410 wc.hIcon = 0;
1411 wc.hCursor = LoadCursorA (0, IDC_ARROWA);
1412 wc.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);
1413 wc.lpszMenuName = NULL;
1414 wc.lpszClassName = SV_CLASS_NAME;
1416 if(!RegisterClassA(&wc))
1417 return E_FAIL;
1420 *phWnd = CreateWindowExA(0, SV_CLASS_NAME, NULL, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS,
1421 prcView->left, prcView->top, prcView->right - prcView->left, prcView->bottom - prcView->top,
1422 This->hWndParent, 0, shell32_hInstance, (LPVOID)This);
1424 MergeToolBar(This);
1426 if(!*phWnd)
1427 return E_FAIL;
1429 return S_OK;
1432 static HRESULT WINAPI IShellView_fnDestroyViewWindow(IShellView * iface)
1434 ICOM_THIS(IShellViewImpl, iface);
1436 TRACE(shell,"(%p)\n",This);
1438 /*Make absolutely sure all our UI is cleaned up.*/
1439 IShellView_UIActivate((IShellView*)This, SVUIA_DEACTIVATE);
1440 if(This->hMenu)
1441 { DestroyMenu(This->hMenu);
1443 DestroyWindow(This->hWnd);
1444 IShellBrowser_Release(This->pShellBrowser);
1445 return S_OK;
1448 static HRESULT WINAPI IShellView_fnGetCurrentInfo(IShellView * iface, LPFOLDERSETTINGS lpfs)
1450 ICOM_THIS(IShellViewImpl, iface);
1452 TRACE(shell,"(%p)->(%p) vmode=%x flags=%x\n",This, lpfs,
1453 This->FolderSettings.ViewMode, This->FolderSettings.fFlags);
1455 if (lpfs)
1456 { *lpfs = This->FolderSettings;
1457 return NOERROR;
1459 else
1460 return E_INVALIDARG;
1463 static HRESULT WINAPI IShellView_fnAddPropertySheetPages(IShellView * iface, DWORD dwReserved,LPFNADDPROPSHEETPAGE lpfn, LPARAM lparam)
1465 ICOM_THIS(IShellViewImpl, iface);
1467 FIXME(shell,"(%p) stub\n",This);
1469 return E_NOTIMPL;
1472 static HRESULT WINAPI IShellView_fnSaveViewState(IShellView * iface)
1474 ICOM_THIS(IShellViewImpl, iface);
1476 FIXME(shell,"(%p) stub\n",This);
1478 return S_OK;
1481 static HRESULT WINAPI IShellView_fnSelectItem(IShellView * iface, LPCITEMIDLIST pidlItem, UINT uFlags)
1482 { ICOM_THIS(IShellViewImpl, iface);
1484 FIXME(shell,"(%p)->(pidl=%p, 0x%08x) stub\n",This, pidlItem, uFlags);
1486 return E_NOTIMPL;
1489 static HRESULT WINAPI IShellView_fnGetItemObject(IShellView * iface, UINT uItem, REFIID riid, LPVOID *ppvOut)
1491 ICOM_THIS(IShellViewImpl, iface);
1493 LPUNKNOWN pObj = NULL;
1494 char xriid[50];
1496 WINE_StringFromCLSID((LPCLSID)riid,xriid);
1497 TRACE(shell,"(%p)->(uItem=0x%08x,\n\tIID=%s, ppv=%p)\n",This, uItem, xriid, ppvOut);
1499 *ppvOut = NULL;
1500 if(IsEqualIID(riid, &IID_IContextMenu))
1501 { ShellView_GetSelections(This);
1502 pObj =(LPUNKNOWN)IContextMenu_Constructor(This->pSFParent,This->aSelectedItems,This->uSelected);
1504 else if (IsEqualIID(riid, &IID_IDataObject))
1505 { ShellView_GetSelections(This);
1506 pObj =(LPUNKNOWN)IDataObject_Constructor(This->hWndParent, This->pSFParent,This->aSelectedItems,This->uSelected);
1509 TRACE(shell,"-- (%p)->(interface=%p)\n",This, ppvOut);
1511 if(!pObj)
1512 return E_OUTOFMEMORY;
1513 *ppvOut = pObj;
1514 return S_OK;
1517 static struct ICOM_VTABLE(IShellView) svvt =
1518 { IShellView_fnQueryInterface,
1519 IShellView_fnAddRef,
1520 IShellView_fnRelease,
1521 IShellView_fnGetWindow,
1522 IShellView_fnContextSensitiveHelp,
1523 IShellView_fnTranslateAccelerator,
1524 IShellView_fnEnableModeless,
1525 IShellView_fnUIActivate,
1526 IShellView_fnRefresh,
1527 IShellView_fnCreateViewWindow,
1528 IShellView_fnDestroyViewWindow,
1529 IShellView_fnGetCurrentInfo,
1530 IShellView_fnAddPropertySheetPages,
1531 IShellView_fnSaveViewState,
1532 IShellView_fnSelectItem,
1533 IShellView_fnGetItemObject