std::wstring OsShell::toolTip(std::wstring itemPath) { ComInitializer comInitializer; std::replace(itemPath.begin(), itemPath.end(), '/', '\\'); std::wstring tipString; ITEMIDLIST * id = 0; HRESULT result = SHParseDisplayName(itemPath.c_str(), 0, &id, 0, 0); if (!SUCCEEDED(result) || !id) return tipString; CItemIdListReleaser idReleaser (id); LPCITEMIDLIST child = 0; IShellFolder * ifolder = 0; result = SHBindToParent(id, IID_IShellFolder, (void**)&ifolder, &child); if (!SUCCEEDED(result) || !child) return tipString; IQueryInfo* iQueryInfo = 0; if (SUCCEEDED(ifolder->GetUIObjectOf(NULL, 1, &child, IID_IQueryInfo, 0, (void**)&iQueryInfo)) && iQueryInfo) { LPWSTR lpszTip = 0; CComInterfaceReleaser releaser (iQueryInfo); if (SUCCEEDED(iQueryInfo->GetInfoTip(0, &lpszTip)) && lpszTip) { tipString = lpszTip; CoTaskMemFree(lpszTip); } } std::replace(tipString.begin(), tipString.end(), '\r', '\n'); return tipString; }
HRESULT WINAPI SHCreateItemFromParsingName(PCWSTR pszPath, IBindCtx *pbc, REFIID riid, void **ppv) { LPITEMIDLIST pidl; HRESULT ret; *ppv = NULL; ret = SHParseDisplayName(pszPath, pbc, &pidl, 0, NULL); if(SUCCEEDED(ret)) { ShellItem *This; ret = IShellItem_Constructor(NULL, riid, (void**)&This); if(SUCCEEDED(ret)) { This->pidl = pidl; *ppv = (void*)This; } else { ILFree(pidl); } } return ret; }
bool FolderBrowserDialog::SetRoot(const wchar_t * str) { bool ret = false; wchar_t* tstr = (wchar_t*)LocalAlloc(LPTR, sizeof(wchar_t)*MAX_WPATH); if (tstr) { if (SetBufFromDir(str, tstr, MAX_WPATH)) if (SHParseDisplayName(tstr, NULL, &root, NULL, NULL) == S_OK) ret = true; LocalFree(tstr); } return ret; }
bool ExploreToFile(LPCTSTR path) { CoInitializeHelper co; bool success = false; PIDLIST_ABSOLUTE pidl; if (FileExists(path) && SHParseDisplayName(path, nullptr, &pidl, 0, nullptr) == S_OK) { success = SUCCEEDED(SHOpenFolderAndSelectItems(pidl, 0, nullptr, 0)); CoTaskMemFree(pidl); } return success; }
bool prepareContextMenuForObjects(std::vector<std::wstring> objects, void * parentWindow, HMENU& hmenu, IContextMenu*& imenu) { ComInitializer comInitializer; if (objects.empty()) return false; std::vector<ITEMIDLIST*> ids; std::vector<LPCITEMIDLIST> relativeIds; IShellFolder * ifolder = 0; for (size_t i = 0; i < objects.size(); ++i) { std::replace(objects[i].begin(), objects[i].end(), '/', '\\'); ids.push_back(0); HRESULT result = SHParseDisplayName(objects[i].c_str(), 0, &ids.back(), 0, 0); if (!SUCCEEDED(result) || !ids.back()) { ids.pop_back(); continue; } relativeIds.push_back(0); result = SHBindToParent(ids.back(), IID_IShellFolder, (void**)&ifolder, &relativeIds.back()); if (!SUCCEEDED(result) || !relativeIds.back()) relativeIds.pop_back(); else if (i < objects.size() - 1 && ifolder) { ifolder->Release(); ifolder = nullptr; } } CItemIdArrayReleaser arrayReleaser(ids); assert_r(parentWindow); assert_and_return_message_r(ifolder, "Error getting ifolder", false); assert_and_return_message_r(!relativeIds.empty(), "RelativeIds is empty", false); imenu = 0; HRESULT result = ifolder->GetUIObjectOf((HWND)parentWindow, (UINT)relativeIds.size(), (const ITEMIDLIST **)relativeIds.data(), IID_IContextMenu, 0, (void**)&imenu); if (!SUCCEEDED(result) || !imenu) return false; hmenu = CreatePopupMenu(); if (!hmenu) return false; return (SUCCEEDED(imenu->QueryContextMenu(hmenu, 0, 1, 0x7FFF, CMF_NORMAL))); }
HRESULT WINAPI SHCreateItemFromParsingName(PCWSTR pszPath, IBindCtx *pbc, REFIID riid, void **ppv) { LPITEMIDLIST pidl; HRESULT ret; *ppv = NULL; ret = SHParseDisplayName(pszPath, pbc, &pidl, 0, NULL); if(SUCCEEDED(ret)) { ret = SHCreateItemFromIDList(pidl, riid, ppv); ILFree(pidl); } return ret; }
bool ExploreToFile(CString path) { bool success = false; HRESULT res = CoInitialize(NULL); if (res == S_OK || res == S_FALSE) { PIDLIST_ABSOLUTE pidl; if (SHParseDisplayName(path, NULL, &pidl, 0, NULL) == S_OK) { success = SUCCEEDED(SHOpenFolderAndSelectItems(pidl, 0, NULL, 0)); CoTaskMemFree(pidl); } CoUninitialize(); } return success; }
//TODO: // http://support.microsoft.com/kb/314853 // strParam.Format( _T( "/n, \"%s\"" ), szDirPath ); 或 .Format( _T( "/n, /select, \"%s\"" ), szFilePath ); // ::ShellExecute( NULL, _T( "open" ), _T( "explorer.exe" ), strParam, NULL, SW_SHOWNORMAL ); HRESULT CFShellUtil::ExplorerToSpecialFile(LPCTSTR pszFilePath) { HRESULT hr = E_FAIL; PIDLIST_RELATIVE pidl = NULL; //ULONG attributes = 0; SFGAOF sfgaofIn = 0, sfgaofOut = 0; CFConversion conv; COM_VERIFY(SHParseDisplayName(conv.TCHAR_TO_UTF16(pszFilePath), NULL, &pidl, sfgaofIn, &sfgaofOut)); if (SUCCEEDED(hr)) { COM_VERIFY(SHOpenFolderAndSelectItems(pidl, 0, NULL, 0)); //ILFree(pidl); CoTaskMemFree(pidl); pidl = NULL; } return hr; }
void WinConsole::ShowInExplorer(const char* filename) { BString<1024> fileName2 = filename; FileSystem::NormalizePathSeparators(fileName2); if (!FileSystem::FileExists(fileName2) && !FileSystem::DirectoryExists(fileName2)) { BString<1024> message("Directory or file %s doesn't exist (yet).", *fileName2); MessageBox(m_trayWindow, message, "Information", MB_ICONINFORMATION); return; } WString wideFilename = FileSystem::UtfPathToWidePath(fileName2); CoInitialize(nullptr); LPITEMIDLIST pidl; HRESULT H = SHParseDisplayName(wideFilename, nullptr, &pidl, 0, nullptr); H = SHOpenFolderAndSelectItems(pidl, 0, 0, 0); }
bool executeCommand(const UINT cmd, const csWStringList& files) { const csWString parallel = regReadParallel(); const DWORD parallelCount = regReadParallelCount(); const bool hasParallel = !parallel.empty() && parallelCount > 1; const DWORD flags = regReadFlags(); const bool isBatch = testFlags(flags, CMD_FLAG_BATCH); const bool isParallel = testFlags(flags, CMD_FLAG_PARALLEL) && hasParallel; const bool isUnc = testFlags(flags, CMD_FLAG_UNC) && cmd != Cmd_List; const bool isUnix = testFlags(flags, CMD_FLAG_UNIX); const csWString scriptPath = regReadScriptsPath(); const csWStringList scripts = regReadScripts(); if( cmd == Cmd_List || cmd == Cmd_ListWithPath || cmd == Cmd_ListWithPathTabular ) { int size = 0; for(csWStringList::const_iterator it = files.begin(); it != files.end(); it++) { wchar_t *uncName = 0; if( isUnc && (uncName = resolveUNC(it->c_str())) != 0 ) { size += lenFN(csWString(uncName), cmd); delete[] uncName; } else { size += lenFN(*it, cmd); } } wchar_t *text = new wchar_t[size+1]; if( text == 0 ) { return false; } int pos = 0; for(csWStringList::const_iterator it = files.begin(); it != files.end(); it++) { wchar_t *uncName = 0; if( isUnc && (uncName = resolveUNC(it->c_str())) != 0 ) { catFN(text, pos, csWString(uncName), cmd); delete[] uncName; } else { catFN(text, pos, *it, cmd); } } text[size] = L'\0'; if( files.size() == 1 ) { // Overwrite trailing <CR><LF> text[size-1] = text[size-2] = L'\0'; } if( isUnix ) { replace(text, size, L'\\', L'/'); } setClipboardText(text); delete[] text; return true; } else if( cmd == Cmd_CreateSymbolicLink ) { csWString symLink; IFileSaveDialog *saveDialog = NULL; HRESULT hr = CoCreateInstance(CLSID_FileSaveDialog, NULL, CLSCTX_INPROC_SERVER, IID_IFileSaveDialog, (LPVOID*)&saveDialog); if( hr == S_OK ) { saveDialog->SetTitle(L"Create symbolic link"); const int index = files.front().lastIndexOf(L'\\'); if( index >= 0 ) { const csWString path = files.front().mid(0, index); const csWString name = files.front().mid(index+1); PIDLIST_ABSOLUTE pidl = NULL; SHParseDisplayName(path.c_str(), NULL, &pidl, 0, NULL); if( pidl != NULL ) { IShellItem *item = NULL; SHCreateItemFromIDList(pidl, IID_IShellItem, (LPVOID*)&item); if( item != NULL ) { saveDialog->SetFolder(item); item->Release(); } CoTaskMemFree(pidl); } saveDialog->SetFileName(name.c_str()); } const COMDLG_FILTERSPEC filterSpec = { L"All files", L"*.*" }; saveDialog->SetFileTypes(1, &filterSpec); const FILEOPENDIALOGOPTIONS opts = FOS_OVERWRITEPROMPT | FOS_FORCEFILESYSTEM | FOS_PATHMUSTEXIST | FOS_CREATEPROMPT | FOS_NOREADONLYRETURN | FOS_NODEREFERENCELINKS | FOS_DONTADDTORECENT; saveDialog->SetOptions(opts); if( saveDialog->Show(NULL) == S_OK ) { IShellItem *item = NULL; if( saveDialog->GetResult(&item) == S_OK ) { wchar_t *filename = NULL; if( item->GetDisplayName(SIGDN_FILESYSPATH, &filename) == S_OK ) { symLink = filename; CoTaskMemFree(filename); } item->Release(); } } saveDialog->Release(); } if( !symLink.empty() ) { if( csFileExists(symLink.c_str()) ) { MessageBoxW(NULL, L"Symbolic link target already exists!", L"Error", MB_OK | MB_ICONERROR); return false; } const DWORD linkFlags = csIsDirectory(files.front().c_str()) ? SYMBOLIC_LINK_FLAG_DIRECTORY : 0; if( CreateSymbolicLinkW(symLink.c_str(), files.front().c_str(), linkFlags) == 0 ) { const DWORD lastError = GetLastError(); csWString msg(L"ERROR(0x"); msg += csWString::number(lastError, 16); msg += L"): "; msg += formatError(lastError); MessageBoxW(NULL, msg.c_str(), L"Error", MB_OK | MB_ICONERROR); return false; } } return true; } else if( cmd == Cmd_CheckBatchProcessing ) { regWriteFlags(flags ^ CMD_FLAG_BATCH); return true; } else if( cmd == Cmd_CheckParallelExecution ) { regWriteFlags(flags ^ CMD_FLAG_PARALLEL); return true; } else if( cmd == Cmd_CheckResolveUncPaths ) { regWriteFlags(flags ^ CMD_FLAG_UNC); return true; } else if( cmd == Cmd_CheckUnixPathSeparators ) { regWriteFlags(flags ^ CMD_FLAG_UNIX); return true; } else if( Cmd_ExecuteScripts <= cmd && cmd < Cmd_ExecuteScripts+scripts.size() ) { csWString script(scriptPath + L"\\"); UINT i = 0; for(csWStringList::const_iterator it = scripts.begin(); it != scripts.end(); it++) { if( i == cmd-Cmd_ExecuteScripts ) { script += *it; break; } i++; } if( isParallel ) { csWStringList args(files); args.push_front(script); args.push_front(csWString::number(parallelCount)); ShellExecuteW(NULL, L"open", parallel.c_str(), joinFileNames(args).c_str(), NULL, SW_SHOWNORMAL); } else { // DO NOT use parallelizer if( isBatch ) { const csWString args = joinFileNames(files); ShellExecuteW(NULL, L"open", script.c_str(), args.c_str(), NULL, SW_SHOWNORMAL); } else { // NO batch processing for(csWStringList::const_iterator it = files.begin(); it != files.end(); it++) { ShellExecuteW(NULL, L"open", script.c_str(), quoteFileName(*it).c_str(), NULL, SW_SHOWNORMAL); } } } return true; } return false; }
// this implementation was pretty much copied verbatime from // Tony Robinson's code in nsExternalProtocolWin.cpp nsresult nsMIMEInfoWin::LoadUriInternal(nsIURI * aURL) { nsresult rv = NS_OK; // 1. Find the default app for this protocol // 2. Set up the command line // 3. Launch the app. // For now, we'll just cheat essentially, check for the command line // then just call ShellExecute()! if (aURL) { // extract the url spec from the url nsCAutoString urlSpec; aURL->GetAsciiSpec(urlSpec); // Unescape non-ASCII characters in the URL nsCAutoString urlCharset; nsAutoString utf16Spec; rv = aURL->GetOriginCharset(urlCharset); NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr<nsITextToSubURI> textToSubURI = do_GetService(NS_ITEXTTOSUBURI_CONTRACTID, &rv); NS_ENSURE_SUCCESS(rv, rv); rv = textToSubURI->UnEscapeNonAsciiURI(urlCharset, urlSpec, utf16Spec); NS_ENSURE_SUCCESS(rv, rv); static const PRUnichar cmdVerb[] = L"open"; SHELLEXECUTEINFOW sinfo; memset(&sinfo, 0, sizeof(sinfo)); sinfo.cbSize = sizeof(sinfo); sinfo.fMask = SEE_MASK_FLAG_DDEWAIT | SEE_MASK_FLAG_NO_UI; sinfo.hwnd = NULL; sinfo.lpVerb = (LPWSTR)&cmdVerb; sinfo.nShow = SW_SHOWNORMAL; LPITEMIDLIST pidl = NULL; SFGAOF sfgao; // Bug 394974 if (SUCCEEDED(SHParseDisplayName(utf16Spec.get(),NULL, &pidl, 0, &sfgao))) { sinfo.lpIDList = pidl; sinfo.fMask |= SEE_MASK_INVOKEIDLIST; } else { // SHParseDisplayName failed. Bailing out as work around for // Microsoft Security Bulletin MS07-061 rv = NS_ERROR_FAILURE; } if (NS_SUCCEEDED(rv)) { BOOL result = ShellExecuteExW(&sinfo); if (!result || ((LONG_PTR)sinfo.hInstApp) < 32) rv = NS_ERROR_FAILURE; } if (pidl) CoTaskMemFree(pidl); } return rv; }
bool show() { #if defined(WIN32) std::wstring title16 = StringHelp::utf8_to_ucs2(title); std::wstring initial_directory16 = StringHelp::utf8_to_ucs2(initial_directory); if(is_vista_or_later()) { HRESULT result; ComPtr<IFileOpenDialog> open_dialog; result = CoCreateInstance(__uuidof(FileOpenDialog), NULL, CLSCTX_ALL, __uuidof(open_dialog), reinterpret_cast<void**>(open_dialog.output_variable())); throw_if_failed(result, "CoCreateInstance(FileOpenDialog) failed"); result = open_dialog->SetTitle(title16.c_str()); throw_if_failed(result, "IFileOpenDialog.SetTitle failed"); result = open_dialog->SetOptions(FOS_PICKFOLDERS | FOS_FORCEFILESYSTEM | FOS_PATHMUSTEXIST); throw_if_failed(result, "IFileOpenDialog.SetOptions((FOS_PICKFOLDERS) failed"); if(initial_directory16.length() > 0) { LPITEMIDLIST item_id_list = NULL; SFGAOF flags = 0; result = SHParseDisplayName(initial_directory16.c_str(), NULL, &item_id_list, SFGAO_FILESYSTEM, &flags); throw_if_failed(result, "SHParseDisplayName failed"); ComPtr<IShellItem> folder_item; result = SHCreateShellItem(NULL, NULL, item_id_list, folder_item.output_variable()); ILFree(item_id_list); throw_if_failed(result, "SHCreateItemFromParsingName failed"); /* This code requires Windows Vista or newer: ComPtr<IShellItem> folder_item; result = SHCreateItemFromParsingName(initial_directory16.c_str(), NULL, IID_PPV_ARGS(folder_item.output_variable())); throw_if_failed(result, "SHCreateItemFromParsingName failed"); */ if(!folder_item.is_null()) { result = open_dialog->SetFolder(folder_item); throw_if_failed(result, "IFileOpenDialog.SetFolder failed"); } } if(owner) result = open_dialog->Show(owner->get_display_window().get_hwnd()); else result = open_dialog->Show(0); if(SUCCEEDED(result)) { ComPtr<IShellItem> chosen_folder; result = open_dialog->GetResult(chosen_folder.output_variable()); throw_if_failed(result, "IFileOpenDialog.GetResult failed"); WCHAR *buffer = 0; result = chosen_folder->GetDisplayName(SIGDN_FILESYSPATH, &buffer); throw_if_failed(result, "IShellItem.GetDisplayName failed"); std::wstring output_directory16; try { output_directory16 = buffer; } catch (...) { CoTaskMemFree(buffer); throw; } CoTaskMemFree(buffer); selected_path = StringHelp::ucs2_to_utf8(output_directory16); return true; } else { return false; } } else { BROWSEINFO bi; ZeroMemory(&bi, sizeof(bi)); std::wstring::value_type path_buffer[FILENAME_MAX] = { 0 }; WCHAR Buffer[MAX_PATH]; memset(Buffer, 0, sizeof(WCHAR) * MAX_PATH); if(owner) bi.hwndOwner = owner->get_display_window().get_hwnd(); else bi.hwndOwner = 0; bi.pszDisplayName = Buffer; bi.lpszTitle = title16.c_str(); bi.ulFlags = BIF_EDITBOX | BIF_NEWDIALOGSTYLE | BIF_RETURNONLYFSDIRS | BIF_SHAREABLE; LPCITEMIDLIST pFolder = SHBrowseForFolder(&bi); if (pFolder == NULL) return false; if (!SHGetPathFromIDList(pFolder, path_buffer)) throw Exception("Bad path for Browse Folder Dialog"); selected_path = StringHelp::ucs2_to_utf8(path_buffer); return true; } #elif defined(__APPLE__) // To do: add cocoa code here return false; #elif defined(I_LOVE_AUTOHELL_AND_FIXED_THE_GTK_CHECK) if (!gtk_init_check(NULL, NULL)) throw Exception("gtk_init_check Failed!"); GtkWidget *dialog; dialog = gtk_file_chooser_dialog_new ("Open File", NULL, GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL); if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) { char *filename; filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog)); //printf("%s\n", filename); g_free (filename); } gtk_widget_destroy (dialog); unsigned int x_time = System::get_time(); while(true) { if(owner) XSync(owner->get_display_window().get_display(), True); gtk_main_iteration_do(FALSE); unsigned int x_time_now = System::get_time(); if ((x_time_now - x_time) > 250) break; } bool success = false; return success; #else return false; #endif }
void Dlg_MemBookmark::ExportJSON() { if ( g_pCurrentGameData->GetGameID() == 0 ) { MessageBox( nullptr, _T("ROM not loaded: please load a ROM first!"), _T("Error!"), MB_OK ); return; } if ( m_vBookmarks.size() == 0) { MessageBox( nullptr, _T("No bookmarks to save: please create a bookmark before attempting to save."), _T("Error!"), MB_OK ); return; } std::string defaultDir = RA_DIR_BOOKMARKS; defaultDir.erase ( 0, 2 ); // Removes the characters (".\\") defaultDir = g_sHomeDir + defaultDir; IFileSaveDialog* pDlg = nullptr; HRESULT hr = CoCreateInstance( CLSID_FileSaveDialog, NULL, CLSCTX_ALL, IID_IFileSaveDialog, reinterpret_cast<void**>( &pDlg ) ); if ( hr == S_OK ) { hr = pDlg->SetFileTypes( ARRAYSIZE( c_rgFileTypes ), c_rgFileTypes ); if ( hr == S_OK ) { char defaultFileName[ 512 ]; sprintf_s ( defaultFileName, 512, "%s-Bookmarks.txt", std::to_string( g_pCurrentGameData->GetGameID() ).c_str() ); hr = pDlg->SetFileName( Widen( defaultFileName ).c_str() ); if ( hr == S_OK ) { PIDLIST_ABSOLUTE pidl; hr = SHParseDisplayName( Widen( defaultDir ).c_str(), NULL, &pidl, SFGAO_FOLDER, 0 ); if ( hr == S_OK ) { IShellItem* pItem = nullptr; SHCreateShellItem( NULL, NULL, pidl, &pItem ); hr = pDlg->SetDefaultFolder( pItem ); if ( hr == S_OK ) { pDlg->SetDefaultExtension( L"txt" ); hr = pDlg->Show( nullptr ); if ( hr == S_OK ) { hr = pDlg->GetResult( &pItem ); if ( hr == S_OK ) { LPWSTR pStr = nullptr; hr = pItem->GetDisplayName( SIGDN_FILESYSPATH, &pStr ); if ( hr == S_OK ) { Document doc; Document::AllocatorType& allocator = doc.GetAllocator(); doc.SetObject(); Value bookmarks( kArrayType ); for ( MemBookmark* bookmark : m_vBookmarks ) { Value item( kObjectType ); char buffer[ 256 ]; sprintf_s( buffer, Narrow( bookmark->Description() ).c_str(), sizeof( buffer ) ); Value s( buffer, allocator ); item.AddMember( "Description", s, allocator ); item.AddMember( "Address", bookmark->Address(), allocator ); item.AddMember( "Type", bookmark->Type(), allocator ); item.AddMember( "Decimal", bookmark->Decimal(), allocator ); bookmarks.PushBack( item, allocator ); } doc.AddMember( "Bookmarks", bookmarks, allocator ); _WriteBufferToFile( Narrow( pStr ), doc ); } pItem->Release(); ILFree( pidl ); } } } } } } pDlg->Release(); } }
void CClassicCopyFile::GetFileInfo( IAccessible *pAcc, bool bSrc ) { long count; pAcc->get_accChildCount(&count); CComVariant children[20]; AccessibleChildren(pAcc,0,count,children,&count); wchar_t fname[_MAX_PATH]=L""; wchar_t dir[_MAX_PATH]=L""; CString size; CString date; // get the file name, directory, size and date for (int i=0;i<count;i++) { CComBSTR name; if (children[i].vt==VT_DISPATCH) { CComQIPtr<IAccessible> pChild=children[i].pdispVal; if (pChild) pChild->get_accName(CComVariant(CHILDID_SELF),&name); } else { pAcc->get_accName(children[i],&name); } switch (i) { case 2: if (wcslen(name)<_countof(fname)) wcscpy_s(fname,name); break; case 3: if (wcslen(name)<_countof(dir)) wcscpy_s(dir,name); break; case 4: size=name; break; case 5: date=name; break; } } if (bSrc) { m_FileName=fname; m_SrcSize=size; m_SrcTime=date; } else { m_DstSize=size; m_DstTime=date; } if (!fname[0] || !dir[0]) return; wchar_t fname2[_MAX_PATH]; memcpy(fname2,fname,sizeof(fname2)); *PathFindExtension(fname2)=0; int len1=Strlen(fname2); // the directory text is something like "filename (directory)". we need to parse out the real directory name int len2=Strlen(dir); if (dir[0]==0x202A) len1++; // for RTL languages the first character is some RTL marker. needs to be skipped if (len1+1>=len2 || dir[len1]!=L' ' || dir[len1+1]!=L'(' || dir[len2-1]!=L')') return; dir[len2-1]=0; // construct the full file name wchar_t path[_MAX_PATH]; _wmakepath_s(path,NULL,dir+len1+2,fname,NULL); if (!bSrc) { DWORD attrib=GetFileAttributes(path); if (attrib!=INVALID_FILE_ATTRIBUTES) { if (attrib&FILE_ATTRIBUTE_READONLY) m_bReadOnly=true; if (attrib&FILE_ATTRIBUTE_SYSTEM) m_bSystem=true; } } // get file icon HICON hIcon=NULL; PIDLIST_ABSOLUTE pidl=NULL; if (SUCCEEDED(SHParseDisplayName(path,NULL,&pidl,0,NULL)) && pidl) { int iconSize=GetSystemMetrics(SM_CXICON); HBITMAP hBitmap=NULL; CComPtr<IShellItemImageFactory> pFactory; if (SUCCEEDED(SHCreateItemFromIDList(pidl,IID_IShellItemImageFactory,(void**)&pFactory)) && pFactory) { SIZE size={iconSize,iconSize}; if (FAILED(pFactory->GetImage(size,SIIGBF_ICONONLY,&hBitmap))) hBitmap=NULL; } ILFree(pidl); if (hBitmap) { HBITMAP hMonoBitmap=CreateBitmap(iconSize,iconSize,1,1,NULL); ICONINFO info={TRUE,0,0,hMonoBitmap,hBitmap}; hIcon=CreateIconIndirect(&info); DeleteObject(hMonoBitmap); DeleteObject(hBitmap); } } if (!hIcon) return; if (bSrc) m_SrcIcon=hIcon; else m_DstIcon=hIcon; }
bool show() { #ifdef WIN32 CL_String16 title16 = CL_StringHelp::utf8_to_ucs2(title); CL_String16 initial_directory16 = CL_StringHelp::utf8_to_ucs2(initial_directory); #ifndef __MINGW32__ if(is_vista_or_later()) { HRESULT result; CL_ComPtr<IFileOpenDialog> open_dialog; result = CoCreateInstance(__uuidof(FileOpenDialog), NULL, CLSCTX_ALL, __uuidof(open_dialog), reinterpret_cast<void**>(open_dialog.output_variable())); throw_if_failed(result, "CoCreateInstance(FileOpenDialog) failed"); result = open_dialog->SetTitle(title16.c_str()); throw_if_failed(result, "IFileOpenDialog.SetTitle failed"); result = open_dialog->SetOptions(FOS_PICKFOLDERS | FOS_FORCEFILESYSTEM | FOS_PATHMUSTEXIST); throw_if_failed(result, "IFileOpenDialog.SetOptions((FOS_PICKFOLDERS) failed"); if(initial_directory16.length() > 0) { LPITEMIDLIST item_id_list = NULL; SFGAOF flags = 0; result = SHParseDisplayName(initial_directory16.c_str(), NULL, &item_id_list, SFGAO_FILESYSTEM, &flags); throw_if_failed(result, "SHParseDisplayName failed"); CL_ComPtr<IShellItem> folder_item; result = SHCreateShellItem(NULL, NULL, item_id_list, folder_item.output_variable()); ILFree(item_id_list); throw_if_failed(result, "SHCreateItemFromParsingName failed"); /* This code requires Windows Vista or newer: CL_ComPtr<IShellItem> folder_item; result = SHCreateItemFromParsingName(initial_directory16.c_str(), NULL, IID_PPV_ARGS(folder_item.output_variable())); throw_if_failed(result, "SHCreateItemFromParsingName failed"); */ if(!folder_item.is_null()) { result = open_dialog->SetFolder(folder_item); throw_if_failed(result, "IFileOpenDialog.SetFolder failed"); } } if(owner) result = open_dialog->Show(owner->get_display_window().get_hwnd()); else result = open_dialog->Show(0); if(SUCCEEDED(result)) { CL_ComPtr<IShellItem> chosen_folder; result = open_dialog->GetResult(chosen_folder.output_variable()); throw_if_failed(result, "IFileOpenDialog.GetResult failed"); WCHAR *buffer = 0; result = chosen_folder->GetDisplayName(SIGDN_FILESYSPATH, &buffer); throw_if_failed(result, "IShellItem.GetDisplayName failed"); CL_String16 output_directory16; try { output_directory16 = buffer; } catch (...) { CoTaskMemFree(buffer); throw; } CoTaskMemFree(buffer); selected_path = CL_StringHelp::ucs2_to_utf8(output_directory16); return true; } else { return false; } } else #endif { BROWSEINFO bi; ZeroMemory(&bi, sizeof(bi)); CL_String16::char_type path_buffer[FILENAME_MAX] = { 0 }; WCHAR Buffer[MAX_PATH]; memset(Buffer, 0, sizeof(WCHAR) * MAX_PATH); if(owner) bi.hwndOwner = owner->get_display_window().get_hwnd(); else bi.hwndOwner = 0; bi.pszDisplayName = Buffer; bi.lpszTitle = title16.c_str(); bi.ulFlags = BIF_EDITBOX | BIF_NEWDIALOGSTYLE | BIF_RETURNONLYFSDIRS | BIF_SHAREABLE; LPCITEMIDLIST pFolder = SHBrowseForFolder(&bi); if (pFolder == NULL) return false; if (!SHGetPathFromIDList(pFolder, path_buffer)) throw CL_Exception("Bad path for Browse Folder Dialog"); selected_path = CL_StringHelp::ucs2_to_utf8(path_buffer); return true; } #else bool success = false; return success; #endif }