D2D1CreateFactory fails if D2D1_DEBUG_LEVEL_INFORMATION is set - c++

The following code runs fine:
HRESULT hr = S_OK;
D2D1_FACTORY_OPTIONS options;
ZeroMemory( &options, sizeof( D2D1_FACTORY_OPTIONS ) );
#ifdef _DEBUG
// options.debugLevel = D2D1_DEBUG_LEVEL_INFORMATION;
#endif
hr = D2D1CreateFactory(
D2D1_FACTORY_TYPE_SINGLE_THREADED,
__uuidof( ID2D1Factory2 ),
&options,
&m_sp2DFactory
);
if ( FAILED( hr ) )
return hr;
However, if I remove the //, thus enabling the D2D1_DEBUG_LEVEL_INFORMATION I get:
hr: E_NOINTERFACE No such interface supported.
My System is the latest Windows 10 TechPreview. I am using Visual Studio 2013. As far as I understand it, all DirectX Debugging libraries come with Visual Studio 2013. Is the D2D1_DEBUG_LEVEL_INFORMATION flag no longer supported? I couldn't find any info on that.

Related

Can't query IDirect3D7 from IDirectDraw7 in Win10

I'm trying the following code:
hr = ddr7->QueryInterface(IID_IDirect3D7,(void**)&d3d7)
the hr returned is E_NOINTERFACE, how does this happen?
On my Windows 10 system Version 1909 (18363) [x64], this worked fine:
#define INITGUID
#include <windows.h>
#include <stdio.h>
#include <ddraw.h>
#include <d3d.h>
typedef HRESULT ( WINAPI* LPDIRECTDRAWCREATEEX )( GUID FAR * lpGuid, LPVOID *lplpDD, REFIID iid,IUnknown FAR *pUnkOuter );
void main()
{
HINSTANCE hInstDDraw = nullptr;
LPDIRECTDRAW pDDraw = nullptr;
hInstDDraw = LoadLibraryW( L"ddraw.dll" );
if( hInstDDraw )
{
auto pDDCreate = reinterpret_cast<LPDIRECTDRAWCREATEEX>(GetProcAddress( hInstDDraw, "DirectDrawCreateEx" ) );
if (pDDCreate)
{
HRESULT hr = pDDCreate(nullptr, reinterpret_cast<LPVOID*>(&pDDraw), IID_IDirectDraw7, nullptr);
if (SUCCEEDED(hr))
{
LPDIRECT3D7 d3d7 = nullptr;
hr = pDDraw->QueryInterface(IID_IDirect3D7, reinterpret_cast<LPVOID*>(&d3d7));
if (SUCCEEDED(hr))
{
printf("Worked\n");
return;
}
else
{
printf("QI Failed: %08X\n", static_cast<int>(hr));
}
}
else
{
printf("DDCreate Failed: %08X\n", static_cast<int>(hr));
}
}
FreeLibrary( hInstDDraw );
}
printf("Failed\n");
}
You should make sure the HRESULT from your call to DirectDrawCreateEx worked. Also, it's possible it could be an issue with your drivers or setup.
Your original question really should include more code, particularly the DirectDrawCreateEx since the QueryInterface alone isn't particularly informative.
Happens to me too, works fine on 32bit application but fails on 64bit application. I'm on Windows 10 x64 version 10.0.18363.1082. As others already commented, D3D7 is already obsolete.

Implement Microsoft Speech Platform languages in SAPI 5

I created a little program in C++ where I use the SAPI library. In my code, I list the number of voices installed on my system. When I compile, I get 11, but there are only 8 installed and the only voice speaking is Microsoft Anna. I checked it in the registry (HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech\Voices).
I have several languages installed , especially languages from the Microsoft Speech Platform but none can be used.
Furthermore, when I change the voice ID, I get an unhandled exception error and I think it is because the chosen ID does not exist.
Here is my code
#include "stdafx.h"
int main( int argc, char* argv[] )
{
CComPtr<ISpObjectToken> cpVoiceToken;
CComPtr<IEnumSpObjectTokens> cpEnum;
ISpVoice * pVoice = NULL;
ULONG count = 0;
string str;
if( FAILED( ::CoInitialize( NULL ) ) )
return FALSE;
HRESULT hr = CoCreateInstance( CLSID_SpVoice, NULL, CLSCTX_ALL,
IID_ISpVoice, ( void ** )&pVoice );
if( SUCCEEDED( hr ) )
{
//Enumerate Voices
hr = SpEnumTokens( SPCAT_VOICES, NULL /*L"Gender=Female"*/, NULL, &cpEnum);
printf( "Success\n" );
}
else
{
printf( "Failed to initialize SAPI" );
}
if( SUCCEEDED( hr ) )
{
//Get number of voices
hr = cpEnum->GetCount( &count );
printf( "TTS voices found: %i\n", count );
}
else
{
printf( "Failed to enumerate voices" );
hr = S_OK;
}
if( SUCCEEDED( hr ) )
{
cpVoiceToken.Release();
cpEnum->Item( 3, &cpVoiceToken ); //3 represents the ID of the voice
pVoice->SetVoice( cpVoiceToken );
hr = pVoice->Speak( L"You have selected Microsoft Server Speech Text to Speech Voice (en-GB, Hazel) as the computer's default voice.", 0, NULL ); //speak sentence
pVoice->Release();
pVoice = NULL;
}
::CoUninitialize();
system( "PAUSE" );
}
The only voice working is Microsoft Anna, and I don't understand why. If the other languages were not available, the program won't show me that there are so many(11). I wonder if the Microsoft Speech Platform languages are compatible with SAPI.
After many tries and fails, I managed to find an answer to my problem.
I compiled my program in Win32. So I decided to change it to x64 and I recompiled the solution. I changed the voice ID in my program, and the voices from the Microsoft Speech Platform worked. This means that the MS Speech Platform languages are 64 bit voices and Microsoft Anna is a 32 bit voice.
The following post inspired me.

How to hide Desktop icons with Windows API in C++?

The answers I've found link to fHideIcon, but I get a 404 error on Microsoft's page for those links.
I've also tried:
SHELLSTATE ss;
SecureZeroMemory(&ss, sizeof(ss));
SHGetSetSettings(&ss, SSF_HIDEICONS, TRUE);
But that didn't work.
Does anyone know how to do this?
The following approach which uses the official shell API is a little bit involved, but works even under Windows 10.
Steps:
Get the IFolderView2 interface of the desktop (supported since Windows Vista).
Call IFolderView2::SetCurrentFolderFlags() with FWF_NOICONS for both the dwMask and dwFlags parameters.
The effect of the flag is visible immediately. There is no need to restart the computer nor "explorer.exe". The flag also persists after logoff or reboot.
The tricky thing is step 1). Raymond Chen shows C++ code for that in his article "Manipulating the positions of desktop icons", specifically in his FindDesktopFolderView() function.
Here is a full example in form of a console application. It is based on Raymond Chen's code. The program toggles the visibility of the desktop icons each time it is run.
The code has been tested under Windows 10 Version 1803.
"Library" code:
#include <ShlObj.h> // Shell API
#include <atlcomcli.h> // CComPtr & Co.
#include <string>
#include <iostream>
#include <system_error>
// Throw a std::system_error if the HRESULT indicates failure.
template< typename T >
void ThrowIfFailed( HRESULT hr, T&& msg )
{
if( FAILED( hr ) )
throw std::system_error{ hr, std::system_category(), std::forward<T>( msg ) };
}
// RAII wrapper to initialize/uninitialize COM
struct CComInit
{
CComInit() { ThrowIfFailed( ::CoInitialize( nullptr ), "CoInitialize failed" ); }
~CComInit() { ::CoUninitialize(); }
CComInit( CComInit const& ) = delete;
CComInit& operator=( CComInit const& ) = delete;
};
// Query an interface from the desktop shell view.
void FindDesktopFolderView( REFIID riid, void **ppv, std::string const& interfaceName )
{
CComPtr<IShellWindows> spShellWindows;
ThrowIfFailed(
spShellWindows.CoCreateInstance( CLSID_ShellWindows ),
"Failed to create IShellWindows instance" );
CComVariant vtLoc( CSIDL_DESKTOP );
CComVariant vtEmpty;
long lhwnd;
CComPtr<IDispatch> spdisp;
ThrowIfFailed(
spShellWindows->FindWindowSW(
&vtLoc, &vtEmpty, SWC_DESKTOP, &lhwnd, SWFO_NEEDDISPATCH, &spdisp ),
"Failed to find desktop window" );
CComQIPtr<IServiceProvider> spProv( spdisp );
if( ! spProv )
ThrowIfFailed( E_NOINTERFACE, "Failed to get IServiceProvider interface for desktop" );
CComPtr<IShellBrowser> spBrowser;
ThrowIfFailed(
spProv->QueryService( SID_STopLevelBrowser, IID_PPV_ARGS( &spBrowser ) ),
"Failed to get IShellBrowser for desktop" );
CComPtr<IShellView> spView;
ThrowIfFailed(
spBrowser->QueryActiveShellView( &spView ),
"Failed to query IShellView for desktop" );
ThrowIfFailed(
spView->QueryInterface( riid, ppv ),
"Could not query desktop IShellView for interface " + interfaceName );
}
Example to toggle desktop icons using the above code:
void ToggleDesktopIcons()
{
CComPtr<IFolderView2> spView;
FindDesktopFolderView( IID_PPV_ARGS(&spView), "IFolderView2" );
DWORD flags = 0;
ThrowIfFailed(
spView->GetCurrentFolderFlags( &flags ),
"GetCurrentFolderFlags failed" );
ThrowIfFailed(
spView->SetCurrentFolderFlags( FWF_NOICONS, flags ^ FWF_NOICONS ),
"SetCurrentFolderFlags failed" );
}
int wmain(int argc, wchar_t **argv)
{
try
{
CComInit init;
ToggleDesktopIcons();
std::cout << "Desktop icons have been toggled.\n";
}
catch( std::system_error const& e )
{
std::cout << "ERROR: " << e.what() << ", error code: " << e.code() << "\n";
return 1;
}
return 0;
}
The third parameter isn't about changing the setting, it's to select the SHGetSetSettings() behavior.
FALSE will get the value of the current setting and store it in ss, TRUE will set the value of the setting to what is in ss.
So basically you have to do ss.fHideIcons = TRUE and then call SHGetSetSettings(&ss, SSF_HIDEICONS, TRUE) to set it.
I know, it's weird, but on the other hand it allows you to change multiple settings simultaneously because SSF_* is a bitmask.
The following seems to work (adapted from https://stackoverflow.com/a/6403014/5743288):
#include <windows.h>
int main ()
{
HWND hProgman = FindWindowW (L"Progman", L"Program Manager");
HWND hChild = GetWindow (hProgman, GW_CHILD);
ShowWindow (hChild, SW_HIDE);
Sleep (2000);
ShowWindow (hChild, SW_SHOW);
}
Please note: this approach is not supported by Microsoft and disables right-clicking on ths desktop.

CoCreateInstance of IWICImagingFactory

I am running Visual Studio 2012 on my Windows 7 machine.
When I run the SimpleDirect2dApplication found here : http://technet.microsoft.com/en-us/subscriptions/dd940321%28v=vs.85%29.aspx
hr = CoCreateInstance(
CLSID_WICImagingFactory,
NULL,
CLSCTX_INPROC_SERVER,
IID_PPV_ARGS(&m_pWICFactory)
);
the CoCreateInstance fails with a "Class Not Registered" and the ptr to the factory is 0.
Any help would be appreciated.
According to an answer in a Microsoft's forum a breaking change in the Windows SDK 8.0 requires you to define _WIN32_WINNT to 0x0600 for backward compatibility with Windows Vista or to 0x0601 for backward compatibily with Windows 7.
Here's the code I use to handle WIC creation for both WIC and WIC2 scenarios:
namespace
{
bool g_WIC2 = false;
BOOL WINAPI InitializeWICFactory(PINIT_ONCE, PVOID, PVOID *ifactory) noexcept
{
#if (_WIN32_WINNT >= _WIN32_WINNT_WIN8) || defined(_WIN7_PLATFORM_UPDATE)
HRESULT hr = CoCreateInstance(
CLSID_WICImagingFactory2,
nullptr,
CLSCTX_INPROC_SERVER,
__uuidof(IWICImagingFactory2),
ifactory
);
if (SUCCEEDED(hr))
{
// WIC2 is available on Windows 10, Windows 8.x, and Windows 7 SP1 with KB 2670838 installed
g_WIC2 = true;
return TRUE;
}
else
{
hr = CoCreateInstance(
CLSID_WICImagingFactory1,
nullptr,
CLSCTX_INPROC_SERVER,
__uuidof(IWICImagingFactory),
ifactory
);
return SUCCEEDED(hr) ? TRUE : FALSE;
}
#else
return SUCCEEDED(CoCreateInstance(
CLSID_WICImagingFactory,
nullptr,
CLSCTX_INPROC_SERVER,
__uuidof(IWICImagingFactory),
ifactory)) ? TRUE : FALSE;
#endif
}
}
bool IsWIC2() noexcept
{
return g_WIC2;
}
IWICImagingFactory* GetWIC() noexcept
{
static INIT_ONCE s_initOnce = INIT_ONCE_STATIC_INIT;
IWICImagingFactory* factory = nullptr;
if (!InitOnceExecuteOnce(
&s_initOnce,
InitializeWICFactory,
nullptr,
reinterpret_cast<LPVOID*>(&factory)))
{
return nullptr;
}
return factory;
}
This handles creating the factory once from any thread. You use it by just calling:
auto pWIC = GetWIC();
if (!pWIC)
// error
For those few cases where you care about WIC vs. WIC2, you use IsWIC2:
if (targetFormat && memcmp(&guidContainerFormat, &GUID_ContainerFormatBmp, sizeof(WICPixelFormatGUID)) == 0 && IsWIC2())
{
// Opt-in to the WIC2 support for writing 32-bit Windows BMP files with an alpha channel
PROPBAG2 option = {};
option.pstrName = const_cast<wchar_t*>(L"EnableV5Header32bppBGRA");
VARIANT varValue;
varValue.vt = VT_BOOL;
varValue.boolVal = VARIANT_TRUE;
(void)props->Write(1, &option, &varValue);
}
I had use a C++11 lambda for this code in the past, but clang/LLVM doesn't like it so much.
using this
#if defined(CLSID_WICImagingFactory)
#undef CLSID_WICImagingFactory
#endif
and then you may pass this
Refer:
http://skia.googlecode.com/svn/trunk/src/ports/SkImageDecoder_WIC.cpp

GmfBridge doesn't connect sink filter with source filter

I am trying to use GmfBridge library to dynamically change source filters from cam to file and vice versa. All functions return S_OK (well, almost all - pMediaControlOutput->Run() returns S_FALSE actually, but in msdn said that this can be ok too), so I've assumed that all is ok but data isn't transfered to the other side of the bridge. I use GraphStudio to connect to remote graph and all seems to be ok - all filters in both graph are connected as it should be. But while playing I receive following messages in bridge log file:
0: Started 2011-09-10 15:58:38
0: Buffer minimum 100
0: Added stream 1: 畡楤o, Decompressed Only, Discard mode
1: Sink 0x7ae0ca8 has 1 pins
1: Sink filter 0x7ae0cf8 in graph 0x193bf0
2: Source 0x7ae1030 has 1 pins
2: Source filter 0x7ae1080 in graph 0x194c18
14: ReceiveConnection Aware: false
14: Bridging 0x194c18 to 0x193bf0
14: Pin 0x7ae3438 disconnect
25: Source 0x7ae1030 pause from 0
25: Source pin 0x7ae3618 active
2234: Pin 0x7ae3438 receive 0x721ec68
2234: Sink pin 0x7ae3438 disconnected: discarding 0x721ec68
3389: Pin 0x7ae3438 receive 0x721ec68
3389: Sink pin 0x7ae3438 disconnected: discarding 0x721ec68
3940: Pin 0x7ae3438 receive 0x721ec68
3940: Sink pin 0x7ae3438 disconnected: discarding 0x721ec68
4440: Pin 0x7ae3438 receive 0x721ec68
So as you can see, left graph isn't connected to right one despite BridgeGraphs() returned S_OK and media sample is discarded. Below there is my code. Where am I going wrong?
// Create graphs
HRESULT hr = m_graphInput.CreateInstance(CLSID_FilterGraph);
ATLASSERT( SUCCEEDED( hr ) );
hr = m_graphOutput.CreateInstance(CLSID_FilterGraph);
ATLASSERT( SUCCEEDED( hr ) );
// Get IMediaControl interfaces
hr = m_graphInput.QueryInterface( IID_IMediaControl, (void**)&pMediaControlInput );
ATLASSERT( SUCCEEDED( hr ) );
hr = m_graphOutput.QueryInterface( IID_IMediaControl, (void**)&pMediaControlOutput );
ATLASSERT( SUCCEEDED( hr ) );
// Get builder interfaces
hr = m_graphInput.QueryInterface( IID_IGraphBuilder, (void**)&pBuilderInput );
ATLASSERT( SUCCEEDED( hr ) );
hr = m_graphOutput.QueryInterface( IID_IGraphBuilder, (void**)&pBuilderOutput );
ATLASSERT( SUCCEEDED( hr ) );
// Load source filter (on sink side)
LocateFilter( SOURCE_FILTER_NAME, CLSID_LegacyAmFilterCategory, &inputDevice );
hr = m_graphInput->AddFilter( inputDevice, SOURCE_FILTER_NAME );
ATLASSERT( SUCCEEDED( hr ) );
// Load render filter (on bridge's source side)
LocateFilter( _T( "Default DirectSound Device" ), CLSID_AudioRendererCategory, &audioOutputPreview );
hr = m_graphOutput->AddFilter( audioOutputPreview, _T( "Default DirectSound Device" ) );
ATLASSERT( SUCCEEDED( hr ) );
// Init bridge
bridge.CreateInstance( __uuidof(GMFBridgeController) );
hr = bridge->SetBufferMinimum( 100 );
ATLASSERT( SUCCEEDED( hr ) );
hr = bridge->AddStream( false, eUncompressed, false );
ATLASSERT( SUCCEEDED( hr ) );
// Add sink filter and connect to input graph
IUnknownPtr pSinkFilter;
{
hr = bridge->InsertSinkFilter( m_graphInput, (IUnknown**)&pSinkFilter );
ATLASSERT( SUCCEEDED( hr ) );
// Using own functions get pins
IPin* pInAudio = CPinController::getOutputPin( inputDevice, _T("Audio"));
IPin* pOutAudio = CPinController::getInputPin( pSinkFilter );
hr = pBuilderInput->Connect( pOutAudio, pInAudio );
ATLASSERT( SUCCEEDED( hr ) );
}
// Add output filter and connect to output graph
IUnknownPtr pFeederFilter;
{
hr = bridge->InsertSourceFilter( pSinkFilter, m_graphOutput, &pFeederFilter );
ATLASSERT( SUCCEEDED( hr ) );
// Get pins
IPin* pInAudio = CPinController::getOutputPin( pFeederFilter/*, _T("Audio")*/);
IPin* pOutAudio = CPinController::getInputPin( audioOutputPreview );
hr = pBuilderOutput->Connect( pInAudio, pOutAudio );
ATLASSERT( SUCCEEDED( hr ) );
}
// Run left
hr = pMediaControlInput->Run();
ATLASSERT( SUCCEEDED( hr ) );
// Run right
hr = pMediaControlOutput->Run();
ATLASSERT( SUCCEEDED( hr ) );
hr = bridge->BridgeGraphs( m_graphOutput, m_graphInput );
ATLASSERT( SUCCEEDED( hr ) );
It's really ridiculous but about a few minutes ago after a day of searching we have found the answer. All deal was about really huge hole in GmfBridge. I was giving wrong interfaces here (there are graphs instead of bridge's sink and source filters) 'coz function needed pointers to IUnknown:
hr = bridge->BridgeGraphs( m_graphOutput, m_graphInput );
And in GmfBridge library this situation wasn't handled properly - there is no "else" brunch to handle error and function returns hr which was set in begin to S_OK:
HRESULT STDMETHODCALLTYPE BridgeGraphs(
/* [in] */ IUnknown *pSourceGraphSinkFilter,
/* [in] */ IUnknown *pRenderGraphSourceFilter)
{
HRESULT hr = S_OK;
...
// if we are not given both filters, then
// we need do nothing
IBridgeSinkPtr pSink = pSourceGraphSinkFilter;
IBridgeSourcePtr pSource = pRenderGraphSourceFilter;
if ((pSink != NULL) && (pSource != NULL))
{
...
}
return hr;
}
So as you can see it just says there is nothing wrong and then it just do nothing! I think it's good idea to notify authors of the lib about this bug.
Hope this info will help someone.