v useful article, thanks for sharing...
ReplyOriginally posted by: Bryan Welton
Hi,
Found this article very useful. However, I have hit a problem. If I create an OCX in VB which itself uses mscomctl.ocx, I get a crash occurring when I close the container.
Anyone else observed this?
--
Bryan Welton
Software Engineer
ORIMOS Ltd
Originally posted by: Lucian
void CChildFrame::OnEditPaste() // on some event
int CChildFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CMDIChildWnd::OnCreate(lpCreateStruct) == -1)
return -1;
// TODO: Add your command handler code here
m_pCtrl = new CPolyCtl(); // the ActiveX wrapper
bool ret = m_pCtrl->Create("Hi",WS_VISIBLE|WS_CHILD,CRect(0,0,100,100),this,1234);
if (!ret)
AfxMessageBox("Create failed !");
return 0;
}
{
m_pCtrl->ShowWindow(SW_SHOW);
m_pCtrl->UpdateWindow();
}
Originally posted by: G. Satyanarayanane
Dear Friends,
I would like to know how to create OCX file which enables us to add the .GIF file to the projects. It should be done in VB-6. Is it possible?? If so and if you R having any examples pls post or send email to me.
Thanks
Satyanarayanane.
Originally posted by: Alexei
I have been developing a project with dynamic creation of ActiveX controls. Unfortunately, wrapper class for my ActiveX control doesn't have Serialize(...) member, and CWnd impelemtation does nothing except calling CObect::Serialize(...) method. So the question is how to make serialization with MFC?
Reply
Originally posted by: Markus Schiefele
Thinking about my last comment, I noticed that it might be difficult to get the DISPID of the event you want to handle. So I found a more simple way of event-handling. Before you delete the control from the dialog template and remove the DDX_CONTROL entry from the MESSAGE_MAP, simply let the wizard create event-handling routines for all the events you want to handle. So the wizard will create an EVENT_SINK_MAP and will do nearly all the work for you. The only thing that remains is to change the ID of the control in the ON_EVENT macros. If you want to add more than one control on runtime, you also have to replace the ON_EVENT macros by ON_EVENT_RANGE macros. Please don't forget to add an additional VTS_I4 paramater at the beginning of the parameter list of the ON_EVENT_RANGE macros, and also an ULONG parameter to get the ID in the event-handling routines.
I think you will never have it more easily.
Originally posted by: Markus Schiefele
m_ctlMyControl.Create(NULL, WS_VISIBLE, rControlRect, this, 5000);
Where RECT rControlRect contains the rect in which to display the control.
Now about eventhandling. This a little bit more work. First add the DECLARE_EVENTSINK_MAP() macro to the header of your dialog class (best at the end). In the cpp of your class you must add an event-sink-map next. If your class is CMyDlg it might have the following form:
BEGIN_EVENTSINK_MAP(CMyDlg, CDialog)
The ON_EVENT_RANGE macro has the following parameters: first the name of your dialog class, the next two describe the range of the ID of your control. The ID was fixed in the Create Method (here the ID should have a value between 5000 and 5009, i.e. you can create ten controls at runtime. If you want to create only one control at runtime you can use the simpler ON_EVENT macro). The next parameter is the dispatch-id of Event you want to handle. Then comes the name of the Method to handdle the event. Last but not least follows the parameterlist. The first parameter must always be a VTS_I4 parameter because it gets the ID of the control, which fired the event. The following parameters are the parameters of the event. This EVENT_SINK_MAP would be good if your control has two events, both with two VTS_I4 parameters (like clicked_in and clicked_out of the Polygon control from the ATL-Tutorial in MSDN-help).
afx_msg BOOL OnEvent1(UINT id, long x, long y);
Please note that the method has to return a BOOL. The implementation could be:
BOOL CMyDlg::OnEvent1(UINT id, long x, long y)
Thats it.
There is a much more easier way to create ActiveX-controls on runtime. Add the desired control to the dialog-template, then ctrl-double-click it to make the class wizard add a wrapper-class for it. Remove the control from the dialog-template and remove the DDX_CONTROL entry from the AFX_DATA_MAP (you will find it in the DoDataExchange Method of your dialog class). Now you can use the instanciated wrapper class the wizard created. you can use the Create (it has the same Parameters as CreateControl from CWnd)Method to display it and the DestroyWindow Method to delete it. If you want to give your control an ID of 5000 and the instance of the wrapper is m_ctlMyControl it coul be:
ON_EVENT_RANGE(CMyDlg, 5000, 5009, 1, OnEvent1, VTS_I4 VTS_I4 VTS_I4)
ON_EVENT_RANGE(CMyDlg, 5000, 5009, 2, OnEvent2, VTS_I4 VTS_I4 VTS_I4)
END_EVENTSINK_MAP()
Now add the Methods to handle the events in the Message-Map of the header of your dialog class (maybe below OnQueryDragIcon()). For the Event 1 in our example this might look like:
{
if (id == 5000)
{
MessageBox("Control 5000 fired Event1");
//Something else with x an y
}
return TRUE;
}
Originally posted by: Miguel Chavez
Any Ideas on how to handle event or another way of dynamically create ActiveX controls.
Thank you
Miguel
Originally posted by: Sunil Gade
This is a wonderful article.
May I take this opportunity to ask you the following questions?
Que 1: How do I handle the events in the client of such an Active x control, if created it dynamically?
Que 2: How do I create one Active X control from another Active X control. How do I make them communicate through events?
Looking forward to get the valuable guidance from you ( if possible, I would appreciate your sending the sample source code)
Yours Sincerely,
Sunil Gade
Originally posted by: Narayan Bhagavatula
I want to dynamically create a control from another ActiveX Control (e.g MSFlexGrid), should I create the other control with a simple DLL or make my own custom ActiveX control which is dynamically created when desired ? Which is more coding, flexible etc. etc. ?
thanks,
Narayan Bhagavatula
Reply