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