This is a very simple question: how to properly build a DLL with MDI support?
wx-2.8 MSW/GTK, MSVC/gcc
This is what I have so far:
for static linking - in the DLL project:
/nologo /MDd /W4 /Gm /GR /GX /Zi /Od /I "c:\wxMSW-2.8.1\wxWidgets-2.8.1\include" /I "c:\wxMSW-2.8.1\wxWidgets-2.8.1\lib\vc_lib\mswd" /I "e:\home\igor\real_project\Dialogs\src\libdialogs" /I "e:\home\igor\real_project\Dialogs\src\libdialogs\res" /I "e:\home\igor\real_project\apppainter\src\libapppainter\res" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_USRDLL" /D "WXMAKINGDLL" /D "DLL_EXPORTS" /Fp"Debug/apppainter.pch" /YX /Fo"Debug/" /Fd"Debug/" /FD /c
wxmsw28d_core.lib wxbase28d.lib wxmsw28d_media.lib wxtiffd.lib wxjpegd.lib wxpngd.lib wxzlibd.lib wxregexd.lib wxmsw28d_xrc.lib wxexpatd.lib comctl32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib rpcrt4.lib winmm.lib "c:\Program Files\DevStudio\VC\lib\winspoof.lib" /nologo /subsystem:windows /dll /incremental:no /pdb:"Debug/apppainter.pdb" /debug /machine:I386 /out:"Debug/apppainter.dll" /implib:"Debug/apppainter.lib" /libpath:"c:\wxMSW-2.8.1\wxWidgets-2.8.1\lib\vc_lib"
for static linking - in the .exe project
/nologo /MDd /W4 /Gm /GR /Zi /Od /I "c:\wxMSW-2.8.1\wxWidgets-2.8.1\include" /I "c:\wxMSW-2.8.1\wxWidgets-2.8.1\lib\vc_lib\mswd" /I "e:\home\igor\real_project\apppainter\src\libapppainter" /I "e:\home\igor\real_project\Dialogs\src\libdialogs" /I "e:\home\igor\real_project\Dialogs\src\libdialogs\res" /I "e:\home\igor\real_project\library\src" /D "WIN32" /D "_DEBUG" /D "__WXMSW__" /D "__WXDEBUG__" /D "_WINDOWS" /D "NOPCH" /Fo"vc_mswd\docview/" /Fd"vc_mswd\docview.pdb" /FD /EHsc /c
wxmsw28d_core.lib wxbase28d.lib wxmsw28d_media.lib wxtiffd.lib wxjpegd.lib wxpngd.lib wxzlibd.lib wxregexd.lib wxexpatd.lib kernel32.lib user32.lib gdi32.lib comdlg32.lib winspool.lib winmm.lib shell32.lib comctl32.lib ole32.lib oleaut32.lib uuid.lib rpcrt4.lib advapi32.lib wsock32.lib odbc32.lib library.lib /nologo /subsystem:windows /incremental:yes /pdb:"vc_mswd/docview.pdb" /debug /machine:I386 /out:"vc_mswd\docview.exe" /libpath:"c:\wxMSW-2.8.1\wxWidgets-2.8.1\lib\vc_lib" /libpath:"e:\home\igor\real_project\library\src\Debug"
for dynamic linking - in the DLL project:
/nologo /MDd /W4 /Gm /GR /Zi /Od /I "c:\wxMSW-2.8.1\wxWidgets-2.8.1\include" /I "c:\wxMSW-2.8.1\wxWidgets-2.8.1\lib\vc_lib\mswd" /I "e:\home\igor\real_project\Dialogs\src\libdialogs" /I "e:\home\igor\real_project\Dialogs\src\libdialogs\res" /I "e:\home\igor\real_project\apppainter\src\libapppainter\res" /D "WIN32" /D "_DEBUG" /D "__WXMSW__" /D "__WXDEBUG__" /D "WXUSINGDLL" /D "DLL_EXPORTS" /Fo"apppaint/" /Fd"apppaint/" /FD /c
wxmsw28d_core.lib wxbase28d.lib wxmsw28d_media.lib wxtiffd.lib wxjpegd.lib wxpngd.lib wxzlibd.lib wxregexd.lib wxmsw28d_xrc.lib wxexpatd.lib comctl32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib rpcrt4.lib winmm.lib "c:\Program Files\DevStudio\VC\lib\winspoof.lib" /nologo /subsystem:windows /dll /incremental:yes /pdb:"apppaint/apppainter.pdb" /debug /machine:I386 /out:"apppaint/apppainter.dll" /implib:"apppaint/apppainter.lib" /libpath:"c:\wxMSW-2.8.1\wxWidgets-2.8.1\lib\vc_dll"
In the DLL there is a following code:
Code: Select all
IMPLEMENT_APP_NO_MAIN(apppainterapp)
#ifdef __WXMSW__
WXDLLIMPEXP_BASE void wxSetInstance( HINSTANCE hInst );
BOOL APIENTRY DllMain( HANDLE hModule, DWORD fdwReason, LPVOID lpReserved)
{
lpReserved = lpReserved;
int argc = 0;
char **argv = NULL;
switch( fdwReason )
{
case DLL_PROCESS_ATTACH:
#ifdef WXUSINGDLL
wxInitialize();
#else
wxSetInstance( (HINSTANCE) hModule );
wxEntryStart( argc, argv );
if( !wxTheApp || !wxTheApp->CallOnInit() )
{
wxEntryCleanup();
if( wxTheApp )
wxTheApp->OnExit();
return FALSE;
}
#endif
break;
case DLL_PROCESS_DETACH:
#ifdef WXUSINGDLL
wxUninitialize();
#else
if( wxTheApp )
wxTheApp->OnExit();
wxEntryCleanup();
#endif
break;
}
return TRUE;
}
#endif
extern "C" WXEXPORT void ApplicationPainter( wxDocManager *docManager, wxWindow *parent )
{
#ifdef __WXMSW__
wxGetApp().SetTopWindow( parent );
#endif
(void) new wxDocTemplate( docManager, _T( "Application" ), _T( "*.abl" ), _T( "" ), _T( "abl" ), _T( "Application Library Builder" ), _T( "Application View" ), CLASSINFO( CApplicationDocument ), CLASSINFO( CApplicationView ), wxDEFAULT_TEMPLATE_FLAGS );
}
bool CApplicationView::OnCreate( wxDocument *doc, long WXUNUSED( flags ) )
{
m_toolbar = NULL;
int width, height, widthMain, heightMain;
wxMDIParentFrame *parent = (wxMDIParentFrame *) wxGetApp().GetTopWindow();
parent->GetClientSize( &widthMain, &heightMain );
m_frame = new wxDocMDIChildFrame( doc, this, parent, wxID_ANY, _T( "Application" ), wxPoint( 0, 0 ), wxSize( widthMain - 2, heightMain - 2 ), wxDEFAULT_FRAME_STYLE | wxNO_FULL_REPAINT_ON_RESIZE );
m_frame->GetClientSize( &width, &height );
m_canvas = new CCanvas( this, m_frame, wxPoint( 0, 0 ), wxSize( width, height ), wxALWAYS_SHOW_SB | wxHSCROLL | wxVSCROLL );
m_frame->SetTitle( _T( "Application" ) );
m_frame->Show( true );
Activate( true );
CreateViewToolbar();
return true;
}
void CApplicationView::CreateViewToolbar()
{
ToolbarSetupStruct ts;
long style;
wxSize size = ((wxMDIParentFrame *) wxGetApp().GetTopWindow())->GetClientSize();
if( ts.m_isShown )
{
m_toolbar = new wxToolBar( (wxMDIParentFrame *) wxGetApp().GetTopWindow(), wxID_ANY, wxDefaultPosition, wxDefaultSize, style, _T( "PainterBar1" ) );
m_toolbar->AddTool( wxID_NEWOBJECT, _T( "New" ), wxBitmap( new_obj ), wxNullBitmap, wxITEM_NORMAL, _T( "New" ), _T( "Create a New Application" ) );
m_toolbar->AddTool( wxID_OPENOBJECT, _T( "Open" ), wxBitmap( open_obj ), wxNullBitmap, wxITEM_NORMAL, _T( "Open" ), _T( "Open an Exisiting Application" ) );
m_toolbar->AddTool( wxID_SAVEOBJECT, _T( "Save" ), wxBitmap( save ), wxNullBitmap, wxITEM_NORMAL, _T( "Save" ), _T( "Save an Application" ) );
m_toolbar->AddTool( wxID_SCRIPT, _T( "Script" ), wxBitmap( script ), wxNullBitmap, wxITEM_NORMAL, _T( "Script" ), _T( "Create a Script" ) );
m_toolbar->AddTool( wxID_PROPERTIES, _T( "Properties" ), wxBitmap( properties ), wxNullBitmap, wxITEM_NORMAL, _T( "Properies" ), _T( "Edit Application Properties" ) );
m_toolbar->AddTool( wxID_CLOSE, _T( "Close" ), wxBitmap( exit_prog ), wxNullBitmap, wxITEM_NORMAL, _T( "Close" ), _T( "Close a Painter" ) );
m_toolbar->Realize();
int offset;
if( ts.m_orientation == 1 )
{
m_toolbar->SetSize( 0, 0, wxDefaultCoord, size.y );
offset = m_toolbar->GetSize().x;
m_frame->SetSize( offset, 0, size.x - offset, size.y );
}
if( ts.m_orientation == 2 )
{
m_toolbar->SetSize( 0, 0, size.x, wxDefaultCoord );
offset = m_toolbar->GetSize().y;
m_frame->SetSize( 0, offset, size.x, size.y - offset );
}
if( ts.m_orientation == 3 )
{
m_toolbar->SetSize( size.x - m_toolbar->GetSize().x, 0, size.x, size.y );
m_frame->SetSize( 0, 0, size.x - m_toolbar->GetSize().x, size.y );
}
if( ts.m_orientation == 4 )
{
m_toolbar->SetSize( 0, size.y - m_toolbar->GetSize().y, size.x, m_toolbar->GetSize().y );
m_frame->SetSize( 0, 0, size.x, size.y - m_toolbar->GetSize().y );
}
// DoLayout( ts.m_orientation );
}
else
m_frame->SetSize( 0, 0, size.x, size.y );
}
void CApplicationView::DoLayout( short orient )
{
if( m_toolbar )
{
wxSize size = ((wxMDIParentFrame *) wxTheApp->GetTopWindow())->GetClientSize();
int offset;
if( orient == 1 )
{
m_toolbar->SetSize( 0, 0, wxDefaultCoord, size.y );
offset = m_toolbar->GetSize().x;
m_frame->SetSize( offset, 0, size.x - offset, size.y );
}
if( orient == 2 )
{
m_toolbar->SetSize( 0, 0, size.x, wxDefaultCoord );
offset = m_toolbar->GetSize().y;
m_frame->SetSize( 0, offset, size.x, size.y - offset );
}
if( orient == 3 )
{
offset = m_toolbar->GetSize().x;
m_toolbar->SetSize( size.x - offset, 0, size.x, size.y );
m_frame->SetSize( 0, 0, size.x - offset, size.y );
}
if( orient == 4 )
{
offset = m_toolbar->GetSize().y;
m_toolbar->SetSize( 0, size.y - offset, size.x, offset );
m_frame->SetSize( 0, 0, size.x, size.y - offset );
}
}
else
{
wxSize size = ((wxMDIParentFrame *) wxTheApp->GetTopWindow())->GetClientSize();
m_frame->SetSize( 0, 0, size.x, size.y );
}
}
Code: Select all
bool AppBuilderapp::OnInit()
{
#ifdef __WXMSW__
m_config = new wxConfig( _T( "AppBuilder" ) );
#else
m_config = new wxConfig( _T( "appbuilder" ) );
#endif
m_docManager = new wxDocManager;
frame = new CMainWindow( (wxDocManager *) m_docManager, (wxFrame *) NULL, wxT( "ApplicationBuilder" ), wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_STYLE | wxNO_FULL_REPAINT_ON_RESIZE | wxFRAME_NO_WINDOW_MENU
/*#ifdef __WXMSW__
| wxMAXIMIZE
#endif*/
);
#ifdef __WXGTK__
if( m_painterLib.Load( _T( "/mnt/usb/projects/apppainter/debug/src/libapppainter/.libs/libapppainter.so" ) ) )
#elif defined __WXMSW__
#ifdef WXUSINGDLL
if( m_painterLib.Load( _T( "E:\\home\\igor\\real_project\\apppainter\\src\\libapppainter\\apppaint\\apppainter.dll" ) ) )
#else
if( m_painterLib.Load( _T( "E:\\home\\igor\\real_project\\apppainter\\src\\libapppainter\\Debug\\apppainter.dll" ) ) )
#endif
#endif
{
Painter func = (Painter) m_painterLib[0].GetSymbol( _T( "ApplicationPainter" ) );
if( !func )
{
wxMessageBox( _T( "Error loading dynamic link library. Exiting" ) );
return FALSE;
}
else
func( m_docManager, frame );
}
else
{
if( m_painterLib.IsLoaded() )
{
wxMessageBox( _T( "Library is already loaded!" ) );
m_painterLib.Unload();
return TRUE;
}
else
{
wxMessageBox( _T( "Can't find a library to continue execution! Exiting..." ) );
return TRUE;
}
}
}
void CMainWindow::OnSize( wxSizeEvent &event)
{
wxSize size = GetClientSize();
int offset;
bool foundChild = false, foundTb = false;
wxDocMDIChildFrame *child = NULL;
wxToolBar *tb = NULL;
for( wxWindowList::compatibility_iterator iter = GetChildren().GetFirst(); iter; iter = iter->GetNext() )
{
wxWindow *current = iter->GetData();
if( !foundChild )
{
child = dynamic_cast<wxDocMDIChildFrame*>( current );
if( child )
foundChild = true;
}
if( !foundTb )
{
tb = dynamic_cast<wxToolBar*>( current );
if( tb && tb->GetName() == _T( "PainterBar1" ) )
foundTb = true;
}
}
if( child && tb )
{
int style = tb->GetWindowStyle();
if( style & wxTB_VERTICAL )
{
tb->SetSize( 0, 0, wxDefaultCoord, size.y );
offset = tb->GetSize().x;
child->SetSize( offset, 0, size.x - offset, size.y );
}
if( style & wxTB_HORIZONTAL )
{
tb->SetSize( 0, 0, size.x, wxDefaultCoord );
offset = tb->GetSize().y;
child->SetSize( 0, offset, size.x - 2, ( size.y - offset ) - 2 );
}
if( style & wxTB_RIGHT )
{
offset = tb->GetSize().x;
tb->SetSize( size.x - offset, 0, size.x, size.y );
child->SetSize( 0, 0, size.x - offset, size.y );
}
if( style & wxTB_BOTTOM )
{
offset = tb->GetSize().y;
tb->SetSize( 0, size.y - offset, size.x, offset );
child->SetSize( 0, 0, size.x, size.y - offset );
}
}
else if( !tb )
event.Skip();
}
When I use a dynamic (DLL build) linking the program crashes in the CApplicationView::OnCreate() when trying to get the pointer to CMainFrame.
On Linux running dll build of wx it works, but the positioning of the child frame is incorrect.
Is there a way to maybe fix a dynamic build or better yet fix both configuration so they both run properly.
Thank you and sorry for the long posting.