Domanda

Voglio scoprire se un pulsante viene premuto o meno. Questa sembra non essere una proprietà ufficiale di un pulsante (non una casella di controllo in stile pulsante!), Ma sembra accessibile, c'è il messaggio BM_GetState, ad esempio che dovrebbe ottenere il risultato desiderato.

Il problema è, spesso, non ricevo le maniglie delle finestre per i miei pulsanti (sono solo una parte di un'altra barra degli strumenti, sebbene possano essere distinti dall'automazione). E avrei bisogno di una tale maniglia per la funzione SendMessage.

Quindi .. c'è un modo per accedere a quella proprietà? So che è accessibile, dal momento che l'ho visto in altri programmi di automazione, non ho solo konw come arrivarci.

Userò C#, ma qualsiasi codice C andrebbe bene.

Grazie molto

È stato utile?

Soluzione

(EDIT: Quindi sono finalmente riuscito a realizzare il formato del codice correttamente qui - basta inserire 4 spazi all'inizio.)

Divertiti, mi ci è voluto molto tempo per farlo funzionare .. ma ora ho voglia di aver raggiunto un nuovo livello. :)

(Per favore dimmi come realizzarlo correttamente - sia citazione che codice non sono riusciti a

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

EDIT: qui http://www.andreas-reiff.de/2011/06/c-speicher-anderan-prozess-befullen-lassen-checken-ob-ein-butt-gedruckt/ Con codice leggibile e spiegazioni in una strana lingua straniera. Tuttavia, i commenti del codice sono l'inglese. Spero che tu lo trovi utile. Inoltre, non sarei stato in grado di risolverlo senza le informazioni qui Come mai alcuni controlli non hanno una maniglia di Windows?.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top