private void ExpandNode(IntPtr Node) { int Position = 0; Stopwatch timer; int Left = 0; int Top = 0; int Right = 0; int Bottom = 0; NM.tagRect ClientRect = new NM.tagRect(); // check if already expanded GUI.m_APE.AddFirstMessageFindByHandle(DataStores.Store0, Identity.ParentHandle, Identity.Handle); GUI.m_APE.AddQueryMessageReflect(DataStores.Store0, DataStores.Store1, "NodeFromHandle", MemberTypes.Method, new Parameter(GUI.m_APE, Node)); GUI.m_APE.AddQueryMessageReflect(DataStores.Store1, DataStores.Store2, "IsExpanded", MemberTypes.Property); GUI.m_APE.AddRetrieveMessageGetValue(DataStores.Store2); GUI.m_APE.SendMessages(EventSet.APE); GUI.m_APE.WaitForMessages(EventSet.APE); // Get the value(s) returned MUST be done straight after the WaitForMessages call bool IsExpanded = GUI.m_APE.GetValueFromMessage(); if (IsExpanded) { return; } for (int i = 0; i < 2; i++) { // Get bounds GUI.m_APE.AddFirstMessageFindByHandle(DataStores.Store0, Identity.ParentHandle, Identity.Handle); GUI.m_APE.AddQueryMessageReflect(DataStores.Store0, DataStores.Store1, "NodeFromHandle", MemberTypes.Method, new Parameter(GUI.m_APE, Node)); GUI.m_APE.AddQueryMessageReflect(DataStores.Store1, DataStores.Store2, "EnsureVisible", MemberTypes.Method); GUI.m_APE.AddQueryMessageReflect(DataStores.Store1, DataStores.Store3, "Bounds", MemberTypes.Property); GUI.m_APE.AddQueryMessageReflect(DataStores.Store3, DataStores.Store4, "Left", MemberTypes.Property); GUI.m_APE.AddQueryMessageReflect(DataStores.Store3, DataStores.Store5, "Top", MemberTypes.Property); GUI.m_APE.AddQueryMessageReflect(DataStores.Store3, DataStores.Store6, "Right", MemberTypes.Property); GUI.m_APE.AddQueryMessageReflect(DataStores.Store3, DataStores.Store7, "Bottom", MemberTypes.Property); GUI.m_APE.AddRetrieveMessageGetValue(DataStores.Store4); GUI.m_APE.AddRetrieveMessageGetValue(DataStores.Store5); GUI.m_APE.AddRetrieveMessageGetValue(DataStores.Store6); GUI.m_APE.AddRetrieveMessageGetValue(DataStores.Store7); GUI.m_APE.SendMessages(EventSet.APE); GUI.m_APE.WaitForMessages(EventSet.APE); // Get the value(s) returned MUST be done straight after the WaitForMessages call Left = GUI.m_APE.GetValueFromMessage(); Top = GUI.m_APE.GetValueFromMessage(); Right = GUI.m_APE.GetValueFromMessage(); Bottom = GUI.m_APE.GetValueFromMessage(); NM.GetClientRect(Identity.Handle, out ClientRect); if (Left < 0 || Top < 0 || Bottom > ClientRect.bottom) { // Go round again } else { break; } } if (Right > ClientRect.right) { Right = ClientRect.right; } bool WaitForMove = false; if (Bottom > ClientRect.bottom) { WaitForMove = true; Bottom = ClientRect.bottom; } // Expand it if (m_ShowPlusMinus) { int CheckBoxModifier = 0; if (m_CheckBoxes) { CheckBoxModifier = 12; } // Scroll the expand icon in to view if need be int X = Left - 7 - CheckBoxModifier - 5; if (X < 0) { //get current scroll bar pos Position = NM.GetScrollPos(Identity.Handle, NM.SBS_HORZ); //update the pos Position = Position + X; NM.SetScrollPos(Identity.Handle, NM.SBS_HORZ, Position, false); //send the message to move IntPtr MessageResult; IntPtr SendResult = NM.SendMessageTimeout(Handle, NM.WM_HSCROLL, new IntPtr(MakeLParam((int)NM.SB_THUMBPOSITION, Position)), IntPtr.Zero, NM.SendMessageTimeoutFlags.SMTO_NORMAL, (uint)GUI.GetTimeOut(), out MessageResult); base.SingleClickInternal(5, Top + ((Bottom - Top) / 2), MouseButton.Left, MouseKeyModifier.None); } else { base.SingleClickInternal(Left - 7 - CheckBoxModifier, Top + ((Bottom - Top) / 2), MouseButton.Left, MouseKeyModifier.None); } } else { base.DoubleClickInternal(Right - 4, Top + ((Bottom - Top) / 2), MouseButton.Left, MouseKeyModifier.None); } // Wait for it to be expanded bool IsNowExpanded = false; timer = Stopwatch.StartNew(); do { // Get if expanded GUI.m_APE.AddFirstMessageFindByHandle(DataStores.Store0, Identity.ParentHandle, Identity.Handle); GUI.m_APE.AddQueryMessageReflect(DataStores.Store0, DataStores.Store1, "NodeFromHandle", MemberTypes.Method, new Parameter(GUI.m_APE, Node)); GUI.m_APE.AddQueryMessageReflect(DataStores.Store1, DataStores.Store2, "IsExpanded", MemberTypes.Property); GUI.m_APE.AddRetrieveMessageGetValue(DataStores.Store2); GUI.m_APE.SendMessages(EventSet.APE); GUI.m_APE.WaitForMessages(EventSet.APE); // Get the value(s) returned MUST be done straight after the WaitForMessages call IsNowExpanded = GUI.m_APE.GetValueFromMessage(); if (IsNowExpanded) { break; } if (timer.ElapsedMilliseconds > GUI.m_APE.TimeOut) { throw new Exception("Node failed to expand"); } Thread.Sleep(15); }while (true); //left clicking on a node which is partially off the bottom of the window will scroll it if (WaitForMove) { timer = Stopwatch.StartNew(); do { // Get bounds GUI.m_APE.AddFirstMessageFindByHandle(DataStores.Store0, Identity.ParentHandle, Identity.Handle); GUI.m_APE.AddQueryMessageReflect(DataStores.Store0, DataStores.Store1, "NodeFromHandle", MemberTypes.Method, new Parameter(GUI.m_APE, Node)); GUI.m_APE.AddQueryMessageReflect(DataStores.Store1, DataStores.Store2, "Bounds", MemberTypes.Property); GUI.m_APE.AddQueryMessageReflect(DataStores.Store2, DataStores.Store3, "Bottom", MemberTypes.Property); GUI.m_APE.AddRetrieveMessageGetValue(DataStores.Store3); GUI.m_APE.SendMessages(EventSet.APE); GUI.m_APE.WaitForMessages(EventSet.APE); // Get the value(s) returned MUST be done straight after the WaitForMessages call Bottom = GUI.m_APE.GetValueFromMessage(); if (Bottom >= ClientRect.bottom) { break; } if (timer.ElapsedMilliseconds > GUI.m_APE.TimeOut) { throw new Exception("Node failed to scroll fully into view"); } Thread.Sleep(15); }while (true); } // After clicking sleep for a bit to give time for the treeview to update Thread.Sleep(30); }