1 /* 2 * PROJECT: ReactOS API tests 3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+) 4 * PURPOSE: Test for IShellFolderViewCB 5 * COPYRIGHT: Copyright 2017 Mark Jansen (mark.jansen@reactos.org) 6 */ 7 8 #include "shelltest.h" 9 #include <atlsimpcoll.h> 10 #include <stdio.h> 11 #include <shellutils.h> 12 //#include <msgtrace.h> 13 14 static DWORD g_WinVersion; 15 #define WINVER_VISTA 0x0600 16 17 #ifndef SFVM_SELECTIONCHANGED 18 #define SFVM_SELECTIONCHANGED 8 /* undocumented */ 19 #define SFVM_DRAWMENUITEM 9 /* undocumented */ 20 #define SFVM_MEASUREMENUITEM 10 /* undocumented */ 21 #define SFVM_EXITMENULOOP 11 /* undocumented */ 22 #define SFVM_VIEWRELEASE 12 /* undocumented */ 23 #define SFVM_GETNAMELENGTH 13 /* undocumented */ 24 #define SFVM_WINDOWCLOSING 16 /* undocumented */ 25 #define SFVM_LISTREFRESHED 17 /* undocumented */ 26 #define SFVM_WINDOWFOCUSED 18 /* undocumented */ 27 #define SFVM_REGISTERCOPYHOOK 20 /* undocumented */ 28 #define SFVM_COPYHOOKCALLBACK 21 /* undocumented */ 29 #define SFVM_UNMERGEFROMMENU 28 /* undocumented */ 30 #define SFVM_ADDINGOBJECT 29 /* undocumented */ 31 #define SFVM_REMOVINGOBJECT 30 /* undocumented */ 32 #define SFVM_GETCOMMANDDIR 33 /* undocumented */ 33 #define SFVM_GETCOLUMNSTREAM 34 /* undocumented */ 34 #define SFVM_CANSELECTALL 35 /* undocumented */ 35 #define SFVM_ISSTRICTREFRESH 37 /* undocumented */ 36 #define SFVM_ISCHILDOBJECT 38 /* undocumented */ 37 #define SFVM_GETEXTVIEWS 40 /* undocumented */ 38 #define SFVM_GET_CUSTOMVIEWINFO 77 /* undocumented */ 39 #define SFVM_ENUMERATEDITEMS 79 /* undocumented */ 40 #define SFVM_GET_VIEW_DATA 80 /* undocumented */ 41 #define SFVM_GET_WEBVIEW_LAYOUT 82 /* undocumented */ 42 #define SFVM_GET_WEBVIEW_CONTENT 83 /* undocumented */ 43 #define SFVM_GET_WEBVIEW_TASKS 84 /* undocumented */ 44 #define SFVM_GET_WEBVIEW_THEME 86 /* undocumented */ 45 #define SFVM_GETDEFERREDVIEWSETTINGS 92 /* undocumented */ 46 #endif 47 48 #define DUM_MSG_GetWindow 400 49 #define DUM_MSG_ContextSensitiveHelp 401 50 #define DUM_MSG_InsertMenusSB 402 51 #define DUM_MSG_SetMenuSB 403 52 #define DUM_MSG_RemoveMenusSB 404 53 #define DUM_MSG_SetStatusTextSB 405 54 #define DUM_MSG_EnableModelessSB 406 55 #define DUM_MSG_TranslateAcceleratorSB 407 56 #define DUM_MSG_BrowseObject 408 57 #define DUM_MSG_GetViewStateStream 409 58 #define DUM_MSG_GetControlWindow 410 59 #define DUM_MSG_SendControlMsg 411 60 #define DUM_MSG_QueryActiveShellView 412 61 #define DUM_MSG_OnViewWindowActive 413 62 #define DUM_MSG_SetToolbarItems 414 63 64 65 const char* msg2str(UINT uMsg) 66 { 67 static char buf[2][50]; 68 static int index = 0; 69 index ^= 1; 70 71 switch (uMsg) 72 { 73 case SFVM_MERGEMENU: return "SFVM_MERGEMENU"; 74 case SFVM_INVOKECOMMAND: return "SFVM_INVOKECOMMAND"; 75 case SFVM_GETHELPTEXT: return "SFVM_GETHELPTEXT"; 76 case SFVM_GETTOOLTIPTEXT: return "SFVM_GETTOOLTIPTEXT"; 77 case SFVM_GETBUTTONINFO: return "SFVM_GETBUTTONINFO"; 78 case SFVM_GETBUTTONS: return "SFVM_GETBUTTONS"; 79 case SFVM_INITMENUPOPUP: return "SFVM_INITMENUPOPUP"; 80 case SFVM_SELECTIONCHANGED: return "SFVM_SELECTIONCHANGED"; 81 case SFVM_DRAWMENUITEM: return "SFVM_DRAWMENUITEM"; 82 case SFVM_MEASUREMENUITEM: return "SFVM_MEASUREMENUITEM"; 83 case SFVM_EXITMENULOOP: return "SFVM_EXITMENULOOP"; 84 case SFVM_VIEWRELEASE: return "SFVM_VIEWRELEASE"; 85 case SFVM_GETNAMELENGTH: return "SFVM_GETNAMELENGTH"; 86 case SFVM_FSNOTIFY: return "SFVM_FSNOTIFY"; 87 case SFVM_WINDOWCREATED: return "SFVM_WINDOWCREATED"; 88 case SFVM_WINDOWCLOSING: return "SFVM_WINDOWCLOSING"; 89 case SFVM_LISTREFRESHED: return "SFVM_LISTREFRESHED"; 90 case SFVM_WINDOWFOCUSED: return "SFVM_WINDOWFOCUSED"; 91 case SFVM_REGISTERCOPYHOOK: return "SFVM_REGISTERCOPYHOOK"; 92 case SFVM_COPYHOOKCALLBACK: return "SFVM_COPYHOOKCALLBACK"; 93 case SFVM_GETDETAILSOF: return "SFVM_GETDETAILSOF"; 94 case SFVM_COLUMNCLICK: return "SFVM_COLUMNCLICK"; 95 case SFVM_QUERYFSNOTIFY: return "SFVM_QUERYFSNOTIFY"; 96 case SFVM_DEFITEMCOUNT: return "SFVM_DEFITEMCOUNT"; 97 case SFVM_DEFVIEWMODE: return "SFVM_DEFVIEWMODE"; 98 case SFVM_UNMERGEFROMMENU: return "SFVM_UNMERGEFROMMENU"; 99 case SFVM_ADDINGOBJECT: return "SFVM_ADDINGOBJECT"; 100 case SFVM_REMOVINGOBJECT: return "SFVM_REMOVINGOBJECT"; 101 case SFVM_UPDATESTATUSBAR: return "SFVM_UPDATESTATUSBAR"; 102 case SFVM_BACKGROUNDENUM: return "SFVM_BACKGROUNDENUM"; 103 case SFVM_GETCOMMANDDIR: return "SFVM_GETCOMMANDDIR"; 104 case SFVM_GETCOLUMNSTREAM: return "SFVM_GETCOLUMNSTREAM"; 105 case SFVM_CANSELECTALL: return "SFVM_CANSELECTALL"; 106 case SFVM_DIDDRAGDROP: return "SFVM_DIDDRAGDROP"; 107 case SFVM_ISSTRICTREFRESH: return "SFVM_ISSTRICTREFRESH"; 108 case SFVM_ISCHILDOBJECT: return "SFVM_ISCHILDOBJECT"; 109 case SFVM_SETISFV: return "SFVM_SETISFV"; 110 case SFVM_GETEXTVIEWS: return "SFVM_GETEXTVIEWS"; 111 case SFVM_THISIDLIST: return "SFVM_THISIDLIST"; 112 case SFVM_ADDPROPERTYPAGES: return "SFVM_ADDPROPERTYPAGES"; 113 case SFVM_BACKGROUNDENUMDONE: return "SFVM_BACKGROUNDENUMDONE"; 114 case SFVM_GETNOTIFY: return "SFVM_GETNOTIFY"; 115 case SFVM_GETSORTDEFAULTS: return "SFVM_GETSORTDEFAULTS"; 116 case SFVM_SIZE: return "SFVM_SIZE"; 117 case SFVM_GETZONE: return "SFVM_GETZONE"; 118 case SFVM_GETPANE: return "SFVM_GETPANE"; 119 case SFVM_GETHELPTOPIC: return "SFVM_GETHELPTOPIC"; 120 case SFVM_GETANIMATION: return "SFVM_GETANIMATION"; 121 case SFVM_GET_CUSTOMVIEWINFO: return "SFVM_GET_CUSTOMVIEWINFO"; 122 case SFVM_ENUMERATEDITEMS: return "SFVM_ENUMERATEDITEMS"; 123 case SFVM_GET_VIEW_DATA: return "SFVM_GET_VIEW_DATA"; 124 case SFVM_GET_WEBVIEW_LAYOUT: return "SFVM_GET_WEBVIEW_LAYOUT"; 125 case SFVM_GET_WEBVIEW_CONTENT: return "SFVM_GET_WEBVIEW_CONTENT"; 126 case SFVM_GET_WEBVIEW_TASKS: return "SFVM_GET_WEBVIEW_TASKS"; 127 case SFVM_GET_WEBVIEW_THEME: return "SFVM_GET_WEBVIEW_THEME"; 128 case SFVM_GETDEFERREDVIEWSETTINGS: return "SFVM_GET_WEBVIEW_THEME"; 129 130 case DUM_MSG_GetWindow: return "|GetWindow|"; 131 case DUM_MSG_ContextSensitiveHelp: return "|ContextSensitiveHelp|"; 132 case DUM_MSG_InsertMenusSB: return "|InsertMenusSB|"; 133 case DUM_MSG_SetMenuSB: return "|SetMenuSB|"; 134 case DUM_MSG_RemoveMenusSB: return "|RemoveMenusSB|"; 135 case DUM_MSG_SetStatusTextSB: return "|SetStatusTextSB|"; 136 case DUM_MSG_EnableModelessSB: return "|EnableModelessSB|"; 137 case DUM_MSG_TranslateAcceleratorSB: return "|TranslateAcceleratorSB|"; 138 case DUM_MSG_BrowseObject: return "|BrowseObject|"; 139 case DUM_MSG_GetViewStateStream: return "|GetViewStateStream|"; 140 case DUM_MSG_GetControlWindow: return "|GetControlWindow|"; 141 case DUM_MSG_SendControlMsg: return "|SendControlMsg|"; 142 case DUM_MSG_QueryActiveShellView: return "|QueryActiveShellView|"; 143 case DUM_MSG_OnViewWindowActive: return "|OnViewWindowActive|"; 144 case DUM_MSG_SetToolbarItems: return "|SetToolbarItems|"; 145 default: 146 sprintf(buf[index], "[%u]", uMsg); 147 return buf[index]; 148 } 149 } 150 151 152 #define PTR_VALUE 0xf7f7f7f7 153 154 struct message 155 { 156 message(UINT msg, WPARAM wp, LPARAM lp) : uMsg(msg), wParam(wp), lParam(lp) { ; } 157 158 UINT uMsg; 159 WPARAM wParam; 160 LPARAM lParam; 161 }; 162 163 CSimpleArray<message> g_Received; 164 165 void clear_list() 166 { 167 g_Received.RemoveAll(); 168 } 169 170 void add_msg(UINT uMsg, WPARAM wParam, LPARAM lParam) 171 { 172 g_Received.Add(message(uMsg, wParam, lParam)); 173 } 174 175 void print_list_(const CSimpleArray<message>& input, const char* file, int line) 176 { 177 trace_(file, line)("Got list:\n"); 178 for (int n = 0; n < input.GetSize(); ++n) 179 { 180 const message& msg = input[n]; 181 trace_(file, line)("msg: %d(%s), wParam:0x%x, lParam:0x%lx\n", msg.uMsg, msg2str(msg.uMsg), msg.wParam, msg.lParam); 182 } 183 trace_(file, line)("End of list.\n"); 184 } 185 186 void compare_list_(const CSimpleArray<message>& input, const message* compare, const char* file, int line) 187 { 188 int input_item = 0; 189 int compare_item = 0; 190 LONG old_failures = winetest_get_failures(); 191 while (compare[compare_item].uMsg && input_item < input.GetSize()) 192 { 193 const message& inp = input[input_item]; 194 const message& cmp = compare[compare_item]; 195 if (cmp.uMsg == inp.uMsg) 196 { 197 if (cmp.lParam != (LPARAM)PTR_VALUE) 198 { 199 ok_(file, line)(cmp.lParam == inp.lParam, "Expected lParam to be 0x%lx, was 0x%lx for %i(%s)\n", 200 cmp.lParam, inp.lParam, compare_item, msg2str(cmp.uMsg)); 201 } 202 else 203 { 204 ok_(file, line)(inp.lParam != 0, "Expected lParam to be a pointer, was 0 for %i(%s)\n", 205 compare_item, msg2str(cmp.uMsg)); 206 } 207 if (cmp.wParam != PTR_VALUE) 208 { 209 ok_(file, line)(cmp.wParam == inp.wParam, "Expected wParam to be 0x%x, was 0x%x for %i(%s)\n", 210 cmp.wParam, inp.wParam, compare_item, msg2str(cmp.uMsg)); 211 } 212 else 213 { 214 ok_(file, line)(inp.wParam != 0, "Expected wParam to be a pointer, was 0 for %i(%s)\n", 215 compare_item, msg2str(cmp.uMsg)); 216 } 217 compare_item++; 218 } 219 else 220 { 221 /* We skip unknown items for now */ 222 } 223 224 input_item++; 225 } 226 227 while (compare[compare_item].uMsg) 228 { 229 ok_(file, line)(0, "Message %i(%s) not found\n", compare_item, msg2str(compare[compare_item].uMsg)); 230 compare_item++; 231 } 232 if (old_failures != winetest_get_failures()) 233 { 234 print_list_(input, file, line); 235 } 236 } 237 238 #define compare_list(cmp) compare_list_(g_Received, cmp, __FILE__, __LINE__) 239 #define print_list() print_list_(g_Received, __FILE__, __LINE__) 240 241 242 LONG g_AddRef = 0; 243 LONG g_Release = 0; 244 245 class CFolderViewCB : 246 public IShellFolderViewCB 247 { 248 public: 249 CFolderViewCB(void) : 250 m_RefCount(1) 251 { 252 } 253 virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject) 254 { 255 if (riid == IID_IShellFolderViewCB) 256 { 257 *ppvObject = static_cast<IShellFolderViewCB*>(this); 258 AddRef(); 259 return S_OK; 260 } 261 return E_NOINTERFACE; 262 } 263 virtual ULONG STDMETHODCALLTYPE AddRef(void) 264 { 265 InterlockedIncrement(&g_AddRef); 266 return InterlockedIncrement(&m_RefCount); 267 } 268 virtual ULONG STDMETHODCALLTYPE Release(void) 269 { 270 InterlockedIncrement(&g_Release); 271 return InterlockedDecrement(&m_RefCount); 272 } 273 virtual HRESULT STDMETHODCALLTYPE MessageSFVCB(UINT uMsg, WPARAM wParam, LPARAM lParam) 274 { 275 //DbgPrint("MessageSFVCB(uMsg:%s, wParam:%u, lParam:%u\n", msg2str(uMsg), wParam, lParam); 276 add_msg(uMsg, wParam, lParam); 277 return E_NOTIMPL; 278 } 279 private: 280 LONG m_RefCount; 281 }; 282 283 284 static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) 285 { 286 if (msg == WM_DESTROY) 287 { 288 PostQuitMessage(0); 289 return 0; 290 } 291 return DefWindowProc(hwnd, msg, wParam, lParam); 292 } 293 294 295 class CDummyShellBrowser : public IShellBrowser 296 { 297 public: 298 HWND m_hwnd; 299 CDummyShellBrowser() 300 { 301 static const TCHAR* class_name = TEXT("DUMMY_TEST_CLASS"); 302 WNDCLASSEX wx = {}; 303 wx.cbSize = sizeof(WNDCLASSEX); 304 wx.lpfnWndProc = WndProc; 305 wx.hInstance = GetModuleHandle(NULL); 306 wx.lpszClassName = class_name; 307 wx.style = CS_DBLCLKS; 308 RegisterClassEx(&wx); 309 m_hwnd = CreateWindowEx(0, class_name, TEXT("dummy_name"), WS_OVERLAPPEDWINDOW, 0, 0, 0, 0, NULL, NULL, NULL, NULL); 310 ShowWindow(m_hwnd, SW_SHOW); 311 } 312 313 // *** IUnknown methods *** 314 virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject) 315 { 316 if (riid == IID_IShellBrowser || riid == IID_IUnknown) 317 { 318 *ppvObject = this; 319 return S_OK; 320 } 321 return E_NOINTERFACE; 322 } 323 virtual ULONG STDMETHODCALLTYPE AddRef(void) 324 { 325 return 2; 326 } 327 virtual ULONG STDMETHODCALLTYPE Release(void) 328 { 329 return 1; 330 } 331 332 // *** IOleWindow methods *** 333 virtual HRESULT STDMETHODCALLTYPE GetWindow(HWND *phwnd) 334 { 335 //DbgPrint("%s()\n", __FUNCTION__); 336 *phwnd = m_hwnd; 337 add_msg(DUM_MSG_GetWindow, NULL, NULL); 338 return S_OK; 339 } 340 virtual HRESULT STDMETHODCALLTYPE ContextSensitiveHelp(BOOL fEnterMode) 341 { 342 //DbgPrint("%s()\n", __FUNCTION__); 343 add_msg(DUM_MSG_ContextSensitiveHelp, NULL, NULL); 344 return E_NOTIMPL; 345 } 346 347 // *** IShellBrowser methods *** 348 virtual HRESULT STDMETHODCALLTYPE InsertMenusSB(HMENU hmenuShared, LPOLEMENUGROUPWIDTHS lpMenuWidths) 349 { 350 //DbgPrint("%s()\n", __FUNCTION__); 351 add_msg(DUM_MSG_InsertMenusSB, NULL, NULL); 352 return S_OK; 353 } 354 virtual HRESULT STDMETHODCALLTYPE SetMenuSB(HMENU hmenuShared, HOLEMENU holemenuRes, HWND hwndActiveObject) 355 { 356 //DbgPrint("%s()\n", __FUNCTION__); 357 add_msg(DUM_MSG_SetMenuSB, NULL, NULL); 358 return S_OK; 359 } 360 virtual HRESULT STDMETHODCALLTYPE RemoveMenusSB(HMENU hmenuShared) 361 { 362 //DbgPrint("%s()\n", __FUNCTION__); 363 add_msg(DUM_MSG_RemoveMenusSB, NULL, NULL); 364 return E_NOTIMPL; 365 } 366 virtual HRESULT STDMETHODCALLTYPE SetStatusTextSB(LPCWSTR pszStatusText) 367 { 368 //DbgPrint("%s()\n", __FUNCTION__); 369 add_msg(DUM_MSG_SetStatusTextSB, NULL, NULL); 370 return E_NOTIMPL; 371 } 372 virtual HRESULT STDMETHODCALLTYPE EnableModelessSB(BOOL fEnable) 373 { 374 //DbgPrint("%s()\n", __FUNCTION__); 375 add_msg(DUM_MSG_EnableModelessSB, NULL, NULL); 376 return E_NOTIMPL; 377 } 378 virtual HRESULT STDMETHODCALLTYPE TranslateAcceleratorSB(MSG *pmsg, WORD wID) 379 { 380 //DbgPrint("%s()\n", __FUNCTION__); 381 add_msg(DUM_MSG_TranslateAcceleratorSB, NULL, NULL); 382 return E_NOTIMPL; 383 } 384 virtual HRESULT STDMETHODCALLTYPE BrowseObject(PCUIDLIST_RELATIVE pidl,UINT wFlags) 385 { 386 //DbgPrint("%s()\n", __FUNCTION__); 387 add_msg(DUM_MSG_BrowseObject, NULL, NULL); 388 return E_NOTIMPL; 389 } 390 virtual HRESULT STDMETHODCALLTYPE GetViewStateStream(DWORD grfMode,IStream **ppStrm) 391 { 392 //DbgPrint("%s()\n", __FUNCTION__); 393 add_msg(DUM_MSG_GetViewStateStream, NULL, NULL); 394 return E_NOTIMPL; 395 } 396 virtual HRESULT STDMETHODCALLTYPE GetControlWindow(UINT id,HWND *phwnd) 397 { 398 //DbgPrint("%s()\n", __FUNCTION__); 399 add_msg(DUM_MSG_GetControlWindow, NULL, NULL); 400 return E_NOTIMPL; 401 } 402 virtual HRESULT STDMETHODCALLTYPE SendControlMsg(UINT id,UINT uMsg,WPARAM wParam,LPARAM lParam,LRESULT *pret) 403 { 404 //DbgPrint("%s()\n", __FUNCTION__); 405 add_msg(DUM_MSG_SendControlMsg, NULL, NULL); 406 return E_NOTIMPL; 407 } 408 virtual HRESULT STDMETHODCALLTYPE QueryActiveShellView(IShellView **ppshv) 409 { 410 //DbgPrint("%s()\n", __FUNCTION__); 411 add_msg(DUM_MSG_QueryActiveShellView, NULL, NULL); 412 return E_NOTIMPL; 413 } 414 virtual HRESULT STDMETHODCALLTYPE OnViewWindowActive(IShellView *pshv) 415 { 416 //DbgPrint("%s()\n", __FUNCTION__); 417 add_msg(DUM_MSG_OnViewWindowActive, NULL, NULL); 418 return E_NOTIMPL; 419 } 420 virtual HRESULT STDMETHODCALLTYPE SetToolbarItems(LPTBBUTTONSB lpButtons,UINT nButtons,UINT uFlags) 421 { 422 //DbgPrint("%s()\n", __FUNCTION__); 423 add_msg(DUM_MSG_SetToolbarItems, NULL, NULL); 424 return E_NOTIMPL; 425 } 426 }; 427 428 429 START_TEST(IShellFolderViewCB) 430 { 431 RTL_OSVERSIONINFOEXW rtlinfo = { sizeof(rtlinfo) }; 432 void (__stdcall* pRtlGetVersion)(RTL_OSVERSIONINFOEXW*); 433 pRtlGetVersion = (void (__stdcall*)(RTL_OSVERSIONINFOEXW*))GetProcAddress(GetModuleHandleA("ntdll"), "RtlGetVersion"); 434 pRtlGetVersion(&rtlinfo); 435 g_WinVersion = (rtlinfo.dwMajorVersion << 8) | rtlinfo.dwMinorVersion; 436 437 CoInitialize(NULL); 438 CFolderViewCB cb; 439 440 CComPtr<IShellFolder> desktop; 441 442 HRESULT hr = SHGetDesktopFolder(&desktop); 443 ok_hex(hr, S_OK); 444 if (!desktop) 445 return; 446 447 SFV_CREATE sfvc = { sizeof(sfvc), desktop }; 448 sfvc.psfvcb = &cb; 449 IShellView* psv = NULL; 450 451 g_AddRef = 0; 452 g_Release = 0; 453 454 hr = SHCreateShellFolderView(&sfvc, &psv); 455 ok_hex(hr, S_OK); 456 if (!SUCCEEDED(hr)) 457 return; 458 459 ok_int(g_AddRef, 1); 460 ok_int(g_Release, 0); 461 462 clear_list(); 463 464 HWND wnd; 465 RECT rc = { 0 }; 466 FOLDERSETTINGS fs = { FVM_DETAILS, 0 }; 467 CDummyShellBrowser dum; 468 hr = psv->CreateViewWindow(NULL, &fs, &dum, &rc, &wnd); 469 470 471 static message init_list[] = 472 { 473 /* ... */ 474 message(DUM_MSG_GetWindow, 0, 0), 475 /* Some unknown messages here, and multiple SFVM_GET_WEBVIEW_THEME + SFVM_GETSORTDEFAULTS + SFVM_GETCOLUMNSTREAM */ 476 message(SFVM_SIZE, 0, 0), 477 /* ... */ 478 message(DUM_MSG_InsertMenusSB, 0, 0), 479 message(SFVM_MERGEMENU, 0, PTR_VALUE), 480 message(DUM_MSG_SetMenuSB, 0, 0), 481 /* ... */ 482 message(SFVM_WINDOWCREATED, PTR_VALUE, 0), 483 /* ... */ 484 485 message(SFVM_GETBUTTONINFO, 0, PTR_VALUE), 486 message(SFVM_GETBUTTONS, PTR_VALUE, PTR_VALUE), 487 message(DUM_MSG_SetToolbarItems, 0, 0), 488 489 message(0, 0, 0) 490 }; 491 492 493 static message init_list_vista[] = 494 { 495 /* Some unknown messages here */ 496 message(DUM_MSG_GetWindow, 0, 0), 497 /* Some unknown messages here, and multiple SFVM_GET_WEBVIEW_THEME + SFVM_GETSORTDEFAULTS + SFVM_GETCOLUMNSTREAM */ 498 message(SFVM_SIZE, 0, 0), 499 message(SFVM_WINDOWCREATED, PTR_VALUE, 0), 500 /* Some unknown messages here */ 501 message(DUM_MSG_InsertMenusSB, 0, 0), 502 message(SFVM_MERGEMENU, 0, PTR_VALUE), 503 message(DUM_MSG_SetMenuSB, 0, 0), 504 505 message(0, 0, 0) 506 }; 507 508 if (g_WinVersion < WINVER_VISTA) 509 { 510 compare_list(init_list); 511 } 512 else 513 { 514 compare_list(init_list_vista); 515 } 516 clear_list(); 517 518 hr = psv->Refresh(); 519 //ok_hex(hr, S_FALSE); 520 521 static message refresh_list[] = 522 { 523 message(SFVM_LISTREFRESHED, 1, 0), 524 525 message(SFVM_UNMERGEFROMMENU, 0, PTR_VALUE), 526 message(DUM_MSG_SetMenuSB, 0, 0), 527 message(DUM_MSG_RemoveMenusSB, 0, 0), 528 message(DUM_MSG_InsertMenusSB, 0, 0), 529 message(SFVM_MERGEMENU, 0, PTR_VALUE), 530 message(DUM_MSG_SetMenuSB, 0, 0), 531 532 message(0, 0, 0) 533 }; 534 535 static message refresh_list_vista[] = 536 { 537 message(SFVM_LISTREFRESHED, 1, 0), 538 539 message(SFVM_UNMERGEFROMMENU, 0, PTR_VALUE), 540 message(DUM_MSG_SetMenuSB, 0, 0), 541 message(DUM_MSG_RemoveMenusSB, 0, 0), 542 message(DUM_MSG_InsertMenusSB, 0, 0), 543 message(SFVM_MERGEMENU, 0, PTR_VALUE), 544 message(DUM_MSG_SetMenuSB, 0, 0), 545 /* Some messages here, like SFVM_GET_WEBVIEW_THEME, SFVM_GETSORTDEFAULTS, SFVM_GETCOLUMNSTREAM */ 546 message(SFVM_UNMERGEFROMMENU, 0, PTR_VALUE), 547 message(DUM_MSG_SetMenuSB, 0, 0), 548 message(DUM_MSG_RemoveMenusSB, 0, 0), 549 message(DUM_MSG_InsertMenusSB, 0, 0), 550 message(SFVM_MERGEMENU, 0, PTR_VALUE), 551 message(DUM_MSG_SetMenuSB, 0, 0), 552 553 message(0, 0, 0) 554 }; 555 556 if (g_WinVersion < WINVER_VISTA) 557 { 558 compare_list(refresh_list); 559 } 560 else 561 { 562 compare_list(refresh_list_vista); 563 } 564 clear_list(); 565 566 hr = psv->DestroyViewWindow(); 567 568 static message destroy_list[] = 569 { 570 message(SFVM_UNMERGEFROMMENU, 0, PTR_VALUE), 571 message(DUM_MSG_SetMenuSB, 0, 0), 572 message(DUM_MSG_RemoveMenusSB, 0, 0), 573 message(SFVM_WINDOWCLOSING, PTR_VALUE, 0), 574 575 message(0, 0, 0) 576 }; 577 578 compare_list(destroy_list); 579 clear_list(); 580 581 CComPtr<IShellFolderView> folderView; 582 hr = psv->QueryInterface(IID_PPV_ARG(IShellFolderView, &folderView)); 583 ok_hex(hr, S_OK); 584 if (SUCCEEDED(hr)) 585 { 586 IShellFolderViewCB* oldPtr; 587 588 hr = folderView->SetCallback(NULL, &oldPtr); 589 ok_int(g_AddRef, 1); 590 ok_int(g_Release, 0); 591 592 /* Last pointer is not optional! */ 593 IShellFolderViewCB* oldPtr2; 594 hr = folderView->SetCallback(oldPtr, &oldPtr2); 595 ok_int(g_AddRef, 2); 596 ok_int(g_Release, 0); 597 } 598 599 ULONG refCount = psv->Release(); 600 ok(refCount == 1, "refCount = %lu\n", refCount); 601 602 static message release_list[] = 603 { 604 message(SFVM_VIEWRELEASE, 0, 0), 605 606 message(0, 0, 0) 607 }; 608 609 /* Investigate why this fails */ 610 if (refCount == 0) 611 { 612 compare_list(release_list); 613 } 614 } 615