zoukankan      html  css  js  c++  java
  • windows下C语言调用系统文件选择对话框

    代码片段,在windows下用C语言调用文件选择对话框,以备忘


    #define DEFAULT_DIR ""
    char extraction_path[MAX_PATH] = DEFAULT_DIR;
    
    
    /*
     * Browse for a folder and update the folder edit box
     * Will use the newer IFileOpenDialog if *compiled* for Vista or later
     */
    void browse_for_folder(void) {
    
    	BROWSEINFOW bi;
    	LPITEMIDLIST pidl;
    
    #if (_WIN32_WINNT >= 0x0600)	// Vista and later
    	WCHAR *wpath;
    	size_t i;
    	HRESULT hr;
    	IShellItem *psi = NULL;
    	IShellItem *si_path = NULL;	// Automatically freed
    	IFileOpenDialog *pfod = NULL;
    	WCHAR *fname;
    	char* tmp_path = NULL;
    
    	// Even if we have Vista support with the compiler,
    	// it does not mean we have the Vista API available
    	INIT_VISTA_SHELL32;
    	if (IS_VISTA_SHELL32_AVAILABLE) {
    		hr = CoCreateInstance(&CLSID_FileOpenDialog, NULL, CLSCTX_INPROC,
    			&IID_IFileOpenDialog, (LPVOID)&pfod);
    		if (FAILED(hr)) {
    			dprintf("CoCreateInstance for FileOpenDialog failed: error %X", hr);
    			pfod = NULL;	// Just in case
    			goto fallback;
    		}
    		hr = pfod->lpVtbl->SetOptions(pfod, FOS_PICKFOLDERS);
    		if (FAILED(hr)) {
    			dprintf("Failed to set folder option for FileOpenDialog: error %X", hr);
    			goto fallback;
    		}
    		// Set the initial folder (if the path is invalid, will simply use last)
    		wpath = utf8_to_wchar(extraction_path);
    		// The new IFileOpenDialog makes us split the path
    		fname = NULL;
    		if ((wpath != NULL) && (wcslen(wpath) >= 1)) {
    			for (i=wcslen(wpath)-1; i!=0; i--) {
    				if (wpath[i] == L'\') {
    					wpath[i] = 0;
    					fname = &wpath[i+1];
    					break;
    				}
    			}
    		}
    
    		hr = (*pSHCreateItemFromParsingName)(wpath, NULL, &IID_IShellItem, (LPVOID)&si_path);
    		if (SUCCEEDED(hr)) {
    			if (wpath != NULL) {
    				hr = pfod->lpVtbl->SetFolder(pfod, si_path);
    			}
    			if (fname != NULL) {
    				hr = pfod->lpVtbl->SetFileName(pfod, fname);
    			}
    		}
    		safe_free(wpath);
    
    		hr = pfod->lpVtbl->Show(pfod, hMain);
    		if (SUCCEEDED(hr)) {
    			hr = pfod->lpVtbl->GetResult(pfod, &psi);
    			if (SUCCEEDED(hr)) {
    				psi->lpVtbl->GetDisplayName(psi, SIGDN_FILESYSPATH, &wpath);
    				tmp_path = wchar_to_utf8(wpath);
    				CoTaskMemFree(wpath);
    				if (tmp_path == NULL) {
    					dprintf("Could not convert path");
    				} else {
    					safe_strcpy(extraction_path, MAX_PATH, tmp_path);
    					safe_free(tmp_path);
    				}
    			} else {
    				dprintf("Failed to set folder option for FileOpenDialog: error %X", hr);
    			}
    		} else if ((hr & 0xFFFF) != ERROR_CANCELLED) {
    			// If it's not a user cancel, assume the dialog didn't show and fallback
    			dprintf("could not show FileOpenDialog: error %X", hr);
    			goto fallback;
    		}
    		pfod->lpVtbl->Release(pfod);
    		return;
    	}
    fallback:
    	if (pfod != NULL) {
    		pfod->lpVtbl->Release(pfod);
    	}
    #endif
    	INIT_XP_SHELL32;
    	memset(&bi, 0, sizeof(BROWSEINFOW));
    	bi.hwndOwner = hMain;
    	bi.lpszTitle = L"Please select the installation folder:";
    	bi.lpfn = browseinfo_callback;
    	// BIF_NONEWFOLDERBUTTON = 0x00000200 is unknown on MinGW
    	bi.ulFlags = BIF_RETURNFSANCESTORS | BIF_RETURNONLYFSDIRS |
    		BIF_DONTGOBELOWDOMAIN | BIF_EDITBOX | 0x00000200;
    	pidl = SHBrowseForFolderW(&bi);
    	if (pidl != NULL) {
    		CoTaskMemFree(pidl);
    	}
    }


  • 相关阅读:
    解决Android调用https服务API时出错的问题
    Sqlite 数据库出现database disk image is malformed报错的解决方法
    Bootstrap Chart组件使用分享
    Devexpress TreeList控件绑定显示父子节点对像
    回顾过去的2015展望已经到来的2016年,给自己的一些计划
    1006
    1003
    1001
    Swing用户界面组件-1
    图形程序设计
  • 原文地址:https://www.cnblogs.com/dyllove98/p/3141072.html
Copyright © 2011-2022 走看看