15 мая 2023 года "Исходники.РУ" отмечают своё 23-летие!
Поздравляем всех причастных и неравнодушных с этим событием!
И огромное спасибо всем, кто был и остаётся с нами все эти годы!

Главная Форум Журнал Wiki DRKB Discuz!ML Помощь проекту


GetControlUnknown function ALWAYS returns NULL

MikeMike -- MikeMike@athens.emi.net
Thursday, April 04, 1996

Microsoft VC4.1
Microsoft Windows95
Microsoft MFC
Microsoft Natural Keyboard
Microsoft Mouse ...that's enough MS

I've  Searched: MSDN (Jan) , Technet (Mar), KB (Web)  with no luck

Hello

Short Version:

I cannot get a valid IUnknown from calling GetControlUnknown when 
GetControlUnknown is called from within my CMyFunc within my CMyOleControl 
class

Why not?  It will work on the same object, but only when called from the 
ClientSite (meaning parent window of the control)

Long Version:

I have an Ole Control created using ControlWizard

If I am in any method (function) of the CMyCtrl::COleControl the 
COleControl::GetControlUnknown function ALWAYS returns NULL

For example
CMyCtrl::AnyFunc
{
	ASSERT(GetControlUnknown())  <<<--- Fails each time
}

Why?  I don't know...(which is why I am sending this email)

But what I have seen by stepping through the source code is in the 
MFC/SRC/WINOCC.CPP file, the following function and member variables are of 
interest to look at

First: thing I noticed is that m_pCtrlSite was NULL when it really 
shouldn't be since this was CERTAINLY an OLE Control

LPUNKNOWN CWnd::GetControlUnknown()
{
	if (m_pCtrlSite == NULL)
		return NULL;	<<<<<<<<<<<m_pObject;
}

Secondly...(Why was it set to null?)  Well the line LockupPermanent 
returned NULL...There go is the root of the problem...

void CWnd::AttachControlSite(CHandleMap* pMap)
{
	if (this != NULL && m_pCtrlSite == NULL)
	{
		// Determine if parent is an OLE control container
		CWnd* pWndParent;
		if (pMap->LookupPermanent(::GetParent(m_hWnd), (CObject*&)pWndParent))
			AttachControlSite(pWndParent);
	}
}

My question is
How do you "GetControlUnknown" from within a CWnd Object.....
If this doesn't work, how do you get any interface?

(Any yes I am doing dual interface)

Thanks in advance
MikeMike@emi.net






John & Annette Elsbree -- elsbree@msn.com
Wednesday, April 17, 1996

MikeMike -

GetControlUnknown returns NULL because it's intended to be used only by an OLE 
control container, not by an OLE control itself. From just reading the class 
library reference for this function, I can see why you might expect it to work 
from within a control... the documentation doesn't clearly explain that this 
is a container-side-only function.

Some explanation of how MFC implements OLE control containment will help to 
sort this out.

When you instantiate an MFC window that contains an OLE control, MFC creates a 
CWnd object to represent the contained control (we call such an object an "OLE 
control proxy CWnd") . However, each proxy CWnd is a COMPLETELY SEPARATE 
OBJECT from the actual OLE control itself. It only exists so that the 
container app has an object that "looks and acts like" a CWnd, that it can 
manipulate.

Now, if the OLE control happens to be implemented with MFC (not all OLE 
controls are), then there will also be a separate CWnd-derived (i.e., 
COleControl-derived) object. But the fact that this object is a CWnd is 
entirely hidden from the container application; the container just sees it as 
an OLE object with various interfaces, and the control's own CWnd is just an 
implementation detail.

The CWnd::GetControlUnknown function is intended to be used on proxy CWnd 
objects ONLY. On CWnd objects that aren't proxies, it returns NULL. This 
explains why it was always returning NULL for you: you're not implementing a 
container of OLE controls, you're implementing the control itself.

So, how do you obtain the IUnknown pointer from within your control? Probably 
the best way is to call CCmdTarget::GetControllingUnknown(). True, it's in the 
"Implementation" section of the class declaration, but it is mentioned in MFC 
TechNote 38, and it has a pretty good chance of not changing in future 
revisions.

John (not speaking for Microsoft)

----------
From: 	owner-mfc-l@netcom.com on behalf of MikeMike

I cannot get a valid IUnknown from calling GetControlUnknown when 
GetControlUnknown is called from within my CMyFunc within my CMyOleControl 
class

Why not?  It will work on the same object, but only when called from the 
ClientSite (meaning parent window of the control)




| Вернуться в корень Архива |