Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi Kontextmenü einer anderen Anwendung aufrufen (https://www.delphipraxis.net/79803-kontextmenue-einer-anderen-anwendung-aufrufen.html)

nezumi 28. Okt 2006 21:10


Kontextmenü einer anderen Anwendung aufrufen
 
Nabend allerseits,

In einem Programm erscheint ein Kontextmenü, wenn man innerhalb eines bestimmten Fensters im Programm rechts klickt. Dann kann man verschiedenes auswählen, unter anderem "alles markieren".

Dies möchte ich gerne durch ein Delphi-Programm erledigen lassen. Kann mir jemand einen Tipp geben, wie man das macht?

(Wie man das andere Programm aufruft usw, weiß ich. Es geht mir nur darum, wie man auf das Kontextmenü des Programms zugreift und dort was auswählt)

Gruß,

mkinzler 28. Okt 2006 21:13

Re: Kontextmenü einer anderen Anwendung aufrufen
 
Sende dem Fenster doch nen Rechtsklick.

nezumi 28. Okt 2006 21:17

Re: Kontextmenü einer anderen Anwendung aufrufen
 
Hallo mkinzler,

danke für die schnelle Antwort. Hört sich jetzt blöd an, aber wie sende ich dem Fenster ein Rechtsklick?

Was mir aber noch schleierhafter ist: Wie kann ich dann aus dem Kontextmenü etwas auswählen?

Gruß,

DocE 28. Okt 2006 21:21

Re: Kontextmenü einer anderen Anwendung aufrufen
 
N'Abend nezumi,

wenn es z.B. um sowas wie "Alles markieren" geht, würde ich den Tastaturbefehl STRG+A senden (ist einfacher)...

Oder geht es Dir darum, wie das allgemein geht?

Grüsse
...Doc

nezumi 28. Okt 2006 21:27

Re: Kontextmenü einer anderen Anwendung aufrufen
 
Hallo DocE,

Gute Idee, wenn ich es anders nicht hinbekomme, werde ich es so versuchen. Das Problem ist nur, dass mir mit Strg+A viel zu viel markiert wird. Wenn ich rechts klicke und dann "alles markieren" auswähle, markiert er mir genau das was ich haben will.

(Außerdem würde ich auch gerne mal kapieren, wie das grundsätzlich geht...)

Gruß,

mkinzler 28. Okt 2006 21:30

Re: Kontextmenü einer anderen Anwendung aufrufen
 
Gibt es für "Alles markieren" im Kontextmenü auch einen Shortcut?

nezumi 28. Okt 2006 21:37

Re: Kontextmenü einer anderen Anwendung aufrufen
 
Zitat:

Zitat von mkinzler
Gibt es für "Alles markieren" im Kontextmenü auch einen Shortcut?

Nein, leider nicht... :(

nezumi 29. Okt 2006 08:26

Re: Kontextmenü einer anderen Anwendung aufrufen
 
Hi all,

da das scheinbar schwierig ist mit dem Kontextmenü (habs die halbe Nacht erfolglos versucht), wollte ich es so machen, dass einfach alles markiert wird. Aber auch das klappt nicht.

Um dem Fehler auf den Grund zu gehen, habe ich ein einfaches Prog geschrieben, welches in ein geöffnetes Notepad die Buchstaben "ABC" reinschreibt und dann alles markiert.

Delphi-Quellcode:
 
procedure TForm1.Button6Click(Sender: TObject);
var
  wnd, wnd2 : HWND;
  i  : Integer;
  s  : string;
begin
  wnd := FindWindow('notepad',nil);
  if wnd <> 0 then begin
    wnd2 := FindWindowEx(wnd,0,'Edit',nil);
    s := 'ABC';
    For i := 1 to Length(s) do begin
    SendMessage(wnd2, WM_CHAR, Word(s[i]), 0) end;
    BringWindowToTop(wnd);

    SendMessage(wnd2, WM_KEYDOWN, VK_CONTROL , 0);
    SendMessage(wnd2, WM_KEYDOWN, Ord('A'), 0);
    SendMessage(wnd2, WM_KEYUP, Ord('A'), 0);
    SendMessage(wnd2, WM_KEYUP, VK_CONTROL, 0);

  end;
end;
Das Reinschreiben der Buchstaben klappt, aber markiert wird nichts. Was mach ich falsch? Wie sendet man ein "Strg+A" an eine andere Anwendung?

Gruß,

EWeiss 29. Okt 2006 08:43

Re: Kontextmenü einer anderen Anwendung aufrufen
 
Zitat:

Zitat von nezumi
Hi all,

da das scheinbar schwierig ist mit dem Kontextmenü (habs die halbe Nacht erfolglos versucht), wollte ich es so machen, dass einfach alles markiert wird. Aber auch das klappt nicht.

Um dem Fehler auf den Grund zu gehen, habe ich ein einfaches Prog geschrieben, welches in ein geöffnetes Notepad die Buchstaben "ABC" reinschreibt und dann alles markiert.

Delphi-Quellcode:
 
procedure TForm1.Button6Click(Sender: TObject);
var
  wnd, wnd2 : HWND;
  i  : Integer;
  s  : string;
begin
  wnd := FindWindow('notepad',nil);
  if wnd <> 0 then begin
    wnd2 := FindWindowEx(wnd,0,'Edit',nil);
    s := 'ABC';
    For i := 1 to Length(s) do begin
    SendMessage(wnd2, WM_CHAR, Word(s[i]), 0) end;
    BringWindowToTop(wnd);

    SendMessage(wnd2, WM_KEYDOWN, VK_CONTROL , 0);
    SendMessage(wnd2, WM_KEYDOWN, Ord('A'), 0);
    SendMessage(wnd2, WM_KEYUP, Ord('A'), 0);
    SendMessage(wnd2, WM_KEYUP, VK_CONTROL, 0);

  end;
end;
Das Reinschreiben der Buchstaben klappt, aber markiert wird nichts. Was mach ich falsch? Wie sendet man ein "Strg+A" an eine andere Anwendung?

Gruß,

1. Du kannst dir die Schleife sparen wenn du die API CopyMemory verwendest und den String komplett sendest.
2. Du mußt die Applikation erst aktivieren
3. Dann mit Sendkeys (STRG+A) den ganzen Text auswählen.

gruß

nezumi 29. Okt 2006 08:51

Re: Kontextmenü einer anderen Anwendung aufrufen
 
Hallo Emil,

vielen Dank für Deine Antwort. Leider versteh ich nur Bahnhof...

Könntest Du das bitte etwas genauer beschreiben oder vielleicht ein Code-Beispiel schreiben (insbes. zu Punkt 2 und 3)? Würde mir sehr helfen...

Thanx,

EWeiss 29. Okt 2006 09:12

Re: Kontextmenü einer anderen Anwendung aufrufen
 
Zitat:

Zitat von nezumi
Hallo Emil,

vielen Dank für Deine Antwort. Leider versteh ich nur Bahnhof...

Könntest Du das bitte etwas genauer beschreiben oder vielleicht ein Code-Beispiel schreiben (insbes. zu Punkt 2 und 3)? Würde mir sehr helfen...

Thanx,

2. Sendmessage .... WM_ACTIVATE
3. Hier im Forum suchenSendkeys (ALT) aktiviert/Deaktiviert die Shortcuts (B) aktiviert das 2 Hauptmenü, (STRG+A) wählt alles aus wenn die vorherigen sendkeys ausgeführt wurden.

EDIT:
Weiss nicht was du vorhast ?
Solltest du lediglich den Text aus der anderen Anwendung benötigen dann geht das auch über WM_GETTEXT
Dafür benötigst du aber das HAndle des Controls welche den Text enthält.
Dann mußt du nichts makieren.

Senden kannst du ihn dann über sendmessage in verbindung mit WM_SETTEXT in deine eigene Anwendung
Textbox oder was auch immer.

Gruß

EWeiss 29. Okt 2006 13:29

Re: Kontextmenü einer anderen Anwendung aufrufen
 
Hier mal ein Beispiel wie man Text aus einer anderen Anwendung ohne
Kontexmenü bekommen kann.

Delphi-Quellcode:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, StdCtrls;

type
  TForm1 = class(TForm)
    Timer1: TTimer;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    Label4: TLabel;
    Label5: TLabel;
    Label6: TLabel;
    Edit1: TEdit;
    Label7: TLabel;
    Edit2: TEdit;
    RadioButton1: TRadioButton;
    RadioButton2: TRadioButton;
    procedure Timer1Timer(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

function LeftStr(Const Str: String; Size: Word): String;
begin
  Result := Copy(Str, 1, Size)
end;

function InStr(Start: integer; Source: string; SourceToFind: string): integer;
begin
  Result := pos(SourceToFind, copy(Source, Start, Length(Source) - (Start - 1)));
end;

procedure TForm1.Timer1Timer(Sender: TObject);
const
  MAX_BUFFER = 32767;

Var
 Res   : Integer;
 Handle : HWND;
 Parent : HWND;
 Pt    : TPOINT;
 Buffer : String;
 Klasse : String;

begin

    if GetCursorPos(Pt) then
    begin
      Handle := WindowFromPoint(Pt);
      Parent := GetParent(Handle);
                 SetLength(Klasse, 128);
      Res    := GetClassName(Handle, PChar(Klasse), 128);
      Klasse := LeftStr(Klasse, Res);

      Label2.Caption := IntToStr(Handle);
      Label4.Caption := IntToStr(Parent);
      Label6.Caption := Klasse;

      If (InStr(1, Klasse, 'Edit') <> 0) Or (InStr(1, Klasse, 'text') <> 0) Then
        begin
          If RadioButton1.Checked = True Then
            begin
                          SetLength(Buffer, MAX_BUFFER);
            Res       := SendMessage(Handle, WM_GETTEXT, Length(Buffer), Integer(PChar(Buffer)));
            Edit1.Text := LeftStr(Buffer, Res);
            end Else
            SendMessage(Handle, WM_SETTEXT, 0, Integer(Edit1.Text));
        end;
    end;
end;

end.
Gruß

nezumi 30. Okt 2006 20:38

Re: Kontextmenü einer anderen Anwendung aufrufen
 
Super, danke!

Ich habs jetzt mit einer Kombination Deiner Tipps hinbekommen.

Blöderweise muss ich zum Abschluss noch F9 drücken. Ich hab das probiert mit

Delphi-Quellcode:
SendKeys('F9', true);
//bzw
SendKeys((F9), true);
//bzw
SendKeys($78, true);
//bzw
SendMessage(wnd2, WM_KEYDOWN, VK_F9, 0);
Leider funktioniert keine dieser Möglichkeiten (die unit sndkey32 ist installiert).
Warum geht das nicht??

Gruß,

EWeiss 30. Okt 2006 21:38

Re: Kontextmenü einer anderen Anwendung aufrufen
 
Zitat:

Zitat von nezumi
Super, danke!

Ich habs jetzt mit einer Kombination Deiner Tipps hinbekommen.

Blöderweise muss ich zum Abschluss noch F9 drücken. Ich hab das probiert mit

Delphi-Quellcode:
SendKeys('F9', true);
//bzw
SendKeys((F9), true);
//bzw
SendKeys($78, true);
//bzw
SendMessage(wnd2, WM_KEYDOWN, VK_F9, 0);
Leider funktioniert keine dieser Möglichkeiten (die unit sndkey32 ist installiert).
Warum geht das nicht??

Gruß,

Bin gerade dabei ein Sample zu schreiben mit dem man von jeden xbeliebigen Fenster welches geöffnet ist
das Systemmenü und Standardmenü aufrufen und aus der anwendung steuern kann ..jeden einzelnen MenüPunkt.
Damit kann man auch einträge aus dem SystemMenü (beliebige) zu seiner anwendung hinzufügen.


Dauert aber noch etwas :(

gruß

nezumi 31. Okt 2006 09:33

Re: Kontextmenü einer anderen Anwendung aufrufen
 
[quote="EWeiss"]
Zitat:

Zitat von nezumi
Super, danke!

Bin gerade dabei ein Sample zu schreiben mit dem man von jeden xbeliebigen Fenster welches geöffnet ist
das Systemmenü und Standardmenü aufrufen und aus der anwendung steuern kann ..jeden einzelnen MenüPunkt.
Damit kann man auch einträge aus dem SystemMenü (beliebige) zu seiner anwendung hinzufügen.

Dauert aber noch etwas :(

gruß

Cool, das interessiert mich! Wann ist es denn fertig.... :roll: ?

Mein Prob hab ich jetzt gelöst. Es ging nur mit
Delphi-Quellcode:
keybd_event(VK_F9, 0, 0, 0);
Thanx all!


Alle Zeitangaben in WEZ +1. Es ist jetzt 22:30 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz