unit uwinhelper;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, Windows;

type

  TAppWin = class(TObject)
    WinHandle    : HWND;
    WinTitle,
    WinClassName : string;
    WinVisibel   : Boolean;
  end;

procedure CloseApp(aWindow, aClass: string);
function IsAppRunning(aWindow, aClass: string): boolean;
function ListWindowComp(aWindow, aClass: string; aList: TStringList = nil): Boolean;
function ListHWNDComp(hWindow: HWND; aList: TStringList = nil): Boolean;
function ListHWNDProps(hWindow: HWND; aList: TStringList = nil): Boolean;
function ListWindows(aList: TStringList = nil): Boolean;
function ListVisibleWindows(aList: TStringList = nil): Boolean;
procedure RunShellExecute(const prog,params:string);

procedure SendVK(aVk:word);
procedure SendF1;
procedure SendF2;
procedure SendF3;

implementation

uses
  ShellApi
  , JwaWinUser  // für TInput
  ;

procedure CloseApp(aWindow, aClass: string);
var
  hWindow: HWND;
begin
  hWindow := FindWindow(pchar(aClass), pchar(aWindow));
  SendMessage(hWindow, WM_CLOSE, 0, 0);
end;

function IsAppRunning(aWindow, aClass: string): boolean;
var
  hWindow: HWND;
begin
  hWindow := FindWindow(pchar(aClass), pchar(aWindow));
  Result := (hWindow <> 0);
end;


var
  PropList : TStringList;

function EnumPrposProc(wHandle: HWND; lpszString: LPCSTR; hData: HANDLE): Bool; stdcall; export;
var
  ClassName, WindowText: array[0..255] of char;
  aWinEntry : TAppWin;
  buf, Caption: array[0..255] of char;
begin
  //GetClassName(wnd, buf, SizeOf(buf) - 1);
  //SendMessage(wnd, WM_GETTEXT, 256, Integer(@Caption));
  //Lines.Add(Format('ID: %d, ClassName: %s, Caption: %s',[GetDlgCtrlID(wnd), buf, Caption]));
  Result := True;
  aWinEntry := nil;;
  aWinEntry := TAppWin.Create;
  aWinEntry.WinClassName:= '';
  aWinEntry.WinTitle:= lpszString;
  aWinEntry.WinHandle:=wHandle;
  aWinEntry.WinVisibel:= true;
  PropList.AddObject(Format('Prop: %s', [lpszString]),aWinEntry);
end;

function ListHWNDProps(hWindow: HWND; aList: TStringList = nil): Boolean;
var
  i: Integer;
begin
  Result := false;
  if aList = nil then
     exit; // ==>>
  PropList := aList;
  EnumProps(hWindow, @EnumPrposProc);
  PropList := nil;
  Result := true;
end;

function EnumWindowChildProc(wHandle: HWND; param : LPARAM): Bool; stdcall; export;
var
  ClassName, WindowText: array[0..255] of char;
  aWinEntry : TAppWin;
  buf, Caption: array[0..255] of char;
begin
  //GetClassName(wnd, buf, SizeOf(buf) - 1);
  //SendMessage(wnd, WM_GETTEXT, 256, Integer(@Caption));
  //Lines.Add(Format('ID: %d, ClassName: %s, Caption: %s',[GetDlgCtrlID(wnd), buf, Caption]));
  Result := True;
  GetClassName(wHandle, buf, 255);
  SendMessage(wHandle, WM_GETTEXT, 256, Integer(@Caption));
  GetWindowText(wHandle, WindowText, 255);
  aWinEntry := nil;;
  aWinEntry := TAppWin.Create;
  aWinEntry.WinClassName:= ClassName;
  aWinEntry.WinTitle:= WindowText;
  aWinEntry.WinHandle:=wHandle;
  aWinEntry.WinVisibel:= IsWindowVisible(wHandle);
  TStringList(param).AddObject(Format('ID: %d, ClassName: %s, Caption: %s, Text: %s',[GetDlgCtrlID(wHandle), buf, Caption, WindowText]),aWinEntry);
end;

function ListHWNDComp(hWindow: HWND; aList: TStringList = nil): Boolean;
var
  i: Integer;
begin
  Result := false;
  if aList = nil then
     exit; // ==>>
  EnumChildWindows(hWindow, @EnumWindowChildProc, longint(aList));
  Result := true;
end;


function ListWindowComp(aWindow, aClass: string; aList: TStringList = nil): Boolean;
var
  i: Integer;
  hWindow: HWND;
begin
  Result := false;
  if aList = nil then
     exit; // ==>>
  hWindow := FindWindow(pchar(aClass), pchar(aWindow));
  EnumChildWindows(hWindow, @EnumWindowChildProc, longint(aList));
  Result := true;
end;


function EnumWindowsProc(wHandle: HWND; param : LPARAM): Bool; stdcall; export;
var
  Title, ClassName: array[0..255] of char;
  aWinEntry : TAppWin;
begin
  Result := True;
  GetWindowText(wHandle, Title, 255);
  GetClassName(wHandle, ClassName, 255);
  aWinEntry := nil;;
  aWinEntry := TAppWin.Create;
  aWinEntry.WinClassName:= ClassName;
  aWinEntry.WinTitle:= Title;
  aWinEntry.WinHandle:=wHandle;
  aWinEntry.WinVisibel:= IsWindowVisible(wHandle);
  TStringList(param).AddObject(string(Title) + '-' + string(ClassName),aWinEntry);
end;

function EnumVisibleWindowsProc(wHandle: HWND; param : LPARAM): Bool; stdcall; export;
var
  Title, ClassName: array[0..255] of char;
  aWinEntry : TAppWin;
begin
  Result := True;
  if IsWindowVisible(wHandle) then begin
    GetWindowText(wHandle, Title, 255);
    GetClassName(wHandle, ClassName, 255);
    aWinEntry := nil;;
    aWinEntry := TAppWin.Create;
    aWinEntry.WinClassName:= ClassName;
    aWinEntry.WinTitle:= Title;
    aWinEntry.WinHandle:=wHandle;
    aWinEntry.WinVisibel:= IsWindowVisible(wHandle);
    TStringList(param).AddObject(string(Title) + '-' + string(ClassName),aWinEntry);
  end;
end;


function ListWindows(aList: TStringList = nil): Boolean;
begin
  Result := false;
  if aList = nil then
     exit; // ==>>
  EnumWindows(@EnumWindowsProc, longint(aList));
  Result := true;
end;

function ListVisibleWindows(aList: TStringList = nil): Boolean;
var
  i: Integer;
begin
  Result := false;
  if aList = nil then
     exit; // ==>>
  EnumWindows(@EnumVisibleWindowsProc, longint(aList));
  Result := true;
end;


procedure RunShellExecute(const prog,params:string);
begin
  //  ( Handle, nil/'open'/'edit'/'find'/'explore'/'print',   // 'open' isn't always needed
  //      path+prog, params, working folder,
  //        0=hide / 1=SW_SHOWNORMAL / 3=max / 7=min)   // for SW_ constants : uses ... Windows ...
  if ShellExecute(0,'open',PChar(prog),PChar(params),PChar(extractfilepath(prog)),1) >32 then; //success
  // return values 0..32 are errors
end;

procedure SendVK(aVK:word);
var
  input: TInput;
begin
  FillChar(input, sizeof(TInput), 0);

  input.type_ := INPUT_KEYBOARD;
  input.ki.wVk := aVK;

  SendInput(1, @input, sizeof(TInput));
end;

procedure SendF1;
begin
  SendVK(VK_F1);
end;

procedure SendF2;
begin
  SendVK(VK_F2);
end;

procedure SendF3;
begin
  SendVK(VK_F3);
end;

//var
//  inputArray: array[0..0] of TInput;
//begin
//  FillChar(inputArray, length(inputArray) * sizeof(TInput), 0);
//
//  inputArray[0].type_ := INPUT_KEYBOARD;
//  inputArray[0].ki.wVk := VK_F3;
//
//  //inputArray[1].type_ := INPUT_KEYBOARD;
//  //inputArray[1].ki.wVk := VkKeyScan('S');
//  //
//  //inputArray[2].type_ := INPUT_KEYBOARD;
//  //inputArray[2].ki.wVk := VkKeyScan('S');
//  //inputArray[2].ki.dwFlags := KEYEVENTF_KEYUP;
//  //
//  //inputArray[3].type_ := INPUT_KEYBOARD;
//  //inputArray[3].ki.wVk := VK_LCONTROL;
//  //inputArray[3].ki.dwFlags := KEYEVENTF_KEYUP;
//
//  SendInput(length(inputArray), @inputArray[0], sizeof(TInput));
//end;

end.

