Вопрос Озучивание компонентов

Ekspoint

Новичок
а может кто нибудь сделать озвучку компонента при нажатии на кнопку как тут?
 

sergey3695

Ветеран
Модератор
Ekspoint, а где там кнопки?
p.s. хамик у тебя не остался пример что я те кидал? (влом писать) :lol: даже это сообщение. у всех голова болит из-за.. а у кого-то сопельки :bad:
 

Shegorat

Lord of Madness
Администратор
Как-то так
Код:
[Setup]
AppName=My Program
AppVerName=My Program 1.5
DefaultDirName={pf}\My Program
DefaultGroupName=My Program
ComponentsListTVStyle=true

[Files]
Source: sounds\*; flags: dontcopy;

[Languages]
Name: russian; MessagesFile: compiler:Languages\Russian.isl

[Components]
Name: sound; Description: Звук выстрела; Types: full;
Name: sound\snd1; Description: "Тихий"; Flags: exclusive;
Name: sound\snd2; Description: "Громкий"; Flags: exclusive;

[Code]
const
  LB_ITEMFROMPOINT  = $01A9;

type
  TComponentSound = record
    SoundName: String;
    Index: Integer;
  end;
  TSize = record
    cx: Longint;
    cy: Longint;
  end;
  ABC = record
    abcA: Integer;
    abcB: UINT;
    abcC: Integer;
  end;
  HDC = Longword;
  HGDIOBJ = Longword;

var
  iSound: array of TComponentSound;
  OldProc: TNotifyEvent;

function GetCursorPos(var lpPoint: TPoint): BOOL; external 'GetCursorPos@user32.dll stdcall';
function MapWindowPoints(hWndFrom, hWndTo: HWND; var lpPoints: TPoint; cPoints: UINT): Integer; external 'MapWindowPoints@user32.dll stdcall';

function GetTextExtentPoint32(DC: HDC; lpString: String; Len: Integer; var lpSize: TSize): Boolean; external 'GetTextExtentPoint32W@gdi32.dll stdcall';
function GetClientDC(hWnd: HWND): HDC; external 'GetDC@user32.dll stdcall';
function ReleaseClientDC(hWnd: HWND; hDC: HDC): Integer; external 'ReleaseDC@user32.dll stdcall';
function SelectObject(DC: HDC; p2: HGDIOBJ): HGDIOBJ; external 'SelectObject@gdi32.dll stdcall';
function GetCharABCWidths(DC: HDC; uFirstChar, uLastChar: UINT; var lpAbc: ABC): Boolean; external 'GetCharABCWidthsW@gdi32.dll stdcall';

function sndPlaySound(lpszSoundName: String; fuSound: UINT): BOOL; external 'sndPlaySoundW@winmm.dll stdcall';


function GetTextWidth(aFont: TFont; Text: String): Integer;
var DC: HDC; aSize: TSize; OldObj: Longword; abc1, abc2: ABC;
begin
  DC:= GetClientDC(0);
  try
    if Text='' then Exit;
    OldObj:= SelectObject(DC, aFont.Handle);
    GetTextExtentPoint32(DC, Text, Length(Text), aSize);
    Result:= aSize.cx;
    if (Length(Text)<>1)and(fsItalic in aFont.Style) then begin
      GetCharABCWidths(DC, Ord(Text[1]), Ord(Text[1]), abc1);
      GetCharABCWidths(DC, Ord(Text[Length(text)]), Ord(Text[Length(text)]), abc2);
      if abc1.abcA<0 then Result:= Result-abc1.abcA;
      if abc2.abcC<0 then Result:= Result-abc2.abcC
    end;
  finally
    SelectObject(DC, OldObj);
    ReleaseClientDC(0, DC);
  end;
end;

procedure PlaySound(Sender: TObject);
var
  x, lParam, i, f, ids, w1, w2, x1, x2: Integer;
  p: TPoint;
  sp, s: String;
begin
  GetCursorPos(p);
  MapWindowPoints(0, WizardForm.ComponentsList.Handle, p, 1);

  lParam:= p.x or (p.y shl 16);
  i:= SendMessage(WizardForm.ComponentsList.Handle, LB_ITEMFROMPOINT, 0, lParam);
  if ((i shr 16) = 1) or ((i and $FFFF) < 0) then Exit;

  ids:= i and $FFFF;
  x:= ScaleX(20 + 17 *(WizardForm.ComponentsList.ItemLevel[ids] + 1));
  sp:= ' '+#$266B;

  f:= -1;
  for i:= 0 to GetArrayLength(iSound)-1 do begin
    if (ids = iSound[i].Index) then begin
      f:= i;
      Break;
    end;
  end;

  if (f < 0) then Exit;

  s:= WizardForm.ComponentsList.ItemCaption[ids];

  if (Pos(#$266B, s) <= 0) then Exit;

  w1:= GetTextWidth(WizardForm.ComponentsList.Font, Trim(s));
  w2:= GetTextWidth(WizardForm.ComponentsList.Font, sp);

  x2:= w1 + x;
  x1:= x2 - w2;

  if (p.x >= (x1 - 1)) and (p.x <= (x2 + 1)) then begin
    if FileExists(iSound[f].SoundName) then
      sndPlaySound(iSound[f].SoundName, 0);
  end;
end;

procedure AddItemSound(AIndex: Integer; AFilename: String);
var
  i, k: Integer;
begin
  i:= GetArrayLength(iSound);
  SetArrayLength(iSound, i+1);
  iSound[i].Index:= AIndex-1;
  iSound[i].SoundName:= ExpandConstant(AFilename);
  WizardForm.ComponentsList.ItemCaption[AIndex-1]:= WizardForm.ComponentsList.ItemCaption[AIndex-1] + ' '+#$266B;
end;

procedure InitializeWizard();
begin
  WizardForm.TypesCombo.Visible:=False;
  WizardForm.ComponentsList.Height := ScaleY(181) - WizardForm.TypesCombo.Top;
  WizardForm.ComponentsList.Top := WizardForm.TypesCombo.Top;
  WizardForm.ComponentsList.Width := ScaleX(417);
  OldProc:= WizardForm.ComponentsList.OnClick;
  WizardForm.ComponentsList.OnClick:= @PlaySound;

  ExtractTemporaryFile('sound1.wav');
  ExtractTemporaryFile('sound2.wav');
  AddItemSound(2, '{tmp}\sound1.wav');
  AddItemSound(3, '{tmp}\sound2.wav');
end;

Реализация только для UNICODE версии Inno Setup.
Звук проигрывается соответственно по клику на символ рядом с названием.
 

Ekspoint

Новичок
Как-то так
Код:
[Setup]
AppName=My Program
AppVerName=My Program 1.5
DefaultDirName={pf}\My Program
DefaultGroupName=My Program
ComponentsListTVStyle=true

[Files]
Source: sounds\*; flags: dontcopy;

[Languages]
Name: russian; MessagesFile: compiler:Languages\Russian.isl

[Components]
Name: sound; Description: Звук выстрела; Types: full;
Name: sound\snd1; Description: "Тихий"; Flags: exclusive;
Name: sound\snd2; Description: "Громкий"; Flags: exclusive;

[Code]
const
  LB_ITEMFROMPOINT  = $01A9;

type
  TComponentSound = record
    SoundName: String;
    Index: Integer;
  end;
  TSize = record
    cx: Longint;
    cy: Longint;
  end;
  ABC = record
    abcA: Integer;
    abcB: UINT;
    abcC: Integer;
  end;
  HDC = Longword;
  HGDIOBJ = Longword;

var
  iSound: array of TComponentSound;
  OldProc: TNotifyEvent;

function GetCursorPos(var lpPoint: TPoint): BOOL; external 'GetCursorPos@user32.dll stdcall';
function MapWindowPoints(hWndFrom, hWndTo: HWND; var lpPoints: TPoint; cPoints: UINT): Integer; external 'MapWindowPoints@user32.dll stdcall';

function GetTextExtentPoint32(DC: HDC; lpString: String; Len: Integer; var lpSize: TSize): Boolean; external 'GetTextExtentPoint32W@gdi32.dll stdcall';
function GetClientDC(hWnd: HWND): HDC; external 'GetDC@user32.dll stdcall';
function ReleaseClientDC(hWnd: HWND; hDC: HDC): Integer; external 'ReleaseDC@user32.dll stdcall';
function SelectObject(DC: HDC; p2: HGDIOBJ): HGDIOBJ; external 'SelectObject@gdi32.dll stdcall';
function GetCharABCWidths(DC: HDC; uFirstChar, uLastChar: UINT; var lpAbc: ABC): Boolean; external 'GetCharABCWidthsW@gdi32.dll stdcall';

function sndPlaySound(lpszSoundName: String; fuSound: UINT): BOOL; external 'sndPlaySoundW@winmm.dll stdcall';


function GetTextWidth(aFont: TFont; Text: String): Integer;
var DC: HDC; aSize: TSize; OldObj: Longword; abc1, abc2: ABC;
begin
  DC:= GetClientDC(0);
  try
    if Text='' then Exit;
    OldObj:= SelectObject(DC, aFont.Handle);
    GetTextExtentPoint32(DC, Text, Length(Text), aSize);
    Result:= aSize.cx;
    if (Length(Text)<>1)and(fsItalic in aFont.Style) then begin
      GetCharABCWidths(DC, Ord(Text[1]), Ord(Text[1]), abc1);
      GetCharABCWidths(DC, Ord(Text[Length(text)]), Ord(Text[Length(text)]), abc2);
      if abc1.abcA<0 then Result:= Result-abc1.abcA;
      if abc2.abcC<0 then Result:= Result-abc2.abcC
    end;
  finally
    SelectObject(DC, OldObj);
    ReleaseClientDC(0, DC);
  end;
end;

procedure PlaySound(Sender: TObject);
var
  x, lParam, i, f, ids, w1, w2, x1, x2: Integer;
  p: TPoint;
  sp, s: String;
begin
  GetCursorPos(p);
  MapWindowPoints(0, WizardForm.ComponentsList.Handle, p, 1);

  lParam:= p.x or (p.y shl 16);
  i:= SendMessage(WizardForm.ComponentsList.Handle, LB_ITEMFROMPOINT, 0, lParam);
  if ((i shr 16) = 1) or ((i and $FFFF) < 0) then Exit;

  ids:= i and $FFFF;
  x:= ScaleX(20 + 17 *(WizardForm.ComponentsList.ItemLevel[ids] + 1));
  sp:= ' '+#$266B;

  f:= -1;
  for i:= 0 to GetArrayLength(iSound)-1 do begin
    if (ids = iSound[i].Index) then begin
      f:= i;
      Break;
    end;
  end;

  if (f < 0) then Exit;

  s:= WizardForm.ComponentsList.ItemCaption[ids];

  if (Pos(#$266B, s) <= 0) then Exit;

  w1:= GetTextWidth(WizardForm.ComponentsList.Font, Trim(s));
  w2:= GetTextWidth(WizardForm.ComponentsList.Font, sp);

  x2:= w1 + x;
  x1:= x2 - w2;

  if (p.x >= (x1 - 1)) and (p.x <= (x2 + 1)) then begin
    if FileExists(iSound[f].SoundName) then
      sndPlaySound(iSound[f].SoundName, 0);
  end;
end;

procedure AddItemSound(AIndex: Integer; AFilename: String);
var
  i, k: Integer;
begin
  i:= GetArrayLength(iSound);
  SetArrayLength(iSound, i+1);
  iSound[i].Index:= AIndex-1;
  iSound[i].SoundName:= ExpandConstant(AFilename);
  WizardForm.ComponentsList.ItemCaption[AIndex-1]:= WizardForm.ComponentsList.ItemCaption[AIndex-1] + ' '+#$266B;
end;

procedure InitializeWizard();
begin
  WizardForm.TypesCombo.Visible:=False;
  WizardForm.ComponentsList.Height := ScaleY(181) - WizardForm.TypesCombo.Top;
  WizardForm.ComponentsList.Top := WizardForm.TypesCombo.Top;
  WizardForm.ComponentsList.Width := ScaleX(417);
  OldProc:= WizardForm.ComponentsList.OnClick;
  WizardForm.ComponentsList.OnClick:= @PlaySound;

  ExtractTemporaryFile('sound1.wav');
  ExtractTemporaryFile('sound2.wav');
  AddItemSound(2, '{tmp}\sound1.wav');
  AddItemSound(3, '{tmp}\sound2.wav');
end;
Реализация только для UNICODE версии Inno Setup.
Звук проигрывается соответственно по клику на символ рядом с названием.
Огромное спасибо!!:) То что надо
 

Ekspoint

Новичок
еще вопрос,а можно сделать привязку компонента вот такого вида
Код:
[Setup]
RawDataResource=SndA:скрипты звуков\звуки\тихая.WAV |SndB:скрипты звуков\звуки\средняя.WAV |SndC:скрипты звуков\звуки\громкая.WAV |SndD:скрипты звуков\звуки\тихая 10 сек.WAV |SndE:скрипты звуков\звуки\громкая 10  сек.WAV
[Code]
#define A = (Defined UNICODE) ? "W" : "A"

Type
HINST = THandle;
HMODULE = HINST;
Pointer = Longint;
HRSRC = THandle;
HGLOBAL = THandle;

Const
SND_ASYNC           = $0001;
SND_NODEFAULT       = $0002;
SND_MEMORY          = $0004;
RT_RCDATA           = 10;

Function sndPlaySound(lpszSoundName: Pointer; uFlags: UINT): BOOL; external 'sndPlaySound{#A}@Winmm.dll stdcall';
Function LoadResource(hModule: HINST; hResInfo: HRSRC): HGLOBAL; external 'LoadResource@kernel32.dll stdcall';
Function FindResource(hModule: HMODULE; lpName: String; lpType: Longint): HRSRC; external 'FindResource{#A}@kernel32.dll stdcall';
Function LockResource(hResData: HGLOBAL): Pointer; external 'LockResource@kernel32.dll stdcall';

Var
pSoundMemory_A, pSoundMemory_B, pSoundMemory_C, pSoundMemory_D, pSoundMemory_E: Pointer;
IndexLast: Integer;
  
Function GetResourceSoundAddr(const ResourceName: String): Pointer;
var
hResourceSound: HRSRC;
begin
hResourceSound := FindResource(HInstance, ResourceName, RT_RCDATA);
Result := LockResource(LoadResource(HInstance, hResourceSound));
end;

Procedure ComponentsOnClickCheck(Sender: TObject);
begin
if IsComponentSelected('KMP\22\2\1') then
begin
  sndPlaySound(pSoundMemory_A, SND_MEMORY or SND_NODEFAULT or SND_ASYNC);
end;
//"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""//
begin
if IsComponentSelected('KMP\22\2\2') then
begin
  sndPlaySound(pSoundMemory_B, SND_MEMORY or SND_NODEFAULT or SND_ASYNC);
end;
end;
//"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""//
begin
if IsComponentSelected('KMP\22\2\3') then
begin
  sndPlaySound(pSoundMemory_C, SND_MEMORY or SND_NODEFAULT or SND_ASYNC);
end;
end;
//"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""//
begin
if IsComponentSelected('KMP\22\2\4') then
begin
  sndPlaySound(pSoundMemory_D, SND_MEMORY or SND_NODEFAULT or SND_ASYNC);
end;
end;
//"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""//
begin
if IsComponentSelected('KMP\22\2\5') then
begin
  sndPlaySound(pSoundMemory_E, SND_MEMORY or SND_NODEFAULT or SND_ASYNC);
end;
end;
//"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""//
end;
procedure InitializeWizard8();
begin
IndexLast := -1;

pSoundMemory_A := GetResourceSoundAddr('_IS_SNDA');
pSoundMemory_B := GetResourceSoundAddr('_IS_SNDB');
pSoundMemory_C := GetResourceSoundAddr('_IS_SNDC');
pSoundMemory_D := GetResourceSoundAddr('_IS_SNDD');
pSoundMemory_E := GetResourceSoundAddr('_IS_SNDE');
  
WizardForm.ComponentsList.OnClickCheck := @ComponentsOnClickCheck;
end;
 

Shegorat

Lord of Madness
Администратор
Ekspoint
Можно сделать многое. Но что вы подразумеваете под?
а можно сделать привязку компонента вот такого вида
Если же привязку под внутреннее имя компонента типа "KMP\22\2\1" то нельзя.
Точнее нельзя стандартными средствами, т.к. я уже говорил, что эти данные не доступны в секции code - нельзя с их помощью получить индекс компонента.
Конечно можно через препроцессор сдампить секцию и потом распарсить ее в коде, но и там будут свои ограничения.

P.S. Для благодарностей есть кнопочка "Мне нравится". Нет нужды писать сообщение со словом "Спасибо"
 

Ekspoint

Новичок
Ekspoint
Можно сделать многое. Но что вы подразумеваете под?

Если же привязку под внутреннее имя компонента типа "KMP\22\2\1" то нельзя.
Точнее нельзя стандартными средствами, т.к. я уже говорил, что эти данные не доступны в секции code - нельзя с их помощью получить индекс компонента.
Конечно можно через препроцессор сдампить секцию и потом распарсить ее в коде, но и там будут свои ограничения.
Ясно,а конфликт с музыкой в установщике может быть или нет,а то я в свой код добавил и не работает
 

Shegorat

Lord of Madness
Администратор
Ясно,а конфликт с музыкой в установщике может быть или нет,а то я в свой код добавил и не работает
Я не знаю как вы интегрировали вышеприведенный код в свой скрипт, а также как у вас реализована музыка и т.д. Поэтому что-то конкретно ответить не могу. Возможно просто произошел оверрайд процедуры клика по компонентам или что-то подобное.
 

Shegorat

Lord of Madness
Администратор
Немного подправил код
Код:
[Setup]
AppName=My Program
AppVerName=My Program 1.5
DefaultDirName={pf}\My Program
DefaultGroupName=My Program
ComponentsListTVStyle=true

[Files]
Source: sounds\*; flags: dontcopy;

[Languages]
Name: russian; MessagesFile: compiler:Languages\Russian.isl

[Components]
Name: sound; Description: Звук выстрела; Types: full;
Name: sound\snd1; Description: "Тихий"; Flags: exclusive;
Name: sound\snd2; Description: "Громкий"; Flags: exclusive;

[Code]
const
  LB_ITEMFROMPOINT  = $01A9;

type
  TComponentSound = record
    SoundName: String;
    Index: Integer;
  end;
  TSize = record
    cx: Longint;
    cy: Longint;
  end;
  ABC = record
    abcA: Integer;
    abcB: UINT;
    abcC: Integer;
  end;
  HDC = Longword;
  HGDIOBJ = Longword;

var
  iSound: array of TComponentSound;
  sndCompOldProc: TNotifyEvent;

function GetCursorPos(var lpPoint: TPoint): BOOL; external 'GetCursorPos@user32.dll stdcall';
function MapWindowPoints(hWndFrom, hWndTo: HWND; var lpPoints: TPoint; cPoints: UINT): Integer; external 'MapWindowPoints@user32.dll stdcall';

function GetTextExtentPoint32(DC: HDC; lpString: String; Len: Integer; var lpSize: TSize): Boolean; external 'GetTextExtentPoint32W@gdi32.dll stdcall';
function GetClientDC(hWnd: HWND): HDC; external 'GetDC@user32.dll stdcall';
function ReleaseClientDC(hWnd: HWND; hDC: HDC): Integer; external 'ReleaseDC@user32.dll stdcall';
function SelectObject(DC: HDC; p2: HGDIOBJ): HGDIOBJ; external 'SelectObject@gdi32.dll stdcall';
function GetCharABCWidths(DC: HDC; uFirstChar, uLastChar: UINT; var lpAbc: ABC): Boolean; external 'GetCharABCWidthsW@gdi32.dll stdcall';

function sndPlaySound(lpszSoundName: String; fuSound: UINT): BOOL; external 'sndPlaySoundW@winmm.dll stdcall';

function GetTextWidth(aFont: TFont; Text: String): Integer;
var
  DC: HDC;
  aSize: TSize;
  OldObj: Longword;
  abc1, abc2: ABC;
begin
  if Text='' then Exit;
  DC:= GetClientDC(0);
  try
    OldObj:= SelectObject(DC, aFont.Handle);
    GetTextExtentPoint32(DC, Text, Length(Text), aSize);
    Result:= aSize.cx;
    if (Length(Text)<>1)and(fsItalic in aFont.Style) then begin
      GetCharABCWidths(DC, Ord(Text[1]), Ord(Text[1]), abc1);
      GetCharABCWidths(DC, Ord(Text[Length(text)]), Ord(Text[Length(text)]), abc2);
      if abc1.abcA<0 then Result:= Result-abc1.abcA;
      if abc2.abcC<0 then Result:= Result-abc2.abcC
    end;
  finally
    SelectObject(DC, OldObj);
    ReleaseClientDC(0, DC);
  end;
end;

procedure PlaySound(Sender: TObject);
var
  x, o, n, lParam, i, f, ids, w1, w2, x1, x2: Integer;
  p: TPoint;
  sp, s: String;
begin
  GetCursorPos(p);
  MapWindowPoints(0, WizardForm.ComponentsList.Handle, p, 1);

  lParam:= p.x or (p.y shl 16);
  i:= SendMessage(WizardForm.ComponentsList.Handle, LB_ITEMFROMPOINT, 0, lParam);
  if ((i shr 16) = 1) or ((i and $FFFF) < 0) then Exit;

  ids:= i and $FFFF;

  o:= WizardForm.ComponentsList.Offset;
  n:= WizardForm.ComponentsList.ItemLevel[ids];
  x:= ScaleX((1 + o) + ((13 + o * 2)*(n + 1)) + (14 + o * 2));
  sp:= ' '+#$266B;

  f:= -1;
  for i:= 0 to GetArrayLength(iSound)-1 do begin
    if (ids = iSound[i].Index) then begin
      f:= i;
      Break;
    end;
  end;

  if (f < 0) then Exit;

  s:= WizardForm.ComponentsList.ItemCaption[ids];
  if (Pos(#$266B, s) <= 0) then Exit;

  w1:= GetTextWidth(WizardForm.ComponentsList.Font, Trim(s));
  w2:= GetTextWidth(WizardForm.ComponentsList.Font, sp);

  x2:= w1 + x;
  x1:= x2 - w2;

  if (p.x >= (x1 - 1)) and (p.x <= (x2 + 1)) then begin
    if FileExists(iSound[f].SoundName) then
      sndPlaySound(iSound[f].SoundName, 0);
  end;
  
  if (sndCompOldProc <> nil) then
    sndCompOldProc(Sender);
end;

procedure AddItemSound(AIndex: Integer; AFilename: String);
var
  i: Integer;
begin
  i:= GetArrayLength(iSound);
  SetArrayLength(iSound, i+1);
  iSound[i].Index:= AIndex-1;
  iSound[i].SoundName:= ExpandConstant(AFilename);
  WizardForm.ComponentsList.ItemCaption[AIndex-1]:= WizardForm.ComponentsList.ItemCaption[AIndex-1] + ' '+#$266B;
end;

procedure InitializeWizard();
begin
  WizardForm.TypesCombo.Visible:=False;
  WizardForm.ComponentsList.Height := ScaleY(181) - WizardForm.TypesCombo.Top;
  WizardForm.ComponentsList.Top := WizardForm.TypesCombo.Top;
  WizardForm.ComponentsList.Width := ScaleX(417);
  sndCompOldProc:= WizardForm.ComponentsList.OnClick;
  WizardForm.ComponentsList.OnClick:= @PlaySound;

  ExtractTemporaryFile('sound1.wav');
  ExtractTemporaryFile('sound2.wav');
  AddItemSound(2, '{tmp}\sound1.wav');
  AddItemSound(3, '{tmp}\sound2.wav');
end;
 

Ekspoint

Новичок
а убивать этот процес надо,а то у меня бывает инстал вылетает из за ошибки
 

Shegorat

Lord of Madness
Администратор
Еще немного подправил код
Код:
[Setup]
AppName=My Program
AppVerName=My Program 1.5
DefaultDirName={pf}\My Program
DefaultGroupName=My Program
ComponentsListTVStyle=true

[Files]
Source: sounds\*; flags: dontcopy;

[Languages]
Name: russian; MessagesFile: compiler:Languages\Russian.isl

[Components]
Name: sound; Description: Звук выстрела; Types: full;
Name: sound\snd1; Description: "Тихий"; Flags: exclusive;
Name: sound\snd2; Description: "Громкий"; Flags: exclusive;

[Code]
const
  LB_ITEMFROMPOINT  = $01A9;

type
  TComponentSound = record
    SoundName: String;
    Index: Integer;
  end;
  TSize = record
    cx: Longint;
    cy: Longint;
  end;
  ABC = record
    abcA: Integer;
    abcB: UINT;
    abcC: Integer;
  end;
  HDC = Longword;
  HGDIOBJ = Longword;

var
  iSound: array of TComponentSound;
  sndCompOldProc: TNotifyEvent;

function GetCursorPos(var lpPoint: TPoint): BOOL; external 'GetCursorPos@user32.dll stdcall';
function MapWindowPoints(hWndFrom, hWndTo: HWND; var lpPoints: TPoint; cPoints: UINT): Integer; external 'MapWindowPoints@user32.dll stdcall';

function GetTextExtentPoint32(DC: HDC; lpString: String; Len: Integer; var lpSize: TSize): Boolean; external 'GetTextExtentPoint32W@gdi32.dll stdcall';
function GetClientDC(hWnd: HWND): HDC; external 'GetDC@user32.dll stdcall';
function ReleaseClientDC(hWnd: HWND; hDC: HDC): Integer; external 'ReleaseDC@user32.dll stdcall';
function SelectObject(DC: HDC; p2: HGDIOBJ): HGDIOBJ; external 'SelectObject@gdi32.dll stdcall';
function GetCharABCWidths(DC: HDC; uFirstChar, uLastChar: UINT; var lpAbc: ABC): Boolean; external 'GetCharABCWidthsW@gdi32.dll stdcall';

function sndPlaySound(lpszSoundName: String; fuSound: UINT): BOOL; external 'sndPlaySoundW@winmm.dll stdcall';

function GetTextWidth(aFont: TFont; Text: String): Integer;
var
  DC: HDC;
  aSize: TSize;
  OldObj: Longword;
  abc1, abc2: ABC;
begin
  if Text='' then Exit;
  DC:= GetClientDC(0);
  try
    OldObj:= SelectObject(DC, aFont.Handle);
    GetTextExtentPoint32(DC, Text, Length(Text), aSize);
    Result:= aSize.cx;
    if (Length(Text)<>1)and(fsItalic in aFont.Style) then begin
      GetCharABCWidths(DC, Ord(Text[1]), Ord(Text[1]), abc1);
      GetCharABCWidths(DC, Ord(Text[Length(text)]), Ord(Text[Length(text)]), abc2);
      if abc1.abcA<0 then Result:= Result-abc1.abcA;
      if abc2.abcC<0 then Result:= Result-abc2.abcC
    end;
  finally
    SelectObject(DC, OldObj);
    ReleaseClientDC(0, DC);
  end;
end;

procedure PlaySound(Sender: TObject);
var
  x, o, n, lParam, i, f, ids, w1, w2, x1, x2: Integer;
  p: TPoint;
  sp, s: String;
  fnt: TFont;
begin
  GetCursorPos(p);
  MapWindowPoints(0, WizardForm.ComponentsList.Handle, p, 1);

  lParam:= p.x or (p.y shl 16);
  i:= SendMessage(WizardForm.ComponentsList.Handle, LB_ITEMFROMPOINT, 0, lParam);
  if ((i shr 16) = 1) or ((i and $FFFF) < 0) then Exit;

  ids:= i and $FFFF;

  o:= WizardForm.ComponentsList.Offset;
  n:= WizardForm.ComponentsList.ItemLevel[ids];
  if (WizardForm.ComponentsList.TreeViewStyle) then
    x:= ScaleX((1 + o) + ((13 + o * 2)*(n + 1)) + (14 + o * 2))
  else
    x:= ScaleX((13 + o * 2)*(n + 1));
    
  sp:= ' '+#$266B;

  f:= -1;
  for i:= 0 to GetArrayLength(iSound)-1 do begin
    if (ids = iSound[i].Index) then begin
      f:= i;
      Break;
    end;
  end;

  if (f < 0) then Exit;

  s:= WizardForm.ComponentsList.ItemCaption[ids];
  if (Pos(#$266B, s) <= 0) then Exit;

  fnt:= WizardForm.ComponentsList.Font;
  fnt.Style:= WizardForm.ComponentsList.ItemFontStyle[i];
  
  w1:= GetTextWidth(fnt, Trim(s));
  w2:= GetTextWidth(fnt, sp);
  
  x2:= w1 + x;
  x1:= x2 - w2;

  if (p.x >= (x1 - 1)) and (p.x <= (x2 + 1)) then begin
    if FileExists(iSound[f].SoundName) then
      sndPlaySound(iSound[f].SoundName, 0);
  end;
  
  if (sndCompOldProc <> nil) then
    sndCompOldProc(Sender);
end;

procedure AddItemSound(AIndex: Integer; AFilename: String);
var
  i: Integer;
begin
  i:= GetArrayLength(iSound);
  SetArrayLength(iSound, i+1);
  iSound[i].Index:= AIndex-1;
  iSound[i].SoundName:= ExpandConstant(AFilename);
  WizardForm.ComponentsList.ItemCaption[AIndex-1]:= WizardForm.ComponentsList.ItemCaption[AIndex-1] + ' '+#$266B;
end;

procedure InitializeWizard();
begin
  WizardForm.TypesCombo.Visible:=False;
  WizardForm.ComponentsList.Height := ScaleY(181) - WizardForm.TypesCombo.Top;
  WizardForm.ComponentsList.Top := WizardForm.TypesCombo.Top;
  WizardForm.ComponentsList.Width := ScaleX(417);
  sndCompOldProc:= WizardForm.ComponentsList.OnClick;
  WizardForm.ComponentsList.OnClick:= @PlaySound;

  ExtractTemporaryFile('sound1.wav');
  ExtractTemporaryFile('sound2.wav');
  AddItemSound(2, '{tmp}\sound1.wav');
  AddItemSound(3, '{tmp}\sound2.wav');
end;
 

Ekspoint

Новичок
Еще немного подправил код
Код:
[Setup]
AppName=My Program
AppVerName=My Program 1.5
DefaultDirName={pf}\My Program
DefaultGroupName=My Program
ComponentsListTVStyle=true

[Files]
Source: sounds\*; flags: dontcopy;

[Languages]
Name: russian; MessagesFile: compiler:Languages\Russian.isl

[Components]
Name: sound; Description: Звук выстрела; Types: full;
Name: sound\snd1; Description: "Тихий"; Flags: exclusive;
Name: sound\snd2; Description: "Громкий"; Flags: exclusive;

[Code]
const
  LB_ITEMFROMPOINT  = $01A9;

type
  TComponentSound = record
    SoundName: String;
    Index: Integer;
  end;
  TSize = record
    cx: Longint;
    cy: Longint;
  end;
  ABC = record
    abcA: Integer;
    abcB: UINT;
    abcC: Integer;
  end;
  HDC = Longword;
  HGDIOBJ = Longword;

var
  iSound: array of TComponentSound;
  sndCompOldProc: TNotifyEvent;

function GetCursorPos(var lpPoint: TPoint): BOOL; external 'GetCursorPos@user32.dll stdcall';
function MapWindowPoints(hWndFrom, hWndTo: HWND; var lpPoints: TPoint; cPoints: UINT): Integer; external 'MapWindowPoints@user32.dll stdcall';

function GetTextExtentPoint32(DC: HDC; lpString: String; Len: Integer; var lpSize: TSize): Boolean; external 'GetTextExtentPoint32W@gdi32.dll stdcall';
function GetClientDC(hWnd: HWND): HDC; external 'GetDC@user32.dll stdcall';
function ReleaseClientDC(hWnd: HWND; hDC: HDC): Integer; external 'ReleaseDC@user32.dll stdcall';
function SelectObject(DC: HDC; p2: HGDIOBJ): HGDIOBJ; external 'SelectObject@gdi32.dll stdcall';
function GetCharABCWidths(DC: HDC; uFirstChar, uLastChar: UINT; var lpAbc: ABC): Boolean; external 'GetCharABCWidthsW@gdi32.dll stdcall';

function sndPlaySound(lpszSoundName: String; fuSound: UINT): BOOL; external 'sndPlaySoundW@winmm.dll stdcall';

function GetTextWidth(aFont: TFont; Text: String): Integer;
var
  DC: HDC;
  aSize: TSize;
  OldObj: Longword;
  abc1, abc2: ABC;
begin
  if Text='' then Exit;
  DC:= GetClientDC(0);
  try
    OldObj:= SelectObject(DC, aFont.Handle);
    GetTextExtentPoint32(DC, Text, Length(Text), aSize);
    Result:= aSize.cx;
    if (Length(Text)<>1)and(fsItalic in aFont.Style) then begin
      GetCharABCWidths(DC, Ord(Text[1]), Ord(Text[1]), abc1);
      GetCharABCWidths(DC, Ord(Text[Length(text)]), Ord(Text[Length(text)]), abc2);
      if abc1.abcA<0 then Result:= Result-abc1.abcA;
      if abc2.abcC<0 then Result:= Result-abc2.abcC
    end;
  finally
    SelectObject(DC, OldObj);
    ReleaseClientDC(0, DC);
  end;
end;

procedure PlaySound(Sender: TObject);
var
  x, o, n, lParam, i, f, ids, w1, w2, x1, x2: Integer;
  p: TPoint;
  sp, s: String;
  fnt: TFont;
begin
  GetCursorPos(p);
  MapWindowPoints(0, WizardForm.ComponentsList.Handle, p, 1);

  lParam:= p.x or (p.y shl 16);
  i:= SendMessage(WizardForm.ComponentsList.Handle, LB_ITEMFROMPOINT, 0, lParam);
  if ((i shr 16) = 1) or ((i and $FFFF) < 0) then Exit;

  ids:= i and $FFFF;

  o:= WizardForm.ComponentsList.Offset;
  n:= WizardForm.ComponentsList.ItemLevel[ids];
  if (WizardForm.ComponentsList.TreeViewStyle) then
    x:= ScaleX((1 + o) + ((13 + o * 2)*(n + 1)) + (14 + o * 2))
  else
    x:= ScaleX((13 + o * 2)*(n + 1));
   
  sp:= ' '+#$266B;

  f:= -1;
  for i:= 0 to GetArrayLength(iSound)-1 do begin
    if (ids = iSound[i].Index) then begin
      f:= i;
      Break;
    end;
  end;

  if (f < 0) then Exit;

  s:= WizardForm.ComponentsList.ItemCaption[ids];
  if (Pos(#$266B, s) <= 0) then Exit;

  fnt:= WizardForm.ComponentsList.Font;
  fnt.Style:= WizardForm.ComponentsList.ItemFontStyle[i];
 
  w1:= GetTextWidth(fnt, Trim(s));
  w2:= GetTextWidth(fnt, sp);
 
  x2:= w1 + x;
  x1:= x2 - w2;

  if (p.x >= (x1 - 1)) and (p.x <= (x2 + 1)) then begin
    if FileExists(iSound[f].SoundName) then
      sndPlaySound(iSound[f].SoundName, 0);
  end;
 
  if (sndCompOldProc <> nil) then
    sndCompOldProc(Sender);
end;

procedure AddItemSound(AIndex: Integer; AFilename: String);
var
  i: Integer;
begin
  i:= GetArrayLength(iSound);
  SetArrayLength(iSound, i+1);
  iSound[i].Index:= AIndex-1;
  iSound[i].SoundName:= ExpandConstant(AFilename);
  WizardForm.ComponentsList.ItemCaption[AIndex-1]:= WizardForm.ComponentsList.ItemCaption[AIndex-1] + ' '+#$266B;
end;

procedure InitializeWizard();
begin
  WizardForm.TypesCombo.Visible:=False;
  WizardForm.ComponentsList.Height := ScaleY(181) - WizardForm.TypesCombo.Top;
  WizardForm.ComponentsList.Top := WizardForm.TypesCombo.Top;
  WizardForm.ComponentsList.Width := ScaleX(417);
  sndCompOldProc:= WizardForm.ComponentsList.OnClick;
  WizardForm.ComponentsList.OnClick:= @PlaySound;

  ExtractTemporaryFile('sound1.wav');
  ExtractTemporaryFile('sound2.wav');
  AddItemSound(2, '{tmp}\sound1.wav');
  AddItemSound(3, '{tmp}\sound2.wav');
end;
Спасиб,а что именно
 

Shegorat

Lord of Madness
Администратор

Вложения

Сверху