IAudioEndpointVolume has no member named GetMasterVolumeLevelScalar - c++

Consider this program:
#include <stdio.h>
#include <windows.h>
#include <mmdeviceapi.h>
#include <endpointvolume.h>
#include <math.h>
int main() {
IAudioEndpointVolume *wh;
IMMDevice *ya;
IMMDeviceEnumerator *xr;
CoInitialize(0);
CoCreateInstance(__uuidof(MMDeviceEnumerator), 0, CLSCTX_INPROC_SERVER,
__uuidof(IMMDeviceEnumerator), (void**)&xr);
xr->GetDefaultAudioEndpoint(eRender, eConsole, &ya);
ya->Activate(__uuidof(IAudioEndpointVolume), CLSCTX_ALL, 0, (void**)&wh);
float zu;
wh->GetMasterVolumeLevelScalar(&zu);
printf("%d\n", (int) round(100 * zu));
}
I can compile it as C++ with no issue:
x86_64-w64-mingw32-g++ vol.cpp -lole32
However if I try to compile it as C:
x86_64-w64-mingw32-gcc vol.c -lole32
I get errors such as:
error: ‘IAudioEndpointVolume’ has no member named ‘GetMasterVolumeLevelScalar’
This program does not seem to be particularly “C++”, so what is causing the
problem? Also, can I change something so that it compiles as C?

This seems to do it:
#include <stdio.h>
#include <initguid.h>
#include <mmdeviceapi.h>
#include <endpointvolume.h>
#include <math.h>
int main() {
IAudioEndpointVolume *wh;
IMMDevice *ya;
IMMDeviceEnumerator *xr;
CoInitialize(0);
CoCreateInstance(&CLSID_MMDeviceEnumerator, 0, CLSCTX_INPROC_SERVER,
&IID_IMMDeviceEnumerator, (void**)&xr);
xr->lpVtbl->GetDefaultAudioEndpoint(xr, eRender, eConsole, &ya);
ya->lpVtbl->Activate(ya, &IID_IAudioEndpointVolume, CLSCTX_ALL,
0, (void**)&wh);
float zu;
wh->lpVtbl->GetMasterVolumeLevelScalar(wh, &zu);
printf("%d\n", (int) round(100 * zu));
}
Changes:
#include <initguid.h>
&CLSID_MMDeviceEnumerator instead of __uuidof(MMDeviceEnumerator)
lpVtbl->GetDefaultAudioEndpoint instead of GetDefaultAudioEndpoint
Source

Related

How do I address character encoding issues with PROCESSENTRY32 for the C++ compiler?

I know this has likely been addressed before, but I am struggling to solve this issue and it is driving me nuts.
I have a "target process name" static string defined (as ANSI) which I am later using with a "find_process" function later in my code - specifically the comparison function "_stricmp". While I don't define that the program should be compiled (at least I dont think I do) as UNICODE, it seems that PROCESSENTRY32 is opting for PROCESSENTRY32W by default (UNICODE). And it throws the error below for "_stricmp" as PROCESSENTRY32 is UNICODE and my static string is ANSI. (see error image below)
But when I change the "target process name" to WCHAR* and use "wcscmp" for debugging string comparison in the "find_process" function, all of a sudden PROCESSENTRY32 doesn't seem to be UNICODE anymore and it fails saying PROCESSENTRY32 is CHAR[240] and not WCHAR*. Not sure what is happening.
Any ideas how I can address this issue? I know it compiles fine with a C compiler, however trying to address the issue for the C++ compiler.
#include <Windows.h>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <string.h>
#include <stdio.h>
#include <wincrypt.h>
#include <winuser.h>
#include <string>
#include <cstring>
#include <strsafe.h>
#pragma comment (lib, "crypt32.lib")
#pragma comment (lib, "advapi32")
#include <psapi.h>
#define DEFAULT_BUFLEN 1024
#pragma comment(lib, "user32.lib")
#include <memoryapi.h>
#include <tlhelp32.h>
#include <stdlib.h>
#include <wchar.h>
#include <exception>
// const string definition as ANSI
#define TARGET_PROCESS_NAME "notepad.exe"
"find process" function:
DWORD find_process(const char* process) {
PROCESSENTRY32 process_entry;
process_entry.dwSize = sizeof(PROCESSENTRY32);
DWORD dwProcessId;
//get the list of processes
HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
//check processes to find TARGET_PROCESS_NAME
if (Process32First(snapshot, &process_entry) == TRUE) {
while (Process32Next(snapshot, &process_entry) == TRUE) {
// this is where things fail for UNICODE / ANSI
if (_stricmp(process_entry.szExeFile, process) == 0) { //process is the target process name declared in headers // changing strcmp to stricmp
//if (wcscmp(process_entry.szExeFile, pTmp) == 0) { //process is the target process name declared in headers // changing strcmp to stricmp
CloseHandle(snapshot);
dwProcessId = process_entry.th32ProcessID;
char buf1[10];
_itoa_s(dwProcessId, buf1, 10);
return process_entry.th32ProcessID;
}
}
}
CloseHandle(snapshot);
return 0;
}
Errors:

error C2079 uses undefined class - WinRT/UWP?

So here is my code:
// wrl-consume-component.cpp
// compile with: runtimeobject.lib
#include <Windows.Foundation.h>
#include <wrl\wrappers\corewrappers.h>
#include <wrl\client.h>
#include <stdio.h>
#include <windows.networking.vpn.h>
using namespace ABI::Windows::Foundation;
using namespace ABI::Windows::Networking::Vpn;
using namespace Microsoft::WRL;
using namespace Microsoft::WRL::Wrappers;
// Prints an error string for the provided source code line and HRESULT
// value and returns the HRESULT value as an int.
int PrintError(unsigned int line, HRESULT hr)
{
wprintf_s(L"ERROR: Line:%d HRESULT: 0x%X\n", line, hr);
return hr;
}
int wmain()
{
// Initialize the Windows Runtime.
RoInitializeWrapper initialize(RO_INIT_MULTITHREADED);
if (FAILED(initialize))
{
return PrintError(__LINE__, initialize);
}
// Get the activation factory for the IUriRuntimeClass interface.
ComPtr<VpnManagementAgent> uriFactory;
HRESULT hr = GetActivationFactory(HStringReference(RuntimeClass_Windows_Networking_Vpn_VpnManagementAgent).Get(), &uriFactory);
if (FAILED(hr))
{
return PrintError(__LINE__, hr);
}
// VpnManagementAgent vpn;
auto profiles = uriFactory->GetProfilesAsync().get();
wprintf(L"Found %d profiles\n", profiles.Size());
for (auto vp : profiles)
{
wprintf(L"Found profile %s\n", vp.ProfileName().c_str());
}}
/*
Output:
Domain name: microsoft.com
*/
It's basically copy paste from msdn and the answer to that question.
I'm compiling like this:
cl /diagnostics:column wrl-consume-component.cpp /link RuntimeObject.lib windows.networking.lib
Obviously I'm missing something huge here.
The error message is:
wrl-consume-component.cpp(40,27): error C2027: use of undefined type 'ABI::Windows::Networking::Vpn::VpnManagementAgent'

Unable to use WaitForCompletion() in #include <dshow.h>

I am using Qt patch in visual studio 2008. I am trying to run a video using #include <dshow.h>. I can run video successfully, but on using WaitForCompletion() my video gets hang. here is my code:-
MediaPlayer = new Media(ui.stackedWidget->currentWidget());
connect(ui.stackedWidget->currentWidget(), SIGNAL(videograph()), MediaPlayer,SLOT(HandleGraphEvent()));
MediaPlayer->pMediaControl->Run();
long evCode;
MediaPlayer->g_pEvent1->WaitForCompletion(INFINITE,&evCode);
My header file:-
Media.cpp
#include <dshow.h>
#include <commctrl.h>
#include <commdlg.h>
#include <stdio.h>
#include <tchar.h>
//#include <atlbase.h>
#include "Media.h"
#include <qtconcurrentrun.h>
Media::Media(QWidget *parent)
{
HRESULT hr;
CoInitialize(NULL);
hr = CoCreateInstance(CLSID_VideoMixingRenderer, NULL, CLSCTX_INPROC, IID_IBaseFilter, (void**)&pVmr);
hr = pVmr->QueryInterface(IID_IVMRFilterConfig, (void**)&pWc);
hr = pWc->SetNumberOfStreams(2);
hr = pVmr->QueryInterface(IID_IVMRMixerBitmap,(void **)&pBitMAp);
if(SUCCEEDED(hr))
{
hr = pWc->SetRenderingMode(VMRMode_Windowless);
hr = pWc->SetRenderingPrefs( RenderPrefs_ForceOffscreen| RenderPrefs_AllowOffscreen );
pWc->Release();
}
if(SUCCEEDED(hr))
{
hr = pVmr->QueryInterface(IID_IVMRWindowlessControl, (void**)&pWl);
if(SUCCEEDED(hr))
hr = pWl->SetVideoClippingWindow(parent->winId());
}
CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC, IID_IGraphBuilder, (void **)&pGraph);
pGraph->QueryInterface(IID_IMediaControl, (void **)&pMediaControl);
pGraph->QueryInterface(IID_IMediaEventEx, (void **)&g_pEvent);
pGraph->QueryInterface(IID_IBasicAudio,(void **)&pAudio);
pGraph->QueryInterface(IID_IMediaSeeking, (void **)&pMediaSeeking );
pGraph->QueryInterface( IID_IMediaPosition, (void **) &pMediaPosition);
hr = pGraph->AddFilter(pVmr, L"Video Mixing Renderer");
g_pEvent->SetNotifyWindow((OAHWND)parent->winId(), WM_GRAPHNOTIFY, 0);
RECT grc;
GetWindowRect(parent->winId(), &grc);
pGraph->RenderFile(L"/FlashDisk/test.mp4", NULL);
long lWidth, lHeight;
hr = pWl->GetNativeVideoSize(&lWidth, &lHeight, NULL, NULL);
if (SUCCEEDED(hr))
{
SetRect(&g_rcSRc, 0, 0, lWidth, lHeight);
GetWindowRect(parent->winId(), &g_rcDest);
SetRect(&g_rcDest, 0, 0, g_rcDest.right, g_rcDest.bottom);
}
video_rendered = 1;
pWl->SetVideoPosition(&g_rcSRc, &g_rcDest);
}
Media::~Media()
{
CleanUp();
}
void Media::HandleGraphEvent()
{
if (g_pEvent == NULL)
return;
long evCode;
LONG_PTR param1, param2;
while (SUCCEEDED(g_pEvent->GetEvent(&evCode, &param1, &param2, 0)))
{
g_pEvent->FreeEventParams(evCode, param1, param2);
switch (evCode)
{
case EC_STATE_CHANGE: //ADDED for state change from pause to play to indiacte video paused.
//SetEvent(sync_event);
return;
case EC_COMPLETE: // Fall through.
CleanUp();
return;
case EC_USERABORT: // Fall through.
case EC_ERRORABORT:
CleanUp();
//media.play_next_file();
return;
}
}
}
/*#######################################################################################
CleanUp
#######################################################################################*/
void Media::CleanUp(void)
{
video_rendered = 0;
g_pEvent->SetNotifyWindow(NULL, 0, 0);
g_pEvent->Release();
g_pEvent = NULL;
pMediaControl->Release();
pAudio->Release();
pGraph->Release();
}
Media.h
#ifndef MEDIA_H
#define MEDIA_H
//#define max(a,b) (((a) > (b)) ? (a) : (b))
//#define min(a,b) (((a) < (b)) ? (a) : (b))
#include <windef.h>
#include <QObject>
#include <QDebug>
#include <QFile>
#include <QMessageBox>
#include <QTimer>
#include <windows.h>
#include <math.h>
#include <stdlib.h>
#include <Phonon>
#include <dshow.h>
#include <commctrl.h>
#include <commdlg.h>
#include <stdio.h>
#include <tchar.h>
//#include <atlbase.h>
#include <qtconcurrentrun.h>
#pragma comment (lib, "strmiids.lib")
#define WM_GRAPHNOTIFY WM_APP + 1
#define WM_AUDIOGRAPHNOTIFY WM_APP + 2
class Media: public QObject
{
Q_OBJECT
public:
Media(QWidget *parent);
~Media();
IMediaControl *pMediaControl;
IMediaEventEx *g_pEvent;
IMediaEvent *g_pEvent1;
IVideoWindow *pVidWin;
IVMRMixerBitmap *pBitMAp;
IVMRMixerBitmap *pBitMAp1;
IMediaSeeking *pMediaSeeking;
IMediaPosition *pMediaPosition;
IVMRFilterConfig *pWc;
IBaseFilter *pVmr;
IVMRWindowlessControl *pWl;
RECT g_rcSRc;
RECT g_rcDest;
IBasicAudio *pAudio;
IVMRMixerControl *pVmc;
IGraphBuilder *pGraph;
DWORD width;
unsigned char video_rendered;
void CleanUp(void);
public slots:
void HandleGraphEvent(void);
};
#endif
Please suggest me what i am missing here.
On a COM STA thread you are responsible to dispatch window messages and WaitForCompletion is a blocking call without a promise to implement message loop.
See DShow Sample Code for playing video does not play the video
An easy way to find out if #2 is the problem is placing MessageBox call between Run and WaitForCompletion. MessageBox dispatches messages for you and as long as you keep the box open, video plays as well (or start playing well and keeps playing even after you close the box). Proper solution is to wait and displach messages in the same time (WaitDispatchingMessages, this SO question or similar).
This applies to your case as well, change to finite timeout, dispatch messages and get back to another wait attempt.

Playing sound using MinGW

I want to play sounds in my application using mciSendString. For this purpose I found the following simple snippet on the Microsoft website:
#include "stdafx.h"
#include <windows.h>
#include <mmsystem.h>
#pragma comment(lib, "Winmm.lib")
int _tmain(int argc, _TCHAR* argv[])
{
mciSendString("play MyFile wait", NULL, 0, 0);
mciSendString("close MyFile", NULL, 0, 0);
return 0;
}
My problem is that I don't use Visual Studio. Is there a way to get this example compiled via MinGW?
Once I remove the MSVS-isms
#include <windows.h>
int main()
{
mciSendString("play MyFile wait", NULL, 0, 0);
mciSendString("close MyFile", NULL, 0, 0);
return 0;
}
and compile with
g++ -o test.exe "src\\test.o" -lwinmm
as per the linked duplicate, the build is successful.

ADsOpenObject bind unsuccessful

I am trying to connect to an AD server from a computer that is outside the domain using ADSI however the bind is unsuccessful. Using Visual c++ 2010 express.
Here is the code snippet:
#include "stdafx.h"
#include <iostream>
#include <conio.h>
#include <wchar.h>
#include <objbase.h>
#include <activeds.h>
#include <AdsHlp.h>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
IADs *pObject;
HRESULT hr;
hr = ADsOpenObject(L"LDAP://aswathy-server3/cn=users,dc=aswathy,dc=local",
L"administrator",
L"password",
ADS_SECURE_AUTHENTICATION,
IID_IADs,
(void**)&pObject);
if(SUCCEEDED(hr))
{
cout<<"Success";
pObject->Release();
}
else
cout<<"Unsuccessful";
getch();
return 0;
}
I have included adsiid,lib and activeds.lib under project properties -> linker -> input -> additional dependencies.
Does anyone know why bind is not successful?
hr = ADsOpenObject(L"WinNT://aswathy.local/users",
L"administrator",
L"password",
ADS_SECURE_AUTHENTICATION,
IID_IADs,
(void**)&pObject);