1 ///////////////////////////////////////////////////////////////////////////////
3 // Purpose: wxRegKey class demo
4 // Author: Vadim Zeitlin
8 // Copyright: (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
9 // Licence: wxWindows licence
10 ///////////////////////////////////////////////////////////////////////////////
12 // ============================================================================
14 // ============================================================================
16 // ----------------------------------------------------------------------------
18 // ----------------------------------------------------------------------------
19 #include "wx/wxprec.h"
29 #include "wx/treectrl.h"
30 #include "wx/config.h"
31 #include "wx/imaglist.h"
32 #include "wx/tokenzr.h"
34 #if wxUSE_CONFIG_NATIVE && defined( __WXMSW__ )
40 // ----------------------------------------------------------------------------
42 // ----------------------------------------------------------------------------
43 class RegApp
: public wxApp
49 // ----------------------------------------------------------------------------
50 // image list with registry icons
51 // ----------------------------------------------------------------------------
52 class RegImageList
: public wxImageList
69 // ----------------------------------------------------------------------------
71 // ----------------------------------------------------------------------------
72 class RegTreeCtrl
: public wxTreeCtrl
76 RegTreeCtrl(wxWindow
*parent
, wxWindowID id
);
77 virtual ~RegTreeCtrl();
80 void OnDeleteItem (wxTreeEvent
& event
);
81 void OnItemExpanding (wxTreeEvent
& event
);
82 void OnSelChanged (wxTreeEvent
& event
);
84 void OnBeginEdit (wxTreeEvent
& event
);
85 void OnEndEdit (wxTreeEvent
& event
);
87 void OnBeginDrag (wxTreeEvent
& event
);
88 void OnEndDrag (wxTreeEvent
& event
);
90 void OnRightClick (wxMouseEvent
& event
);
91 void OnChar (wxKeyEvent
& event
);
92 void OnIdle (wxIdleEvent
& event
);
94 // forwarded notifications (by the frame)
98 void GoTo(const wxString
& location
);
100 void DeleteSelected();
101 void ShowProperties();
102 void CreateNewKey(const wxString
& strName
);
103 void CreateNewTextValue(const wxString
& strName
);
104 void CreateNewBinaryValue(const wxString
& strName
);
105 void SetRegistryView(wxRegKey::WOW64ViewMode viewMode
);
108 bool IsKeySelected() const;
111 // structure describing a registry key/value
112 class TreeNode
: public wxTreeItemData
114 WX_DEFINE_ARRAY_PTR(TreeNode
*, TreeChildren
);
116 RegTreeCtrl
*m_pTree
; // must be !NULL
117 TreeNode
*m_pParent
; // NULL only for the root node
118 wxTreeItemId m_id
; // the id of the tree control item
119 wxString m_strName
; // name of the key/value
120 TreeChildren m_aChildren
; // array of subkeys/values
121 bool m_bKey
; // key or value?
122 wxRegKey
*m_pKey
; // only may be !NULL if m_bKey == true
123 wxRegKey::WOW64ViewMode m_viewMode
; // How to view the registry.
126 wxTreeItemId
Id() const { return m_id
; }
127 bool IsRoot() const { return m_pParent
== NULL
; }
128 bool IsKey() const { return m_bKey
; }
129 TreeNode
*Parent() const { return m_pParent
; }
137 bool DeleteChild(TreeNode
*child
);
138 void DestroyChildren();
139 const wxChar
*FullName() const;
140 void SetRegistryView(wxRegKey::WOW64ViewMode viewMode
);
142 // get the associated key: make sure the pointer is !NULL
143 wxRegKey
& Key() { if ( !m_pKey
) OnExpand(); return *m_pKey
; }
145 // dtor deletes all children
149 wxImageList
*m_imageList
;
150 wxMenu
*m_pMenuPopup
;
154 TreeNode
*m_draggedItem
; // the item being dragged
155 bool m_copyOnDrop
; // if false, then move
157 bool m_restoreStatus
; // after OnItemExpanding()
159 wxString m_nameOld
; // the initial value of item being renamed
161 wxRegKey::WOW64ViewMode m_viewMode
; // Registry view to use for keys.
163 TreeNode
*GetNode(const wxTreeEvent
& event
)
164 { return (TreeNode
*)GetItemData(event
.GetItem()); }
167 // create a new node and insert it to the tree
168 TreeNode
*InsertNewTreeNode(TreeNode
*pParent
,
169 const wxString
& strName
,
170 int idImage
= RegImageList::ClosedKey
,
171 const wxString
*pstrValue
= NULL
,
172 wxRegKey::WOW64ViewMode viewMode
= wxRegKey::WOW64ViewMode_Default
);
174 // add standard registry keys
178 DECLARE_EVENT_TABLE()
181 #endif // #if DO_REGTEST
183 // ----------------------------------------------------------------------------
184 // the main window of our application
185 // ----------------------------------------------------------------------------
186 class RegFrame
: public wxFrame
190 RegFrame(wxFrame
*parent
, const wxChar
*title
, int x
, int y
, int w
, int h
);
194 void OnQuit (wxCommandEvent
& event
);
195 void OnAbout(wxCommandEvent
& event
);
196 void OnTest (wxCommandEvent
& event
);
198 void OnGoTo (wxCommandEvent
& event
);
200 void OnExpand (wxCommandEvent
& event
);
201 void OnCollapse(wxCommandEvent
& event
);
202 void OnToggle (wxCommandEvent
& event
);
203 void OnRefresh (wxCommandEvent
& event
);
205 void OnDelete (wxCommandEvent
& event
);
206 void OnNewKey (wxCommandEvent
& event
);
207 void OnNewText (wxCommandEvent
& event
);
208 void OnNewBinary(wxCommandEvent
& event
);
210 void OnInfo (wxCommandEvent
& event
);
212 void OnViewChange (wxCommandEvent
& event
);
214 DECLARE_EVENT_TABLE()
219 RegTreeCtrl
*m_treeCtrl
;
223 // ----------------------------------------------------------------------------
225 // ----------------------------------------------------------------------------
251 // ----------------------------------------------------------------------------
253 // ----------------------------------------------------------------------------
255 BEGIN_EVENT_TABLE(RegFrame
, wxFrame
)
256 EVT_MENU(Menu_Test
, RegFrame::OnTest
)
257 EVT_MENU(Menu_About
, RegFrame::OnAbout
)
258 EVT_MENU(Menu_Quit
, RegFrame::OnQuit
)
259 EVT_MENU(Menu_GoTo
, RegFrame::OnGoTo
)
260 EVT_MENU(Menu_Expand
, RegFrame::OnExpand
)
261 EVT_MENU(Menu_Collapse
, RegFrame::OnCollapse
)
262 EVT_MENU(Menu_Toggle
, RegFrame::OnToggle
)
263 EVT_MENU(Menu_Refresh
, RegFrame::OnRefresh
)
264 EVT_MENU(Menu_Delete
, RegFrame::OnDelete
)
265 EVT_MENU(Menu_NewKey
, RegFrame::OnNewKey
)
266 EVT_MENU(Menu_NewText
, RegFrame::OnNewText
)
267 EVT_MENU(Menu_NewBinary
, RegFrame::OnNewBinary
)
268 EVT_MENU(Menu_Info
, RegFrame::OnInfo
)
269 EVT_MENU(Menu_ViewDefault
, RegFrame::OnViewChange
)
270 EVT_MENU(Menu_View32
, RegFrame::OnViewChange
)
271 EVT_MENU(Menu_View64
, RegFrame::OnViewChange
)
276 BEGIN_EVENT_TABLE(RegTreeCtrl
, wxTreeCtrl
)
277 EVT_TREE_DELETE_ITEM (Ctrl_RegTree
, RegTreeCtrl::OnDeleteItem
)
278 EVT_TREE_ITEM_EXPANDING (Ctrl_RegTree
, RegTreeCtrl::OnItemExpanding
)
279 EVT_TREE_ITEM_COLLAPSING(Ctrl_RegTree
, RegTreeCtrl::OnItemExpanding
)
280 EVT_TREE_SEL_CHANGED (Ctrl_RegTree
, RegTreeCtrl::OnSelChanged
)
282 EVT_TREE_BEGIN_LABEL_EDIT(Ctrl_RegTree
, RegTreeCtrl::OnBeginEdit
)
283 EVT_TREE_END_LABEL_EDIT (Ctrl_RegTree
, RegTreeCtrl::OnEndEdit
)
285 EVT_TREE_BEGIN_DRAG (Ctrl_RegTree
, RegTreeCtrl::OnBeginDrag
)
286 EVT_TREE_BEGIN_RDRAG (Ctrl_RegTree
, RegTreeCtrl::OnBeginDrag
)
287 EVT_TREE_END_DRAG (Ctrl_RegTree
, RegTreeCtrl::OnEndDrag
)
289 EVT_CHAR (RegTreeCtrl::OnChar
)
290 EVT_RIGHT_DOWN(RegTreeCtrl::OnRightClick
)
291 EVT_IDLE (RegTreeCtrl::OnIdle
)
296 // ============================================================================
298 // ============================================================================
300 // ----------------------------------------------------------------------------
302 // ----------------------------------------------------------------------------
304 // create the "registry operations" menu
305 wxMenu
*CreateRegistryMenu()
307 wxMenu
*pMenuNew
= new wxMenu
;
308 pMenuNew
->Append(Menu_NewKey
, wxT("&Key"), wxT("Create a new key"));
309 pMenuNew
->AppendSeparator();
310 pMenuNew
->Append(Menu_NewText
, wxT("&Text value"), wxT("Create a new text value"));
311 pMenuNew
->Append(Menu_NewBinary
, wxT("&Binary value"), wxT("Create a new binary value"));
313 wxMenu
*pMenuView
= new wxMenu
;
314 pMenuView
->AppendRadioItem(
317 wxT("Default registry view for the program environment."));
318 pMenuView
->AppendRadioItem(
320 wxT("32-bit Registry"),
321 wxT("View 32-bit registry."));
322 pMenuView
->AppendRadioItem(
324 wxT("64-bit Registry"),
325 wxT("View 64-bit registry."));
327 wxMenu
*pMenuReg
= new wxMenu
;
328 pMenuReg
->Append(Menu_New
, wxT("&New"), pMenuNew
);
329 pMenuReg
->Append(Menu_Delete
, wxT("&Delete..."), wxT("Delete selected key/value"));
330 pMenuReg
->AppendSeparator();
331 pMenuReg
->Append(Menu_GoTo
, wxT("&Go to...\tCtrl-G"), wxT("Go to registry key"));
332 pMenuReg
->Append(Menu_Expand
, wxT("&Expand"), wxT("Expand current key"));
333 pMenuReg
->Append(Menu_Collapse
, wxT("&Collapse"), wxT("Collapse current key"));
334 pMenuReg
->Append(Menu_Toggle
, wxT("&Toggle"), wxT("Toggle current key"));
335 pMenuReg
->AppendSeparator();
336 pMenuReg
->Append(Menu_Refresh
, wxT("&Refresh"), wxT("Refresh the subtree"));
337 pMenuReg
->Append(Menu_View
, wxT("&View"), pMenuView
);
338 pMenuReg
->AppendSeparator();
339 pMenuReg
->Append(Menu_Info
, wxT("&Properties"),wxT("Information about current selection"));
344 // ----------------------------------------------------------------------------
346 // ----------------------------------------------------------------------------
347 IMPLEMENT_APP(RegApp
)
349 // `Main program' equivalent, creating windows and returning main app frame
350 bool RegApp::OnInit()
352 if ( !wxApp::OnInit() )
355 // create the main frame window and show it
356 RegFrame
*frame
= new RegFrame(NULL
, wxT("wxRegTest"), 50, 50, 600, 350);
362 // ----------------------------------------------------------------------------
364 // ----------------------------------------------------------------------------
366 RegFrame::RegFrame(wxFrame
*parent
, const wxChar
*title
, int x
, int y
, int w
, int h
)
367 : wxFrame(parent
, wxID_ANY
, title
, wxPoint(x
, y
), wxSize(w
, h
))
369 // this reduces flicker effects
370 SetBackgroundColour(wxColour(255, 255, 255));
374 SetIcon(wxIcon(wxT("app_icon")));
378 wxMenu
*pMenuFile
= new wxMenu
;
379 pMenuFile
->Append(Menu_Test
, wxT("Te&st"), wxT("Test key creation"));
380 pMenuFile
->AppendSeparator();
381 pMenuFile
->Append(Menu_About
, wxT("&About..."), wxT("Show an extraordinarly beautiful dialog"));
382 pMenuFile
->AppendSeparator();
383 pMenuFile
->Append(Menu_Quit
, wxT("E&xit"), wxT("Quit this program"));
385 wxMenuBar
*pMenu
= new wxMenuBar
;
386 pMenu
->Append(pMenuFile
, wxT("&File"));
387 pMenu
->Append(CreateRegistryMenu(), wxT("&Registry"));
391 // create child controls
392 // ---------------------
393 m_treeCtrl
= new RegTreeCtrl(this, Ctrl_RegTree
);
397 // create the status line
398 // ----------------------
400 #endif // wxUSE_STATUSBAR
403 RegFrame::~RegFrame()
406 // this makes deletion of it *much* quicker
411 void RegFrame::OnQuit(wxCommandEvent
& WXUNUSED(event
))
416 void RegFrame::OnAbout(wxCommandEvent
& WXUNUSED(event
))
418 wxMessageDialog
dialog(this,
419 wxT("wxRegistry sample\n")
420 wxT("(c) 1998, 2000 Vadim Zeitlin"),
421 wxT("About wxRegTest"), wxOK
);
426 void RegFrame::OnTest(wxCommandEvent
& WXUNUSED(event
))
429 m_treeCtrl
->OnMenuTest();
433 void RegFrame::OnGoTo(wxCommandEvent
& WXUNUSED(event
))
435 static wxString s_location
= wxT("HKEY_CURRENT_USER\\Software\\wxWidgets");
437 wxString location
= wxGetTextFromUser(
438 wxT("Enter the location to go to:"),
439 wxT("wxRegTest question"),
446 s_location
= location
;
448 m_treeCtrl
->GoTo(location
);
452 void RegFrame::OnExpand(wxCommandEvent
& WXUNUSED(event
))
455 m_treeCtrl
->Expand(m_treeCtrl
->GetSelection());
459 void RegFrame::OnCollapse(wxCommandEvent
& WXUNUSED(event
))
462 m_treeCtrl
->Collapse(m_treeCtrl
->GetSelection());
466 void RegFrame::OnToggle(wxCommandEvent
& WXUNUSED(event
))
469 m_treeCtrl
->Toggle(m_treeCtrl
->GetSelection());
473 void RegFrame::OnRefresh(wxCommandEvent
& WXUNUSED(event
))
476 m_treeCtrl
->DoRefresh();
480 void RegFrame::OnDelete(wxCommandEvent
& WXUNUSED(event
))
483 m_treeCtrl
->DeleteSelected();
487 void RegFrame::OnNewKey(wxCommandEvent
& WXUNUSED(event
))
490 if ( m_treeCtrl
->IsKeySelected() )
492 m_treeCtrl
->CreateNewKey(
493 wxGetTextFromUser(wxT("Enter the name of the new key")));
498 void RegFrame::OnNewText(wxCommandEvent
& WXUNUSED(event
))
501 if ( m_treeCtrl
->IsKeySelected() )
503 m_treeCtrl
->CreateNewTextValue(
504 wxGetTextFromUser(wxT("Enter the name for the new text value")));
509 void RegFrame::OnNewBinary(wxCommandEvent
& WXUNUSED(event
))
512 if ( m_treeCtrl
->IsKeySelected() )
514 m_treeCtrl
->CreateNewBinaryValue(
515 wxGetTextFromUser(wxT("Enter the name for the new binary value")));
520 void RegFrame::OnInfo(wxCommandEvent
& WXUNUSED(event
))
523 m_treeCtrl
->ShowProperties();
527 void RegFrame::OnViewChange(wxCommandEvent
& event
)
530 wxRegKey::WOW64ViewMode view
;
531 switch ( event
.GetId() )
533 case Menu_ViewDefault
:
534 view
= wxRegKey::WOW64ViewMode_Default
;
538 view
= wxRegKey::WOW64ViewMode_32
;
542 view
= wxRegKey::WOW64ViewMode_64
;
546 wxFAIL_MSG("Unexpected event source for view change.");
550 m_treeCtrl
->SetRegistryView(view
);
554 // ----------------------------------------------------------------------------
556 // ----------------------------------------------------------------------------
557 RegImageList::RegImageList() : wxImageList(16, 16, true)
559 // should be in sync with enum RegImageList::RegIcon
560 static const wxChar
*aszIcons
[] = { wxT("key1"),wxT("key2"),wxT("key3"),wxT("value1"),wxT("value2") };
561 wxString str
= wxT("icon_");
562 for ( unsigned int n
= 0; n
< WXSIZEOF(aszIcons
); n
++ )
564 Add(wxIcon(str
+ aszIcons
[n
], wxBITMAP_TYPE_ICO_RESOURCE
));
570 // ----------------------------------------------------------------------------
572 // ----------------------------------------------------------------------------
574 // create a new tree item and insert it into the tree
575 RegTreeCtrl::TreeNode
*RegTreeCtrl::InsertNewTreeNode(
577 const wxString
& strName
,
579 const wxString
*pstrValue
,
580 wxRegKey::WOW64ViewMode viewMode
)
582 // create new item & insert it
583 TreeNode
*pNewNode
= new TreeNode
;
584 pNewNode
->m_pTree
= this;
585 pNewNode
->m_pParent
= pParent
;
586 pNewNode
->m_strName
= strName
;
587 pNewNode
->m_bKey
= pstrValue
== NULL
;
588 pNewNode
->m_pKey
= NULL
;
589 pNewNode
->m_viewMode
= viewMode
;
592 pNewNode
->m_id
= AppendItem(pParent
->Id(),
593 pNewNode
->IsKey() ? strName
: *pstrValue
,
598 pNewNode
->m_id
= AddRoot(strName
);
601 wxASSERT_MSG( pNewNode
->m_id
, wxT("can't create tree control item!"));
603 // save the pointer in the item
604 SetItemData(pNewNode
->m_id
, pNewNode
);
606 // add it to the list of parent's children
607 if ( pParent
!= NULL
)
609 pParent
->m_aChildren
.Add(pNewNode
);
612 if ( pNewNode
->IsKey() )
614 SetItemHasChildren(pNewNode
->Id());
616 if ( !pNewNode
->IsRoot() )
618 // set the expanded icon as well
619 SetItemImage(pNewNode
->Id(),
620 RegImageList::OpenedKey
,
621 wxTreeItemIcon_Expanded
);
628 RegTreeCtrl::RegTreeCtrl(wxWindow
*parent
, wxWindowID id
)
629 : wxTreeCtrl(parent
, id
, wxDefaultPosition
, wxDefaultSize
,
630 wxTR_HAS_BUTTONS
| wxTR_EDIT_LABELS
| wxSUNKEN_BORDER
)
633 m_draggedItem
= NULL
;
634 m_restoreStatus
= false;
635 m_viewMode
= wxRegKey::WOW64ViewMode_Default
;
637 // create the image list
638 // ---------------------
639 m_imageList
= new RegImageList
;
640 SetImageList(m_imageList
);
647 wxT("Registry Root"),
654 m_pMenuPopup
= CreateRegistryMenu();
657 RegTreeCtrl::~RegTreeCtrl()
660 // delete m_pRoot; -- this is done by the tree now
664 void RegTreeCtrl::AddStdKeys()
666 for ( unsigned int ui
= 0; ui
< wxRegKey::nStdKeys
; ui
++ )
670 wxRegKey::GetStdKeyName(ui
),
671 RegImageList::ClosedKey
,
677 // ----------------------------------------------------------------------------
679 // ----------------------------------------------------------------------------
681 void RegTreeCtrl::OnIdle(wxIdleEvent
& WXUNUSED(event
))
683 if ( m_restoreStatus
)
685 // restore it after OnItemExpanding()
686 wxLogStatus(wxT("Ok"));
687 wxSetCursor(*wxSTANDARD_CURSOR
);
689 m_restoreStatus
= false;
693 void RegTreeCtrl::OnRightClick(wxMouseEvent
& event
)
696 wxTreeItemId lId
= HitTest(wxPoint(event
.GetX(), event
.GetY()), iFlags
);
697 if ( iFlags
& wxTREE_HITTEST_ONITEMLABEL
)
699 // select the item first
702 //else: take the currently selected item if click not on item
704 PopupMenu(m_pMenuPopup
, event
.GetX(), event
.GetY());
708 void RegTreeCtrl::OnDeleteItem(wxTreeEvent
& WXUNUSED(event
))
712 // test the key creation functions
713 void RegTreeCtrl::OnMenuTest()
715 wxTreeItemId lId
= GetSelection();
716 TreeNode
*pNode
= (TreeNode
*)GetItemData(lId
);
718 wxCHECK_RET( pNode
!= NULL
, wxT("tree item without data?") );
720 if ( pNode
->IsRoot() )
722 wxLogError(wxT("Can't create a subkey under the root key."));
726 if ( !pNode
->IsKey() )
728 wxLogError(wxT("Can't create a subkey under a value!"));
732 wxRegKey
key1(pNode
->Key(), wxT("key1"));
735 wxRegKey
key2a(key1
, wxT("key2a")), key2b(key1
, wxT("key2b"));
736 if ( key2a
.Create() && key2b
.Create() )
738 // put some values under the newly created keys
739 key1
.SetValue(wxT("first_term"), wxT("10"));
740 key1
.SetValue(wxT("second_term"), wxT("7"));
741 key2a
= wxT("this is the unnamed value");
742 key2b
.SetValue(wxT("sum"), 17);
746 wxLogStatus(wxT("Test keys successfully added."));
751 wxLogError(wxT("Creation of test keys failed."));
754 void RegTreeCtrl::OnChar(wxKeyEvent
& event
)
756 switch ( event
.GetKeyCode() )
763 if ( event
.AltDown() )
774 void RegTreeCtrl::OnSelChanged(wxTreeEvent
& event
)
777 wxFrame
*pFrame
= (wxFrame
*) wxWindow::GetParent();
778 pFrame
->SetStatusText(GetNode(event
)->FullName(), 1);
781 #endif // wxUSE_STATUSBAR
784 void RegTreeCtrl::OnItemExpanding(wxTreeEvent
& event
)
786 TreeNode
*pNode
= GetNode(event
);
787 bool bExpanding
= event
.GetEventType() == wxEVT_COMMAND_TREE_ITEM_EXPANDING
;
789 // expansion might take some time
790 wxSetCursor(*wxHOURGLASS_CURSOR
);
791 wxLogStatus(wxT("Working..."));
792 wxYield(); // to give the status line a chance to refresh itself
793 m_restoreStatus
= true; // some time later...
795 if ( pNode
->IsKey() )
799 // expanding: add subkeys/values
800 if ( !pNode
->OnExpand() )
805 // collapsing: clean up
811 void RegTreeCtrl::OnBeginEdit(wxTreeEvent
& event
)
813 TreeNode
*pNode
= GetNode(event
);
814 if ( pNode
->IsRoot() || pNode
->Parent()->IsRoot() )
816 wxLogStatus(wxT("This registry key can't be renamed."));
822 m_nameOld
= pNode
->m_strName
;
826 void RegTreeCtrl::OnEndEdit(wxTreeEvent
& event
)
830 wxString name
= event
.GetLabel();
832 TreeNode
*pNode
= GetNode(event
);
833 if ( pNode
->IsKey() )
835 wxRegKey
& key
= pNode
->Key();
836 ok
= key
.Rename(name
);
840 pNode
= pNode
->Parent();
841 wxRegKey
& key
= pNode
->Key();
843 ok
= key
.RenameValue(m_nameOld
, name
);
848 wxLogError(wxT("Failed to rename '%s' to '%s'."),
849 m_nameOld
.c_str(), name
.c_str());
851 #if 0 // MSW tree ctrl doesn't like this at all, it hangs
859 void RegTreeCtrl::OnBeginDrag(wxTreeEvent
& event
)
861 m_copyOnDrop
= event
.GetEventType() == wxEVT_COMMAND_TREE_BEGIN_DRAG
;
863 TreeNode
*pNode
= GetNode(event
);
864 if ( pNode
->IsRoot() || pNode
->Parent()->IsRoot() )
866 wxLogStatus(wxT("This registry key can't be %s."),
867 m_copyOnDrop
? wxT("copied") : wxT("moved"));
871 wxLogStatus(wxT("%s item %s..."),
872 m_copyOnDrop
? wxT("Copying") : wxT("Moving"),
875 m_draggedItem
= pNode
;
881 void RegTreeCtrl::OnEndDrag(wxTreeEvent
& event
)
883 wxCHECK_RET( m_draggedItem
, wxT("end drag without begin drag?") );
885 // clear the pointer anyhow
886 TreeNode
*src
= m_draggedItem
;
887 m_draggedItem
= NULL
;
889 // where are we going to drop it?
890 TreeNode
*dst
= GetNode(event
);
891 if ( dst
&& !dst
->IsKey() )
893 // we need a parent key
897 if ( !dst
|| dst
->IsRoot() )
899 wxLogError(wxT("Can't create a key here."));
904 bool isKey
= src
->IsKey();
905 if ( (isKey
&& (src
== dst
)) ||
906 (!isKey
&& (dst
->Parent() == src
)) ) {
907 wxLogStatus(wxT("Can't copy something on itself"));
912 // remove the "Registry Root\\" from the full name
913 wxString nameSrc
, nameDst
;
914 nameSrc
<< wxString(src
->FullName()).AfterFirst('\\');
915 nameDst
<< wxString(dst
->FullName()).AfterFirst('\\') << '\\'
916 << wxString(src
->FullName()).AfterLast('\\');
918 wxString verb
= m_copyOnDrop
? wxT("copy") : wxT("move");
919 wxString what
= isKey
? wxT("key") : wxT("value");
921 if ( wxMessageBox(wxString::Format
923 wxT("Do you really want to %s the %s %s to %s?"),
929 wxT("RegTest Confirm"),
930 wxICON_QUESTION
| wxYES_NO
| wxCANCEL
, this) != wxYES
) {
937 wxRegKey
& key
= src
->Key();
938 wxRegKey
keyDst(dst
->Key(), src
->m_strName
);
939 ok
= keyDst
.Create(false);
942 wxLogError(wxT("Key '%s' already exists"), keyDst
.GetName().c_str());
946 ok
= key
.Copy(keyDst
);
949 if ( ok
&& !m_copyOnDrop
)
951 // delete the old key
952 ok
= key
.DeleteSelf();
955 src
->Parent()->Refresh();
961 wxRegKey
& key
= src
->Parent()->Key();
962 ok
= key
.CopyValue(src
->m_strName
, dst
->Key());
963 if ( ok
&& !m_copyOnDrop
)
965 // we moved it, so delete the old one
966 ok
= key
.DeleteValue(src
->m_strName
);
972 wxLogError(wxT("Failed to %s registry %s."),
973 verb
.c_str(), what
.c_str());
981 // ----------------------------------------------------------------------------
982 // TreeNode implementation
983 // ----------------------------------------------------------------------------
984 bool RegTreeCtrl::TreeNode::OnExpand()
986 // we add children only once
987 if ( !m_aChildren
.IsEmpty() )
989 // we've been already expanded
995 // we're the root key
996 m_pTree
->AddStdKeys();
1000 if ( Parent()->IsRoot() )
1002 // we're a standard key
1003 m_pKey
= new wxRegKey(m_strName
, m_viewMode
);
1007 // we're a normal key
1008 m_pKey
= new wxRegKey(*(Parent()->m_pKey
), m_strName
);
1011 if ( !m_pKey
->Open() )
1013 wxLogError(wxT("The key '%s' can't be opened."), FullName());
1017 // if we're empty, we shouldn't be expandable at all
1018 bool isEmpty
= true;
1020 // enumeration variables
1025 // enumerate all subkeys
1026 bCont
= m_pKey
->GetFirstKey(str
, l
);
1029 m_pTree
->InsertNewTreeNode(
1032 RegImageList::ClosedKey
,
1035 bCont
= m_pKey
->GetNextKey(str
, l
);
1037 // we have at least this key...
1041 // enumerate all values
1042 bCont
= m_pKey
->GetFirstValue(str
, l
);
1047 strItem
= wxT("<default>");
1050 strItem
+= wxT(" = ");
1052 // determine the appropriate icon
1053 RegImageList::Icon icon
;
1054 switch ( m_pKey
->GetValueType(str
) )
1056 case wxRegKey::Type_String
:
1057 case wxRegKey::Type_Expand_String
:
1058 case wxRegKey::Type_Multi_String
:
1061 icon
= RegImageList::TextValue
;
1062 m_pKey
->QueryValue(str
, strValue
);
1063 strItem
+= strValue
;
1067 case wxRegKey::Type_None
:
1068 // @@ handle the error...
1069 icon
= RegImageList::BinaryValue
;
1072 case wxRegKey::Type_Dword
:
1075 m_pKey
->QueryValue(str
, &l
);
1082 icon
= RegImageList::BinaryValue
;
1085 m_pTree
->InsertNewTreeNode(this, str
, icon
, &strItem
, m_viewMode
);
1086 bCont
= m_pKey
->GetNextValue(str
, l
);
1088 // we have at least this value...
1094 // this is for the case when our last child was just deleted
1095 wxTreeItemId
theId(Id()); // Temp variable seems necessary for BC++
1096 m_pTree
->Collapse(theId
);
1098 // we won't be expanded any more
1099 m_pTree
->SetItemHasChildren(theId
, false);
1105 void RegTreeCtrl::TreeNode::OnCollapse()
1112 void RegTreeCtrl::TreeNode::Refresh()
1117 wxTreeItemId
theId(Id()); // Temp variable seems necessary for BC++
1118 bool wasExpanded
= m_pTree
->IsExpanded(theId
);
1120 m_pTree
->Collapse(theId
);
1123 m_pTree
->SetItemHasChildren(theId
);
1126 m_pTree
->Expand(theId
);
1131 bool RegTreeCtrl::TreeNode::DeleteChild(TreeNode
*child
)
1133 int index
= m_aChildren
.Index(child
);
1134 wxCHECK_MSG( index
!= wxNOT_FOUND
, false,
1135 wxT("our child in tree should be in m_aChildren") );
1137 m_aChildren
.RemoveAt((size_t)index
);
1140 if ( child
->IsKey() )
1142 // must close key before deleting it
1143 child
->OnCollapse();
1145 ok
= Key().DeleteKey(child
->m_strName
);
1149 ok
= Key().DeleteValue(child
->m_strName
);
1154 wxTreeItemId
theId(child
->Id()); // Temp variable seems necessary for BC++
1155 m_pTree
->Delete(theId
);
1163 void RegTreeCtrl::TreeNode::DestroyChildren()
1165 // destroy all children
1166 size_t nCount
= m_aChildren
.GetCount();
1167 for ( size_t n
= 0; n
< nCount
; n
++ )
1169 wxTreeItemId lId
= m_aChildren
[n
]->Id();
1170 m_pTree
->Delete(lId
);
1173 m_aChildren
.Empty();
1176 RegTreeCtrl::TreeNode::~TreeNode()
1181 const wxChar
*RegTreeCtrl::TreeNode::FullName() const
1183 static wxString s_strName
;
1187 return wxT("Registry Root");
1191 // our own registry key might not (yet) exist or we might be a value,
1192 // so just use the parent's and concatenate
1193 s_strName
= Parent()->FullName();
1194 s_strName
<< wxT('\\') << m_strName
;
1200 void RegTreeCtrl::TreeNode::SetRegistryView(wxRegKey::WOW64ViewMode viewMode
)
1202 m_viewMode
= viewMode
;
1204 // Update children with new view.
1205 size_t nCount
= m_aChildren
.GetCount();
1206 for (size_t n
= 0; n
< nCount
; n
++)
1207 m_aChildren
[n
]->SetRegistryView(viewMode
);
1210 // ----------------------------------------------------------------------------
1211 // operations on RegTreeCtrl
1212 // ----------------------------------------------------------------------------
1214 void RegTreeCtrl::GoTo(const wxString
& location
)
1216 wxStringTokenizer
tk(location
, wxT("\\"));
1218 wxTreeItemId id
= GetRootItem();
1220 while ( tk
.HasMoreTokens() )
1222 wxString subkey
= tk
.GetNextToken();
1224 wxTreeItemId idCurrent
= id
;
1225 if ( !IsExpanded(idCurrent
) )
1228 wxTreeItemIdValue dummy
;
1229 id
= GetFirstChild(idCurrent
, dummy
);
1231 if ( idCurrent
== GetRootItem() )
1233 // special case: we understand both HKCU and HKEY_CURRENT_USER here
1234 for ( size_t key
= 0; key
< wxRegKey::nStdKeys
; key
++ )
1236 if ( subkey
== wxRegKey::GetStdKeyName(key
)
1237 || subkey
== wxRegKey::GetStdKeyShortName(key
) )
1242 id
= GetNextChild(idCurrent
, dummy
);
1247 // enum all children
1250 if ( subkey
== ((TreeNode
*)GetItemData(id
))->m_strName
)
1253 id
= GetNextChild(idCurrent
, dummy
);
1259 wxLogError(wxT("No such key '%s'."), location
.c_str());
1269 void RegTreeCtrl::DeleteSelected()
1271 wxTreeItemId lCurrent
= GetSelection(),
1272 lParent
= GetItemParent(lCurrent
);
1274 if ( lParent
== GetRootItem() )
1276 wxLogError(wxT("Can't delete root key."));
1280 TreeNode
*pCurrent
= (TreeNode
*)GetItemData(lCurrent
),
1281 *pParent
= (TreeNode
*)GetItemData(lParent
);
1283 wxCHECK_RET(pCurrent
&& pParent
, wxT("either node or parent without data?"));
1285 if ( pParent
->IsRoot() )
1287 wxLogError(wxT("Can't delete standard key."));
1291 wxString what
= pCurrent
->IsKey() ? wxT("key") : wxT("value");
1292 if ( wxMessageBox(wxString::Format
1294 wxT("Do you really want to delete this %s?"),
1297 wxT("Confirmation"),
1298 wxICON_QUESTION
| wxYES_NO
| wxCANCEL
, this) != wxYES
)
1303 pParent
->DeleteChild(pCurrent
);
1306 void RegTreeCtrl::CreateNewKey(const wxString
& strName
)
1308 wxTreeItemId lCurrent
= GetSelection();
1309 TreeNode
*pCurrent
= (TreeNode
*)GetItemData(lCurrent
);
1311 wxCHECK_RET( pCurrent
!= NULL
, wxT("node without data?") );
1313 wxASSERT( pCurrent
->IsKey() ); // check must have been done before
1315 if ( pCurrent
->IsRoot() )
1317 wxLogError(wxT("Can't create a new key under the root key."));
1321 wxRegKey
key(pCurrent
->Key(), strName
);
1323 pCurrent
->Refresh();
1326 void RegTreeCtrl::CreateNewTextValue(const wxString
& strName
)
1328 wxTreeItemId lCurrent
= GetSelection();
1329 TreeNode
*pCurrent
= (TreeNode
*)GetItemData(lCurrent
);
1331 wxCHECK_RET( pCurrent
!= NULL
, wxT("node without data?") );
1333 wxASSERT( pCurrent
->IsKey() ); // check must have been done before
1335 if ( pCurrent
->IsRoot() )
1337 wxLogError(wxT("Can't create a new value under the root key."));
1341 if ( pCurrent
->Key().SetValue(strName
, wxEmptyString
) )
1342 pCurrent
->Refresh();
1345 void RegTreeCtrl::CreateNewBinaryValue(const wxString
& strName
)
1347 wxTreeItemId lCurrent
= GetSelection();
1348 TreeNode
*pCurrent
= (TreeNode
*)GetItemData(lCurrent
);
1350 wxCHECK_RET( pCurrent
!= NULL
, wxT("node without data?") );
1352 wxASSERT( pCurrent
->IsKey() ); // check must have been done before
1354 if ( pCurrent
->IsRoot() )
1356 wxLogError(wxT("Can't create a new value under the root key."));
1360 if ( pCurrent
->Key().SetValue(strName
, 0) )
1361 pCurrent
->Refresh();
1364 void RegTreeCtrl::SetRegistryView(wxRegKey::WOW64ViewMode viewMode
)
1366 m_viewMode
= viewMode
;
1367 m_pRoot
->SetRegistryView(viewMode
);
1371 void RegTreeCtrl::ShowProperties()
1373 wxTreeItemId lCurrent
= GetSelection();
1374 TreeNode
*pCurrent
= (TreeNode
*)GetItemData(lCurrent
);
1376 if ( !pCurrent
|| pCurrent
->IsRoot() )
1378 wxLogStatus(wxT("No properties"));
1383 if ( pCurrent
->IsKey() )
1385 const wxRegKey
& key
= pCurrent
->Key();
1386 size_t nSubKeys
, nValues
;
1387 if ( !key
.GetKeyInfo(&nSubKeys
, NULL
, &nValues
, NULL
) )
1389 wxLogError(wxT("Couldn't get key info"));
1393 wxLogMessage(wxT("Key '%s' has %u subkeys and %u values."),
1394 key
.GetName().c_str(), nSubKeys
, nValues
);
1397 else // it's a value
1399 TreeNode
*parent
= pCurrent
->Parent();
1400 wxCHECK_RET( parent
, wxT("reg value without key?") );
1402 const wxRegKey
& key
= parent
->Key();
1403 const wxChar
*value
= pCurrent
->m_strName
.c_str();
1404 wxLogMessage(wxT("Value '%s' under the key '%s' is of type ")
1407 parent
->m_strName
.c_str(),
1408 key
.GetValueType(value
),
1409 key
.IsNumericValue(value
) ? wxT("numeric") : wxT("string"));
1414 bool RegTreeCtrl::IsKeySelected() const
1416 wxTreeItemId lCurrent
= GetSelection();
1417 TreeNode
*pCurrent
= (TreeNode
*) GetItemData(lCurrent
);
1419 wxCHECK( pCurrent
!= NULL
, false );
1421 return pCurrent
->IsKey();
1424 void RegTreeCtrl::DoRefresh()
1426 wxTreeItemId lId
= GetSelection();
1430 TreeNode
*pNode
= (TreeNode
*) GetItemData(lId
);
1432 wxCHECK_RET( pNode
!= NULL
, wxT("tree item without data?") );