Creating a D3D device without HWND input parameter to MSFT CreateDevice() function - c++

Kindly Pardon me if my doubt is silly or foolish. I am totally new to DirectX programming. Just have C++ knowledge (Very basic COM knowledge).
Below code sample is from MSDN Creating D3D device which explains how to create a D3D device from scratch.
MyDoubt is :
Here the function "pD3D->CreateDeviceEx()" takes in a parameter
HWND hwnd. What if I am trying to create a D3D device from a
commadline C++ win32 app where I need to use some of the functions in D3D device's interfaces. How do I get the HWND field. In this case
how do I create D3D device. PLease explain in detail.
HRESULT InitD3D9Ex( /* IN */ HWND hWnd, /* OUT */ IDirect3DDevice9Ex ** ppD3DDevice )
{
HRESULT hr = E_FAIL;
IDirect3D9Ex * pD3D = NULL;
IDirect3DDevice9Ex * pDevice = NULL;
if(ppD3DDevice == NULL)
{
return hr;
}
// Create the D3D object, which is needed to create the D3DDevice.
if(FAILED(hr = Direct3DCreate9Ex( D3D_SDK_VERSION, &pD3D )))
{
*ppD3DDevice = NULL;
return hr;
}
// Set up the structure used to create the D3DDevice.
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory( &d3dpp, sizeof(d3dpp) );
d3dpp.Windowed = TRUE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
// Create the Direct3D device.
if( FAILED( hr = pD3D->CreateDeviceEx( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&d3dpp, NULL, &pDevice ) ) )
{
*ppD3DDevice = NULL;
return hr;
}
// Device state would normally be set here
*ppD3DDevice = pDevice;
return hr;
}

In Windows all the visual things are controlled by window handles. You cannot create the D3D "device" and attach it to "nothing". You must associate the "D3D device" with some window (your own one or a desktop).
Your console window is created by the system and you do not control its creation flags, so even if you use the GetConsoleWindow function, you cannot use this HWND in Direct3D device creation functions (this might have changed with the introduction of Aero).
You cannot avoid creating getting yet another window handle in your console application. Use the RegisterWindowClass and CreateWindow functions to create a new window or find the handle to your desktop (I doubt you would want that).

Related

I am trying to send a window (application) from the main monitor (touch screen) to a secondary monitor using the same graphics card on the same host

I am trying to send a window (application) from the main monitor (touch screen) to a secondary monitor using the same graphics card on the same host
I spent a long time gathering data, trying to get a clear idea:
The MoveDown MOVEDEV_PARAMS
BOOL GetWindowRect(
HWND hWnd, // handle to window
LPRECT lpRect // window coordinates
);
AND...
And the following, but my brain can't put them together into something useful for me
BOOL EnumDisplayDevices(
LPCTSTR lpDevice, // device name
DWORD iDevNum, // display device
PDISPLAY_DEVICE lpDisplayDevice, // device information
DWORD dwFlags // reserved);
BOOL EnumDisplayMonitors(
HDC hdc, // handle to display DC
LPCRECT lprcClip, // clipping rectangle
MONITORENUMPROC lpfnEnum, // callback function
LPARAM dwData // data for callback function
);
BOOL EnumDisplaySettings(
LPCTSTR lpszDeviceName, // display device
DWORD iModeNum, // graphics mode
LPDEVMODE lpDevMode // graphics mode settings);
How to open a window on a specific display in Windows?
//VisualAPP Open
SHELLEXECUTEINFO sei;
ZeroMemory(&sei, sizeof(SHELLEXECUTEINFO));
sei.cbSize = sizeof(SHELLEXECUTEINFO);
sei.fMask = SEE_MASK_NOCLOSEPROCESS;
sei.lpVerb = _T("open");
sei.lpFile = _T("C:\\Users\\Administrator\\Desktop\\xxx.lnk");
sei.nShow = SW_SHOW;
if(ShellExecuteEx(&sei)) // Execute successfully
{
MoveApp(); // Moving program window
if (sei.hProcess)
WaitForSingleObject(sei.hProcess, INFINITE);
}
else
{
CString s;
s.Format(_T("ShellExecuteEx error,errer code:%d"), GetLastError());
// s = GetLastError();
MessageBox(s);
}
and the like...
There was a lot of enthusiastic user data that was very helpful to me, now how do I do development in VC6 is also important.
There is no problem in Visual stubio 2019, but not in Visual c++ 6.0 (maybe different support standards).
It made my feature development very difficult, and we were using VC6.
We cannot upgrade vc6 to vs19(VSCode) in a short time. Do you have a better way to solve the imminent problem.
This is probably the most important thing for ‘me to achieve immortality ’

DirectX9 CreateDevice() returns D3DERR_INVALIDCALL in injected DLL for VMT hooking

I want to modify a DirectX-Application's behavior (namely I want to implement a program similar to the Statman-Application by OrfeasZ [https://github.com/OrfeasZ/Statman/releases] as Onscreen-Info for Hitman 2) by injecting code (as DLL) into it and hooking the DirectX DeviceInterface VMT.
Since there are very limited resources on how to do this for DirectX11-Applications, I first wanted to learn how to do this in DX9 by creating a program that gets the DeviceInterface pointer of any DirectX9-Application. I wrote this code in the DllMain() function of my DLL (which is almost a 1:1 copy/paste of the third answer to this thread Hooking DirectX EndScene from an injected DLL):
HMODULE hDLL = GetModuleHandleA("d3d9");
LPDIRECT3D9(__stdcall*pDirect3DCreate9)(UINT) = (LPDIRECT3D9(__stdcall*)(UINT))GetProcAddress(hDLL, "Direct3DCreate9");
LPDIRECT3D9 pD3D = pDirect3DCreate9(D3D_SDK_VERSION);
D3DDISPLAYMODE d3ddm;
HRESULT hRes = pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm);
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory(&d3dpp, sizeof(d3dpp));
d3dpp.Windowed = true;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat = d3ddm.Format;
//WNDPROC TempWndProc;
WNDCLASSEX wc = { sizeof(WNDCLASSEX),CS_CLASSDC, WndProc,0L,0L,GetModuleHandle(NULL),NULL,NULL,NULL,NULL,TEXT("1"),NULL };
RegisterClassEx(&wc);
HWND hWnd = CreateWindow(TEXT("1"), NULL, WS_OVERLAPPEDWINDOW, 100, 100, 300, 300, GetDesktopWindow(), NULL, wc.hInstance, NULL);
ShowWindow(hWnd, SW_SHOW);
IDirect3DDevice9 * ppReturnedDeviceInterface;
hRes = pD3D->CreateDevice(
D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,
hWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&d3dpp, &ppReturnedDeviceInterface);
pD3D->Release();
DestroyWindow(hWnd);
if (pD3D == NULL) {
//printf ("WARNING: D3D FAILED");
return false;
}
unsigned long* pInterface = (unsigned long*)*((unsigned long*)ppReturnedDeviceInterface);
When I inject the DLL into a DirectX9-Application (I've tried this with Civilization V and Total War: Shogun 2), it opens a window, so it actually is able to get the Direct3DCreate9 function from the d3d9.dll within the game, but pD3D->CreateDevice() always returns `D3DERR_INVALIDCALL. I don't really get what could be the reason for this, especially since the rest of this program works flawlessly. Does anybody have any idea what is missing/wrong?
D3DERR_INVALIDCALL
The method call is invalid. For example, a method's parameter may not
be a valid pointer.
Based on the error information this issue may caused by invalid parameter of IDirect3D9::CreateDevice method. You need initialize the pointer:
IDirect3DDevice9 *pReturnedDeviceInterface = NULL;
Also check if hWnd is a valid window handle and d3ddm.Format etc.

DirectX 9 - Getting camera resolutions? (C++)

noob question:
Any examples of how to get parameters from the connected camera, such as supported resolutions?
I'm using DirectX June 2010.
Code to create a device:
HWND m_hwnd;
HDC *phdc;
IDirect3D9 *m_pD3D;
IDirect3DDevice9 *m_pDevice;
IDirect3DSwapChain9 *m_pSwapChain;
HRESULT DrawDevice::CreateDevice(HWND hwnd)
{
if (m_pDevice)
{
return S_OK;
}
// Create the Direct3D object.
if (m_pD3D == NULL)
{
m_pD3D = Direct3DCreate9(D3D_SDK_VERSION);
if (m_pD3D == NULL)
{
return E_FAIL;
}
}
HRESULT hr = S_OK;
D3DPRESENT_PARAMETERS pp = { 0 };
D3DDISPLAYMODE mode = { 0 };
hr = m_pD3D->GetAdapterDisplayMode(
D3DADAPTER_DEFAULT,
&mode
);
if (FAILED(hr)) { return hr; }
hr = m_pD3D->CheckDeviceType(
D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,
mode.Format,
D3DFMT_X8R8G8B8,
TRUE // windowed
);
if (FAILED(hr)) { return hr; }
pp.BackBufferFormat = D3DFMT_X8R8G8B8;
pp.SwapEffect = D3DSWAPEFFECT_COPY;
pp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
pp.Windowed = TRUE;
pp.hDeviceWindow = hwnd;
hr = m_pD3D->CreateDevice(
D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,
hwnd,
D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_FPU_PRESERVE,
&pp,
&m_pDevice
);
if (FAILED(hr)) { return hr; }
m_hwnd = hwnd;
m_d3dpp = pp;
return hr;
}
My purpose is to give the user a list of options to choose...
Thanks !!
Well if you need Monitor resolutions you should use DXUT microsoft Gui library or QT or custom you should make enumeration type and declare screen resolutions. I don't know what kind of resolutions you prefer.
P.S. I am not sure if you will succeded with DX SDK 2010 June and if you are using latest Windows and Visual Studio IDE. Simply that kind of DirectX SDK doesn't supported any more by Microsoft. You should use Windows SDK at least Windows 8.1 version. Hope this helps.
Direct3D is used to render to a monitor, not to capture images from a camera. Depending on what version of the OS you are using, you should take a look at Media Foundation or legacy DirectShow.
Direct3D 9 itself is also deprecated, as is the legacy DirectX SDK. See MSDN and this post. New projects should use DirectX 11 (or very experienced Direct3D graphics developers looking for high performance on Windows 10 / Xbox One should consider DirectX 12).
For a Win32 desktop application, you should look at this sample on GitHub.
For a Universal Windows Platform (UWP) app, you should look at this sample on GitHub.

Different D3D9 devices dont share the same VTable address

Lately I've been messing around with VTables and virtual pointers,
and I've found that every vptr from the same class type (should) point to the same VTable.(They point to the same address).
And I've searched for information about how COM objects work, and I've found that they also share the same VTable.(Objects of the same class ofc )
https://www.codeproject.com/articles/153096/intercepting-calls-to-com-interfaces]
First of all, when you set a method hook, it will work not only for the current instance of the COM object. It’ll work for all objects of the same class (but not for all the classes implementing the interface hooked).
The problem I have is as follows: I created in a test app 3 different d3d9 devices and I checked their pointer to the VTable but they are not the same!
if( NULL == ( g_pD3D = Direct3DCreate9( D3D_SDK_VERSION ) ) )
return E_FAIL;
if (NULL == (g_pD3D2 = Direct3DCreate9(D3D_SDK_VERSION)))
return E_FAIL;
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory( &d3dpp, sizeof( d3dpp ) );
d3dpp.Windowed = TRUE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
D3DPRESENT_PARAMETERS d3dpp2;
ZeroMemory(&d3dpp2, sizeof(d3dpp2));
d3dpp2.Windowed = TRUE;
d3dpp2.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp2.BackBufferFormat = D3DFMT_UNKNOWN;
if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&d3dpp, &g_pd3dDevice ) ) )
{
return E_FAIL;
}
if (FAILED(g_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&d3dpp2, &g_pd3dDevic)))
{
return E_FAIL;
}
WNDCLASSEX wc = { sizeof(WNDCLASSEX),CS_CLASSDC,TempWProc,0L,0L,GetModuleHandle(NULL),NULL,NULL,NULL,NULL,(LPCWSTR)("1"),NULL };
RegisterClassEx(&wc);
HWND hWndd = CreateWindow((L"1"), NULL, WS_OVERLAPPEDWINDOW, 100, 100, 300, 300, GetDesktopWindow(), NULL, wc.hInstance, NULL);
if (FAILED(g_pD3D2->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWndd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING | D3DCREATE_DISABLE_DRIVER_MANAGEMENT,
&d3dpp2, &g_pd3dDevic3)))
{
return E_FAIL;
}
(As a last resort I also created a different window and initialized a new D3D Interface just in case it would make the new d3d9 device point to the same VTable.)
In the debugger I checked the values of the device's pointers and this is what they yield:
g_pd3dDevice(The first one) : __vfptr = 0x00b75d1c { 0x6a976f19 }
g_pd3dDevic(The second one) : __vfptr = 0x0512a75c { 0x6a976f19 }
g_pd3dDevic3(The third one) : __vfptr = 0x0524393c { 0x6a976f19 }
The 3 VTables are the same, but they are in different places. (The three pointers point to the same function)
(And I also checked and the VTable is offseted by 0x2D9C from the object)
So this is what I dont really understand:
Do D3D9 devices always use the same VTable?
Why don't they use the same VTable as COM objects do as pointed by the link I've given?
Is it a problem related to having more than one device in the same HWND?
Is it some compiler optimization- related thingie?
Are they really VTables?
P.S: Sorry for my poor English, and my way of explaining things :C
Thanks a lot for reading this wall of text, seriously, thanks.
Thanks in advance!!!
(And sorry if it is a really dumby question)

Screenshot of game window

How can i take a screenshot of a full screen game in c++? I know it can be done with directx and i have written a simple code which can take a screenshot of a window but i don't know how to get a HWND of game.
Here is my code.
#include <d3dx9.h>
#include <d3dx9tex.h>
#include <stdio.h>
#pragma comment(lib,"d3d9.lib")
#pragma comment(lib,"d3dx9.lib")
int main()
{
IDirect3DSurface9 *surface;
IDirect3DDevice9 *g_pd3dDevice;
IDirect3D9 *g_pD3D;
D3DDISPLAYMODE d3ddm;
D3DPRESENT_PARAMETERS d3dpp;
HWND hWnd = GetConsoleWindow();
if((g_pD3D = Direct3DCreate9(D3D_SDK_VERSION)) == NULL)
{
printf("fail 1");
}
if(FAILED(g_pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm)))
{
printf("fail 2");
}
ZeroMemory(&d3dpp, sizeof(D3DPRESENT_PARAMETERS));
d3dpp.Windowed = TRUE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat = d3ddm.Format;
d3dpp.BackBufferHeight = d3ddm.Height;
d3dpp.BackBufferWidth = d3ddm.Width;
if(FAILED(g_pD3D->CreateDevice(D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL, hWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&d3dpp, &g_pd3dDevice)))
{
printf("fail 3");
}
g_pd3dDevice->CreateOffscreenPlainSurface(800, 600, D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &surface, NULL);
g_pd3dDevice->GetFrontBufferData(0, surface);
D3DXSaveSurfaceToFile("c:\\tmp\\output.jpg", D3DXIFF_JPG, surface, NULL, NULL);
surface->Release();
return 0;
}
I don't have any experience with Direct3D, but with OpenGL.
But both APIs provide almost the same functionality.
You should read back the back buffer (using Direct3D and not some Windows functionality) to host memory. Then simply save that bitmap to a file using an image library or something like that.
It's actually an extremely simple process.
These two links might be helpful to you:
http://www.mvps.org/directx/articles/screengrab.htm
How to save backbuffer to file in DirectX 10?