I am trying to use a subclass of System.Runtime.InteropServices.SafeHandle
to manage pointers to Win32 GUI objects (namely, HWND
and HMENU
). I am then using these handles to implement a Win32-based GUI library in C#. In this process, I create a menu and assign it to a window. However, suppose that I do not retain the SafeHandle containing HMENU
, so that it is garbage collected before the window that owns it is. I cannot simply destroy all HMENU
pointers when their SafeHandles go away, because then something like this happens:
- I create an
HMENU
and assign it into a subclass ofSafeHandle
that callsDestroyMenu()
automatically. - I create a top-level
HWND
, and assign it theHMENU
using theSetMenu()
Win32 API call. - Because the
HWND
now retains theHMENU
, it should not be destroyed (throughDestroyMenu()
) until theHWND
that owns it is destroyed, at the earliest. - However, because I wrapped the
HMENU
in a SafeHandle, the GC would soon deallocate the SafeHandle, and thus destroy theHMENU
, while it is still referenced by theHWND
. - My program then crashes due to the use of an explicitly deleted handle.
Is there anything I can do to ensure that the HMENU
stays around as long as it is needed, but is still destroyed once the owning HWND
is GCed? I looked at this question, which would be nearly ideal, except it talks about using a native library that has reference counting built-in. Win32 does not — a handle either exists, or is destroyed. I considered adding my own reference-counting using a class like SafeHandle
, but was stymied due to the fact that not all of the parts of the program (namely, Win32) referencing the HMENU
have access to my reference-counting class. Is this a concern for my use-case? Are there any other ways I can/should implement such an API wrapper?