static HRESULT create_folder(NewMenuImpl *This, IShellView *view) { IFolderView *folder_view = NULL; IShellFolder *desktop = NULL; IShellFolder *parent = NULL; ISFHelper *helper = NULL; LPITEMIDLIST pidl = NULL; WCHAR nameW[MAX_PATH]; HRESULT hr; if (view) { hr = IShellView_QueryInterface(view, &IID_IFolderView, (void **)&folder_view); if (FAILED(hr)) return hr; hr = IFolderView_GetFolder(folder_view, &IID_IShellFolder, (void **)&parent); if (FAILED(hr)) goto out; } else { hr = SHGetDesktopFolder(&desktop); if (FAILED(hr)) goto out; hr = IShellFolder_BindToObject(desktop, This->pidl, NULL, &IID_IShellFolder, (void **)&parent); if (FAILED(hr)) goto out; } IShellFolder_QueryInterface(parent, &IID_ISFHelper, (void **)&helper); if (FAILED(hr)) goto out; hr = ISFHelper_GetUniqueName(helper, nameW, MAX_PATH); if (FAILED(hr)) goto out; hr = ISFHelper_AddFolder(helper, 0, nameW, &pidl); if (FAILED(hr)) goto out; if (view) { IShellView_SelectItem(view, pidl, SVSI_DESELECTOTHERS | SVSI_EDIT | SVSI_ENSUREVISIBLE | SVSI_FOCUSED | SVSI_SELECT); } out: if (pidl) SHFree(pidl); if (helper) ISFHelper_Release(helper); if (parent) IShellFolder_Release(parent); if (desktop) IShellFolder_Release(desktop); if (folder_view) IFolderView_Release(folder_view); return hr; }
static void test_GetSetCurrentViewMode(void) { IShellFolder *desktop; IShellView *sview; IFolderView *fview; IShellBrowser *browser; FOLDERSETTINGS fs; UINT viewmode; HWND hwnd; RECT rc = {0, 0, 10, 10}; HRESULT hr; UINT i; static const int winxp_res[11] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; static const int win2k3_res[11] = {0, 1, 2, 3, 4, 5, 6, 5, 8, 0, 0}; static const int vista_res[11] = {0, 1, 5, 3, 4, 5, 6, 7, 7, 0, 0}; static const int win7_res[11] = {1, 1, 1, 3, 4, 1, 6, 1, 8, 8, 8}; hr = SHGetDesktopFolder(&desktop); ok(hr == S_OK, "got (0x%08x)\n", hr); hr = IShellFolder_CreateViewObject(desktop, NULL, &IID_IShellView, (void**)&sview); ok(hr == S_OK, "got (0x%08x)\n", hr); fs.ViewMode = 1; fs.fFlags = 0; browser = IShellBrowserImpl_Construct(); hr = IShellView_CreateViewWindow(sview, NULL, &fs, browser, &rc, &hwnd); ok(hr == S_OK || broken(hr == S_FALSE /*Win2k*/ ), "got (0x%08x)\n", hr); hr = IShellView_QueryInterface(sview, &IID_IFolderView, (void**)&fview); ok(hr == S_OK || broken(hr == E_NOINTERFACE), "got (0x%08x)\n", hr); if(SUCCEEDED(hr)) { HWND hwnd_lv; UINT count; if(0) { /* Crashes under Win7/WinXP */ hr = IFolderView_GetCurrentViewMode(fview, NULL); } hr = IFolderView_GetCurrentViewMode(fview, &viewmode); ok(hr == S_OK, "got (0x%08x)\n", hr); ok(viewmode == 1, "ViewMode was %d\n", viewmode); hr = IFolderView_SetCurrentViewMode(fview, FVM_AUTO); ok(hr == S_OK, "got (0x%08x)\n", hr); hr = IFolderView_SetCurrentViewMode(fview, 0); ok(hr == E_INVALIDARG || broken(hr == S_OK), "got (0x%08x)\n", hr); hr = IFolderView_GetCurrentViewMode(fview, &viewmode); ok(hr == S_OK, "got (0x%08x)\n", hr); for(i = 1; i < 9; i++) { hr = IFolderView_SetCurrentViewMode(fview, i); ok(hr == S_OK || (i == 8 && hr == E_INVALIDARG /*Vista*/), "(%d) got (0x%08x)\n", i, hr); hr = IFolderView_GetCurrentViewMode(fview, &viewmode); ok(hr == S_OK, "(%d) got (0x%08x)\n", i, hr); /* Wine currently behaves like winxp here. */ ok((viewmode == win7_res[i]) || (viewmode == vista_res[i]) || (viewmode == win2k3_res[i]) || (viewmode == winxp_res[i]), "(%d) got %d\n",i , viewmode); } hr = IFolderView_SetCurrentViewMode(fview, 9); ok(hr == E_INVALIDARG || broken(hr == S_OK), "got (0x%08x)\n", hr); /* Test messages */ hwnd_lv = subclass_listview(hwnd); ok(hwnd_lv != NULL, "Failed to subclass listview\n"); if(hwnd_lv) { /* Vista seems to set the viewmode by other means than sending messages. At least no related messages are captured by subclassing. */ BOOL vista_plus = FALSE; static const UINT vista_plus_msgs[] = { WM_SETREDRAW, WM_NOTIFY, WM_NOTIFYFORMAT, WM_QUERYUISTATE, WM_MENUCHAR, WM_WINDOWPOSCHANGING, WM_NCCALCSIZE, WM_WINDOWPOSCHANGED, WM_PARENTNOTIFY, LVM_GETHEADER, 0 }; flush_sequences(sequences, NUM_MSG_SEQUENCES); hr = IFolderView_SetCurrentViewMode(fview, 1); ok(hr == S_OK, "got 0x%08x\n", hr); /* WM_SETREDRAW is not sent in versions before Vista. */ vista_plus = get_msg_count(sequences, LISTVIEW_SEQ_INDEX, WM_SETREDRAW); if(vista_plus) verify_msgs_in(sequences[LISTVIEW_SEQ_INDEX], vista_plus_msgs); else ok_sequence(sequences, LISTVIEW_SEQ_INDEX, folderview_setcurrentviewmode1_2_prevista, "IFolderView::SetCurrentViewMode(1)", TRUE); hr = IFolderView_SetCurrentViewMode(fview, 2); ok(hr == S_OK, "got 0x%08x\n", hr); if(vista_plus) verify_msgs_in(sequences[LISTVIEW_SEQ_INDEX], vista_plus_msgs); else ok_sequence(sequences, LISTVIEW_SEQ_INDEX, folderview_setcurrentviewmode1_2_prevista, "IFolderView::SetCurrentViewMode(2)", TRUE); hr = IFolderView_SetCurrentViewMode(fview, 3); ok(hr == S_OK, "got 0x%08x\n", hr); if(vista_plus) verify_msgs_in(sequences[LISTVIEW_SEQ_INDEX], vista_plus_msgs); else ok_sequence(sequences, LISTVIEW_SEQ_INDEX, folderview_setcurrentviewmode3_prevista, "IFolderView::SetCurrentViewMode(3)", TRUE); hr = IFolderView_SetCurrentViewMode(fview, 4); ok(hr == S_OK, "got 0x%08x\n", hr); if(vista_plus) verify_msgs_in(sequences[LISTVIEW_SEQ_INDEX], vista_plus_msgs); else ok_sequence(sequences, LISTVIEW_SEQ_INDEX, folderview_setcurrentviewmode4_prevista, "IFolderView::SetCurrentViewMode(4)", TRUE); hr = IFolderView_SetCurrentViewMode(fview, 5); ok(hr == S_OK, "got 0x%08x\n", hr); todo_wine { if(vista_plus) { verify_msgs_in(sequences[LISTVIEW_SEQ_INDEX], vista_plus_msgs); } else { count = get_msg_count(sequences, LISTVIEW_SEQ_INDEX, LVM_SETVIEW); ok(count == 1, "LVM_SETVIEW sent %d times.\n", count); count = get_msg_count(sequences, LISTVIEW_SEQ_INDEX, LVM_SETEXTENDEDLISTVIEWSTYLE); ok(count == 1 || count == 2, "LVM_SETEXTENDEDLISTVIEWSTYLE sent %d times.\n", count); flush_sequences(sequences, NUM_MSG_SEQUENCES); } } hr = IFolderView_SetCurrentViewMode(fview, 6); ok(hr == S_OK, "got 0x%08x\n", hr); todo_wine { if(vista_plus) { verify_msgs_in(sequences[LISTVIEW_SEQ_INDEX], vista_plus_msgs); } else { count = get_msg_count(sequences, LISTVIEW_SEQ_INDEX, LVM_SETVIEW); ok(count == 1, "LVM_SETVIEW sent %d times.\n", count); count = get_msg_count(sequences, LISTVIEW_SEQ_INDEX, LVM_SETEXTENDEDLISTVIEWSTYLE); ok(count == 1 || count == 2, "LVM_SETEXTENDEDLISTVIEWSTYLE sent %d times.\n", count); flush_sequences(sequences, NUM_MSG_SEQUENCES); } } hr = IFolderView_SetCurrentViewMode(fview, 7); ok(hr == S_OK, "got 0x%08x\n", hr); todo_wine { if(vista_plus) { verify_msgs_in(sequences[LISTVIEW_SEQ_INDEX], vista_plus_msgs); } else { count = get_msg_count(sequences, LISTVIEW_SEQ_INDEX, LVM_SETVIEW); ok(count == 1, "LVM_SETVIEW sent %d times.\n", count); count = get_msg_count(sequences, LISTVIEW_SEQ_INDEX, LVM_SETEXTENDEDLISTVIEWSTYLE); ok(count == 2, "LVM_SETEXTENDEDLISTVIEWSTYLE sent %d times.\n", count); flush_sequences(sequences, NUM_MSG_SEQUENCES); } } hr = IFolderView_SetCurrentViewMode(fview, 8); ok(hr == S_OK || broken(hr == E_INVALIDARG /* Vista */), "got 0x%08x\n", hr); todo_wine { if(vista_plus) { verify_msgs_in(sequences[LISTVIEW_SEQ_INDEX], vista_plus_msgs); } else { count = get_msg_count(sequences, LISTVIEW_SEQ_INDEX, LVM_SETVIEW); ok(count == 1, "LVM_SETVIEW sent %d times.\n", count); count = get_msg_count(sequences, LISTVIEW_SEQ_INDEX, LVM_SETEXTENDEDLISTVIEWSTYLE); ok(count == 2, "LVM_SETEXTENDEDLISTVIEWSTYLE sent %d times.\n", count); flush_sequences(sequences, NUM_MSG_SEQUENCES); } } hr = IFolderView_GetCurrentViewMode(fview, &viewmode); ok(hr == S_OK, "Failed to get current viewmode.\n"); ok_sequence(sequences, LISTVIEW_SEQ_INDEX, empty_seq, "IFolderView::GetCurrentViewMode", FALSE); } IFolderView_Release(fview); } else {
static void test_IFolderView(void) { IShellFolder *desktop, *folder; FOLDERSETTINGS settings; IShellView *view; IShellBrowser *browser; IFolderView *fv; HWND hwnd_view, hwnd_list; PITEMID_CHILD pidl; HRESULT hr; INT ret, count; POINT pt; LONG ref1, ref2; RECT r; hr = SHGetDesktopFolder(&desktop); ok(hr == S_OK, "got (0x%08x)\n", hr); hr = IShellFolder_CreateViewObject(desktop, NULL, &IID_IShellView, (void**)&view); ok(hr == S_OK, "got (0x%08x)\n", hr); hr = IShellView_QueryInterface(view, &IID_IFolderView, (void**)&fv); if (hr != S_OK) { win_skip("IFolderView not supported by desktop folder\n"); IShellView_Release(view); IShellFolder_Release(desktop); return; } /* call methods before window creation */ hr = IFolderView_GetSpacing(fv, NULL); ok(hr == S_FALSE || broken(hr == S_OK) /* win7 */, "got (0x%08x)\n", hr); pidl = (void*)0xdeadbeef; hr = IFolderView_Item(fv, 0, &pidl); ok(hr == E_INVALIDARG || broken(hr == E_FAIL) /* < Vista */, "got (0x%08x)\n", hr); ok(pidl == 0 || broken(pidl == (void*)0xdeadbeef) /* < Vista */, "got %p\n", pidl); if (0) { /* crashes on Vista and Win2k8 - List not created yet case */ hr = IFolderView_GetSpacing(fv, &pt); /* crashes on XP */ hr = IFolderView_GetSelectionMarkedItem(fv, NULL); hr = IFolderView_GetFocusedItem(fv, NULL); /* crashes on Vista+ */ hr = IFolderView_Item(fv, 0, NULL); } browser = IShellBrowserImpl_Construct(); settings.ViewMode = FVM_ICON; settings.fFlags = 0; hwnd_view = (HWND)0xdeadbeef; r.left = r.top = 0; r.right = r.bottom = 100; hr = IShellView_CreateViewWindow(view, NULL, &settings, browser, &r, &hwnd_view); ok(hr == S_OK, "got (0x%08x)\n", hr); ok(IsWindow(hwnd_view), "got %p\n", hwnd_view); hwnd_list = subclass_listview(hwnd_view); if (!hwnd_list) { win_skip("Failed to subclass ListView control\n"); IShellBrowser_Release(browser); IFolderView_Release(fv); IShellView_Release(view); IShellFolder_Release(desktop); return; } /* IFolderView::GetSpacing */ flush_sequences(sequences, NUM_MSG_SEQUENCES); hr = IFolderView_GetSpacing(fv, NULL); ok(hr == S_OK, "got (0x%08x)\n", hr); ok_sequence(sequences, LISTVIEW_SEQ_INDEX, empty_seq, "IFolderView::GetSpacing, empty", FALSE); flush_sequences(sequences, NUM_MSG_SEQUENCES); hr = IFolderView_GetSpacing(fv, &pt); ok(hr == S_OK, "got (0x%08x)\n", hr); /* fails with empty sequence on win7 for unknown reason */ if (sequences[LISTVIEW_SEQ_INDEX]->count) { ok_sequence(sequences, LISTVIEW_SEQ_INDEX, folderview_getspacing_seq, "IFolderView::GetSpacing", FALSE); ok(pt.x > 0, "got %d\n", pt.x); ok(pt.y > 0, "got %d\n", pt.y); ret = SendMessageA(hwnd_list, LVM_GETITEMSPACING, 0, 0); ok(pt.x == LOWORD(ret) && pt.y == HIWORD(ret), "got (%d, %d)\n", LOWORD(ret), HIWORD(ret)); } /* IFolderView::ItemCount */ if (0) { /* crashes on XP */ hr = IFolderView_ItemCount(fv, SVGIO_ALLVIEW, NULL); } flush_sequences(sequences, NUM_MSG_SEQUENCES); hr = IFolderView_ItemCount(fv, SVGIO_ALLVIEW, &count); ok(hr == S_OK, "got (0x%08x)\n", hr); ok_sequence(sequences, LISTVIEW_SEQ_INDEX, count ? folderview_itemcount_seq : empty_seq, "IFolderView::ItemCount", FALSE); /* IFolderView::GetSelectionMarkedItem */ if (0) { /* crashes on XP */ hr = IFolderView_GetSelectionMarkedItem(fv, NULL); } flush_sequences(sequences, NUM_MSG_SEQUENCES); hr = IFolderView_GetSelectionMarkedItem(fv, &ret); if (count) ok(hr == S_OK, "got (0x%08x)\n", hr); else ok(hr == S_FALSE, "got (0x%08x)\n", hr); ok_sequence(sequences, LISTVIEW_SEQ_INDEX, folderview_getselectionmarked_seq, "IFolderView::GetSelectionMarkedItem", FALSE); /* IFolderView::GetFocusedItem */ flush_sequences(sequences, NUM_MSG_SEQUENCES); hr = IFolderView_GetFocusedItem(fv, &ret); if (count) ok(hr == S_OK, "got (0x%08x)\n", hr); else ok(hr == S_FALSE, "got (0x%08x)\n", hr); ok_sequence(sequences, LISTVIEW_SEQ_INDEX, folderview_getfocused_seq, "IFolderView::GetFocusedItem", FALSE); /* IFolderView::GetFolder, just return pointer */ if (0) { /* crashes on XP */ hr = IFolderView_GetFolder(fv, NULL, (void**)&folder); hr = IFolderView_GetFolder(fv, NULL, NULL); } hr = IFolderView_GetFolder(fv, &IID_IShellFolder, NULL); ok(hr == E_POINTER, "got (0x%08x)\n", hr); ref1 = IShellFolder_AddRef(desktop); IShellFolder_Release(desktop); hr = IFolderView_GetFolder(fv, &IID_IShellFolder, (void**)&folder); ok(hr == S_OK, "got (0x%08x)\n", hr); ref2 = IShellFolder_AddRef(desktop); IShellFolder_Release(desktop); ok(ref1 == ref2 || ref1 + 1 == ref2, /* >= vista */ "expected same refcount, got %d\n", ref2); ok(desktop == folder, "\n"); IShellBrowser_Release(browser); IFolderView_Release(fv); IShellView_Release(view); IShellFolder_Release(desktop); }