I'm writing a small MFC app and loading an icon handle like this in my executable upon launch:
const HANDLE hIconLarge = ::LoadImage(AfxGetInstanceHandle()
MAKEINTRESOURCE(IDI_EXAMPLE), IMAGE_ICON,
::GetSystemMetrics(SM_CXICON), ::GetSystemMetrics(SM_CYICON), 0);
I am retaining this same handle in another class in a DLL I created by simply assigning it like this:
m_hLargeWindowIcon = p_hLargeIconHandle;
where m_hLargeWindowIcon is a private class HANDLE variable in a singleton that I call IconManager. I then later occasionally use this icon handle to set the large icon for pop-up windows that my DLL creates.
It seems to be working fine, but I am concerned about the life cycle of the handle I am retaining.
Is it safe to save a handle in this fashion (i.e. the handle will remain valid until the host process of my DLL is terminated) or can I run into issues where the handle may not be valid when I access it at a later point in time? Should I be using DuplicateHandle or something to that nature in this case?
You don't need to duplicate the handle in any way. Your usage is fine, apart from the fact that you are using the wrong type. Instead of HANDLE you should use HICON.
When nothing more refers to that icon handle, you do need to destroy it. Call DestroyIcon to do so.
The lifetime of the icon is as long as a valid handle to it (HICON) exists, else, it'll get cleaned up when the process exits.
Normally you would want to wrap the functionality up in a Icon class of some sort with appropriate copy and move semantics. Or at the very least tie it to a RAII class to manage the lifetime of the HICON.
Given the singleton nature of its use here, that may be overkill. Let the singleton clean it up DestroyIcon when the program exits. One caveat here is that you really should be sure that clients of the code don't try clean it up for you. Once they have a bit copy, sure, there is little you can do to stop them, but at least be clear in the documentation how the code behaves and some reason as to why (since this seems to be a corner case w.r.t. the resource management).
Side note: I believe the correct function to duplicate an icon is CopyIcon.
Related
I have seen some examples on the internet where buttons were created under WM_CREATE and I have done some projects where creating "some" buttons such as Start/Stop buttons or Text Fields had to be created under MainWindow and not under WM_CREATE.
Is there any reason for chosing/difference/benefit of the choice of one over other when we can chose between these two?
I don't know anything about the Win32Gui library in particular, but I've used plenty of Win32 wrapper libraries and even written one myself.
Handling the WM_CREATE message (which is sent to a window after it is created) is the typical way of creating dynamic child windows such as button controls. This would be the same regardless of whether you're working directly with the Win32 API or using a wrapper library. The only difference might be how that wrapper library expects you to handle the message. For example, in MFC, you would override a member function of the window class called OnWmCreate.
But you really can create child windows anywhere in the code. You aren't forced to do it in response to WM_CREATE. You could do it in response to WM_KEYDOWN if you wanted. The only requirement is that you must have already created the parent window (because you must pass a valid handle to the parent window when creating the child window).
It sounds to me like the MainWindow you're talking about is the constructor method for your MainWindow class (a C++ object that models a Win32 window). Depending on the design of the framework, this may or may not be a valid place to create child windows. It depends on that above-stated requirement: whether the underlying Win32 window represented by the C++ object has already been created and whether you have a valid handle to it available inside of the constructor body.
Some frameworks implement a two-phase style of construction for window objects. What I mean by that is that the class constructor creates an instance of a C++ object, and then you need to call a second member function (e.g. Create) to create the Win32 window represented by the C++ object. In cases like this, you cannot create child windows inside of the parent window's constructor because the parent window has not yet been created and you do not have a valid handle to use when creating the children.
Other frameworks might require that you specify all of the necessary parameters to create the underlying Win32 window when creating your C++ object, and then the constructor will take care of creating both the C++ object and the underlying Win32 window (e.g. by calling the CreateWindow function). If the creation of either fails, an exception will be thrown. Otherwise, you can be sure that you have access to a valid window handle inside the body of your derived class's constructor.
However, even if this single-phase approach to construction describes the design of your wrapper library, I would still suggest creating child windows in response to the WM_CREATE message, rather than in the constructor. But that's just a personal preference and a matter of individual style.
Different people have different ideas about how much work should be done inside of a constructor. My personal litmus test is that, after the constructor has run, you should have a valid, fully usable object on which any member functions can be called. I don't much care for two-phase construction, because I don't like the interface complexity that introduces of requiring the consumer to not only create the object, but also call a Create or Init method. I don't consider child windows to be an integral part of the parent, though, so I say that their creation belongs elsewhere than in the parent's constructor.
I cannot understand why you say
I have done some projects where creating "some" buttons such as Start/Stop buttons or Text Fields had to be created under MainWindow and not under WM_CREATE.
There is no reason why you would have to create child windows in the constructor and you would be unable or it would not work to do so in response to the WM_CREATE message.
While writing a new vst-plugin using VSTGUI I'm really struggling with how to use the library, and most progress is made from guessing and debugging after (because there really is no documentation besides the million lines and ygrabit, which states little more than the obvious).
So far it's going good, but my last contribution to the project involved threads which made the design a little bit more problematic. Specifically, I'm working on a set of textlabels in a container (doing non-atomic operations) and these may (and obviously does) get destructed without my knowledge, when a user closes the window.
Even adding checks right before changing elements might still be a problem. So I actually need to control the lifetime of these objects (which is fine) except when they are shown in a CViewContainer, it automatically assumes ownership.
I have no idea how to write the backbone of the editor, so i used a program called VSTGUIBuilder for this, and appended (and basically rewrote) what i needed. However, since all 'views' you can work with requires either a parent or a systemwindow, you cannot instantiate any views/controls before reaching the AEffEditor::Open() function, which is called whenever your window is popped up.
And the AEffEditor::close() method is called whenever the window is closed. Now, the vstguibuilder put a
delete frame;
inside the AEffEditor::close() method which suggests you rebuild and dispense all resources on every open and close. Can this really be true? And if it is, is there no way i can protect my container's contents (which for details is a vector< CTextLabel *>) from getting deleted mid-function? It's no problem to dispose of it afterwards, I'm just worrying about segfaults while changing it.
Using mutexes and the such is really the last resort (if the call is coming from the host), I don't want to hang the host in any case if my code faults and never releases.
Edit:
I ended up finding a solution which is not so elegant, but works safely. Here's the code in the worker function:
while(bLock) {
Sleep(0);
}
bLock = true;
if(msgs.empty())
return;
/*
Prevent someone deletes our lines in close().
we create a copy of the container to be 100% sure
and increase the reference count, so we can safely
work with our own container and we 'forget' them
afterwards, so they will be deleted if needed.
This ensures that close AND open can be called
meanwhile we are working with the lines
*/
bDeleteLock = true;
// also the copy constructor should work as expected here
// since we are working with pointers, we still reference the same content.
auto copy_lines = lines;
for each(auto line in copy_lines) {
line->remember();
}
bDeleteLock = false;
...
for each(auto line in copy_lines) {
line->forget();
}
cont->setDirty();
bLock is another 'mutex' that protects a message queue, which this function will print out. bDeleteLock protects the process of copying the line container and 'remembering' them, and instantly releases if afterwards. Both are declared as volatile bools, shouldn't that be enough? Here's the close() method btw.
void CConsole::Close() {
// locking lines while copying them over in a container we can work with
while(bDeleteLock)
Sleep(0);
//waiting for bLock is not needed because it wont get deleted.
if(!visible) //if we are not visible it's our responsibility to remove the view
delete cont;
lines.clear();
}
Ahh, VSTGUI, that brings back some dark memories. ;) But seriously, yes, you will probably have to use a mutex to prevent the host from hanging. Having to instantiate everything when the window reopens seems kind of silly, but you can see many plugins do just that.
One potential workaround is to use a shared memory segment for cached view data, and then pass a reference to the location back to your plugin
I've been working a lot with Win32 lately, but I'm pretty new to it, and need some advice concerning organization. In C++, although it works syntactically to declare global variables, I was always under the impression that this was sloppy, because the variable can then be modified anywhere, so it becomes much more difficult to track changes to it.
In my Win32 project, I've got several variables which need to be modified in multiple places. For instance, one such variable was in the WndProc function and also in a dialog procedure function. Due to the way it was used, I was able to simply use the actual values in WndProc, and then call the dialog box using DialogBoxParam, and pass the value to the dialog box through the lParam value.
However, there are other values, such as certain bitmaps that I use for drawing or variables that are used in multiple different window message calls, where the value(s) need to be retained throughout multiple instances of the WndProc function or multiple functions. I can control the parameters of the functions I created, but what if I need to pass a variable into the WndProc function so that I can use it regardless of multiple different window messages? What if I need to pass in multiple values?
So far I've just been making everything global, and it works, but it feels sloppy to me...but I know that some variables are generally global as a matter of convention - like the main window and instance variables.
What do you all think?
It might help if you had a specific example in code. But I think you're talking about lifetime--you have a resource (say a bitmap) and you need to reference it many times in response to different Windows messages. You could make it global, yes, but I agree that's sloppy.
So who created the window? Likely your "App" class or something along those lines. Since that class's lifetime is logically longer than the window's, it could hold the resources required by the window.
Or a better approach is to create a "Window" class. Your App instantiates a Window object. The Window object creates the Win32 window and holds the HWND (you've now abstracted that away from the App so it doesn't need to know those gory details), and the Window instance can hold the bitmap resources.
Instead of using global variables you can store window-specific data in a C++ object associated with the relevant window.
To associate a C++ object with a window, use any of a number of existing C++ class frameworks (such as e.g. Microsoft’ WTL or Torjo's Win32GUI), or do it yourself by using SetWindowSubclass API function.
For the Do It Yourself™ solution, I presented a complete C++ example in another SO answer.
That said, for a tiny little program global variables + a dialog is the easiest and presents no problems. So in general, use the Right Tool™ for the job. For larger jobs, use more heavy tooling…
According to msdn, when I get a CWnd* with CWnd::FromHandle,
The pointer may be temporary and should not be stored for later use.
What is meant by "later use" is not clear to me. Is it only the scope of the current method?
As far as I know, there is no GC in Win32!
MFC maintains a number of handle maps, from HWND to CWnd, HDC to CDC etc, which are stored in the thread state. Each handle map contains a permanent map and temporary map - permanent entries are added when you call a method such as CWnd::Create or CDC::Attach, while temporary entries are created when you call FromHandle on a handle that doesn't have a permanent entry.
Temporary entries are cleaned up during idle processing (in CWinApp::OnIdle), so they can only safely be used while processing the current message. As soon as you return to the message loop, or enter another modal loop (e.g. by calling DoModal) then they may be deleted.
FromHandle is basically used for getting a transient reference to an already existing window object. MFC stores these references in an internal structure called a temporary handle map (a handle map is a map of Windows HWNDs to MFC CWnd objects used by MFC to make Win32 calls to manipulate the actual Windows window the MFC object corresponds to). In order to avoid the number of objects in this structure from growing beyond all bounds, items are deleted from the handle map during MFC's idle loop processing.
As you may have guessed, there is also a permanent handle map that won't have this automatic clean up behavior. If you need to get a CWnd object that doesn't put its HWND reference in the temporary handle map you can call FromHandlePermanent().
-Ron
Based on the same MSDN description, I would assume that this means that if no CWnd is attached to the hWnd provided as an object, it will create a temporary CWnd which probably gets destroyed once something goes out of scope, or a destructor elsewhere is called, or a CWnd is explicitly created for the hWnd in question. So if you already have a CWnd created, you should be OK, otherwise you will probably need to be very careful with storing the pointer you receive.
Typically they only want you to use this handle with in the scope of your function. And not to store it as a class field where you reference it through out the life of your object.
I need to call API
CallWindowProc((WNDPROC)lpfnOldProc, hWnd, Message, wParam, lParam);
Now how can I make sure that lpfnOldProc still valid ?
Basically,lpfnOldProc is procedure in another dll and if that dll is unloaded then lpfnOldProc will still be pointing to something but not valid memory?
Are there some memory API's through which I can verify validity of lpfnOldProc?
Don't worry. You're in a hook proc obviously. Now, even in your absence the program would crash if the original window proc was unloaded and called. It doesn't matter that you're now the caller instead of Windows.
A Window Proc should remain in memory as long as there are existing windows using it. The responsibility for this check lies fully with the code considering the unload, not the callers of the Window Proc (i.e. you). This responsibility can be summarized in one line: "Don't unload anything still in use."
You can't check. You can set up structured exception handling to catch the fault that will result of the DLL in question has gone away or been replaced by a copy of the Encyclopedia Brittanica mapped into memory.
Happened something similar in the pass, name two or more dll trying to override a window proc. Normally as part of the process shutdown, or a plugin unload, they try to restore the "oldWndProc", but since they are not aware of each other they may end up overriding a good pointer with an invalid pointer and then crash happens.
If you have access to the source code the best you can do is to have only one dll responsible for hooking a window proc, and then the rest can implement a kind of delegate, so when unloding it can be set to null, and the hooking dll can check and if it is null skip the call.
If you don't have access to the source code, perhaps because you are trying to make your dll work with an already very popular (and buggy) plugin, you may try to find a repeteable procedure so you can detect this case of corruption before it happens (check some of messages before your crash), and workaround it with a custom message notifying your wndproc.