具体实现过程如下:

  1. 首先需要包含头文件和链接库:
#include <Windows.h>
#include <ShlObj.h>
#include <vector>
#include <string>
#pragma comment(lib, "Shell32.lib")
  1. 创建一个函数,用于获取当前选中的文件夹路径:
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 转换为路径。
  • 返回该路径。
  1. 在 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 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录