Author Topic: Bricscad and wxWidgets  (Read 11611 times)

0 Members and 1 Guest are viewing this topic.

It's Alive!

  • BricsCAD
  • Needs a day job
  • Posts: 6942
  • AKA Daniel
Bricscad and wxWidgets
« on: January 08, 2010, 11:09:02 PM »
Now that the port of Bricscad to Linux has begun.. Don't get too excited yet, it's still pre alpha. I've been thinking about how to make plug-ins that may work with this new killer app. I know that the ODA libraries are supposed to be platform independent (although there are no DRX SDKs for Linux yet!) , so I am assuming that at some point Bricscad Linux will load DRX modules. I also know that BRX apps may not work as they have been linked to MFC. So we are going to need to use a cross platform GUI like wxWidgets, the same GUI the Bricscad uses.


 Get yourself a copy of wxWidgets, compile it with VC8/Unicode,
Setup VC8 with the necessary paths i.e

$(DRX206)\include
$(BRICSDS)
$(WxW)\include
$(WxW)\msvc\include

and

$(DRX206)\lib\VC8md
$(BRICSDS)
$(WxW)lib\vc_lib

add these preprocessor definitions
DRXWX_EXPORTS
wxUSE_GUI =1
__WXMSW__

for your DLLMain use something like this

Code: [Select]
// __WXMSW__ needs to be defined
#ifdef __WXMSW__
static HANDLE ThreadId;
class WXEXPORT wxDLLApp : public wxApp
{
public:
  bool OnInit()
  {
    //Set the Bricscad main frame as the top level wxWindow
    wxWindow * win = new wxWindow();
    win->SetHWND((WXHWND)sds_getmainhwnd());
    win->AdoptAttributesFromHWND();
    SetTopWindow(win);
    return true;
  }
};
IMPLEMENT_APP_NO_MAIN(wxDLLApp)
DWORD WINAPI ThreadProc(LPVOID lpParameter)
{
  wxApp::SetInstance(new wxDLLApp());
  wxEntry(GetModuleHandle(NULL),NULL,NULL,SW_SHOW);
  return true;
}
BOOL APIENTRY DllMain(HANDLE hModule,
                      DWORD  ul_reason_for_call,
                      LPVOID lpReserved
                      )
{
  switch (ul_reason_for_call)
  {
  case DLL_PROCESS_ATTACH:
    ThreadId = CreateThread(NULL,0,ThreadProc,NULL,0,NULL);
    break;
  case DLL_THREAD_ATTACH: break;
  case DLL_THREAD_DETACH: break;
  case DLL_PROCESS_DETACH:
    wxEntryCleanup();
    break;
  }
  return TRUE;
}
#endif
« Last Edit: January 08, 2010, 11:17:40 PM by Daniel »

It's Alive!

  • BricsCAD
  • Needs a day job
  • Posts: 6942
  • AKA Daniel
Re: Bricscad and wxWidgets
« Reply #1 on: January 08, 2010, 11:12:44 PM »
Next, setup a dialog, I just used a quick sample

Code: [Select]
class CustomDialog : public wxDialog
{
public:
   CustomDialog(const wxString& title , wxWindow* parent = NULL);
};

Code: [Select]
CustomDialog::CustomDialog(const wxString & title , wxWindow* parent/* = NULL*/)
: wxDialog(parent, -1, title, wxDefaultPosition, wxSize(250, 230))
{
  wxPanel *panel = new wxPanel(this, -1);

  wxBoxSizer *vbox = new wxBoxSizer(wxVERTICAL);
  wxBoxSizer *hbox = new wxBoxSizer(wxHORIZONTAL);

  wxStaticBox *st = new wxStaticBox(panel, -1, wxT("Colors"),
    wxPoint(5, 5), wxSize(240, 150));
  wxRadioButton *rb = new wxRadioButton(panel, -1,
    wxT("256 Colors"), wxPoint(15, 30), wxDefaultSize, wxRB_GROUP);

  wxRadioButton *rb1 = new wxRadioButton(panel, -1,
    wxT("16 Colors"), wxPoint(15, 55));
  wxRadioButton *rb2 = new wxRadioButton(panel, -1,
    wxT("2 Colors"), wxPoint(15, 80));
  wxRadioButton *rb3 = new wxRadioButton(panel, -1,
    wxT("Custom"), wxPoint(15, 105));
  wxTextCtrl *tc = new wxTextCtrl(panel, -1, wxT(""),
    wxPoint(95, 105));

  wxButton *okButton = new wxButton(this, -1, wxT("Ok"),
    wxDefaultPosition, wxSize(70, 30));
  wxButton *closeButton = new wxButton(this, -1, wxT("Close"),
    wxDefaultPosition, wxSize(70, 30));

  hbox->Add(okButton, 1);
  hbox->Add(closeButton, 1, wxLEFT, 5);

  vbox->Add(panel, 1);
  vbox->Add(hbox, 0, wxALIGN_CENTER | wxTOP | wxBOTTOM, 10);

  SetSizer(vbox);

}

and now call the new dialog

Code: [Select]
class CommandDRXTest : public OdStaticRxObject < OdEdCommand >
{
public:
  const OdString localName() const { return globalName(); }
  const OdString groupName() const { return DD_T("DRXGLOBAL"); }
  const OdString globalName() const { return DD_T("DRXTest"); }

  //++--
  void execute(OdEdCommandContext* pCmdCtx)
  {
    OdDbCommandContextPtr pDbCmdCtx(pCmdCtx); //++-- downcast for database access
    OdDbUserIO* pDbIO = pDbCmdCtx->dbUserIO(); //++-- User IO
    OdDbDatabasePtr pDb = pDbCmdCtx->database(); //++-- Current database
   
    CustomDialog custom(wxT("CustomDialog"));
    custom.ShowModal();
  }
};

It's Alive!

  • BricsCAD
  • Needs a day job
  • Posts: 6942
  • AKA Daniel
Re: Bricscad and wxWidgets
« Reply #2 on: January 08, 2010, 11:15:35 PM »
and  8-)

gskelly

  • Newt
  • Posts: 185
Re: Bricscad and wxWidgets
« Reply #3 on: January 09, 2010, 09:16:59 AM »
COOL!!! I have wondered how to do that... I know there have been requests for a sample app that contains a wx based interface but I have not found one. I wondered if they were thinking of wrapping the required MFC dependencies or what.

Please forgive my ignorance if this is something obvious but... Does the BRX app run as a plug-in to the Bricscad app? The bits I was able to find (and not really understand) previously indicated the difficult issue is the plug-in has to "become part of the wxApp" to get messages from the wxApp or where your wxDLLApp is derived from wxApp does this mean it is a separate "application" with it's own message queue?

Hope that makes sense... as you can tell the subject is really foggy in my mind.
Bricscad v12

gskelly

  • Newt
  • Posts: 185
Re: Bricscad and wxWidgets
« Reply #4 on: January 09, 2010, 09:26:32 AM »
Do you need to ensure you have the same version of wxWidgets or do you need to keep your own wxWidget dll? I am guessing the latter.

edit: I mean same version as Bricscad is using

Thanks
Bricscad v12

It's Alive!

  • BricsCAD
  • Needs a day job
  • Posts: 6942
  • AKA Daniel
Re: Bricscad and wxWidgets
« Reply #5 on: January 09, 2010, 10:33:11 AM »
I'm not 100% sure about the messages, I was able to assign the Bricscad frame as the top level wxWindow in OnInit() , which the modal dialogs respond to. Before I added the code modal dialogs behaved strange. I will have to look into whether or not  this hooks into the message pump.

I don't know if different versions will cause a problem or not. Bricscad is using dynamic DLLs, where I compiled mine as static libraries. It didn't crash :)

I'll know more once I get into this a little deeper, I just wanted to throw it out there

It's Alive!

  • BricsCAD
  • Needs a day job
  • Posts: 6942
  • AKA Daniel
Re: Bricscad and wxWidgets
« Reply #6 on: January 09, 2010, 08:36:22 PM »
Seems I am able to get events 

Code: [Select]
class CustomDialog : public wxDialog
{
private:
  wxStaticText *st1;
  wxStaticText *st2;
public:
   CustomDialog(const wxString& title);
   void OnMove(wxMoveEvent & event);
};

Code: [Select]

CustomDialog::CustomDialog(const wxString & title)
: wxDialog(NULL,wxID_ANY, title, wxDefaultPosition, wxSize(250, 230))
{
  wxPanel *panel = new wxPanel(this,0,0,100,100,wxBORDER);

  st1 = new wxStaticText(panel, wxID_ANY, wxT("x: "), wxPoint(10, 10));
  st2 = new wxStaticText(panel, wxID_ANY, wxT("y: "), wxPoint(10, 30));

  this->Connect(wxEVT_MOVE, wxMoveEventHandler(CustomDialog::OnMove));
  this->Centre();
}

void CustomDialog::OnMove( wxMoveEvent & event )
{
  wxPoint size = event.GetPosition();
  st1->SetLabel(wxString::Format(wxT("x: %d"), size.x ));
  st2->SetLabel(wxString::Format(wxT("y: %d"), size.y ));
}


Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Bricscad and wxWidgets
« Reply #7 on: January 09, 2010, 09:35:14 PM »

Modal and modeless Dan ?
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

--> Donate to theSwamp<--

It's Alive!

  • BricsCAD
  • Needs a day job
  • Posts: 6942
  • AKA Daniel
Re: Bricscad and wxWidgets
« Reply #8 on: January 09, 2010, 09:44:49 PM »
yes sir


It's Alive!

  • BricsCAD
  • Needs a day job
  • Posts: 6942
  • AKA Daniel
Re: Bricscad and wxWidgets
« Reply #9 on: January 09, 2010, 09:51:04 PM »
Hey, this wxWidgets stuff is like totaly neato, it ought to work with ARX/BRX/SDS etc.
I just need to figure out how to work giving way to the editor window during getXXX functions

It's Alive!

  • BricsCAD
  • Needs a day job
  • Posts: 6942
  • AKA Daniel
Re: Bricscad and wxWidgets
« Reply #10 on: January 10, 2010, 06:58:16 AM »
Yep getting the messaging right seems to be an issue. I was able to get keyboard and mouse events, for some strange reason on-button-clicked events failed.  I was able to get the buttons events to work, when mapping them to mouse_left_up, but it's a total kluge. Oh well   :mrgreen:
« Last Edit: January 10, 2010, 06:08:22 PM by Daniel »

gskelly

  • Newt
  • Posts: 185
Re: Bricscad and wxWidgets
« Reply #11 on: January 10, 2010, 12:39:07 PM »
I think the stuff I read before about loading wx plugins into a wxApp indicated I would use the wx RTTI macros:
Code: [Select]
DECLARE_ABSTRACT_CLASS and IMPLEMENT_ABSTRACT_CLASS
DECLARE_DYNAMIC_CLASS and IMPLEMENT_DYNAMIC_CLASS

and then the loading gets done in the wxApp using wxPluginManager::LoadLibrary() which then get registered by the main wxApp. How that is applied to Bricscad I am not sure. I have asked so hopefully something will come back.

I don't have anything specific noted but I seem to recall others saying it was not safe to create a wxApp in a DLL and load that into a wx based application but I could be wrong or it might have been related to some specific usage.

Man, you seem to burn through learning stuff FAST...

Bricscad v12

It's Alive!

  • BricsCAD
  • Needs a day job
  • Posts: 6942
  • AKA Daniel
Re: Bricscad and wxWidgets
« Reply #12 on: January 10, 2010, 09:00:51 PM »
I have asked so hopefully something will come back.

It would be nice to hear from the horse's mouth what the plans are for the Linux/Mac APIs/SDKs, just so we can plan  :-)

It's Alive!

  • BricsCAD
  • Needs a day job
  • Posts: 6942
  • AKA Daniel
Re: Bricscad and wxWidgets
« Reply #13 on: January 11, 2010, 07:53:47 AM »
Just for Grins, I ran testes with ARX and BRX  (No MFC references)
In Bricscad, I got the same results everything works but the button click events, if you tab through and use the keyboard, everything works.

In Autocad everything I have tested works without a hitch.

I'm going to post this DLL main here for  reference as this seems to work  :laugh:

Code: [Select]
#include "StdAfx.h"
#include "resource.h"
#include <wx/wx.h>

//BRX use #pragma comment(lib, "comctl32.lib")
//
//$(WxW)\include
//$(WxW)\msvc\include
//and
//
//$(WxW)lib\vc_lib
//
//add these preprocessor definitions
//wxUSE_GUI =1
//__WXMSW__
//
//use this for a parent
//wxWindow *win = new  wxWindow();
//win->SetHWND((WXHWND)adsw_acadMainWnd())

class CMyApp : public wxApp
{
public:
  bool OnInit(){
    return true;
  }
};

IMPLEMENT_APP_NO_MAIN(CMyApp)
DECLARE_APP(CMyApp)

extern "C" BOOL WINAPI
DllMain (HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved) {
  //- Remove this if you use lpReserved
  UNREFERENCED_PARAMETER(lpReserved) ;

  if ( dwReason == DLL_PROCESS_ATTACH ) {
    _hdllInstance =hInstance ;
    int argc = 0;
    char** argv = NULL;
    if(!wxEntryStart(argc, argv) || !wxTheApp || !wxTheApp->CallOnInit())
      return FALSE;
  }
  else if ( dwReason == DLL_PROCESS_DETACH ){
    wxEntryCleanup();
  }
  return (TRUE) ;
}

gskelly

  • Newt
  • Posts: 185
Re: Bricscad and wxWidgets
« Reply #14 on: January 11, 2010, 08:38:51 PM »
I have asked so hopefully something will come back.

It would be nice to hear from the horse's mouth what the plans are for the Linux/Mac APIs/SDKs, just so we can plan  :-)

Well, this is what I know so far:
Quote
[UTC 18:13 2009-12-15] What will the development environment be for the new version on Linux?

Will Lisp have the Visual Lisp (ActiveX) capabilities?
Will BRX be available?
Will VBA work?
Will we compile with gcc?
Is it too soon to give these details?

Thanks
Quote
Response

[UTC 08:23 2009-12-16] TM:
Dear Greg,

just a (personal) comment from my side, before official answer ...
Lisp :
- the normal (vl-...) functions will be available
- some (vlax-...) functions will be available
- (vla-...) and (vlax-...) functions will not be available in first implementation,
but I have some ideas and plans to mimic COM under Linux, at least, for
use with (vla-...) and (vlax-...)
but this might take some time
In general, Lisp uses very low-level COM access, and very few functions only;
i.e. all Variants and SafeArrays are processed as VARIANT and SAFEARRAY structures, which are available on Linux (or, in worst case, can simply be defined by Lisp)

Many greetings, Torsten

And:
Quote
[UTC 17:09 2010-01-10] Hello,

I have been wondering for some time if this is possible. I see a little discussion and experimentation going on currently (Daniel Marcotte).

Is there anything (document or sample) you recommend that describes using wxWidgets framework for the BRX app interface.

The reading I have done thus far indicates wxWidgets supports dynamic loading and plugins (ref: wx/dynload.h). Does Bricscad automatically discover wxWidgets classes if we use the wxWidgets RTTI macros?

If not, I am wondering if Bricscad exposes an interface that makes use of wxDynamicLibrary, wxPluginLibrary, wxPluginManager family (or anything else) that enables loading a BRX application with a wxWidgets interface and have it recognized by Bricscad?

Obviously I expect I would need to compile against the same version of wxWidgets.

Thanks,

Greg
Quote
[UTC 17:37 2010-01-11] LDB:
I attached a working sample, based on our brxSample app.
I added a new test command "WX", it creates a modal WxWidgets based dialog.
I did it in a rush, so it's a little dirty still. I only configured it for Bricscad_Release, haven't tried debug.

[FILE UPLOADED]: LDB
[UTC 17:25 2010-01-11] LDB:
One more remark: you might run into trouble with the /Zc:wchar_t setting.
BRX applications require it. While our WxWidgets dlls are build with the /Zc:wchar_t- setting.

[UTC 17:06 2010-01-11] LDB:
We don't officially support this, therefore we have no documentation or samples written by ourselves. All documentation needs to be looked up on the wxwidgets website.

A simple dialog creation should work, like this

wxDialog dialog(NULL,wxID_ANY,_T("Wx Dialog"));
dialog.ShowModal();

Dynamic loading of wx based plugins: we have no data or experience with this.
Bricscad is a WxWidgets client, but nothing is exported with the intention to support wxbased plugins. Feel free to try out what you intend to achieve, but we can not give guarantees.

But I don't think you need all this stuff in order to create a WxWidgets based GUI for your modules. Just try out the lines above, but you will need to spend some time to figure our the necessary includes, libs, and preprocessor symbols. I assume you will need to put __WXMSW__
and WXUSINGDLL, at least.

Our version of WxWidgets is currently 2.8, but there are plans to upgrade.

The sample did not compile for me. I will have to take a look again later when I get a chance.
Bricscad v12