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