What context should I refer to so I am able to BitBlt on top of any application or window? Is there a "general" context which refer to display? - winapi

So I`m very new to win32ui, basically just starting. I was once using BitBlt wit python win32api module and as far as I remember to draw on top of display (so any application - if they are opened) I had to get specific context handle. But my memory is hazy on whether it simply was NULL or was it some specific context? Null doesn't seem to work, so I wonder how to obtain that general context? I really want to avoid to create fully transparent un blocking window.

The GetDC API allows you to get a device context for any given window. Alternatively,
If [hWnd] is NULL, GetDC retrieves the DC for the entire screen.
You can use the device context for the entire screen to read from, reliably (with restrictions). Rendering into a device context for a window you do not own won't be reliable, though. While it won't fail straight away, the window owner can overwrite your rendering at any point. There's no way for you to even be notified about this.
If you need to render on top of the screen you will have to create a top-most (transparent) window yourself, and use its device context. Make sure you ask the question: What if two programs did this?

Related

OpenGL on a secondary display

I have a Windows 7 system, a regular monitor as the primary display (serving as a desktop, etc.), and an additional screen attached to the same graphics card.
I want to write a program that takes control of the secondary display and uses it for fullscreen OpenGL rendering. I tried to enumerate displays with EnumDisplaySettings, pick the secondary display, create a device context associated with the display, set the pixel format on the DC, and create a WGL context associated with it. I can get this far without errors, but then the call to wglMakeCurrent fails for no apparent reason (return value is 0, GetLastError() is 0, and OpenGL does not function.)
The only way I could get it to work is to extend the desktop onto the secondary display (manually, from Windows display settings), create a window and move it onto the secondary display. Which is tolerable but undesirable (I don't want the secondary display to interfere with the desktop. For example, in this setup, I can move the mouse cursor from the desktop into the secondary display.) Is there a way to avoid this?
More generally, in order to get OpenGL to work on a display, do I need (1) to have the display attached to the desktop (or "a" desktop?), and/or (2) to have a window of my own on that display?
P.S. It seems that I might be able to get this to work with a third-party library such as glfw3, but I don't want extra baggage (I don't need 90% of functionality of glfw3) and I'd prefer to get this done directly through native API calls if possible.
Unfortunately the Windows graphics driver model does not allow to use displays independently. You will have to extend the desktop to the second display and create a fullscreen window on it. When it comes to constraining the mouse, the usual way is to hook into the system mouse events and whenever the mouse pointer is moved into the secondary screen remove it back to the primary screen.

How to capture a Direct3D/WPF/DWM window into a bitmap?

The normal way to capture an image of a window is to call:
HDC SharedWndDC = GetWindowDC(SharedWnd);
BitBlt(BitmapDC, 0, 0, width, height, SharedWndDC, 0, 0, SRCCOPY /* |CAPTUREBLT */);
ReleaseDC(SharedWnd, SharedWndDC);
Which on a system running DWM, nicely grabs just the window in question, even if it's being overlapped by other windows or partly off the screen, or whatnot.
But, it doesn't work right on some windows (presumably those that use WPF), and does funny things with the glass areas. Basically, the GDI capture doesn't work on non-GDI things.
I understand what I really want is to grab the Direct3D "back buffer" or "front buffer", but the numerous examples I've seen for that are for capturing the entire screen or desktop. Not knowing Direct3D, I can't find an example or simple statement of how to obtain the proper object for an existing window, which I could then grab the buffers from.
Can some kind soul at least show that missing piece?
—John
I don't believe there is a way to capture the front buffer contents without capturing the whole screen, and the back buffer is private to the application running Direct3D. The front buffer's content can only be seen when the graphics card actually presents the data to the monitor. With GDI, Windows has access to the front and back buffers, because it is managing them itself. But with Direct3D (and I'm presuming WPF), this is no longer the case. Windows does not have access to the buffers, and as such, can't obtain the data unless the application gives it to Windows, which is impossible (there's no message defined to do so).
EDIT:
This looks like a dead question, but I'll add this anyway in case someone else comes along looking for answers. The aforementioned issues still apply to getting the window contents programmatically. However, it is possible in Windows to get the contents of a single window by utilizing the shortcut ALT+Print Screen when the window you want to capture has the keyboard focus (a.k.a. it's the active window). This may or may not help you, but it does capture the contents of just the window in question, even with DirectX stuff.

Painting data from device context

I've just got a fresh device context (DC):
GetDC(someForeignHwnd)
Most normal people now want to paint on this. I don't. I want to display the context in my own program. Or duplicate, I wouldn't even mind the window I stole the context from beeing empty.
In my case, I want it in a TPanel in Delphi, but anything else helping me understanding goes.
Afterwards, I'll probably find the DC invalid by the time I get to display it.
My main problem is: Showing the content of another window in my own. But that isn't important. First of all, I want to know how these DC are of any use. Can I do something like the following?
Canvas.Draw(0, 0, MyNewDC);
The answer can be in Java, C, or Pascal. Is it just not possible or just a stupid idea?
While it's possible to use a device context that you retrieve via GetDC() as the SOURCE for BitBlt(), etc., you will likely not get the results that you're looking for. When you call GetDC() for a specific window, Windows essentially returns a device context for the screen, but with a clipping region set to exclude any portions of the screen where the window is not visible. For example, if there happens to be another window overlapping the source window, the portion of the source window that is covered is clipped from the device context. Therefore, you can only "retrieve" the bits that are actually visible.
You may have better luck sending a WM_PRINT or WM_PRINTCLIENT message to the window. However, not all windows respond to these messages, so this isn't a universal solution.

How to create an invisible X11 window for GPGPU?

Is it possible to create an invisible X window? For initialization of an OpenGL ES 2.0 context, one has to create a X window manually, but I can't find a way to make it invisible. Since I'm only doing GPGPU I don't need an output window. In fact, it is rather annoying in my case.
I'm aware of a solution from an earlier question, where it has been pointed out to use InputOnly in XCreateWindow(). This, however, leads to the X error GLXBadDrawable. Probably because EGL requires the window to respond to graphics request. Is there another way? Maybe create it minimized? But I can't find anything on that either. Also setting the window's size really small doesn't help, since it always occupies the whole screen on my device (Nokia N9).
When you create an X window, it is created unmapped, so what about creating an InputOutput window and leaving it unmapped? Another option would be (if the window must stay mapped), to move it out of the screen.

How do OpenGL contexts and device contexts work?

I'm new to U/I programming, and I'm trying to get started with OpenGL. When I run an example program which creates a new OpenGL window with GLUT, it works fine. Good. However, in the context of another program, where I have to respond to Draw events (on Windows), with a device context passed to me - and where I might not have GLUT available - my confusion is this:
When is a device context created and destroyed? Can I draw to any device context given to me, or only some of them (and how do I know)?
Do I have to create my own OpenGL context and use that to draw to, or can I use a "current" OpenGL context? Do I have to re-create the context every time a draw event is sent?
Basically my question is, given a situation where I am sent "Draw" events, how often do I attempt to create OpenGL contexts and how does this relate to the creation/destruction cycle of device contexts?
In general, it's usually safe to think of a single OpenGL context as a window, especially on windows.
A device context will (typically) map to an Window Handle (HWND). It's actually a DC (HDC is the handle), but normally you associate one HDC with a single HWND. In Windows, you'll create a window to use based off the window on screen where you want to render.
Typically, you'll reuse this device context for the entire runtime of your application. If you want to render into a different window, you'll need to generate a device context (HDC) for the new window handle. Also, offscreen rendering is a bit different, since you'd create a compatible device context for that, as well.
As for your questions:
1) When you create the window where you want to do the rendering, you'll grab a device context, and use it for the lifetime of that window.
2) You'll want to always use the device context created for the window where you are rendering.

Resources