Pregunta

Quiero averiguar si se presiona o no un botón. Esta parece no ser una propiedad oficial de un botón (¡no una casilla de verificación estilo botón!), Pero parece accesible, existe el mensaje BM_GetState, por ejemplo, que debería obtener el resultado deseado.

El problema es que, con frecuencia, no obtengo manejo de la ventana para mis botones (son solo parte de otra barra de herramientas, aunque el AutomationElement puede distinguirlos). Y necesitaría tal mango para la función SendMessage.

Entonces ... ¿hay alguna forma de acceder a esa propiedad? Sé que es accesible, ya que lo he visto en otros programas de automatización, simplemente no sé cómo hacerlo.

Voy a usar C#, pero cualquier código C estaría bien.

Muchas gracias

¿Fue útil?

Solución

(Editar: así finalmente logré hacer el formato de código correctamente aquí, solo inserte 4 espacios al principio).

Disfrútalo, me llevó mucho tiempo hacer que funcionara ... pero ahora tengo que haber alcanzado un nuevo nivel. :)

(Por favor, dígame cómo hacer que se formaten correctamente: tanto la cita como el código me fallaron)

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

Editar: aquí http://www.andreas-reiff.de/2011/06/c-peicher-anderen-prozess-befullen-lassen-checken-ob-ein-button-gedruckt/ con código legible y explicaciones en un idioma extraño y extranjero. Sin embargo, los comentarios de código son inglés. Esperamos que te sea útil. Además, no hubiera podido resolver esto sin la información aquí ¿Cómo es que algunos controles no tienen un mango de Windows?.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top