Author: Tomas Rutkauskas 
I need to capture the text from a scrolling text window in another program that I 
don't have access to only through a window handle. Can I use SendMEssage or 
something to ge the text with WM_GETTEXT type message. I know there are programs 
like spell checkers that can do this. Any help would be appreciated.
Answer:
Solve 1:
The example runs 'chkdsk.exe c:\' and displays the output to Memo1. Put a TMemo 
(Memo1) and a TButton (Button1) on your form. Put this code in the OnCLick of 
Button1:
1   
2   procedure TForm1.Button1Click(Sender: TObject);
3   
4     procedure RunDosInMemo(DosApp: string; AMemo: TMemo);
5     const
6       ReadBuffer = 2400;
7     var
8       Security: TSecurityAttributes;
9       ReadPipe, WritePipe: THandle;
10      start: TStartUpInfo;
11      ProcessInfo: TProcessInformation;
12      Buffer: Pchar;
13      BytesRead: DWord;
14      Apprunning: DWord;
15    begin
16      with Security do
17      begin
18        nlength := SizeOf(TSecurityAttributes);
19        binherithandle := true;
20        lpsecuritydescriptor := nil;
21      end;
22      if Createpipe(ReadPipe, WritePipe, @Security, 0) then
23      begin
24        Buffer := AllocMem(ReadBuffer + 1);
25        FillChar(Start, Sizeof(Start), #0);
26        start.cb := SizeOf(start);
27        start.hStdOutput := WritePipe;
28        start.hStdInput := ReadPipe;
29        start.dwFlags := STARTF_USESTDHANDLES + STARTF_USESHOWWINDOW;
30        start.wShowWindow := SW_HIDE;
31        if CreateProcess(nil, PChar(DosApp), @Security, @Security, true,
32          NORMAL_PRIORITY_CLASS, nil, nil, start, ProcessInfo) then
33        begin
34          repeat
35            Apprunning := WaitForSingleObject(ProcessInfo.hProcess, 100);
36            Application.ProcessMessages;
37          until
38            (Apprunning <> WAIT_TIMEOUT);
39          repeat
40            BytesRead := 0;
41            ReadFile(ReadPipe, Buffer[0],
42              ReadBuffer, BytesRead, nil);
43            Buffer[BytesRead] := #0;
44            OemToAnsi(Buffer, Buffer);
45            AMemo.Text := AMemo.text + string(Buffer);
46          until
47            (BytesRead < ReadBuffer);
48        end;
49        FreeMem(Buffer);
50        CloseHandle(ProcessInfo.hProcess);
51        CloseHandle(ProcessInfo.hThread);
52        CloseHandle(ReadPipe);
53        CloseHandle(WritePipe);
54      end;
55    end;
56  
57  begin {Button1 code}
58    RunDosInMemo('chkdsk.exe c:\', Memo1);
59  end;
Unfortunaly that will only work with applications that send output to stdout. A 
Windows application usually doesn't do this.
Solve 2:
The usually use different techiques, like OCR on a screen bitmap. There is simply 
no generic method to get text from other windows. What you can try, however, is 
this:
60  
61  function GetTextFromWindow(wnd: HWND): string;
62  var
63    count: Cardinal;
64  begin
65    result := '';
66    if SendMessageTimeout(wnd, WM_GETTEXTLENGTH, 0, 0,
67      SMTO_ABORTIFHUNG, 1000, count) <> 0 then
68    begin
69      if count = 0 then
70        Exit;
71      SetLength(result, count);
72      if SendMessageTimeout(wnd, WM_GETTEXT, count + 1, lparam(@result[1]),
73        SMTO_ABORTIFHUNG, 1000, count) = 0 then
74        result := '';
75    end;
76  end;
77  
78  procedure TForm1.Button1Click(Sender: TObject);
79  var
80    wnd: HWND;
81  begin
82    wnd := FindWindow('notepad', nil);
83    if wnd <> 0 then
84    begin
85      wnd := GetWindow(wnd, GW_CHILD);
86      if wnd <> 0 then
87        memo1.text := GetTextfromwindow(wnd);
88    end
89    else
90      memo1.text := 'Notepad not running.';
91  end;
			
           |