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 - c++

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 ’

Related

Why can't i set a thumbnail on the Taskbar using DwmSetIconicThumbnail?

I need your help for a project at my job.
The main software, using 4D language, works as a MDI, it creates many windows included in the main window. The main issue is that we have a lot of windows and we need an easy way to switch from a window to another.
We decided to create a little c++ plugin which is a dll to resolve this issue.
This plugin will create a tab on the taskbar for each window opened like Windows Explorer. The creation and the deletion of tabs already works.
But the current problem is that no thumbnail is set on the Tab.
The parameter given is the ID of the window from the main software. The method called PA_GetHWND is the method given by 4D to obtain the handle of the window using the windowID.
I have already check where is the problem. The bitmap created from the window already exists and is good. For this test, i put the bitmap in the clipboard and paste it on Paint and the Bitmap was good.
Here is the code introducing the method to refresh the bitmap on the tab.
bool CManageTaskBar::UpdateWindow(long WindowID)
{
HRESULT res;
HDC hdcScreen;
HDC hdcWindow;
HDC hdcMemDC = NULL;
HBITMAP hbmScreen = NULL;
//Get the Handle from 4D
HWND nHandle = (HWND)(PA_GetHWND((PA_WindowRef)(WindowID)));
// Retrieve the handle to a display device context for the client
// area of the window.
hdcScreen = GetDC(NULL);
hdcWindow = GetDC(nHandle);
// Create a compatible DC which is used in a BitBlt from the window DC
hdcMemDC = CreateCompatibleDC(hdcWindow);
// Get the client area for size calculation
RECT rcClient;
GetClientRect(nHandle, &rcClient);
// Create a compatible bitmap from the Window DC
hbmScreen = CreateCompatibleBitmap(hdcWindow,rcClient.right - rcClient.left, rcClient.bottom - rcClient.top);
// Select the compatible bitmap into the compatible memory DC.
SelectObject(hdcMemDC, hbmScreen);
// Bit block transfer into our compatible memory DC.
if (!BitBlt(hdcMemDC,
0, 0,
rcClient.right - rcClient.left, rcClient.bottom - rcClient.top,
hdcWindow,
0, 0,
SRCCOPY))
{
MessageBox(nHandle, L"BitBlt has failed", L"Failed", MB_OK);
//goto done;
}
ITaskbarList3* ptbl = NULL;
HRESULT hr = CoCreateInstance(my_CLSID_TaskbarList, NULL, CLSCTX_ALL, my_IID_ITaskbarList3, (LPVOID*)&ptbl);
BOOL fForceIconic = TRUE;
BOOL fHasIconic = TRUE;
res = DwmSetWindowAttribute(nHandle, DWMWA_FORCE_ICONIC_REPRESENTATION, &fForceIconic, sizeof(fForceIconic));
res = DwmSetWindowAttribute(nHandle, DWMWA_HAS_ICONIC_BITMAP, &fHasIconic, sizeof(fHasIconic));
if (hbmScreen)
{
res = DwmSetIconicThumbnail(nHandle, hbmScreen,0);//DWM_SIT_DISPLAYFRAME);
}
DeleteObject(hbmScreen);
DeleteObject(hdcMemDC);
ReleaseDC(NULL, hdcScreen);
ReleaseDC(nHandle, hdcWindow);
return true;
}
The calls to DwmSetWindowAttribute return Invalid Handle. This handle works to get a bitmap but not to set an attribute.
And the call to DwmSetIconicThumbnail returns E_INVALIDARG maybe because the handle given is wrong.
Why cannot I set an attribute to this handle and why the call to set the thumbnail returns E_INVALIDARG ?
Thanks to everyone who will take care of my problem.
It's my first question, be friendly please :)

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.

Win32: capture handle to Display monitor

I am currently developing an application that requires an HDC for each of the screens connected to the system.
I am currently using code like this:
std::vector<HDC> dcs;
HDC dcMain = ::GetDC(nullptr); // <-- don't understand this
::EnumDisplayMonitors(dcMain, nullptr, MONITORENUMPROC(&DisplayMonitorCallback), LPARAM(&dcs));
My callback is as follows:
BOOL DisplayMonitorCallback(const HMONITOR monitor, const HDC hdcMonitor, const LPRECT lprcMonitor, std::vector<HDC>& dcs)
{
dcs.push_back(hdcMonitor);
// here is where it gets weird!
HBRUSH br = CreateSolidBrush(RGB(0, 255, 0));
auto rst = FillRect(hdcMonitor, lprcMonitor, br);
// Process all monitors
return TRUE;
}
Notice that I am currently rendering a green brush on each screen. This works perfectly in THIS context (i.e. within the callback).
Now, the problem is, I am capturing those HDCs to use at a later time.
So a couple of lines later, I'm iterating over my dcs vector:
for (HDC dc : dcs)
{
HBRUSH br = CreateSolidBrush(RGB(255, 255, 0));
RECT x = { 100, 100, 500, 500 };
auto rst = FillRect(dc, &x, br);
printf("%d", rst);
}
So, my questions are:
for the dcMain, I have to pass this in, is this the good way to get one?
why does the rendering work in the callback, but does not work when I capture the HDCs and iterate over them later?
yes, and this is mentioned in the EnumDisplayMonitors() documentation:
To paint the entire virtual screen optimally for each display monitor, you can use code like this:
hdc = GetDC(NULL);
EnumDisplayMonitors(hdc, NULL, MyPaintScreenEnumProc, 0);
ReleaseDC(NULL, hdc);
the HDCs are only valid inside of the callback, as #andlabs suggested. And this makes sense, because an HDC has to be obtained and then released, but only EnumDisplayMonitors() knows how each HDC is obtained, and so only it knows how to release each one correctly. Since there is no API function for releasing an enumerated HDC, this implies that the HDCs are not valid outside of the enumeration.
MSDN tells you how to obtain an HDC for a given monitor:
HMONITOR and the Device Context
Each physical display is represented by a monitor handle of type HMONITOR. A valid HMONITOR is guaranteed to be non-NULL. A physical display has the same HMONITOR as long as it is part of the desktop. When a WM_DISPLAYCHANGE message is sent, any monitor may be removed from the desktop and thus its HMONITOR becomes invalid or has its settings changed. Therefore, an application should check whether all HMONITORS are valid when this message is sent.
Any function that returns a display device context (DC) normally returns a DC for the primary monitor. To obtain the DC for another monitor, use the EnumDisplayMonitors function. Or, you can use the device name from the GetMonitorInfo function to create a DC with CreateDC. However, if the function, such as GetWindowDC or BeginPaint, gets a DC for a window that spans more than one display, the DC will also span the two displays.
For example:
typedef std::vector<HDC> hdc_vector;
BOOL CALLBACK DisplayMonitorCallback(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData)
{
MONITORINFOEX mi = {0};
mi.cbSize = sizeof(mi);
if (GetMonitorInfo(hMonitor, &mi))
{
HDC dc = CreateDC(NULL, mi.szDevice, NULL, NULL);
if (dc)
reinterpret_cast<hdc_vector*>(dwData)->push_back(dc);
}
...
return TRUE;
}
hdc_vector dcs;
EnumDisplayMonitors(dcMain, nullptr, DisplayMonitorCallback, reinterpret_cast<LPARAM>(&dcs));
...
for (HDC dc : dcs)
{
...
}
...
for (HDC dc : dcs)
DeleteDC(dc);
Since you are clearly using C++11, I would suggest using std::unique_ptr for the memory management of the HDCs so you don't have to call DeleteDC() manually. And I would use a lambda for the callback, and change the std::vector to a std::map (so you can lookup the HDC of any specific monitor when needed):
typedef std::unique_ptr<std::remove_pointer<HDC>::type, decltype(::DeleteDC)> device_hdc;
typedef std::map<HMONITOR, device_hdc> device_hdc_map;
device_hdc_map dcs;
EnumDisplayMonitors(dcMain, nullptr,
[](HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData) -> BOOL {
MONITORINFOEX mi = {0};
mi.cbSize = sizeof(mi);
if (GetMonitorInfo(hMonitor, &mi))
{
HDC dc = CreateDC(NULL, mi.szDevice, NULL, NULL);
if (dc)
(*reinterpret_cast<device_hdc_map*>(dwData))[hMonitor] = device_hdc(dc, &::DeleteDC);
}
...
return TRUE;
},
reinterpret_cast<LPARAM>(&dcs)
);
...
for (device_hdc_map::value_type &dc : dcs)
{
// use dc.second.get() (the actual HDC) as needed ...
}

C++ Win32 Not receiving DBT_DEVICEARRIVAL or DBT_DEVICEREMOVECOMPLETE on WM_DEVICECHANGE

I have been working on detecting USB insertion/removal. I have implemented code using CreateWindowEx(), passing a WNCLASSEX that with my window process callback. On inserting and removing my usb, I successfully receive the WM_DEVICECHANGE message, but the wParam is always set to DBT_DEVNODES_CHANGED.
I never get either DBT_DEVICEARRIVAL or DBT_DEVICEREMOVECOMPLETE. I have been using what I am getting, but I really need to be able to tell the difference between device arrival and removal, so that I can take different actions depending on which I receive.
Right now, I'm having to put a timer after receiving DBT_DEVNODES_CHANGED, and then test to see if there are any new removables on the system, or if any in my list are no longer there. I'm sure this isn't right, so I thought I'd ask. I would much rather to get rid of the timer and just receive these two messages. That would help a lot in what I have to do. Any suggestions?
Here is the code that I have for registering the callback, as well as the callback itself:
NOTE: 3/12/2015: Code updated to show actual GUID and the definition of the DoRegisterDeviceInterfaceToHwnd() function.):
GUID WceusbshGUID = { 0x25dbce51, 0x6c8f, 0x4a72, 0x8a,0x6d,0xb5,0x4c,0x2b,0x4f,0xc8,0x35 };
//GUID WusbrawGUID = {0xa5dcbf10, 0x6530, 0x11d2, 0x90, 0x1f, 0x00, 0xc0, 0x4f, 0xb9, 0x51, 0xed };
//GUID WusbGUID = {0x88BAE032, 0x5A81, 0x49f0, 0xBC, 0x3D, 0xA4, 0xFF, 0x13, 0x82, 0x16, 0xD6 };
INT_PTR WINAPI WinProcCallback(HWND __hWnd, UINT message, WPARAM wParam, LPARAM lParam);
BOOL DoRegisterDeviceInterfaceToHwnd(GUID InterfaceClassGuid, HWND __hWnd, HDEVNOTIFY *hDeviceNotify);
bool UsbController::startNotifyUsbAddedRemoved(QString &errmsg)
{
WNDCLASSEX wndClass;
wndClass.cbSize = sizeof(wndClass);
wndClass.style = 0;
wndClass.hInstance = reinterpret_cast<HINSTANCE>(GetModuleHandle(0));
wndClass.lpfnWndProc = reinterpret_cast<WNDPROC>(WinProcCallback);
wndClass.cbClsExtra = 0;
wndClass.cbWndExtra = 0;
wndClass.hIcon = LoadIcon(0, IDI_APPLICATION);
wndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wndClass.hCursor = LoadCursor(0, IDC_ARROW);
wndClass.lpszClassName = WND_CLASS_NAME;
wndClass.lpszMenuName = NULL;
wndClass.hIconSm = LoadIcon(0, IDI_APPLICATION);
if (!RegisterClassEx(&wndClass))
{
FormatErrorMsg("RegisterClassEx: ", errmsg);
return false;
}
HINSTANCE hInstance = (HINSTANCE)::GetModuleHandle(NULL);
__hWnd = CreateWindowEx(
WS_EX_CLIENTEDGE | WS_EX_APPWINDOW,
WND_CLASS_NAME,
WND_APP_NAME,
WS_OVERLAPPEDWINDOW, // style
CW_USEDEFAULT, 0,
0, 0,
NULL, NULL,
hInstance,
NULL);
if ( __hWnd == NULL )
{
FormatErrorMsg("CreateWindowEx: ", errmsg);
return false;
}
return true;
}
INT_PTR WINAPI WinProcCallback(HWND __hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
LRESULT lRet = 1;
static HDEVNOTIFY hDeviceNotify;
static HWND hEditWnd;
static ULONGLONG msgCount = 0;
switch (message)
{
case WM_CREATE:
//
// This is the actual registration., In this example, registration
// should happen only once, at application startup when the window
// is created.
//
// If you were using a service, you would put this in your main code
// path as part of your service initialization.
//
if ( ! DoRegisterDeviceInterfaceToHwnd( WceusbshGUID, __hWnd, &hDeviceNotify) )
{
// Terminate on failure.
//ErrorHandler(TEXT("DoRegisterDeviceInterfaceToHwnd"));
ExitProcess(1);
}
//
// Make the child window for output.
//
hEditWnd = CreateWindow(TEXT("EDIT"),// predefined class
NULL, // no window title
WS_CHILD | WS_VISIBLE | WS_VSCROLL |
ES_LEFT | ES_MULTILINE | ES_AUTOVSCROLL,
0, 0, 0, 0, // set size in WM_SIZE message
__hWnd, // parent window
(HMENU)1, // edit control ID
(HINSTANCE) GetWindowLong(__hWnd, GWL_HINSTANCE),
NULL); // pointer not needed
if ( hEditWnd == NULL )
{
// Terminate on failure.
ExitProcess(1);
}
// Add text to the window.
SendMessage(hEditWnd, WM_SETTEXT, 0,
(LPARAM)TEXT("Registered for USB device notification...\n"));
break;
case WM_SETFOCUS:
SetFocus(hEditWnd);
break;
case WM_SIZE:
// Make the edit control the size of the window's client area.
MoveWindow(hEditWnd,
0, 0, // starting x- and y-coordinates
LOWORD(lParam), // width of client area
HIWORD(lParam), // height of client area
TRUE); // repaint window
break;
case WM_DEVICECHANGE:
{
//
// This is the actual message from the interface via Windows messaging.
// This code includes some additional decoding for this particular device type
// and some common validation checks.
//
// Note that not all devices utilize these optional parameters in the same
// way. Refer to the extended information for your particular device type
// specified by your GUID.
//
// Output some messages to the window.
UsbController *pusbctl;
switch (wParam)
{
case DBT_DEVICEARRIVAL:
msgCount++;
pusbctl = UsbController::instance();
pusbctl->signalDeviceArrival();
break;
case DBT_DEVICEREMOVECOMPLETE:
msgCount++;
pusbctl = UsbController::instance();
pusbctl->signalDeviceRemoval();
break;
case DBT_DEVNODES_CHANGED:
msgCount++;
pusbctl = UsbController::instance();
pusbctl->signalDeviceAddedRemoved();
break;
default:
msgCount++;
break;
}
}
break;
default:
// Send all other messages on to the default windows handler.
lRet = DefWindowProc(__hWnd, message, wParam, lParam);
break;
}
return lRet;
}
BOOL DoRegisterDeviceInterfaceToHwnd(GUID InterfaceClassGuid, HWND __hWnd, HDEVNOTIFY *hDeviceNotify)
{
DEV_BROADCAST_DEVICEINTERFACE NotificationFilter;
ZeroMemory( &NotificationFilter, sizeof(NotificationFilter) );
NotificationFilter.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
NotificationFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
//NotificationFilter.dbcc_devicetype = DEVICE_NOTIFY_ALL_INTERFACE_CLASSES;
NotificationFilter.dbcc_classguid = InterfaceClassGuid;
*hDeviceNotify = RegisterDeviceNotification(
__hWnd, // events recipient
&NotificationFilter, // type of device
DEVICE_NOTIFY_WINDOW_HANDLE // type of recipient handle
);
if ( NULL == *hDeviceNotify )
{
return FALSE;
}
return TRUE;
}
If you read MSDN's documentation, it says:
Detecting Media Insertion or Removal
Windows sends all top-level windows a set of default WM_DEVICECHANGE messages when new devices or media (such as a CD or DVD) are added and become available, and when existing devices or media are removed. You do not need to register to receive these default messages. See the Remarks section in RegisterDeviceNotification for details on which messages are sent by default.
RegisterDeviceNotification function
Any application with a top-level window can receive basic notifications by processing the WM_DEVICECHANGE message. Applications can use the RegisterDeviceNotification function to register to receive device notifications.
...
The DBT_DEVICEARRIVAL and DBT_DEVICEREMOVECOMPLETE events are automatically broadcast to all top-level windows for port devices. Therefore, it is not necessary to call RegisterDeviceNotification for ports, and the function fails if the dbch_devicetype member is DBT_DEVTYP_PORT.
DEV_BROADCAST_HDR structure
DBT_DEVTYP_PORT
0x00000003
Port device (serial or parallel). This structure is a DEV_BROADCAST_PORT structure.
A USB device is not a serial/parallel port. It is a Device Interface (DBT_DEVTYP_DEVICEINTERFACE) instead. And DBT_DEVICEARRIVAL/DBT_DEVICEREMOVECOMPLETE are not sent for DBT_DEVTYP_DEVICEINTERFACE devices by default. If you want them, you have to use RegisterDeviceNotification() to request them.
It looks like your code is based on this MSDN example:
Registering for Device Notification
In that code, WceusbshGUID is defined as {25dbce51-6c8f-4a72-8a6d-b54c2b4fc835}, which is commented as being the class guid for USB serial host PnP drivers. According to this MSDN page:
System-Defined Device Setup Classes Available to Vendors
That guid is the class guid for Windows CE USB ActiveSync Devices (which is more consistent with the Wceusb... prefix used in the code). Also on that same page is {88BAE032-5A81-49f0-BC3D-A4FF138216D6} for USB Device (all USB devices that do not belong to another class).
The following CodeProject article:
Detecting Hardware Insertion and/or Removal
Mentions {a5dcbf10-6530-11d2-901f-00c04fb951ed} for USB Raw Device. That same guid is documented on MSDN as GUID_DEVINTERFACE_USB_DEVICE (the naming of which probably stems back to pre-XP days when the naming of class guids and interface guids was not well separated).
So when you call RegisterDeviceNotification() with a specific class guid, make sure it is the correct class guid, as you are going to get device events for only that specific type of device. It is likely that your USB device is using a different class guid than the one you are registering, and that is why you are not getting the device events you are expecting.
If you want to detect any USB device regardless of its class guid (and there are several USB class guids defined), you can use the DEVICE_NOTIFY_ALL_INTERFACE_CLASSES flag when calling RegisterDeviceNotification(), then the class guid will be ignored. In the DBT_DEVICEARRIVAL and DBT_DEVICEREMOVECOMPLETE messages (assuming you are able to get them now), the reported dbcc_classguid will tell you the actual class guid, and the reported dbcc_name will begin with the \\?\USB: prefix.
One last thing - you are only going to get DBT_DEVICE... messages if a USB device is inserted/removed while your app is already running. To detect if a USB device is already plugged in when your app starts, you have to use SetupAPI functions (SetupDiGetClassDevs(), SetupDiEnumDeviceInterfaces(), SetupDiGetDeviceInterfaceDetail(), etc) to enumerate the available devices.

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

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).