-
Использую MSAcm.pas где описаны процедуры ACM 1.Почему-то не входит в калбэк для acmFormatEnum 2. Если раскомментирую строку //acmMetrics(HACMOBJ(hACMDrv),.... то по выходу из DriverEnumProc выдает ошибку Runtime Error. не пойму в чем проблема...
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, MMSystem;
type
TForm1 = class(TForm)
Button1: TButton;
ListBox1: TListBox;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
public
end;
var
Form1: TForm1;
implementation
uses MSAcm;
var WaveFormatEx : PWaveFormatEx;
ACMFmtDet : PACMFormatDetails;
function FormatEnumProc(hACMDrvId: HACMDRIVERID; const NewACMFmtDet: PAcmFormatDetails;
dwInstance: DWord; fdwSupport: DWord): longbool; stdcall;
begin
try Result := True;
NewACMFmtDet^.pwfx^.cbSize:=0; TListBox(dwInstance).Items.Add('F'+IntTostr(NewACMFmtDet^.pwfx^.wFormatTag)+
' - C'+IntTostr(NewACMFmtDet^.pwfx^.nChannels)+
' - SPS'+IntTostr(NewACMFmtDet^.pwfx^.nSamplesPerSec)+
' - BPS'+IntTostr(NewACMFmtDet^.pwfx^.wBitsPerSample));
except Result := False; end;
end;
function DriverEnumProc(hACMDrvId: HACMDRIVERID; dwInstance: DWord; fdwSupport: DWord): bool; stdcall;
var MaxSize: Word;
hACMDrv: HACMDriver;
begin
try
Result := True;
if (fdwSupport = ACMDRIVERDETAILS_SUPPORTF_CODEC) then
begin
FillChar(WaveFormatEx^, SizeOf(TWaveFormatEx), #0);
FillChar(ACMFmtDet^, SizeOf(TACMFormatDetails), #0);
hACMDrv := nil;
if acmDriverOpen(hACMDrv, hACMDrvId, 0) = 0 then
begin
MaxSize := MAXWORD;
if MaxSize < SizeOf(TWaveFormatEx) then MaxSize := SizeOf(TWaveFormatEx);
WaveFormatEx^.cbSize := LoWord(MaxSize) - SizeOf(TWaveFormatEx);
WaveFormatEx^.wFormatTag := 0;
ACMFmtDet^.cbStruct := SizeOf(TACMFormatDetails);
ACMFmtDet^.pwfx := WaveFormatEx;
ACMFmtDet^.cbwfx := MaxSize;
ACMFmtDet^.dwFormatTag := 0;
acmFormatEnum(hACMDrv, ACMFmtDet^, @FormatEnumProc, dwInstance, 0);
acmDriverClose(hACMDrv, 0);
end
else
Result := False;
end;
except
Result := False;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
Button1.Enabled:=false;
acmDriverEnum(DriverEnumProc, integer(ListBox1), 0);
Button1.Enabled:=true;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
New(WaveFormatEx);
New(ACMFmtDet);
end;
end.
-
Скорее всего неверная декларация функции или ее соглашения о вызовах...
-
дело было в var MaxSize: Word; надо было обьявлять Cardinal; но теперь новая проблема: При закрытии программы выдает ошибку Invalid Pointer Operation
-
> New(WaveFormatEx); > ACMFmtDet^.cbwfx := MaxSize;
- угу, выделяем sizeof(TWaveFormatEx), а утверждаем, что MaxSize... Обманывать не хорошо, особенно систему...
-
хм... если я ставлю ACMFmtDet^.cbwfx := SizeOf(TWaveFormatEx); то работает без ошибок, но в списке тогда только те форматы у которых нет доп. байтов в заголовке...
-
всем спасибо. заработало в таком варианте финкции
function DriverEnumProc(hACMDrvId: THandle;
dwInstance: DWord; fdwSupport: DWord): bool; stdcall;
var MaxSize: Cardinal;
hACMDrv: THandle;
ACMFmtDet : PACMFormatDetails;
ACMDrvDet : TACMDriverDetails;
p:Pointer;
begin
Result := True;
if fdwSupport<>ACMDRIVERDETAILS_SUPPORTF_CODEC then Exit;
ACMDrvDet.cbStruct := SizeOf(ACMDrvDet);
hACMDrv := 0;
try if acmDriverOpen(hACMDrv, hACMDrvId, 0) = 0 then begin
acmMetrics(HACMOBJ(hACMDrv), ACM_METRIC_MAX_SIZE_FORMAT, MaxSize);
if MaxSize < SizeOf(TWaveFormatEx) then MaxSize := SizeOf(TWaveFormatEx);
p:=AllocMem(MaxSize); FillChar(p^, MaxSize, 0);
New(ACMFmtDet); FillChar(ACMFmtDet^, SizeOf(TACMFormatDetails), 0);
ACMFmtDet^.cbStruct := SizeOf(TACMFormatDetails);
ACMFmtDet^.pwfx := p;
ACMFmtDet^.cbwfx := MaxSize;
ACMFmtDet^.dwFormatTag := 0;
acmFormatEnum(hACMDrv, ACMFmtDet^, @FormatEnumProc, dwInstance, 0);
acmDriverClose(hACMDrv, 0);
Dispose(ACMFmtDet);
FreeMem(p);
end else Result := False;
except Result := False; end;
end;
ЗЫ. респект han_malign за дельную подсказку
-
спасибо всем )
|