BCB6で共有RTLライブラリをDLLで有効にするとExe側のFreeLibraryで落ちる
なぞ。とりあえずDLL側の共有RTLライブラリは切っとくことがお勧め。
| 固定リンク | コメント (0) | トラックバック (0)
| 固定リンク | コメント (0) | トラックバック (0)
//////////////////////////////////////////////////////////////////////////////// //stl #include <string> //windows #include <windows.h> #include <Shlobj.h> #pragma comment(lib, "Ole32.lib") //////////////////////////////////////////////////////////////////////////////// #if !defined( TBENFORCEH ) #define TB_ENFORCE( enforcer, statement ) statement #pragma warning( disable :4552 ) //warning C4552: '!' : 演算子にプログラム上の作用がありません。作用を持つ演算子を使用してください #endif //#if !defined( TBENFORCEH ) //////////////////////////////////////////////////////////////////////////////// class System { public: virtual ~System() throw(){} static void Run( const std::string& path ); }; //////////////////////////////////////////////////////////////////////////////// void System::Run( const std::string& path ) { //COMを初期化 TB_ENFORCE( NotEqualFail( S_OK ), CoInitialize( NULL ) ); //デスクトップフォルダを取得 IShellFolder* pDesktopFolder; TB_ENFORCE( NotEqualFail( S_OK ), ::SHGetDesktopFolder( &pDesktopFolder ) ); //引数のパスへのフルパスを含むITEMIDLISTを作成 LPITEMIDLIST pFullPathIDList; { //まず引数をユニコードに変換 OLECHAR convertedPath[MAX_PATH*2+1]; TB_ENFORCE( API(), ::MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, path.c_str(), -1, convertedPath, MAX_PATH*2 ) ); //ITEMIDLISTを取得 ULONG chEaten, dwAttributes; TB_ENFORCE( NotEqualFail( S_OK ), pDesktopFolder->ParseDisplayName( NULL, NULL, convertedPath, &chEaten, &pFullPathIDList, &dwAttributes ) ); } //引数のパスの親フォルダのIShellFolderを取得。 IShellFolder* pCurrent = pDesktopFolder; { //IMallocを取得しておく。 IMalloc* pMalloc; ::SHGetMalloc( &pMalloc ); //IShellFolderをトラバース do { //フルパスを示すITEMIDLISTから今見ているフォルダのITEMIDLISTをコピー LPITEMIDLIST pCurrentIDList; { //コピー元のアイテムのサイズを取得 int srcSize = pFullPathIDList->mkid.cb; //コピー先のサイズはUSHORTのサイズを足したもの int dstSize = srcSize + sizeof(USHORT); //新しいアイテム用メモリを確保 pCurrentIDList = reinterpret_cast< LPITEMIDLIST >( TB_ENFORCE( NullFail(), pMalloc->Alloc( dstSize ) ) ); //内容をコピー memcpy( pCurrentIDList, pFullPathIDList, srcSize ); //余りは0で埋める。 memset( reinterpret_cast<LPBYTE>(pCurrentIDList) + srcSize, 0, dstSize - srcSize ); } //今見てるフォルダのITEMIDLISTからIShellFolderを取得 IShellFolder* pTemp; TB_ENFORCE( NotEqualFail( S_OK ), pCurrent->BindToObject( pCurrentIDList, NULL, IID_IShellFolder, reinterpret_cast< void**>( &pTemp ) ) ); //取得できたので前のIShellFolderは解放 pCurrent->Release(); //pCurrentを置き換える。 pCurrent = pTemp; //ついでにITEMIDLISTもいらないので解放 pMalloc->Free( pCurrentIDList ); //ItemIDListを次に進める。 pFullPathIDList = reinterpret_cast<LPITEMIDLIST>( ( reinterpret_cast<LPBYTE>( pFullPathIDList ) ) + pFullPathIDList->mkid.cb ); } while( reinterpret_cast<LPITEMIDLIST>( ( reinterpret_cast<LPBYTE>( pFullPathIDList ) ) + pFullPathIDList->mkid.cb )->mkid.cb != 0 ); //↑pFullPathIDListの次がsize==0ならループを終わる。 //IMallocを解放 pMalloc->Release(); } //pCurrentがpathの指すファイルの親フォルダ。 //pFullPathIDListは今ファイル名を指す。 //以上の情報からそのファイルの右クリックメニューを取得して既定のコマンドを実行 //まずIContextMenuを取得。 IContextMenu* pContextMenu; TB_ENFORCE( NotEqualFail( S_OK ), pCurrent->GetUIObjectOf( NULL, 1, ( LPCITEMIDLIST* )(&pFullPathIDList), IID_IContextMenu, 0, reinterpret_cast< void ** >( &pContextMenu ) ) ); {//コマンドを実行 //IContextMenu::InvokeCommandの引数用構造体を用意 CMINVOKECOMMANDINFO invokeInfo = { sizeof( invokeInfo ) }; //lpVerbメンバにメニューの識別子を設定 HMENU hMenu = TB_ENFORCE( API< HMENU >( NULL ), ::CreatePopupMenu() ); TB_ENFORCE( TrueFail(), FAILED( pContextMenu->QueryContextMenu( hMenu, 0, 1, 0xffff, CMF_EXPLORE ) ) ); invokeInfo.lpVerb = MAKEINTRESOURCE( TB_ENFORCE( EqualFail( -1 ), GetMenuItemID( hMenu, TB_ENFORCE( API(-1), GetMenuDefaultItem( hMenu, TRUE, NULL ) ) ) )-1 ); invokeInfo.nShow = SW_SHOWNORMAL;
//実行 HRESULT result = pContextMenu->InvokeCommand( &invokeInfo ); //「0x800704c7 この操作はユーザーによって取り消されました。」の場合はエラーとしない。 if( 0x800704c7 != result && S_OK != result ) TB_ENFORCE( FalseFail(), !"pContextMenu->InvokeCommand( &invokeInfo )" ); } //COMを解放 CoUninitialize(); } ////////////////////////////////////////////////////////////////////////////////
| 固定リンク | コメント (0) | トラックバック (0)
| 固定リンク | コメント (0) | トラックバック (0)
最近のコメント