SystemVolume W6-10 CoInitialize CoUninitialize [MasterVolume, MasterMute] lazarus / 34-Windows ---------------------------------------------------------------------- RAW · 2017-02-13 02:30 Is it really necessary to use COINITIALIZE and COUNINITIALIZE ? I remember a post where someone said that it is only necessary in Delphi not in FreePascal. I was playing around with this Code and everything is working as it should. Then I recognized that I miss those two lines... And If so where should I put those lines ??? Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i Unit uMasterMuteW7; {$MODE OBJFPC}{$H+} Interface  USES  Classes, SysUtils, Forms, Controls,  Windows, ComObj, ActiveX, ShellApi;   TYPE  TMyBOOL = (myFalse = Integer(0),             myTrue  = Integer(1));  TYPE  TwndGUI = Class(TForm)    Procedure SetMasterVolume (    sinVol: Single );   Procedure GetMasterVolume (Out sinVol: Single );   Function  GetMasterMute              : TMyBOOL;   Procedure SetMasterMute   (     Value: TMyBOOL);    Procedure FormKeyDown     (Sender: TObject; Var Key: Word;                              Shift : TShiftState);  End;   // WINDOWS 7 VOLUME BEGIN TYPE  IAudioEndpointVolumeCallback = Interface(IUnknown)   ['{657804FA-D6AD-4496-8A60-352752AF4F89}']  End;   IAudioEndpointVolume = Interface(IUnknown)   ['{5CDF2C82-841E-4546-9722-0CF74078229A}']     Function RegisterControlChangeNotify(              AudioEndPtVol: IAudioEndpointVolumeCallback): HRESULT; StdCall;    Function UnregisterControlChangeNotify(              AudioEndPtVol: IAudioEndpointVolumeCallback): HRESULT; StdCall;    Function GetChannelCount(Out PInteger): HRESULT; StdCall;     Function SetMasterVolumeLevel(              fLevelDB: Single; pguidEventContext: PGUID): HRESULT; StdCall;    Function SetMasterVolumeLevelScalar(              fLevelDB: Single; pguidEventContext: PGUID): HRESULT; StdCall;     Function GetMasterVolumeLevel(              Out fLevelDB: Single): HRESULT; StdCall;    Function GetMasterVolumeLevelScalar(              Out fLevelDB: Single): HRESULT; StdCall;     Function SetChannelVolumeLevel(              nChannel: Integer; fLevelDB: Double; pguidEventContext: PGUID):             HRESULT; StdCall;    Function SetChannelVolumeLevelScalar(              nChannel: Integer; fLevelDB: Double; pguidEventContext: PGUID):             HRESULT; StdCall;     Function GetChannelVolumeLevel(              nChannel: Integer; Out fLevelDB: Double): HRESULT; StdCall;    Function GetChannelVolumeLevelScalar(              nChannel: Integer; Out fLevelDB: Double): HRESULT; StdCall;     Function SetMute(            bSetMute: Bool; pguidEventContext: PGUID): HRESULT; StdCall;    Function GetMute(              Out bGetMute: Bool): HRESULT; StdCall;     Function GetVolumeStepInfo(              pnStep: Integer; Out pnStepCount: Integer): HRESULT; StdCall;    Function VolumeStepUp(              pguidEventContext: PGUID): HRESULT; StdCall;    Function VolumeStepDown(              pguidEventContext: PGUID): HRESULT; StdCall;    Function GetVolumeRange(              Out pflVolumeMindB: Double; Out pflVolumeMaxdB: Double;              Out pflVolumeIncrementdB: Double): HRESULT; StdCall;    Function QueryHardwareSupport(              Out pdwHardwareSupportMask): HRESULT; StdCall;  End;   IAudioMeterInformation = Interface(IUnknown)   ['{C02216F6-8C67-4B5B-9D00-D008E73E0064}']  End;   IPropertyStore = Interface(IUnknown)  End;   IMMDevice = Interface(IUnknown)   ['{D666063F-1587-4E43-81F1-B948E807363F}']    Function Activate(              Const refId: TGUID; dwClsCtx: DWORD; pActivationParams: PInteger;              Out pEndpointVolume: IAudioEndpointVolume): HRESULT; StdCall;    Function OpenPropertyStore(              stgmAccess: DWORD; Out ppProperties: IPropertyStore):             HRESULT; StdCall;    Function GetId   (Out ppstrId: PLPWSTR): HRESULT; StdCall;    Function GetState(Out State: Integer):   HRESULT; StdCall;  End;   IMMDeviceCollection = interface(IUnknown)   ['{0BD7A1BE-7A1A-44DB-8397-CC5392387B5E}']  End;   IMMNotificationClient = interface(IUnknown)   ['{7991EEC9-7E89-4D85-8390-6C703CEC60C0}']  End;   IMMDeviceEnumerator = interface(IUnknown)   ['{A95664D2-9614-4F35-A746-DE8DB63617E6}']    Function EnumAudioEndpoints(              dataFlow: TOleEnum; deviceState: SYSUINT; DevCollection:              IMMDeviceCollection): HRESULT; StdCall;    Function GetDefaultAudioEndpoint(              EDF: SYSUINT; ER: SYSUINT; Out Dev: IMMDevice): HRESULT; StdCall;    Function GetDevice(pwstrId: Pointer; Out Dev: IMMDevice): HRESULT; StdCall;    Function RegisterEndpointNotificationCallback(            pClient: IMMNotificationClient): HRESULT; StdCall;  End;  CONST  CLASS_IMMDeviceEnumerator: TGUID = '{BCDE0395-E52F-467C-8E3D-C4579291692E}';  IID_IMMDeviceEnumerator  : TGUID = '{A95664D2-9614-4F35-A746-DE8DB63617E6}';  IID_IAudioEndpointVolume : TGUID = '{5CDF2C82-841E-4546-9722-0CF74078229A}'; // WINDOWS 7 VOLUME END  VAR  wndGUI: TwndGUI; Implementation {$R *.LFM}  Procedure TwndGUI.FormKeyDown(Sender: TObject; Var Key: Word;                            Shift : TShiftState);  Var   myMute: TMyBOOL;   sinVol: Single; Begin  // MIXER  If Key = Ord('V')  Then ShellExecute(0, Nil, PChar('sndvol.exe'), '', '', SW_SHOWNORMAL);   // MUTE  If Key = Ord('M')  Then   Begin    myMute:= GetMasterMute;     If myMute = myTrue    Then SetMasterMute(myFalse)    Else SetMasterMute(myTrue);   End;   // MAX VOLUME  If Key = Ord('F')  Then   Begin    myMute:= GetMasterMute;     If myMute = myTrue    Then SetMasterMute(myFalse);     SetMasterVolume(1.0);   End;   // VOLUME UP 1%  If Key = VK_UP  Then   Begin    GetMasterVolume(sinVol);     sinVol:= sinVol+0.01;     If sinVol   > 1.0    Then sinVol:= 1.0;     SetMasterVolume(sinVol);   End;   // VOLUME DOWN 1%  If Key = VK_DOWN  Then   Begin    GetMasterVolume(sinVol);     sinVol:= sinVol-0.01;   If sinVol   < 0.0    Then sinVol:= 0.0;     SetMasterVolume(sinVol);   End; End;  Procedure TwndGUI.SetMasterVolume(sinVol: Single);  Var   EndpointVolume  : IAudioEndpointVolume;   DeviceEnumerator: IMMDeviceEnumerator;   Device          : IMMDevice; Begin  CoCreateInstance(   CLASS_IMMDeviceEnumerator, Nil, CLSCTX_INPROC_SERVER,   IID_IMMDeviceEnumerator, DeviceEnumerator);  DeviceEnumerator.GetDefaultAudioEndpoint($00000000, $00000000, Device);  Device.Activate(   IID_IAudioEndpointVolume, CLSCTX_INPROC_SERVER, Nil, EndpointVolume);  EndpointVolume.SetMasterVolumeLevelScalar(sinVol, Nil); End;  Procedure TwndGUI.GetMasterVolume(Out sinVol: Single);  Var   EndpointVolume  : IAudioEndpointVolume;   DeviceEnumerator: IMMDeviceEnumerator;   Device          : IMMDevice; Begin  CoCreateInstance(   CLASS_IMMDeviceEnumerator, Nil, CLSCTX_INPROC_SERVER,   IID_IMMDeviceEnumerator, DeviceEnumerator);  DeviceEnumerator.GetDefaultAudioEndpoint($00000000, $00000000, Device);  Device.Activate(   IID_IAudioEndpointVolume, CLSCTX_INPROC_SERVER, Nil, EndpointVolume);  EndpointVolume.GetMasterVolumeLevelScalar(sinVol); End;  Function TwndGUI.GetMasterMute: TMyBOOL;  Var   EndpointVolume  : IAudioEndpointVolume;   DeviceEnumerator: IMMDeviceEnumerator;   Device          : IMMDevice;    hrRes: HResult;   bRes : BOOL; Begin  CoCreateInstance(   CLASS_IMMDeviceEnumerator, Nil, CLSCTX_INPROC_SERVER,   IID_IMMDeviceEnumerator, DeviceEnumerator);  DeviceEnumerator.GetDefaultAudioEndpoint($00000000, $00000000, Device);  Device.Activate(   IID_IAudioEndpointVolume, CLSCTX_INPROC_SERVER, Nil, EndpointVolume);   hrRes:= EndpointVolume.GetMute(bRes);    If FAILED(hrRes)   Then OleCheck(hrRes);   Result:= TMyBOOL(bRes); End;  Procedure TwndGUI.SetMasterMute(Value: TMyBOOL);  Var   EndpointVolume  : IAudioEndpointVolume;   DeviceEnumerator: IMMDeviceEnumerator;   Device          : IMMDevice;    hrRes: HResult; Begin  CoCreateInstance(   CLASS_IMMDeviceEnumerator, Nil, CLSCTX_INPROC_SERVER,   IID_IMMDeviceEnumerator, DeviceEnumerator);  DeviceEnumerator.GetDefaultAudioEndpoint($00000000, $00000000, Device);  Device.Activate(   IID_IAudioEndpointVolume, CLSCTX_INPROC_SERVER, Nil, EndpointVolume);   hrRes:= EndpointVolume.SetMute(BOOL(Value), Nil);   OleCheck(hrRes); End; End. ---------------------------------------------------------------------- Thaddy · 2017-02-13 06:12 Quote from: RAW on February 13, 2017, 03:30:26 amIs it really necessary to use COINITIALIZE and COUNINITIALIZE ? I remember a post where someone said that it is only necessary in Delphi not in FreePascal. That's only the case if you use the comobj unit, which is not necessary to use com in general. So that information is .... not correct... That would be highly gambling to rely on. comobj needs only to be pulled in if you write your own com objects. ActiveX is the one you want if you use third party com code, like in your case. Every COM using program needs to initialize and uninitialize the COM sub-system in any language. You only have to do it once so  do it in the initialization and finalization section of the main unit and/or in the unit above. There is no harm to do it in more than one unit though. May even be practical. There is a refcount on it, so for every call to coInitialize you have to call a corresponding coUninitialize. Hence the initialization and finalization sections are the right place to call them. so before  the end of your code add: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i initialization   coInitialize(nil);finalization  coUnInitialize;end. To summarize: If you have comobj somewhere in the uses clause it is not necessary to call coInitialize/coUnInitialize. If you use just external com objects and need just ActiveX to work with it, you need to call coInitialize and coUnInitialize. Don't pull in comobj if you do not need it, i.e.: if you don't write com objects yourself. There's no real harm in adding comobj to the uses clause, but your code will be much larger. Com code from comobj can not be always eliminated by the compiler/linker if you do not use it due to its run-time callable nature. ---------------------------------------------------------------------- RAW · 2017-02-13 21:17 Thank you very much for your explanation... So the first code doesn't need coInitialize and coUninitialize because of COMOBJ, but if I don't need OLECHECK (it's optional), then I can use only ACTIVEX in combination with coInitialize and coUninitialize and eliminate COMOBJ. Sounds good... Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i Unit uMasterMuteW7; {$MODE OBJFPC}{$H+} Interface  USES  Classes, SysUtils, Forms, Controls,  Windows, ActiveX,  ShellApi;  TYPE  TMyBOOL = (myFalse = Integer(0),             myTrue  = Integer(1));  TYPE  TwndGUI = Class(TForm)    Procedure SetMasterVolume (    sinVol: Single );   Procedure GetMasterVolume (Out sinVol: Single );   Function  GetMasterMute              : TMyBOOL;   Procedure SetMasterMute   (     Value: TMyBOOL);    Procedure FormKeyDown     (Sender: TObject; Var Key: Word;                              Shift : TShiftState);  End;  // WINDOWS 7 VOLUME BEGIN TYPE  IAudioEndpointVolumeCallback = Interface(IUnknown)   ['{657804FA-D6AD-4496-8A60-352752AF4F89}']  End;   IAudioEndpointVolume = Interface(IUnknown)   ['{5CDF2C82-841E-4546-9722-0CF74078229A}']     Function RegisterControlChangeNotify(              AudioEndPtVol: IAudioEndpointVolumeCallback): HRESULT; StdCall;    Function UnregisterControlChangeNotify(              AudioEndPtVol: IAudioEndpointVolumeCallback): HRESULT; StdCall;    Function GetChannelCount(Out PInteger): HRESULT; StdCall;     Function SetMasterVolumeLevel(              fLevelDB: Single; pguidEventContext: PGUID): HRESULT; StdCall;    Function SetMasterVolumeLevelScalar(              fLevelDB: Single; pguidEventContext: PGUID): HRESULT; StdCall;     Function GetMasterVolumeLevel(              Out fLevelDB: Single): HRESULT; StdCall;    Function GetMasterVolumeLevelScalar(              Out fLevelDB: Single): HRESULT; StdCall;     Function SetChannelVolumeLevel(              nChannel: Integer; fLevelDB: Double; pguidEventContext: PGUID):             HRESULT; StdCall;    Function SetChannelVolumeLevelScalar(              nChannel: Integer; fLevelDB: Double; pguidEventContext: PGUID):             HRESULT; StdCall;     Function GetChannelVolumeLevel(              nChannel: Integer; Out fLevelDB: Double): HRESULT; StdCall;    Function GetChannelVolumeLevelScalar(              nChannel: Integer; Out fLevelDB: Double): HRESULT; StdCall;     Function SetMute(            bSetMute: Bool; pguidEventContext: PGUID): HRESULT; StdCall;    Function GetMute(              Out bGetMute: Bool): HRESULT; StdCall;     Function GetVolumeStepInfo(              pnStep: Integer; Out pnStepCount: Integer): HRESULT; StdCall;    Function VolumeStepUp(              pguidEventContext: PGUID): HRESULT; StdCall;    Function VolumeStepDown(              pguidEventContext: PGUID): HRESULT; StdCall;    Function GetVolumeRange(              Out pflVolumeMindB: Double; Out pflVolumeMaxdB: Double;              Out pflVolumeIncrementdB: Double): HRESULT; StdCall;    Function QueryHardwareSupport(              Out pdwHardwareSupportMask): HRESULT; StdCall;  End;   IAudioMeterInformation = Interface(IUnknown)   ['{C02216F6-8C67-4B5B-9D00-D008E73E0064}']  End;   IPropertyStore = Interface(IUnknown)  End;   IMMDevice = Interface(IUnknown)   ['{D666063F-1587-4E43-81F1-B948E807363F}']    Function Activate(              Const refId: TGUID; dwClsCtx: DWORD; pActivationParams: PInteger;              Out pEndpointVolume: IAudioEndpointVolume): HRESULT; StdCall;    Function OpenPropertyStore(              stgmAccess: DWORD; Out ppProperties: IPropertyStore):             HRESULT; StdCall;    Function GetId   (Out ppstrId: PLPWSTR): HRESULT; StdCall;    Function GetState(Out State: Integer):   HRESULT; StdCall;  End;   IMMDeviceCollection = interface(IUnknown)   ['{0BD7A1BE-7A1A-44DB-8397-CC5392387B5E}']  End;   IMMNotificationClient = interface(IUnknown)   ['{7991EEC9-7E89-4D85-8390-6C703CEC60C0}']  End;   IMMDeviceEnumerator = interface(IUnknown)   ['{A95664D2-9614-4F35-A746-DE8DB63617E6}']    Function EnumAudioEndpoints(              dataFlow: TOleEnum; deviceState: SYSUINT; DevCollection:              IMMDeviceCollection): HRESULT; StdCall;    Function GetDefaultAudioEndpoint(              EDF: SYSUINT; ER: SYSUINT; Out Dev: IMMDevice): HRESULT; StdCall;    Function GetDevice(pwstrId: Pointer; Out Dev: IMMDevice): HRESULT; StdCall;    Function RegisterEndpointNotificationCallback(            pClient: IMMNotificationClient): HRESULT; StdCall;  End;  CONST  CLASS_IMMDeviceEnumerator: TGUID = '{BCDE0395-E52F-467C-8E3D-C4579291692E}';  IID_IMMDeviceEnumerator  : TGUID = '{A95664D2-9614-4F35-A746-DE8DB63617E6}';  IID_IAudioEndpointVolume : TGUID = '{5CDF2C82-841E-4546-9722-0CF74078229A}'; // WINDOWS 7 VOLUME END  VAR  wndGUI: TwndGUI; Implementation {$R *.LFM}  Procedure TwndGUI.FormKeyDown(Sender: TObject; Var Key: Word;                            Shift : TShiftState);  Var   myMute: TMyBOOL;   sinVol: Single; Begin  // MIXER  If Key = Ord('V')  Then ShellExecute(0, Nil, PChar('sndvol.exe'), '', '', SW_SHOWNORMAL);   // MUTE  If Key = Ord('M')  Then   Begin    myMute:= GetMasterMute;     If myMute = myTrue    Then SetMasterMute(myFalse)    Else SetMasterMute(myTrue);   End;   // MAX VOLUME  If Key = Ord('F')  Then   Begin    myMute:= GetMasterMute;     If myMute = myTrue    Then SetMasterMute(myFalse);     SetMasterVolume(1.0);   End;   // VOLUME UP 1%  If Key = VK_UP  Then   Begin    GetMasterVolume(sinVol);       If (1-sinVol) < 0.01    Then sinVol:= 1    Else sinVol:= sinVol+0.01;     SetMasterVolume(sinVol);   End;   // VOLUME DOWN 1%  If Key = VK_DOWN  Then   Begin    GetMasterVolume(sinVol);     If (sinVol-0.01) < 0    Then sinVol:= 0    Else sinVol:= sinVol-0.01;   SetMasterVolume(sinVol);   End; End;  Procedure TwndGUI.SetMasterVolume(sinVol: Single);  Var   EndpointVolume  : IAudioEndpointVolume;   DeviceEnumerator: IMMDeviceEnumerator;   Device          : IMMDevice; Begin  CoCreateInstance(   CLASS_IMMDeviceEnumerator, Nil, CLSCTX_INPROC_SERVER,   IID_IMMDeviceEnumerator, DeviceEnumerator);  DeviceEnumerator.GetDefaultAudioEndpoint($00000000, $00000000, Device);  Device.Activate(   IID_IAudioEndpointVolume, CLSCTX_INPROC_SERVER, Nil, EndpointVolume);  EndpointVolume.SetMasterVolumeLevelScalar(sinVol, Nil); End;  Procedure TwndGUI.GetMasterVolume(Out sinVol: Single);  Var   EndpointVolume  : IAudioEndpointVolume;   DeviceEnumerator: IMMDeviceEnumerator;   Device          : IMMDevice; Begin  CoCreateInstance(   CLASS_IMMDeviceEnumerator, Nil, CLSCTX_INPROC_SERVER,   IID_IMMDeviceEnumerator, DeviceEnumerator);  DeviceEnumerator.GetDefaultAudioEndpoint($00000000, $00000000, Device);  Device.Activate(   IID_IAudioEndpointVolume, CLSCTX_INPROC_SERVER, Nil, EndpointVolume);  EndpointVolume.GetMasterVolumeLevelScalar(sinVol); End;  Function TwndGUI.GetMasterMute: TMyBOOL;  Var   EndpointVolume  : IAudioEndpointVolume;   DeviceEnumerator: IMMDeviceEnumerator;   Device          : IMMDevice;    bRes: BOOL; Begin  CoCreateInstance(   CLASS_IMMDeviceEnumerator, Nil, CLSCTX_INPROC_SERVER,   IID_IMMDeviceEnumerator, DeviceEnumerator);  DeviceEnumerator.GetDefaultAudioEndpoint($00000000, $00000000, Device);  Device.Activate(   IID_IAudioEndpointVolume, CLSCTX_INPROC_SERVER, Nil, EndpointVolume);  EndpointVolume.GetMute(bRes);   Result:= TMyBOOL(bRes); End;  Procedure TwndGUI.SetMasterMute(Value: TMyBOOL);  Var   EndpointVolume  : IAudioEndpointVolume;   DeviceEnumerator: IMMDeviceEnumerator;   Device          : IMMDevice; Begin  CoCreateInstance(   CLASS_IMMDeviceEnumerator, Nil, CLSCTX_INPROC_SERVER,   IID_IMMDeviceEnumerator, DeviceEnumerator);  DeviceEnumerator.GetDefaultAudioEndpoint($00000000, $00000000, Device);  Device.Activate(   IID_IAudioEndpointVolume, CLSCTX_INPROC_SERVER, Nil, EndpointVolume);  EndpointVolume.SetMute(BOOL(Value), Nil); End; Initialization coInitia lize(Nil);Finalization coUnInitialize; End.  I was a little bit confused, because if I don't use COMOBJ and don't use coInitialize and coUninitialize then it's still working. Normally when I miss something, then I expect an error or any kind of exception or at least that the code is not working. ---------------------------------------------------------------------- majid.ebru · 2017-10-28 22:55 Hi is it possible put your sample program , here?