Ce petit utilitaire permet simplement de changer le volume principal.
La fenetre est tres discrete (cf. capture d'ecran ^^) et n'apparait pas dans la barre des taches. Elle peut etre deplacee ou l'on veut en cliquant / deplacant avec le bouton droit de la souris. Comme le prog est toujours visible, il est en permanence accessible sans avoir a passer par le controle du volume de Windows qui met un temps fou a s'ouvrir (du moins sur mon PC :)
Le programme gere entre autres :
- la gestion du volume principal (on trouve beaucoup de code sources pour changer le volume "WAV" mais tres peu pour changer le volume "MASTER" !)
- comment dessiner une fenetre "a la main" avec les fonctions de dessin de Delphi
- Gestion simple d'un fichier .ini pour sauvegarder la position de la fenetre
- Gestion de la souris pour "glisser / deplacer" la fenetre et gerer un effet de "rollover"
Source / Exemple :
unit main;
interface
uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, mmsystem,
ExtCtrls, StdCtrls, ComCtrls, shellApi, IniFiles;
type
TForm1 = class(TForm)
Timer1: TTimer;
procedure FormCreate(Sender: TObject);
procedure FormShow(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
procedure FormMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure FormMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
procedure FormPaint(Sender: TObject);
private
{ Déclarations privées }
public
{ Déclarations publiques }
end;
const FORM_BORDER = 1;
const SLIDER_HEIGHT = 8;
const SLIDER_WIDTH = 2;
const BORDER_COLOR = $0000FF;
var
Form1: TForm1;
masterVolumeID:DWORD;
nid : TNotifyIconData;
pDragging : string;
pLastVolumeLevel: DWORD;
pIniFile: TIniFile;
implementation
{$R *.DFM}
{ Dessine le contour de la fenetre
en utilisant la couleur donnee }
procedure drawBorder(iColor: longWord);
begin
with Form1.Canvas do begin
brush.Color := iColor;
fillRect(rect(0, 0, form1.width, 1));
fillRect(rect(form1.width - 1, 0, form1.width, form1.height));
fillRect(rect(0, form1.height - 1, form1.width, form1.height));
fillRect(rect(0, 0, 1, form1.height));
end;
end;
{ Verifie si le curseur de la souris
est dans la fenetre }
function mouseInside(): boolean;
begin
result := (mouse.CursorPos.x > form1.left) and (mouse.cursorPos.x < form1.Left + form1.width) and (mouse.cursorPos.y > form1.Top) and (mouse.cursorPos.y < form1.top + form1.height);
end;
{ Dessine la fenetre, en positionnant le curseur en fonction
du volume. }
procedure updateVolumeControl(iVolumeLevel: DWORD; iBorderColor: longWord);
var positionPercent : real;
sliderRect: TRect;
barHeight: integer;
begin
{ Recupere la position du curseur
en pourcentage (0.0 en bas et 1.0 en haut) }
sliderRect := rect(0,0,0,0);
if iVolumeLevel <= 0.0 then begin
positionPercent := 0.0;
end else begin
positionPercent := iVolumeLevel / 65535.0;
end;
if positionPercent < 0.0 then positionPercent := 0.0;
if positionPercent > 1.0 then positionPercent := 1.0;
with Form1.Canvas do begin
{ Peint la fenetre en noir }
Brush.Color := $000000;
FillRect(Form1.ClientRect);
barHeight := Form1.clientRect.bottom - Form1.clientRect.top;
{ Calcule le rectangle du curseur de volume }
sliderRect.top := FORM_BORDER + round((1.0 - positionPercent) * (barHeight - SLIDER_HEIGHT - 2 * FORM_BORDER));
sliderRect.left := FORM_BORDER;
sliderRect.bottom := sliderRect.top + SLIDER_HEIGHT;
sliderRect.right := sliderRect.left + SLIDER_WIDTH;
{ Peint le curseur }
brush.color := $FFFFFF;
fillRect(sliderRect);
end;
{ Dessine le contours de la fenetre }
drawBorder(iBorderColor);
end;
{ Recupere l'identifiant du mixeur donne
L'identifiant servira par exemple a recuperer
le volume }
function GetMixerControlID(CompType: integer) : DWORD;
var mxl: MIXERLINE;
mxc: MIXERCONTROL ;
mxlc: MIXERLINECONTROLS ;
begin
mxl.cbStruct := sizeof(mxl);
mxl.dwComponentType := CompType;
Result := 0;
if (mixerGetLineInfo(0, @mxl, MIXER_GETLINEINFOF_COMPONENTTYPE) =
MMSYSERR_NOERROR) then begin
mxlc.cbStruct := sizeof(mxlc);
mxlc.dwLineID := mxl.dwLineID;
mxlc.dwControlType := MIXERCONTROL_CONTROLTYPE_VOLUME;
mxlc.cControls := mxl.cControls;
mxlc.cbmxctrl := sizeof(mxc);
mxlc.pamxctrl := @mxc;
if (mixerGetLineControls(0, @mxlc, MIXER_GETLINECONTROLSF_ONEBYTYPE) =
MMSYSERR_NOERROR) then Result := mxc.dwControlID;
end;
end;
{ Retourne le volume du composant donne }
function GetVolume( nIDControl: DWORD) : DWORD;
var Volume : Array[0..1] Of TMixerControlDetails_Unsigned;
mxcd: TMixerControlDetails;
begin
mxcd.cbStruct := sizeof(mxcd);
mxcd.dwControlID := nIDControl;
mxcd.cChannels := 2;
mxcd.cMultipleItems := 0;
mxcd.cbDetails := sizeof(MIXERCONTROLDETAILS_UNSIGNED) * 2;
mxcd.paDetails := @Volume;
Result := 0;
try
mixerGetControlDetails(0, @mxcd, MIXER_GETCONTROLDETAILSF_VALUE);
Result := Volume[0].dwValue;
except
end;
end;
{ Change le volume du composant donne }
function SetVolume(ID, Value: DWord): Boolean;
var Volume : Array[0..1] Of TMixerControlDetails_Unsigned;
mxcd: TMixerControlDetails;
begin
Volume[0].dwValue := Value;
Volume[1].dwValue := Value;
With mxcd Do
Begin
cbStruct := SizeOf(mxcd);
dwControlID := ID;
cChannels := 2;
cMultipleItems := 0;
cbDetails := SizeOf(TMixerControlDetails_Unsigned) * 2;
paDetails := @Volume;
Result := (mixerSetControlDetails(0, @mxcd,
MIXER_SETCONTROLDETAILSF_VALUE) = MMSYSERR_NOERROR);
End; {With}
End;
procedure TForm1.FormCreate(Sender: TObject);
begin
{ pDragging indique le type de deplacement en cours:
- soit le deplacement du curseur de volume (pConfig = 'slider')
- soit le deplacement de la fenetre (pConfig = 'form')
- soit rien (pConfig = 'none' }
pDragging := 'none';
{ Recupere l'identifiant du control de volume principal }
masterVolumeID := GetMixerControlID(MIXERLINE_COMPONENTTYPE_DST_SPEAKERS);
pLastVolumeLevel := 99999;
{ Change la taille de la fenetre }
Form1.width := FORM_BORDER * 2 + SLIDER_WIDTH;
Timer1.enabled := false;
{ Lit la position de la fenetre dans le fichier .ini }
pIniFile := TIniFile.Create(ExtractFilePath(Application.ExeName) + 'changerVolume.ini');
form1.left := strToInt(pIniFile.readString('CONFIG', 'form.left', '50'));
form1.top := strToInt(pIniFile.readString('CONFIG', 'form.top', '50'));
pIniFile.Free;
end;
procedure TForm1.FormShow(Sender: TObject);
begin
{ Enleve l'application de la barre des taches }
ShowWindow(Application.Handle, SW_HIDE);
end;
{ Le timer est actif uniquement lorsque
l'on clique sur la fenetre }
procedure TForm1.Timer1Timer(Sender: TObject);
begin
{ Code pour deplacer la fenetre }
if pDragging = 'form' then begin
form1.left := Mouse.CursorPos.x;
form1.top := Mouse.CursorPos.y;
if form1.Left + form1.width > screen.Width then form1.left := screen.width - form1.width;
if form1.Left < 0 then form1.left := 0;
if form1.top + form1.height > screen.height then form1.top := screen.height - form1.height;
if form1.top < 0 then form1.top := 0;
end else begin
{ Si la souris n'est plus
a l'interieur de la fenetre
on desactive le timer }
if not mouseInside() then begin
if pDragging = 'none' then begin
Timer1.enabled := false;
drawBorder($000000);
end;
end;
end;
end;
{ MouseDown }
procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
{ Click gauche: on change le volume
Click droit: on commence a deplacer la fenetre }
if button = mbLeft then begin
pDragging := 'slider'
end else begin
pDragging := 'form';
Timer1.enabled := true;
end;
end;
{ MouseUp }
procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
{ Sauvegarde la position de la fenetre dans le fichier .ini }
if pDragging = 'form' then begin
pIniFile := TIniFile.Create(ExtractFilePath(Application.ExeName) + 'changerVolume.ini');
pIniFile.writeString('CONFIG', 'form.left', intToStr(form1.left));
pIniFile.writeString('CONFIG', 'form.top', intToStr(form1.top));
pIniFile.Free;
end;
pDragging := 'none';
end;
{ MouseMove }
procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
var volumeLevel:integer;
begin
{ Changement du volume }
if pDragging = 'slider' then begin
{/ Calcule le nouveau volume }
volumeLevel := 65535 - round(y / Form1.Height * 65535);
if volumeLevel > 65535 then volumeLevel := 65535;
if volumeLevel < 0 then volumeLevel := 0;
{ On redessine la fenetre et on change le volume }
updateVolumeControl(volumeLevel, BORDER_COLOR);
SetVolume(masterVolumeID, volumeLevel);
end else begin
{ Sinon on redessine juste la fenetre
pour l'effet de "rollover" }
volumeLevel := getVolume(masterVolumeID);
updateVolumeControl(volumeLevel, BORDER_COLOR);
end;
Timer1.enabled := enabled;
end;
{ OnPaint }
procedure TForm1.FormPaint(Sender: TObject);
var volumeLevel:integer;
begin
{ On redessine juste la fenetre
en utilisant le volume courant }
volumeLevel := getVolume(masterVolumeID);
updateVolumeControl(volumeLevel, $000000);
end;
end.
Vous n'êtes pas encore membre ?
inscrivez-vous, c'est gratuit et ça prend moins d'une minute !
Les membres obtiennent plus de réponses que les utilisateurs anonymes.
Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.
Le fait d'être membre vous permet d'avoir des options supplémentaires.