c++ 通过win api 如果鼠标点击的是在资源管理器那么输出资源管理器的目录路径思路Create an instance of IShellWindows and use that to enumerate all currently open Explorer windows Using various related interfaces you can get the window ha
具体实现过程如下:
- 首先需要包含头文件和链接库:
#include <Windows.h>
#include <ShlObj.h>
#include <vector>
#include <string>
#pragma comment(lib, "Shell32.lib")
- 创建一个函数,用于获取当前选中的文件夹路径:
std::wstring GetExplorerPath(HWND hwnd)
{
std::wstring path;
IShellWindows *pShellWindows = NULL;
HRESULT hr = CoCreateInstance(CLSID_ShellWindows, NULL, CLSCTX_ALL, IID_IShellWindows, (void**)&pShellWindows);
if (SUCCEEDED(hr))
{
HWND hWnd;
IDispatch* pDisp;
VARIANT vEmpty = {};
VARIANT vHWND = {};
vHWND.vt = VT_I4;
vHWND.lVal = (LONG_PTR)hwnd;
pShellWindows->FindWindowSW(&vHWND, &pDisp, SWC_EXPLORER, &hWnd, SWFO_NEEDDISPATCH);
IWebBrowserApp* pBrowser;
hr = pDisp->QueryInterface(IID_IWebBrowserApp, (void**)&pBrowser);
if (SUCCEEDED(hr))
{
IShellFolder* pFolder;
LPITEMIDLIST pidl;
hr = SHGetSpecialFolderLocation(NULL, CSIDL_DESKTOP, &pidl);
if (SUCCEEDED(hr))
{
hr = SHBindToObject(NULL, pidl, NULL, IID_IShellFolder, (void**)&pFolder);
if (SUCCEEDED(hr))
{
IShellFolder2* pFolder2;
hr = pFolder->QueryInterface(IID_IShellFolder2, (void**)&pFolder2);
if (SUCCEEDED(hr))
{
IDispatch* pDisp;
hr = pBrowser->get_Document(&pDisp);
if (SUCCEEDED(hr))
{
IHTMLDocument2* pDocument;
hr = pDisp->QueryInterface(IID_IHTMLDocument2, (void**)&pDocument);
if (SUCCEEDED(hr))
{
IHTMLElement* pElement;
hr = pDocument->getElementById(L'address', &pElement);
if (SUCCEEDED(hr))
{
BSTR bstrPath;
hr = pElement->get_innerText(&bstrPath);
if (SUCCEEDED(hr))
{
path = bstrPath;
SysFreeString(bstrPath);
}
pElement->Release();
}
pDocument->Release();
}
pDisp->Release();
}
pFolder2->Release();
}
pFolder->Release();
}
CoTaskMemFree(pidl);
}
pBrowser->Quit();
pBrowser->Release();
}
pDisp->Release();
pShellWindows->Release();
}
return path;
}
这个函数的大致流程如下:
- 创建一个 IShellWindows 实例,并使用该实例列举所有当前打开的资源管理器窗口。
- 对于每个资源管理器窗口,获取其句柄和当前文件夹的 PIDL。
- 如果该窗口的句柄等于当前激活窗口的句柄,则将 PIDL 转换为路径。
- 返回该路径。
- 在 WinMain 函数中,将该函数与 WM_LBUTTONDOWN 消息关联起来,实现鼠标点击资源管理器时输出其路径:
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_LBUTTONDOWN:
{
HWND foreWnd = GetForegroundWindow();
HWND explorerWnd = NULL;
do
{
explorerWnd = FindWindowEx(NULL, explorerWnd, L"CabinetWClass", NULL);
if (explorerWnd != NULL)
{
if (explorerWnd == foreWnd)
{
std::wstring path = GetExplorerPath(explorerWnd);
MessageBox(hwnd, path.c_str(), L"Explorer Path", MB_OK);
break;
}
}
else break;
} while (true);
break;
}
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASS wc = {};
wc.lpfnWndProc = WndProc;
wc.hInstance = hInstance;
wc.lpszClassName = L"MyClass";
RegisterClass(&wc);
HWND hwnd = CreateWindow(L"MyClass", L"MyWindow", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 640, 480, NULL, NULL, hInstance, NULL);
ShowWindow(hwnd, nCmdShow);
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int)msg.wParam;
}
这段代码实现了一个简单的窗口,当鼠标单击时,会遍历所有资源管理器窗口,找到当前激活的窗口并输出其路径
原文地址: https://www.cveoy.top/t/topic/hbad 著作权归作者所有。请勿转载和采集!