I defined a Tactionlist which contains all actions to show/hide my forms. This could be modal (showmodal) or non modal (visible:=true). I found some code to catch the screen shots by this:
procedure GetScreenShot(shotType: TScreenShotType; var img: TJpegImage);
var
w,h: integer;
DC: HDC;
hWin: Cardinal;
r: TRect;
tmpBmp: TBitmap;
begin
hWin := 0;
case shotType of
sstActiveWindow:
begin //This is what I use
//only the active window
hWin := GetForegroundWindow;
dc := GetWindowDC(hWin);
GetWindowRect(hWin,r);
w := r.Right - r.Left;
h := r.Bottom - r.Top;
end; //sstActiveWindow
sstActiveClientArea:
begin
end; //sstActiveClientArea
sstPrimaryMonitor:
begin
end; //sstPrimaryMonitor
sstDesktop:
begin
end; //sstDesktop
else begin
Exit;
end; //case else
end; //case
//convert to jpg
tmpBmp := TBitmap.Create;
try
tmpBmp.Width := w;
tmpBmp.Height := h;
BitBlt(tmpBmp.Canvas.Handle,0,0,tmpBmp.Width,
tmpBmp.Height,DC,0,0,SRCCOPY);
img.Assign(tmpBmp);
finally
ReleaseDC(hWin,DC);
FreeAndNil(tmpBmp);
end; //try-finally
end;
My "scan" routine is as follows:
for ACnt := 0 to GenActions.ActionCount - 1 do
begin
try
LogBook.ML(Format('%d. Aktion %s gestartet',[ACnt,quotedstr(GenActions.Actions[ACnt].Name)]));
if GenActions.Actions[ACnt].Tag > 0 then
begin // Action is ready for test
TAction(GenActions.Actions[ACnt]).checked:=true;
if GenActions.Actions[ACnt].Execute then
begin
LogBook.ML(Format('%d. Aktion %s erfolgreich ausgeführt',[ACnt,quotedstr(GenActions.Actions[ACnt].Name)]));
if SaveScreens then // var boolean
begin
img:=TJPEGImage.Create;
try
GetScreenShot(sstActiveWindow,img);
img.SaveToFile(IncludeTrailingBackslash(Optionen.PictPfad.Text)+inttostr(ACnt)+'.jpg');
finally
img.Free;
end;
end;
repeat
sleep(100);
Application.ProcessMessages;
until not DM_Gen.TestTimer.Enabled ; //for modal windows a timer sends modalresult:=mrcancel
end;
end
else
begin
LogBook.ML(Format('%d Aktion %s nicht getestet',[ACnt,quotedstr(GenActions.Actions[ACnt].Name)]));
end;
except
on E: Exception do
LogBook.ML(Format('%d. Aktion hat Fehler %s gemeldet',[ACnt,E.Message]));
end;
end;
finally
LogBook.ML('Testlauf beendet');
end;
When I run this code I get for about the first 150 actions the mainform, then some other forms like the logbook or the browser or ... Nearly never the form I want.
I found some posts which recommended the use of "findwindow". Here is my problem that I don't know the exact caption of the window, because in all windows the caption is modified in the onshow event in order to show actual information.
Any ideas how can catch my actual opened window?
So a problem is to understand how my actions work. Here two typical examples:
procedure TDM_Gen.VALstVisActExecute(Sender: TObject);
begin
if Sender is TAction then
begin // set some properties
end;
ListeVeranst_2.Visible:=VALstVisAct.Checked;
end;
procedure TDM_Gen.NewVAActExecute(Sender: TObject);
var
NewVA : TNewVeranstaltung;
begin
if Sender <> nil then
begin
if Sender is TButton then
begin //do something depending on who fired
end;
end;
try
NewVA:=TNewVeranstaltung.Create(nil);
case NewVA.ShowModal of
mrOk:
begin // e.g. refresh some lists
end;
mrCancel:
begin // clean up
end;
end;
finally
NewVA.Free;
end;
end;
The caption of the window is set during the onshow event by:
caption:=Format('This is window %s %s',[Param1, Param2]);
Problem you are facing is due to ShowModal
method that is blocking call. That means that all subsequent code after that call will start executing after the form is closed.
Code flow in following simplified example:
MyAction.Execute;
CaptureScreen;
procedure TSomeForm.MyActionExecute(Sender: TObject);
var frm: TForm;
begin
frm := TForm.Create(nil);
try
frm.ShowModal; // this call blocks execution of subsequent code in this method until form is closed
finally
frm.Free;
end;
end;
will be MyAction.Execute -> frm.ShowModal -> frm.Close -> frm.Free -> CaptureScreen
You will have to initiate screen capturing from within your modal form in order to capture its screen.