in Revit i am trying to select the checkbox next to ‘View Templates’ in a ListBox of the TransferProjectStandards Dialog. I was able to implement the ‘Check None’ functionality, but I couldn’t figure out how to interact with the individual items in the ListBox. I’ll provide my code for better clarification. I appreciate any suggestions you may have.
Thank you
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
namespace RunTransfer
{
public class ListBoxItem
{
public string Text { get; set; }
public string Type { get; set; }
public int Index { get; set; }
}
internal class Program
{
static List<ListBoxItem> listBoxItems = new List<ListBoxItem>();
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr GetWindow(IntPtr hWnd, uint uCmd);
[DllImport("user32.dll", SetLastError = true)]
static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);
[DllImport("user32.dll", SetLastError = true)]
static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool EnumChildWindows(IntPtr hwndParent, EnumWindowsProc lpEnumFunc, IntPtr lParam);
[DllImport("user32.dll")]
static extern int SendMessage(IntPtr hWnd, uint Msg, int wParam, int lParam);
[DllImport("user32.dll")]
static extern int SendMessage(IntPtr hWnd, uint Msg, int wParam, StringBuilder lParam);
private delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam);
const int MAX_STRING_LENGTH = 512;
const uint BM_CLICK = 0x00F5;
const uint LB_GETCOUNT = 0x018B;
const uint LB_GETTEXT = 0x0189;
const uint BM_SETCHECK = 0x00F1;
const uint BST_CHECKED = 0x0001;
const uint LB_SETCURSEL = 0x0186;
static IntPtr FindTransferProjectStandardsWindow()
{
return FindWindow(null, "Transfer Project Standards");
}
static void EnumerateChildWindows(IntPtr parentHandle, EnumWindowsProc callback)
{
EnumChildWindows(parentHandle, callback, IntPtr.Zero);
}
static bool EnumWindow(IntPtr hWnd, IntPtr lParam)
{
StringBuilder windowText = new StringBuilder(MAX_STRING_LENGTH);
StringBuilder className = new StringBuilder(MAX_STRING_LENGTH);
GetWindowText(hWnd, windowText, MAX_STRING_LENGTH);
GetClassName(hWnd, className, MAX_STRING_LENGTH);
Console.WriteLine($"Window Title: {windowText}, Class: {className}");
// Click "Check &None" button
if (windowText.ToString() == "Check &None")
{
SendMessage(hWnd, BM_CLICK, 0, 0);
return true; // Continue enumeration
}
// Handle ListBox items
if (className.ToString().Contains("ListBox"))
{
int itemCount = SendMessage(hWnd, LB_GETCOUNT, 0, 0); // LB_GETCOUNT
for (int i = 0; i < itemCount; i++)
{
StringBuilder itemText = new StringBuilder(MAX_STRING_LENGTH);
SendMessage(hWnd, LB_GETTEXT, i, itemText);
ListBoxItem item = new ListBoxItem
{
Text = itemText.ToString(),
Index = i
};
listBoxItems.Add(item);
Console.WriteLine($" ListBox Item {i + 1}: Text: {item.Text}");
if (item.Text == "View Templates")
{
// Select the "View Templates" item
SendMessage(hWnd, LB_SETCURSEL, i, 0);
Console.WriteLine(" Selected the 'View Templates' item");
// Locate and check the checkbox associated with "View Templates"
IntPtr checkboxHandle = FindCheckboxHandle(hWnd);
if (checkboxHandle != IntPtr.Zero)
{
SendMessage(checkboxHandle, BM_SETCHECK, (int)BST_CHECKED, 0);
Console.WriteLine(" Checked the 'View Templates' item");
}
else
{
Console.WriteLine(" Could not find the checkbox handle for 'View Templates'");
}
}
}
}
return true;
}
static IntPtr FindCheckboxHandle(IntPtr listBoxHandle)
{
IntPtr checkboxHandle = IntPtr.Zero;
// Enumerate child windows of the parent to find the checkbox
EnumChildWindows(listBoxHandle, (childHwnd, lParam) =>
{
StringBuilder className = new StringBuilder(MAX_STRING_LENGTH);
GetClassName(childHwnd, className, MAX_STRING_LENGTH);
StringBuilder windowText = new StringBuilder(MAX_STRING_LENGTH);
GetWindowText(childHwnd, windowText, MAX_STRING_LENGTH);
Console.WriteLine($"Child Window Title: {windowText}, Class: {className}");
// Check for checkbox
if (className.ToString().Contains("Button"))
{
checkboxHandle = childHwnd;
return false;
}
return true;
}, IntPtr.Zero);
return checkboxHandle;
}
static void Main(string[] args)
{
Run();
}
static void Run()
{
IntPtr transferWindow = FindTransferProjectStandardsWindow();
if (transferWindow != IntPtr.Zero)
{
Console.WriteLine("Transfer Project Standards window found.");
EnumerateChildWindows(transferWindow, EnumWindow);
}
else
{
Console.WriteLine("Transfer Project Standards window not found.");
}
Console.ReadKey();
}
}
}
get into the selection of the items in the ListBox of the TransferProjectStandards in Revit
Hans101 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.