• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            S.l.e!ep.¢%

            像打了激速一樣,以四倍的速度運轉,開心的工作
            簡單、開放、平等的公司文化;尊重個性、自由與個人價值;
            posts - 1098, comments - 335, trackbacks - 0, articles - 1
              C++博客 :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

            用VC6.0實現快捷方式中的查找目標功能

            Posted on 2010-08-20 13:47 S.l.e!ep.¢% 閱讀(483) 評論(0)  編輯 收藏 引用 所屬分類: VC

             最近寫一個開發輔助工具,在這個過程要做一個類似文件快捷方式中查找目標的功能,先查MSDN98,大家不要見笑,我現在一直都用它,沒有相應的API,后又. Net 2003中的MSDN,找到了可以實現該功能的API,SHOpenFolderAndSelectItems()函數,它的原型如下:

              (具體用法參考MSDN)“Opens a Microsoft? Windows? Explorer window with specified items in a particular folder selected.”
            HRESULT SHOpenFolderAndSelectItems(
            ???? LPCITEMIDLIST pidlFolder,
            ???? UINT cidl,
            ???? LPCITEMIDLIST *apidl,
            ???? DWORD dwFlags
            );  但是,它需要Windows XP及上,若在Win2000或Win98如何實現它呢?于是我就上網搜索,幾經周折最終搜到的一篇文章,但它只是利用工具通過反匯編Windows API函數得到的代碼,可能可以實現與快捷方式相同的對話框(我沒有試過),但其代碼可讀性非常差,我只能參考一下大概的流程,他提到一個非常重要的一點,那就是使用一個未公開的API函數SHGetIDispatchForFolder,它可幫助我打開文件夾。好不多說了,下面是關鍵的部分:

              查找目標功能,分為兩個步驟,首先打開或找到目標文件所在的文件夾,其次在打開的文件夾中選中相應的項目(即文件)。在說這個步驟之前,先認識一下,下面兩個結構

            typedef struct _SHITEMID {
            ???? USHORT cb;
            ???? BYTE??? abID[1];
            } SHITEMID, * LPSHITEMID;
            typedef const SHITEMID?? * LPCSHITEMID;

            typedef struct _ITEMIDLIST {
            ???? SHITEMID mkid;
            } ITEMIDLIST, * LPITEMIDLIST;
            typedef const ITEMIDLIST * LPCITEMIDLIST;

              這兩個結構的數據保存的是項目定義符列表(僅是字面翻譯),這個結構所表示的文件夾及文件除了正常的,還包括一些特殊的文件夾及文件(如目錄,我的電腦等),SHGetIDispatchForFolder函數正是用它的做為參數,可以打開一些特殊的文件夾。SHGetIDispatchForFolder函數的原型是 :??????? HRESULT (WINAPI*gpfSHGetIDispatchForFolder)(ITEMIDLIST* pidl, IWebBrowserApp** ppIWebBrowserApp);   通常快捷方式給我的ITEMIDLIST是包含文件名的,若直接調用上面的函數,它將直接會打開出目標文件,而不是打開文件夾。下面是區分文件及文件夾的代碼:
            ?pIdlFile = pidl;??????
            ?/// 找出目標文件中文件名的偏移量
            ?while (cb = pIdlFile->mkid.cb)
            ?{
            ?? pidl2 = pIdlFile;
            ?? pIdlFile = (ITEMIDLIST*)((BYTE*)pIdlFile + cb);
            ?}

            ?cb = pidl2->mkid.cb;
            ?pidl2->mkid.cb = 0;
              下面是打開文件夾及選中文件的代碼,相信大家不難理解。???? /// 打開目標文件所在的文件夾
            ?if (SUCCEEDED(GetShellFolderViewDual(pidl, &pIShellFolderViewDual)))
            ?{
            ?? pidl2->mkid.cb = cb;
            ?? // 0 Deselect the item.
            ?? // 1 Select the item.
            ?? // 3 Put the item in edit mode.
            ?? // 4 Deselect all but the specified item.
            ?? // 8 Ensure the item is displayed in the view.
            ?? // 0x10 Give the item the focus.
            ?? COleVariant bszFile(pidl2);
            ??????
            ?? if(pIShellFolderViewDual != NULL)
            ?? {
            ??? /// 選中相應的選項
            ??? pIShellFolderViewDual->SelectItem(bszFile, 0x1d);
            ??? pIShellFolderViewDual->Release();
            ?? }
            ?? return TRUE;
            ?}  源代碼中包含了一個DEMO。下面是完整的函數,可以直接調用FindTarget(CString str)參數為文件名,若是快捷方式則會自動指向其目標。若代碼中已做過COM的初始化工作,請刪除CoInitialize(NULL);及CoUninitialize();語句。
            HRESULT GetShellFolderViewDual(ITEMIDLIST* pidl, IShellFolderViewDual** ppIShellFolderViewDual)
            {
            ?IWebBrowserApp* pIWebBrowserApp;
            ?IDispatch* pDoc;
            ?HWND hWnd;
            ?HRESULT hr;
            ?HINSTANCE ghSHDOCVW;

            ?HRESULT (WINAPI*gpfSHGetIDispatchForFolder)(ITEMIDLIST* pidl, IWebBrowserApp** ppIWebBrowserApp);

            ?*ppIShellFolderViewDual = NULL;

            ?ghSHDOCVW = LoadLibrary(_T("SHDOCVW.DLL"));
            ?if (ghSHDOCVW == NULL)
            ?? return FALSE;

            ?pIWebBrowserApp=NULL;
            ?gpfSHGetIDispatchForFolder =
            ?? (HRESULT (WINAPI*)(ITEMIDLIST*, IWebBrowserApp**)) GetProcAddress(ghSHDOCVW, "SHGetIDispatchForFolder");
            ?if (gpfSHGetIDispatchForFolder == NULL)
            ?? return FALSE;

            ?/// 調用未公開的API函數 SHGetIDispatchForFolder
            ?if (SUCCEEDED(gpfSHGetIDispatchForFolder(pidl, &pIWebBrowserApp)))
            ?{
            ?? if (SUCCEEDED(pIWebBrowserApp->get_HWND((long*)&hWnd)))
            ?? {
            ??? SetForegroundWindow(hWnd);
            ??? ShowWindow(hWnd, SW_SHOWNORMAL);
            ?? }

            ?? if (SUCCEEDED(hr = pIWebBrowserApp->get_Document(&pDoc)))
            ?? {
            ??? pDoc->QueryInterface(IID_IShellFolderViewDual, (void**) ppIShellFolderViewDual);
            ??? pDoc->Release();
            ?? }

            ?? pIWebBrowserApp->Release();
            ?}
            ?FreeLibrary(ghSHDOCVW);

            ?return TRUE;
            }

            BOOL XZSHOpenFolderAndSelectItems(ITEMIDLIST *pidlFolder)
            {
            ?ITEMIDLIST *pidl, *pidl2;
            ?ITEMIDLIST* pIdlFile;
            ?USHORT cb;
            ?IShellFolderViewDual* pIShellFolderViewDual;

            ?HRESULT (WINAPI *gpfSHOpenFolderAndSelectItems)(LPCITEMIDLIST *pidlFolder, UINT cidl, LPCITEMIDLIST *apidl, DWORD dwFlags);
            ?HINSTANCE ghShell32;
            /// 只有WinXp及以上及系統才支持SHOpenFolderAndSelectItems() API
            /// 那其它系統該怎么實現這個功能呢?只能采用其它的方法來處理
            /// 首先用XP跟蹤到SHOpenFolderAndSelectItems()API中,看它是如何處理的,再用同樣的方法去實現
            /// 其它系統的這個功能使用工具 VC6 .net 2003 MSDN Ollydbg v1.10中文版

            ?ghShell32 = LoadLibrary(_T("Shell32.DLL"));
            ?if (ghShell32 == NULL)
            ?? return FALSE;

            ?gpfSHOpenFolderAndSelectItems =
                     (HRESULT (WINAPI*)(LPCITEMIDLIST*, UINT, LPCITEMIDLIST*, DWORD)) GetProcAddress(ghShell32, "SHOpenFolderAndSelectItems");
            ?if (gpfSHOpenFolderAndSelectItems != NULL)
            ?{
            ?? /// 可以獲得SHOpenFolderAndSelectItems()函數的API地址
            ?? if (SUCCEEDED(gpfSHOpenFolderAndSelectItems((LPCITEMIDLIST*)pidlFolder,0,(LPCITEMIDLIST*)NULL,0)))
            ?? {
            ??? ///直接調用系統的功能
            ??? FreeLibrary(ghShell32);
            ??? return TRUE;
            ?? }
            ?? FreeLibrary(ghShell32);
            ?? return FALSE;
            ?}
            ?FreeLibrary(ghShell32);

            ?/// 當操作系統不支持SHOpenFolderAndSelectItems()函數的API時的處理,
            ?/// 自已動手寫一個與系統功能相同的代碼
            ?pidl = pidlFolder;
            ?pIdlFile = pidl;
            ?/// 找出目標文件中文件名的偏移量
            ?while (cb = pIdlFile->mkid.cb)
            ?{
            ?? pidl2 = pIdlFile;
            ?? pIdlFile = (ITEMIDLIST*)((BYTE*)pIdlFile + cb);
            ?}

            ?cb = pidl2->mkid.cb;
            ?pidl2->mkid.cb = 0;

            ?/// 打開目標文件所在的文件夾
            ?if (SUCCEEDED(GetShellFolderViewDual(pidl, &pIShellFolderViewDual)))
            ?{
            ?? pidl2->mkid.cb = cb;
            ?? // 0 Deselect the item.??
            ?? // 1 Select the item.??
            ?? // 3 Put the item in edit mode.??
            ?? // 4 Deselect all but the specified item.??
            ?? // 8 Ensure the item is displayed in the view.??
            ?? // 0x10 Give the item the focus.??
            ?? COleVariant bszFile(pidl2);

            ?? if(pIShellFolderViewDual != NULL)
            ?? {
            ??? /// 選中相應的選項
            ??? pIShellFolderViewDual->SelectItem(bszFile, 0x1d);
            ??? pIShellFolderViewDual->Release();
            ?? }
            ?? return TRUE;
            ?}

            ?return FALSE;
            }

            void FindTarget(CString str)
            {
            ?HRESULT hres;
            ?IShellLink *psl;
            ?ITEMIDLIST *pidl;
            ?IPersistFile *ppf;

            CoInitialize(NULL);

            ?// Get a pointer to the IShellLink interface.
            ?hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
            ??????? IID_IShellLink, (LPVOID*)&psl);
            ?if (SUCCEEDED(hres))
            ?{
            ?? // 設置目標文件
            ?? psl->SetPath(str);
            ?? /// 獲得目標文件的ITEMIDLIST
            ?? psl->GetIDList(&pidl);

            ?? // Get a pointer to the IPersistFile interface.
            ?? hres = psl->QueryInterface(IID_IPersistFile, (void**)&ppf);
            ?? if (SUCCEEDED(hres))
            ?? {
            ??? WCHAR wsz[MAX_PATH];
            #ifdef _UNICODE
            ??? wcscpy(wsz, str);
            #else
            ??? // Ensure that the string is Unicode.
            ??? MultiByteToWideChar(CP_ACP, 0, str, -1, wsz, MAX_PATH);
            #endif
            ?
            ??? // Load the shortcut.
            ??? hres = ppf->Load(wsz, STGM_READ);

            ??? if (SUCCEEDED(hres))
            ??? {
            ???? /// 獲得快捷方式的ITEMIDLIST
            ???? psl->GetIDList(&pidl);
            ??? }m
            ??? ppf->Release();
            ?? }

            ?? /// 打開文件夾并選中項目
            ?? XZSHOpenFolderAndSelectItems(pidl);

            ?? psl->Release();
            ?}
            ?CoUninitialize();
            }

            在VC6下編譯后的代碼,通過98,2k,XP的測試。
            ?
            本篇文章來源于:開發學院 http://edu.codepub.com?? 原文鏈接:http://edu.codepub.com/2009/0808/12691.php

            三级韩国一区久久二区综合 | 99久久综合狠狠综合久久止| 国内精品久久久久久久久电影网| 日产精品99久久久久久| 国产A三级久久精品| 亚洲va久久久噜噜噜久久 | 久久久久黑人强伦姧人妻| 狠狠狠色丁香婷婷综合久久俺| 精品一区二区久久| 精品永久久福利一区二区| 精品久久久久香蕉网| 国内精品久久久久久久97牛牛| 亚洲狠狠婷婷综合久久久久| 久久亚洲精品成人av无码网站| 亚洲国产精品无码成人片久久| 久久99精品国产麻豆| 久久99精品久久久久久| 久久不见久久见免费影院www日本| 国内精品欧美久久精品| 国产精品久久久久蜜芽| 精品久久久久久国产| 国产精品久久影院| 久久国产免费直播| 久久人做人爽一区二区三区 | 99久久99久久精品国产片果冻| 伊人久久大香线蕉综合Av| 久久久久久亚洲AV无码专区| 97久久久久人妻精品专区| 精品久久久久中文字幕一区| 久久久久久久波多野结衣高潮 | 久久天天躁夜夜躁狠狠躁2022| 久久婷婷五月综合色奶水99啪| 99久久精品免费观看国产| 蜜桃麻豆www久久国产精品| 老色鬼久久亚洲AV综合| 久久久噜噜噜久久| 99久久国产综合精品麻豆| 久久天天躁狠狠躁夜夜不卡 | 久久人人爽人人爽人人片AV不| 久久久无码人妻精品无码| 欧美国产精品久久高清|