Volume Control Program SmartVolume production notes on
==========================================
For a long time, I have been so disgusted with Win2000's volume control. Sometimes when the volume is not suitable for adjustment, I will click the small horn on the tray bar. The next step is not to drag the lever, but to wait patiently ...... just listen to a burst of hard drive, the mouse cursor turns into an hourglass, around five seconds, will jump out of the small adjust volume window. I felt a sigh of relief and made a adjustment. This is the case every time.
In the dark of night, sometimes running a program suddenly generates a loud voice, fearing that it will affect my family's sleeping, and then I am in a hurry! The previous volume adjustment must be unavailable because the response is too slow. I jumped up and went to the switch behind the speaker. Switch is surprisingly difficult to find. What's more, this is an emergency? Dial the power cord of the speaker. The whole world is quiet. I sat down and breathed a sigh of relief. I was glad that I didn't dial the power cord of the host.
Think of the "Good Days" that we used to use win98 ". The volume under 98 is adjusted very quickly, so don't worry about it. But it is also not good. In the middle of the night, I want to listen to music. Of course, I need to adjust the volume to a small value. However, when I pulled the TraceBar to the bottom, it broke down! The volume suddenly becomes the maximum! It was a bit of a mess, and later I scolded Microsoft.
I have made countless efforts to find a volume control software or write one by myself. I searched the internet roughly. I don't have a proper choice. I 'd better write it by myself. This is the benefit of being a programmer. Haha.
The trouble is that I don't know the API for controlling the volume. Check online. Find an article from google, how to control the computer system volume http://gamepower.myst.com.cn/tech/vb_clvol.htm), a look, is the VB source code, which contains several API instructions and calls. That's easy to find. Let's take a look at the APIS it uses: auxGetNumDevs, auxGetDevCaps, auxSetVolume, and auxGetVolume. It looks like these Apis.
Use the file search function provided by windows to search for files with auxSetVolume *. pas in all Delphi source code and control source code, only in mmsystem. pas. Check out the relevant statements. I did not know enough about delphi. I forgot to check the Delphi source program first.
Unfortunately, the sample program is not found. Check the Windows SDK help provided by Delphi. It seems that it is not detailed enough. Check it on MSDN and find that the content of the two is similar. I tried to run this statement in Delphi.
ShowMessage (Inttostr (auxGetNumDevs); // use mmsystem;
The result is 0. It seems that there is still a problem here. aux means the auxiliary device, probably not here. I want to adjust the main volume of windows, not wave, midi, or aux. I don't know much about multimedia. I can only guess this.
It seems that I have seen software that monitors APIs. If I can monitor which APIS it has called when adjusting the volume, will it solve it? Therefore, the "monitoring API" is used for keyword search on Google. It turns out that this software is called APIspy. Chinese websites are hard to download. Use apispy download to continue google search. Finally, we downloaded version 2.5 from a foreign site. Http://madmat.hypermart.net/apis3225.exe)
APIspy can specify and run a program to monitor API calls during running. How do I know the program name for adjusting the volume in windows?
Use Sound for keyword query in MSDN and find an article
The SndVol32 program (sndvol32.exe) controls both the volume settings for varous sound sources (such as wave, CD, and synthesizer) and the master volume setting.
It was originally sndvol32.exe, and I found it easily in system32. Open it with apispy, And the run button is grayed out. I tried to click imports next to it. A dialog box is displayed, showing the name of the api of each dll called by the sndvol32 program. There are advapi32.dll, comctl32.dll,... and finally winmm. dll. I only care about sound control. Of course, I double-click each winmm api to add them to the monitoring list.
Now the run button is available. Click it. The Volume Control window is displayed, and apispy displays the called APIs. I pulled the main volume Adjusting Lever And the monitoring window changed. In the monitoring results, I found several calls: mixerGetControlDetails and mixerGetLineInfo. Mixer is a mix.
On MSDN, I continued to use the newly found API and found several related items.
UINT mixerGetNumDevs (VOID );
MMRESULT mixerSetControlDetails (
HMIXEROBJ hmxobj,
LPMIXERCONTROLDETAILS pmxcd,
DWORD fdwDetails
);
Complicated! (See http://msdn.microsoft.com/library/default.asp? Url =/library/EN-US/multimed/mmfunc_8hkf.asp)
Try to call mixerGetNumDevs in Delphi. The result is 1. Run the following code:
Procedure TForm1.Button1Click (Sender: TObject );
Var
NumDevs: integer;
Dcaps: TAuxCaps;
I: integer;
Begin
NumDevs: = mixerGetNumDevs;
For I: = 0 to NumDevs-1 do
Begin
MixerGetDevCaps (I, @ dcaps, sizeof (dcaps ));
Listbox1.Items. Add (dcaps. szPname)
End;
End;
The result is SiS 7012 Wave, which is my sound card. Everything is correct.
I tried to use mixerSetControlDetails to set the volume, but I couldn't always get in. Go online again and find the demonstration case. I do not know why, google can not go, with Baidu query mixerSetControlDetails, find an article, the name is "volume adjustment and mute" (http://www.csdn.net/develop/article/17/17257.shtm), the author is Haofei. Next, it is a complete unit of Delphi. There are four functions to get the volume GetVolume (DN), set the volume SetVolume (DN, Value), and get the mute GetVolumeMute (DN) and set the mute SetVolumeMute (DN, Value ).
Put it in your own program and write two lines of code, which is completely correct.
I wanted to write it on my own. I don't think someone has finished it. We are both happy and disappointed. So far, we have explored the technology of volume adjustment.
There is no difficulty in the rest of the work, and soon you can write your own volume control program.
Conclusion: In the search process, also found the hubdog home page also has a similar article "Delphi 4 Write Audio Mixer Control" (http://hubdog.myrice.com/Recommend/rcAudioMixer.htm), it seems that, many people have tried the same thing, and I am just a little late.
Originally, the problem was solved, but throughout the process, I began to want to write my own experiences for reference by beginners.
----------------------------------------------------------------------
Volume Control Program SmartVolume production notes
==========================================
Next, we will go to the field programming stage.
What I want is:
1. Press a hot key such as Ctrl-Alt-minus on the keyboard to turn on/off the sound.
2. Press the hot key Ctrl-Alt-Up and down arrow keys to adjust the volume.
There is also a small problem that needs to be solved, that is, the global hot key. I know that LMDGlobalHotkey can be used in the LMD control group, but I want to solve this problem by myself this time.
I can go to the LMD source code or access the Internet to find information, but I remember it was like the Register header Api. I checked it from the SDK help. It was indeed the RegisterHotKey and UnregisterHotKey, and the message WM_HOTKEY was used at the same time.
Let's take a look at the API help. After a simple analysis, I wrote a program as follows and ran it. It seems very simple. I used to think too complicated about these technologies:
Procedure TForm1.Button2Click (Sender: TObject );
Begin
RegisterHotKey (handle, 1, MOD_ALT or MOD_CONTROL, VK_SUBTRACT); // Ctrl-Alt-keyboard minus sign
RegisterHotKey (handle, 2, MOD_ALT or MOD_CONTROL, VK_DOWN); // Ctrl-Alt-
End;
Procedure TForm1.WMHotKey (var Message: TWMHotkey );
Begin
Case Message. HotKey
1: showmessage ('1 ');
2: showmessage ('2 ');
Else
Showmessage (inttostr (message. HotKey ));
End;
End;
Procedure TForm1.Button3Click (Sender: TObject );
Begin
UnregisterHotKey (handle, 1 );
UnregisterHotKey (handle, 2 );
End;
The next step is to get your own HOTKEY. Delphi has a native THotkey control to do this. However, with help, THotkey serves TMenuItem. Turning it into a parameter used by the API really takes a long time. By looking at the source code of THotkey and adding a test, it is done.
Procedure TForm1.Button2Click (Sender: TObject );
Var
Modifiers: integer;
HK: longint;
Begin
Modifiers: = 0;
If hkShift in Hotkey1.Modifiers then
Modifiers: = Modifiers or MOD_SHIFT;
If hkCtrl in Hotkey1.Modifiers then
Modifiers: = Modifiers or MOD_CONTROL;
If hkAlt in Hotkey1.Modifiers then
Modifiers: = Modifiers or MOD_ALT;
HK: = SendMessage (Hotkey1.Handle, HKM_GETHOTKEY, 0, 0); // learned from the source code
Win32Check (RegisterHotKey (handle, 1, Modifiers, HK and $ FF ));
End;
The parameter of THotkey should be easily saved. You only need to save two numbers: byte (Hotkey1.Modifiers) and Hotkey1.Hotkey.
I want to come and think about it. It's still uncomfortable to use Delphi's THotkey. Write a component by yourself. The name is TGlobalHotKey.
I have little experience writing components, but I only know the general method.
For example, when adding or deleting some attributes, we found that the Inspector of the Object was not reflected in time. Open DclUser. dpk and compile it.
Haha, it's done. The following is the source code of the GlobalHotKey control.
// ------------------- GlobalHotKey. pas start ----------------------
// Author: anfuguo http://anjo.delphibbs.com 2003.5
Unit GlobalHotKey;
Interface
Uses
SysUtils, Classes, Controls, ComCtrls, IniFiles, Windows,
CommCtrl, Messages;
Type
TGlobalHotKey = class (THotKey)
Private
FGlobalID: integer;
FOnExecute: tpolicyevent;
Procedure SetGlobalID (const Value: integer );
{Private declarations}
Protected
{Protected declarations}
Procedure WMHotKey (var Message: TWMHotkey); message WM_HOTKEY;
Public
{Public declarations}
// Save the hotkey to the INI File
Procedure LoadFromIni (Ini: TIniFile );
// Retrieve the hotkey from the INI File
Procedure SaveToIni (Ini: TIniFile );
// Check whether the Hotkey has been registered in windows. If no value exists, true is returned.
Function QueryGlobalHotkey: boolean;
// Register as a global Hotkey
Function RegisterGlobalHotkey: boolean;
// Cancel the global Hotkey
Procedure UnregisterGlobalHotkey;
// Compare with another THotKey
Function compute to (AHotKey: THotKey): boolean;
Published
{Published declarations}
Property GlobalID: integer read FGlobalID write SetGlobalID default 1;
Property OnExecute: tpolicyevent read FOnExecute write FOnExecute;
End;
Procedure Register;
Implementation
Procedure Register;
Begin
RegisterComponents ('system', [TGlobalHotKey]);
End;
{TGlobalHotKey}
Function TGlobalHotKey. pointer to (AHotKey: THotKey): boolean;
Begin
Result: = (Modifiers = AHotKey. Modifiers) and (HotKey = AHotKey. HotKey );
End;
Procedure TGlobalHotKey. LoadFromIni (Ini: TIniFile );
Var
SectionName: string;
Begin
SectionName: = 'globalkey _ '+ name;
Modifiers: = THKModifiers (byte (ini. ReadInteger (SectionName, 'modifiers', byte (Modifiers ))));
HotKey: = ini. ReadInteger (SectionName, 'hotkey', Hotkey );
End;
Function TGlobalHotKey. QueryGlobalHotkey: boolean;
Begin
Result: = RegisterGlobalHotkey;
If result then
UnregisterGlobalHotkey;
End;
Function TGlobalHotKey. RegisterGlobalHotkey: boolean;
Var
AModifiers: integer;
HK: longint;
Begin
AModifiers: = 0;
If hkShift in Modifiers then
AModifiers: = AModifiers or MOD_SHIFT;
If hkCtrl in Modifiers then
AModifiers: = AModifiers or MOD_CONTROL;
If hkAlt in Modifiers then
AModifiers: = AModifiers or MOD_ALT;
HK: = SendMessage (Handle, HKM_GETHOTKEY, 0, 0 );
Result: = RegisterHotKey (handle, GlobalID, AModifiers, HK and $ FF );
End;
Procedure TGlobalHotKey. SaveToIni (Ini: TIniFile );
Var
SectionName: string;
Begin
SectionName: = 'globalkey _ '+ name;
Ini. WriteInteger (SectionName, 'modifiers', byte (Modifiers ));
Ini. WriteInteger (SectionName, 'hotkey', Hotkey );
End;
Procedure TGlobalHotKey. SetGlobalID (const Value: integer );
Begin
FGlobalID: = Value;
End;
Procedure TGlobalHotKey. UnregisterGlobalHotkey;
Begin
UnregisterHotKey (handle, GlobalID );
End;
Procedure TGlobalHotKey. WMHotKey (var Message: TWMHotkey );
Begin
If Assigned (FOnExecute) then FOnExecute (Self );
End;
End.
// ------------------- GlobalHotKey. pas ended ------------------------
In GlobalHotKey, I added the GlobalID parameter used to call the RegisterHotKey for the original THotkey and the event onExecute in response to the Hotkey press.
It is reasonable to say that TGlobalHotKey should be made into a non-visual control, but I think, if you don't want to see it, you can set the Visible attribute to False, and the effect is the same.
According to the previously conceived SmartVolume function, it needs to reduce the runtime to the taskbar in the lower right corner. This is a standard TrayIcon application. I have seen numerous articles on TrayIcon since I started learning Delphi, and I usually use the corresponding control RxTrayIcon in Rxlib for perfection and convenience. I didn't need any controls to complete SmartVolume. I looked at the TrayIcon materials, which is very troublesome! Still use Rxlib.
After more than two days of work, the program was completed. The preceding two functions are completely implemented, and you can customize the hot key by using sndvol32.exe. After each hot key adjustment, the window will automatically disappear after three seconds.
Although I have written countless programs in my life, I think this one is the most perfect ......
Continue to read the full text of volume control program preparation note (and all source code...