Autor Beitrag
netspy
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 75



BeitragVerfasst: Mo 13.03.06 01:07 
In meinem Wörterbuch biete ich die Funktion an, das Programm über einen HotKey aufzurufen. Wenn in der gerade aktiven Anwendung ein Text markiert ist, soll diese gleich automatisch mit über die Zwischenablage übernommen und übersetzt werden. Vereinfacht sieht der Code jetzt so aus:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
WindowHandle := ... // Handle des aktiven Fenster ermitteln

Sleep(200);

// da HotKey standardmäßig Alt+F12 ist
Keybd_Event(VK_MENU, 0, KEYEVENTF_KEYUP, 0);

// Strg+Einfg drücken
Keybd_Event(VK_CONTROL, 000);
Keybd_Event(VK_INSERT, 000);

Sleep(50);

// Strg+Einfg loslassen
Keybd_Event(VK_INSERT, 0, KEYEVENTF_KEYUP, 0);
Keybd_Event(VK_CONTROL, 0, KEYEVENTF_KEYUP, 0);

Sleep(50);


Das Problem ist, dass dass nicht immer funktioniert. Offensichtlich gibt es da ein Timingproblem, dass manchmal Tastendrücke in der Anwendung noch nicht richtig verarbeitet sind. Deshalb habe ich auch einige sleep() eingebaut, die zwar helfen, jedoch nicht immer.

Versuche mit PostMessage(WindowHandle, WM_COPY, 0, 0); oder ähnlichen bringen keine Besserung.

Irgendwelche Vorschläge, wie ich das verbessern kann, so dass das in den meisten Fällen funktioniert?
Peter Wolf
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 37

WinXP Pro
Delphi7 Ent.
BeitragVerfasst: Mo 13.03.06 13:43 
Hallo netspy,

wie Du schon richtig erkannt hast, handelt es sich um ein Timingproblem. Also dann löse es doch auch mit einem Timer.

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
begin
   ...
   //Du hast Deinen Hotkey erkannt, mach nun Timer "scharf"
   Timer1.Intervall:= 1000;
   Timer1.enabled:= true;
   ...
end;

procedure TForm1.Timer1Timer(blabla);
begin
   //Setze hier nun den Code rein, der das markierte in die ZA kopiert
end;


Grüße Peter
netspy Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 75



BeitragVerfasst: Mo 13.03.06 14:13 
user profile iconPeter Wolf hat folgendes geschrieben:
wie Du schon richtig erkannt hast, handelt es sich um ein Timingproblem. Also dann löse es doch auch mit einem Timer.

Nicht jedes Timing-Problem lässt sich mit einem Timer lösen. :wink:

In dem Fall nützt mir das leider gar nichts, da das Timing-Problem ja beim Senden der Tasten und der Reaktion der fremden Anwendung liegt. Ich bräuchte also eine Bestätigung der Anwendung, dass die Tastendrücke verarbeitet wurden.
Peter Wolf
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 37

WinXP Pro
Delphi7 Ent.
BeitragVerfasst: Mo 13.03.06 14:40 
Hallo Netspy,

Also ich würde sagen, dass Dir das schon etwas nützt.

Der User markiert in irgendeiner anderen Anwendung einen Text.
Mittels Hotkey z.B. STRG+U ruft der User Deine Anwendung aus der fremden Anwendung heraus auf.
Nun kommt der Timer.
Beim Ereignis OnTimer simulierst Du STRG+C und liest die Zwischenablage aus, das Wort wird übersetzt oder was auch immer, und dann schiebst Du das übersetzte Wort wieder zurück in die Zwischenablage.
Oder hab ich Dein Problem ganz falsch verstanden?

Hatte auch mal ein ähnliches Problem, deswegen habe ich es damit gelöst. Zusätzlich habe ich in dem OnTimer-Ereignis
das kopieren wie folgt gemacht.
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
    keybd_event(17000);
    sleep(20);
    keybd_event(67000);
    sleep(100);
    keybd_event(670, KEYEVENTF_KEYUP, 0);
    sleep(20);
    keybd_event(170, KEYEVENTF_KEYUP, 0); 
    keybd_event(170, KEYEVENTF_KEYUP, 0); //Dieses doppelte CTRL-UP ist bewusst hier, da bei meiner Anwendung  
                                            //sonst Windows immer noch CTRL als gedrückt erkannt hatte
    sleep(20);
    Application.ProcessMessages;
    DeinWort:= GetStrFromClipbrd;


Grüße Peter
netspy Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 75



BeitragVerfasst: Mo 13.03.06 14:59 
Hallo Peter,

user profile iconPeter Wolf hat folgendes geschrieben:
Also ich würde sagen, dass Dir das schon etwas nützt.

Leider nicht wirklich. Ob ich die Ausführung mit Sleep oder einem Timer verzögere, ist Jacke wie Hose. Das eigentliche Problem kommt ja auch erst beim Senden der Tasten. In deinem Quellcode hast du da ja auch einige Sleeps eingebaut und im Kommentar sprichst du von einem Problem mit deinem Windows. Genau da ist auch der Haken, bei meinem Windows funktioniert es mit den Verzögerungen auch in 99% der Fälle. Andere Nutzer berichten mir aber, dass es bei ihnen seltener oder fast nie klappt. Das scheint von Windows zu Windows, Anwendung zu Anwendung und Rechner zu Rechner unterschiedlich zu sein, abhängig auch noch von der Rechenleistung und den jeweils noch laufenden Anwendungen.

Deshalb suche ich eine Variante, die ohne sleep() oder Timer auskommt und immer funktioniert. Wie ich schon schrieb, bräuchte ich also igrendeine Bestätigung, dass der Tastendruck auch in der Anwendung angekommen und verarbeitet wurde.