Jak wykryć wyświetlenie okna innej aplikacji.

0

Witam.
Otwieram plik .txt poprzez ShellExecute w Notatniku i chciałbym wykryć moment ukazania się na ekranie okna Notatnika z wczytanym plikiem.txt. Podobnie ma się sytuacja z Word'em ale w tym przypadku chciałbym wykryć moment wyświetlenia na ekranie okna głównego z zawartością pliku a nie splash'a
Proszę o podpowiedzi gdzie szukać
Pozdrawiam.

1

Jest możliwośc wywołania ShellExecuteEx tak, aby zwróciło PID procesu. Jednak przykładowy kod mogę pokazać dopiero jutro wieczorem, gdyż nie mam dostępu do swojego PC w tej chwili. Mając już PID, który łatwiej uzyskać z funkcji CreateProces. Mozemy używając funkcji EnumWindows w połączeniu z GetWindowThreadProcessId uzyskać konktetny uchwyt. Oczywiście CreateProcess, pozwala na uruchomienie plików wykonywalnych, a nie skojarzonych. Więcej informacji na MSDN, a przykłady na mnóstwie stron, które trzeba sobie wygooglować.

2

Możesz też spróbować użyć funkcji FindWindow i w parametrze podać nazwę okna np.
dla nazwy pliku "test.txt":
"test.txt – Notatnik" (zwróć uwagę na niestandardowy myślnik)
"test.txt - Microsoft Word"

1
function GetWordWindowByDocFileName(ADocFileName: string): THandle;
const
  MSWORD_WND_CLASS_NAME = 'OpusApp';
  MSWORD_WND_CAPTION_SUFIX = ' - Microsoft Word';
var
  WordWndCaption: string;
begin
  WordWndCaption:= ChangeFileExt(ADocFileName, '') + MSWORD_WND_CAPTION_SUFIX;
  result:= FindWindow(MSWORD_WND_CLASS_NAME, PChar(WordWndCaption));
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  if GetWordWindowByDocFileName('test.doc') > 0 then
  begin
    Timer1.Enabled:= False;
    ShowMessage('Uruchomiłeś Worda!!!');
  end;
end;
0
kAzek napisał(a):
function GetWordWindowByDocFileName(ADocFileName: string): THandle;
const
  MSWORD_WND_CLASS_NAME = 'OpusApp';
  MSWORD_WND_CAPTION_SUFIX = ' - Microsoft Word';
var
  WordWndCaption: string;
begin
  WordWndCaption:= ChangeFileExt(ADocFileName, '') + MSWORD_WND_CAPTION_SUFIX;
  result:= FindWindow(MSWORD_WND_CLASS_NAME, PChar(WordWndCaption));
end;

Nie mam w tej chwili możliwości sprawdzenia jaki jest format captiona okna Worda z wczytanym dokumentem, ale z tego co pamiętam, to może być np. taki: "Dokument.doc - Microsoft Word", a nie "Dokument - Microsoft Word", więc formatowanie tekstu przypisanego do "WordWndCaption" nie będzie prawidłowe, bo jest wycinane rozszerzenie ".doc" i okno Worda nie będzie znalezione.
Pomysł na wyszukiwanie oczywiście jak najbardziej spoko.

0

Dziękuję wszystkim za zainteresowanie.
Pomysł z listą okien jest najlepszy, a sprawdzenie nazwy lub fragmentu nazwy pliku w nazwie okna realizuje przez funkcję "pos".
Dla zainteresowanych podaję funkcję zapisującą do

 TStringList 

nazwy okien aplikacji uruchomionych w systemie. Funkcja FindWindow

 nie działąła mi prawidłowo przy Windows 7.

```delphi
 
function AllWindows(wHnd: THandle; List: TStringList): Bool; stdcall;
  var Buffer: array[0..255] of char;
  begin
  SendMessage(wHnd, WM_GETTEXT, 255, LongInt(@Buffer[0]));
  if (Buffer <> '') and IsWindow(wHnd) then
  begin
  List.AddObject(Buffer, TObject(wHnd));
  end;
  Result := True;   
  end. 

Pozdrawiam.

0

Moduł zwracający PID przy wywołaniu przez funkcję ShellExecAndGetPid dołączam do tego posta. A i co to znaczy, że pod Windows 7 FindWindow źle Tobie działa? Używałem jej wielokrotnie na Windowsie 7 Ultimate 64 bit. I nie było żadnych problemów. Być może jednak, w jakimś przypadku musisz rozpoznać tytuł po UNICODE, to wtedy użyj FindWindowW.

0

Można też coś takiego:

uses
  ShellApi;

  //funkcja dostepna od Windows XP SP1
  function GetProcessId(hProcess: Cardinal): Cardinal; stdcall; external 'kernel32.dll';

procedure TForm1.Button1Click(Sender: TObject);
var
  Info: TShellExecuteInfo;
  hWin: HWND;
  PID, PIDCurrentWnd: Cardinal;
  len: Integer;
  buff: string;
begin
  ZeroMemory(@Info, SizeOf(TShellExecuteInfo));
  Info.cbSize:= SizeOf(TShellExecuteInfo);
  Info.fMask:= SEE_MASK_NOCLOSEPROCESS;
  Info.nShow:= SW_NORMAL;
  Info.lpFile:= 'c:\Users\kAzek\Documents\test.docx';
  if ShellExecuteEx(@Info) then
  begin
    PID:= GetProcessID(Info.hProcess);
    WaitForInputIdle(Info.hProcess, INFINITE);
    repeat
      hWin:= GetForegroundWindow;
      while (hWin <> 0) do
      begin
        GetWindowThreadProcessID(hWin, PIDCurrentWnd);
        if PIDCurrentWnd = PID then
        begin
          len:= GetWindowTextLength(hWin) + 1;
          SetLength(buff, len);
          len:= GetWindowText(hWin, PChar(buff), len);
          SetLength(buff, len);
          if (Pos('Microsoft Word', buff) > 0) and (Pos('test', buff) = 1) then
            break;
        end;
        hWin:= GetNextWindow(hWin, GW_HWNDNEXT);
      end;
      Sleep(100);
      Application.ProcessMessages;
    until (hWin <> 0);

    ShowMessage('Zaladowany!');
  end;
end;

1 użytkowników online, w tym zalogowanych: 0, gości: 1