Einzelnen Beitrag anzeigen

musicman56
(Gast)

n/a Beiträge
 
#1

Button in einer fremden Anwendung aktivieren

  Alt 18. Okt 2013, 17:07
Hallo API-Spezialisten,

ich möchte von meinem Programm aus die Windows-Wählhilfe starten und in das Eingabefeld die Telefonnummer schreiben. Das klappt auch wunderbar. Das Problem ist, der Button [Wählen] in der Wahlhilfe wird dadurch nicht aktiviert. Erst wenn der User die Telefonnummer im Eingabefeld nochmals ändert, ist der Button aktiviert. Die Abhilfe wäre wohl, dem Button oder dem Eingabefeld eine weitere Message zur Aktivierung zu schicken, aber welche, das ist meine Frage bzw. mein Problem.

Es soll mal eine Konsolen-Anwendung werden, aber zum Testen hab ich erst mal eine Form erstellt.

Delphi-Quellcode:
unit HwpDialer;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

type
  TFrmHwpDialer = class(TForm)
    Nummer: TEdit;
    Label1: TLabel;
    BtnDial: TButton;
    BtnClose: TButton;
    BtnReset: TButton;
    procedure FormCreate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure FormCanResize(Sender: TObject; var NewWidth, NewHeight: Integer;
      var Resize: Boolean);
    procedure BtnDialClick(Sender: TObject);
    procedure BtnCloseClick(Sender: TObject);
    procedure BtnResetClick(Sender: TObject);
  private
    { Private-Deklarationen }
    FAppHandle, FEditHandle, FDialButtonHandle: THandle;
    FHandleList: TStrings;
  public
    { Public-Deklarationen }
    function WindowsDialerStart: boolean;
    function WindowsDialerInit: boolean;
  end;

var
  FrmHwpDialer: TFrmHwpDialer;

implementation

uses ShellAPI;

{$R *.dfm}

resourcestring
  rsWahlhilfeCaption = 'Wählhilfe';
  rsEditClassname = 'Edit';
  rsButtonDialClassName = 'Button';
  rsWahlhilfeExeName = 'Dialer.exe';

function EnumChilds(hwnd: HWND; lParam: LPARAM): BOOL; stdcall;
begin
  Result := True;
  FrmHwpDialer.FHandleList.Add(IntToStr(hwnd));
end;

procedure TFrmHwpDialer.FormCreate(Sender: TObject);
begin
  FHandleList := TStringList.Create;
  BtnDial.Enabled := WindowsDialerInit;
end;

procedure TFrmHwpDialer.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  FHandleList.Free;
end;

procedure TFrmHwpDialer.FormCanResize(Sender: TObject; var NewWidth,
  NewHeight: Integer; var Resize: Boolean);
begin
  Resize := false;
end;

procedure TFrmHwpDialer.BtnCloseClick(Sender: TObject);
begin
  Close;
end;

procedure TFrmHwpDialer.BtnDialClick(Sender: TObject);
begin
  // Hat der User die Wählhilfe beendet...?
  if not WindowsDialerStart then exit;
  // Minimiertes Fenster normal anzeigen
  if IsIconic(FAppHandle) then ShowWindow(FAppHandle, SW_RESTORE);
  // In den Vordergrund
  SetForegroundWindow(FAppHandle);
  // Text an das Editfeld schicken
  SendMessage(FEditHandle,WM_Settext,0,Integer(PChar(Nummer.Text)));
end;

procedure TFrmHwpDialer.BtnResetClick(Sender: TObject);
begin
  BtnDial.Enabled := WindowsDialerInit;
end;

{ Public-Deklarationen }

function TFrmHwpDialer.WindowsDialerStart: boolean;
var
  SEI: TShellExecuteInfo;
begin
  FillChar(SEI, SizeOf(SEI), #0);
  SEI.cbSize := SizeOf(SEI);
  SEI.Wnd := Handle;
  SEI.fMask := SEE_MASK_NOCLOSEPROCESS;
  SEI.lpVerb := 'open';
  SEI.lpFile := PChar(rsWahlhilfeExeName);
  SEI.lpParameters := nil;
  SEI.lpDirectory := nil;
  SEI.nShow := SW_SHOW;
  try
    Result := ShellExecuteEx(@SEI);
  except
    on E:Exception do Showmessage(E.Message);
  end;
  CloseHandle(SEI.hProcess);
end;

function TFrmHwpDialer.WindowsDialerInit: boolean;
const
  iClassNameSize = 128;
var
  i: integer;
  H: THandle;
  ClassName: array[0..iClassNameSize] of char;
  WC: TWndClass;
begin
  if FAppHandle > 0 then
  if FindWindow(nil,PChar(rsWahlhilfeCaption)) = FAppHandle then Exit(True);
  Result := false;
  FEditHandle := 0;
  FDialButtonHandle := 0;
  FHandleList.Clear;
  FAppHandle := FindWindow(nil,PChar(rsWahlhilfeCaption));
  {-wenn die Wählhilfe nicht läuft....starten-}
  if FAppHandle = 0 then begin
    if not WindowsDialerStart then exit;
    FAppHandle := FindWindow(nil,PChar(rsWahlhilfeCaption));
  end;
  if FAppHandle > 0 then begin
    EnumChildWindows(FAppHandle, @EnumChilds, FAppHandle);
    for i := 0 to Pred(FHandleList.Count) do begin
      H := StrToInt(FHandleList[i]);
      GetClassName(H,ClassName,iClassNameSize);
      if GetClassInfo(H,@ClassName,WC) then begin
        {-Eingabefeld-}
        if SameText(rsEditClassName,string(WC.lpszClassName))
        then FEditHandle := H;
        {-Botton-}
        if SameText(rsButtonDialClassName,string(WC.lpszClassName)) then begin
          {-Button gefunden...aber welcher ??? }
          FDialButtonHandle := H;
        end;
      end;
      if (FDialButtonHandle > 0) and (FEditHandle > 0) then Exit(true);
    end;
  end;
end;

end.
  Mit Zitat antworten Zitat