- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我一直在苦苦思索如何才能做到这一点。基本上,我的应用程序需要使用 winapi 在 c++ 中的 Windows 中找出事件文件资源管理器(即前台的文件资源管理器)的目录路径。
取而代之的是:
TCHAR* getWindowDir(){
TCHAR* windowTitle = new TCHAR[MAX_PATH];
HWND windowHandle = GetForegroundWindow();
GetWindowText(windowHandle,windowTitle,MAX_PATH);
return windowTitle;
}
这显然会返回窗口标题,我希望它返回事件目录。
最佳答案
创建 IShellWindows
的实例并使用它来枚举所有当前打开的资源管理器窗口。使用各种相关接口(interface),您可以以PIDL
的形式获取窗口句柄和当前文件夹。来自 IShellWindows
枚举的每个项目。如果窗口句柄等于 GetForegroundWindow()
的结果,则将 PIDL 转换为路径。
在下文中,我提供了一些用于获取有关所有资源管理器窗口的信息的代码。它部分基于 code of Raymond Chen但使用智能指针来编写不那么脆弱和更干净的代码。我还通过异常添加了错误处理。
首先是所需的包含和一些实用程序代码:
#include <Windows.h>
#include <shlobj.h>
#include <atlcomcli.h> // for COM smart pointers
#include <atlbase.h> // for COM smart pointers
#include <vector>
#include <system_error>
#include <memory>
#include <iostream>
// Throw a std::system_error if the HRESULT indicates failure.
template< typename T >
void ThrowIfFailed( HRESULT hr, T&& msg )
{
if( FAILED( hr ) )
throw std::system_error{ hr, std::system_category(), std::forward<T>( msg ) };
}
// Deleter for a PIDL allocated by the shell.
struct CoTaskMemDeleter
{
void operator()( ITEMIDLIST* pidl ) const { ::CoTaskMemFree( pidl ); }
};
// A smart pointer for PIDLs.
using UniquePidlPtr = std::unique_ptr< ITEMIDLIST, CoTaskMemDeleter >;
现在我们定义一个函数 GetCurrentExplorerFolders()
来返回所有当前打开的资源管理器窗口的信息,包括窗口句柄和当前文件夹的 PIDL
。
// Return value of GetCurrentExplorerFolders()
struct ExplorerFolderInfo
{
HWND hwnd = nullptr; // window handle of explorer
UniquePidlPtr pidl; // PIDL that points to current folder
};
// Get information about all currently open explorer windows.
// Throws std::system_error exception to report errors.
std::vector< ExplorerFolderInfo > GetCurrentExplorerFolders()
{
CComPtr< IShellWindows > pshWindows;
ThrowIfFailed(
pshWindows.CoCreateInstance( CLSID_ShellWindows ),
"Could not create instance of IShellWindows" );
long count = 0;
ThrowIfFailed(
pshWindows->get_Count( &count ),
"Could not get number of shell windows" );
std::vector< ExplorerFolderInfo > result;
result.reserve( count );
for( long i = 0; i < count; ++i )
{
ExplorerFolderInfo info;
CComVariant vi{ i };
CComPtr< IDispatch > pDisp;
ThrowIfFailed(
pshWindows->Item( vi, &pDisp ),
"Could not get item from IShellWindows" );
if( ! pDisp )
// Skip - this shell window was registered with a NULL IDispatch
continue;
CComQIPtr< IWebBrowserApp > pApp{ pDisp };
if( ! pApp )
// This window doesn't implement IWebBrowserApp
continue;
// Get the window handle.
pApp->get_HWND( reinterpret_cast<SHANDLE_PTR*>( &info.hwnd ) );
CComQIPtr< IServiceProvider > psp{ pApp };
if( ! psp )
// This window doesn't implement IServiceProvider
continue;
CComPtr< IShellBrowser > pBrowser;
if( FAILED( psp->QueryService( SID_STopLevelBrowser, &pBrowser ) ) )
// This window doesn't provide IShellBrowser
continue;
CComPtr< IShellView > pShellView;
if( FAILED( pBrowser->QueryActiveShellView( &pShellView ) ) )
// For some reason there is no active shell view
continue;
CComQIPtr< IFolderView > pFolderView{ pShellView };
if( ! pFolderView )
// The shell view doesn't implement IFolderView
continue;
// Get the interface from which we can finally query the PIDL of
// the current folder.
CComPtr< IPersistFolder2 > pFolder;
if( FAILED( pFolderView->GetFolder( IID_IPersistFolder2, (void**) &pFolder ) ) )
continue;
LPITEMIDLIST pidl = nullptr;
if( SUCCEEDED( pFolder->GetCurFolder( &pidl ) ) )
{
// Take ownership of the PIDL via std::unique_ptr.
info.pidl = UniquePidlPtr{ pidl };
result.push_back( std::move( info ) );
}
}
return result;
}
示例显示如何调用 GetCurrentExplorerFolders()
,将 PIDL
转换为路径并捕获异常。
int main()
{
::CoInitialize( nullptr );
try
{
std::wcout << L"Currently open explorer windows:\n";
for( const auto& info : GetCurrentExplorerFolders() )
{
CComHeapPtr<wchar_t> pPath;
if( SUCCEEDED( ::SHGetNameFromIDList( info.pidl.get(), SIGDN_FILESYSPATH, &pPath ) ) )
{
std::wcout << L"hwnd: 0x" << std::hex << info.hwnd
<< L", path: " << static_cast<LPWSTR>( pPath ) << L"\n";
}
}
}
catch( std::system_error& e )
{
std::cout << "ERROR: " << e.what() << "\nError code: " << e.code() << "\n";
}
::CoUninitialize();
}
可能的输出:
Currently open explorer windows:
hwnd: 0x0030058E, path: C:\Windows
hwnd: 0x000C06D4, path: C:\Program Files
关于c++ - 如何在 C++ winapi 中获取事件文件资源管理器窗口的路径,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43815932/
我之前让 dll 注入(inject)器变得简单,但我有 Windows 7,我用 C# 和 C++ 做了它,它工作得很好!但是现在当我在 Windows 8 中尝试相同的代码时,它似乎没有以正确的方
我正在尝试制作一个名为 core-splitter 的元素,该元素在 1.0 中已弃用,因为它在我们的项目中起着关键作用。 如果您不知道 core-splitter 的作用,我可以提供一个简短的描述。
我有几个不同的蜘蛛,想一次运行所有它们。基于 this和 this ,我可以在同一个进程中运行多个蜘蛛。但是,我不知道如何设计一个信号系统来在所有蜘蛛都完成后停止 react 器。 我试过了: cra
有没有办法在达到特定条件时停止扭曲 react 器。例如,如果一个变量被设置为某个值,那么 react 器应该停止吗? 最佳答案 理想情况下,您不会将变量设置为一个值并停止 react 器,而是调用
https://code.angularjs.org/1.0.0rc9/angular-1.0.0rc9.js 上面的链接定义了外部js文件,我不知道Angular-1.0.0rc9.js的注入(in
我正在尝试运行一个函数并将服务注入(inject)其中。我认为这可以使用 $injector 轻松完成.所以我尝试了以下(简化示例): angular.injector().invoke( [ "$q
在 google Guice 中,我可以使用函数 createInjector 创建基于多个模块的注入(inject)器。 因为我使用 GWT.create 在 GoogleGin 中实例化注入(in
我在 ASP.NET Core 1.1 解决方案中使用配置绑定(bind)。基本上,我在“ConfigureServices Startup”部分中有一些用于绑定(bind)的简单代码,如下所示: s
我在 Spring MVC 中设置 initBinder 时遇到一些问题。我有一个 ModelAttribute,它有一个有时会显示的字段。 public class Model { privat
我正在尝试通过jquery post发布knockoutjs View 模型 var $form = $('#barcodeTemplate form'); var data = ko.toJS(vm
如何为包含多态对象集合的复杂模型编写自定义模型绑定(bind)程序? 我有下一个模型结构: public class CustomAttributeValueViewModel { publi
您好,我正在尝试实现我在 this article 中找到的扩展方法对于简单的注入(inject)器,因为它不支持开箱即用的特定构造函数的注册。 根据这篇文章,我需要用一个假的委托(delegate)
你好,我想自动注册我的依赖项。 我现在拥有的是: public interface IRepository where T : class public interface IFolderReposi
我正在使用 Jasmine 测试一些 Angular.js 代码。为此,我需要一个 Angular 注入(inject)器: var injector = angular.injector(['ng'
我正在使用 Matlab 代码生成器。不可能包含代码风格指南。这就是为什么我正在寻找一个工具来“ reshape ”、重命名和重新格式化生成的代码,根据我的: 功能横幅约定 文件横幅约定 命名约定 等
这个问题在这里已经有了答案: Where and why do I have to put the "template" and "typename" keywords? (8 个答案) 关闭 8
我开发了一种工具,可以更改某些程序的外观。为此,我需要在某些进程中注入(inject)一个 dll。 现在我基本上使用这个 approach .问题通常是人们无法注入(inject) dll,因为他们
我想使用 swing、spring 和 hibernate 编写一个 java 应用程序。 我想使用数据绑定(bind)器用 bean 的值填充 gui,并且我还希望它反射(reflect) gui
我有这段代码,当两个蜘蛛完成后,程序仍在运行。 #!C:\Python27\python.exe from twisted.internet import reactor from scrapy.cr
要点是 Spring Batch (v2) 测试框架具有带有 @Autowired 注释的 JobLauncherTestUtils.setJob。我们的测试套件有多个 Job 类提供者。因为这个类不
我是一名优秀的程序员,十分优秀!