Using wxWidget in an ActiveX control: VC2005+wxWidget 2.8.10 Topic is solved

Do you have a typical platform dependent issue you're battling with ? Ask it here. Make sure you mention your platform, compiler, and wxWidgets version.
Post Reply
grifos
In need of some credit
In need of some credit
Posts: 3
Joined: Mon Jun 07, 2010 11:50 am

Using wxWidget in an ActiveX control: VC2005+wxWidget 2.8.10

Post by grifos » Mon Jun 07, 2010 12:40 pm

Hi,
I'm currently working on a project where I need to make a kind of ActiveX wrapper around a component using wxWidget (this component is in a dll).
In fact the ActiveX control should be able to display the component (which is a wxScrolledWindow) right inside itself.
So i must make the ActiveX control the parent of the wxScrolledWindow.
I know this issue has been discussed a lot already but i can't seem to make it work all right
I tried many things like this example: http://wiki.wxwidgets.org/WxWidgets_For_MFC_Programmers

Here is a small code example of what I want to do:

I'll first describe the class used:

ActiveXCtrl: which is the ActiveX class inherit from COleControl.

MyCustomScrolledWindow : The component I want to display in the ActiveX control.

ActiveXWxApp: The ddl containing the component does not declare a wxApp (and I can't modify this dll), so this class is used in the ActiveX.

So here is an example

Code: Select all


class ActiveXCtrl: public COleControl
{
private:
	wxWindow * m_pActiveXWindow;
	MyCustomScrolledWindow *  m_pCustomScrolledWindow;
public:
/*
*   Stuff
*/
ActiveXCtrl();
InitFinished();
OnDraw();
ForceRedraw();
/*
*   Stuff again 
*/
	
};

// Constructor
ActiveXCtrl::ActiveXCtrl()
{
   // We declare the wxApp
   m_pWxApp = new CActiveXWxApp();
   m_pActiveXWindow = NULL;
   m_pCustomScrolledWindow = NULL;
}

// Intialisation finished (so we have a valid HWND for the activeX
void ActiveXCtrl::InitFinished()
{
   m_pActiveXWindow = new wxWindow();                             // We create a dummy window
   m_pActiveXWindow->SetHWND((WXHWND)this->m_hWnd);               // We set the ActiveX HWND
   m_pActiveXWindow->AdoptAttributesFromHWND();
   m_pActiveXWindow->Reparent(m_pWxApp->GetTopWindow());
   
   
   // The sizer
   wxBoxSizer* boxSizer = new wxBoxSizer( wxVERTICAL );
   m_pActiveXWindow->SetSizer(boxSizer);
   
   m_pCustomScrolledWindow = DLL::Instance()->CreateCustomScrolledWindow(m_pActiveXWindow); // We create the custom window with the parent
   
   boxSizer->Add( m_pCustomScrolledWindow, 1, wxALL|wxEXPAND, 0 );
}

// Method called when window paint event are received
void ActiveXCtrl::OnDraw()
{
	m_pActiveXWindow->Update();
}

// Method that force the redraw of all the content of the wxScrolledWindow (shouldn't be called often)
void ActiveXCtrl::ForceRedraw()
{
   m_pCustomScrolledWindow->RedrawAll();
}	
I manage to create the MyCustomScrolledWindow object successfully with the ActiveX as the parent, however no events seemed to be received be the component (size,paint,etc...)
The OnDraw method has no effect and does not redraw the content of the wxScrolledWindow (the functionnality is implemented proprelly thought)
I only managed to draw the content by calling the ForceRedraw() method which calls a MyCustomScrolledWindow internal method that draw the content (whith the use of wxGraphicContext and a MemoryDC + blit)
The content of the scrolledWindow is not resized according to the size of the parent ActiveX control, it takes all the place it needs. So the scroll bars are not displayed.
I tried without the sizer, but same result. I also tried to change the size of the m_pCustomScrolledWindow right after it's creation, but that didn't do anything.

I hope anyone can help me with this, because I'm lost right knwo xD

Regards All

Edited:

Code: Select all

/*!
*   wxApp already defined in the COleControlModule derived class (with InitInstance and ExitInstance
*/

// ActiveXCtrl.h
class ActiveXCtrl: public COleControl 
{ 
private: 
   wxWindow * m_pActiveXWindow; 
   MyCustomScrolledWindow *  m_pCustomScrolledWindow; 
public: 
/* 
*   Stuff 
*/ 
ActiveXCtrl(); 
InitFinished(); 
OnDraw();
afx_msg void OnPaint();
afx_msg void OnSize(UINT nType, int cx, int cy);
afx_msg void OnMove(int x, int y);
ForceRedraw(); 
/* 
*   Stuff again 
*/ 
        
}; 


//ActiveXCtrl.cpp
// Constructor 
ActiveXCtrl::ActiveXCtrl() 
{ 
   m_pActiveXWindow = NULL; 
   m_pCustomScrolledWindow = NULL; 
} 

// Intialisation finished (so we have a valid HWND for the activeX 
void ActiveXCtrl::InitFinished() 
{ 
   m_pActiveXWindow = new wxWindow();                             // We create a dummy window 
   m_pActiveXWindow->SetHWND((WXHWND)this->m_hWnd);               // We set the ActiveX HWND 
   m_pActiveXWindow->AdoptAttributesFromHWND(); 
   wxGetApp().SetTopWindow(m_pActiveXWindow);
    
   m_pCustomScrolledWindow = DLL::Instance()->CreateCustomScrolledWindow(m_pActiveXWindow); // We create the custom window with the parent 
   
} 

// Method called when window paint event are received 
void ActiveXCtrl::OnDraw() 
{ 
   return;
} 

// Method that force the redraw of all the content of the wxScrolledWindow (shouldn't be called often) 
void ActiveXCtrl::ForceRedraw() 
{ 
   m_pCustomScrolledWindow->RedrawAll(); 
}

// On paint event
afx_msg void ActiveXCtrl::OnPaint()
{
   CPaintDC dc(this); // device context for painting
   if ( NULL != m_pCustomScrolledWindow )
   {
       m_pCustomScrolledWindow->Update();
   }
}

// On size event
afx_msg void ActiveXCtrl::OnSize(UINT nType, int cx, int cy)
{
   __super::OnSize(nType, cx, cy);

   if ( NULL != m_pCustomScrolledWindow )
   {
      RECT rectActiveX;
      this->GetWindowRect(&rectActiveX); 
      m_pCustomScrolledWindow->SetSize(0,0, rectActiveX.right - rectActiveX.left, rectActiveX.bottom - rectActiveX.top );
      m_pCustomScrolledWindow->Layout();
   }
}

// On move event
afx_msg void ActiveXCtrl::OnMove(int x, int y)
{
	__super::OnMove(x, y);

   if ( NULL != m_pCustomScrolledWindow )
   {
      RECT rectActiveX;
      this->GetWindowRect(&rectActiveX); 
      m_pCustomScrolledWindow->SetSize(0,0, rectActiveX.right - rectActiveX.left, rectActiveX.bottom - rectActiveX.top );
      m_pCustomScrolledWindow->Layout();
   }
}  
Grifos
Last edited by grifos on Tue Jun 08, 2010 3:19 pm, edited 1 time in total.

grifos
In need of some credit
In need of some credit
Posts: 3
Joined: Mon Jun 07, 2010 11:50 am

Post by grifos » Tue Jun 08, 2010 11:41 am

I managed to make it work right,
The code was right until

Code: Select all

m_pActiveXWindow->Reparent(m_pWxApp->GetTopWindow());
that should be replaced by

Code: Select all

m_pWxApp->SetTopWindow(m_pActiveXWindow);
Plus the OnDraw method should not be used for drawing, but the a method should mapped to the WM_PAINT event.
Also the WM_MOVE and WM_SIZE event should be mapped and the size and position of the m_pActiveXWindow child (m_pCustomScrolledWindow) should be changed manually.

Finally a wxApp should be declared with IMPLEMENT_APP_NO_MAIN.
I've edited the previous post to show all the changes
Regards all.

grifos
In need of some credit
In need of some credit
Posts: 3
Joined: Mon Jun 07, 2010 11:50 am

Post by grifos » Fri Jun 11, 2010 9:27 am

Hi,
I have a new problem that I don't manage to solve.
The previous ActiveX works just fine, however, when I quit the ActiveX (or unload it), a thread is still running, so the activeX win't stop.
I think it is due to the event loop created by the wxApp and I don't know how to stop it in a clean way.

Just for reminder this is how I create the wxApp and how I destroy it:

Code: Select all

// In the ActiveXCtrl constructor
int argc = 0;
char ** argv = NULL;
m_pApp = new wxApp();
wxApp::SetInstance(m_pApp);
wxEntryStart(argc,argv);
m_pApp->OnInit();


// In the ActiveXCtrl destructor
m_pApp->OnExit();
m_pApp->CleanUp();
wxApp::SetInstance(NULL);
delete m_pApp;
wxModule::CleanUpModules();
I can't use wxEntryCleanup because the DoPostCommonCleanUp function crash the App

Edit:
Problem solved seems to be a MFC issue in DEBUG mode

Regards

anthillbpt
In need of some credit
In need of some credit
Posts: 1
Joined: Tue Jul 19, 2011 5:35 am

Re: Using wxWidget in an ActiveX control: VC2005+wxWidget 2.

Post by anthillbpt » Tue Jul 19, 2011 5:44 am

Hi grifos,
Can you share a sample program where activeX control uses the wxWidgets library or an activeX component which will launch an app MyApp

class MyApp: public wxApp
{
virtual bool OnInit();
};

I tried to use ATL to create and ActiveX component and use the wxWidgets library but in vain. I could not compile the code at all. Could you help me on this, as I can see that you are able to create the activeX component using the wxWidgets library.

Thanks in advance,
bpt

Elmi
Super wx Problem Solver
Super wx Problem Solver
Posts: 293
Joined: Thu Mar 12, 2009 3:23 pm
Location: Germany
Contact:

Re: Using wxWidget in an ActiveX control: VC2005+wxWidget 2.

Post by Elmi » Thu Jan 30, 2014 2:11 pm

While this thread is quite old it is still interesting and top-hit in Google when somebody searches for a wxwidgets/ActiveX solution. Now I found a fully working example in wxWidgets mailing list demonstrating how to create an ActiveX (.OCX) that itself accesses a wxWidgets application which is encapsulated in an external DLL. Please find this example attached.
Attachments
wxActiveX.zip
ActiveX example
(18.77 KiB) Downloaded 127 times

Post Reply