News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

DLL pickle

Started by NoCforMe, May 12, 2025, 09:40:12 AM

Previous topic - Next topic

NoCforMe

I'm in a pickle with a DLL.
The DLL registers a window class, in a different .obj module linked with the main DLL code.
Problem is, I just discovered that window classes registered by a DLL are not automatically unregistered when the DLL is unloaded (as they are when an application terminates). From the documentation for RegisterClassEx():

QuoteNo window classes registered by a DLL are unregistered when the DLL is unloaded. A DLL must explicitly unregister its classes when it is unloaded.

OK, so I need to unregister that class manually.

But that's a problem: I can't do it in the DLLMain() entry point, because of the restrictions on what you can do there:

QuoteYou should never perform the following tasks from within DllMain:
  • Call functions in User32.dll or Gdi32.dll. Some functions load another DLL, which may not be initialized.

UnregisterClass() is in User32.dll.

So how do I do this? I need to unregister when the DLL reason is DLL_PROCESS_DETACH. But I can't do it in the DLLmain() function.

I thought of sending a message somewhere else that could do this, but SendMessage() is also in User32.dll.
32-bit code and Windows 7 foreva!

sinsi

Do you have a DLL export to register your classes? Then you should also have a DLL export to unregister them I guess.

NoCforMe

No; I'm calling an initialization function in another module (linked into the DLL) which calls RegisterClassEx(). No export.

Now I'm confused: let's say I did have a DLL export, "UnregisterMyClass()". Would the application that's using the DLL have to call that function? And how would it know when the proper time to do that is? Keep in kind that all windows of that class have to be destroyed before you can unregister the class.

No, I don't think that would work.

I've found some stuff online that may be of help, will post more later after I digest it.
32-bit code and Windows 7 foreva!

sinsi


TimoVJL

#4
If component DLL have safeguard mechanism, it deny to unload as long there are a windows using it.
FindWindow can find windows by registered class.

Perhaps some component code show, how they work.

Dynamic-Link Library Best Practices

What is the HINSTANCE passed to CreateWindow and RegisterClass used for?
May the source be with you

NoCforMe

Wellll, apparently my problem kind of solved itself.
Not really: I made some changes to my program. But it looks as if when the DLL is unloaded, the registered class gets automagically un-registered, probably because it's being created by the process that loaded the DLL and not the DLL itself.

This is all very confusing, but the Raymond Chen stuff you linked to, sinsi, is helpful.
One thing I found is that in order to make the whole thing work, in my DLLMain() proc, I had to use GetModuleHandle(NULL) instead of using the instance handle that's the 1st parameter of that function. This retrieves the instance handle of the calling process, not of the DLL.

So apparently no need to use UnregisterClass().

BTW, in searching for info online I found an interesting discussion of this issue on a board called Cprogramming.com, including a couple posts by our own @adeyblue, from 10 years ago.

Oh, and I'm not using CS_GLOBALCLASS, as this is a private class only used by the DLL itself.
32-bit code and Windows 7 foreva!

sinsi

After reading more, it seems that there are two times you would need to use UnregisterClass
- if you are registering with CS_GLOBALCLASS
    - this means that the DLL has to be in memory in case another process is using your class
    - Raymond mentions a registry key to ensure your DLL is loaded by every process, but I'm not sure that works anymore
- if you are dynamically loading/unloading your DLL
    - if you are then you control the register/unregister calls

The main point from Raymond is (I think)
QuoteUnregister your classes if the process is going to continue running after your DLL unloads.


NoCforMe

Here's the structure of my program that uses the DLL:

You cannot view this attachment.

The DLL is a debugger (data-only logger, no code or CPU, but still very useful) that's called on demand from the debugee.

The watch facility is one of many possible functions. When the debugee calls for a variable to be watched, it sends a watch request to the DLL.

If this is the first watch request it has to set up the watch window. That's when it calls the initialization code for the mcLB2 (multi-column listbox) control used in the watch window, which includes registering the class for that control. The DLL then creates the watch window with the mcLB2 control in it.

The DLL also has a main UI window. If this window is closed by the user, the DLL remains loaded.

So I'm curious about how exactly processes work here. Does the DLL run in a separate process, or is it part of the debugee's process? Also, my understanding is that the DLL will be unloaded when the last program (process) that uses it terminates (i.e., when the reference count goes to zero); is that correct? It seems to work that way.

In any case, everything seems to be working OK. One possible snag occurs to me, though: what if there are multiple programs that are using that control? That means that the class will remain registered even after the DLL is unloaded.

So much to keep track of here ...
32-bit code and Windows 7 foreva!

zedd

#8
I like dill pickles.
DILL pickles taste good. But it must be a quality brand. Vlasic is very popular, but Claussen is better, imo.
Once there are no more pickles, you must drink the juice.

Oh no. Wait... my bad.
It said DLL pickle.  :biggrin:
:biggrin:  :skrewy:

NoCforMe

So you see what I did there ...
32-bit code and Windows 7 foreva!