Nachrichten ID von Menü & Toolbaar eines Programms ermitteln



  • Guten Tag

    Ich will ein Programm automatisiert ansteuern indem ich immer wieder kehrende Eingabeabfolgen durch ein selbst geschriebenes MFC-Programm auslöse.

    Früher(tm) habe ich es so gemacht, das ich mir einfach die ID des Menüeintrags bew. des Toolbarelements mittels Spy++ geholt und diese dann mit meinem Programm gesendet habe.

    Doch das fernzusteuernde Programm hat diese neumodernen Ribons.
    Da sind die einzigen Nachrichten die ich bekomme Mousemove-, Mouseclick-, NcHittest-, Paint- und Windowactivate-Nachrichten.

    Also nichts, das man zuverlässig zum Ansteuern des Programms verwenden kann.
    Hat jemand eine Idee wie ich an die Nachrichten komme die ich senden muss um die Aktionen auszulösen?

    Leider verfügt das Programm über keinerlei Shortcuts die man über Tastatur eingeben könnte.

    Ich will nicht die einzelnen Schaltflächen über OCR suchen müssen um mich dann über Maus-Ereignisse durchzuklicken.


  • Mod

    Auch Ribbons verwenden WM_COMMAND Codes. Zumindest alle Implementierungen die nicht auf .NET basieren.

    Insofern kannst Du auch dort mit dem Spy++ den WM_COMMAND Code ermitteln.



  • Leider kommen beim Interagieren mit dem Menü keine WM_COMMAND Nachricht.
    Die einzigen Nachrichten die ich bekomme sind Mousemove-, Mouseclick-, NcHittest-, Paint- und Windowactivate-Nachrichten wenn ich mich durch das Menü klicke.

    Das ist es ja was mich zum Verzweifeln bringt.

    Kann es daran liegen dass ich noch mit Visual Studio 2005 arbeite?


  • Mod

    Nö. Sag mal lieber um welches Programm es geht.



  • Entschuldigung das ich mich so spät melde.

    Es handelt sich um CadManB (Version 8.0)
    Es ist eine Programmiersoftware für eine CNC-Abkantpresse von LVD und ein Bugfest vor dem Herrn.



  • Eine kleine Rückmeldung meinerseits.

    Wie es aussieht arbeitet jedes Ribon-Element wie ein eigenes Programmfenster, das über einen anderen Weg als über das Nachrichtensystem mit dem Hauptprogramm komuniziert.

    Ich habe es jetzt so gelöst, dass ich die aktuelle Mausposition zwischenspeichere, die Maus programmgesteuert durch die Gegend fahre & klicke und dann wieder auf die Ursprungsposition zurückstelle.

    Das ist zwar nicht sauber, aber es funktioniert.

    Ein kleines Beispiel:

    .
    .
    .
    // Zuerst das Fenster recursiv im Fensterbaum suchen
    CSearchWnd cSearch;
    CWnd* cWnd = cSearch.Recurse(	FindWindow(_T("Klassenname des Haupt-Programmfensters"),NULL),
    								_T("Name des Ribonelements"),
    								CSearchWnd::enSuchartFenstername);
    if(cWnd == NULL)
    {
    	MessageBox(	_T("Das Eingabeelement konnte nicht gefunden werden."),
    				DEF_UEBERSCHRIFT_MESSAGEBOX,
    				MB_ICONEXCLAMATION);
    	return -1;
    }
    
    CPoint cCursorPointOld;
    // Zielposition relativ zum Ribonelement
    CPoint cCursorPointNew(DEF_POS_RIBON_NAECHSTE_LOESUNG_X,DEF_POS_RIBON_NAECHSTE_LOESUNG_Y);
    // Alte Mausposition sichern
    if(!GetCursorPos(&cCursorPointOld))
    {
    	MessageBox(	_T("Fehler beim Ermitteln der Mausposition."),
    				DEF_UEBERSCHRIFT_MESSAGEBOX,
    				MB_ICONEXCLAMATION);
    	return -2;
    }
    
    // Neue Mausposition ermitteln 
    cWnd->ClientToScreen(&cCursorPointNew);
    
    // Maus auf die gewünschte Position bewegen
    if(!SetCursorPos(cCursorPointNew.x,cCursorPointNew.y))
    {
    	MessageBox(	_T("Fehler beim Setzen der Mausposition."),
    				DEF_UEBERSCHRIFT_MESSAGEBOX,
    				MB_ICONEXCLAMATION);
    	return -3;
    }
    //Einal klicken
    mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);  
    mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
    
    // Und wieder zurück
    if(!SetCursorPos(cCursorPointOld.x,cCursorPointOld.y))
    {
    	MessageBox(	_T("Fehler beim Zurücksetzen der Mausposition."),
    				DEF_UEBERSCHRIFT_MESSAGEBOX,
    				MB_ICONEXCLAMATION);
    	return -4;
    }
    
    return 1;
    

Log in to reply