Autor Beitrag
snoopyonline
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 38



BeitragVerfasst: Mo 15.08.05 21:48 
Ich habe das ganze Forum nach allen möglichen Vorkommen von Postmessage und Sendmessage durchsucht aber nirgendwo herausfinden können warum meine Versuche scheitern, bzw. wie mans eigentlich macht:

Ich versuche verzweifelt, beim Internet-Explorer-Download Fenster den Speichern-Button auszulösen.
Es klappt zwar, mit folgendem Code ein "Return/Enter" zu senden:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
procedure TForm1.Timer1Timer(Sender: TObject);
var hwindow: hwnd;

begin
hwindow := FindWindow(nil,pchar('Dateidownload'));
if hwindow <> 0 then
try postMessage(hWindow, WM_KEYDOWN,VK_Return,0except end;
end;


Das löst zwar den "Speichern"-Button aus - allerdings in ca 5% der Fälle gleich anschließend auch den "Abbrechen"-Knopf während des gestarteten Downloads...
Leider kann man die beiden unterschiedlichen Fenster vor und während des downloads nicht unterscheiden, da beide Fenster den gleichen Titel tragen.

Die Lösung wäre also, mit dem senden von "S" den Speichern-Knopf zu drücken, doch egal wie ichs probiere - nichts bewegt sich...

--> postMessage(hWindow, WM_KEYDOWN,VK_Return,0)

Ich habe statt VK-Return schon alles mögliche probiert:
83 als Tastencode für S
53 als Tastencode für S laut der MSDN-VirtualKey-Liste
ord('s')

und nichts klappt.

Was mache ich falsch?????

Moderiert von user profile iconmatze: Code- durch Delphi-Tags ersetzt.
Moderiert von user profile iconChristian S.: Topic aus CLX / Delphi Language (Object-Pascal) verschoben am Mi 17.08.2005 um 12:50
Logikmensch
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 390

Win XP
Delphi 2007 Prof., XE2, XE5
BeitragVerfasst: Di 16.08.05 06:32 
Titel: Taste auch wieder loslassen...
Hallo,

ich kenne Dein Problem - habe selber schon sowas ähnliches versucht.
Ist aber schon 'ne Weile her. Aber weißt Du, es genügt eben nicht, die Taste nur zu drücken, sie muss auch wieder losgelassen werden. Schicke noch eine entsprechende Botschaft hinterher, wahrscheinlich läuft's dann...

Liebe Grüße,

Claus.
Harry M.
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 754

Win 2000, XP
D2005
BeitragVerfasst: Di 16.08.05 08:43 
Naja ein Problem war das ja nicht hat ganze 2 Min gedauert :lol:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
procedure PressKeyDown(ZEICHEN: Char; GROSS: Boolean);
begin
  if GROSS then keybd_event(VK_SHIFT, MapVirtualKey(VK_SHIFT, 0), 00);
  keybd_event(Ord(UpCase(ZEICHEN)), MapVirtualKey(Ord(UpCase(ZEICHEN)), 0), 00);
end;
////////////////////////////////////////////////////////////////////////////////
procedure PressKeyUp(ZEICHEN: Char; GROSS: Boolean);
begin
  keybd_event(Ord(UpCase(ZEICHEN)), MapVirtualKey(Ord(UpCase(ZEICHEN)), 0), KEYEVENTF_KEYUP, 0);
  if GROSS then keybd_event(VK_SHIFT, MapVirtualKey(VK_SHIFT, 0), KEYEVENTF_KEYUP, 0);
end;
////////////////////////////////////////////////////////////////////////////////
procedure TForm1.Timer1Timer(Sender: TObject);
var hwindow: hwnd;
begin
  hwindow := FindWindow(nil,pchar('Dateidownload'));
  if hwindow <> 0 then begin
    PressKeyDown(chr(13), FALSE); // Taste drücken
    PressKeyUp(chr(13), FALSE);  // und wieder loslassen -> is wichtig ;-)
    end;
end;

Edit: Die Sache mit dem "S" kann auch nicht gehen. Du musst nämlich Alt+S drücken ;-)

_________________
Gruß Harry
Et spes me per dies sine te ducat et amor me ferat, si dolor spem tollit.
snoopyonline Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 38



BeitragVerfasst: Di 16.08.05 20:43 
@Harry

Also ersteinmal danke für die Antwort... Allerdings war die Lösung des Problems dann doch nicht ganz so einfach.
Das Problem liegt einfach darin, dass die verwendete keybd_event Prozedur die Taste "wild in die Gegend" sendet. Genau das ist aber das was ich nicht gebrauchen kann und sicher genauso schnell hinbekommen hätte ;-)
Mit Postmessage kann man halt genau das gewünschte Fenster ansteuern, was unabdingbar ist, da bei mir das Download-Fenster nicht immer den Focus hat.

Und wieso muß ich ALT+S simulieren, wenn doch 'S' als realer Tastendruck normalerweise ausreicht? Aber wenn es so klappen könnte wärs ja gut - nur weiß ich leider noch weniger wie ich ALT+S mit dem Postmessage kombinieren kann.

@Logikmensch

Also ich habe sämtliche meiner im 1. Thread beschriebenen Varianten mit "Keydown" und anschließendem "Keyup" im Postmessage durchprobiert - immer mit dem gleichen unzureichenden Ergebnis


Zuletzt bearbeitet von snoopyonline am Di 16.08.05 20:46, insgesamt 1-mal bearbeitet
Harry M.
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 754

Win 2000, XP
D2005
BeitragVerfasst: Di 16.08.05 20:46 
Also das Beispiel wie ich es oben gepostet habe, hat bei mir gefuntz. Sonst hätte ich es nicht gepostet. Wenn ich heute abend noch Zeit finde poste ich noch wie es mit PostMessage geht. Bin nur grad busy.

_________________
Gruß Harry
Et spes me per dies sine te ducat et amor me ferat, si dolor spem tollit.
snoopyonline Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 38



BeitragVerfasst: Di 16.08.05 20:51 
@Harry

Bitte glaub nicht einen Vorwurf aus meinem letzten Posting herauszuhören... Hab den augenzwinkernden Smiley halt nicht dick genug hinbekommen...

Und prinzipiell funktioniert dein Code ja auch - nur leider auch dann wenn man gerade im falschen Fenster arbeitet und dann entsprechend die "S" oder Enter-Taste ungefragt dazwischengeknallt bekommt...

Ich könnte mich ja auch mit meiner bisherigen 95% Trefferquote zufrieden geben - aber irgendwie glaube ich geht das hier im Forum allen so - man kann dort einfach nicht aufhören
Harry M.
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 754

Win 2000, XP
D2005
BeitragVerfasst: Di 16.08.05 20:55 
Warum machst Du es überhaupt so kompliziert und lädst die File nicht mit den Indys runter? Einfacher und komfortabler gehst nicht.

_________________
Gruß Harry
Et spes me per dies sine te ducat et amor me ferat, si dolor spem tollit.
snoopyonline Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 38



BeitragVerfasst: Di 16.08.05 21:19 
@Harry:

Einfach runterladen - egal ob mit Indy, Downloadtofile oder Delphi-Downloadmanager-Komponenten scheitert daran, dass die Programmierer der betreffenden Webseite dies (anscheinend sehr effektiv) unterbunden haben. Man kann nur eine Pseudo-Webadresse mit dem Browser annavigieren, wodurch der Download dann gestartet und die tatsächliche Datei-URL erst "mitgeteilt" wird... Es funktioniert also irgendwie nur der Download per Browser-Downloadfenster. Und alle Versuche diesen abzufangen und die Url zubekommen sind noch mehr im Sande verlaufen....

P.S.(1): Selbst technisch ausgereifte, professionelle Downloadmanager beißen sich daran irgendwie die Zähne aus...
P.S.(2): Um irgendwelchen Fragen/Vorwürfen zuvorzukommen: ich bin ordentlich angemeldeter User der betreffenden Seite und versuche nichts illegales sondern bin einfach zu faul und zu ehrgeizig um ständig selbst zu klicken...
P.S.(3): Ok - mit dem Ehrgeiz ist das so ne Sache - wie man sieht schaff ichs ja doch nicht ganz alleine ;-)
Harry M.
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 754

Win 2000, XP
D2005
BeitragVerfasst: Mi 17.08.05 00:27 
Ich bin zwar jetzt nicht sicher ob es in Deinem konkreten Fall funtz aber versuch das mal:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
procedure TForm1.Timer1Timer(Sender: TObject);
var hWindow: hwnd;
begin
  hwindow := FindWindow(nil, PChar('Dateidownload'));
  if hWindow <> 0 then begin
    PostMessage(hWindow, WM_KEYDOWN, VK_RETURN, 0);
    PostMessage(hWindow, WM_KEYUP, VK_RETURN, 0);

    hwindow := FindWindow(nil, PChar('Datei speichern unter'));
    if hWindow <> 0 then begin
      PostMessage(hWindow, WM_KEYDOWN, VK_RETURN, 0);
      PostMessage(hWindow, WM_KEYUP, VK_RETURN, 0);
      end;
    end;
end;

Problem gab es bei mir nur, wenn die Datei schon existiert.

_________________
Gruß Harry
Et spes me per dies sine te ducat et amor me ferat, si dolor spem tollit.
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Mi 17.08.05 06:45 
Irgendwie ziemlich grausam, was ihr da macht. Irgendwelchen obskuren Tasten wild durch die Gegend schicken und auf gut Glück irgendwelche Returns an Dialoge schicken. Da kann man nur beten, dass da kein "Datei löschen"-Dialog versehentlich aufgegangen ist. :roll:

Wenn man einen Schaltfläche anklickt, dann sendet Windows an das Parent eine WM_COMMAND Nachricht mit dem Notificationcode (hier BN_CLICKED) und der ID des Kontrols. Die ID ist immer gleich, nicht zu verwechseln mit dem Handle, und dient dazu, dass der Programmierer die Kontrols besser unterscheiden kann, wenn er so clever ist und welche vergibt. Rausfinden kann man diese IDs entweder mit dem Spy++ vom VC oder WinSpy von Delphi oder mit dem Programm WindowInfo von mir. In der Fensterprozedur des Parents sieht das dann so aus:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
function dlgfunc(hDlg: hWnd; uMsg: dword; wParam: wParam; lParam: lParam): bool;
  stdcall;
begin
  result := true;
  case uMsg of
    WM_...:  ;
    WM_...:  ;
    // WM_COMMAND Nachricht
    WM_COMMAND:
      begin
        // Notificationcode
        if hiword(wParam) = BN_CLICKED then
        begin
          case LoWord(wParam) of
            // ID des Kontrols
            IDC_BTN_CLOSE: SendMessage(hDlg, WM_CLOSE, 00);
          end;
        end;
      end
  else
    result := false;
  end;
end;

IDC_BTN_CLOSE ist nur eine benannte Konstante. Hat hier zum Beispiel den Wert 103 oder so. Bei uns hat sie einmal 4420 für die "Speichern"-Schaltfläche auf dem Download-Dialog und einmal 1 auf dem "Datei speichern unter"-Dialog.
Schicken wir die Nachricht BM_CLICK an die Schaltfläche lösen wir genau das aus:
Zitat:

An application sends a BM_CLICK message to simulate the user clicking a button. [..] ...and the button's parent window to receive a BN_CLICKED notification message.

Dazu suchen wir uns erst das jeweilige Parent mit FindWindow und dann holen wir uns das Handle der Schaltfläche über die Kontrol ID mit der API Funktion GetDlgItem.

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
procedure TForm1.Button1Click(Sender: TObject);
var
  hDlg                   : THandle;
  hBtn                   : THandle;
begin
  // Download-Dialog
  hDlg := FindWindow(nil'Dateidownload');
  if hDlg <> 0 then
  begin
    // Speichern-Schlatfläche auf Download-Dialog
    // ID ist immer die gleiche
    hBtn := GetDlgItem(hDlg, 4420);
    if hBtn <> 0 then
    begin
      // "Speichern" drücken
      // Warum zweimal? Keine Ahnung.
      SendMessage(hBtn, BM_CLICK, 00);
      SendMessage(hBtn, BM_CLICK, 00);
      Sleep(2000);
      // "Datei speichern unter"-Dialog
      hDlg := FindWindow(nil'Datei speichern unter');
      if hDlg <> 0 then
      begin
        // Speichern-Schaltfläche auf "Datei speichern Dialog"
        // ID ist immer die gleiche
        hBtn := GetDlgItem(hDlg, 1);
        if hBtn <> 0 then
        begin
          SendMessage(hBtn, BM_CLICK, 00);
        end;
      end;
    end;
  end;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
var
  hDlg                   : THandle;
  hBtn                   : THandle;
begin
  // Download-Dialog
  hDlg := FindWindow(nil'Dateidownload');
  if hDlg <> 0 then
  begin
    // Speichern-Schaltfläche auf Download-Dialog
    // ID ist immer die gleiche
    hBtn := GetDlgItem(hDlg, 4420);
    if hBtn <> 0 then
    begin
      // "Speichern" drücken
      // Warum zweimal? Keine Ahnung.
      SendMessage(hBtn, BM_CLICK, 00);
      SendMessage(hBtn, BM_CLICK, 00);
      Sleep(2000);
      // "Datei speichern unter"-Dialog
      hDlg := FindWindow(nil'Datei speichern unter');
      if hDlg <> 0 then
      begin
        // Speichern-Schaltfläche auf "Datei speichern unter"-Dialog
        // ID ist immer die gleiche
        hBtn := GetDlgItem(hDlg, 1);
        if hBtn <> 0 then
        begin
          SendMessage(hBtn, BM_CLICK, 00);
        end;
      end;
    end;
  end;
end;

Einmal mit Schaltfläche und einmal mit Timer. Und das mit dem Timer geht auch, wenn das Programmfesnetr im Hintergrund ist bzw. das Downloadfenster, also eigentlich sollte es immer gehen.

@Harry M: Als Systemprogrammierer sollte man eigentlich solche grundlegenden Mechanismen kennen wie Windows funktioniert. ;)
Harry M.
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 754

Win 2000, XP
D2005
BeitragVerfasst: Mi 17.08.05 06:51 
user profile iconLuckie hat folgendes geschrieben:
Irgendwie ziemlich grausam, was ihr da macht. Nix mit irgendwelchen obskuren Tasten wild durch die Gegend schicken und auf gut Glück irgendwelche Returns an Dialoge schicken. Da kann man nur beten, dass da kein "Datei löschen"-Dialog versehentlich aufgegangen ist. :roll:

Datei-Lösch-Dialog bei "Speichern unter..." :gruebel:

user profile iconLuckie hat folgendes geschrieben:

@Harry M: Als Systemprogrammierer sollte man eigentlich solche grundlegenden Mechanismen kennen wie Windows funktioniert. ;)


Systemprogrammierer - hört sich zwar net an aber bleiben wir doch mal beim Hobby. Vielleicht komme ich da mal hin. :lol:

_________________
Gruß Harry
Et spes me per dies sine te ducat et amor me ferat, si dolor spem tollit.
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Mi 17.08.05 06:55 
user profile iconHarry M. hat folgendes geschrieben:
user profile iconLuckie hat folgendes geschrieben:
Irgendwie ziemlich grausam, was ihr da macht. Nix mit irgendwelchen obskuren Tasten wild durch die Gegend schicken und auf gut Glück irgendwelche Returns an Dialoge schicken. Da kann man nur beten, dass da kein "Datei löschen"-Dialog versehentlich aufgegangen ist. :roll:

Datei-Lösch-Dialog bei "Speichern unter..." :gruebel:

Jupp, wenn man zum Beispiel versehentlich auf "Datei löschen" klickt, der Dialog zum Löschen geht auf und du schickst gerade ein Return wild durch die Gegend.


Zitat:

Systemprogrammierer - hört sich zwar net an aber bleiben wir doch mal beim Hobby. Vielleicht komme ich da mal hin.

Hm, den Eindruck versuchst du aber irgendwie immer zu erwecken. Ich erinnere dich mal an die Aussage mit dem besseren Usermanager. ;)
Harry M.
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 754

Win 2000, XP
D2005
BeitragVerfasst: Mi 17.08.05 06:59 
Was den besseren UserMgr angeht. Das soll es gar nicht werden. Ist nur eines von vielen Features. Und warte ab... Ende diesen Jahres / Anfang Nächsten's :wink: :lol:

_________________
Gruß Harry
Et spes me per dies sine te ducat et amor me ferat, si dolor spem tollit.
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Mi 17.08.05 07:04 
In sechs Monaten? Viel Glück.
Harry M.
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 754

Win 2000, XP
D2005
BeitragVerfasst: Mi 17.08.05 07:05 
Thx. Das werd ich brauchen :lol:

_________________
Gruß Harry
Et spes me per dies sine te ducat et amor me ferat, si dolor spem tollit.
snoopyonline Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 38



BeitragVerfasst: Mi 17.08.05 20:30 
@Luckie:

Funktioniert wunderbar und ist zudem anscheinend auch noch "sauberstes" Delphi - da muß ich wohl mal den ganzen Quellcode posten, damit mir den auch gleich noch jemand so perfekt überarbeitet :-)
Na gut - Scherz beiseite: Das mit dem Knöpfendrücken über die Button-ID geht super. Allerdings würde mich dann am Rande doch interessieren, wie man die IDs der einzelnen Buttons auch bei anderen Fenstern herausbekommen kann. Gibts da irgendne funktion für?

Aber wenns zuviel Mühe machen würde ist es auch nicht ganz so wild - wer weiß ob man das jemals wieder braucht...
Ihr habt mir ja schon enorm weitergeholfen - THX an alle Beteiligten...
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Do 18.08.05 00:52 
Habe ich dir doch geschrieben:
Zitat:

Rausfinden kann man diese IDs entweder mit dem Spy++ vom VC oder WinSpy von Delphi oder mit dem Programm WindowInfo von mir.

WindowInfo findest du hier: www.luckie-online.de...per/Delphi/Programme