3f66f6a5b3
This keyword is not expanded by Git which means it's not replaced with the correct revision value in the releases made using git-based scripts and it's confusing to have lines with unexpanded "$Id$" in the released files. As expanding them with Git is not that simple (it could be done with git archive and export-subst attribute) and there are not many benefits in having them in the first place, just remove all these lines. If nothing else, this will make an eventual transition to Git simpler. Closes #14487. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@74602 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
1437 lines
37 KiB
C++
1437 lines
37 KiB
C++
///////////////////////////////////////////////////////////////////////////////
|
|
// Name: regtest.cpp
|
|
// Purpose: wxRegKey class demo
|
|
// Author: Vadim Zeitlin
|
|
// Modified by:
|
|
// Created: 03.04.98
|
|
// Copyright: (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
|
|
// Licence: wxWindows licence
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
// ============================================================================
|
|
// declarations
|
|
// ============================================================================
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// headers
|
|
// ----------------------------------------------------------------------------
|
|
#include "wx/wxprec.h"
|
|
|
|
#ifdef __BORLANDC__
|
|
# pragma hdrstop
|
|
#endif
|
|
|
|
#ifndef WX_PRECOMP
|
|
# include "wx/wx.h"
|
|
#endif
|
|
|
|
#include "wx/treectrl.h"
|
|
#include "wx/config.h"
|
|
#include "wx/imaglist.h"
|
|
#include "wx/tokenzr.h"
|
|
|
|
#if wxUSE_CONFIG_NATIVE && defined( __WINDOWS__ )
|
|
# define DO_REGTEST 1
|
|
#else
|
|
# define DO_REGTEST 0
|
|
#endif
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// application type
|
|
// ----------------------------------------------------------------------------
|
|
class RegApp : public wxApp
|
|
{
|
|
public:
|
|
bool OnInit();
|
|
};
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// image list with registry icons
|
|
// ----------------------------------------------------------------------------
|
|
class RegImageList : public wxImageList
|
|
{
|
|
public:
|
|
enum Icon
|
|
{
|
|
Root,
|
|
ClosedKey,
|
|
OpenedKey,
|
|
TextValue,
|
|
BinaryValue
|
|
};
|
|
|
|
RegImageList();
|
|
};
|
|
|
|
#if DO_REGTEST
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// our control
|
|
// ----------------------------------------------------------------------------
|
|
class RegTreeCtrl : public wxTreeCtrl
|
|
{
|
|
public:
|
|
// ctor & dtor
|
|
RegTreeCtrl(wxWindow *parent, wxWindowID id);
|
|
virtual ~RegTreeCtrl();
|
|
|
|
// notifications
|
|
void OnDeleteItem (wxTreeEvent& event);
|
|
void OnItemExpanding (wxTreeEvent& event);
|
|
void OnSelChanged (wxTreeEvent& event);
|
|
|
|
void OnBeginEdit (wxTreeEvent& event);
|
|
void OnEndEdit (wxTreeEvent& event);
|
|
|
|
void OnBeginDrag (wxTreeEvent& event);
|
|
void OnEndDrag (wxTreeEvent& event);
|
|
|
|
void OnRightClick (wxMouseEvent& event);
|
|
void OnChar (wxKeyEvent& event);
|
|
void OnIdle (wxIdleEvent& event);
|
|
|
|
// forwarded notifications (by the frame)
|
|
void OnMenuTest();
|
|
|
|
// operations
|
|
void GoTo(const wxString& location);
|
|
void DoRefresh();
|
|
void DeleteSelected();
|
|
void ShowProperties();
|
|
void CreateNewKey(const wxString& strName);
|
|
void CreateNewTextValue(const wxString& strName);
|
|
void CreateNewBinaryValue(const wxString& strName);
|
|
void SetRegistryView(wxRegKey::WOW64ViewMode viewMode);
|
|
|
|
// information
|
|
bool IsKeySelected() const;
|
|
|
|
private:
|
|
// structure describing a registry key/value
|
|
class TreeNode : public wxTreeItemData
|
|
{
|
|
WX_DEFINE_ARRAY_PTR(TreeNode *, TreeChildren);
|
|
public:
|
|
RegTreeCtrl *m_pTree; // must be !NULL
|
|
TreeNode *m_pParent; // NULL only for the root node
|
|
wxTreeItemId m_id; // the id of the tree control item
|
|
wxString m_strName; // name of the key/value
|
|
TreeChildren m_aChildren; // array of subkeys/values
|
|
bool m_bKey; // key or value?
|
|
wxRegKey *m_pKey; // only may be !NULL if m_bKey == true
|
|
wxRegKey::WOW64ViewMode m_viewMode; // How to view the registry.
|
|
|
|
// trivial accessors
|
|
wxTreeItemId Id() const { return m_id; }
|
|
bool IsRoot() const { return m_pParent == NULL; }
|
|
bool IsKey() const { return m_bKey; }
|
|
TreeNode *Parent() const { return m_pParent; }
|
|
|
|
// notifications
|
|
bool OnExpand();
|
|
void OnCollapse();
|
|
|
|
// operations
|
|
void Refresh();
|
|
bool DeleteChild(TreeNode *child);
|
|
void DestroyChildren();
|
|
const wxChar *FullName() const;
|
|
void SetRegistryView(wxRegKey::WOW64ViewMode viewMode);
|
|
|
|
// get the associated key: make sure the pointer is !NULL
|
|
wxRegKey& Key() { if ( !m_pKey ) OnExpand(); return *m_pKey; }
|
|
|
|
// dtor deletes all children
|
|
~TreeNode();
|
|
};
|
|
|
|
wxImageList *m_imageList;
|
|
wxMenu *m_pMenuPopup;
|
|
|
|
TreeNode *m_pRoot;
|
|
|
|
TreeNode *m_draggedItem; // the item being dragged
|
|
bool m_copyOnDrop; // if false, then move
|
|
|
|
bool m_restoreStatus; // after OnItemExpanding()
|
|
|
|
wxString m_nameOld; // the initial value of item being renamed
|
|
|
|
wxRegKey::WOW64ViewMode m_viewMode; // Registry view to use for keys.
|
|
|
|
TreeNode *GetNode(const wxTreeEvent& event)
|
|
{ return (TreeNode *)GetItemData(event.GetItem()); }
|
|
|
|
public:
|
|
// create a new node and insert it to the tree
|
|
TreeNode *InsertNewTreeNode(TreeNode *pParent,
|
|
const wxString& strName,
|
|
int idImage = RegImageList::ClosedKey,
|
|
const wxString *pstrValue = NULL,
|
|
wxRegKey::WOW64ViewMode viewMode = wxRegKey::WOW64ViewMode_Default);
|
|
|
|
// add standard registry keys
|
|
void AddStdKeys();
|
|
|
|
private:
|
|
DECLARE_EVENT_TABLE()
|
|
};
|
|
|
|
#endif // #if DO_REGTEST
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// the main window of our application
|
|
// ----------------------------------------------------------------------------
|
|
class RegFrame : public wxFrame
|
|
{
|
|
public:
|
|
// ctor & dtor
|
|
RegFrame(wxFrame *parent, const wxChar *title, int x, int y, int w, int h);
|
|
virtual ~RegFrame();
|
|
|
|
// callbacks
|
|
void OnQuit (wxCommandEvent& event);
|
|
void OnAbout(wxCommandEvent& event);
|
|
void OnTest (wxCommandEvent& event);
|
|
|
|
void OnGoTo (wxCommandEvent& event);
|
|
|
|
void OnExpand (wxCommandEvent& event);
|
|
void OnCollapse(wxCommandEvent& event);
|
|
void OnToggle (wxCommandEvent& event);
|
|
void OnRefresh (wxCommandEvent& event);
|
|
|
|
void OnDelete (wxCommandEvent& event);
|
|
void OnNewKey (wxCommandEvent& event);
|
|
void OnNewText (wxCommandEvent& event);
|
|
void OnNewBinary(wxCommandEvent& event);
|
|
|
|
void OnInfo (wxCommandEvent& event);
|
|
|
|
void OnViewChange (wxCommandEvent& event);
|
|
|
|
DECLARE_EVENT_TABLE()
|
|
|
|
private:
|
|
|
|
#if DO_REGTEST
|
|
RegTreeCtrl *m_treeCtrl;
|
|
#endif
|
|
};
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// various ids
|
|
// ----------------------------------------------------------------------------
|
|
|
|
enum
|
|
{
|
|
Menu_Quit = 100,
|
|
Menu_About,
|
|
Menu_Test,
|
|
Menu_GoTo,
|
|
Menu_Expand,
|
|
Menu_Collapse,
|
|
Menu_Toggle,
|
|
Menu_Refresh,
|
|
Menu_New,
|
|
Menu_NewKey,
|
|
Menu_NewText,
|
|
Menu_NewBinary,
|
|
Menu_Delete,
|
|
Menu_Info,
|
|
Menu_View,
|
|
Menu_ViewDefault,
|
|
Menu_View32,
|
|
Menu_View64,
|
|
|
|
Ctrl_RegTree = 200
|
|
};
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// event tables
|
|
// ----------------------------------------------------------------------------
|
|
|
|
BEGIN_EVENT_TABLE(RegFrame, wxFrame)
|
|
EVT_MENU(Menu_Test, RegFrame::OnTest)
|
|
EVT_MENU(Menu_About, RegFrame::OnAbout)
|
|
EVT_MENU(Menu_Quit, RegFrame::OnQuit)
|
|
EVT_MENU(Menu_GoTo, RegFrame::OnGoTo)
|
|
EVT_MENU(Menu_Expand, RegFrame::OnExpand)
|
|
EVT_MENU(Menu_Collapse, RegFrame::OnCollapse)
|
|
EVT_MENU(Menu_Toggle, RegFrame::OnToggle)
|
|
EVT_MENU(Menu_Refresh, RegFrame::OnRefresh)
|
|
EVT_MENU(Menu_Delete, RegFrame::OnDelete)
|
|
EVT_MENU(Menu_NewKey, RegFrame::OnNewKey)
|
|
EVT_MENU(Menu_NewText, RegFrame::OnNewText)
|
|
EVT_MENU(Menu_NewBinary, RegFrame::OnNewBinary)
|
|
EVT_MENU(Menu_Info, RegFrame::OnInfo)
|
|
EVT_MENU(Menu_ViewDefault, RegFrame::OnViewChange)
|
|
EVT_MENU(Menu_View32, RegFrame::OnViewChange)
|
|
EVT_MENU(Menu_View64, RegFrame::OnViewChange)
|
|
END_EVENT_TABLE()
|
|
|
|
#if DO_REGTEST
|
|
|
|
BEGIN_EVENT_TABLE(RegTreeCtrl, wxTreeCtrl)
|
|
EVT_TREE_DELETE_ITEM (Ctrl_RegTree, RegTreeCtrl::OnDeleteItem)
|
|
EVT_TREE_ITEM_EXPANDING (Ctrl_RegTree, RegTreeCtrl::OnItemExpanding)
|
|
EVT_TREE_ITEM_COLLAPSING(Ctrl_RegTree, RegTreeCtrl::OnItemExpanding)
|
|
EVT_TREE_SEL_CHANGED (Ctrl_RegTree, RegTreeCtrl::OnSelChanged)
|
|
|
|
EVT_TREE_BEGIN_LABEL_EDIT(Ctrl_RegTree, RegTreeCtrl::OnBeginEdit)
|
|
EVT_TREE_END_LABEL_EDIT (Ctrl_RegTree, RegTreeCtrl::OnEndEdit)
|
|
|
|
EVT_TREE_BEGIN_DRAG (Ctrl_RegTree, RegTreeCtrl::OnBeginDrag)
|
|
EVT_TREE_BEGIN_RDRAG (Ctrl_RegTree, RegTreeCtrl::OnBeginDrag)
|
|
EVT_TREE_END_DRAG (Ctrl_RegTree, RegTreeCtrl::OnEndDrag)
|
|
|
|
EVT_CHAR (RegTreeCtrl::OnChar)
|
|
EVT_RIGHT_DOWN(RegTreeCtrl::OnRightClick)
|
|
EVT_IDLE (RegTreeCtrl::OnIdle)
|
|
END_EVENT_TABLE()
|
|
|
|
#endif
|
|
|
|
// ============================================================================
|
|
// implementation
|
|
// ============================================================================
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// global functions
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// create the "registry operations" menu
|
|
wxMenu *CreateRegistryMenu()
|
|
{
|
|
wxMenu *pMenuNew = new wxMenu;
|
|
pMenuNew->Append(Menu_NewKey, wxT("&Key"), wxT("Create a new key"));
|
|
pMenuNew->AppendSeparator();
|
|
pMenuNew->Append(Menu_NewText, wxT("&Text value"), wxT("Create a new text value"));
|
|
pMenuNew->Append(Menu_NewBinary, wxT("&Binary value"), wxT("Create a new binary value"));
|
|
|
|
wxMenu *pMenuView = new wxMenu;
|
|
pMenuView->AppendRadioItem(
|
|
Menu_ViewDefault,
|
|
wxT("&Default"),
|
|
wxT("Default registry view for the program environment."));
|
|
pMenuView->AppendRadioItem(
|
|
Menu_View32,
|
|
wxT("32-bit Registry"),
|
|
wxT("View 32-bit registry."));
|
|
pMenuView->AppendRadioItem(
|
|
Menu_View64,
|
|
wxT("64-bit Registry"),
|
|
wxT("View 64-bit registry."));
|
|
|
|
wxMenu *pMenuReg = new wxMenu;
|
|
pMenuReg->Append(Menu_New, wxT("&New"), pMenuNew);
|
|
pMenuReg->Append(Menu_Delete, wxT("&Delete..."), wxT("Delete selected key/value"));
|
|
pMenuReg->AppendSeparator();
|
|
pMenuReg->Append(Menu_GoTo, wxT("&Go to...\tCtrl-G"), wxT("Go to registry key"));
|
|
pMenuReg->Append(Menu_Expand, wxT("&Expand"), wxT("Expand current key"));
|
|
pMenuReg->Append(Menu_Collapse, wxT("&Collapse"), wxT("Collapse current key"));
|
|
pMenuReg->Append(Menu_Toggle, wxT("&Toggle"), wxT("Toggle current key"));
|
|
pMenuReg->AppendSeparator();
|
|
pMenuReg->Append(Menu_Refresh, wxT("&Refresh"), wxT("Refresh the subtree"));
|
|
pMenuReg->Append(Menu_View, wxT("&View"), pMenuView);
|
|
pMenuReg->AppendSeparator();
|
|
pMenuReg->Append(Menu_Info, wxT("&Properties"),wxT("Information about current selection"));
|
|
|
|
return pMenuReg;
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// application class
|
|
// ----------------------------------------------------------------------------
|
|
IMPLEMENT_APP(RegApp)
|
|
|
|
// `Main program' equivalent, creating windows and returning main app frame
|
|
bool RegApp::OnInit()
|
|
{
|
|
if ( !wxApp::OnInit() )
|
|
return false;
|
|
|
|
// create the main frame window and show it
|
|
RegFrame *frame = new RegFrame(NULL, wxT("wxRegTest"), 50, 50, 600, 350);
|
|
frame->Show(true);
|
|
|
|
return true;
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// RegFrame
|
|
// ----------------------------------------------------------------------------
|
|
|
|
RegFrame::RegFrame(wxFrame *parent, const wxChar *title, int x, int y, int w, int h)
|
|
: wxFrame(parent, wxID_ANY, title, wxPoint(x, y), wxSize(w, h))
|
|
{
|
|
// this reduces flicker effects
|
|
SetBackgroundColour(*wxWHITE);
|
|
|
|
// set the icon
|
|
// ------------
|
|
SetIcon(wxIcon(wxT("app_icon")));
|
|
|
|
// create menu
|
|
// -----------
|
|
wxMenu *pMenuFile = new wxMenu;
|
|
pMenuFile->Append(Menu_Test, wxT("Te&st"), wxT("Test key creation"));
|
|
pMenuFile->AppendSeparator();
|
|
pMenuFile->Append(Menu_About, wxT("&About"), wxT("Show an extraordinarly beautiful dialog"));
|
|
pMenuFile->AppendSeparator();
|
|
pMenuFile->Append(Menu_Quit, wxT("E&xit"), wxT("Quit this program"));
|
|
|
|
wxMenuBar *pMenu = new wxMenuBar;
|
|
pMenu->Append(pMenuFile, wxT("&File"));
|
|
pMenu->Append(CreateRegistryMenu(), wxT("&Registry"));
|
|
SetMenuBar(pMenu);
|
|
|
|
#if DO_REGTEST
|
|
// create child controls
|
|
// ---------------------
|
|
m_treeCtrl = new RegTreeCtrl(this, Ctrl_RegTree);
|
|
#endif
|
|
|
|
#if wxUSE_STATUSBAR
|
|
// create the status line
|
|
// ----------------------
|
|
CreateStatusBar(2);
|
|
#endif // wxUSE_STATUSBAR
|
|
}
|
|
|
|
RegFrame::~RegFrame()
|
|
{
|
|
#if DO_REGTEST
|
|
// this makes deletion of it *much* quicker
|
|
m_treeCtrl->Hide();
|
|
#endif
|
|
}
|
|
|
|
void RegFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
Close(true);
|
|
}
|
|
|
|
void RegFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
wxMessageDialog dialog(this,
|
|
wxT("wxRegistry sample\n")
|
|
wxT("(c) 1998, 2000 Vadim Zeitlin"),
|
|
wxT("About wxRegTest"), wxOK);
|
|
|
|
dialog.ShowModal();
|
|
}
|
|
|
|
void RegFrame::OnTest(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
#if DO_REGTEST
|
|
m_treeCtrl->OnMenuTest();
|
|
#endif
|
|
}
|
|
|
|
void RegFrame::OnGoTo(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
static wxString s_location = wxT("HKEY_CURRENT_USER\\Software\\wxWidgets");
|
|
|
|
wxString location = wxGetTextFromUser(
|
|
wxT("Enter the location to go to:"),
|
|
wxT("wxRegTest question"),
|
|
s_location,
|
|
this);
|
|
|
|
if ( !location )
|
|
return;
|
|
|
|
s_location = location;
|
|
#if DO_REGTEST
|
|
m_treeCtrl->GoTo(location);
|
|
#endif
|
|
}
|
|
|
|
void RegFrame::OnExpand(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
#if DO_REGTEST
|
|
m_treeCtrl->Expand(m_treeCtrl->GetSelection());
|
|
#endif
|
|
}
|
|
|
|
void RegFrame::OnCollapse(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
#if DO_REGTEST
|
|
m_treeCtrl->Collapse(m_treeCtrl->GetSelection());
|
|
#endif
|
|
}
|
|
|
|
void RegFrame::OnToggle(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
#if DO_REGTEST
|
|
m_treeCtrl->Toggle(m_treeCtrl->GetSelection());
|
|
#endif
|
|
}
|
|
|
|
void RegFrame::OnRefresh(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
#if DO_REGTEST
|
|
m_treeCtrl->DoRefresh();
|
|
#endif
|
|
}
|
|
|
|
void RegFrame::OnDelete(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
#if DO_REGTEST
|
|
m_treeCtrl->DeleteSelected();
|
|
#endif
|
|
}
|
|
|
|
void RegFrame::OnNewKey(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
#if DO_REGTEST
|
|
if ( m_treeCtrl->IsKeySelected() )
|
|
{
|
|
m_treeCtrl->CreateNewKey(
|
|
wxGetTextFromUser(wxT("Enter the name of the new key")));
|
|
}
|
|
#endif
|
|
}
|
|
|
|
void RegFrame::OnNewText(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
#if DO_REGTEST
|
|
if ( m_treeCtrl->IsKeySelected() )
|
|
{
|
|
m_treeCtrl->CreateNewTextValue(
|
|
wxGetTextFromUser(wxT("Enter the name for the new text value")));
|
|
}
|
|
#endif
|
|
}
|
|
|
|
void RegFrame::OnNewBinary(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
#if DO_REGTEST
|
|
if ( m_treeCtrl->IsKeySelected() )
|
|
{
|
|
m_treeCtrl->CreateNewBinaryValue(
|
|
wxGetTextFromUser(wxT("Enter the name for the new binary value")));
|
|
}
|
|
#endif
|
|
}
|
|
|
|
void RegFrame::OnInfo(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
#if DO_REGTEST
|
|
m_treeCtrl->ShowProperties();
|
|
#endif
|
|
}
|
|
|
|
void RegFrame::OnViewChange(wxCommandEvent& event)
|
|
{
|
|
#if DO_REGTEST
|
|
wxRegKey::WOW64ViewMode view;
|
|
switch ( event.GetId() )
|
|
{
|
|
case Menu_ViewDefault:
|
|
view = wxRegKey::WOW64ViewMode_Default;
|
|
break;
|
|
|
|
case Menu_View32:
|
|
view = wxRegKey::WOW64ViewMode_32;
|
|
break;
|
|
|
|
case Menu_View64:
|
|
view = wxRegKey::WOW64ViewMode_64;
|
|
break;
|
|
|
|
default:
|
|
wxFAIL_MSG("Unexpected event source for view change.");
|
|
return;
|
|
}
|
|
|
|
m_treeCtrl->SetRegistryView(view);
|
|
#endif
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// RegImageList
|
|
// ----------------------------------------------------------------------------
|
|
RegImageList::RegImageList() : wxImageList(16, 16, true)
|
|
{
|
|
// should be in sync with enum RegImageList::RegIcon
|
|
static const wxChar *aszIcons[] = { wxT("key1"),wxT("key2"),wxT("key3"),wxT("value1"),wxT("value2") };
|
|
wxString str = wxT("icon_");
|
|
for ( unsigned int n = 0; n < WXSIZEOF(aszIcons); n++ )
|
|
{
|
|
Add(wxIcon(str + aszIcons[n], wxBITMAP_TYPE_ICO_RESOURCE));
|
|
}
|
|
}
|
|
|
|
#if DO_REGTEST
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// RegTreeCtrl
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// create a new tree item and insert it into the tree
|
|
RegTreeCtrl::TreeNode *RegTreeCtrl::InsertNewTreeNode(
|
|
TreeNode *pParent,
|
|
const wxString& strName,
|
|
int idImage,
|
|
const wxString *pstrValue,
|
|
wxRegKey::WOW64ViewMode viewMode)
|
|
{
|
|
// create new item & insert it
|
|
TreeNode *pNewNode = new TreeNode;
|
|
pNewNode->m_pTree = this;
|
|
pNewNode->m_pParent = pParent;
|
|
pNewNode->m_strName = strName;
|
|
pNewNode->m_bKey = pstrValue == NULL;
|
|
pNewNode->m_pKey = NULL;
|
|
pNewNode->m_viewMode = viewMode;
|
|
if (pParent)
|
|
{
|
|
pNewNode->m_id = AppendItem(pParent->Id(),
|
|
pNewNode->IsKey() ? strName : *pstrValue,
|
|
idImage);
|
|
}
|
|
else
|
|
{
|
|
pNewNode->m_id = AddRoot(strName);
|
|
}
|
|
|
|
wxASSERT_MSG( pNewNode->m_id, wxT("can't create tree control item!"));
|
|
|
|
// save the pointer in the item
|
|
SetItemData(pNewNode->m_id, pNewNode);
|
|
|
|
// add it to the list of parent's children
|
|
if ( pParent != NULL )
|
|
{
|
|
pParent->m_aChildren.Add(pNewNode);
|
|
}
|
|
|
|
if ( pNewNode->IsKey() )
|
|
{
|
|
SetItemHasChildren(pNewNode->Id());
|
|
|
|
if ( !pNewNode->IsRoot() )
|
|
{
|
|
// set the expanded icon as well
|
|
SetItemImage(pNewNode->Id(),
|
|
RegImageList::OpenedKey,
|
|
wxTreeItemIcon_Expanded);
|
|
}
|
|
}
|
|
|
|
return pNewNode;
|
|
}
|
|
|
|
RegTreeCtrl::RegTreeCtrl(wxWindow *parent, wxWindowID id)
|
|
: wxTreeCtrl(parent, id, wxDefaultPosition, wxDefaultSize,
|
|
wxTR_HAS_BUTTONS | wxTR_EDIT_LABELS | wxSUNKEN_BORDER)
|
|
{
|
|
// init members
|
|
m_draggedItem = NULL;
|
|
m_restoreStatus = false;
|
|
m_viewMode = wxRegKey::WOW64ViewMode_Default;
|
|
|
|
// create the image list
|
|
// ---------------------
|
|
m_imageList = new RegImageList;
|
|
SetImageList(m_imageList);
|
|
|
|
// create root keys
|
|
// ----------------
|
|
m_pRoot =
|
|
InsertNewTreeNode(
|
|
NULL,
|
|
wxT("Registry Root"),
|
|
RegImageList::Root,
|
|
NULL,
|
|
m_viewMode);
|
|
|
|
// create popup menu
|
|
// -----------------
|
|
m_pMenuPopup = CreateRegistryMenu();
|
|
}
|
|
|
|
RegTreeCtrl::~RegTreeCtrl()
|
|
{
|
|
delete m_pMenuPopup;
|
|
// delete m_pRoot; -- this is done by the tree now
|
|
delete m_imageList;
|
|
}
|
|
|
|
void RegTreeCtrl::AddStdKeys()
|
|
{
|
|
for ( unsigned int ui = 0; ui < wxRegKey::nStdKeys; ui++ )
|
|
{
|
|
InsertNewTreeNode(
|
|
m_pRoot,
|
|
wxRegKey::GetStdKeyName(ui),
|
|
RegImageList::ClosedKey,
|
|
NULL,
|
|
m_viewMode);
|
|
}
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// notifications
|
|
// ----------------------------------------------------------------------------
|
|
|
|
void RegTreeCtrl::OnIdle(wxIdleEvent& WXUNUSED(event))
|
|
{
|
|
if ( m_restoreStatus )
|
|
{
|
|
// restore it after OnItemExpanding()
|
|
wxLogStatus(wxT("Ok"));
|
|
wxSetCursor(*wxSTANDARD_CURSOR);
|
|
|
|
m_restoreStatus = false;
|
|
}
|
|
}
|
|
|
|
void RegTreeCtrl::OnRightClick(wxMouseEvent& event)
|
|
{
|
|
int iFlags;
|
|
wxTreeItemId lId = HitTest(wxPoint(event.GetX(), event.GetY()), iFlags);
|
|
if ( iFlags & wxTREE_HITTEST_ONITEMLABEL )
|
|
{
|
|
// select the item first
|
|
SelectItem(lId);
|
|
}
|
|
//else: take the currently selected item if click not on item
|
|
|
|
PopupMenu(m_pMenuPopup, event.GetX(), event.GetY());
|
|
}
|
|
|
|
|
|
void RegTreeCtrl::OnDeleteItem(wxTreeEvent& WXUNUSED(event))
|
|
{
|
|
}
|
|
|
|
// test the key creation functions
|
|
void RegTreeCtrl::OnMenuTest()
|
|
{
|
|
wxTreeItemId lId = GetSelection();
|
|
TreeNode *pNode = (TreeNode *)GetItemData(lId);
|
|
|
|
wxCHECK_RET( pNode != NULL, wxT("tree item without data?") );
|
|
|
|
if ( pNode->IsRoot() )
|
|
{
|
|
wxLogError(wxT("Can't create a subkey under the root key."));
|
|
return;
|
|
}
|
|
|
|
if ( !pNode->IsKey() )
|
|
{
|
|
wxLogError(wxT("Can't create a subkey under a value!"));
|
|
return;
|
|
}
|
|
|
|
wxRegKey key1(pNode->Key(), wxT("key1"));
|
|
if ( key1.Create() )
|
|
{
|
|
wxRegKey key2a(key1, wxT("key2a")), key2b(key1, wxT("key2b"));
|
|
if ( key2a.Create() && key2b.Create() )
|
|
{
|
|
// put some values under the newly created keys
|
|
key1.SetValue(wxT("first_term"), wxT("10"));
|
|
key1.SetValue(wxT("second_term"), wxT("7"));
|
|
key2a = wxT("this is the unnamed value");
|
|
key2b.SetValue(wxT("sum"), 17);
|
|
|
|
// refresh tree
|
|
pNode->Refresh();
|
|
wxLogStatus(wxT("Test keys successfully added."));
|
|
return;
|
|
}
|
|
}
|
|
|
|
wxLogError(wxT("Creation of test keys failed."));
|
|
}
|
|
|
|
void RegTreeCtrl::OnChar(wxKeyEvent& event)
|
|
{
|
|
switch ( event.GetKeyCode() )
|
|
{
|
|
case WXK_DELETE:
|
|
DeleteSelected();
|
|
return;
|
|
|
|
case WXK_RETURN:
|
|
if ( event.AltDown() )
|
|
{
|
|
ShowProperties();
|
|
|
|
return;
|
|
}
|
|
}
|
|
|
|
event.Skip();
|
|
}
|
|
|
|
void RegTreeCtrl::OnSelChanged(wxTreeEvent& event)
|
|
{
|
|
#if wxUSE_STATUSBAR
|
|
wxFrame *pFrame = (wxFrame *) wxWindow::GetParent();
|
|
pFrame->SetStatusText(GetNode(event)->FullName(), 1);
|
|
#else
|
|
wxUnusedVar(event);
|
|
#endif // wxUSE_STATUSBAR
|
|
}
|
|
|
|
void RegTreeCtrl::OnItemExpanding(wxTreeEvent& event)
|
|
{
|
|
TreeNode *pNode = GetNode(event);
|
|
bool bExpanding = event.GetEventType() == wxEVT_TREE_ITEM_EXPANDING;
|
|
|
|
// expansion might take some time
|
|
wxSetCursor(*wxHOURGLASS_CURSOR);
|
|
wxLogStatus(wxT("Working..."));
|
|
wxYield(); // to give the status line a chance to refresh itself
|
|
m_restoreStatus = true; // some time later...
|
|
|
|
if ( pNode->IsKey() )
|
|
{
|
|
if ( bExpanding )
|
|
{
|
|
// expanding: add subkeys/values
|
|
if ( !pNode->OnExpand() )
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
// collapsing: clean up
|
|
pNode->OnCollapse();
|
|
}
|
|
}
|
|
}
|
|
|
|
void RegTreeCtrl::OnBeginEdit(wxTreeEvent& event)
|
|
{
|
|
TreeNode *pNode = GetNode(event);
|
|
if ( pNode->IsRoot() || pNode->Parent()->IsRoot() )
|
|
{
|
|
wxLogStatus(wxT("This registry key can't be renamed."));
|
|
|
|
event.Veto();
|
|
}
|
|
else
|
|
{
|
|
m_nameOld = pNode->m_strName;
|
|
}
|
|
}
|
|
|
|
void RegTreeCtrl::OnEndEdit(wxTreeEvent& event)
|
|
{
|
|
bool ok;
|
|
|
|
wxString name = event.GetLabel();
|
|
|
|
TreeNode *pNode = GetNode(event);
|
|
if ( pNode->IsKey() )
|
|
{
|
|
wxRegKey& key = pNode->Key();
|
|
ok = key.Rename(name);
|
|
}
|
|
else
|
|
{
|
|
pNode = pNode->Parent();
|
|
wxRegKey& key = pNode->Key();
|
|
|
|
ok = key.RenameValue(m_nameOld, name);
|
|
}
|
|
|
|
if ( !ok )
|
|
{
|
|
wxLogError(wxT("Failed to rename '%s' to '%s'."),
|
|
m_nameOld.c_str(), name.c_str());
|
|
}
|
|
#if 0 // MSW tree ctrl doesn't like this at all, it hangs
|
|
else
|
|
{
|
|
pNode->Refresh();
|
|
}
|
|
#endif // 0
|
|
}
|
|
|
|
void RegTreeCtrl::OnBeginDrag(wxTreeEvent& event)
|
|
{
|
|
m_copyOnDrop = event.GetEventType() == wxEVT_TREE_BEGIN_DRAG;
|
|
|
|
TreeNode *pNode = GetNode(event);
|
|
if ( pNode->IsRoot() || pNode->Parent()->IsRoot() )
|
|
{
|
|
wxLogStatus(wxT("This registry key can't be %s."),
|
|
m_copyOnDrop ? wxT("copied") : wxT("moved"));
|
|
}
|
|
else
|
|
{
|
|
wxLogStatus(wxT("%s item %s..."),
|
|
m_copyOnDrop ? wxT("Copying") : wxT("Moving"),
|
|
pNode->FullName());
|
|
|
|
m_draggedItem = pNode;
|
|
|
|
event.Allow();
|
|
}
|
|
}
|
|
|
|
void RegTreeCtrl::OnEndDrag(wxTreeEvent& event)
|
|
{
|
|
wxCHECK_RET( m_draggedItem, wxT("end drag without begin drag?") );
|
|
|
|
// clear the pointer anyhow
|
|
TreeNode *src = m_draggedItem;
|
|
m_draggedItem = NULL;
|
|
|
|
// where are we going to drop it?
|
|
TreeNode *dst = GetNode(event);
|
|
if ( dst && !dst->IsKey() )
|
|
{
|
|
// we need a parent key
|
|
dst = dst->Parent();
|
|
}
|
|
|
|
if ( !dst || dst->IsRoot() )
|
|
{
|
|
wxLogError(wxT("Can't create a key here."));
|
|
|
|
return;
|
|
}
|
|
|
|
bool isKey = src->IsKey();
|
|
if ( (isKey && (src == dst)) ||
|
|
(!isKey && (dst->Parent() == src)) ) {
|
|
wxLogStatus(wxT("Can't copy something on itself"));
|
|
|
|
return;
|
|
}
|
|
|
|
// remove the "Registry Root\\" from the full name
|
|
wxString nameSrc, nameDst;
|
|
nameSrc << wxString(src->FullName()).AfterFirst('\\');
|
|
nameDst << wxString(dst->FullName()).AfterFirst('\\') << '\\'
|
|
<< wxString(src->FullName()).AfterLast('\\');
|
|
|
|
wxString verb = m_copyOnDrop ? wxT("copy") : wxT("move");
|
|
wxString what = isKey ? wxT("key") : wxT("value");
|
|
|
|
if ( wxMessageBox(wxString::Format
|
|
(
|
|
wxT("Do you really want to %s the %s %s to %s?"),
|
|
verb.c_str(),
|
|
what.c_str(),
|
|
nameSrc.c_str(),
|
|
nameDst.c_str()
|
|
),
|
|
wxT("RegTest Confirm"),
|
|
wxICON_QUESTION | wxYES_NO | wxCANCEL, this) != wxYES ) {
|
|
return;
|
|
}
|
|
|
|
bool ok;
|
|
if ( isKey )
|
|
{
|
|
wxRegKey& key = src->Key();
|
|
wxRegKey keyDst(dst->Key(), src->m_strName);
|
|
ok = keyDst.Create(false);
|
|
if ( !ok )
|
|
{
|
|
wxLogError(wxT("Key '%s' already exists"), keyDst.GetName().c_str());
|
|
}
|
|
else
|
|
{
|
|
ok = key.Copy(keyDst);
|
|
}
|
|
|
|
if ( ok && !m_copyOnDrop )
|
|
{
|
|
// delete the old key
|
|
ok = key.DeleteSelf();
|
|
if ( ok )
|
|
{
|
|
src->Parent()->Refresh();
|
|
}
|
|
}
|
|
}
|
|
else // value
|
|
{
|
|
wxRegKey& key = src->Parent()->Key();
|
|
ok = key.CopyValue(src->m_strName, dst->Key());
|
|
if ( ok && !m_copyOnDrop )
|
|
{
|
|
// we moved it, so delete the old one
|
|
ok = key.DeleteValue(src->m_strName);
|
|
}
|
|
}
|
|
|
|
if ( !ok )
|
|
{
|
|
wxLogError(wxT("Failed to %s registry %s."),
|
|
verb.c_str(), what.c_str());
|
|
}
|
|
else
|
|
{
|
|
dst->Refresh();
|
|
}
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// TreeNode implementation
|
|
// ----------------------------------------------------------------------------
|
|
bool RegTreeCtrl::TreeNode::OnExpand()
|
|
{
|
|
// we add children only once
|
|
if ( !m_aChildren.IsEmpty() )
|
|
{
|
|
// we've been already expanded
|
|
return true;
|
|
}
|
|
|
|
if ( IsRoot() )
|
|
{
|
|
// we're the root key
|
|
m_pTree->AddStdKeys();
|
|
return true;
|
|
}
|
|
|
|
if ( Parent()->IsRoot() )
|
|
{
|
|
// we're a standard key
|
|
m_pKey = new wxRegKey(m_strName, m_viewMode);
|
|
}
|
|
else
|
|
{
|
|
// we're a normal key
|
|
m_pKey = new wxRegKey(*(Parent()->m_pKey), m_strName);
|
|
}
|
|
|
|
if ( !m_pKey->Open() )
|
|
{
|
|
wxLogError(wxT("The key '%s' can't be opened."), FullName());
|
|
return false;
|
|
}
|
|
|
|
// if we're empty, we shouldn't be expandable at all
|
|
bool isEmpty = true;
|
|
|
|
// enumeration variables
|
|
long l;
|
|
wxString str;
|
|
bool bCont;
|
|
|
|
// enumerate all subkeys
|
|
bCont = m_pKey->GetFirstKey(str, l);
|
|
while ( bCont )
|
|
{
|
|
m_pTree->InsertNewTreeNode(
|
|
this,
|
|
str,
|
|
RegImageList::ClosedKey,
|
|
NULL,
|
|
m_viewMode);
|
|
bCont = m_pKey->GetNextKey(str, l);
|
|
|
|
// we have at least this key...
|
|
isEmpty = false;
|
|
}
|
|
|
|
// enumerate all values
|
|
bCont = m_pKey->GetFirstValue(str, l);
|
|
while ( bCont )
|
|
{
|
|
wxString strItem;
|
|
if (str.empty())
|
|
strItem = wxT("<default>");
|
|
else
|
|
strItem = str;
|
|
strItem += wxT(" = ");
|
|
|
|
// determine the appropriate icon
|
|
RegImageList::Icon icon;
|
|
switch ( m_pKey->GetValueType(str) )
|
|
{
|
|
case wxRegKey::Type_String:
|
|
case wxRegKey::Type_Expand_String:
|
|
case wxRegKey::Type_Multi_String:
|
|
{
|
|
wxString strValue;
|
|
icon = RegImageList::TextValue;
|
|
m_pKey->QueryValue(str, strValue);
|
|
strItem += strValue;
|
|
}
|
|
break;
|
|
|
|
case wxRegKey::Type_None:
|
|
// @@ handle the error...
|
|
icon = RegImageList::BinaryValue;
|
|
break;
|
|
|
|
case wxRegKey::Type_Dword:
|
|
{
|
|
long l;
|
|
m_pKey->QueryValue(str, &l);
|
|
strItem << l;
|
|
}
|
|
|
|
// fall through
|
|
|
|
default:
|
|
icon = RegImageList::BinaryValue;
|
|
}
|
|
|
|
m_pTree->InsertNewTreeNode(this, str, icon, &strItem, m_viewMode);
|
|
bCont = m_pKey->GetNextValue(str, l);
|
|
|
|
// we have at least this value...
|
|
isEmpty = false;
|
|
}
|
|
|
|
if ( isEmpty )
|
|
{
|
|
// this is for the case when our last child was just deleted
|
|
wxTreeItemId theId(Id()); // Temp variable seems necessary for BC++
|
|
m_pTree->Collapse(theId);
|
|
|
|
// we won't be expanded any more
|
|
m_pTree->SetItemHasChildren(theId, false);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void RegTreeCtrl::TreeNode::OnCollapse()
|
|
{
|
|
DestroyChildren();
|
|
|
|
wxDELETE(m_pKey);
|
|
}
|
|
|
|
void RegTreeCtrl::TreeNode::Refresh()
|
|
{
|
|
if ( !IsKey() )
|
|
return;
|
|
|
|
wxTreeItemId theId(Id()); // Temp variable seems necessary for BC++
|
|
bool wasExpanded = m_pTree->IsExpanded(theId);
|
|
if ( wasExpanded )
|
|
m_pTree->Collapse(theId);
|
|
|
|
OnCollapse();
|
|
m_pTree->SetItemHasChildren(theId);
|
|
if ( wasExpanded )
|
|
{
|
|
m_pTree->Expand(theId);
|
|
OnExpand();
|
|
}
|
|
}
|
|
|
|
bool RegTreeCtrl::TreeNode::DeleteChild(TreeNode *child)
|
|
{
|
|
int index = m_aChildren.Index(child);
|
|
wxCHECK_MSG( index != wxNOT_FOUND, false,
|
|
wxT("our child in tree should be in m_aChildren") );
|
|
|
|
m_aChildren.RemoveAt((size_t)index);
|
|
|
|
bool ok;
|
|
if ( child->IsKey() )
|
|
{
|
|
// must close key before deleting it
|
|
child->OnCollapse();
|
|
|
|
ok = Key().DeleteKey(child->m_strName);
|
|
}
|
|
else
|
|
{
|
|
ok = Key().DeleteValue(child->m_strName);
|
|
}
|
|
|
|
if ( ok )
|
|
{
|
|
wxTreeItemId theId(child->Id()); // Temp variable seems necessary for BC++
|
|
m_pTree->Delete(theId);
|
|
|
|
Refresh();
|
|
}
|
|
|
|
return ok;
|
|
}
|
|
|
|
void RegTreeCtrl::TreeNode::DestroyChildren()
|
|
{
|
|
// destroy all children
|
|
size_t nCount = m_aChildren.GetCount();
|
|
for ( size_t n = 0; n < nCount; n++ )
|
|
{
|
|
wxTreeItemId lId = m_aChildren[n]->Id();
|
|
m_pTree->Delete(lId);
|
|
}
|
|
|
|
m_aChildren.Empty();
|
|
}
|
|
|
|
RegTreeCtrl::TreeNode::~TreeNode()
|
|
{
|
|
delete m_pKey;
|
|
}
|
|
|
|
const wxChar *RegTreeCtrl::TreeNode::FullName() const
|
|
{
|
|
static wxString s_strName;
|
|
|
|
if ( IsRoot() )
|
|
{
|
|
return wxT("Registry Root");
|
|
}
|
|
else
|
|
{
|
|
// our own registry key might not (yet) exist or we might be a value,
|
|
// so just use the parent's and concatenate
|
|
s_strName = Parent()->FullName();
|
|
s_strName << wxT('\\') << m_strName;
|
|
|
|
return s_strName.t_str();
|
|
}
|
|
}
|
|
|
|
void RegTreeCtrl::TreeNode::SetRegistryView(wxRegKey::WOW64ViewMode viewMode)
|
|
{
|
|
m_viewMode = viewMode;
|
|
|
|
// Update children with new view.
|
|
size_t nCount = m_aChildren.GetCount();
|
|
for (size_t n = 0; n < nCount; n++)
|
|
m_aChildren[n]->SetRegistryView(viewMode);
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// operations on RegTreeCtrl
|
|
// ----------------------------------------------------------------------------
|
|
|
|
void RegTreeCtrl::GoTo(const wxString& location)
|
|
{
|
|
wxStringTokenizer tk(location, wxT("\\"));
|
|
|
|
wxTreeItemId id = GetRootItem();
|
|
|
|
while ( tk.HasMoreTokens() )
|
|
{
|
|
wxString subkey = tk.GetNextToken();
|
|
|
|
wxTreeItemId idCurrent = id;
|
|
if ( !IsExpanded(idCurrent) )
|
|
Expand(idCurrent);
|
|
|
|
wxTreeItemIdValue dummy;
|
|
id = GetFirstChild(idCurrent, dummy);
|
|
|
|
if ( idCurrent == GetRootItem() )
|
|
{
|
|
// special case: we understand both HKCU and HKEY_CURRENT_USER here
|
|
for ( size_t key = 0; key < wxRegKey::nStdKeys; key++ )
|
|
{
|
|
if ( subkey == wxRegKey::GetStdKeyName(key)
|
|
|| subkey == wxRegKey::GetStdKeyShortName(key) )
|
|
{
|
|
break;
|
|
}
|
|
|
|
id = GetNextChild(idCurrent, dummy);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// enum all children
|
|
while ( id.IsOk() )
|
|
{
|
|
if ( subkey == ((TreeNode *)GetItemData(id))->m_strName )
|
|
break;
|
|
|
|
id = GetNextChild(idCurrent, dummy);
|
|
}
|
|
}
|
|
|
|
if ( !id.IsOk() )
|
|
{
|
|
wxLogError(wxT("No such key '%s'."), location.c_str());
|
|
|
|
return;
|
|
}
|
|
}
|
|
|
|
if ( id.IsOk() )
|
|
SelectItem(id);
|
|
}
|
|
|
|
void RegTreeCtrl::DeleteSelected()
|
|
{
|
|
wxTreeItemId lCurrent = GetSelection(),
|
|
lParent = GetItemParent(lCurrent);
|
|
|
|
if ( lParent == GetRootItem() )
|
|
{
|
|
wxLogError(wxT("Can't delete root key."));
|
|
return;
|
|
}
|
|
|
|
TreeNode *pCurrent = (TreeNode *)GetItemData(lCurrent),
|
|
*pParent = (TreeNode *)GetItemData(lParent);
|
|
|
|
wxCHECK_RET(pCurrent && pParent, wxT("either node or parent without data?"));
|
|
|
|
if ( pParent->IsRoot() )
|
|
{
|
|
wxLogError(wxT("Can't delete standard key."));
|
|
return;
|
|
}
|
|
|
|
wxString what = pCurrent->IsKey() ? wxT("key") : wxT("value");
|
|
if ( wxMessageBox(wxString::Format
|
|
(
|
|
wxT("Do you really want to delete this %s?"),
|
|
what.c_str()
|
|
),
|
|
wxT("Confirmation"),
|
|
wxICON_QUESTION | wxYES_NO | wxCANCEL, this) != wxYES )
|
|
{
|
|
return;
|
|
}
|
|
|
|
pParent->DeleteChild(pCurrent);
|
|
}
|
|
|
|
void RegTreeCtrl::CreateNewKey(const wxString& strName)
|
|
{
|
|
wxTreeItemId lCurrent = GetSelection();
|
|
TreeNode *pCurrent = (TreeNode *)GetItemData(lCurrent);
|
|
|
|
wxCHECK_RET( pCurrent != NULL, wxT("node without data?") );
|
|
|
|
wxASSERT( pCurrent->IsKey() ); // check must have been done before
|
|
|
|
if ( pCurrent->IsRoot() )
|
|
{
|
|
wxLogError(wxT("Can't create a new key under the root key."));
|
|
return;
|
|
}
|
|
|
|
wxRegKey key(pCurrent->Key(), strName);
|
|
if ( key.Create() )
|
|
pCurrent->Refresh();
|
|
}
|
|
|
|
void RegTreeCtrl::CreateNewTextValue(const wxString& strName)
|
|
{
|
|
wxTreeItemId lCurrent = GetSelection();
|
|
TreeNode *pCurrent = (TreeNode *)GetItemData(lCurrent);
|
|
|
|
wxCHECK_RET( pCurrent != NULL, wxT("node without data?") );
|
|
|
|
wxASSERT( pCurrent->IsKey() ); // check must have been done before
|
|
|
|
if ( pCurrent->IsRoot() )
|
|
{
|
|
wxLogError(wxT("Can't create a new value under the root key."));
|
|
return;
|
|
}
|
|
|
|
if ( pCurrent->Key().SetValue(strName, wxEmptyString) )
|
|
pCurrent->Refresh();
|
|
}
|
|
|
|
void RegTreeCtrl::CreateNewBinaryValue(const wxString& strName)
|
|
{
|
|
wxTreeItemId lCurrent = GetSelection();
|
|
TreeNode *pCurrent = (TreeNode *)GetItemData(lCurrent);
|
|
|
|
wxCHECK_RET( pCurrent != NULL, wxT("node without data?") );
|
|
|
|
wxASSERT( pCurrent->IsKey() ); // check must have been done before
|
|
|
|
if ( pCurrent->IsRoot() )
|
|
{
|
|
wxLogError(wxT("Can't create a new value under the root key."));
|
|
return;
|
|
}
|
|
|
|
if ( pCurrent->Key().SetValue(strName, 0) )
|
|
pCurrent->Refresh();
|
|
}
|
|
|
|
void RegTreeCtrl::SetRegistryView(wxRegKey::WOW64ViewMode viewMode)
|
|
{
|
|
m_viewMode = viewMode;
|
|
m_pRoot->SetRegistryView(viewMode);
|
|
m_pRoot->Refresh();
|
|
}
|
|
|
|
void RegTreeCtrl::ShowProperties()
|
|
{
|
|
wxTreeItemId lCurrent = GetSelection();
|
|
TreeNode *pCurrent = (TreeNode *)GetItemData(lCurrent);
|
|
|
|
if ( !pCurrent || pCurrent->IsRoot() )
|
|
{
|
|
wxLogStatus(wxT("No properties"));
|
|
|
|
return;
|
|
}
|
|
|
|
if ( pCurrent->IsKey() )
|
|
{
|
|
const wxRegKey& key = pCurrent->Key();
|
|
size_t nSubKeys, nValues;
|
|
if ( !key.GetKeyInfo(&nSubKeys, NULL, &nValues, NULL) )
|
|
{
|
|
wxLogError(wxT("Couldn't get key info"));
|
|
}
|
|
else
|
|
{
|
|
wxLogMessage(wxT("Key '%s' has %u subkeys and %u values."),
|
|
key.GetName().c_str(), nSubKeys, nValues);
|
|
}
|
|
}
|
|
else // it's a value
|
|
{
|
|
TreeNode *parent = pCurrent->Parent();
|
|
wxCHECK_RET( parent, wxT("reg value without key?") );
|
|
|
|
const wxRegKey& key = parent->Key();
|
|
const wxChar *value = pCurrent->m_strName.c_str();
|
|
wxLogMessage(wxT("Value '%s' under the key '%s' is of type ")
|
|
wxT("%d (%s)."),
|
|
value,
|
|
parent->m_strName.c_str(),
|
|
key.GetValueType(value),
|
|
key.IsNumericValue(value) ? wxT("numeric") : wxT("string"));
|
|
|
|
}
|
|
}
|
|
|
|
bool RegTreeCtrl::IsKeySelected() const
|
|
{
|
|
wxTreeItemId lCurrent = GetSelection();
|
|
TreeNode *pCurrent = (TreeNode *) GetItemData(lCurrent);
|
|
|
|
wxCHECK( pCurrent != NULL, false );
|
|
|
|
return pCurrent->IsKey();
|
|
}
|
|
|
|
void RegTreeCtrl::DoRefresh()
|
|
{
|
|
wxTreeItemId lId = GetSelection();
|
|
if ( !lId )
|
|
return;
|
|
|
|
TreeNode *pNode = (TreeNode *) GetItemData(lId);
|
|
|
|
wxCHECK_RET( pNode != NULL, wxT("tree item without data?") );
|
|
|
|
pNode->Refresh();
|
|
}
|
|
|
|
#endif
|