Get resolution of DirectX device - c++

Where should I be looking for resolution of DirectX (3D) device? getViewport seems to have Width and Height, yet as far as I know viewport is supposed to be an area, not 2D "canvas" with these attributes.
(I hope "resolution" applies to the device, not D3D directly. Please correct me if this part is wrong.)
Simple MSDN link will be good answer as well, however I already browsed it through and couldn't find it.
Edit: it seems like getDisplayMode will work for fullscreen apps that changes resolution since it returns the display adapter mode, yet I'd like to be able to get the size of d3d window too.

DirectX doesn't actually own a window. If you remember when you initialise the device, you give it a handle to a window. It takes this and displays to its viewports within this window.
So if your looking specifically for the window size then you'll want to get it at the OS level.
This question discusses how to deal with it.
Namely GetWindowRect/GetClientRect(HWND, LPRECT)

If for some reason you only have the d3d interface, you can use getcreationparameters to get the original hwnd and then you can use GetWindowRect or GetClientRect as suggested before.
D3DDEVICE_CREATION_PARAMETERS cparams;
RECT rect;
device->GetCreationParameters(&cparams);
GetWindowRect(cparams.hFocusWindow, &rect);
//rect.width
//rect.height

Perhaps this is what you need: IDirect3D9::GetAdapterDisplayMode Method
http://msdn.microsoft.com/en-us/library/bb174316%28v=VS.85%29.aspx

If you want the window size then call "GetClientRect" on the hWnd you are setting up with.

Related

What is necessary to toggle fullscreen in DirectX 11?

I've just started learning DX so I know almost nothing about it although I do know OpenGL (to certain extent). I'm follow a tutorial (http://www.rastertek.com/tutdx11.html) and I have a working window rendering just a white background (clear).
Now - how do I actually switch from windowed mode to fullscreen and vice versa? I know there are many tutorials, some even provide a code for doing that but since I'm a newbie that's not really helpful. Why? Because every code sample is different and trying to find a pattern in all of them is apparently too difficult for me.
So I don't ask for code - instead I would like you to tell me what things I need to release/recreate/change to toggle correctly (and all of them). I know I need to change the display settings, I know I have to change something about the swap chain and release/recreate some buffers - but not really sure which exactly.
You can use SetFullScreenState on your swap chain:
swapChain->SetFullScreenState(true, NULL);
MSDN
The main thing you have to do is release all reference to the IDXGISwapChain, call ResizeBuffers, then re-create everything.
Since Win32 throws the WM_SIZE message upon window initialization, it's entirely possible to:
Clear the previous window-size-specific context
If the swap chain already exists, resize it, otherwise create one
Obtain the backbuffer for this window which will be the final 3D rendertarget.
Create a view interface on the rendertarget to use on bind.
Allocate a 2-D surface as the depth/stencil buffer and create a DepthStencil view on this surface to use on bind.
Create a viewport descriptor of the full window size.
Set the current viewport using the descriptor.
inside a static function (unless WinMain has an object from which to call), and call that function when the WM_SIZE message is triggered.
You can check out how the DirectXTK does it here:
https://directxtk.codeplex.com/

How do I determine if a window is off-screen?

In Windows XP and above, given a window handle (HWND), how can I tell if the window position and size leaves the window irretrievably off screen? For example, if the title bar is available to the cursor, then the window can be dragged back on screen. I need to discover if the window is in fact visible or at least available to the user. I guess I also need to know how to detect and respond to resolution changes and how to deal with multiple monitors. This seems like a fairly big deal. I'm using C++ and the regular SDK, so please limit your answers to that platform rather than invoking C# or similar.
Windows makes it relatively simple to determine the size of a user's working area on the primary monitor (i.e., the area of the screen not obscured by the taskbar). Call the SystemParametersInfo function and specify the SPI_GETWORKAREA flag for the first parameter (uiAction). The pvParam parameter should point to a RECT structure that will receive the coordinates of the working area in virtual screen coordinates.
Once you've got the coordinates that describe the working area, it's a simple matter of comparing those to the current position of your application's window to determine if it lies within those bounds.
The desire to support multiple monitors makes things slightly more complicated. The documentation for SystemParametersInfo suggests that you need to call the GetMonitorInfo function instead to get the working area of a monitor other than the primary. It fills in a structure called MONITORINFOEX that contains the member rcWork that defines the working area of that monitor, again expressed in virtual screen coordinates as a RECT structure.
To do this right, you'll need to enumerate all of the monitors a user has connected to the system and retrieve the working area of each using GetMonitorInfo.
There are a few samples of this to be found around the Internet:
MSDN has some sample code for Positioning Objects on a Multiple Display Setup.
If you're using MFC, here's what looks to be an excellent example of multiple monitor support.
Even if you're not using MFC, that article refers the following link which looks be a real gem as far as explaining how multiple monitor supports works in Windows, even if it's a little bit old school. Like it or not, very little of this has changed in later versions of Windows.
Finally, you mentioned wanting to detect resolution changes. This is much simpler than you probably imagined. As you know if you've done any Windows programming, the primary way that the operating system communicates with your application is by sending messages to your WindowProc function.
In this case, you'll want to watch for the WM_DISPLAYCHANGE message, which is sent to all windows when the display resolution has changed. The wParam contains the new image depth in bits per pixel; the low-order word of the lParam specifies the horizontal resolution and the high-order word of the lParam specifies the vertical resolution of the screen.
You can use MonitorFromRect or MonitorFromPoint to check if window's top left point or bottom right point isn't contained within any display monitor (off screen).
POINT p;
p.x = x;
p.y = y;
HMONITOR hMon = MonitorFromPoint(p, MONITOR_DEFAULTTONULL);
if (hMon == NULL) {
// point is off screen
}
Visibility check is really easy.
RECT rtDesktop, rtView;
GetWindowRect( GetDesktopWindow(), &rtDesktop );
GetWindowRect( m_hWnd, &rtView );
HRGN rgn = CreateRectRgn( rtDesktop.left, rtDesktop.top, rtDesktop.right, rtDesktop.bottom );
BOOL viewIsVisible = RectInRegion( rgn, &rtView );
DeleteObject(rgn);
You don't have to use RectInRegion, I used for shorten code.
Display, resolution change monitoring is also easy if you handle WM_SETTINGCHANGE message.
http://msdn.microsoft.com/en-us/library/ms725497(v=vs.85).aspx
UPDATE
As #Cody Gray noted, I think WM_DISPLAYCHANGE is more appropriate than WM_SETTINGCHANGE. But MFC 9.0 library make use of WM_SETTINGCHANGE.

Function to retrieve the size of an element

What I need is a function to retrieve the size of an element, be it a Java Applet window in a browser, text boxes in programs, applications window and so on.
Now I don't know what this kind of function is called, but I uploaded an example from an application that had that functionality.
Example (The red box)
What I need to be able to with this is get its size and its coordinates on the screen. This needs to be in C++.
So ff anyone could give an example, or atleast the name of that kind of function, I would be grateful.
I found a program that has the function I seek: It is called Scar Divi, which is a scriptable tool to perform repetitive actions, mostly uses for cheating in a game called Runescape it seems. Unfortunately it is closed source.
Are you looking for Window Geometry or desktop widget?
After getting an image of the screen (there will be somethign in Qt to do this)
You need an image processing library like openCV to find the rectangle - look for "Hough Transform"
I found the solution!
POINT p;
HWND wnd;
RECT rec;
GetCursorPos(&p);
wnd = WindowFromPoint(p);
GetWindowRect(wnd, &rec);
This will give you the coordinates for the box (extract from rec).

Best Method for Minimizable Fullscreen Window

I'm coding a short game in C++ and Win32, and I want to be able to make it in fullscreen with a fixed size. I also want the user to be able to switch focus between the game window and other windows as much as he/she wants without any weird screen glitches.
So far I know of the ChangeDisplaySettings function and creating the window with the WS_POPUP style at initialization to make it fullscreen. To detect the user switching focus to other windows by way of alt+tab or otherwise, what messages should I be handling on the window's WndProc or should I be using another function? When loss of focus is detected should I only call ChangeDisplaySettings(NULL, 0); or are there other functions I should call as well? And what method should I use to handle focus back into the window?
Also can anyone give me some info on how to make it work smoothly for different screen sizes?
Thanks for any help.
If you want an exclusive full screen window, use DirectX.
But I don't recommend it. Changing the display mode causes glitches, rearranges the users icons and so on. Whether done by you, or Direct X.
Rather create a normal window at your native res, and let the user maximize it if wanted.
You could also use the GDI+ library of Windows XP (and newer) to use hardware-accelerated stretching (draw in 640x480, let GDI+ resize it to the native resolution). Then you don't need exclusive mode of DirectDraw nor ChangeDisplaySettings.
Also drawing into a 640x480 big background buffer and bit blitting it on the drawing surface via StretchBlt can be a performant solution.

Windows not drawing above OpenGL windows

I have an application with an OpenGL window as a child window of the main window.
When I display a dialog box above the OpenGL window, it doesn't get drawn. It's like it's not getting WM_PAINT messages. If I can guess the title bar position of the dialog box, I can drag it and it's still responsive.
I realise this might be a vague question, but I was wondering if anyone else has seen this sort of behaviour before and knew of a solution?
I wondered if the Pixel Format Descriptor would make a difference - I had PFD_DRAW_TO_WINDOW, but changing to PDF_DRAW_TO_BITMAP didn't make any difference. I'm not sure what else I should be looking at?
Bugger. Should have given all the details. I was running Windows in a virtual machine on Mac OS X using Parallels. I upgrade from Parallels 3 to 4 and now everything is working fine. I suspect a Parallels video driver issue.
Thanks to all those who answered with suggestions.
Is your opengl window constantly rendering. It is possible that the 3D hardware is simply rendering into an overlay that is overdrawing your dialog box. If you position the dialog box so it overlaps your main window, can you see some of it?
Try to pause rendering into the main display to see if it effects the results.
You will also need to make sure that your window style ensures the results are clipped...
cs.style |= WS_CLIPSIBLINGS | WS_CLIPCHILDREN ;
You should check though all the items mentioned in this MSDN article, as it covers a lot of the basics for getting opengl rendering in a window correctly.
http://msdn.microsoft.com/en-us/library/ms970745.aspx
You may need to switch overlay off. It can be done via forcing back buffer presenting method to copy instead of swap.
Use wglChoosePixelFormatARB and one of parameters should be
WGL_SWAP_METHOD_ARB with value WGL_SWAP_COPY_ARB
This may seems stupid but are you sure your OpenGL window is not flagged "topmost" ?
Does the dialog box disappear also behind borders of your window or just behind the OpenGL rendering rectangle ?