目前,我正在使用wxWidgets的wxGenericDirCtrl,它为我提供了目录树的用户界面。它看起来像这样:
但是,我希望它看起来像这样:
与wxWidgets开发人员交谈时,他们建议继续进行的一个好方法是修改wxGenericDirCtrl类以使用本机Windows目录控件。我想自己将此功能贡献给wxWidgets,但我不知道从哪里开始,并且可以使用一些建议让我开始。
问题:
答案 0 :(得分:3)
自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 );
}
}
}
当父窗口被销毁时,通常在父窗口的Release()
处理程序中调用COM对象的WM_DESTROY
方法来销毁命名空间树控件:
pTree.Release(); // Releases the COM object and sets the pointer to nullptr
在启动程序时不要忘记CoInitialize(nullptr)
,在关机前忘记CoUninitialize()
。
答案 1 :(得分:0)
wxWidgets不使用MFC,.NET或Windows上的任何其他高级库。只是基本的系统API(libs kernel32,winspool,comctl32等)。 OSX也是如此,使用操作系统提供的API。在Linux中没有这样的“基本API”,因此wxWidgets使用GTK +。
您已经拥有要搜索的关键字: explorer like control 。
wxGenericDirCtrl
有GetTreeCtrl()
个成员。然后,只需将图像添加到节点,例如wxTreeCtrl::AssignButtonsImageList()
。见wx docs
答案 2 :(得分:0)
<强> ExplorerApp.h 强>
#ifndef EXPLORERAPP_H
#define EXPLORERAPP_H
#include <wx/app.h>
class ExplorerApp : public wxApp
{
public:
virtual bool OnInit();
};
#endif // EXPLORERAPP_H
<强> ExplorerApp.cpp 强>
#include "ExplorerApp.h"
//(*AppHeaders
#include "ExplorerMain.h"
#include <wx/image.h>
//*)
IMPLEMENT_APP(ExplorerApp);
bool ExplorerApp::OnInit()
{
//(*AppInitialize
bool wxsOK = true;
wxInitAllImageHandlers();
if ( wxsOK )
{
ExplorerFrame* Frame = new ExplorerFrame(0);
Frame->Show();
SetTopWindow(Frame);
}
//*)
return wxsOK;
}
<强> ExplorerMain.h 强>
#ifndef EXPLORERMAIN_H
#define EXPLORERMAIN_H
#include<wx/imaglist.h>
#include<wx/artprov.h>
#include<wx/dir.h>
////(*Headers(ExplorerFrame)
#include <wx/treectrl.h>
#include <wx/textctrl.h>
#include <wx/button.h>
#include <wx/dirdlg.h>
#include <wx/frame.h>
//*)
class ExplorerFrame: public wxFrame
{
public:
ExplorerFrame(wxWindow* parent,wxWindowID id = -1);
virtual ~ExplorerFrame();
private:
////(*Handlers(ExplorerFrame)
void OnQuit(wxCommandEvent& event);
void OnAbout(wxCommandEvent& event);
void OnButton1Click(wxCommandEvent& event);
void findir(wxTreeItemId,wxString);
//*)
////(*Identifiers(ExplorerFrame)
static const long ID_TEXTCTRL1;
static const long ID_BUTTON1;
static const long ID_CUSTOM1;
//*)
////(*Declarations(ExplorerFrame)
wxButton* Button1;
wxDirDialog* DirDialog1;
wxTextCtrl* TextCtrl1;
wxTreeCtrl* Mytreectrl;
//*)
wxImageList* myimageliste;
wxTreeItemId root;
wxTreeItemId Child1;
wxTreeItemId Child2;
wxTreeItemId Child3;
DECLARE_EVENT_TABLE()
};
#endif // EXPLORERMAIN_H
<强> ExplorerMain.cpp 强>
#include "ExplorerMain.h"
#include <wx/msgdlg.h>
////(*InternalHeaders(ExplorerFrame)
#include <wx/intl.h>
#include <wx/string.h>
//*)
//helper functions
enum wxbuildinfoformat {
short_f, long_f };
wxString wxbuildinfo(wxbuildinfoformat format)
{
wxString wxbuild(wxVERSION_STRING);
if (format == long_f )
{
#if defined(__WXMSW__)
wxbuild << _T("-Windows");
#elif defined(__UNIX__)
wxbuild << _T("-Linux");
#endif
#if wxUSE_UNICODE
wxbuild << _T("-Unicode build");
#else
wxbuild << _T("-ANSI build");
#endif // wxUSE_UNICODE
}
return wxbuild;
}
//(*IdInit(ExplorerFrame)
const long ExplorerFrame::ID_TEXTCTRL1 = wxNewId();
const long ExplorerFrame::ID_BUTTON1 = wxNewId();
const long ExplorerFrame::ID_CUSTOM1 = wxNewId();
//*)
BEGIN_EVENT_TABLE(ExplorerFrame,wxFrame)
//(*EventTable(ExplorerFrame)
//*)
END_EVENT_TABLE()
ExplorerFrame::ExplorerFrame(wxWindow* parent,wxWindowID id)
{
////(*Initialize(ExplorerFrame)
Create(parent, id, _("wxTreeCtrl"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_STYLE, _T("id"));
SetClientSize(wxSize(400,298));
TextCtrl1 = new wxTextCtrl(this, ID_TEXTCTRL1, _("C:/"), wxPoint(32,16), wxSize(240,22), 0, wxDefaultValidator, _T("ID_TEXTCTRL1"));
Button1 = new wxButton(this, ID_BUTTON1, _("Browse"), wxPoint(320,16), wxDefaultSize, 0, wxDefaultValidator, _T("ID_BUTTON1"));
Mytreectrl = new wxTreeCtrl(this,ID_CUSTOM1,wxPoint(24,56),wxSize(352,224),wxTR_HAS_BUTTONS,wxDefaultValidator,_T("ID_CUSTOM1"));
DirDialog1 = new wxDirDialog(this, _("Select directory"), wxEmptyString, wxDD_DEFAULT_STYLE, wxDefaultPosition, wxDefaultSize, _T("wxDirDialog"));
Center();
Connect(ID_BUTTON1,wxEVT_COMMAND_BUTTON_CLICKED,(wxObjectEventFunction)&ExplorerFrame::OnButton1Click);
//*)
myimageliste = new wxImageList(16,16);
myimageliste->Add(wxArtProvider::GetBitmap(wxART_FOLDER,wxART_OTHER,wxSize(16,16)));
myimageliste->Add(wxArtProvider::GetBitmap(wxART_REPORT_VIEW,wxART_OTHER,wxSize(16,16)));
Mytreectrl->AssignImageList(myimageliste);
root = Mytreectrl->AddRoot(_T("Root"),0);
/*Child1 = Mytreectrl->AppendItem(root,_T("Folder 1"),0);
Mytreectrl->AppendItem(Child1,_T("My folder 11"),1);
Mytreectrl->AppendItem(Child1,_T("My folder 12"),1);
Mytreectrl->AppendItem(Child1,_T("My folder 13"),1);
Child2 = Mytreectrl->AppendItem(root,_T("Folder 2"),0);
Mytreectrl->AppendItem(Child2,_T("My folder 21"),1);
Mytreectrl->AppendItem(Child2,_T("My folder 22"),1);
Mytreectrl->AppendItem(Child2,_T("My folder 23"),1);
Child3 = Mytreectrl->AppendItem(root,_T("Folder 3"),0);
Mytreectrl->ExpandAll();*/
//findir(root,"C:\\");
}
ExplorerFrame::~ExplorerFrame()
{
//(*Destroy(ExplorerFrame)
//*)
}
void ExplorerFrame::OnQuit(wxCommandEvent& event)
{
Close();
}
void ExplorerFrame::OnAbout(wxCommandEvent& event)
{
wxString msg = wxbuildinfo(long_f);
wxMessageBox(msg, _("Welcome to..."));
}
void ExplorerFrame::findir(wxTreeItemId id,wxString path){
wxDir mydir;
//DirDialog1->SetPath(_T("C://"));
bool isopen = false;
//int dir = DirDialog1->ShowModal();
// if(dir == wxID_OK){
//TextCtrl1->SetValue(DirDialog1->GetPath());
//Mytreectrl->DeleteChildren(root);
//Mytreectrl->SetItemText(root,DirDialog1->GetPath());
isopen = mydir.Open(path);
//}
wxString filename;
bool cont = false;
bool con = false;
if(isopen){
con = mydir.GetFirst(&filename,wxEmptyString,wxDIR_DIRS);
}
int handleforfiles = 0;
while(con and isopen){
wxTreeItemId ids = Mytreectrl->AppendItem(id,filename,0);
//wxMessageBox(path+filename,path+'\\'+filename);
if(handleforfiles >= 150){
//wxMessageBox(_T("The Max File limit reached"),_T("The Max File limit reached"));
break;
}
findir(ids,path+'\\'+filename);
con = mydir.GetNext(&filename);
++handleforfiles;
}
if(isopen){
cont = mydir.GetFirst(&filename,wxEmptyString,wxDIR_FILES);
}
handleforfiles = 0;
while(cont and isopen){
Mytreectrl->AppendItem(id,filename,1);
if(handleforfiles >= 150){
//wxMessageBox(_T("The Max File limit reached"),_T("The Max File limit reached"));
break;
}
cont = mydir.GetNext(&filename);
++handleforfiles;
}
}
void ExplorerFrame::OnButton1Click(wxCommandEvent& event)
{
//wxDir mydir;
DirDialog1->SetPath(_T("C://"));
//bool isopen = false;
int dir = DirDialog1->ShowModal();
if(dir == wxID_OK){
TextCtrl1->SetValue(DirDialog1->GetPath());
Mytreectrl->DeleteChildren(root);
Mytreectrl->SetItemText(root,DirDialog1->GetPath());
//isopen = mydir.Open(DirDialog1->GetPath());
findir(root,DirDialog1->GetPath());
}
}