【问题标题】:Creating a Windows explorer like directory tree创建类似目录树的 Windows 资源管理器
【发布时间】:2018-02-02 15:37:42
【问题描述】:

目前,我正在使用 wxWidgets 的 wxGenericDirCtrl,它为我提供了目录树的用户界面。它看起来像这样:

但是,我希望它看起来像这样:

在与 wxWidgets 开发人员交谈时,他们建议继续进行的一种好方法是修改 wxGenericDirCtrl 类以使用本机 Windows 目录控件。我想自己为 wxWidgets 贡献这个功能,但我不确定从哪里开始,并且可以使用一些建议来帮助我开始。

问题:

  1. 在 C++ 中创建此类控件的正确本机方法是什么。我使用的是 MFC、.NET 还是其他东西?
  2. 是否有任何关键字可以帮助我找到这些信息?
  3. 是否有任何示例代码显示如何执行此操作?

【问题讨论】:

  • 具体怎么做的,看微软的USBView例子,不错。
  • MFC 使用CMFCShellTreeCtrl,它不是像TreeView 这样的原生控件。我认为在 wxwidgets 中使用它是不切实际的。你可以试试 WinAPI Shell functions
  • 为什么不创建一个TreeView 控件并实现所有必要的 - 用FindFirst 等填充文件名。顺便说一句,第一个示例包括文件 (.txt),Windows 资源管理器树只有文件夹。

标签: c++ winapi wxwidgets windows-shell


【解决方案1】:

自 Windows Vista 以来,创建类似于目录树的窗口资源管理器(称为“shell 命名空间树控件”)变得非常容易。该控件可以通过名为INameSpaceTreeControl 的COM 类创建。 Windows 7 添加了这个类的更新版本,称为INameSpaceTreeControl2

可以从父窗口的WM_CREATE 处理程序调用以下示例代码。它创建一个名称空间树控件,其根设置为桌面文件夹。其他根目录也是可以的,甚至可以插入多个根目录。

#include <ShlObj.h>   //Shell COM API
#include <atlbase.h>  //CComPtr

static CComPtr<INameSpaceTreeControl> pTree;
if( SUCCEEDED( pTree.CoCreateInstance( CLSID_NamespaceTreeControl ) ) )
{
    RECT rc{ 0, 0, 444, 333 }; // Client coordinates of the tree control
    if( SUCCEEDED( pTree->Initialize( hWndParent, &rc, 
            NSTCS_HASEXPANDOS | NSTCS_AUTOHSCROLL | NSTCS_FADEINOUTEXPANDOS ) ) )
    {
        CComPtr<IShellItem> pItem;
        if( SUCCEEDED( SHCreateItemInKnownFolder( FOLDERID_Desktop, 0, nullptr, 
                                                  IID_PPV_ARGS( &pItem ) ) ) )
        {
            pTree->AppendRoot( pItem, SHCONTF_FOLDERS, NSTCRS_EXPANDED, nullptr );
        }
    }
}

当父窗口被销毁时,通过调用 COM 对象的Release() 方法来销毁命名空间树控件,通常在父窗口的WM_DESTROY 处理程序中:

pTree.Release();  // Releases the COM object and sets the pointer to nullptr

别忘了在程序启动时CoInitialize(nullptr) 一次,在关机前CoUninitialize()

【讨论】:

  • 这很有帮助!以防它帮助别人:至少在 Windows 10 中,我发现释放界面并没有破坏窗口。实际上,创建后根本不需要保留接口指针。此外,MSDN 没有记录真正重要的事情:使用 IUnknown_GetWindow 获取控件的 HWND,您可以使用它来调整它的大小、销毁它(如果需要并且父级没有被销毁)等等。跨度>
【解决方案2】:

wxWidgets 不使用 MFC、.NET 或 Windows 上的任何其他高级库。只是基本的系统 API(libs kernel32、winspool、comctl32 等)。 OSX 也是如此,使用 OS 提供的 API。在 Linux 中没有这样的“基本 API”,因此 wxWidgets 使用 GTK+。

您已经有了要搜索的关键字:explorer like control

wxGenericDirCtrl 拥有GetTreeCtrl()member。然后,只需将图像添加到节点,例如通过wxTreeCtrl::AssignButtonsImageList()。见wx docs

【讨论】:

  • 我的问题不是关于修改 wxGenericDirCtrl 中的图标,而是在可能的情况下实际使用本机控件。你是说这在 wxWidgets 中是不可能的,而唯一的方法是创建一个看起来像 Windows 的新控件?
  • 我不知道你想要的MS native control。我认为 MS 使用带有自定义展开按钮和图像的 TreeView。这就是wxGenericDirCtrl所做的。
猜你喜欢
  • 1970-01-01
  • 2010-09-16
  • 2011-07-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-31
  • 2021-09-04
相关资源
最近更新 更多