"Not necessarily. In this case the clients will be using late binding"
late binding doesn't matter. A dll is only loaded ONCE. That is why you can't get single use from a component. Single use means that a seperate process is started for each instance. DLL's, as you have said, load into the callers address space (lets not get into COM+ here because even then they load in the callers address space the caller is just DLLHOST.EXE) thus only load ONCE.
"...parent handle from a process id..." My point is a process can have multiple windows. Write a VB program with a SUB MAIN then open 10 windows modaless from that sub main. The first window isn't the parent. All 10 windows have no parent window.
GetActiveWindow is a good bet just make sure your window is active before the call. But then you might as well just pass the window handle in.
For example I have 2 windows in my program. Window 1 is in the background but still processing its message pump (Modaless) Window 2 is the active window. Window 1 calls the DLL. The dll will get window 2 window not the caller, window 1, because both window 1 & 2 are in the same thread (vb is single threaded).
I'm a firm believer that if you want a method/function to know some state that its caller knowns then you should pass it in.