我想知道是否按下了按钮。这似乎不是按钮的官方属性(不是按钮样式的复选框!),但似乎可以访问,例如应该得到所需结果的 BM_GETSTATE 消息。
问题是,我的按钮经常没有窗口句柄(它们只是另一个工具栏的一部分,尽管它们可以通过 AutomationElement 区分)。我需要这样的 SendMessage 函数句柄。
那么..有没有办法让我访问该属性?我知道它是可访问的,因为我在其他自动化程序中看到过它,我只是不知道如何获得它。
我将使用 C#,但任何 C 代码都可以。
非常感谢
我想知道是否按下了按钮。这似乎不是按钮的官方属性(不是按钮样式的复选框!),但似乎可以访问,例如应该得到所需结果的 BM_GETSTATE 消息。
问题是,我的按钮经常没有窗口句柄(它们只是另一个工具栏的一部分,尽管它们可以通过 AutomationElement 区分)。我需要这样的 SendMessage 函数句柄。
那么..有没有办法让我访问该属性?我知道它是可访问的,因为我在其他自动化程序中看到过它,我只是不知道如何获得它。
我将使用 C#,但任何 C 代码都可以。
非常感谢
(编辑:所以我终于设法在这里正确地制作代码格式 - 只需在开头插入 4 个空格。)
享受它,我花了很长时间才让它发挥作用..但现在我感觉自己达到了一个新的水平。:)
(请告诉我如何使其格式正确 - 引用和代码对我来说都失败了)
int res;
#region direct method
int hwnd = ae.Current.NativeWindowHandle;
if (hwnd != 0)
{
const UInt32 BM_GETSTATE = 0x00F2;
res = SendMessage(hwnd, BM_GETSTATE, 0, 0);
}
#endregion
else
#region method via toolbar
{
AutomationElement parent = TreeWalker.RawViewWalker.GetParent(ae);
while ((parent != null) && (parent.Current.ControlType != ControlType.ToolBar))
parent = TreeWalker.RawViewWalker.GetParent(ae);
if (parent != null)
{
int toolBarHandle = parent.Current.NativeWindowHandle;
#region defines
const int WM_USER = 0x400;
const int TB_GETSTATE = (WM_USER + 18);
const int TB_GETBUTTON = (WM_USER + 23);
const int TB_BUTTONCOUNT = (WM_USER + 24);
#endregion
#region get correct child number
int numButtons = SendMessage(toolBarHandle, TB_BUTTONCOUNT, 0, 0);
AutomationElement sibling = ae;
int cnt = -1;
while (sibling != null)
{
sibling = TreeWalker.RawViewWalker.GetPreviousSibling(sibling);
++cnt;
}
if (cnt >= numButtons)
cnt = 0; // nonsense value, but pass a valid one
#endregion
#region get command id
TBBUTTON butInfo = new TBBUTTON();
butInfo.idCommand = 1234;
uint pid;
GetWindowThreadProcessId((IntPtr)toolBarHandle, out pid);
IntPtr process = OpenProcess(ProcessAccessFlags.VMOperation | ProcessAccessFlags.VMRead |
ProcessAccessFlags.VMWrite | ProcessAccessFlags.QueryInformation, false, pid);
IntPtr p = VirtualAllocEx(process, IntPtr.Zero, (uint)Marshal.SizeOf(typeof(TBBUTTON)), AllocationType.Commit
, MemoryProtection.ReadWrite);
int _res = SendMessage(toolBarHandle, TB_GETBUTTON, cnt, p.ToInt32());
#region getresult
int read;
IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(TBBUTTON)));
Marshal.StructureToPtr(butInfo, ptr, true);
bool __res = ReadProcessMemory(process, p, ptr, Marshal.SizeOf(typeof(TBBUTTON)), out read);
System.Diagnostics.Debug.Assert(read == Marshal.SizeOf(typeof(TBBUTTON)));
butInfo = (TBBUTTON)Marshal.PtrToStructure(ptr, typeof(TBBUTTON));
#endregion
int commandId = butInfo.idCommand;
VirtualFreeEx(process, p, 0, FreeType.Release);
#endregion
//!define BST_UNCHECKED 0
//!define BST_CHECKED 1
//!define BST_INDETERMINATE 2
//!define BST_PUSHED 4
//!define BST_FOCUS 8
#region get state
res = SendMessage(toolBarHandle, TB_GETSTATE, commandId, 0);
#endregion
}
}
#endregion
编辑:这里http://www.andreas-reiff.de/2011/06/c-speicher-anderen-prozess-befullen-lassen-checken-ob-ein-button-gedruckt/带有可读的代码和奇怪的解释,外语..代码注释是英文的,不过。希望你觉得它有用。另外,如果没有此处的信息,我将无法解决此问题。为什么某些控件没有 Windows 句柄?.