To classify the question:
Basically, it's all about a user dialog!!! I work with WPF and don't want to use the FolderBrowserDialog because the Forms NameSpace can only be integrated poorly in a .NETCore WPF project. So I chose the SHBrowseForFolder dialog natively under the API32 in the ShellNameSpace. The FolderBrowserDialog is just a wrapper around this Windows dialog. (I'm building an MVVM-enabled WPF wrapper, for a directory selection dialog.)
No problem, the dialog is displayed, a root directory can be defined ... the only problem is the initial select directory. (Selecting the start directory in the dialog window/TreeView))
For this I use a launcher that is started before the directory dialog is called and (via a timer) "gets" the dialog window and accesses the directory tree view.
Now I want to iterate through the treeview (of the dialog window) and select the treeview item that matches the select directory.
It is precisely at this point that the problem arises that I cannot "access" subordinate items.
The details ...
I'm working with C# and I want to iterate through the TreeView of a Windows FolderDialogBrowser (WINAPI).
I get the pointer to the TreeView via the Windows dialog window (user32.dll -> FindWindow).
IntPtr hwndDlg = FindWindow(null, _topLevelSearchString); // "get" the handle of the dlg box window
if (hwndDlg != IntPtr.Zero) // Has the Dlg box window found?
{
IntPtr hwndFolderCtrl = GetDlgItem(hwndDlg, _dlgControl); // "get" the dlg box control in the dlg box window
if (hwndFolderCtrl != IntPtr.Zero) // Has the dlg box control found in the dlg box window?
{
IntPtr hwndTV = GetDlgItem(hwndFolderCtrl, _dlgTreeView); // "Get" the handle of the TreeView of the Dlg box
...
Now I want to iterate through this one... as an example with fixed references:
IntPtr RootItem = IntPtr.Zero; // Initialize the handle of the root entry
IntPtr AktItem = IntPtr.Zero; // handle of the current Initialize TreeView items
string AktVerzeichnis = RootVerzeichnis; // Initialize current directory
RootItem = SendMessage(pTV, TVM_GETNEXTITEM, new(TVGN_ROOT), IntPtr.Zero); // Get root entry
AktItem = RootItem; // Pointer to the current update entry
if (!SelectVerzeichnis.Equals(AktVerzeichnis)) // Select Directory Is Not Root Directory?
{
if (AktItem != IntPtr.Zero) // Is there a root item?
{
IntPtr Item1 = SendMessage(pTV, TVM_GETNEXTITEM, new(TVGN_CHILD), RootItem); // Item1 entry = get child entry from root entry [level 1]
System.Diagnostics.Debug.Print("1. Eintrag: " + GetTVItem(pTV, Item1)); // Determine the designation of the 1st entry
IntPtr Item1_1 = SendMessage(pTV, TVM_GETNEXTITEM, new(TVGN_CHILD), Item1); // Get 1st sub-item from Item1 [level 2].
System.Diagnostics.Debug.Print("1.1 Eintrag: " + GetTVItem(pTV, Item1_1)); // Designation of 1.1. Determine entry
IntPtr Item2 = SendMessage(pTV, TVM_GETNEXTITEM, new(TVGN_NEXT), Item1); // Get 2nd entry [level 1].
System.Diagnostics.Debug.Print("2. Eintrag: " + GetTVItem(pTV, Item2)); // Determine the designation of the 2nd entry
IntPtr Item3 = SendMessage(pTV, TVM_GETNEXTITEM, new(TVGN_NEXT), Item2); // Get 3rd entry [level 1].
System.Diagnostics.Debug.Print("3. Eintrag: " + GetTVItem(pTV, Item3)); // Determine the designation of the 3rd entry
IntPtr Item3_1 = SendMessage(pTV, TVM_GETNEXTITEM, new(TVGN_CHILD), Item3); // Get 1st sub-item from Item3 [level 2].
System.Diagnostics.Debug.Print("3.1 Eintrag: " + GetTVItem(pTV, Item3_1)); // Designation of 3.1. Determine entry
The above sequence gives: Item1: Anruf_Info Item1_1: Item2: Anruf_Info REPORT22 Item3: Druck Item3_1:
My problem is that I always don't get the sub-items (both Item1_1 and Item3_1) (=> IntPtr.Zerro).
TVGN_CHILD is (except sub-entry from root entry => Item1 !!!) not work!!!
What can that be???
Different calls from:
SendMessage(pTV, TVM_GETNEXTIM, new(TVGN_CHILD), Item1)
I select the entry before retrieving the sub-entry so that (internally through the TreeView) the sub-entries are loaded dynamically.
IntPtr Item1 = SendMessage(pTV, TVM_GETNEXTITEM, new(TVGN_CHILD), RootItem); // 1. Eintrag = Untergeordneter Eintrag vom Root-Eintrag holen [Ebene 1]
SendMessage(pTV, TVM_SELECTITEM, new IntPtr(TVGN_CARET), Item1); // 1. Eintrag selektieren
SendMessage(pTV, TVGN_FIRSTVISIBLE, IntPtr.Zero, Item1); // 1. Eintrag in den sichtbaren Bereich bringen
IntPtr Item1_1 = SendMessage(pTV, TVM_GETNEXTITEM, new(TVGN_CHILD), Item1); // 1. Unter-Eintrag vom 1. Eintrag [Ebene 2] holen