Windows資源管理器相關資訊獲取

2021-08-21 16:51:13 字數 3632 閱讀 1540

翻譯參考

有的時候,軟體開發是創造新的東西,不過更常見的是把現有的東西組合到一起。今天的難題就屬於後一種。

給定乙個視窗控制代碼,你可以判定:(1)是否是乙個資源管理器視窗,如果是,那麼(2)它正在顯示哪個資料夾,而且(3)當前焦點在哪一項上。

這其實不是一件難事。你只需把許多小碎片拼湊起來就可以。

一切從 shellwindows 物件開始,它代表所有開啟的外殼視窗。你可以使用 item 屬性遍歷它們。用 c++ 來做這事看起來有點笨拙,因為 shellwindows 物件就是為像 jscript 或者 visual basic 這樣的指令碼語言的使用所設計的。

ishellwindows *psw;

if (succeeded(cocreateinstance(clsid_shellwindows, null, clsctx_all,

iid_ishellwindows, (void**)&psw)))

psw->release();

}

對於每乙個元素,我們可以詢問其視窗控制代碼以判斷是否是我們需要的。

hwnd hwndwba;

if (succeeded(pwba->get_hwnd((long_ptr*)&hwndwba)) &&

hwndwba == hwndfind)

pwba->release();

}

iserviceprovider *psp;

if (succeeded(pwba->queryinte***ce(iid_iserviceprovider, (void**)&psp)))

psp->release();

}

我們再使用 queryactiveshellview 方法從 ishellbrowser 介面請求當前的外殼檢視(shell view)。

ishellview *psv;

if (succeeded(psb->queryactiveshellview(&psv)))

當然,我們真正想要的其實是 ifolderview 介面,它是乙個自動化物件,囊括了所有的好東西。

ifolderview *pfv;

if (succeeded(psv->queryinte***ce(iid_ifolderview,

(void**)&pfv)))

挺好。想從檢視裡得到些什麼呢,正被瀏覽的 ishellfolder 的位置怎麼樣?做這件事情,我們需要使用 ipersistfolder2::getcurfolder。getfolder 方法可以使我們訪問到外殼資料夾(shell folder),我們要從那裡請求 ipersistfolder2。(大部分情況下你需要 ishellfolder 介面,因為大多數的酷玩意兒都在那兒。)

ipersistfolder2 *ppf2;

if (succeeded(pfv->getfolder(iid_ipersistfolder2,

(void**)&ppf2)))

ppf2->release();

}

我們把 pidl 轉換為用於顯示的路徑。

if (!shgetpathfromidlist(pidlfolder, g_szpath)) 

...

用我們已經得到的這些可以幹什麼呢?哦,對了,來看一下當前的焦點在什麼上吧。

int ifocus;

if (succeeded(pfv->getfocuseditem(&ifocus)))

要把聚焦項的名字顯示出來,我們需要該項的 pidl 和 ishellfolder。(看看,我告訴過你好東西就在 ishellfolder 那兒)。項可以通過 item 方法得到。

lpitemidlist pidlitem;

if (succeeded(pfv->item(ifocus, &pidlitem)))

(如果想得到選中項的列表,我們可以使用 items 方法,需要傳入 svgio_selection。)

得到 pidl 之後,還需要 ishellfolder:

ishellfolder *psf;

if (succeeded(ppf2->queryinte***ce(iid_ishellfolder,

(void**)&psf)))

然後我們用這兩樣東西以及 getdisplaynameof 方法的輔助來獲取項的顯示名字。

strret str;

if (succeeded(psf->getdisplaynameof(pidlitem,

shgdn_infolder,

&str)))

我們可以使用輔助函式 strrettobuf 把那個乖僻的 strret 結構轉換為令人生厭的字串緩衝區。(怪異的 strret 結構的歷史容以後再說。)

strrettobuf(&str, pidlitem, g_szitem, max_path);
好,下面我們把所有這些都組合起來。**看起來相當醜陋,因為我把所有東西都放到了乙個大函式裡而沒有把它們分離為子函式。在「現實生活」中,我會把它們分為小的輔助函式,那樣更便於管理。

開啟 scratch(譯者注:原作者的乙個測試用程式原型) 程式,新增一下函式:

#include 

#include

tchar g_szpath[max_path];

tchar g_szitem[max_path];

void

callback

recalctext(hwnd hwnd, uint, uint_ptr, dword)

int ifocus;

if (succeeded(pfv->getfocuseditem(&ifocus)))

psf->release();

}cotaskmemfree(pidlitem);}}

cotaskmemfree(pidlfolder);

}ppf2->release();

}pfv->release();

}psv->release();

}psb->release();

}psp->release();}}

pwba->release();

}pdisp->release();

} psw->release();

} invalidaterect(hwnd, null, true);

}

剩下的就是定期呼叫此函式並列印結果。

bool oncreate(hwnd hwnd, lpcreatestruct lpcs)

void paintcontent(hwnd hwnd, paintstruct *pps)

現在已經準備就緒了。執行程式,把它放到一邊,然後啟動資源管理器並觀察程式,會發現它可以跟蹤你所在的資料夾和焦點所在的項。

我希望我已經證實了我的觀點:通常,你所需的東西的所有片斷已經存在了,你只不過是需要指出怎樣把它們拼在一塊。注意,每一小片都不大。只是你必須能意識到可以用一種有趣的方法把它們放到一起。

Windows資源管理器

在資源管理器中,選定多個非連續檔案的操作為 a 按住shift鍵,單擊每乙個要選定的檔案圖示 b 按住ctrl鍵,單擊每乙個要選定的檔案圖示 c 先選中第乙個檔案,按住shift鍵,再單擊最後乙個要選定的檔案圖示 d 先選中第乙個檔案,按住ctrl鍵,再單擊最後乙個要選定的檔案圖示 檔案abc.bm...

資源管理器

using system using system.collections.generic using system.linq using system.text using system.threading.tasks namespace day 09 小型資源管理器 檔案長度 public st...

Windows窗體資源管理器Treeview運用

using system using system.collections.generic using system.componentmodel using system.data using system.drawing using system.text using system.window...