bool DirectoryRefDialog(HWND hWnd,char *Result) { bool r = false; LPMALLOC Memory; LPCSTR Buffer; LPITEMIDLIST Ret; LPITEMIDLIST Root; SHGetMalloc(&Memory); Buffer = (LPSTR)Memory->Alloc(1000); SHGetSpecialFolderLocation(hWnd,CSIDL_DESKTOP,&Root); ZeroMemory(&BI,sizeof(BROWSEINFO)); BI.hwndOwner = hWnd; BI.pidlRoot = Root; BI.ulFlags = BIF_STATUSTEXT | BIF_RETURNONLYFSDIRS; BI.lpszTitle = "展開先を指定してください"; BI.pszDisplayName = (LPSTR)Buffer; BI.lpfn = BrowseCallbackProc; Ret = SHBrowseForFolder(&BI); if (SHGetPathFromIDList(Ret,(LPSTR)Buffer)) { lstrcpy(Result,Buffer); r = true; } Memory->Free(Ret); Memory->Free(Root); Memory->Free((void*)Buffer); return r; }
//---------------------------------------------------------------------------------------- static void GetWindowsFolder(int folder, nsFileSpec& outDirectory) //---------------------------------------------------------------------------------------- { if (gGetSpecialPathProc) { TCHAR path[MAX_PATH]; HRESULT result = gGetSpecialPathProc(NULL, path, folder, true); if (!SUCCEEDED(result)) return; // Append the trailing slash int len = PL_strlen(path); if (len>1 && path[len-1] != '\\') { path[len] = '\\'; path[len + 1] = '\0'; } outDirectory = path; return; } LPMALLOC pMalloc = NULL; LPSTR pBuffer = NULL; LPITEMIDLIST pItemIDList = NULL; int len; // Get the shell's allocator. if (!SUCCEEDED(SHGetMalloc(&pMalloc))) return; // Allocate a buffer if ((pBuffer = (LPSTR) pMalloc->Alloc(MAX_PATH + 2)) == NULL) return; // Get the PIDL for the folder. if (!SUCCEEDED(SHGetSpecialFolderLocation( NULL, folder, &pItemIDList))) goto Clean; if (!SUCCEEDED(SHGetPathFromIDList(pItemIDList, pBuffer))) goto Clean; // Append the trailing slash len = PL_strlen(pBuffer); pBuffer[len] = '\\'; pBuffer[len + 1] = '\0'; // Assign the directory outDirectory = pBuffer; Clean: // Clean up. if (pItemIDList) pMalloc->Free(pItemIDList); if (pBuffer) pMalloc->Free(pBuffer); pMalloc->Release(); } // GetWindowsFolder
/**************************************************************************** * * FUNCTION: CopyITEMID(LPMALLOC lpMalloc, LPITEMIDLIST lpi) * * PURPOSE: Copies the ITEMID * ****************************************************************************/ LPITEMIDLIST CShellPidl::CopyITEMID(LPMALLOC lpMalloc, LPITEMIDLIST lpi) { LPITEMIDLIST lpiTemp; lpiTemp=(LPITEMIDLIST)lpMalloc->Alloc(lpi->mkid.cb+sizeof(lpi->mkid.cb)); CopyMemory((PVOID)lpiTemp, (CONST VOID *)lpi, lpi->mkid.cb+sizeof(lpi->mkid.cb)); return lpiTemp; }
LPITEMIDLIST Pidl_Create(UINT cbSize) { LPITEMIDLIST pidl = NULL; pidl = (LPITEMIDLIST) g_pMalloc->Alloc(cbSize); if(pidl) ZeroMemory(pidl, cbSize); return pidl; }
// 深度拷贝一个PIDL // LPITEMIDLIST CShellOperator::CopyItemID(LPMALLOC pMalloc, LPCITEMIDLIST pidl) { if(pMalloc == NULL || pidl == NULL) { return NULL; } LPITEMIDLIST pidlTemp = NULL; pidlTemp=(LPITEMIDLIST)pMalloc->Alloc(pidl->mkid.cb+sizeof(pidl->mkid.cb)); // 分配内存 // 将pidl内存的数据复制到pidlTemp位置 CopyMemory((PVOID)pidlTemp, (CONST VOID *)pidl, pidl->mkid.cb+sizeof(pidl->mkid.cb)); return pidlTemp; }
// CoTaskMemAlloc uses the default OLE allocator to allocate a memory // block in the same way that IMalloc::Alloc does LPVOID NEAR CoTaskMemAlloc(ULONG cb) { LPMALLOC pMalloc; if (SUCCEEDED(CoGetMalloc(MEMCTX_TASK, &pMalloc))) { LPVOID lpv = pMalloc->Alloc(cb); pMalloc->Release(); return lpv; } return NULL; }
void CSetDlgBasic::OnBnClickedButtonRecPath() { // TODO: ここにコントロール通知ハンドラー コードを追加します。 UpdateData(TRUE); BROWSEINFO bi; LPWSTR lpBuffer; LPITEMIDLIST pidlRoot = NULL; LPITEMIDLIST pidlBrowse; LPMALLOC lpMalloc = NULL; HRESULT hr = SHGetMalloc(&lpMalloc); if(FAILED(hr)) return; if ((lpBuffer = (LPWSTR) lpMalloc->Alloc(_MAX_PATH*2)) == NULL) { return; } if( recFolderPath.IsEmpty() != 0 ){ if (!SUCCEEDED(SHGetSpecialFolderLocation( m_hWnd,CSIDL_DESKTOP,&pidlRoot ) )){ lpMalloc->Free(lpBuffer); return; } } bi.hwndOwner = m_hWnd; bi.pidlRoot = pidlRoot; bi.pszDisplayName = lpBuffer; bi.lpszTitle = L"録画ファイル保存フォルダを選択してください"; bi.ulFlags = 0; bi.lpfn = NULL; bi.lParam = (LPARAM)recFolderPath.GetBuffer(0); pidlBrowse = SHBrowseForFolder(&bi); if (pidlBrowse != NULL) { if (SHGetPathFromIDList(pidlBrowse, lpBuffer)) { recFolderPath = lpBuffer; } lpMalloc->Free(pidlBrowse); } if( pidlRoot != NULL ){ lpMalloc->Free(pidlRoot); } lpMalloc->Free(lpBuffer); lpMalloc->Release(); UpdateData(FALSE); }
const char * MWindow::getOpenDir(const char * title, const char * startPath) { setActive(false); static char filename[256]; static BROWSEINFO bi; ITEMIDLIST * pItem; LPSTR szBuffer; LPMALLOC ppMalloc; SHGetMalloc(&ppMalloc); szBuffer = (LPSTR)ppMalloc->Alloc(MAX_PATH); bi.hwndOwner = m_hWnd; bi.pidlRoot = NULL; bi.pszDisplayName = szBuffer; bi.lpszTitle = title; bi.ulFlags = BIF_NEWDIALOGSTYLE | BIF_RETURNONLYFSDIRS; bi.lpfn = (BFFCALLBACK)browseCallbackProc; pItem = SHBrowseForFolder(&bi); if(pItem) { SHGetPathFromIDList(pItem, szBuffer); bi.lParam = (LPARAM)pItem; strcpy(filename, szBuffer); setActive(true); return filename; ppMalloc->Free(pItem); ppMalloc->Free(szBuffer); } else { ppMalloc->Free(pItem); ppMalloc->Free(szBuffer); } setActive(true); return NULL; }
void __fastcall TOptionsForm::ToolButton1Click(TObject *Sender) { UnicodeString dir; if (!DirectoryExists(AcfParams.Save_Dir)) dir = ExtractFilePath(Application->ExeName); else dir = AcfParams.Save_Dir; _browseinfoA lpbi; LPMALLOC ppMalloc; char *buffer; PItemIDList ItemIDList; memset(&lpbi, 0 ,sizeof(_browseinfoA)); if ((SHGetMalloc(&ppMalloc) == S_OK) && (ppMalloc != NULL)) { buffer = (char *) ppMalloc->Alloc(1024); try { OleInitialize(NULL); lpbi.hwndOwner = Application->Handle; lpbi.pidlRoot = NULL; lpbi.pszDisplayName = buffer; lpbi.lpszTitle = "Выберите директорию для сохранения данных"; lpbi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_USENEWUI | BIF_EDITBOX; lpbi.lpfn = &BrowseCallbackProc; lpbi.lParam = (long) AcfParams.Save_Dir.t_str(); try { ItemIDList = SHBrowseForFolderA(&lpbi); } catch (...) { } if (ItemIDList != NULL) { SHGetPathFromIDListA(ItemIDList, buffer); ppMalloc->Free(ItemIDList); Label56->Caption = buffer; } } __finally { ppMalloc->Free(buffer); } }
LPVOID CPropertyPageEx::operator new(size_t size) { #ifdef _WIN32 return HeapAlloc(GetProcessHeap(), 0, size); #else LPMALLOC pMalloc; if (SUCCEEDED(CoGetMalloc(MEMCTX_TASK, &pMalloc))) { LPVOID lpv = pMalloc->Alloc(size); pMalloc->Release(); return lpv; } return NULL; #endif }
/**************************************************************************** * * FUNCTION: CreatePidl(UINT cbSize) * * PURPOSE: Allocates a PIDL * ****************************************************************************/ LPITEMIDLIST CShellPidl::CreatePidl(UINT cbSize) { LPMALLOC lpMalloc; HRESULT hr; LPITEMIDLIST pidl=NULL; hr=SHGetMalloc(&lpMalloc); if (FAILED(hr)) return 0; pidl=(LPITEMIDLIST)lpMalloc->Alloc(cbSize); if (pidl) memset(pidl, 0, cbSize); // zero-init for external task alloc if (lpMalloc) lpMalloc->Release(); return pidl; }
// 创建一个新的PIDL // LPITEMIDLIST CShellOperator::CreatePidl(UINT cbSize) { LPITEMIDLIST pidl = NULL; LPMALLOC pMalloc; SHGetMalloc(&pMalloc); // 取得IMalloc接口 if(pMalloc != NULL) { pidl = (LPITEMIDLIST)pMalloc->Alloc(cbSize); // 分配内存 if (pidl != NULL) { memset(pidl, 0, cbSize); // 内存清零 } pMalloc->Release(); // 释放IMalloc接口 } return pidl; }
//--------------------------------------------------------------------------- AnsiString GetFolderName(HWND hWnd, AnsiString Text, AnsiString OldFolder,UINT ulFlags) { LPMALLOC pMalloc; AnsiString S=OldFolder; if (SUCCEEDED(SHGetMalloc(&pMalloc))) { LPITEMIDLIST pidlDesktop; if (SUCCEEDED(SHGetSpecialFolderLocation(Application->Handle,CSIDL_DESKTOP,&pidlDesktop))) { char *Buffer=(char *)pMalloc->Alloc(MAX_PATH); if (Buffer) { BROWSEINFO bi; strcpy(Buffer,OldFolder.c_str()); bi.hwndOwner=hWnd; bi.pidlRoot=pidlDesktop; bi.pszDisplayName=Buffer; bi.lpszTitle=Text.c_str(); bi.ulFlags=ulFlags;//BIF_DONTGOBELOWDOMAIN+BIF_RETURNONLYFSDIRS+BIF_STATUSTEXT; bi.lpfn=&BrowseCallbackProc; bi.lParam=(LPARAM)Buffer; bi.iImage=0; LPITEMIDLIST pidlBrowse=SHBrowseForFolder(&bi); if (pidlBrowse) { if (SHGetPathFromIDList(pidlBrowse,Buffer)&& *Buffer) { S=AnsiString (Buffer); } pMalloc->Free(pidlBrowse); } pMalloc->Free(Buffer); } pMalloc->Free(pidlDesktop); } pMalloc->Release(); } return S; }
LPITEMIDLIST Pidl_Copy(LPCITEMIDLIST pidlSource) { LPITEMIDLIST pidlTarget = NULL; UINT cbSource = 0; if(NULL == pidlSource) return NULL; // // Allocate the new ITEMIDLIST // cbSource = Pidl_GetSize(pidlSource); pidlTarget = (LPITEMIDLIST) g_pMalloc->Alloc(cbSource); if(!pidlTarget) return NULL; // // Copy the source to the target // CopyMemory(pidlTarget, pidlSource, cbSource); return pidlTarget; }
/* #FN# Fills a branch of the TreeView control. Given the shell folder, enumerate the subitems of this folder, and add the appropriate items to the tree. This function enumerates the items in the folder identifed by lpsf. Note that since we are filling the left hand pane, we will only add items that are folders and/or have sub-folders. We *could* put all items in here if we wanted, but that's not the intent. */ void /* #AS# Nothing */ CShellTree:: FillTreeView( LPSHELLFOLDER lpsf, /* #IN# Pointer to shell folder that we want to enumerate items */ LPITEMIDLIST lpifq, /* #IN# Fully qualified item id list to the item that we are enumerating items for; in other words, this is the PIDL to the item identified by the lpsf parameter */ HTREEITEM hParent /* #IN# Parent node */ ) { TV_ITEM tvi; /* TreeView Item */ TV_INSERTSTRUCT tvins; /* TreeView Insert Struct */ HTREEITEM hPrev = NULL; /* Previous Item Added */ LPSHELLFOLDER lpsf2 = NULL; LPENUMIDLIST lpe = NULL; LPITEMIDLIST lpi = NULL; LPITEMIDLIST lpifqThisItem = NULL; LPTVITEMDATA lptvid = NULL; LPMALLOC lpMalloc = NULL; ULONG ulFetched = 0; HWND hwnd = ::GetParent( m_hWnd ); char szBuff[ MAX_PATH + 1 ]; char szPath[ MAX_PATH + 1 ]; HRESULT hr; /* Allocate a shell memory object */ hr = ::SHGetMalloc( &lpMalloc ); if( FAILED(hr) ) return; if( SUCCEEDED(hr) ) { /* Get the IEnumIDList object for the given folder */ hr = lpsf->EnumObjects( hwnd, SHCONTF_FOLDERS | SHCONTF_NONFOLDERS | SHCONTF_INCLUDEHIDDEN, &lpe ); if( S_OK == hr && lpe ) { /* Enumerate throught the list of folder and non-folder objects */ while( S_OK == lpe->Next( 1, &lpi, &ulFetched ) ) { /* Create a fully qualified path to the current item. The SH* shell API's take a fully qualified path pidl, (see GetIcon above where I call SHGetFileInfo) whereas the interface methods take a relative path pidl */ ULONG ulAttrs = SFGAO_FOLDER | SFGAO_HASSUBFOLDER; if( !m_bFolderMode ) ulAttrs |= SFGAO_FILESYSTEM | SFGAO_LINK; /* Determine what type of object we have */ lpsf->GetAttributesOf( 1, (const struct _ITEMIDLIST **)&lpi, &ulAttrs ); if( m_bFolderMode && ulAttrs & (SFGAO_HASSUBFOLDER | SFGAO_FOLDER) || (!m_bFolderMode && ulAttrs & (SFGAO_HASSUBFOLDER | SFGAO_FOLDER | SFGAO_FILESYSTEM) && !(ulAttrs & SFGAO_LINK)) ) { tvi.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_PARAM; /* We need this next if statement so that we don't add things like the MSN to our tree. MSN is not a folder, but according to the shell it has subfolders */ /* OK, let's get some memory for our ITEMDATA struct */ lptvid = (LPTVITEMDATA)lpMalloc->Alloc( sizeof(TVITEMDATA) ); if( !lptvid ) goto Done; /* Error - could not allocate memory */ /* Now get the friendly name that we'll put in the treeview */ if( !GetName( lpsf, lpi, SHGDN_NORMAL, szBuff ) ) goto Done; /* Error - could not get friendly name */ tvi.pszText = szBuff; tvi.cchTextMax = MAX_PATH; /* Allocate/create the fully qualified PIDL, consisting of the parents full PIDL and our relative PIDL */ lpifqThisItem = ConcatPidls( lpifq, lpi ); if( ulAttrs & SFGAO_FOLDER && (ulAttrs & SFGAO_HASSUBFOLDER || /* There are not any subfolders but what about files? */ (!m_bFolderMode && SHGetPathFromIDList( lpifqThisItem, szPath ) && !IsFolderEmpty( szPath ))) ) { /* This item has sub-folders, so let's put the + in the TreeView. The first time the user clicks on the item, we'll populate the sub-folders */ tvi.cChildren = 1; tvi.mask |= TVIF_CHILDREN; } /* Now, make a copy of the ITEMIDLIST (non-qualified) */ lptvid->lpi = CopyITEMID( lpMalloc, lpi ); tvi.iImage = GetItemIcon( lpifqThisItem, SHGFI_PIDL | SHGFI_SYSICONINDEX | SHGFI_SMALLICON ); tvi.iSelectedImage = GetItemIcon( lpifqThisItem, SHGFI_PIDL | SHGFI_SYSICONINDEX | SHGFI_SMALLICON | SHGFI_OPENICON ); lptvid->lpsfParent = lpsf; /* Store the parent folders SF */ lpsf->AddRef(); /* Increment our saved reference */ /* Now create another PIDL from our Full parents PIDL and the releative one that we'll save */ lptvid->lpifq = ConcatPidls( lpifq, lpi ); /* Populate the TreeView Insert Struct. The item is the one filled above. Insert it after the last item inserted at this level. And indicate this is a root entry */ tvi.lParam = (LPARAM)lptvid; tvins.item = tvi; tvins.hInsertAfter = hPrev; tvins.hParent = hParent; /* Add the item to the tree */ hPrev = InsertItem( &tvins ); /* Free this item with task allocator */ lpMalloc->Free( lpifqThisItem ); lpifqThisItem = 0; } lpMalloc->Free( lpi ); /* Free the pidl that the shell gave us */ lpi = 0; } } } else return; Done: if( lpe ) lpe->Release(); /* The following 2 if statements will only be TRUE if we got here on an error condition from the "goto" statement. Otherwise, we free this memory at the end of the while loop above */ if( lpi && lpMalloc ) lpMalloc->Free( lpi ); if( lpifqThisItem && lpMalloc ) lpMalloc->Free( lpifqThisItem ); if( lpMalloc ) lpMalloc->Release(); } /* #OF# CShellTree::FillTreeView */
// ============================================= // CSHBrowseForFolder::SelectDirectory // 概要 : フォルダ参照ダイアログ処理 // 引数 : sLocal = パス(入出力) // 戻り値: bool // ============================================= bool CSHBrowseForFolder::Exec(char *sLocal) { BOOL bResult = FALSE; BROWSEINFO bi; LPSTR lpBuffer; LPITEMIDLIST pidlRoot; // ブラウズのルートPIDL LPITEMIDLIST pidlBrowse; // ユーザーが選択したPIDL LPMALLOC lpMalloc = NULL; HRESULT hr = SHGetMalloc(&lpMalloc); if (FAILED(hr)) return(FALSE); HWND hwnd = AfxGetMainWnd()->GetSafeHwnd(); // ブラウズ情報受け取りバッファ領域の確保 if ((lpBuffer = (LPSTR) lpMalloc->Alloc(_MAX_PATH)) == NULL) { lpMalloc->Release(); /* WildCherry2 080 */ return(FALSE); } // ダイアログ表示時のルートフォルダのPIDLを取得 // ※以下はデスクトップをルートとしている。デスクトップをルートとする // 場合は、単に bi.pidlRoot に0を設定するだけでもよい。その他の特 // 殊フォルダをルートとする事もできる。詳細はSHGetSpecialFolderLoca // tionのヘルプを参照の事。 if (!SUCCEEDED(SHGetSpecialFolderLocation( hwnd, CSIDL_DESKTOP, &pidlRoot))) { lpMalloc->Free(lpBuffer); lpMalloc->Release(); /* WildCherry2 080 */ return(FALSE); } // BROWSEINFO構造体の初期値設定 // ※BROWSEINFO構造体の各メンバの詳細説明もヘルプを参照 bi.hwndOwner = hwnd; bi.pidlRoot = pidlRoot; bi.pszDisplayName = lpBuffer; bi.lpszTitle = "フォルダを選択して下さい。"; bi.ulFlags = 0; bi.lpfn = CallbackSelectDir; // コールバック関数のアドレスを設定 bi.lParam = (LPARAM)sLocal; // 指定したいパスを設定 // フォルダ選択ダイアログの表示 pidlBrowse = SHBrowseForFolder(&bi); if (pidlBrowse != NULL) { // PIDL形式の戻り値のファイルシステムのパスに変換 if (SHGetPathFromIDList(pidlBrowse, lpBuffer)) { // 取得成功 strcpy(sLocal, lpBuffer); bResult = TRUE; } // SHBrowseForFolderの戻り値PIDLを解放 lpMalloc->Free(pidlBrowse); } // クリーンアップ処理 lpMalloc->Free(pidlRoot); lpMalloc->Free(lpBuffer); lpMalloc->Release(); if (pSubDir) { /* WildCherry2 080 */ delete pSubDir; pSubDir = NULL; } return(bResult ? true : false); }