1133 lines
30 KiB
Plaintext
1133 lines
30 KiB
Plaintext
unit DBs1RcdMain;
|
||
|
||
interface
|
||
|
||
uses
|
||
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
|
||
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls,
|
||
FFBaseComponent, FFEncode, Vcl.WinXCtrls, Vcl.StdCtrls, DFindWindow,
|
||
Vcl.Buttons, System.Actions, Vcl.ActnList, ManagerConfig,
|
||
Vcl.Menus, System.ImageList, Vcl.ImgList, PngImageList, FFJoin,
|
||
DWaitWork, Tocsg.Trace, ThdRecordWait;
|
||
|
||
type
|
||
TDlgBs1RcdMain = class(TForm)
|
||
pnTop: TPanel;
|
||
btnSetFile: TSpeedButton;
|
||
btnRecPause: TSpeedButton;
|
||
btnRecStop: TSpeedButton;
|
||
SaveDialog: TSaveDialog;
|
||
btnShowFrame: TSpeedButton;
|
||
btnShowFrameDummy: TSpeedButton;
|
||
pnClient: TPanel;
|
||
pnBottom: TPanel;
|
||
lbPos: TLabel;
|
||
lbSize: TLabel;
|
||
btnFindWindow: TBitBtn;
|
||
ActionList: TActionList;
|
||
acCancelFindWnd: TAction;
|
||
popTray: TPopupMenu;
|
||
btnConfig: TSpeedButton;
|
||
miSetFile: TMenuItem;
|
||
miRecPause: TMenuItem;
|
||
miRecStop: TMenuItem;
|
||
N5: TMenuItem;
|
||
miExit: TMenuItem;
|
||
N7: TMenuItem;
|
||
btnStayOnTop: TSpeedButton;
|
||
btnStayOnTopDummy: TSpeedButton;
|
||
tReTry: TTimer;
|
||
tClearFile: TTimer;
|
||
btnTest: TButton;
|
||
tInit: TTimer;
|
||
procedure btnSetFileClick(Sender: TObject);
|
||
procedure btnRecPauseClick(Sender: TObject);
|
||
procedure btnRecStopClick(Sender: TObject);
|
||
procedure btnShowFrameClick(Sender: TObject);
|
||
procedure FormResize(Sender: TObject);
|
||
procedure btnFindWindowMouseDown(Sender: TObject; Button: TMouseButton;
|
||
Shift: TShiftState; X, Y: Integer);
|
||
procedure btnFindWindowMouseUp(Sender: TObject; Button: TMouseButton;
|
||
Shift: TShiftState; X, Y: Integer);
|
||
procedure btnFindWindowMouseMove(Sender: TObject; Shift: TShiftState; X,
|
||
Y: Integer);
|
||
procedure acCancelFindWndExecute(Sender: TObject);
|
||
procedure btnConfigClick(Sender: TObject);
|
||
procedure FormClose(Sender: TObject; var Action: TCloseAction);
|
||
procedure miExitClick(Sender: TObject);
|
||
procedure btnStayOnTopClick(Sender: TObject);
|
||
procedure FFEncoderTerminate(Sender: TObject;
|
||
const ATerminateInfo: TTerminateInfo);
|
||
procedure tReTryTimer(Sender: TObject);
|
||
procedure tClearFileTimer(Sender: TObject);
|
||
procedure btnTestClick(Sender: TObject);
|
||
procedure tInitTimer(Sender: TObject);
|
||
private
|
||
{ Private declarations }
|
||
sOutMovPath_: String;
|
||
nPauseFlag_: Integer;
|
||
rtRecFrame_: TRect;
|
||
DlgFindWnd_: TDlgFindWindow;
|
||
bFindingWnd_: Boolean;
|
||
hPreTopHWND_: HWND;
|
||
Trace_: TTgTrace;
|
||
Config_: TManagerConfig;
|
||
RecPathList_: TStringList;
|
||
dlgWait_: TDlgWaitWork;
|
||
nLeft_, nTop_,
|
||
nWidth_, nHeight_: Integer;
|
||
llMergeSize_: LONGLONG;
|
||
|
||
ThdRecordWait_: TThdRecordWait;
|
||
|
||
function StartRecord: Boolean;
|
||
procedure StopRecord;
|
||
procedure ShowWindow(bVal: Boolean);
|
||
procedure ExpandWindow(bVal: Boolean);
|
||
procedure UpdateRecFramePositionInfo;
|
||
procedure UpdateRecFrameSizeInfo;
|
||
function MergeVideo: Boolean;
|
||
procedure StopMergeWait(bClearFiles: Boolean = false);
|
||
public
|
||
{ Public declarations }
|
||
Constructor Create(aOwner: TComponent); override;
|
||
Destructor Destroy; override;
|
||
|
||
procedure process_WM_WINDOWPOSCHANGING(var msg: TMessage); Message WM_WINDOWPOSCHANGING;
|
||
procedure process_WM_SYSCOMMAD( var msg: TWMSysCommand); Message WM_SYSCOMMAND;
|
||
procedure process_WM_START_RECORD(var msg: TMessage); Message WM_START_RECORD;
|
||
procedure process_WM_STOP_RECORD(var msg: TMessage); Message WM_STOP_RECORD;
|
||
procedure process_WM_COPYDATA(var msg: TMessage); Message WM_COPYDATA;
|
||
end;
|
||
|
||
var
|
||
DlgBs1RcdMain: TDlgBs1RcdMain;
|
||
|
||
implementation
|
||
|
||
uses
|
||
GDICapture, Winapi.DwmApi, DConfig, Define, AVCodecStubs, Tocsg.Path,
|
||
Tocsg.Exception, Tocsg.Files, Tocsg.Safe, Tocsg.WndUtil, superobject, DefineHelper;
|
||
|
||
resourcestring
|
||
RS_FailHotKey1 = 'HOKEY_REC_RESUMPAUSE <20><>Ű <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>';
|
||
RS_FailHotKey2 = 'HOKEY_REC_STOP <20><>Ű <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>';
|
||
RS_NotFoundLibAv = '<27><><EFBFBD>ڴ<EFBFBD> <20><><EFBFBD>̺귯<CCBA><EAB7AF><EFBFBD><EFBFBD> ã<><C3A3> <20><> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD>.';
|
||
RS_ErrorRecoding = '<27><>ȭ<EFBFBD><C8AD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><EFBFBD><DFBB>߽<EFBFBD><DFBD>ϴ<EFBFBD>...';
|
||
RS_TerminatedRecord = '<27><>ȭ<EFBFBD><C8AD> <20>ߴ<EFBFBD> <20>Ǿ<EFBFBD><C7BE><EFBFBD><EFBFBD>ϴ<EFBFBD>.';
|
||
RS_NotFoundRecFrame = '<27><>ȭ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ã<><C3A3> <20><> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD>.';
|
||
RS_ErrorInitWork = '<27>۾<EFBFBD><DBBE><EFBFBD> <20>غ<EFBFBD><D8BA>ϴ<EFBFBD><CFB4><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><EFBFBD><DFBB>߽<EFBFBD><DFBD>ϴ<EFBFBD>.';
|
||
RS_Stop = '<27><><EFBFBD><EFBFBD>';
|
||
RS_ScreenRecStop = 'ȭ<><C8AD> <20><>ȭ <20><><EFBFBD><EFBFBD>';
|
||
RS_Restart = '<27><><EFBFBD><EFBFBD>';
|
||
RS_ScreenRecRestart = 'ȭ<><C8AD> <20><>ȭ <20><><EFBFBD><EFBFBD>';
|
||
RS_Pause = '<27><><EFBFBD><EFBFBD>';
|
||
RS_ScreenRecPause = 'ȭ<><C8AD> <20><>ȭ <20><><EFBFBD><EFBFBD>';
|
||
RS_Rec = '<27><>ȭ';
|
||
RS_PlzRecStop = 'ȭ<><C8AD> <20><>ȭ<EFBFBD><C8AD><EFBFBD>Դϴ<D4B4>. <20><><EFBFBD><EFBFBD> <20><>ȭ<EFBFBD><C8AD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֽʽÿ<CABD>.';
|
||
|
||
{$R *.dfm}
|
||
|
||
const
|
||
FRAME_MARGIN = 5;
|
||
|
||
HOKEY_REC_RESUMPAUSE = 1;
|
||
HOKEY_REC_STOP = 2;
|
||
|
||
{ TDlgQtRecMain }
|
||
|
||
Constructor TDlgBs1RcdMain.Create(aOwner: TComponent);
|
||
|
||
procedure InitCtrls;
|
||
var
|
||
sLogPath: String;
|
||
i: Integer;
|
||
begin
|
||
Caption := APP_NAME;
|
||
|
||
{$IFDEF DEBUG}
|
||
sLogPath := CutFileExt(GetRunExePath) + '.log';
|
||
if FileExists(sLogPath) then
|
||
DeleteFile(sLogPath);
|
||
Trace_ := TTgTrace.Create(sLogPath);
|
||
{$ELSE}
|
||
|
||
{$ENDIF}
|
||
|
||
for i := 0 to pnTop.ControlCount - 1 do
|
||
begin
|
||
if pnTop.Controls[i] is TSpeedButton then
|
||
TSpeedButton(pnTop.Controls[i]).Flat := true;
|
||
end;
|
||
|
||
ExpandWindow(Config_.ShowRecArea);
|
||
btnShowFrame.Down := Config_.ShowRecArea;
|
||
if Config_.SavePosSize then
|
||
begin
|
||
Position := poDesigned;
|
||
Left := Config_.Left;
|
||
Top := Config_.Top;
|
||
if (BorderStyle = bsSizeable) and (Config_.Width > 0) then
|
||
begin
|
||
Width := Config_.Width;
|
||
Height := Config_.Height;
|
||
end;
|
||
end;
|
||
|
||
pnClient.Left := FRAME_MARGIN;
|
||
pnClient.Top := pnTop.Height + FRAME_MARGIN;
|
||
pnClient.Width := ClientWidth - (FRAME_MARGIN * 2);
|
||
pnClient.Height := ClientHeight - pnTop.Height - pnBottom.Height - (FRAME_MARGIN * 2);
|
||
pnClient.Anchors := [akLeft, akTop, akRight, akBottom];
|
||
lbSize.Left := pnBottom.Width - lbSize.Width - 8;
|
||
UpdateRecFramePositionInfo;
|
||
UpdateRecFrameSizeInfo;
|
||
|
||
// Ctrl + Alt + Shift + P
|
||
// if not RegisterHotKey(Handle, HOKEY_REC_RESUMPAUSE, MOD_CONTROL or MOD_ALT or MOD_SHIFT, $50) then
|
||
// TTgTrace.T(RS_FailHotKey1);
|
||
|
||
// Ctrl + Alt + Shift + O
|
||
// if not RegisterHotKey(Handle, HOKEY_REC_STOP, MOD_CONTROL or MOD_ALT or MOD_SHIFT, $4F) then
|
||
// TTgTrace.T(RS_FailHotKey2);
|
||
|
||
if Config_.StayOnTop then
|
||
btnStayOnTop.Click;
|
||
end;
|
||
|
||
begin
|
||
Inherited Create(aOwner);
|
||
sOutMovPath_ := '';
|
||
bFindingWnd_ := false;
|
||
hPreTopHWND_ := 0;
|
||
nLeft_ := -1;
|
||
nTop_ := -1;
|
||
nWidth_ := -1;
|
||
nHeight_ := -1;
|
||
Config_ := TManagerConfig.Create;
|
||
DlgFindWnd_ := TDlgFindWindow.Create(Self);
|
||
RecPathList_ := TStringList.Create;
|
||
Trace_ := nil;
|
||
dlgWait_ := nil;
|
||
ThdRecordWait_ := nil;
|
||
ChangeWindowMessageFilter(WM_COPYDATA, MSGFLT_ADD);
|
||
InitCtrls;
|
||
TTgTrace.T('Create() ..');
|
||
tInit.Enabled := true;
|
||
end;
|
||
|
||
Destructor TDlgBs1RcdMain.Destroy;
|
||
begin
|
||
TTgTrace.T('Destroy() ..');
|
||
UnregisterHotKey(Handle, HOKEY_REC_STOP);
|
||
UnregisterHotKey(Handle, HOKEY_REC_RESUMPAUSE);
|
||
|
||
FreeAndNil(Config_);
|
||
if Trace_ <> nil then
|
||
FreeAndNil(Trace_);
|
||
FreeAndNil(RecPathList_);
|
||
if dlgWait_ <> nil then
|
||
FreeAndNil(dlgWait_);
|
||
if ThdRecordWait_ <> nil then
|
||
FreeAndNil(ThdRecordWait_);
|
||
|
||
Inherited;
|
||
end;
|
||
|
||
procedure TDlgBs1RcdMain.UpdateRecFramePositionInfo;
|
||
var
|
||
pt: TPoint;
|
||
begin
|
||
pt := pnClient.ClientToScreen(TPoint.Create(0, 0));
|
||
lbPos.Caption := Format('X : %d Y : %d', [pt.X, pt.Y]);
|
||
end;
|
||
|
||
procedure TDlgBs1RcdMain.UpdateRecFrameSizeInfo;
|
||
begin
|
||
lbSize.Caption := Format('%d x %d', [pnClient.Width, pnClient.Height]);
|
||
end;
|
||
|
||
procedure TDlgBs1RcdMain.btnSetFileClick(Sender: TObject);
|
||
begin
|
||
if not FFEncoder.AVLibLoaded then
|
||
begin
|
||
if not FFEncoder.LoadAVLib(GetRunExePathDir + DIR_AVLIB) then
|
||
begin
|
||
MessageBox(Handle, PChar(RS_NotFoundLibAv),
|
||
PChar(Caption), MB_ICONSTOP or MB_OK);
|
||
exit;
|
||
end;
|
||
// register gdi(screen/wave) capture demuxer
|
||
GDICapture.register_gdicapture;
|
||
// required for FFJoiner
|
||
FFJoin.register_ffjoin;
|
||
end;
|
||
|
||
SaveDialog.Filter := 'MPEG-4|*.mp4';
|
||
SaveDialog.FileName := '';
|
||
if SaveDialog.Execute(Handle) then
|
||
begin
|
||
nLeft_ := -1;
|
||
nTop_ := -1;
|
||
nWidth_ := -1;
|
||
nHeight_ := -1;
|
||
RecPathList_.Clear;
|
||
FFEncoder.ClearTasks;
|
||
|
||
sOutMovPath_ := SaveDialog.FileName;
|
||
if GetFileExt(sOutMovPath_).ToUpper <> 'MP4' then
|
||
sOutMovPath_ := sOutMovPath_ + '.mp4';
|
||
|
||
btnSetFile.Enabled := false;
|
||
miSetFile.Enabled := false;
|
||
btnRecPause.Enabled := true;
|
||
miRecPause.Enabled := true;
|
||
Caption := sOutMovPath_;
|
||
end;
|
||
end;
|
||
|
||
procedure TDlgBs1RcdMain.ExpandWindow(bVal: Boolean);
|
||
begin
|
||
if bVal then
|
||
begin
|
||
BorderStyle := bsSizeable;
|
||
ClientHeight := 360;
|
||
Constraints.MinHeight := 120;
|
||
pnBottom.Visible := true;
|
||
btnFindWindow.Enabled := true;
|
||
|
||
pnClient.Height := ClientHeight - pnTop.Height - pnBottom.Height - (FRAME_MARGIN * 2);
|
||
lbSize.Left := pnBottom.Width - lbSize.Width - 8;
|
||
|
||
UpdateRecFramePositionInfo;
|
||
UpdateRecFrameSizeInfo;
|
||
end else begin
|
||
Constraints.MinHeight := 0;
|
||
Width := 410;
|
||
BorderStyle := bsSingle;
|
||
ClientHeight := pnTop.Height;
|
||
pnBottom.Visible := false;
|
||
btnFindWindow.Enabled := false;
|
||
end;
|
||
end;
|
||
|
||
procedure TDlgBs1RcdMain.FFEncoderTerminate(Sender: TObject;
|
||
const ATerminateInfo: TTerminateInfo);
|
||
var
|
||
dlgWait: TDlgWaitWork;
|
||
begin
|
||
if ATerminateInfo.Exception then
|
||
begin
|
||
btnRecStop.Click;
|
||
TTgTrace.T('Fail .. %s', [ATerminateInfo.ExceptionMsg]);
|
||
MessageBox(Handle, PChar(Format(RS_ErrorRecoding+#13+#10+'(%s)', [ATerminateInfo.ExceptionMsg])),
|
||
PChar(Caption), MB_ICONWARNING or MB_OK);
|
||
end else
|
||
if ATerminateInfo.Finished and (btnRecPause.Tag <> 0) then
|
||
begin
|
||
if Config_.ReTryRec then
|
||
begin
|
||
tReTry.Enabled := true;
|
||
end else begin
|
||
btnRecStop.Click;
|
||
MessageBox(Handle, PChar(RS_TerminatedRecord), PChar(Caption), MB_ICONINFORMATION or MB_OK);
|
||
end;
|
||
end;
|
||
|
||
StopMergeWait(true);
|
||
end;
|
||
|
||
procedure TDlgBs1RcdMain.FormClose(Sender: TObject; var Action: TCloseAction);
|
||
begin
|
||
FFEncoder.Stop;
|
||
FFEncoder.ClearTasks;
|
||
if Config_.SavePosSize then
|
||
begin
|
||
Config_.Left := Left;
|
||
Config_.Top := Top;
|
||
if BorderStyle = bsSizeable then
|
||
begin
|
||
Config_.Width := Width;
|
||
Config_.Height := Height;
|
||
end;
|
||
Config_.Save;
|
||
end;
|
||
end;
|
||
|
||
procedure TDlgBs1RcdMain.FormResize(Sender: TObject);
|
||
begin
|
||
// UpdateRecFramePositionInfo;
|
||
// UpdateRecFrameSizeInfo;
|
||
end;
|
||
|
||
procedure TDlgBs1RcdMain.miExitClick(Sender: TObject);
|
||
begin
|
||
if btnRecPause.Tag <> 0 then
|
||
begin
|
||
MessageBox(Handle, PChar(RS_PlzRecStop), PChar(Caption), MB_ICONWARNING or MB_OK);
|
||
exit;
|
||
end;
|
||
Close;
|
||
end;
|
||
|
||
procedure TDlgBs1RcdMain.btnShowFrameClick(Sender: TObject);
|
||
begin
|
||
if BorderStyle = bsSizeable then
|
||
begin
|
||
ExpandWindow(false);
|
||
btnShowFrameDummy.Down := true;
|
||
end else begin
|
||
ExpandWindow(true);
|
||
btnShowFrame.Down := true;
|
||
end;
|
||
Config_.ShowRecArea := btnShowFrame.Down;
|
||
Config_.Save;
|
||
end;
|
||
|
||
procedure TDlgBs1RcdMain.btnStayOnTopClick(Sender: TObject);
|
||
begin
|
||
if FormStyle = fsNormal then
|
||
begin
|
||
FormStyle := fsStayOnTop;
|
||
Config_.StayOnTop := true;
|
||
btnStayOnTop.Down := true;
|
||
end else begin
|
||
FormStyle := fsNormal;
|
||
Config_.StayOnTop := false;
|
||
btnStayOnTopDummy.Down := true;
|
||
end;
|
||
Config_.Save;
|
||
end;
|
||
|
||
procedure TDlgBs1RcdMain.btnTestClick(Sender: TObject);
|
||
begin
|
||
RecPathList_.Clear;
|
||
RecPathList_.Add('C:\Users\kku\Desktop\22-00.mp4');
|
||
RecPathList_.Add('C:\Users\kku\Desktop\22-01.mp4');
|
||
RecPathList_.Add('C:\Users\kku\Desktop\22-02.mp4');
|
||
RecPathList_.Add('C:\Users\kku\Desktop\22-03.mp4');
|
||
|
||
nWidth_ := 1000;
|
||
nHeight_ := 800;
|
||
|
||
MergeVideo;
|
||
end;
|
||
|
||
function CalcScaledSize(const SrcW, SrcH: Integer;
|
||
const MaxW, MaxH: Integer;
|
||
out DstW, DstH: Integer): Boolean;
|
||
var
|
||
ScaleW, ScaleH, Scale: Double;
|
||
begin
|
||
Result := false;
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>̹<EFBFBD> <20><><EFBFBD>Ѻ<EFBFBD><D1BA><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>״<EFBFBD><D7B4><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||
if (SrcW <= MaxW) and (SrcH <= MaxH) then
|
||
begin
|
||
DstW := SrcW;
|
||
DstH := SrcH;
|
||
exit;
|
||
end;
|
||
|
||
// <20><> <20><> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||
ScaleW := MaxW / SrcW;
|
||
ScaleH := MaxH / SrcH;
|
||
|
||
// <20><> <20><><EFBFBD><EFBFBD> <20>ٿ<EFBFBD><D9BF><EFBFBD> <20>ϴ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ؾ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||
if ScaleW < ScaleH then
|
||
Scale := ScaleW
|
||
else
|
||
Scale := ScaleH;
|
||
|
||
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ػ<EFBFBD><D8BB><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||
DstW := Round(SrcW * Scale);
|
||
DstH := Round(SrcH * Scale);
|
||
|
||
// ¦<><C2A6> <20><><EFBFBD><EFBFBD>(<28><><EFBFBD>ڴ<EFBFBD><DAB4><EFBFBD> mod2 <20>䱸<EFBFBD>ϴ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>)
|
||
if (DstW mod 2) <> 0 then
|
||
Dec(DstW);
|
||
if (DstH mod 2) <> 0 then
|
||
Dec(DstH);
|
||
|
||
Result := true;
|
||
end;
|
||
|
||
function TDlgBs1RcdMain.StartRecord: Boolean;
|
||
var
|
||
IO: TInputOptions;
|
||
OO: TOutputOptions;
|
||
nTaskIdx, nFps: Integer;
|
||
pt: TPoint;
|
||
sMsg,
|
||
sOutPath: String;
|
||
nW, nH: Integer;
|
||
bProcScale: Boolean;
|
||
begin
|
||
Result := false;
|
||
try
|
||
nPauseFlag_ := 0;
|
||
|
||
// <20>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD><EFBFBD> <20>ٽ<EFBFBD> <20><>ȭ<EFBFBD>ϴ°<CFB4><C2B0><EFBFBD> Ȯ<><C8AE> 21_1118 08:05:58 sunk
|
||
if (nWidth_ = -1) or (nHeight_ = -1) then
|
||
begin
|
||
if BorderStyle = bsSizeable then
|
||
begin
|
||
pt := pnClient.ClientToScreen(TPoint.Create(0, 0));
|
||
nLeft_ := pt.X;
|
||
nTop_ := pt.Y;
|
||
nWidth_ := pnClient.Width;
|
||
nHeight_ := pnClient.Height;
|
||
end else begin
|
||
// nLeft_ := 0;//GetSystemMetrics(SM_XVIRTUALSCREEN);
|
||
// nTop_ := 0;//GetSystemMetrics(SM_YVIRTUALSCREEN);
|
||
// nWidth_ := 3840;//GetSystemMetrics(SM_CXVIRTUALSCREEN);
|
||
// nHeight_ := 2160;//GetSystemMetrics(SM_CYVIRTUALSCREEN);
|
||
|
||
nLeft_ := GetSystemMetrics(SM_XVIRTUALSCREEN);
|
||
nTop_ := GetSystemMetrics(SM_YVIRTUALSCREEN);
|
||
nWidth_ := GetSystemMetrics(SM_CXVIRTUALSCREEN);
|
||
nHeight_ := GetSystemMetrics(SM_CYVIRTUALSCREEN);
|
||
end;
|
||
|
||
if (nWidth_ = 0) or (nHeight_ = 0) then
|
||
begin
|
||
nWidth_ := -1;
|
||
nHeight_ := -1;
|
||
MessageBox(Handle, PChar(RS_NotFoundRecFrame), PChar(Caption), MB_ICONWARNING or MB_OK);
|
||
exit;
|
||
end;
|
||
|
||
// ũ<><C5A9> <20><><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ũ<>Ⱑ ¦<><C2A6><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ȴ<EFBFBD> 21_0721 08:15:50 sunk
|
||
if (nWidth_ mod 2) <> 0 then
|
||
Dec(nWidth_);
|
||
if (nHeight_ mod 2) <> 0 then
|
||
Dec(nHeight_);
|
||
end;
|
||
|
||
case Config_.FrameRate of
|
||
1 : nFps := 25;
|
||
2 : nFps := 30;
|
||
else nFps := 15;
|
||
end;
|
||
|
||
bProcScale := CalcScaledSize(nWidth_, nHeight_, 1920, 1200, nW, nH);
|
||
|
||
InitInputOptions(@IO);
|
||
IO.Options := '-f gdicapture' + // gdi(screen/wave) capture format
|
||
' -pause_pointer ' + IntToStr(NativeUInt(@nPauseFlag_)) + // integer value of pause flag pointer
|
||
' -capture_offset ' + Format('%d,%d', [nLeft_, nTop_]) + // capture offset %d,%d: offset on x and y against the final source window
|
||
// capture flags: +/-showframe: show flashing frame, +/-client: capture client dc instead of window dc, +/-cursor: capture cursor, +/-checkbound: check input bound
|
||
' -s ' + Format('%dx%d', [nWidth_, nHeight_]) +
|
||
Format(' -r %d', [nFps]) + ' -capture_flags +client+cursor';
|
||
|
||
if (BorderStyle <> bsSizeable) or Config_.NoShowRecFrame then
|
||
IO.Options := IO.Options + '-showframe';
|
||
TTgTrace.T('Encoder Init .. Input Options="%s"', [IO.Options]);
|
||
|
||
// try to open input file
|
||
// filename format: video=hwnd:audio=device_id
|
||
// hwnd for screen capture: special window handle; 0 indicate desktop
|
||
// device_id for wave capture: device identifier, such as -1 for WAVE_MAPPER
|
||
nTaskIdx := FFEncoder.AddTask('video=0', @IO);
|
||
if nTaskIdx < 0 then
|
||
begin
|
||
TTgTrace.T('Encoder error .. "%s"', [FFEncoder.LastErrMsg]);
|
||
exit;
|
||
end;
|
||
|
||
TTgTrace.T('Encoder Init .. "%s"', [FFEncoder.Decoders[nTaskIdx, 0].FileInfoText]);
|
||
|
||
// set output options
|
||
InitOutputOptions(@OO);
|
||
|
||
// mp4 output options
|
||
// OO.Options := '-c:v libx264 -pix_fmt yuv420p -g 15 -preset ultrafast -b:v 500';
|
||
// OO.Options := '-vf scale=1680:1050 -c:v libx264 -pix_fmt yuv420p -g 15 ';
|
||
if bProcScale then
|
||
OO.Options := Format('-vf scale=%d:%d -c:v libx264 -pix_fmt yuv420p -g 15 ', [nW, nH])
|
||
else
|
||
OO.Options := '-c:v libx264 -pix_fmt yuv420p -g 15 ';
|
||
case Config_.RecQuality of
|
||
0 : OO.Options := OO.Options + '-b:v 2000k -qscale 255';
|
||
2 : OO.Options := OO.Options + '-preset ultrafast -b:v 500k';
|
||
else OO.Options := OO.Options + '-b:v 1000k';
|
||
end;
|
||
TTgTrace.T('Encoder Init .. Output Options="%s"', [OO.Options]);
|
||
|
||
// try to set output file with output options
|
||
if RecPathList_.Count > 0 then
|
||
begin
|
||
if RecPathList_.Count = 1 then
|
||
begin
|
||
// ù<><C3B9>° <20><><EFBFBD><EFBFBD> <20≯<EFBFBD><CCB8><EFBFBD><EFBFBD><EFBFBD>
|
||
sOutPath := Format('%s-00%s', [CutFileExt(sOutMovPath_), ExtractFileExt(sOutMovPath_)]);
|
||
if not RenameFile(sOutMovPath_, sOutPath) then
|
||
begin
|
||
TTgTrace.T('StartRecord() : Fail .. Rename .. OldPath="%s", NewPath="%s"', [sOutMovPath_, sOutPath]);
|
||
exit;
|
||
end;
|
||
RecPathList_[0] := sOutPath;
|
||
end;
|
||
|
||
sOutPath := Format('%s-%.2d%s', [CutFileExt(sOutMovPath_), RecPathList_.Count, ExtractFileExt(sOutMovPath_)]);
|
||
end else
|
||
sOutPath := sOutMovPath_;
|
||
|
||
if FFEncoder.SetOutput(nTaskIdx, sOutPath, @OO) < 0 then
|
||
begin
|
||
FFEncoder.RemoveTask(nTaskIdx);
|
||
sMsg := Format('Encoder error .. Cannot do convert, "%s"', [FFEncoder.LastErrMsg]);
|
||
TTgTrace.T(sMsg);
|
||
MessageBox(Handle, PChar(sMsg), PChar(Caption), MB_ICONWARNING or MB_OK);
|
||
exit;
|
||
end;
|
||
|
||
if Config_.StartRecToTray then
|
||
ShowWindow(false);
|
||
|
||
TTgTrace.T('Encoder Can do convert ..');
|
||
FFEncoder.Start(1);
|
||
if RecPathList_.IndexOf(sOutPath) = -1 then
|
||
RecPathList_.Add(sOutPath);
|
||
Result := true;
|
||
except
|
||
on E: Exception do
|
||
ETgException.TraceException(Self, E, 'Fail .. StartRecord()');
|
||
end;
|
||
end;
|
||
|
||
procedure TDlgBs1RcdMain.StopRecord;
|
||
begin
|
||
btnRecPause.Tag := 0;
|
||
btnRecPause.Caption := RS_Rec;
|
||
btnRecPause.ImageIndex := 1;
|
||
btnRecPause.Enabled := false;
|
||
miRecPause.Enabled := false;
|
||
miRecPause.ImageIndex := 1;
|
||
btnRecStop.Enabled := false;
|
||
miRecStop.Enabled := false;
|
||
btnSetFile.Enabled := true;
|
||
miSetFile.Enabled := true;
|
||
btnShowFrame.Enabled := true;
|
||
Caption := APP_NAME;
|
||
|
||
if Config_.StartRecToTray then
|
||
ShowWindow(true);
|
||
|
||
FFEncoder.Stop;
|
||
FFEncoder.ClearTasks;
|
||
|
||
if RecPathList_.Count > 1 then
|
||
begin
|
||
// <20><><EFBFBD><EFBFBD> <20><>ġ<EFBFBD><C4A1> 21_1117 14:27:42 sunk
|
||
StopMergeWait;
|
||
Enabled := false;
|
||
dlgWait_ := TDlgWaitWork.Create(Self);
|
||
dlgWait_.Show;
|
||
Application.ProcessMessages;
|
||
Sleep(2000);
|
||
MergeVideo;
|
||
end;
|
||
|
||
// sOutMovPath_ := '';
|
||
end;
|
||
|
||
procedure TDlgBs1RcdMain.tClearFileTimer(Sender: TObject);
|
||
var
|
||
i: Integer;
|
||
begin
|
||
tClearFile.Enabled := false;
|
||
|
||
FFEncoder.Stop;
|
||
FFEncoder.ClearTasks;
|
||
FFJoiner.Reset;
|
||
|
||
if Config_.AutoDelMergeAv and
|
||
((llMergeSize_ div 2) < GetFileSize_path(sOutMovPath_)) then // <20><>ġ<EFBFBD><C4A1> <20><><EFBFBD>и<EFBFBD> <20>뷫 ũ<><C5A9><EFBFBD><EFBFBD> üũ...
|
||
begin
|
||
for i := 0 to RecPathList_.Count - 1 do
|
||
DeleteFile(RecPathList_[i]);
|
||
end;
|
||
RecPathList_.Clear;
|
||
end;
|
||
|
||
procedure TDlgBs1RcdMain.tInitTimer(Sender: TObject);
|
||
begin
|
||
tInit.Enabled := false;
|
||
|
||
case gParam.ExeType of
|
||
etTest : ;
|
||
etRecordWait :
|
||
begin
|
||
TTgTrace.T('tInitTimer() .. etRecordWait');
|
||
|
||
if not FFEncoder.AVLibLoaded then
|
||
begin
|
||
if not FFEncoder.LoadAVLib(GetRunExePathDir + DIR_AVLIB) then
|
||
begin
|
||
TTgTrace.T('Fail .. LoadAVLib()');
|
||
Close;
|
||
exit;
|
||
end;
|
||
// register gdi(screen/wave) capture demuxer
|
||
GDICapture.register_gdicapture;
|
||
// required for FFJoiner
|
||
FFJoin.register_ffjoin;
|
||
end;
|
||
|
||
ThdRecordWait_ := TThdRecordWait.Create(Handle, gParam.OwMtxName, gParam.TaskInfo);
|
||
ThdRecordWait_.StartThread;
|
||
end;
|
||
else Close;
|
||
end;
|
||
end;
|
||
|
||
procedure TDlgBs1RcdMain.tReTryTimer(Sender: TObject);
|
||
begin
|
||
tReTry.Enabled := false;
|
||
|
||
FFEncoder.Stop;
|
||
FFEncoder.ClearTasks;
|
||
|
||
// if BorderStyle = bsSizeable then
|
||
// ShowWindow(true);
|
||
|
||
btnRecPause.Tag := 0;
|
||
btnRecPause.Click;
|
||
end;
|
||
|
||
procedure TDlgBs1RcdMain.acCancelFindWndExecute(Sender: TObject);
|
||
begin
|
||
if bFindingWnd_ then
|
||
begin
|
||
hPreTopHWND_ := 0;
|
||
btnFindWindowMouseUp(nil, TMouseButton(0), [], 0, 0);
|
||
end;
|
||
end;
|
||
|
||
procedure TDlgBs1RcdMain.btnConfigClick(Sender: TObject);
|
||
var
|
||
dlg: TDlgConfig;
|
||
OldFormStyle: TFormStyle;
|
||
begin
|
||
Guard(dlg, TDlgConfig.Create(Self));
|
||
OldFormStyle := FormStyle;
|
||
if OldFormStyle = fsStayOnTop then
|
||
begin
|
||
// dlg.FormStyle := fsStayOnTop <20>̷<EFBFBD><CCB7><EFBFBD> <20><><EFBFBD>൵...
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> fsStayOnTop <20><> <20><><EFBFBD>¸<EFBFBD> <20><><EFBFBD><EFBFBD> <20>ڷ<EFBFBD> <20><><EFBFBD> <20>̷<EFBFBD><CCB7><EFBFBD> ó<><C3B3><EFBFBD><EFBFBD> 21_0728 13:02:43 sunk
|
||
FormStyle := fsNormal;
|
||
dlg.FormStyle := fsStayOnTop;
|
||
end;
|
||
|
||
try
|
||
with Config_, dlg do
|
||
begin
|
||
chSavePosSize.Checked := SavePosSize;
|
||
chNoShowRecFrame.Checked := NoShowRecFrame;
|
||
chStartRecToTray.Checked := StartRecToTray;
|
||
chReTryRec.Checked := ReTryRec;
|
||
chAutoDelMergeAv.Checked := AutoDelMergeAv;
|
||
if RecQuality > -1 then
|
||
cbRecQuality.ItemIndex := RecQuality
|
||
else
|
||
cbRecQuality.ItemIndex := 1;
|
||
if FrameRate > -1 then
|
||
cbFrameRate.ItemIndex := FrameRate;
|
||
if dlg.ShowModal = mrOk then
|
||
begin
|
||
SavePosSize := chSavePosSize.Checked;
|
||
NoShowRecFrame := chNoShowRecFrame.Checked;
|
||
StartRecToTray := chStartRecToTray.Checked;
|
||
ReTryRec := chReTryRec.Checked;
|
||
AutoDelMergeAv := chAutoDelMergeAv.Checked;
|
||
RecQuality := cbRecQuality.ItemIndex;
|
||
FrameRate := cbFrameRate.ItemIndex;
|
||
Save;
|
||
end;
|
||
end;
|
||
finally
|
||
FormStyle := OldFormStyle;
|
||
end;
|
||
end;
|
||
|
||
procedure TDlgBs1RcdMain.btnFindWindowMouseDown(Sender: TObject;
|
||
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
|
||
begin
|
||
bFindingWnd_ := true;
|
||
// btnFindWindow.Cursor := crCross;
|
||
SetCapture(btnFindWindow.Handle);
|
||
end;
|
||
|
||
procedure TDlgBs1RcdMain.btnFindWindowMouseMove(Sender: TObject;
|
||
Shift: TShiftState; X, Y: Integer);
|
||
var
|
||
pt: TPoint;
|
||
hTopHwnd,
|
||
hDeskHwnd,
|
||
hFindHwnd: HWND;
|
||
WndRect: TRect;
|
||
sClassName,
|
||
sProcName: String;
|
||
bGetWindRect: Boolean;
|
||
begin
|
||
if bFindingWnd_ then
|
||
begin
|
||
pt := btnFindWindow.ClientToScreen(TPoint.Create(X, Y));
|
||
hFindHwnd := WindowFromPoint(pt);
|
||
if hFindHwnd = 0 then
|
||
begin
|
||
hPreTopHWND_ := 0;
|
||
exit;
|
||
end;
|
||
|
||
hTopHwnd := GetTopParentHWND(hFindHwnd);
|
||
hDeskHwnd := FindWindowEx(0, 0, 'Progman', 'Program Manager');// <20><><EFBFBD><EFBFBD>ȭ<EFBFBD><C8AD> <20>ڵ<EFBFBD> <20><><EFBFBD><EFBFBD> // GetDesktopWindow;
|
||
if (hFindHwnd <> 0) and
|
||
(hFindHwnd <> Handle) and
|
||
(hTopHwnd <> Handle) and // <20><> <20><><EFBFBD>α<CEB1> <20><><EFBFBD><EFBFBD>
|
||
(hTopHwnd <> hDeskHwnd) and
|
||
(hFindHwnd <> hDeskHwnd) and
|
||
(hPreTopHWND_ <> hFindHwnd) then
|
||
begin
|
||
hPreTopHWND_ := hFindHwnd;
|
||
DlgFindWnd_.Hide;
|
||
bGetWindRect := DwmGetWindowAttribute(hPreTopHWND_, DWMWA_EXTENDED_FRAME_BOUNDS, @WndRect, SizeOf(WndRect)) = S_OK;
|
||
if not bGetWindRect then
|
||
bGetWindRect := GetWindowRect(hPreTopHWND_, WndRect);
|
||
|
||
if bGetWindRect then
|
||
begin
|
||
DlgFindWnd_.ShowFindRect(WndRect);
|
||
// TTgTrace.T('x=%d, y=%d', [pt.X, pt.Y]);
|
||
// TTgTrace.T('WndRect.x=%d, WndRect.y=%d', [WndRect.Left, WndRect.Top]);
|
||
end;
|
||
|
||
// TTgTrace.T('%d', [hFindHwnd]);
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
procedure TDlgBs1RcdMain.btnFindWindowMouseUp(Sender: TObject;
|
||
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
|
||
var
|
||
nLeftGap, nTopGap, nWidthGap, nHeightGap: Integer;
|
||
pt: TPoint;
|
||
begin
|
||
DlgFindWnd_.Hide;
|
||
ReleaseCapture;
|
||
bFindingWnd_ := false;
|
||
// btnFindWindow.Cursor := crDefault;
|
||
try
|
||
if (hPreTopHWND_ <> 0) and (hPreTopHWND_ <> Handle) then
|
||
begin
|
||
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ȭ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
pt := pnClient.ClientToScreen(TPoint.Create(0, 0));
|
||
nLeftGap := pt.X - Left;
|
||
nTopGap := pt.Y - Top;
|
||
nWidthGap := Width - pnClient.Width;
|
||
nHeightGap := Height - pnClient.Height;
|
||
|
||
Left := DlgFindWnd_.Left - nLeftGap;
|
||
Top := DlgFindWnd_.Top - nTopGap;
|
||
Width := DlgFindWnd_.Width + nWidthGap;
|
||
Height := DlgFindWnd_.Height + nHeightGap;
|
||
|
||
// <20>̰<EFBFBD> <20>ȵ<EFBFBD><C8B5><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ٽ<EFBFBD> <20><>ġ <20><><EFBFBD><EFBFBD>
|
||
lbSize.Left := pnBottom.Width - lbSize.Width - 8;
|
||
|
||
UpdateRecFramePositionInfo;
|
||
UpdateRecFrameSizeInfo;
|
||
end;
|
||
finally
|
||
hPreTopHWND_ := 0;
|
||
end;
|
||
end;
|
||
|
||
procedure TDlgBs1RcdMain.btnRecPauseClick(Sender: TObject);
|
||
begin
|
||
case btnRecPause.Tag of
|
||
0 :
|
||
begin
|
||
if not StartRecord then
|
||
begin
|
||
if Config_.StartRecToTray then
|
||
ShowWindow(true);
|
||
|
||
MessageBox(Handle, PChar(RS_ErrorInitWork),
|
||
PChar(Caption), MB_ICONWARNING or MB_OK);
|
||
exit;
|
||
end;
|
||
|
||
btnRecStop.Enabled := true;
|
||
miRecStop.Enabled := true;
|
||
btnShowFrame.Enabled := false;
|
||
btnRecPause.Tag := 1;
|
||
btnRecPause.Caption := RS_Stop;
|
||
btnRecPause.ImageIndex := 2;
|
||
miRecPause.Caption := RS_ScreenRecStop;
|
||
miRecPause.ImageIndex := 2;
|
||
end;
|
||
1 :
|
||
begin
|
||
btnRecPause.Tag := 2;
|
||
FFEncoder.Pause;
|
||
nPauseFlag_ := 1;
|
||
btnRecPause.Caption := RS_Restart;
|
||
btnRecPause.ImageIndex := 3;
|
||
miRecPause.Caption := RS_ScreenRecRestart;
|
||
miRecPause.ImageIndex := 3;
|
||
end;
|
||
2 :
|
||
begin
|
||
btnRecPause.Tag := 1;
|
||
FFEncoder.Resume;
|
||
nPauseFlag_ := 0;
|
||
btnRecPause.Caption := RS_Pause;
|
||
btnRecPause.ImageIndex := 2;
|
||
miRecPause.Caption := RS_ScreenRecPause;
|
||
miRecPause.ImageIndex := 2;
|
||
end;
|
||
end;
|
||
Application.ProcessMessages;
|
||
end;
|
||
|
||
procedure TDlgBs1RcdMain.StopMergeWait(bClearFiles: Boolean = false);
|
||
begin
|
||
if dlgWait_ <> nil then
|
||
begin
|
||
Enabled := true;
|
||
FreeAndNil(dlgWait_);
|
||
|
||
if bClearFiles then
|
||
tClearFile.Enabled := true;
|
||
end;
|
||
end;
|
||
|
||
function TDlgBs1RcdMain.MergeVideo: Boolean;
|
||
|
||
function AAC_Encoder: AnsiString;
|
||
begin
|
||
if Assigned(avcodec_find_encoder_by_name('libfdk_aac')) then
|
||
Result := 'libfdk_aac'
|
||
else if Assigned(avcodec_find_encoder_by_name('libaacplus')) then
|
||
Result := 'libaacplus'
|
||
else if Assigned(avcodec_find_encoder_by_name('libfaac')) then
|
||
Result := 'libfaac'
|
||
else if Assigned(avcodec_find_encoder_by_name('libvo_aacenc')) then
|
||
Result := 'libvo_aacenc'
|
||
else
|
||
Result := 'aac -strict experimental';
|
||
end;
|
||
|
||
var
|
||
i, nTaskIdx: Integer;
|
||
pt: TPoint;
|
||
IO: TInputOptions;
|
||
OO: TOutputOptions;
|
||
sMsg: String;
|
||
begin
|
||
Result := false;
|
||
try
|
||
if RecPathList_.Count < 2 then
|
||
exit;
|
||
|
||
if (nWidth_ = -1) or (nHeight_ = -1) then
|
||
exit;
|
||
|
||
FFJoiner.Reset;
|
||
for i := 0 to RecPathList_.Count - 1 do
|
||
begin
|
||
if FFJoiner.Add(RecPathList_[i]) < 0 then
|
||
begin
|
||
TTgTrace.T('MergeVideo() : File open error .. %s .. Path="%s"',
|
||
[FFJoiner.LastErrMsg, RecPathList_[i]]);
|
||
continue;
|
||
end;
|
||
Inc(llMergeSize_, GetFileSize_path(RecPathList_[i]));
|
||
end;
|
||
|
||
if FFJoiner.FileCount = 0 then
|
||
exit;
|
||
|
||
// ũ<><C5A9> <20><><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ũ<>Ⱑ ¦<><C2A6><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ȴ<EFBFBD> 21_0721 08:15:50 sunk
|
||
if (nWidth_ mod 2) <> 0 then
|
||
Dec(nWidth_);
|
||
if (nHeight_ mod 2) <> 0 then
|
||
Dec(nHeight_);
|
||
|
||
FFJoiner.DesireVideoWidth := nWidth_;
|
||
FFJoiner.DesireVideoHeight := nHeight_;
|
||
|
||
InitInputOptions(@IO);
|
||
IO.Options := '-f ffjoin'; // force to use ffjoin format
|
||
|
||
nTaskIdx := FFEncoder.AddTask(IntToStr(NativeUInt(FFJoiner)), @IO);
|
||
if nTaskIdx < 0 then
|
||
begin
|
||
TTgTrace.T('Encoder error .. "%s"', [FFEncoder.LastErrMsg]);
|
||
exit;
|
||
end;
|
||
|
||
// set output options
|
||
InitOutputOptions(@OO);
|
||
|
||
// mp4 output options
|
||
OO.Options := '-c:a ' + AAC_Encoder + ' -b:a 128k -ar 44100 ' +
|
||
Format('-c:v mpeg4 -s %dx%d ', [nWidth_, nHeight_]);
|
||
case Config_.RecQuality of
|
||
0 : OO.Options := OO.Options + '-b:v 2000k';
|
||
2 : OO.Options := OO.Options + '-b:v 500k';
|
||
else OO.Options := OO.Options + '-b:v 1000k';
|
||
end;
|
||
|
||
if FFEncoder.SetOutput(nTaskIdx, sOutMovPath_, @OO) < 0 then
|
||
begin
|
||
FFEncoder.RemoveTask(nTaskIdx);
|
||
sMsg := Format('Encoder error .. Cannot do convert, "%s"', [FFEncoder.LastErrMsg]);
|
||
TTgTrace.T(sMsg);
|
||
// MessageBox(Handle, PChar(sMsg), PChar(Caption), MB_ICONWARNING or MB_OK);
|
||
exit;
|
||
end;
|
||
|
||
FFEncoder.Start(1);
|
||
|
||
Result := true;
|
||
finally
|
||
if not Result then
|
||
StopMergeWait;
|
||
end;
|
||
end;
|
||
|
||
procedure TDlgBs1RcdMain.btnRecStopClick(Sender: TObject);
|
||
begin
|
||
StopRecord;
|
||
|
||
end;
|
||
|
||
procedure TDlgBs1RcdMain.ShowWindow(bVal: Boolean);
|
||
begin
|
||
if bVal then
|
||
begin
|
||
var bOnTop: Boolean := FormStyle = fsStayOnTop;
|
||
if not bOnTop then
|
||
FormStyle := fsStayOnTop;
|
||
|
||
Show;
|
||
WindowState := wsNormal;
|
||
|
||
if not bOnTop then
|
||
FormStyle := fsNormal;
|
||
end else begin
|
||
WindowState := wsMinimized;
|
||
Hide;
|
||
end;
|
||
end;
|
||
|
||
procedure TDlgBs1RcdMain.process_WM_WINDOWPOSCHANGING(var msg: TMessage);
|
||
begin
|
||
if BorderStyle = bsSizeable then
|
||
begin
|
||
UpdateRecFramePositionInfo;
|
||
UpdateRecFrameSizeInfo;
|
||
end;
|
||
end;
|
||
|
||
procedure TDlgBs1RcdMain.process_WM_SYSCOMMAD( var msg: TWMSysCommand);
|
||
begin
|
||
if msg.CmdType = SC_CLOSE then
|
||
begin
|
||
miExit.Click;
|
||
exit;
|
||
end;
|
||
Inherited;
|
||
end;
|
||
|
||
procedure TDlgBs1RcdMain.process_WM_START_RECORD(var msg: TMessage);
|
||
var
|
||
O: ISuperObject;
|
||
begin
|
||
try
|
||
if ThdRecordWait_ = nil then
|
||
exit;
|
||
|
||
sOutMovPath_ := ThdRecordWait_.OutPath;
|
||
StartRecord;
|
||
|
||
O := SO;
|
||
O.S['RS'] := ThdRecordWait_.Reason;
|
||
if gParam.TaskInfo.hRcvWnd <> 0 then
|
||
SendData(gParam.TaskInfo.hRcvWnd, HPCMD_START_SCREEN_RECORD, O.AsJSon);
|
||
except
|
||
on E: Exception do
|
||
ETgException.TraceException(Self, E, 'Fail .. process_WM_START_RECORD()');
|
||
end;
|
||
end;
|
||
|
||
procedure TDlgBs1RcdMain.process_WM_STOP_RECORD(var msg: TMessage);
|
||
var
|
||
O: ISuperObject;
|
||
llMSec: LONGLONG;
|
||
begin
|
||
try
|
||
if ThdRecordWait_ = nil then
|
||
exit;
|
||
|
||
llMSec := GetTickCount64 - ThdRecordWait_.RcdTick;
|
||
|
||
StopRecord;
|
||
|
||
O := SO;
|
||
O.S['OD'] := sOutMovPath_;
|
||
O.S['RS'] := ThdRecordWait_.Reason;
|
||
O.I['MS'] := llMSec;
|
||
if gParam.TaskInfo.hRcvWnd <> 0 then
|
||
SendData(gParam.TaskInfo.hRcvWnd, HPCMD_STOP_SCREEN_RECORD, O.AsJSon);
|
||
|
||
sOutMovPath_ := '';
|
||
nLeft_ := -1;
|
||
nTop_ := -1;
|
||
nWidth_ := -1;
|
||
nHeight_ := -1;
|
||
RecPathList_.Clear;
|
||
FFEncoder.ClearTasks;
|
||
ThdRecordWait_.InitRecord;
|
||
except
|
||
on E: Exception do
|
||
ETgException.TraceException(Self, E, 'Fail .. process_WM_STOP_RECORD()');
|
||
end;
|
||
end;
|
||
|
||
procedure TDlgBs1RcdMain.process_WM_COPYDATA(var msg: TMessage);
|
||
var
|
||
dwData: DWORD;
|
||
pCpData: PCopyDataStruct;
|
||
TaskInfo: TTaskInfo;
|
||
O: ISuperObject;
|
||
begin
|
||
msg.Result := 0;
|
||
|
||
dwData := 0;
|
||
pCpData := PCopyDataStruct(msg.LParam);
|
||
try
|
||
dwData := pCpData.dwData;
|
||
case dwData of
|
||
9091 : // <20><>å <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ʈ
|
||
begin
|
||
if ThdRecordWait_ = nil then
|
||
exit;
|
||
|
||
O := SO(Copy(PChar(pCpData.lpData), 1, pCpData.cbData));
|
||
TaskInfo := ThdRecordWait_.TaskInfo;
|
||
TaskInfo.sApps := O.S['Apps'];
|
||
TaskInfo.nMaxMain := O.I['MaxMin'];
|
||
ThdRecordWait_.TaskInfo := TaskInfo;
|
||
end;
|
||
end;
|
||
except
|
||
on E: Exception do
|
||
ETgException.TraceException(Self, E, 'Fail .. process_WM_COPYDATA()');
|
||
end;
|
||
end;
|
||
|
||
end.
|