Solved

ATL, Usermode and Visual Basic

Posted on 2001-06-27
11
392 Views
Last Modified: 2013-11-25
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
0
Comment
Question by:felonius
  • 6
  • 5
11 Comments
 
LVL 22

Expert Comment

by:ambience
ID: 6236642
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
 
LVL 1

Author Comment

by:felonius
ID: 6237777
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
 
LVL 1

Author Comment

by:felonius
ID: 6237805
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
 
LVL 22

Expert Comment

by:ambience
ID: 6237815
>>> 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
 
LVL 22

Expert Comment

by:ambience
ID: 6237828
how are you adding a message handler , like  

MESSAGE_HANDLER(WM_CREATE, OnCreate)

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

??
0
Top 6 Sources for Identifying Threat Actor TTPs

Understanding your enemy is essential. These six sources will help you identify the most popular threat actor tactics, techniques, and procedures (TTPs).

 
LVL 1

Author Comment

by:felonius
ID: 6237875
>> 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
 
LVL 22

Expert Comment

by:ambience
ID: 6237948
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
 
LVL 1

Author Comment

by:felonius
ID: 6238037
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
 
LVL 22

Accepted Solution

by:
ambience earned 150 total points
ID: 6238223
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
 
LVL 1

Author Comment

by:felonius
ID: 6238259
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
 
LVL 1

Author Comment

by:felonius
ID: 6239465
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

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Introduction: Dialogs (2) modeless dialog and a worker thread.  Handling data shared between threads.  Recursive functions. Continuing from the tenth article about sudoku.   Last article we worked with a modal dialog to help maintain informat…
If you use Adobe Reader X it is possible you can't open OLE PDF documents in the standard. The reason is the 'save box mode' in adobe reader X. Many people think the protected Mode of adobe reader x is only to stop the write access. But this fe…
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA. http://www.experts-exchange.com/videos/1478/Excel-Error-Handlin…

747 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now