ATL, Usermode and Visual Basic

Hi,

I am building an ATL ActiveX Control that is intended for Visual Basic.

I need to do some initialization before my control is run at run-time, but this may not happen at design time. How can I do this. I know about the ambient setting "usermode" to tell whether I am in run mode or design mode.

I have tried deriving OnAmbientPropertyChange like this:

STDMETHODIMP Cr6dx::OnAmbientPropertyChange(DISPID dispid)
{
  IOleControlImpl<Cr6dx>::OnAmbientPropertyChange(dispid);
  OutputDebugString("OnAmbientPropertyChange");
  return S_OK;
}

And this works fine from the test container but OnAmbientPropertyChange is never called via VB so I cannot detect the mode change there.

Is there any other way I can use?

I have several ideas, such as putting the code for initialization in OnDraw and then testing for change of mode. Is such an approach stable?

Jacob Marner
LVL 1
feloniusAsked:
Who is Participating?

Improve company productivity with a Business Account.Sign Up

x
 
ambienceConnect With a Mentor Commented:
Hmm ... this can be because you did not select Windowed Only check box while adding the control to the project , in container that support windowless controls your control will not create any window, that explains why you dont get WM_CREATE.

the bWindowOnly  member lets you know about if the control should always have a window or not. declare it as a data member in your control class. Your control class will not inherit this data member from the base class because it is declared within a union in the base class.

unsigned m_bWindowOnly:1;

Try Set it to 1 in the contructor. Note the best place for initializations is FinalContruct but you can get any property value and usermode cannot be determined in FinalContruct , so have to find some other means.

I'll let you know if i find something more robust meanwhile try it.
0
 
ambienceCommented:
Why dont you put the initialization stuff in WM_CREATE handler of your control. I dont think OnAmbientPropertyChange is called for usermode change , the question here is does usermode change ? , when you are in design mode you dont normaly directly to rum-time mode without compiling , do you ?
Is is possible for a container to change the user-mode without unloading the control and then reloading ? as far as i know its not done , i've seen many control load certain dlls only at runtime during initializations and dont even bother for a change of user-mode.

Someone correct me  if i am wrong ...:)
0
 
feloniusAuthor Commented:
Hi thank you for your response.

I hadn't realized that ActiveX controls was in fact windows themselves and could have standard windows message handlers. In fact I can find nothing about this in the docs.
I tried adding a WM_CREATE message handler (both in message map and implementation), but it is never called.(?!?) Is the header that ATL AppWizard makes wrong? It differs from the one in MFC and is LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)

And yes I am certain that user mode changes when the apps starts/stops in VB. My OnDraw handler draw different things depending on the usermode and this works fine. The OnAmbientPropertyChange event just isn't called.

Jacob
0
Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
feloniusAuthor Commented:
Concerning OnCreate issue, do I have to call Create() in the ATL class constructor like I have to in MFC?

PS: I have ordered an ATL book from Amazon but haven't gotten it yet so my currently development efforts are based solely on the MSDN library reference which is pretty thin.

Thanks for your time.

Jacob Marner
0
 
ambienceCommented:
>>> The OnAmbientPropertyChange event just isn't called.

This is what i said , maybe i didnt make myself clear, there is not going to be a transition from design mode to user mode directly.

What i mean is that once a control is initializaed , during its lefetime usermode will never change. When you go from design mode in VB to runtime mode , the control infact is destroyed and re-initialized during the transition.



0
 
ambienceCommented:
how are you adding a message handler , like  

MESSAGE_HANDLER(WM_CREATE, OnCreate)

LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);

??
0
 
feloniusAuthor Commented:
>> What i mean is that once a control is initializaed , during its lefetime usermode will never change.
When you go from design mode in VB to runtime mode , the control infact is destroyed and re-initialized
during the transition.

I just tried putting some debug out code in the constrcutor and yes you are right.

And here is my handle code (as you suggest):

Message map:

BEGIN_MSG_MAP(Cr6dx)
     CHAIN_MSG_MAP(CComControl<Cr6dx>)
     DEFAULT_REFLECTION_HANDLER()
     MESSAGE_HANDLER(WM_CREATE, OnCreate)
END_MSG_MAP()

Implementation (inline in header):

LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
  BOOL usermode;
  GetAmbientUserMode(usermode);
  if (usermode==TRUE)
    dxx_d3dinit(m_hWndCD,0,0,100,100);
  return 0;
}

YOu have already been much help already thanks. Bonus!: I raise the points.
0
 
ambienceCommented:
BEGIN_MSG_MAP(Cr6dx)
    CHAIN_MSG_MAP(CComControl<Cr6dx>)
    DEFAULT_REFLECTION_HANDLER()
    MESSAGE_HANDLER(WM_CREATE, OnCreate)
END_MSG_MAP()

try changing above to

BEGIN_MSG_MAP(Cr6dx)
    MESSAGE_HANDLER(WM_CREATE, OnCreate)
    CHAIN_MSG_MAP(CComControl<Cr6dx>)
    DEFAULT_REFLECTION_HANDLER()
END_MSG_MAP()

0
 
feloniusAuthor Commented:
Ok.

<< typing the code and running with a break point in OnCreate and several other places >>

That didn't make any difference. Cr6dx::Cr6dx() is called but not Cr6dx::OnCreate().

Am I supposed to call Create() in the Cr6dx::Cr6dx()? I currently do not.

Also, I have no docs for OnCreate (since it is not the same as in MFC) so I don't even know if I am supposed to call the the implementation in the base class first like in MFC or whether I should call DefWindowProc

Jacob Marner, B.Sc.
0
 
feloniusAuthor Commented:
Okay thanks. I will try it out and let you know. (it may take a couple of hours - I am in the middle of something else at the moment)

(Note: It is a control for the 6DX Engine. Check out the screenshots at www.eldermage.com)

Jacob Marner
0
 
feloniusAuthor Commented:
BINGO!

You were right. Setting WindowedOnly to true made the window appear and the OnCreate was called. Apparently Visual Basic forms supports windowless controls and avoids Windows if possible.

Note however that m_bWindowOnly in fact was inherited automatically so I did not have to redeclare it - doing so would actually be an error since I would be changing another piece of memory - but thats a completely other discussion.

Thank you very much. This will let me continue work on control.

Jacob Marner
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.