Get currentDevice Context in DX9.0c - directx-9

I have a framework (so I don't inject anything to a running process) that uses DX9.0c and WinApi to create a Window and initialize DirectX. However, I do not have either device context nor HWND. Is there any way to obtain device context in this situation? Or should I try to create dummy HWND and create a new device context?

Use NULL as a parameter for CreateCompatibleDC to get an device context which is compatible to your screen.
HDC hdcDC = ::CreateCompatibleDC( NULL );
See https://msdn.microsoft.com/en-us/library/windows/desktop/dd183489(v=vs.85).aspx for more details.

Related

Is CreateCompatibleDC() necessary working with windows on one display?

This example code manually reads a bitmap file, uses CreateDIBSection() to make GDI allocate memory for it, and create an hbitmap handle. Then it uses a MemoryDC to draw the bitmap to a window DC:
ftp://ftp.oreilly.com/examples/9781572319950/cd_contents/Chap15/DibSect/DibSect.c
hdc = BeginPaint (hwnd, &ps) ;
...
hdcMem = CreateCompatibleDC (hdc) ;
Why can't we use GetDC() with NULL or with hwndDesktop instead? Why can't we cache the device context instead of repeatedly creating it?
If the machine has only one display device and we are only drawing to windows why do we need to constantly harmonize bitmaps and device contexts? Once the pixeldata is copied to the buffer provided by GDI, does GDI update it when that HBITMAP is loaded into a DC and drawn on? If the user also wishes to draw on it is it necessary to synchronize access? (By calling GDIFlush() first?)
It's hard to figure this out when most all of the object properties are opaque and abstracted. I've read almost all of the related MSDN, a lot of Petzold's book, and some articles:
Display Device Contexts
CreateCompatibleDC()
CreateDIBSection()
Memory Device Contexts
Guide to Win32 Memory DC
Guide to WIN32 Paint for Intermediates
Programming Windows®, Fifth Edition
Edit:
I think my question boils down to this:
Is a device context a TYPE of display or is it an INSTANCE of graphical data that is able to be displayed. A computer typically has only a handful of displays but it could have hundreds of things to display on them.
GetDC(NULL) is the screen HDC and the screen is a shared resource, therefore you should only do read/query operations on this HDC. Writing to this HDC is not a good idea on Vista and higher because of the DWM.
Since a HDC can only contain one bitmap, one brush and one pen, Windows/applications obviously need more than one HDC provided by the graphics engine.
You can count on CreateCompatibleDC to be relatively cheap operation and I believe Windows has a cache of DCs it can hand out. If you are creating a game/animation type application you might want to cache some of these graphic objects on your own but a normal application should not.
You don't generally call GDIFlush unless you are sharing GDI objects across several threads. You can use SetDIBits if you want to mix raw pixel bytes access and GDI.
I don't really get the once screen argument, Windows has supported multiple monitors since Windows 98 and there is not much you can do to prevent the user from connecting another monitor.
I think your problem is that you are getting hung up on Microsoft's names for things, Microsoft's name "device context" and the names for calls like "CreateCompatibleDC".
"Device Context" is a bad name. The Win32 documentation will tell you that a device context is a data structure for storing the state of a particular device used for rendering graphics commands. This is only partially true. Look at the different kinds of DCs that exist: (1) screen device contexts, (2) printer device contexts, (3) the device context used by a bitmap in memory, and (4) metafile device contexts. Of these only (1) or (2) are actually doing exactly what the documentation claims they are doing. In the other cases device contexts serve as a target for drawing calls but not as containers for the state of some physical device. (This is really noticeably true in the case of metafile DC's: metafiles were an old Win32 thing that basically just cache the GDI calls going in to them to be replayed later, kind of a crude vector format.)
In a hypothetical object oriented programming version of Win32, device contexts could be instances of some class that implements an interface that exposes graphics drawing calls. A better name for such a class would be something like "Graphics" and indeed in GDI+ this is what the analogous construct is actually called. When we "Create" -- via CreateDC, CreateCompatibleDC, etc. -- we create one of these objects. When we GetDC we grab such an object that already exists.
To answer your questions:
Is a device context a TYPE of display or is it an INSTANCE of graphical data that is able to be displayed. ?
They are in so sense types of displays. You can think of them as instances of a class of objects with private implementations that expose a public interface exposing drawing commands.
Why can't we use GetDC() with NULL or with hwndDesktop instead?
You can't use GetDC(NULL) as the device context into which you are going to select an in memory bitmap because in such a situation you need to create a device context that does not already exist; GetDC(NULL) is like a singleton instance that is already in use.
So instead you usually CreateCompatibleDC(NULL) or CreateCompatibleDC(hdcScreen). Again CreateCompatibleDC(...) is a confusing name. Imagine the hypothetical object-oriented version of what is going on here. Say there is an IGraphics interface that is implemented by RasterGraphics, PrinterGraphics, and MetafileGraphics. Imagine the "RasterGraphics" class is used for both the screen and for in memory bitmaps. Then CreateCompatibleDC(...) would be would be like a factory call Graphics.CreateFrom(IGraphics g) that return a new instance of the same concrete type with perhaps some state variables initialized.
Why can't we cache the device context instead of repeatedly creating it?
You can. You do not need to delete device contexts across function calls. The only reason people often do is that they are a shared, finite resource and creating them is cheap. I think actually that they used to be very limited under old versions of Windows so old Win32 programmers tend to not cache them out of muscle memory from the old days, from Windows 95 days.
If the machine has only one display device and we are only drawing to windows why do we need to constantly harmonize bitmaps and device contexts?
Don't think of the "compatible" in CreateCompatibleDC(...) to be about "harmonizing with the screen" think of it as meaning "Okay Windows I want to create one of your graphics interface objects and I want the kind like this one, which is a normal raster graphics one and not for printers or for metafiles."

Application does not appear in taskbar when launched & stays behind main Application

I am launching a WPF application from a MFC Application. Sometimes it happens that when I Launch the WPF Applciation, the applciation does get launched but it does not appear in the taskbar. And stays behind the main application. So I keep waiting that the application has not yet launched. When I minimize the main Application, I see it was already launched. Can anyone please identify whats going on?
Thanks
You are using ShellExecute incorrectly. Please have a look here. The last parameter, nShowCmd, is:
The flags that specify how an application is to be displayed when it is opened. If lpFile specifies a document file, the flag is simply passed to the associated application. It is up to the application to decide how to handle it. These values are defined in Winuser.h.
Therefore, you need to specify the desired ShowWindow flag. I recommend using either SW_SHOWNORMAL or SW_MAXIMIZE:
int nResult = (int)::ShellExecute(NULL, _T("open"), sExePath, NULL, NULL, SW_SHOWNORMAL);
or
int nResult = (int)::ShellExecute(NULL, _T("open"), sExePath, NULL, NULL, SW_MAXIMIZE);
It is also a good idea to check the return code of the function. If it succeeds the value in nReturn should be greater than 32.

Passing user data to Callback function using glade

I am using glade to make my .ui files and then using GtkBuilder I am loading that whole .ui file in my C program, so all the widgets and stuff are created from the builder files itself.
Earlier I had been creating widgets only from the code itself, hence allowing me to pass any type of data to the Callback since the second argument is a gpointer variable and I could anytime create a pointer to a custom made structure and pass any type of data to the callbacks.
But now to connect to the signals I am just using this simple function :
gtk_builder_connect_signals(builder, NULL);
where builder is a pointer to GtkBuilder.
This connects all the signals mentioned in glade file with those of function defined in the .c files without having any provision of passing user_data other than that of Widgets (which themselves can only be defined in glade.)
Can anybody tell me a solution so that I can pass any type of data to my callbacks. I don't want to leave glade since it saves lot of my time, hence I would not like to switch over to traditional way of creating widgets by code only.
An example using both g_connect_signal() and gtk_builder_connect_signals() would be helpful. In this case which one to call first to override signal connection.
You can call gtk_builder_get_object to retrieve any widget created by Glade given the widget's name. Then you can connect the widget to the signals with the usual g_connect_signal API. The drawback is that you can no longer simply "mention" signals in the glade definition.
The other way is to also use gtk_builder_get_object to get the object, but to call g_object_set_qdata to associate the necessary user data with a GQuark key known to you. Your callback can then pick up the user data from the widget using g_object_get_qdata with the same key. This has the advantage that you would still be using gtk_builder_connect_signals.
That NULL pointer you are passing in is for the user data pointer.
gtk_builder_connect_signals(builder, NULL);
^
here----------------------------------|
If you always have the same user data object then your problem is solved. If not you
will need some kind of data structure for the different user data pointers so that
each callback can find the correct one.

WindowInteropHelper.Handle — do I need to release it?

In WPF I'm getting IntPtr handle using this code:
IntPtr mainWindowHandle = new WindowInteropHelper(Application.Current.MainWindow).Handle
When I finish using this handle, do I need to release it in anyway (e.g. using Marshal.FreeHGlobal() method) ?
EDIT: I was thinking about Marshal.FreeHGlobal(), not Marshal.Release(), sorry!
This is not in any way related to COM, Marshal.Release() does not apply. You simply get a copy of the native window handle, it does not have to be released. You need to stop using the handle when the window is destroyed. Signaled by the Window.Close event.

Launching IE from winforms, can I close IE when my winforms closes?

I have a winforms application, that why someone clicks on a button I need to open up IE to a specific URL.
When someone closes the winforms app, I then need to close IE.
Is this possible? If yes, how?
If you dont have the reference to the old process you used for launching IE, you have to search through the process array returned by System.Diagnostics.Process.GetProcessesByName("IEXPLORE") and kill the specific process.
some samples here.
It would be possible to do that, but it might be a better idea to simply embed Internet Explorer into your application using the WebBrowser control. That way when you close the website you have no chance of closing the whole window when your website opened in a new tab in an existing IE window.
Edit: If you're going to do it anyway, look at the MSDN page on System.Diagnostics.Process.Close
Yes it is possible,
When you call System.Diagnostics.Process.Start() to start the browser, use a specifically created process object. You can later use the process information to kill the process.
However, as Dan Walker mentioned, it might be a better idea to just use the Web Browser control, unless you have specific navigation needs, then it might be more effective to just start and kill IE.
Not sure how you are launching IE, but if you keep a reference to the launched process (or the window handle that was created), you can kill the process (or close the window) when you app exits.
EDIT:
Code to close a window handle is like
Utilities.Utilities.SendMessage(mTestPanelHandle, WM_COMMAND, WM_CLOSE, 0);
if you have a P/Invoke
public const int WM_COMMAND = 0x0112;
public const int WM_CLOSE = 0xF060;
[DllImport("user32.dll", EntryPoint = "SendMessage", SetLastError = true,
CallingConvention = CallingConvention.StdCall)]
public static extern int SendMessage(IntPtr hwnd, uint Msg, int wParam, int lParam)
Try this (assuming by WinForms you are using .NET)
Process ieProcess = Process.Start("iexplore", #"http://www.website.com");
// Do work, etc
ieProcess.Kill();
This will only kill the instance you started.

Resources