1 ///////////////////////////////////////////////////////////////////////////////
3 // Purpose: wxRegKey class demo
4 // Author: Vadim Zeitlin
7 // Copyright: (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
8 // Licence: wxWindows licence
9 ///////////////////////////////////////////////////////////////////////////////
11 // ============================================================================
13 // ============================================================================
15 // ----------------------------------------------------------------------------
17 // ----------------------------------------------------------------------------
18 #include "wx/wxprec.h"
28 #include "wx/treectrl.h"
29 #include "wx/config.h"
30 #include "wx/imaglist.h"
31 #include "wx/tokenzr.h"
33 #if wxUSE_CONFIG_NATIVE && defined( __WINDOWS__ )
39 // ----------------------------------------------------------------------------
41 // ----------------------------------------------------------------------------
42 class RegApp
: public wxApp
48 // ----------------------------------------------------------------------------
49 // image list with registry icons
50 // ----------------------------------------------------------------------------
51 class RegImageList
: public wxImageList
68 // ----------------------------------------------------------------------------
70 // ----------------------------------------------------------------------------
71 class RegTreeCtrl
: public wxTreeCtrl
75 RegTreeCtrl(wxWindow
*parent
, wxWindowID id
);
76 virtual ~RegTreeCtrl();
79 void OnDeleteItem (wxTreeEvent
& event
);
80 void OnItemExpanding (wxTreeEvent
& event
);
81 void OnSelChanged (wxTreeEvent
& event
);
83 void OnBeginEdit (wxTreeEvent
& event
);
84 void OnEndEdit (wxTreeEvent
& event
);
86 void OnBeginDrag (wxTreeEvent
& event
);
87 void OnEndDrag (wxTreeEvent
& event
);
89 void OnRightClick (wxMouseEvent
& event
);
90 void OnChar (wxKeyEvent
& event
);
91 void OnIdle (wxIdleEvent
& event
);
93 // forwarded notifications (by the frame)
97 void GoTo(const wxString
& location
);
99 void DeleteSelected();
100 void ShowProperties();
101 void CreateNewKey(const wxString
& strName
);
102 void CreateNewTextValue(const wxString
& strName
);
103 void CreateNewBinaryValue(const wxString
& strName
);
104 void SetRegistryView(wxRegKey::WOW64ViewMode viewMode
);
107 bool IsKeySelected() const;
110 // structure describing a registry key/value
111 class TreeNode
: public wxTreeItemData
113 WX_DEFINE_ARRAY_PTR(TreeNode
*, TreeChildren
);
115 RegTreeCtrl
*m_pTree
; // must be !NULL
116 TreeNode
*m_pParent
; // NULL only for the root node
117 wxTreeItemId m_id
; // the id of the tree control item
118 wxString m_strName
; // name of the key/value
119 TreeChildren m_aChildren
; // array of subkeys/values
120 bool m_bKey
; // key or value?
121 wxRegKey
*m_pKey
; // only may be !NULL if m_bKey == true
122 wxRegKey::WOW64ViewMode m_viewMode
; // How to view the registry.
125 wxTreeItemId
Id() const { return m_id
; }
126 bool IsRoot() const { return m_pParent
== NULL
; }
127 bool IsKey() const { return m_bKey
; }
128 TreeNode
*Parent() const { return m_pParent
; }
136 bool DeleteChild(TreeNode
*child
);
137 void DestroyChildren();
138 const wxChar
*FullName() const;
139 void SetRegistryView(wxRegKey::WOW64ViewMode viewMode
);
141 // get the associated key: make sure the pointer is !NULL
142 wxRegKey
& Key() { if ( !m_pKey
) OnExpand(); return *m_pKey
; }
144 // dtor deletes all children
148 wxImageList
*m_imageList
;
149 wxMenu
*m_pMenuPopup
;
153 TreeNode
*m_draggedItem
; // the item being dragged
154 bool m_copyOnDrop
; // if false, then move
156 bool m_restoreStatus
; // after OnItemExpanding()
158 wxString m_nameOld
; // the initial value of item being renamed
160 wxRegKey::WOW64ViewMode m_viewMode
; // Registry view to use for keys.
162 TreeNode
*GetNode(const wxTreeEvent
& event
)
163 { return (TreeNode
*)GetItemData(event
.GetItem()); }
166 // create a new node and insert it to the tree
167 TreeNode
*InsertNewTreeNode(TreeNode
*pParent
,
168 const wxString
& strName
,
169 int idImage
= RegImageList::ClosedKey
,
170 const wxString
*pstrValue
= NULL
,
171 wxRegKey::WOW64ViewMode viewMode
= wxRegKey::WOW64ViewMode_Default
);
173 // add standard registry keys
177 DECLARE_EVENT_TABLE()
180 #endif // #if DO_REGTEST
182 // ----------------------------------------------------------------------------
183 // the main window of our application
184 // ----------------------------------------------------------------------------
185 class RegFrame
: public wxFrame
189 RegFrame(wxFrame
*parent
, const wxChar
*title
, int x
, int y
, int w
, int h
);
193 void OnQuit (wxCommandEvent
& event
);
194 void OnAbout(wxCommandEvent
& event
);
195 void OnTest (wxCommandEvent
& event
);
197 void OnGoTo (wxCommandEvent
& event
);
199 void OnExpand (wxCommandEvent
& event
);
200 void OnCollapse(wxCommandEvent
& event
);
201 void OnToggle (wxCommandEvent
& event
);
202 void OnRefresh (wxCommandEvent
& event
);
204 void OnDelete (wxCommandEvent
& event
);
205 void OnNewKey (wxCommandEvent
& event
);
206 void OnNewText (wxCommandEvent
& event
);
207 void OnNewBinary(wxCommandEvent
& event
);
209 void OnInfo (wxCommandEvent
& event
);
211 void OnViewChange (wxCommandEvent
& event
);
213 DECLARE_EVENT_TABLE()
218 RegTreeCtrl
*m_treeCtrl
;
222 // ----------------------------------------------------------------------------
224 // ----------------------------------------------------------------------------
250 // ----------------------------------------------------------------------------
252 // ----------------------------------------------------------------------------
254 BEGIN_EVENT_TABLE(RegFrame
, wxFrame
)
255 EVT_MENU(Menu_Test
, RegFrame::OnTest
)
256 EVT_MENU(Menu_About
, RegFrame::OnAbout
)
257 EVT_MENU(Menu_Quit
, RegFrame::OnQuit
)
258 EVT_MENU(Menu_GoTo
, RegFrame::OnGoTo
)
259 EVT_MENU(Menu_Expand
, RegFrame::OnExpand
)
260 EVT_MENU(Menu_Collapse
, RegFrame::OnCollapse
)
261 EVT_MENU(Menu_Toggle
, RegFrame::OnToggle
)
262 EVT_MENU(Menu_Refresh
, RegFrame::OnRefresh
)
263 EVT_MENU(Menu_Delete
, RegFrame::OnDelete
)
264 EVT_MENU(Menu_NewKey
, RegFrame::OnNewKey
)
265 EVT_MENU(Menu_NewText
, RegFrame::OnNewText
)
266 EVT_MENU(Menu_NewBinary
, RegFrame::OnNewBinary
)
267 EVT_MENU(Menu_Info
, RegFrame::OnInfo
)
268 EVT_MENU(Menu_ViewDefault
, RegFrame::OnViewChange
)
269 EVT_MENU(Menu_View32
, RegFrame::OnViewChange
)
270 EVT_MENU(Menu_View64
, RegFrame::OnViewChange
)
275 BEGIN_EVENT_TABLE(RegTreeCtrl
, wxTreeCtrl
)
276 EVT_TREE_DELETE_ITEM (Ctrl_RegTree
, RegTreeCtrl::OnDeleteItem
)
277 EVT_TREE_ITEM_EXPANDING (Ctrl_RegTree
, RegTreeCtrl::OnItemExpanding
)
278 EVT_TREE_ITEM_COLLAPSING(Ctrl_RegTree
, RegTreeCtrl::OnItemExpanding
)
279 EVT_TREE_SEL_CHANGED (Ctrl_RegTree
, RegTreeCtrl::OnSelChanged
)
281 EVT_TREE_BEGIN_LABEL_EDIT(Ctrl_RegTree
, RegTreeCtrl::OnBeginEdit
)
282 EVT_TREE_END_LABEL_EDIT (Ctrl_RegTree
, RegTreeCtrl::OnEndEdit
)
284 EVT_TREE_BEGIN_DRAG (Ctrl_RegTree
, RegTreeCtrl::OnBeginDrag
)
285 EVT_TREE_BEGIN_RDRAG (Ctrl_RegTree
, RegTreeCtrl::OnBeginDrag
)
286 EVT_TREE_END_DRAG (Ctrl_RegTree
, RegTreeCtrl::OnEndDrag
)
288 EVT_CHAR (RegTreeCtrl::OnChar
)
289 EVT_RIGHT_DOWN(RegTreeCtrl::OnRightClick
)
290 EVT_IDLE (RegTreeCtrl::OnIdle
)
295 // ============================================================================
297 // ============================================================================
299 // ----------------------------------------------------------------------------
301 // ----------------------------------------------------------------------------
303 // create the "registry operations" menu
304 wxMenu
*CreateRegistryMenu()
306 wxMenu
*pMenuNew
= new wxMenu
;
307 pMenuNew
->Append(Menu_NewKey
, wxT("&Key"), wxT("Create a new key"));
308 pMenuNew
->AppendSeparator();
309 pMenuNew
->Append(Menu_NewText
, wxT("&Text value"), wxT("Create a new text value"));
310 pMenuNew
->Append(Menu_NewBinary
, wxT("&Binary value"), wxT("Create a new binary value"));
312 wxMenu
*pMenuView
= new wxMenu
;
313 pMenuView
->AppendRadioItem(
316 wxT("Default registry view for the program environment."));
317 pMenuView
->AppendRadioItem(
319 wxT("32-bit Registry"),
320 wxT("View 32-bit registry."));
321 pMenuView
->AppendRadioItem(
323 wxT("64-bit Registry"),
324 wxT("View 64-bit registry."));
326 wxMenu
*pMenuReg
= new wxMenu
;
327 pMenuReg
->Append(Menu_New
, wxT("&New"), pMenuNew
);
328 pMenuReg
->Append(Menu_Delete
, wxT("&Delete..."), wxT("Delete selected key/value"));
329 pMenuReg
->AppendSeparator();
330 pMenuReg
->Append(Menu_GoTo
, wxT("&Go to...\tCtrl-G"), wxT("Go to registry key"));
331 pMenuReg
->Append(Menu_Expand
, wxT("&Expand"), wxT("Expand current key"));
332 pMenuReg
->Append(Menu_Collapse
, wxT("&Collapse"), wxT("Collapse current key"));
333 pMenuReg
->Append(Menu_Toggle
, wxT("&Toggle"), wxT("Toggle current key"));
334 pMenuReg
->AppendSeparator();
335 pMenuReg
->Append(Menu_Refresh
, wxT("&Refresh"), wxT("Refresh the subtree"));
336 pMenuReg
->Append(Menu_View
, wxT("&View"), pMenuView
);
337 pMenuReg
->AppendSeparator();
338 pMenuReg
->Append(Menu_Info
, wxT("&Properties"),wxT("Information about current selection"));
343 // ----------------------------------------------------------------------------
345 // ----------------------------------------------------------------------------
346 IMPLEMENT_APP(RegApp
)
348 // `Main program' equivalent, creating windows and returning main app frame
349 bool RegApp::OnInit()
351 if ( !wxApp::OnInit() )
354 // create the main frame window and show it
355 RegFrame
*frame
= new RegFrame(NULL
, wxT("wxRegTest"), 50, 50, 600, 350);
361 // ----------------------------------------------------------------------------
363 // ----------------------------------------------------------------------------
365 RegFrame::RegFrame(wxFrame
*parent
, const wxChar
*title
, int x
, int y
, int w
, int h
)
366 : wxFrame(parent
, wxID_ANY
, title
, wxPoint(x
, y
), wxSize(w
, h
))
368 // this reduces flicker effects
369 SetBackgroundColour(*wxWHITE
);
373 SetIcon(wxIcon(wxT("app_icon")));
377 wxMenu
*pMenuFile
= new wxMenu
;
378 pMenuFile
->Append(Menu_Test
, wxT("Te&st"), wxT("Test key creation"));
379 pMenuFile
->AppendSeparator();
380 pMenuFile
->Append(Menu_About
, wxT("&About"), wxT("Show an extraordinarly beautiful dialog"));
381 pMenuFile
->AppendSeparator();
382 pMenuFile
->Append(Menu_Quit
, wxT("E&xit"), wxT("Quit this program"));
384 wxMenuBar
*pMenu
= new wxMenuBar
;
385 pMenu
->Append(pMenuFile
, wxT("&File"));
386 pMenu
->Append(CreateRegistryMenu(), wxT("&Registry"));
390 // create child controls
391 // ---------------------
392 m_treeCtrl
= new RegTreeCtrl(this, Ctrl_RegTree
);
396 // create the status line
397 // ----------------------
399 #endif // wxUSE_STATUSBAR
402 RegFrame::~RegFrame()
405 // this makes deletion of it *much* quicker
410 void RegFrame::OnQuit(wxCommandEvent
& WXUNUSED(event
))
415 void RegFrame::OnAbout(wxCommandEvent
& WXUNUSED(event
))
417 wxMessageDialog
dialog(this,
418 wxT("wxRegistry sample\n")
419 wxT("(c) 1998, 2000 Vadim Zeitlin"),
420 wxT("About wxRegTest"), wxOK
);
425 void RegFrame::OnTest(wxCommandEvent
& WXUNUSED(event
))
428 m_treeCtrl
->OnMenuTest();
432 void RegFrame::OnGoTo(wxCommandEvent
& WXUNUSED(event
))
434 static wxString s_location
= wxT("HKEY_CURRENT_USER\\Software\\wxWidgets");
436 wxString location
= wxGetTextFromUser(
437 wxT("Enter the location to go to:"),
438 wxT("wxRegTest question"),
445 s_location
= location
;
447 m_treeCtrl
->GoTo(location
);
451 void RegFrame::OnExpand(wxCommandEvent
& WXUNUSED(event
))
454 m_treeCtrl
->Expand(m_treeCtrl
->GetSelection());
458 void RegFrame::OnCollapse(wxCommandEvent
& WXUNUSED(event
))
461 m_treeCtrl
->Collapse(m_treeCtrl
->GetSelection());
465 void RegFrame::OnToggle(wxCommandEvent
& WXUNUSED(event
))
468 m_treeCtrl
->Toggle(m_treeCtrl
->GetSelection());
472 void RegFrame::OnRefresh(wxCommandEvent
& WXUNUSED(event
))
475 m_treeCtrl
->DoRefresh();
479 void RegFrame::OnDelete(wxCommandEvent
& WXUNUSED(event
))
482 m_treeCtrl
->DeleteSelected();
486 void RegFrame::OnNewKey(wxCommandEvent
& WXUNUSED(event
))
489 if ( m_treeCtrl
->IsKeySelected() )
491 m_treeCtrl
->CreateNewKey(
492 wxGetTextFromUser(wxT("Enter the name of the new key")));
497 void RegFrame::OnNewText(wxCommandEvent
& WXUNUSED(event
))
500 if ( m_treeCtrl
->IsKeySelected() )
502 m_treeCtrl
->CreateNewTextValue(
503 wxGetTextFromUser(wxT("Enter the name for the new text value")));
508 void RegFrame::OnNewBinary(wxCommandEvent
& WXUNUSED(event
))
511 if ( m_treeCtrl
->IsKeySelected() )
513 m_treeCtrl
->CreateNewBinaryValue(
514 wxGetTextFromUser(wxT("Enter the name for the new binary value")));
519 void RegFrame::OnInfo(wxCommandEvent
& WXUNUSED(event
))
522 m_treeCtrl
->ShowProperties();
526 void RegFrame::OnViewChange(wxCommandEvent
& event
)
529 wxRegKey::WOW64ViewMode view
;
530 switch ( event
.GetId() )
532 case Menu_ViewDefault
:
533 view
= wxRegKey::WOW64ViewMode_Default
;
537 view
= wxRegKey::WOW64ViewMode_32
;
541 view
= wxRegKey::WOW64ViewMode_64
;
545 wxFAIL_MSG("Unexpected event source for view change.");
549 m_treeCtrl
->SetRegistryView(view
);
553 // ----------------------------------------------------------------------------
555 // ----------------------------------------------------------------------------
556 RegImageList::RegImageList() : wxImageList(16, 16, true)
558 // should be in sync with enum RegImageList::RegIcon
559 static const wxChar
*aszIcons
[] = { wxT("key1"),wxT("key2"),wxT("key3"),wxT("value1"),wxT("value2") };
560 wxString str
= wxT("icon_");
561 for ( unsigned int n
= 0; n
< WXSIZEOF(aszIcons
); n
++ )
563 Add(wxIcon(str
+ aszIcons
[n
], wxBITMAP_TYPE_ICO_RESOURCE
));
569 // ----------------------------------------------------------------------------
571 // ----------------------------------------------------------------------------
573 // create a new tree item and insert it into the tree
574 RegTreeCtrl::TreeNode
*RegTreeCtrl::InsertNewTreeNode(
576 const wxString
& strName
,
578 const wxString
*pstrValue
,
579 wxRegKey::WOW64ViewMode viewMode
)
581 // create new item & insert it
582 TreeNode
*pNewNode
= new TreeNode
;
583 pNewNode
->m_pTree
= this;
584 pNewNode
->m_pParent
= pParent
;
585 pNewNode
->m_strName
= strName
;
586 pNewNode
->m_bKey
= pstrValue
== NULL
;
587 pNewNode
->m_pKey
= NULL
;
588 pNewNode
->m_viewMode
= viewMode
;
591 pNewNode
->m_id
= AppendItem(pParent
->Id(),
592 pNewNode
->IsKey() ? strName
: *pstrValue
,
597 pNewNode
->m_id
= AddRoot(strName
);
600 wxASSERT_MSG( pNewNode
->m_id
, wxT("can't create tree control item!"));
602 // save the pointer in the item
603 SetItemData(pNewNode
->m_id
, pNewNode
);
605 // add it to the list of parent's children
606 if ( pParent
!= NULL
)
608 pParent
->m_aChildren
.Add(pNewNode
);
611 if ( pNewNode
->IsKey() )
613 SetItemHasChildren(pNewNode
->Id());
615 if ( !pNewNode
->IsRoot() )
617 // set the expanded icon as well
618 SetItemImage(pNewNode
->Id(),
619 RegImageList::OpenedKey
,
620 wxTreeItemIcon_Expanded
);
627 RegTreeCtrl::RegTreeCtrl(wxWindow
*parent
, wxWindowID id
)
628 : wxTreeCtrl(parent
, id
, wxDefaultPosition
, wxDefaultSize
,
629 wxTR_HAS_BUTTONS
| wxTR_EDIT_LABELS
| wxSUNKEN_BORDER
)
632 m_draggedItem
= NULL
;
633 m_restoreStatus
= false;
634 m_viewMode
= wxRegKey::WOW64ViewMode_Default
;
636 // create the image list
637 // ---------------------
638 m_imageList
= new RegImageList
;
639 SetImageList(m_imageList
);
646 wxT("Registry Root"),
653 m_pMenuPopup
= CreateRegistryMenu();
656 RegTreeCtrl::~RegTreeCtrl()
659 // delete m_pRoot; -- this is done by the tree now
663 void RegTreeCtrl::AddStdKeys()
665 for ( unsigned int ui
= 0; ui
< wxRegKey::nStdKeys
; ui
++ )
669 wxRegKey::GetStdKeyName(ui
),
670 RegImageList::ClosedKey
,
676 // ----------------------------------------------------------------------------
678 // ----------------------------------------------------------------------------
680 void RegTreeCtrl::OnIdle(wxIdleEvent
& WXUNUSED(event
))
682 if ( m_restoreStatus
)
684 // restore it after OnItemExpanding()
685 wxLogStatus(wxT("Ok"));
686 wxSetCursor(*wxSTANDARD_CURSOR
);
688 m_restoreStatus
= false;
692 void RegTreeCtrl::OnRightClick(wxMouseEvent
& event
)
695 wxTreeItemId lId
= HitTest(wxPoint(event
.GetX(), event
.GetY()), iFlags
);
696 if ( iFlags
& wxTREE_HITTEST_ONITEMLABEL
)
698 // select the item first
701 //else: take the currently selected item if click not on item
703 PopupMenu(m_pMenuPopup
, event
.GetX(), event
.GetY());
707 void RegTreeCtrl::OnDeleteItem(wxTreeEvent
& WXUNUSED(event
))
711 // test the key creation functions
712 void RegTreeCtrl::OnMenuTest()
714 wxTreeItemId lId
= GetSelection();
715 TreeNode
*pNode
= (TreeNode
*)GetItemData(lId
);
717 wxCHECK_RET( pNode
!= NULL
, wxT("tree item without data?") );
719 if ( pNode
->IsRoot() )
721 wxLogError(wxT("Can't create a subkey under the root key."));
725 if ( !pNode
->IsKey() )
727 wxLogError(wxT("Can't create a subkey under a value!"));
731 wxRegKey
key1(pNode
->Key(), wxT("key1"));
734 wxRegKey
key2a(key1
, wxT("key2a")), key2b(key1
, wxT("key2b"));
735 if ( key2a
.Create() && key2b
.Create() )
737 // put some values under the newly created keys
738 key1
.SetValue(wxT("first_term"), wxT("10"));
739 key1
.SetValue(wxT("second_term"), wxT("7"));
740 key2a
= wxT("this is the unnamed value");
741 key2b
.SetValue(wxT("sum"), 17);
745 wxLogStatus(wxT("Test keys successfully added."));
750 wxLogError(wxT("Creation of test keys failed."));
753 void RegTreeCtrl::OnChar(wxKeyEvent
& event
)
755 switch ( event
.GetKeyCode() )
762 if ( event
.AltDown() )
773 void RegTreeCtrl::OnSelChanged(wxTreeEvent
& event
)
776 wxFrame
*pFrame
= (wxFrame
*) wxWindow::GetParent();
777 pFrame
->SetStatusText(GetNode(event
)->FullName(), 1);
780 #endif // wxUSE_STATUSBAR
783 void RegTreeCtrl::OnItemExpanding(wxTreeEvent
& event
)
785 TreeNode
*pNode
= GetNode(event
);
786 bool bExpanding
= event
.GetEventType() == wxEVT_TREE_ITEM_EXPANDING
;
788 // expansion might take some time
789 wxSetCursor(*wxHOURGLASS_CURSOR
);
790 wxLogStatus(wxT("Working..."));
791 wxYield(); // to give the status line a chance to refresh itself
792 m_restoreStatus
= true; // some time later...
794 if ( pNode
->IsKey() )
798 // expanding: add subkeys/values
799 if ( !pNode
->OnExpand() )
804 // collapsing: clean up
810 void RegTreeCtrl::OnBeginEdit(wxTreeEvent
& event
)
812 TreeNode
*pNode
= GetNode(event
);
813 if ( pNode
->IsRoot() || pNode
->Parent()->IsRoot() )
815 wxLogStatus(wxT("This registry key can't be renamed."));
821 m_nameOld
= pNode
->m_strName
;
825 void RegTreeCtrl::OnEndEdit(wxTreeEvent
& event
)
829 wxString name
= event
.GetLabel();
831 TreeNode
*pNode
= GetNode(event
);
832 if ( pNode
->IsKey() )
834 wxRegKey
& key
= pNode
->Key();
835 ok
= key
.Rename(name
);
839 pNode
= pNode
->Parent();
840 wxRegKey
& key
= pNode
->Key();
842 ok
= key
.RenameValue(m_nameOld
, name
);
847 wxLogError(wxT("Failed to rename '%s' to '%s'."),
848 m_nameOld
.c_str(), name
.c_str());
850 #if 0 // MSW tree ctrl doesn't like this at all, it hangs
858 void RegTreeCtrl::OnBeginDrag(wxTreeEvent
& event
)
860 m_copyOnDrop
= event
.GetEventType() == wxEVT_TREE_BEGIN_DRAG
;
862 TreeNode
*pNode
= GetNode(event
);
863 if ( pNode
->IsRoot() || pNode
->Parent()->IsRoot() )
865 wxLogStatus(wxT("This registry key can't be %s."),
866 m_copyOnDrop
? wxT("copied") : wxT("moved"));
870 wxLogStatus(wxT("%s item %s..."),
871 m_copyOnDrop
? wxT("Copying") : wxT("Moving"),
874 m_draggedItem
= pNode
;
880 void RegTreeCtrl::OnEndDrag(wxTreeEvent
& event
)
882 wxCHECK_RET( m_draggedItem
, wxT("end drag without begin drag?") );
884 // clear the pointer anyhow
885 TreeNode
*src
= m_draggedItem
;
886 m_draggedItem
= NULL
;
888 // where are we going to drop it?
889 TreeNode
*dst
= GetNode(event
);
890 if ( dst
&& !dst
->IsKey() )
892 // we need a parent key
896 if ( !dst
|| dst
->IsRoot() )
898 wxLogError(wxT("Can't create a key here."));
903 bool isKey
= src
->IsKey();
904 if ( (isKey
&& (src
== dst
)) ||
905 (!isKey
&& (dst
->Parent() == src
)) ) {
906 wxLogStatus(wxT("Can't copy something on itself"));
911 // remove the "Registry Root\\" from the full name
912 wxString nameSrc
, nameDst
;
913 nameSrc
<< wxString(src
->FullName()).AfterFirst('\\');
914 nameDst
<< wxString(dst
->FullName()).AfterFirst('\\') << '\\'
915 << wxString(src
->FullName()).AfterLast('\\');
917 wxString verb
= m_copyOnDrop
? wxT("copy") : wxT("move");
918 wxString what
= isKey
? wxT("key") : wxT("value");
920 if ( wxMessageBox(wxString::Format
922 wxT("Do you really want to %s the %s %s to %s?"),
928 wxT("RegTest Confirm"),
929 wxICON_QUESTION
| wxYES_NO
| wxCANCEL
, this) != wxYES
) {
936 wxRegKey
& key
= src
->Key();
937 wxRegKey
keyDst(dst
->Key(), src
->m_strName
);
938 ok
= keyDst
.Create(false);
941 wxLogError(wxT("Key '%s' already exists"), keyDst
.GetName().c_str());
945 ok
= key
.Copy(keyDst
);
948 if ( ok
&& !m_copyOnDrop
)
950 // delete the old key
951 ok
= key
.DeleteSelf();
954 src
->Parent()->Refresh();
960 wxRegKey
& key
= src
->Parent()->Key();
961 ok
= key
.CopyValue(src
->m_strName
, dst
->Key());
962 if ( ok
&& !m_copyOnDrop
)
964 // we moved it, so delete the old one
965 ok
= key
.DeleteValue(src
->m_strName
);
971 wxLogError(wxT("Failed to %s registry %s."),
972 verb
.c_str(), what
.c_str());
980 // ----------------------------------------------------------------------------
981 // TreeNode implementation
982 // ----------------------------------------------------------------------------
983 bool RegTreeCtrl::TreeNode::OnExpand()
985 // we add children only once
986 if ( !m_aChildren
.IsEmpty() )
988 // we've been already expanded
994 // we're the root key
995 m_pTree
->AddStdKeys();
999 if ( Parent()->IsRoot() )
1001 // we're a standard key
1002 m_pKey
= new wxRegKey(m_strName
, m_viewMode
);
1006 // we're a normal key
1007 m_pKey
= new wxRegKey(*(Parent()->m_pKey
), m_strName
);
1010 if ( !m_pKey
->Open() )
1012 wxLogError(wxT("The key '%s' can't be opened."), FullName());
1016 // if we're empty, we shouldn't be expandable at all
1017 bool isEmpty
= true;
1019 // enumeration variables
1024 // enumerate all subkeys
1025 bCont
= m_pKey
->GetFirstKey(str
, l
);
1028 m_pTree
->InsertNewTreeNode(
1031 RegImageList::ClosedKey
,
1034 bCont
= m_pKey
->GetNextKey(str
, l
);
1036 // we have at least this key...
1040 // enumerate all values
1041 bCont
= m_pKey
->GetFirstValue(str
, l
);
1046 strItem
= wxT("<default>");
1049 strItem
+= wxT(" = ");
1051 // determine the appropriate icon
1052 RegImageList::Icon icon
;
1053 switch ( m_pKey
->GetValueType(str
) )
1055 case wxRegKey::Type_String
:
1056 case wxRegKey::Type_Expand_String
:
1057 case wxRegKey::Type_Multi_String
:
1060 icon
= RegImageList::TextValue
;
1061 m_pKey
->QueryValue(str
, strValue
);
1062 strItem
+= strValue
;
1066 case wxRegKey::Type_None
:
1067 // @@ handle the error...
1068 icon
= RegImageList::BinaryValue
;
1071 case wxRegKey::Type_Dword
:
1074 m_pKey
->QueryValue(str
, &l
);
1081 icon
= RegImageList::BinaryValue
;
1084 m_pTree
->InsertNewTreeNode(this, str
, icon
, &strItem
, m_viewMode
);
1085 bCont
= m_pKey
->GetNextValue(str
, l
);
1087 // we have at least this value...
1093 // this is for the case when our last child was just deleted
1094 wxTreeItemId
theId(Id()); // Temp variable seems necessary for BC++
1095 m_pTree
->Collapse(theId
);
1097 // we won't be expanded any more
1098 m_pTree
->SetItemHasChildren(theId
, false);
1104 void RegTreeCtrl::TreeNode::OnCollapse()
1111 void RegTreeCtrl::TreeNode::Refresh()
1116 wxTreeItemId
theId(Id()); // Temp variable seems necessary for BC++
1117 bool wasExpanded
= m_pTree
->IsExpanded(theId
);
1119 m_pTree
->Collapse(theId
);
1122 m_pTree
->SetItemHasChildren(theId
);
1125 m_pTree
->Expand(theId
);
1130 bool RegTreeCtrl::TreeNode::DeleteChild(TreeNode
*child
)
1132 int index
= m_aChildren
.Index(child
);
1133 wxCHECK_MSG( index
!= wxNOT_FOUND
, false,
1134 wxT("our child in tree should be in m_aChildren") );
1136 m_aChildren
.RemoveAt((size_t)index
);
1139 if ( child
->IsKey() )
1141 // must close key before deleting it
1142 child
->OnCollapse();
1144 ok
= Key().DeleteKey(child
->m_strName
);
1148 ok
= Key().DeleteValue(child
->m_strName
);
1153 wxTreeItemId
theId(child
->Id()); // Temp variable seems necessary for BC++
1154 m_pTree
->Delete(theId
);
1162 void RegTreeCtrl::TreeNode::DestroyChildren()
1164 // destroy all children
1165 size_t nCount
= m_aChildren
.GetCount();
1166 for ( size_t n
= 0; n
< nCount
; n
++ )
1168 wxTreeItemId lId
= m_aChildren
[n
]->Id();
1169 m_pTree
->Delete(lId
);
1172 m_aChildren
.Empty();
1175 RegTreeCtrl::TreeNode::~TreeNode()
1180 const wxChar
*RegTreeCtrl::TreeNode::FullName() const
1182 static wxString s_strName
;
1186 return wxT("Registry Root");
1190 // our own registry key might not (yet) exist or we might be a value,
1191 // so just use the parent's and concatenate
1192 s_strName
= Parent()->FullName();
1193 s_strName
<< wxT('\\') << m_strName
;
1195 return s_strName
.t_str();
1199 void RegTreeCtrl::TreeNode::SetRegistryView(wxRegKey::WOW64ViewMode viewMode
)
1201 m_viewMode
= viewMode
;
1203 // Update children with new view.
1204 size_t nCount
= m_aChildren
.GetCount();
1205 for (size_t n
= 0; n
< nCount
; n
++)
1206 m_aChildren
[n
]->SetRegistryView(viewMode
);
1209 // ----------------------------------------------------------------------------
1210 // operations on RegTreeCtrl
1211 // ----------------------------------------------------------------------------
1213 void RegTreeCtrl::GoTo(const wxString
& location
)
1215 wxStringTokenizer
tk(location
, wxT("\\"));
1217 wxTreeItemId id
= GetRootItem();
1219 while ( tk
.HasMoreTokens() )
1221 wxString subkey
= tk
.GetNextToken();
1223 wxTreeItemId idCurrent
= id
;
1224 if ( !IsExpanded(idCurrent
) )
1227 wxTreeItemIdValue dummy
;
1228 id
= GetFirstChild(idCurrent
, dummy
);
1230 if ( idCurrent
== GetRootItem() )
1232 // special case: we understand both HKCU and HKEY_CURRENT_USER here
1233 for ( size_t key
= 0; key
< wxRegKey::nStdKeys
; key
++ )
1235 if ( subkey
== wxRegKey::GetStdKeyName(key
)
1236 || subkey
== wxRegKey::GetStdKeyShortName(key
) )
1241 id
= GetNextChild(idCurrent
, dummy
);
1246 // enum all children
1249 if ( subkey
== ((TreeNode
*)GetItemData(id
))->m_strName
)
1252 id
= GetNextChild(idCurrent
, dummy
);
1258 wxLogError(wxT("No such key '%s'."), location
.c_str());
1268 void RegTreeCtrl::DeleteSelected()
1270 wxTreeItemId lCurrent
= GetSelection(),
1271 lParent
= GetItemParent(lCurrent
);
1273 if ( lParent
== GetRootItem() )
1275 wxLogError(wxT("Can't delete root key."));
1279 TreeNode
*pCurrent
= (TreeNode
*)GetItemData(lCurrent
),
1280 *pParent
= (TreeNode
*)GetItemData(lParent
);
1282 wxCHECK_RET(pCurrent
&& pParent
, wxT("either node or parent without data?"));
1284 if ( pParent
->IsRoot() )
1286 wxLogError(wxT("Can't delete standard key."));
1290 wxString what
= pCurrent
->IsKey() ? wxT("key") : wxT("value");
1291 if ( wxMessageBox(wxString::Format
1293 wxT("Do you really want to delete this %s?"),
1296 wxT("Confirmation"),
1297 wxICON_QUESTION
| wxYES_NO
| wxCANCEL
, this) != wxYES
)
1302 pParent
->DeleteChild(pCurrent
);
1305 void RegTreeCtrl::CreateNewKey(const wxString
& strName
)
1307 wxTreeItemId lCurrent
= GetSelection();
1308 TreeNode
*pCurrent
= (TreeNode
*)GetItemData(lCurrent
);
1310 wxCHECK_RET( pCurrent
!= NULL
, wxT("node without data?") );
1312 wxASSERT( pCurrent
->IsKey() ); // check must have been done before
1314 if ( pCurrent
->IsRoot() )
1316 wxLogError(wxT("Can't create a new key under the root key."));
1320 wxRegKey
key(pCurrent
->Key(), strName
);
1322 pCurrent
->Refresh();
1325 void RegTreeCtrl::CreateNewTextValue(const wxString
& strName
)
1327 wxTreeItemId lCurrent
= GetSelection();
1328 TreeNode
*pCurrent
= (TreeNode
*)GetItemData(lCurrent
);
1330 wxCHECK_RET( pCurrent
!= NULL
, wxT("node without data?") );
1332 wxASSERT( pCurrent
->IsKey() ); // check must have been done before
1334 if ( pCurrent
->IsRoot() )
1336 wxLogError(wxT("Can't create a new value under the root key."));
1340 if ( pCurrent
->Key().SetValue(strName
, wxEmptyString
) )
1341 pCurrent
->Refresh();
1344 void RegTreeCtrl::CreateNewBinaryValue(const wxString
& strName
)
1346 wxTreeItemId lCurrent
= GetSelection();
1347 TreeNode
*pCurrent
= (TreeNode
*)GetItemData(lCurrent
);
1349 wxCHECK_RET( pCurrent
!= NULL
, wxT("node without data?") );
1351 wxASSERT( pCurrent
->IsKey() ); // check must have been done before
1353 if ( pCurrent
->IsRoot() )
1355 wxLogError(wxT("Can't create a new value under the root key."));
1359 if ( pCurrent
->Key().SetValue(strName
, 0) )
1360 pCurrent
->Refresh();
1363 void RegTreeCtrl::SetRegistryView(wxRegKey::WOW64ViewMode viewMode
)
1365 m_viewMode
= viewMode
;
1366 m_pRoot
->SetRegistryView(viewMode
);
1370 void RegTreeCtrl::ShowProperties()
1372 wxTreeItemId lCurrent
= GetSelection();
1373 TreeNode
*pCurrent
= (TreeNode
*)GetItemData(lCurrent
);
1375 if ( !pCurrent
|| pCurrent
->IsRoot() )
1377 wxLogStatus(wxT("No properties"));
1382 if ( pCurrent
->IsKey() )
1384 const wxRegKey
& key
= pCurrent
->Key();
1385 size_t nSubKeys
, nValues
;
1386 if ( !key
.GetKeyInfo(&nSubKeys
, NULL
, &nValues
, NULL
) )
1388 wxLogError(wxT("Couldn't get key info"));
1392 wxLogMessage(wxT("Key '%s' has %u subkeys and %u values."),
1393 key
.GetName().c_str(), nSubKeys
, nValues
);
1396 else // it's a value
1398 TreeNode
*parent
= pCurrent
->Parent();
1399 wxCHECK_RET( parent
, wxT("reg value without key?") );
1401 const wxRegKey
& key
= parent
->Key();
1402 const wxChar
*value
= pCurrent
->m_strName
.c_str();
1403 wxLogMessage(wxT("Value '%s' under the key '%s' is of type ")
1406 parent
->m_strName
.c_str(),
1407 key
.GetValueType(value
),
1408 key
.IsNumericValue(value
) ? wxT("numeric") : wxT("string"));
1413 bool RegTreeCtrl::IsKeySelected() const
1415 wxTreeItemId lCurrent
= GetSelection();
1416 TreeNode
*pCurrent
= (TreeNode
*) GetItemData(lCurrent
);
1418 wxCHECK( pCurrent
!= NULL
, false );
1420 return pCurrent
->IsKey();
1423 void RegTreeCtrl::DoRefresh()
1425 wxTreeItemId lId
= GetSelection();
1429 TreeNode
*pNode
= (TreeNode
*) GetItemData(lId
);
1431 wxCHECK_RET( pNode
!= NULL
, wxT("tree item without data?") );