Programmierung > Delphi > bbMPEG - DLL

Information zum Source Code

Ausführung von bbMPEG

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.

bbMPEG unter XP

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 des Muxvorganges ist nur der zweite Button mit der Beschriftung "Suspend" aktiv. Nach Beendigung des Muxvorganges wird er inaktiv und der mittlere Button wird aktiviert. Gleichzeitig wird dessen Beschriftung von "Cancel" auf "Ok" geändert. Auf diesen müsste nun geklickt werden. Wenn man an das Handle kommt, geht es so:

hBtn := FindbbMPEGOkButton;
if (hBtn <> INVALID_HANDLE_VALUE)
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. Unter Umständen kann es auch passieren, dass der deaktivierte Button ausgelöst wird. Deshalb wird hier ein Button mit der Beschriftung "Ok" gesucht. Gefunden wird er erst wenn bbMPEG den Muxvorgang abgeschlossen 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;