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