556 lines
20 KiB
ObjectPascal
556 lines
20 KiB
ObjectPascal
unit MultimediaDemoMain;
|
|
|
|
interface
|
|
|
|
{$I jcl.inc}
|
|
|
|
uses
|
|
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
|
|
StdCtrls, ComCtrls, MMSystem, JclMultimedia;
|
|
|
|
type
|
|
TMainForm = class(TForm)
|
|
PageControl: TPageControl;
|
|
TabSheet1: TTabSheet;
|
|
Label2: TLabel;
|
|
OpenDriveBtn: TButton;
|
|
CloseDriveBtn: TButton;
|
|
MediaPresentBtn: TButton;
|
|
AudioInfoBtn: TButton;
|
|
AudioInfoMemo: TMemo;
|
|
GroupBox1: TGroupBox;
|
|
Label1: TLabel;
|
|
DriveComboBox: TComboBox;
|
|
DefaultDriveCheckBox: TCheckBox;
|
|
TabSheet2: TTabSheet;
|
|
MixerTreeView: TTreeView;
|
|
Label3: TLabel;
|
|
MixerDetailListView: TListView;
|
|
Label4: TLabel;
|
|
GroupBox2: TGroupBox;
|
|
SpeakersMuteCheckBox: TCheckBox;
|
|
SaveMixerBtn: TButton;
|
|
SaveDialog: TSaveDialog;
|
|
procedure FormCreate(Sender: TObject);
|
|
procedure OpenDriveBtnClick(Sender: TObject);
|
|
procedure CloseDriveBtnClick(Sender: TObject);
|
|
procedure MediaPresentBtnClick(Sender: TObject);
|
|
procedure AudioInfoBtnClick(Sender: TObject);
|
|
procedure DefaultDriveCheckBoxClick(Sender: TObject);
|
|
procedure FormDestroy(Sender: TObject);
|
|
procedure MixerTreeViewCustomDrawItem(Sender: TCustomTreeView;
|
|
Node: TTreeNode; State: TCustomDrawState; var DefaultDraw: Boolean);
|
|
procedure MixerTreeViewChange(Sender: TObject; Node: TTreeNode);
|
|
procedure SpeakersMuteCheckBoxClick(Sender: TObject);
|
|
procedure SaveMixerBtnClick(Sender: TObject);
|
|
private
|
|
FComponentTypes: TStringList;
|
|
FControlTypes: TStringList;
|
|
FMixer: TJclMixer;
|
|
procedure BuildDrives;
|
|
procedure BuildMixerTree;
|
|
procedure BuildTypesList;
|
|
function GetSelectedDrive: Char;
|
|
procedure SaveMixerToFile(const FileName: string);
|
|
procedure UpdateMixerDetails(MixerObject: TObject);
|
|
procedure UpdateMixerControl(MixerHandle: HMIXER; ControlID: DWORD);
|
|
procedure UpdateMixerLine(MixerHandle: HMIXER; LineID: DWORD);
|
|
procedure UpdateSelectedMixerInfo;
|
|
procedure UpdateMixerSpeakerControls;
|
|
procedure WMMmMixmControlChange(var Message: TMessage); message MM_MIXM_CONTROL_CHANGE;
|
|
procedure WMMmMixmLineChange(var Message: TMessage); message MM_MIXM_LINE_CHANGE;
|
|
function GetSelectedMixerTreeObject: TObject;
|
|
public
|
|
function ComponentTypeConstToString(ComponentType: DWORD): string;
|
|
function ControlTypeConstToString(ControlType: DWORD): string;
|
|
property SelectedDrive: Char read GetSelectedDrive;
|
|
property SelectedMixerTreeObject: TObject read GetSelectedMixerTreeObject;
|
|
end;
|
|
|
|
var
|
|
MainForm: TMainForm;
|
|
|
|
implementation
|
|
|
|
{$R *.DFM}
|
|
|
|
uses
|
|
JclFileUtils, JclStrings, JclSysUtils;
|
|
|
|
{ TMainForm }
|
|
|
|
procedure TMainForm.FormCreate(Sender: TObject);
|
|
begin
|
|
FComponentTypes := TStringList.Create;
|
|
FControlTypes := TStringList.Create;
|
|
BuildTypesList;
|
|
FMixer := TJclMixer.Create(Handle);
|
|
BuildDrives;
|
|
BuildMixerTree;
|
|
UpdateMixerSpeakerControls;
|
|
end;
|
|
|
|
procedure TMainForm.FormDestroy(Sender: TObject);
|
|
begin
|
|
FreeAndNil(FComponentTypes);
|
|
FreeAndNil(FControlTypes);
|
|
FreeAndNil(FMixer);
|
|
end;
|
|
|
|
procedure TMainForm.BuildTypesList;
|
|
begin
|
|
FComponentTypes.AddObject('MIXERLINE_COMPONENTTYPE_DST_UNDEFINED', Pointer(MIXERLINE_COMPONENTTYPE_DST_UNDEFINED));
|
|
FComponentTypes.AddObject('MIXERLINE_COMPONENTTYPE_DST_DIGITAL', Pointer(MIXERLINE_COMPONENTTYPE_DST_DIGITAL));
|
|
FComponentTypes.AddObject('MIXERLINE_COMPONENTTYPE_DST_LINE', Pointer(MIXERLINE_COMPONENTTYPE_DST_LINE));
|
|
FComponentTypes.AddObject('MIXERLINE_COMPONENTTYPE_DST_MONITOR', Pointer(MIXERLINE_COMPONENTTYPE_DST_MONITOR));
|
|
FComponentTypes.AddObject('MIXERLINE_COMPONENTTYPE_DST_SPEAKERS', Pointer(MIXERLINE_COMPONENTTYPE_DST_SPEAKERS));
|
|
FComponentTypes.AddObject('MIXERLINE_COMPONENTTYPE_DST_HEADPHONES', Pointer(MIXERLINE_COMPONENTTYPE_DST_HEADPHONES));
|
|
FComponentTypes.AddObject('MIXERLINE_COMPONENTTYPE_DST_TELEPHONE', Pointer(MIXERLINE_COMPONENTTYPE_DST_TELEPHONE));
|
|
FComponentTypes.AddObject('MIXERLINE_COMPONENTTYPE_DST_WAVEIN', Pointer(MIXERLINE_COMPONENTTYPE_DST_WAVEIN));
|
|
FComponentTypes.AddObject('MIXERLINE_COMPONENTTYPE_DST_VOICEIN', Pointer(MIXERLINE_COMPONENTTYPE_DST_VOICEIN));
|
|
FComponentTypes.AddObject('MIXERLINE_COMPONENTTYPE_SRC_UNDEFINED', Pointer(MIXERLINE_COMPONENTTYPE_SRC_UNDEFINED));
|
|
FComponentTypes.AddObject('MIXERLINE_COMPONENTTYPE_SRC_DIGITAL', Pointer(MIXERLINE_COMPONENTTYPE_SRC_DIGITAL));
|
|
FComponentTypes.AddObject('MIXERLINE_COMPONENTTYPE_SRC_LINE', Pointer(MIXERLINE_COMPONENTTYPE_SRC_LINE));
|
|
FComponentTypes.AddObject('MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE', Pointer(MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE));
|
|
FComponentTypes.AddObject('MIXERLINE_COMPONENTTYPE_SRC_SYNTHESIZER', Pointer(MIXERLINE_COMPONENTTYPE_SRC_SYNTHESIZER));
|
|
FComponentTypes.AddObject('MIXERLINE_COMPONENTTYPE_SRC_COMPACTDISC', Pointer(MIXERLINE_COMPONENTTYPE_SRC_COMPACTDISC));
|
|
FComponentTypes.AddObject('MIXERLINE_COMPONENTTYPE_SRC_TELEPHONE', Pointer(MIXERLINE_COMPONENTTYPE_SRC_TELEPHONE));
|
|
FComponentTypes.AddObject('MIXERLINE_COMPONENTTYPE_SRC_PCSPEAKER', Pointer(MIXERLINE_COMPONENTTYPE_SRC_PCSPEAKER));
|
|
FComponentTypes.AddObject('MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT', Pointer(MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT));
|
|
FComponentTypes.AddObject('MIXERLINE_COMPONENTTYPE_SRC_AUXILIARY', Pointer(MIXERLINE_COMPONENTTYPE_SRC_AUXILIARY));
|
|
FComponentTypes.AddObject('MIXERLINE_COMPONENTTYPE_SRC_ANALOG', Pointer(MIXERLINE_COMPONENTTYPE_SRC_ANALOG));
|
|
FControlTypes.AddObject('MIXERCONTROL_CONTROLTYPE_CUSTOM', Pointer(MIXERCONTROL_CONTROLTYPE_CUSTOM));
|
|
FControlTypes.AddObject('MIXERCONTROL_CONTROLTYPE_BOOLEANMETER', Pointer(MIXERCONTROL_CONTROLTYPE_BOOLEANMETER));
|
|
FControlTypes.AddObject('MIXERCONTROL_CONTROLTYPE_SIGNEDMETER', Pointer(MIXERCONTROL_CONTROLTYPE_SIGNEDMETER));
|
|
FControlTypes.AddObject('MIXERCONTROL_CONTROLTYPE_PEAKMETER', Pointer(MIXERCONTROL_CONTROLTYPE_PEAKMETER));
|
|
FControlTypes.AddObject('MIXERCONTROL_CONTROLTYPE_UNSIGNEDMETER', Pointer(MIXERCONTROL_CONTROLTYPE_UNSIGNEDMETER));
|
|
FControlTypes.AddObject('MIXERCONTROL_CONTROLTYPE_BOOLEAN', Pointer(MIXERCONTROL_CONTROLTYPE_BOOLEAN));
|
|
FControlTypes.AddObject('MIXERCONTROL_CONTROLTYPE_ONOFF', Pointer(MIXERCONTROL_CONTROLTYPE_ONOFF));
|
|
FControlTypes.AddObject('MIXERCONTROL_CONTROLTYPE_MUTE', Pointer(MIXERCONTROL_CONTROLTYPE_MUTE));
|
|
FControlTypes.AddObject('MIXERCONTROL_CONTROLTYPE_MONO', Pointer(MIXERCONTROL_CONTROLTYPE_MONO));
|
|
FControlTypes.AddObject('MIXERCONTROL_CONTROLTYPE_LOUDNESS', Pointer(MIXERCONTROL_CONTROLTYPE_LOUDNESS));
|
|
FControlTypes.AddObject('MIXERCONTROL_CONTROLTYPE_STEREOENH', Pointer(MIXERCONTROL_CONTROLTYPE_STEREOENH));
|
|
FControlTypes.AddObject('MIXERCONTROL_CONTROLTYPE_BUTTON', Pointer(MIXERCONTROL_CONTROLTYPE_BUTTON));
|
|
FControlTypes.AddObject('MIXERCONTROL_CONTROLTYPE_DECIBELS', Pointer(MIXERCONTROL_CONTROLTYPE_DECIBELS));
|
|
FControlTypes.AddObject('MIXERCONTROL_CONTROLTYPE_SIGNED', Pointer(MIXERCONTROL_CONTROLTYPE_SIGNED));
|
|
FControlTypes.AddObject('MIXERCONTROL_CONTROLTYPE_UNSIGNED', Pointer(MIXERCONTROL_CONTROLTYPE_UNSIGNED));
|
|
FControlTypes.AddObject('MIXERCONTROL_CONTROLTYPE_PERCENT', Pointer(MIXERCONTROL_CONTROLTYPE_PERCENT));
|
|
FControlTypes.AddObject('MIXERCONTROL_CONTROLTYPE_SLIDER', Pointer(MIXERCONTROL_CONTROLTYPE_SLIDER));
|
|
FControlTypes.AddObject('MIXERCONTROL_CONTROLTYPE_PAN', Pointer(MIXERCONTROL_CONTROLTYPE_PAN));
|
|
FControlTypes.AddObject('MIXERCONTROL_CONTROLTYPE_QSOUNDPAN', Pointer(MIXERCONTROL_CONTROLTYPE_QSOUNDPAN));
|
|
FControlTypes.AddObject('MIXERCONTROL_CONTROLTYPE_FADER', Pointer(MIXERCONTROL_CONTROLTYPE_FADER));
|
|
FControlTypes.AddObject('MIXERCONTROL_CONTROLTYPE_VOLUME', Pointer(MIXERCONTROL_CONTROLTYPE_VOLUME));
|
|
FControlTypes.AddObject('MIXERCONTROL_CONTROLTYPE_BASS', Pointer(MIXERCONTROL_CONTROLTYPE_BASS));
|
|
FControlTypes.AddObject('MIXERCONTROL_CONTROLTYPE_TREBLE', Pointer(MIXERCONTROL_CONTROLTYPE_TREBLE));
|
|
FControlTypes.AddObject('MIXERCONTROL_CONTROLTYPE_EQUALIZER', Pointer(MIXERCONTROL_CONTROLTYPE_EQUALIZER));
|
|
FControlTypes.AddObject('MIXERCONTROL_CONTROLTYPE_SINGLESELECT', Pointer(MIXERCONTROL_CONTROLTYPE_SINGLESELECT));
|
|
FControlTypes.AddObject('MIXERCONTROL_CONTROLTYPE_MUX', Pointer(MIXERCONTROL_CONTROLTYPE_MUX));
|
|
FControlTypes.AddObject('MIXERCONTROL_CONTROLTYPE_MULTIPLESELECT', Pointer(MIXERCONTROL_CONTROLTYPE_MULTIPLESELECT));
|
|
FControlTypes.AddObject('MIXERCONTROL_CONTROLTYPE_MIXER', Pointer(MIXERCONTROL_CONTROLTYPE_MIXER));
|
|
FControlTypes.AddObject('MIXERCONTROL_CONTROLTYPE_MICROTIME', Pointer(MIXERCONTROL_CONTROLTYPE_MICROTIME));
|
|
FControlTypes.AddObject('MIXERCONTROL_CONTROLTYPE_MILLITIME', Pointer(MIXERCONTROL_CONTROLTYPE_MILLITIME));
|
|
end;
|
|
|
|
function TMainForm.ComponentTypeConstToString(ComponentType: DWORD): string;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
Result := '';
|
|
for I := 0 to FComponentTypes.Count - 1 do
|
|
if DWORD(FComponentTypes.Objects[I]) = ComponentType then
|
|
begin
|
|
Result := FComponentTypes[I];
|
|
Break;
|
|
end;
|
|
end;
|
|
|
|
function TMainForm.ControlTypeConstToString(ControlType: DWORD): string;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
Result := '';
|
|
for I := 0 to FControlTypes.Count - 1 do
|
|
if DWORD(FControlTypes.Objects[I]) = ControlType then
|
|
begin
|
|
Result := FControlTypes[I];
|
|
Break;
|
|
end;
|
|
end;
|
|
|
|
//==================================================================================================
|
|
// CD audio
|
|
//==================================================================================================
|
|
|
|
procedure TMainForm.BuildDrives;
|
|
var
|
|
D: Char;
|
|
DriveStr: string;
|
|
begin
|
|
for D := 'A' to 'Z' do
|
|
begin
|
|
DriveStr := D + ':\';
|
|
if GetDriveType(PChar(DriveStr)) = DRIVE_CDROM then
|
|
DriveComboBox.Items.Add(D);
|
|
end;
|
|
if DriveComboBox.Items.Count > 0 then
|
|
DriveComboBox.ItemIndex := 0;
|
|
end;
|
|
|
|
procedure TMainForm.DefaultDriveCheckBoxClick(Sender: TObject);
|
|
begin
|
|
DriveComboBox.Enabled := not DefaultDriveCheckBox.Checked;
|
|
end;
|
|
|
|
function TMainForm.GetSelectedDrive: Char;
|
|
begin
|
|
if DefaultDriveCheckBox.Checked then
|
|
Result := #0
|
|
else
|
|
Result := DriveComboBox.Text[1];
|
|
end;
|
|
|
|
procedure TMainForm.OpenDriveBtnClick(Sender: TObject);
|
|
begin
|
|
Screen.Cursor := crHourGlass;
|
|
try
|
|
OpenCloseCdDrive(True, SelectedDrive);
|
|
finally
|
|
Screen.Cursor := crDefault;
|
|
end;
|
|
end;
|
|
|
|
procedure TMainForm.CloseDriveBtnClick(Sender: TObject);
|
|
begin
|
|
Screen.Cursor := crHourGlass;
|
|
try
|
|
OpenCloseCdDrive(False, SelectedDrive);
|
|
finally
|
|
Screen.Cursor := crDefault;
|
|
end;
|
|
end;
|
|
|
|
procedure TMainForm.MediaPresentBtnClick(Sender: TObject);
|
|
begin
|
|
Screen.Cursor := crHourGlass;
|
|
try
|
|
ShowMessage(BooleanToStr(IsMediaPresentInDrive(SelectedDrive)));
|
|
finally
|
|
Screen.Cursor := crDefault;
|
|
end;
|
|
end;
|
|
|
|
procedure TMainForm.AudioInfoBtnClick(Sender: TObject);
|
|
var
|
|
TotalTimeStr: string;
|
|
begin
|
|
Screen.Cursor := crHourGlass;
|
|
AudioInfoMemo.Lines.BeginUpdate;
|
|
try
|
|
AudioInfoMemo.Lines.Add('Product : ' + GetCdInfo(miProduct, SelectedDrive));
|
|
AudioInfoMemo.Lines.Add('Identity : ' + GetCdInfo(miIdentity, SelectedDrive));
|
|
AudioInfoMemo.Lines.Add('Universal Product Code : ' + GetCdInfo(miUPC, SelectedDrive));
|
|
TotalTimeStr := GetCDAudioTrackList(AudioInfoMemo.Lines, True, SelectedDrive);
|
|
AudioInfoMemo.Lines.Add('Total time: ' + TotalTimeStr);
|
|
finally
|
|
AudioInfoMemo.Lines.EndUpdate;
|
|
Screen.Cursor := crDefault;
|
|
end;
|
|
AudioInfoMemo.Lines.Add('');
|
|
end;
|
|
|
|
//==================================================================================================
|
|
// Audio mixer
|
|
//==================================================================================================
|
|
|
|
procedure TMainForm.BuildMixerTree;
|
|
var
|
|
DeviceIndex, DestionationIndex, SourceIndex, LineControlIndex: Integer;
|
|
DeviceNode, DestionationNode, SourceNode: TTreeNode;
|
|
Device: TJclMixerDevice;
|
|
Destination: TJclMixerDestination;
|
|
SourceLine: TJclMixerSource;
|
|
LineControl: TJclMixerLineControl;
|
|
begin
|
|
with MixerTreeView do
|
|
begin
|
|
Items.BeginUpdate;
|
|
Screen.Cursor := crHourGlass;
|
|
try
|
|
Items.Clear;
|
|
for DeviceIndex := 0 to FMixer.DeviceCount - 1 do
|
|
begin
|
|
Device := FMixer.Devices[DeviceIndex];
|
|
DeviceNode := Items.AddChildObjectFirst(nil, Device.ProductName, Device);
|
|
|
|
for DestionationIndex := 0 to Device.DestinationCount - 1 do
|
|
begin
|
|
Destination := Device.Destinations[DestionationIndex];
|
|
DestionationNode := Items.AddChildObjectFirst(DeviceNode, Destination.Name, Destination);
|
|
|
|
for LineControlIndex := 0 to Destination.LineControlCount - 1 do
|
|
begin
|
|
LineControl := Destination.LineControls[LineControlIndex];
|
|
Items.AddChildObjectFirst(DestionationNode, LineControl.Name, LineControl);
|
|
end;
|
|
|
|
for SourceIndex := 0 to Destination.SourceCount - 1 do
|
|
begin
|
|
SourceLine := Destination.Sources[SourceIndex];
|
|
SourceNode := Items.AddChildObjectFirst(DestionationNode, SourceLine.Name, SourceLine);
|
|
|
|
for LineControlIndex := 0 to SourceLine.LineControlCount - 1 do
|
|
begin
|
|
LineControl := SourceLine.LineControls[LineControlIndex];
|
|
Items.AddChildObjectFirst(SourceNode, LineControl.Name, LineControl);
|
|
end;
|
|
|
|
end;
|
|
end;
|
|
end;
|
|
FullExpand;
|
|
if Items.Count > 0 then
|
|
begin
|
|
Selected := Items.GetFirstNode;
|
|
Selected.MakeVisible;
|
|
end;
|
|
finally
|
|
Items.EndUpdate;
|
|
Screen.Cursor := crDefault;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TMainForm.GetSelectedMixerTreeObject: TObject;
|
|
begin
|
|
if MixerTreeView.Selected <> nil then
|
|
Result := TObject(MixerTreeView.Selected.Data)
|
|
else
|
|
Result := nil;
|
|
end;
|
|
|
|
procedure TMainForm.SaveMixerToFile(const FileName: string);
|
|
var
|
|
List: TStringList;
|
|
I, D: Integer;
|
|
Node: TTreeNode;
|
|
C: Char;
|
|
begin
|
|
List := TStringList.Create;
|
|
MixerDetailListView.Items.BeginUpdate;
|
|
try
|
|
for I := 0 to MixerTreeView.Items.Count - 1 do
|
|
begin
|
|
Node := MixerTreeView.Items[I];
|
|
UpdateMixerDetails(TObject(Node.Data));
|
|
case Node.Level of
|
|
0: C := ' ';
|
|
1: C := '=';
|
|
2: C := '+';
|
|
3: C := '-';
|
|
else
|
|
C := '!';
|
|
end;
|
|
List.Add(Format('%*s%s %s', [Node.Level * 2, '', Node.Text, StringOfChar(C, 119 - Node.Level * 2 - Length(Node.Text))]));
|
|
with MixerDetailListView.Items do
|
|
for D := 0 to Count - 1 do
|
|
begin
|
|
List.Add(Format('%*s%s=%s', [Node.Level * 2, '', Item[D].Caption, Item[D].SubItems[0]]));
|
|
end;
|
|
List.Add('');
|
|
end;
|
|
List.SaveToFile(FileName);
|
|
Node := MixerTreeView.Selected;
|
|
if Assigned(Node) then
|
|
UpdateMixerDetails(TObject(Node.Data))
|
|
else
|
|
UpdateMixerDetails(nil);
|
|
finally
|
|
MixerDetailListView.Items.EndUpdate;
|
|
List.Free;
|
|
end;
|
|
end;
|
|
|
|
procedure TMainForm.UpdateMixerDetails(MixerObject: TObject);
|
|
|
|
procedure AddLine(const ItemName, Value: string);
|
|
begin
|
|
with MixerDetailListView.Items.Add do
|
|
begin
|
|
Caption := ItemName;
|
|
SubItems.Add(Value);
|
|
end;
|
|
end;
|
|
|
|
procedure BuildMixerDeviceDetails(Device: TJclMixerDevice);
|
|
begin
|
|
with Device do
|
|
begin
|
|
AddLine('Handle', IntToHex(Handle, 8));
|
|
AddLine('Mid', IntToHex(Capabilities.wMid, 4));
|
|
AddLine('Pid', IntToHex(Capabilities.wPid, 4));
|
|
with WordRec(LongRec(Capabilities.vDriverVersion).Lo) do
|
|
AddLine('Driver version', FormatVersionString(Hi, Lo));
|
|
AddLine('Support', IntToHex(Capabilities.fdwSupport, 8));
|
|
end;
|
|
end;
|
|
|
|
procedure BuildMixerLineDetails(Line: TJclMixerLine);
|
|
var
|
|
DisplayName: string;
|
|
begin
|
|
with Line do
|
|
begin
|
|
DisplayName := ComponentString;
|
|
if DisplayName = '' then
|
|
DisplayName := Format('(%.8x)', [LineInfo.dwComponentType]);
|
|
AddLine('Component type', Format('%s [%s]', [DisplayName, ComponentTypeConstToString(LineInfo.dwComponentType)]));
|
|
AddLine('ID', IntToHex(ID, 8));
|
|
AddLine('Channels', IntToStr(LineInfo.cChannels));
|
|
AddLine('Connections', IntToStr(LineInfo.cConnections));
|
|
AddLine('Target name', LineInfo.Target.szPname);
|
|
end;
|
|
end;
|
|
|
|
procedure BuildMixerDestinationDetails(Destination: TJclMixerDestination);
|
|
begin
|
|
BuildMixerLineDetails(Destination);
|
|
end;
|
|
|
|
procedure BuildMixerSourceDetails(Source: TJclMixerSource);
|
|
begin
|
|
BuildMixerLineDetails(Source);
|
|
end;
|
|
|
|
procedure BuildMixerLineControlDetails(LineControl: TJclMixerLineControl);
|
|
begin
|
|
with LineControl do
|
|
begin
|
|
AddLine('ID', IntToHex(ControlInfo.dwControlID, 8));
|
|
AddLine('Control type', Format('%.8x [%s]', [ControlInfo.dwControlType, ControlTypeConstToString(ControlInfo.dwControlType)]));
|
|
AddLine('Disabled', BooleanToStr(IsDisabled));
|
|
AddLine('List', BooleanToStr(IsList));
|
|
AddLine('Multiple', BooleanToStr(IsMultiple));
|
|
AddLine('Uniform', BooleanToStr(IsUniform));
|
|
AddLine('Multiple items', IntToHex(ControlInfo.cMultipleItems, 8));
|
|
if not IsMultiple then
|
|
AddLine('Uniform value', IntToHex(UniformValue, 8));
|
|
AddLine('Minimum', IntToHex(ControlInfo.Bounds.lMinimum, 8));
|
|
AddLine('Maximum', IntToHex(ControlInfo.Bounds.lMaximum, 8));
|
|
AddLine('Steps', IntToHex(ControlInfo.Metrics.cSteps, 8));
|
|
AddLine('Value', ValueString);
|
|
AddLine('List text', ListText.CommaText);
|
|
end;
|
|
end;
|
|
|
|
begin
|
|
with MixerDetailListView do
|
|
begin
|
|
Items.BeginUpdate;
|
|
try
|
|
Items.Clear;
|
|
if MixerObject is TJclMixerDevice then
|
|
BuildMixerDeviceDetails(TJclMixerDevice(MixerObject))
|
|
else
|
|
if MixerObject is TJclMixerDestination then
|
|
BuildMixerDestinationDetails(TJclMixerDestination(MixerObject))
|
|
else
|
|
if MixerObject is TJclMixerSource then
|
|
BuildMixerSourceDetails(TJclMixerSource(MixerObject))
|
|
else
|
|
if MixerObject is TJclMixerLineControl then
|
|
BuildMixerLineControlDetails(TJclMixerLineControl(MixerObject));
|
|
finally
|
|
Items.EndUpdate;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TMainForm.UpdateMixerControl(MixerHandle: HMIXER; ControlID: DWORD);
|
|
var
|
|
Control: TJclMixerLineControl;
|
|
begin
|
|
Control := FMixer.LineControlByID[MixerHandle, ControlID];
|
|
if Control <> nil then
|
|
begin
|
|
if Control = SelectedMixerTreeObject then
|
|
UpdateSelectedMixerInfo;
|
|
end;
|
|
end;
|
|
|
|
procedure TMainForm.UpdateMixerLine(MixerHandle: HMIXER; LineID: DWORD);
|
|
var
|
|
Line: TJclMixerLine;
|
|
begin
|
|
Line := FMixer.LineByID[MixerHandle, LineID];
|
|
if Line <> nil then
|
|
begin
|
|
if Line = SelectedMixerTreeObject then
|
|
UpdateSelectedMixerInfo;
|
|
if Line.LineInfo.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_SPEAKERS then
|
|
UpdateMixerSpeakerControls;
|
|
end;
|
|
end;
|
|
|
|
procedure TMainForm.UpdateSelectedMixerInfo;
|
|
begin
|
|
UpdateMixerDetails(SelectedMixerTreeObject);
|
|
end;
|
|
|
|
procedure TMainForm.UpdateMixerSpeakerControls;
|
|
begin
|
|
SpeakersMuteCheckBox.Checked := FMixer.SpeakersMute;
|
|
end;
|
|
|
|
procedure TMainForm.MixerTreeViewCustomDrawItem(Sender: TCustomTreeView;
|
|
Node: TTreeNode; State: TCustomDrawState; var DefaultDraw: Boolean);
|
|
var
|
|
NodeObject: TObject;
|
|
begin
|
|
NodeObject := TObject(Node.Data);
|
|
if NodeObject is TJclMixerDevice then
|
|
Sender.Canvas.Font.Style := [fsBold]
|
|
else
|
|
if NodeObject is TJclMixerDestination then
|
|
begin
|
|
Sender.Canvas.Font.Style := [fsBold];
|
|
if not (cdsFocused in State) then
|
|
Sender.Canvas.Font.Color := clRed;
|
|
end
|
|
else
|
|
if NodeObject is TJclMixerSource then
|
|
begin
|
|
Sender.Canvas.Font.Style := [fsBold];
|
|
if not (cdsFocused in State) then
|
|
Sender.Canvas.Font.Color := clBlue;
|
|
end;
|
|
end;
|
|
|
|
procedure TMainForm.MixerTreeViewChange(Sender: TObject; Node: TTreeNode);
|
|
begin
|
|
UpdateMixerDetails(TObject(Node.Data));
|
|
end;
|
|
|
|
procedure TMainForm.SpeakersMuteCheckBoxClick(Sender: TObject);
|
|
begin
|
|
FMixer.SpeakersMute := SpeakersMuteCheckBox.Checked;
|
|
end;
|
|
|
|
procedure TMainForm.SaveMixerBtnClick(Sender: TObject);
|
|
begin
|
|
SaveDialog.FileName := 'Mixer.txt';
|
|
if SaveDialog.Execute then
|
|
SaveMixerToFile(SaveDialog.FileName);
|
|
end;
|
|
|
|
procedure TMainForm.WMMmMixmControlChange(var Message: TMessage);
|
|
begin
|
|
UpdateMixerControl(Message.WParam, Message.LParam);
|
|
end;
|
|
|
|
procedure TMainForm.WMMmMixmLineChange(var Message: TMessage);
|
|
begin
|
|
UpdateMixerLine(Message.WParam, Message.LParam);
|
|
end;
|
|
|
|
end.
|