News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Global class

Started by TNick, January 09, 2007, 10:55:23 AM

Previous topic - Next topic

TNick

Hi, guys!

As I said somewhere around past days, I am working at some custom controls. For now, I'm just putting them in a dll, and I will decide the final form later. Anyway, for almost each control I must register a class. A global class. When I started working at it, I was remembering something from PSDK saying thet to have a class that can be used in multiple processes, you have to add a certain registry key. That was fine by me and I started the work. When I did a closer read, it seems that the things are not so simple.This is the text:

Quote from: win32.hlpCS_GLOBALCLASS   Allows an application to create a window of the class regardless of the value of the hInstance parameter passed to the CreateWindow or CreateWindowEx function. If you do not specify this style, the hInstance parameter passed to the CreateWindow (or CreateWindowEx) function must be the same as the hInstance parameter passed to the RegisterClass function.
You can create a global class by creating the window class in a dynamic-link library (DLL) and listing the name of the DLL in the registry under the following keys:
HKEY_LOCAL_MACHINE\Software
\Microsoft\Windows NT\
CurrentVersion\Windows\APPINIT_DLLS
Whenever a process starts, the operating system loads the specified DLLs in the context of the newly started process before calling the main function in that process. The DLL must register the class during its initialization procedure and must specify the CS_GLOBALCLASS style.

and this is what I understand:
- to register a class in your exe for a window created by the same exe, don't use the global flag
- to register a class for a window created by a different module, in the same process, use the flag
- to register a class that can be used by any process in that system, use the flag; do the call to RegisterClass(Ex) in the initialization procedure


Of course, my problem is with the second and third point.
First, if I understand correctly, the dll's listed under that key will be mapped in the address space of every process!?
So, if I create a custom tree view control, the dll will be mapped in the address space of Calc, too? Hm .. This should increase loading time for each process, right? Wich doesn't sound good at all!
Second. If you use the second way, you can do thing like this:

DllEntryPoint   PROC hInstance:DWORD, Reason:DWORD, Reserved1:DWORD
   .IF Reason==DLL_PROCESS_ATTACH
      ;register classes
   .ELSEIF   Reason==DLL_PROCESS_DETACH
      ;unregister classes
   .ENDIF
ret
DllEntryPoint    ENDP

When first process loads the dll, the classes are registered. When any other process loads the dll, the register function fails because the classes are already registered, but it will work with the classes registered by the first process. But when a process is terminated the classes are unregistered and the other processes will just fail? Or, because you pass dll module handle, there will be a unique set of classes for each process that uses that dll?

What I wish is this:
- Register the classes when the dll is first loaded (first process is loading)
- Unregister the classes when the dll is unloaded (last process is unloading)
- use the classes happily between those two moments

Is there any way to do this?

Thanks,
Nick

[edit]
Hey, at least a "Stick with lib, forget about dll's ...?!"  :(
[/edit]

Tedd

I'm not entirely sure what happens with global classes, so I can't offer advice there.

However, if you need to load once and only unload once, you can do the following:

- Create a global variable, "instCount", initialised to zero -- you'll need to make sure it's one variable for ALL instances of the dll, and not one for each dll, otherwise it won't work (there is a way to do this.)
- On PROCESS_ATTACH: if (instCount==zero) {register the class.} Add 1 to instCount.
- On PROCESS_DETACH: sub 1 from instCount. if (instCount==zero) {unregister the class.}
No snowflake in an avalanche feels responsible.

mnemonic

Quote from: Tedd on January 12, 2007, 01:28:06 PM
- Create a global variable, "instCount", initialised to zero -- you'll need to make sure it's one variable for ALL instances of the dll, and not one for each dll, otherwise it won't work (there is a way to do this.)
That's right.

Search the forums for "shared section".
Here is one of the first matches: http://www.masm32.com/board/index.php?topic=5194.msg39433#msg39433

HTH
Be kind. Everyone you meet is fighting a hard battle.--Plato
-------
How To Ask Questions The Smart Way

TNick

Tedd and mnemonic,

thanks for your replies. That helps, and I will experiment a little with global classes. I will post the conclusions here.

Regards,
Nick

PS
Tedd, I don't know why I have the feeling that my post here disturbed you. If that's the case, please let me know and you will have my apologies right away.

Tedd

Ummm.... nope, no offence here :wink
We were joking around, that's good :bg
No snowflake in an avalanche feels responsible.

TNick