代码思路来源于开源项目 ,并做了简化.
开始
在VS2017 下创建C++控制台项目,在预编译头文件添加适当的include
#ifndef PCH_H#define PCH_H// TODO: 添加要在此处预编译的标头#include#include #include #include #include #include #include #include #include #endif //PCH_H// 以上为QuickLook所添加的头文件.复制代码
创建函数定义
void GetSelectedInternernal(CComQIPtrpwba);void ObtainFirstItem(CComPtr dao);void getSelectedFromDesktop();复制代码
main 函数
int main(){ for (;;) { getSelectedFromDesktop(); Sleep(1000); }}// 考虑到测试用途直接来个无限循环+Sleep复制代码
getSelectedFromDesktop
void getSelectedFromDesktop() { // 初始化 CoInitialize(nullptr); CComPtrpsw; CComQIPtr pwba; // 获取 IShellWindows 实例 if (FAILED(psw.CoCreateInstance(CLSID_ShellWindows))) return; VARIANT pvarLoc; VariantInit(&pvarLoc); long phwnd; // 获取 IWebBrowserApp 实例 if (FAILED(psw->FindWindowSW(&pvarLoc, &pvarLoc, SWC_DESKTOP, &phwnd, SWFO_NEEDDISPATCH, reinterpret_cast ( &pwba)))) return; GetSelectedInternernal(pwba);}复制代码
GetSelectedInternernal
// 层层递进取得最终的IShellView,并取出选中项(SVGIO_SELECTION)void GetSelectedInternernal(CComQIPtrpwba) { CComQIPtr psp; if (FAILED(pwba->QueryInterface(IID_IServiceProvider, reinterpret_cast (&psp)))) { return; } CComPtr psb; if (FAILED(psp->QueryService(SID_STopLevelBrowser, IID_IShellBrowser, reinterpret_cast (&psb)))) { return; } CComPtr psv; if (FAILED(psb->QueryActiveShellView(&psv))) { return; } CComPtr dao; if (FAILED(psv->GetItemObject(SVGIO_SELECTION, IID_IDataObject, reinterpret_cast (&dao)))) { return; } ObtainFirstItem(dao);}复制代码
// 最终提取文件地址void ObtainFirstItem(CComPtrdao) { FORMATETC formatetc; STGMEDIUM medium = { sizeof medium }; formatetc.cfFormat = CF_HDROP; formatetc.ptd = nullptr; formatetc.dwAspect = DVASPECT_CONTENT; formatetc.lindex = -1; formatetc.tymed = TYMED_HGLOBAL; medium.tymed = TYMED_HGLOBAL; if (FAILED(dao->GetData(&formatetc, &medium))) return; // 获取选中数量 int n = DragQueryFile(HDROP(medium.hGlobal), 0xFFFFFFFF, nullptr, 0); if (n < 1) return; WCHAR buffer[260] = { '\0' }; // 选择第一个 DragQueryFile(HDROP(medium.hGlobal), 0, buffer, MAX_PATH - 1); // 输出 std::wcout << buffer << std::endl;}复制代码