Contexte : Delphi XE7, Windows 7
Problématique : récupérer le texte de la console de l'application courante (suite à l'appel d'une DLL "boite noire").


Je suis confronté au problème suivant :
dans mon application "GUI" je dois créer une console (par AllocConsole) afin de pouvoir appeler sans sortie immédiate
une fonction intégrée à une DLL qui écrit sur le flux standard de sortie "stdOut". J'ai créé la méthode ci-dessous afin de
récupérer le texte écrit sur la console (après appel de la fonction intégrée) et de l'ajouter dans un TMemo
(je me suis inspiré de morceaux de code trouvés sur différents sites).

Lorsque j'appelle cette méthode avec les instructions :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
  ReadRegion.Right := BufferInfo.dwSize.X;  
 
  ReadRegion.Bottom :=BufferInfo.dwSize.Y;
alors le "ReadConsoleOutput" renvoie le message d'erreur 8:ERROR_NOT_ENOUGH_MEMORY

Je n'ai plus d'erreur si j'utilise à la place :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
  ReadRegion.Right := 80;  
 
  ReadRegion.Bottom :=194;
J'ai également l'impression de toujours récupérer la même partie de la console...

Je suis preneur de toute procédure permettant une récupération plus fine du texte de la console....

N.B.

1) il ne s'agit pas de récupérer la sortie texte d'une autre application lancée par l'application courante
2) j'ai essayé des solutions utilisant des "pipes" : ça ne marche pas bien dans mon cas


"MON" CODE :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
function TFicheControleScilab.ReadConsoleQuat(ConsoleHandle: Cardinal):boolean;
 
var
 
  BufferInfo: _CONSOLE_SCREEN_BUFFER_INFO;
 
  BufferSize, BufferCoord: _COORD;
 
  ReadRegion: _SMALL_RECT;
 
  Buffer: Array of _CHAR_INFO;
 
  I, J: Integer;
 
  Line: AnsiString;
 
  car:ansichar;
 
begin
 
  ZeroMemory(@BufferInfo, SizeOf(BufferInfo));
 
  if not GetConsoleScreenBufferInfo(theHandle, BufferInfo) then
 
  begin
 
    raise Exception.Create('GetConsoleScreenBufferInfo error: ' +
 
      IntToStr(GetLastError));
 
  end;
 
 
 
  SetLength(Buffer, BufferInfo.dwSize.X * BufferInfo.dwSize.Y);
 
 
 
  BufferSize.X := BufferInfo.dwSize.X;
 
  BufferSize.Y := BufferInfo.dwSize.Y;
 
  BufferCoord.X := 0;
 
  BufferCoord.Y := 0;
 
  ReadRegion.Left := 0;
 
  ReadRegion.Top := 0;
 
  ReadRegion.Right := BufferInfo.dwSize.X;  //80:OK;
 
  ReadRegion.Bottom :=BufferInfo.dwSize.Y; //194:OK
 
 
 
  if ReadConsoleOutput(ConsoleHandle, Pointer(Buffer), BufferSize, BufferCoord,
 
    ReadRegion) then
 
  begin
 
    result:=true;
 
    for I := 0 to BufferInfo.dwSize.Y - 1 do
 
    begin
 
      Line := '';
 
      for J := 0 to BufferInfo.dwSize.X - 1 do
 
      begin
 
        car:=Buffer[I * BufferInfo.dwSize.X + J].AsciiChar;;
 
        Line := Line + car;
 
      end;
 
      if (trim(line)<>'')  then
 
           memoTrace.lines.Add(Line);
 
    end;
 
  end
 
  else
 
  begin
 
    memoDiagnostic.Lines.Add('ReadConsoleOutput error: ' +IntToStr(GetLastError));
 
    result:=false;
 
  end;
 
  //8        ERROR_NOT_ENOUGH_MEMORY
 
end;