function TbbMPEG.Execute: Cardinal;
{******************************************************************************}
{** bbMPEG ausführen
}
type
TThreadParams = record
fbbMPEGMakeMPEG : TFNbbMPEGMakeMPEG;
fOutputFilename : String;
end;
PThreadParams = ^TThreadParams;
var
ThreadParams : PThreadParams;
hThread : THandle;
ThreadID : Cardinal;
hBtn : THandle;
function Thread(p: PThreadParams): Cardinal;
{****************************************************************************}
{** Die bbMPEG.DLL muss im eigenen Thread ausgeführt werden.
}
var
makeMPEGInfo : TmakeMPEGRecInfo;
begin
FillChar(makeMPEGInfo, SizeOf(makeMPEGInfo), 0);
makeMPEGInfo.outputFilename := PChar(PThreadParams(P)^.fOutputFilename);
Result := PThreadParams(P)^.fbbMPEGMakeMPEG(@makeMPEGInfo);
FreeMem(p, sizeof(TThreadParams));
end;
begin
Result := bbInternalError;
if WriteIni
then begin
...
GetMem(ThreadParams, sizeof(TThreadParams));
ThreadParams.fbbMPEGMakeMPEG := fbbMPEGMakeMPEG;
ThreadParams.fOutputFilename := fbbMPEGSettings.bbIOFiles.OutputFile;
hThread := BeginThread(nil, 0, @Thread, ThreadParams, 0, ThreadID);
if hThread <> INVALID_HANDLE_VALUE
then begin
while WaitForSingleObject(hThread, 1000) = WAIT_TIMEOUT
do begin
Application.ProcessMessages;
...
end;
GetExitCodeThread(hThread, Result);
end;
end;
end;
Die notwendigen Einstellungen bis auf die Ausgabedatei werden in der default.ini gespeichert. Der Name inklusive dem Pfad der Ausgabedatei werden bbMPEG beim Aufruf übergeben. bbMPEG liest nach dem Aufruf die default.ini und nimmt dann seine Arbeit auf.
Ganz so einfach ist es nicht. Führt man bbMPEG nicht im eigenen Thread aus, friert die Anwendung ein. Deshalb wird für bbMPEG ein eigener Thread erstellt. Solange der Thread läuft, wartet die Anwendung auf seine Beendigung.
Für diese modifizierte Version von bbMPEG gibt es keinen XP-Patch. Das heißt, bbMPEG schliesst sich nicht nach der Beendigung seiner Arbeit.
Da sich bbMPEG nicht selbst schließt, wird der Thread auch nicht beendet. Deshalb muss man anders prüfen, wann bbMPEG fertig ist.

Während der Arbeit ist nur der zweite Button mit der Beschriftung "Suspend" aktiv. Anschließend ist nur der mittlere Button aktiv, dessen Beschriftung sich von "Cancel" auf "Ok" geändert hat. Auf diesen müsste nun geklickt werden. Wenn man an das Handle kommt, geht es so:
hBtn := FindbbMPEGOkButton;
if (hBtn <> INVALID_HANDLE_VALUE) and (hBtn > 0)
then SendMessage(hBtn, BM_CLICK, 0, 0);
Bei der Ermittlung des Handle hilft WinSpy. Es erstellt einen Code, mit welchem man das Handle zu einem bestimmten Control ermitteln kann. Dabei wird jedoch nicht die Beschriftung berücksichtigt, sondern ein Zähler verwendet. Dies hat vor einiger Zeit auch funktioniert. Vor kurzem jedoch wurde der deaktivierte Button mit der Beschriftung "Cancel" geklickt und bbMPEG brach ab. Deshalb habe ich den Code so geändert, dass ein Button mit der Beschriftung "Ok" gesucht wird. Gefunden wird er erst wenn bbMPEG seine Arbeit getan hat.
function TbbMPEG.FindbbMPEGOkButton: Hwnd;
{******************************************************************************}
{** Das Handle zum Fenster mit Hilfe des Titels finden.
}
var
wndMain : HWND;
wndChild : HWND;
hChild : HWND;
begin
Result := INVALID_HANDLE_VALUE;
wndMain := FindWindow('OWL_Window','bbMPEG - v1.24 beta 18 (SemiCLI 1.0.0.2)');
if wndMain <> INVALID_HANDLE_VALUE
then begin
wndChild := FindWindowEx(wndMain, 0, '#32770', nil);
hChild := FindWindowEx(wndChild, 0, 'Button', '&Ok');
if hChild <> INVALID_HANDLE_VALUE
then Result := hChild;
end;
end;
Fr_An - Letzte Änderung: 27. Oktober 2009
seit 28. Juli 2010