HINSTANCE requirement
-
As an exercise, I am wrapping some of the lower level win32 structures and methods into a C++ object library. I'd like to avoid forcing the user to do things like "register" classes. I think this is error prone to have the user make 'one' time calls, so I am trying to take advantage of C++ static properties. Currently, I declare an class (static) ATOM and initialize it with a function that is local to the cpp file. My question revolves around the HINSTANCE member of the WNDCLASSEX struct. It clear that for win2k+, the hinstance parameter is ignored in the CreateWindowEx function - but what about for the population of WNDCLASSEX and subsequent RegisterClassEx calls? It seems to work in my demo application (using WNDCLASSEX.hInstance = NULL that is). I have also had luck using the return value of GetModuleHandle. Any suggestiong? I'd like to know whats going on under the hood. Will these methods work in simple cases and not more complex? I've even done this in a small DLL and seemed to have no problems using absolutely no HINSTANCE in the WNDCLASSEX .... When one registers a class, is it registered systemwide? so that any HINSTANCE could instantiate it? The documentation says the WNDPROC must exist in the HINSTANCE. When I don't provide a hinstance, maybe it assumes the hinstance the call is being made from and so far, my WNDPROC always exists there? This all comes back to the question, should I force the user to provide a HINSTANCE and consequently, Register classes explicitly. Any direction would be appreciated. Thanks in advance, -Luther
-
As an exercise, I am wrapping some of the lower level win32 structures and methods into a C++ object library. I'd like to avoid forcing the user to do things like "register" classes. I think this is error prone to have the user make 'one' time calls, so I am trying to take advantage of C++ static properties. Currently, I declare an class (static) ATOM and initialize it with a function that is local to the cpp file. My question revolves around the HINSTANCE member of the WNDCLASSEX struct. It clear that for win2k+, the hinstance parameter is ignored in the CreateWindowEx function - but what about for the population of WNDCLASSEX and subsequent RegisterClassEx calls? It seems to work in my demo application (using WNDCLASSEX.hInstance = NULL that is). I have also had luck using the return value of GetModuleHandle. Any suggestiong? I'd like to know whats going on under the hood. Will these methods work in simple cases and not more complex? I've even done this in a small DLL and seemed to have no problems using absolutely no HINSTANCE in the WNDCLASSEX .... When one registers a class, is it registered systemwide? so that any HINSTANCE could instantiate it? The documentation says the WNDPROC must exist in the HINSTANCE. When I don't provide a hinstance, maybe it assumes the hinstance the call is being made from and so far, my WNDPROC always exists there? This all comes back to the question, should I force the user to provide a HINSTANCE and consequently, Register classes explicitly. Any direction would be appreciated. Thanks in advance, -Luther
Hi Luther, I can only answer some of the questions you've put here. Hopefully someone else will jump in and answer the remainder. Regarding HINSTANCE I only know what's available in MSDN and the platform SDK, and these don't cover what goes on "under the hood" for functions like RegisterClassEx and CreateWindowEx. From experience, using NULL for the HINSTANCE doesn't seem to make much difference (but you already knew that). I don't know the consequence of using NULL for the HINSTANCE in these functions. HINSTANCE can be important for other things though. One example is the TBADDBITMAP structure for a toolbar must get a real HINSTANCE value (not NULL) to create the toolbar. The bottom line is that you will probably find you'll need the HINSTANCE of your application to do some things, but you'll get away with NULL for some others. Not a very adequate answer, but there you go. Regarding RegisterClassEx You need to call this in your application before it creates a normal window. The name registered for the window is not global, each application needs to register the windows before creating it. Using NULL as the HINSTANCE doesn't make it global or system wide. Some predefined window types don't need to be registered. These include dialogs, edit controls, tool bars, status bars and so forth. All "general purpose" windows, however, need to be registered in the application that uses them. By the way, you might find my article "Win32 Framework for SDI Applications" a handy reference. The URL is: http://www.codeproject.com/win32/Framework.asp regards, David If it was easy, anyone could do it.
-
Hi Luther, I can only answer some of the questions you've put here. Hopefully someone else will jump in and answer the remainder. Regarding HINSTANCE I only know what's available in MSDN and the platform SDK, and these don't cover what goes on "under the hood" for functions like RegisterClassEx and CreateWindowEx. From experience, using NULL for the HINSTANCE doesn't seem to make much difference (but you already knew that). I don't know the consequence of using NULL for the HINSTANCE in these functions. HINSTANCE can be important for other things though. One example is the TBADDBITMAP structure for a toolbar must get a real HINSTANCE value (not NULL) to create the toolbar. The bottom line is that you will probably find you'll need the HINSTANCE of your application to do some things, but you'll get away with NULL for some others. Not a very adequate answer, but there you go. Regarding RegisterClassEx You need to call this in your application before it creates a normal window. The name registered for the window is not global, each application needs to register the windows before creating it. Using NULL as the HINSTANCE doesn't make it global or system wide. Some predefined window types don't need to be registered. These include dialogs, edit controls, tool bars, status bars and so forth. All "general purpose" windows, however, need to be registered in the application that uses them. By the way, you might find my article "Win32 Framework for SDI Applications" a handy reference. The URL is: http://www.codeproject.com/win32/Framework.asp regards, David If it was easy, anyone could do it.
Many Thanks David. I have a built a very similar framework - but with templates. Mainly to get as far away from virtual tables as possible. Sometimes subclassing, sometimes superclassing ... but templates add a nice twist. I've come across one or two articles on Thunking (a lengthy one here on codeproject) but it didn't seem to work perfectly in .NET. I'm not an ASSEMBLER, and I was probably doing something incorrectly, but setting the callback function to the thunk wasn't properly executing and the application would freeze. I'm not especially fond of the GetWindowLongPtr method, but at least it works. I'm concerned that an application with windows containing several children - each one using GetWindowLongPtr approach is not going to scale well. Of course that's relative - but c windows apps will always have that speed advantage. It'll probabaly work out just fine ... just trying to explore for a clean, fast solution. Hoping the lack of HINSTANCE in the WNDCLASSEX doesn't come back to bite me. Thanks again, -Luther
-
Many Thanks David. I have a built a very similar framework - but with templates. Mainly to get as far away from virtual tables as possible. Sometimes subclassing, sometimes superclassing ... but templates add a nice twist. I've come across one or two articles on Thunking (a lengthy one here on codeproject) but it didn't seem to work perfectly in .NET. I'm not an ASSEMBLER, and I was probably doing something incorrectly, but setting the callback function to the thunk wasn't properly executing and the application would freeze. I'm not especially fond of the GetWindowLongPtr method, but at least it works. I'm concerned that an application with windows containing several children - each one using GetWindowLongPtr approach is not going to scale well. Of course that's relative - but c windows apps will always have that speed advantage. It'll probabaly work out just fine ... just trying to explore for a clean, fast solution. Hoping the lack of HINSTANCE in the WNDCLASSEX doesn't come back to bite me. Thanks again, -Luther
Luther Baker wrote: Hoping the lack of HINSTANCE in the WNDCLASSEX doesn't come back to bite me. Actually I was interested in your question about HINSTANCE, and was hoping someone else would come up with a definitive answer (hence my delay in answering your question). If you ever get to the bottom of the implications of using an HINSTANCE of NULL it might make for an interesting article on Code Project (for me anyway :-D). I'm currently toying with using TLS (Thread Local Storage) as my thunk (as one of the comments to my article suggested). Seems to work well. Might be easier and more maintainable than assembly. Just a thought. Best Regards, David