2

我有一个带有向导的 Delphi 6 应用程序,可以帮助人们选择合适的视频编解码器。它使用 AviSaveOptions() 向用户显示视频编解码器列表,以便他们选择一个。选择保存到磁盘以供以后重复使用。在向导中的某一时刻,如果用户没有合适的视频编解码器,则会指示用户使用其浏览器下载并安装几种流行的视频编解码器中的一种。但是,在他们安装新的视频编解码器并返回我的应用程序后,当我第二次调用 AviSaveOptions() 以便他们可以选择新安装的视频编解码器时,列表不会显示新的编解码器。

如果我完全退出我的应用程序并返回到向导,调用 AviSaveOptions()确实会在对话框中显示新的编解码器。我显然想从我的应用程序中刷新列表,这样用户就不必重新加载程序来选择新的编解码器。我确实在调用 AviSaveOptions() 的方法中调用了 AviFileInit() 和 AviFileExit()。我还需要做什么才能更新 AviSaveOptions() 对话框中显示的编解码器列表以显示新安装的视频编解码器?下面是我用来调用 AviSaveOptions() 的代码:

function doGetUsersCompressorChoice(theCallingForm: TForm; theFccType: FOURCC): FOURCC;
var
    // theCompressionOptionsFile: TAviCompressionOptionsFile;
    theCompressionOptions: TAVICOMPRESSOPTIONS;
    res: LongBool;
    hr: HRESULT;
    intfAviStream: IAVIStream;
    testVideoFilenameSrc, testVideoFilename: string;
    aryCompressOpts: array[0..0] of PAVICOMPRESSOPTIONS;
    fullSaveOptsFilePath: string;
begin
    // fullPathToCompressorOptsFile := '';
    if not Assigned(theCallingForm) then
        raise Exception.Create('(doGetUsersCompressorChoice) The calling form is unassigned.');

    // Make sure the test video file exists.
    testVideoFilenameSrc := getTestVideoPath_compsettings + TEST_COMPRESSION_VIDEO_FILENAME;

    if not FileExists(testVideoFilenameSrc) then
        raise Exception.Create('(doGetUsersCompressorChoice) Unable to find the test video file: ' + testVideoFilename);

    // Copy it since we are about to tinker with it and don't want to damage
    //  the original.
    testVideoFilename := ChangeFileExt(testVideoFilenameSrc, '.comptest.avi');

    if FileExists(testVideoFilename) then
    begin
        // Delete it.
        if not DeleteFile(testVideoFilename) then
            raise Exception.Create('(doGetUsersCompressorChoice) Unable to delete the test video file: ' + testVideoFilename);
    end; // if FileExists(testVideoFilename) then

    // Copy the source to the test file.
    if not CopyFile(PChar(testVideoFilenameSrc), PChar(testVideoFilename), true) then
        raise Exception.Create('(doGetUsersCompressorChoice) Unable to copy the source video file to the test video file (source, dest): ' + testVideoFilenameSrc + ', ' + testVideoFilename);

    AVIFileInit;

    FillChar(theCompressionOptions, SizeOf(theCompressionOptions), 0);

    aryCompressOpts[0] := @theCompressionOptions;

    // theCompressionOptionsFile := TAviCompressionOptionsFile.Create;

    try
        // Open the test video file.
        hr := AVIStreamOpenFromFile(intfAviStream, PChar(testVideoFilename), theFccType, 0, OF_READ, nil);

        checkAviResult('doGetUsersCompressorChoice', hr, 'Unable to open the test video file (AVIStreamOpenFromFile)');

        // Now prompt the user for the desired compressor.
        res := AVISaveOptions(theCallingForm.Handle, 0, 1, intfAviStream, aryCompressOpts[0]);

        if res then
        begin
            {
                IMPORTANT: Microsoft does not use the fccType field for
                audio compressors and leaves it 0 when calling AviSaveOptions().
                To compensate we are using a fake FOURCC equal to
                ('f','a','k','e') for audio compressors.

                Therefore, you can't tell which audio compressor is in
                use.  The fake FOURCC is only to keep the compressor
                options file object and methods happy since they
                need an identifier to use when storing the compressor
                settings.

                We have a message about this on Stack Overflow but
                so far no one has provided an answer on how to ID
                the compressor being returned by

            }

            if theFccType = streamtypeAUDIO then
                Result := stringToFOURCC(FOURCC_FAKE_AUDIO_COMPRESSOR_ID)
            else
                // Result is the FOURCC of the selected compressor.
                Result := aryCompressOpts[0]^.fccHandler;

            try
                fullSaveOptsFilePath := getCompressorOptsFullFilePath(Result);

                // Save the user's selected compressor settings to disk.
                // theCompressionOptionsFile.save(aryCompressOpts[0]^);
                if writeCompOptsFile(fullSaveOptsFilePath, aryCompressOpts[0]^) <> AVIERR_OK then
                    raise Exception.Create('(doGetUsersCompressorChoice) Unable to save the compressor options to disk, file name: ' + fullSaveOptsFilePath);

                // Return the full path to the saved compressor options file.
                // fullPathToCompressorOptsFile :=
                //    theCompressionOptionsFile.fullFilename;
            finally
                // Free the compression options variable.
                AVISaveOptionsFree(1, aryCompressOpts[0]);
            end; // try
        end
        else
        begin
            // User aborted operation.  Just return the Result of 0.
            Result := 0;
        end;
    finally
        // if Assigned(theCompressionOptionsFile) then
        //    theCompressionOptionsFile.Free;

        AviFileExit;
    end; // try
end;
4

0 回答 0