TheSwamp

Code Red => ARX Programming => Topic started by: It's Alive! on January 08, 2010, 11:09:02 PM

Title: Bricscad and wxWidgets
Post by: It's Alive! 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
Title: Re: Bricscad and wxWidgets
Post by: It's Alive! 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();
  }
};
Title: Re: Bricscad and wxWidgets
Post by: It's Alive! on January 08, 2010, 11:15:35 PM
and  8-)
Title: Re: Bricscad and wxWidgets
Post by: gskelly 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.
Title: Re: Bricscad and wxWidgets
Post by: gskelly 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
Title: Re: Bricscad and wxWidgets
Post by: It's Alive! 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
Title: Re: Bricscad and wxWidgets
Post by: It's Alive! 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 ));
}

Title: Re: Bricscad and wxWidgets
Post by: Kerry on January 09, 2010, 09:35:14 PM

Modal and modeless Dan ?
Title: Re: Bricscad and wxWidgets
Post by: It's Alive! on January 09, 2010, 09:44:49 PM
yes sir

Title: Re: Bricscad and wxWidgets
Post by: It's Alive! 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
Title: Re: Bricscad and wxWidgets
Post by: It's Alive! 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:
Title: Re: Bricscad and wxWidgets
Post by: gskelly 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...

Title: Re: Bricscad and wxWidgets
Post by: It's Alive! 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  :-)
Title: Re: Bricscad and wxWidgets
Post by: It's Alive! 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) ;
}
Title: Re: Bricscad and wxWidgets
Post by: gskelly 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.
Title: Re: Bricscad and wxWidgets
Post by: It's Alive! on January 12, 2010, 05:44:44 AM
I could not get the sample to compile either.  :-(
I got the DLL Main code from here.
http://wxforum.shadonet.com/viewtopic.php?t=24401&highlight=autocad
Title: Re: Bricscad and wxWidgets
Post by: gskelly on January 12, 2010, 12:12:18 PM
Ok, I got this to compile at lunch today...

I had asked an additional question regarding wx compilation:
Quote
I wonder how critical it will be for me to have the identical settings you have?
i.e. Things like:
wxUSE_UNICODE
wxUSE_WCHAR_T
wxUSE_STREAMS
wxUSE_STL
wxUSE_STD_IOSTREAM
wxUSE_STD_STRING
and so on...

with the answer:
Quote
The settings you listed are all enabled on our side.
I think for most of them, possibly all, we use the default setting from WxWidgets.
If you need to make sure for other settings, just ask, I can check it here.

So I re-compiled my wxWidgets 2.8.10 as a unicode dll without treating wchar_t as a builtin type (/Zc:wchar_t-) and it works to create a wxdialog in a BRX module with:

Code: [Select]
#include "wx/wxprec.h"

void cmdWxWidgets()
{
    wxDialog dialog(NULL,wxID_ANY,_T("Wx Dialog"));
    dialog.ShowModal();
}

but remember to change the wchar_t setting for the source file that compiles against wx. I don't think it will be possible to mix BRX code and wx code in the same source file (if I understand everything correctly).

(edit) So the result is a BRX module that is dynamically linked to wx and is resolved to the dll's included with Bricscad. Next is to see if the messages are working right but I'm out of time for now.
Title: Re: Bricscad and wxWidgets
Post by: It's Alive! on January 13, 2010, 12:04:22 AM
Add a button and see if it works  :-) 
here is my solution and ARX&BRX bins for 07 and v10 using static libraries.
the command is doit

Title: Re: Bricscad and wxWidgets
Post by: It's Alive! on January 15, 2010, 09:30:06 PM
.... Next is to see if the messages are working right ....

Any luck with this?
Title: Re: Bricscad and wxWidgets
Post by: frtfff on January 16, 2010, 04:12:44 AM
 :kewl:
Title: Re: Bricscad and wxWidgets
Post by: gskelly on January 16, 2010, 07:59:16 PM
Sorry for the delay... I did create a dialog with a couple of buttons that responded but it is making Bricscad unstable. I am gussing it is because I do not have the identical configuration when I compile my wx to link against.

I have a feeling that unless Bricsys was to provide the configuration (or even better a pre-compiled wx dev environment) there will be a lot of crashing Bricscad this way. I just can't find enough time to play! :-(
Title: Re: Bricscad and wxWidgets
Post by: It's Alive! on January 17, 2010, 05:16:24 AM
Thanks for testing this, I think we will just have to wait & see the roadmap Bricsys lays out for Linux plug-ins done in c++.
Title: Re: Bricscad and wxWidgets
Post by: Swift on February 02, 2010, 07:43:53 AM
Wow Daniel I tried to do this a few years back and never got it to work. I'll be looking at this tonight!
Title: Re: Bricscad and wxWidgets
Post by: It's Alive! on February 02, 2010, 07:53:44 AM
I thought I saw one of your posts over at the widgets forum dated many moons ago. let me know if you have any questions while this is fresh in my head  :laugh:
Title: Re: Bricscad and wxWidgets
Post by: avico on March 07, 2010, 03:57:00 PM
Hi, forum,

read this:

How do I make a dll for use with wxWidgets?

"
// wxDLL is a simple DLL which demonstrates how to use
// wxWindows in a DLL which is called from another
// application (not using wxWindows)
"

http://wxforum.shadonet.com/viewtopic.php?p=5964#5964 (http://wxforum.shadonet.com/viewtopic.php?p=5964#5964)

Title: Re: Bricscad and wxWidgets
Post by: It's Alive! on March 08, 2010, 12:08:36 AM
Hi avico!

I think this is what I ended up using for Autocad.
Welcome to theSwamp  :-)
Title: Re: Bricscad and wxWidgets
Post by: avico on March 08, 2010, 04:06:24 PM
Hi Daniel.

More about this in:

http://groups.google.com/group/wx-users/browse_thread/thread/dbf22597ac119386 (http://groups.google.com/group/wx-users/browse_thread/thread/dbf22597ac119386)
http://forums.wxwidgets.org/viewtopic.php?t=24401 (http://forums.wxwidgets.org/viewtopic.php?t=24401)

And a question (no related for wxwidgets)

How to load opendcl runtime in bricscad ?
I have tested openDCL 6.0.0.23 in briscad V10.2.11 (spanish version) and not work.  OpenDCL.9.brx and OpenDCL.10.brx not load

this image http://www.intellicad.net/photo/bricscad-opendcl?xg_source=activity (http://www.intellicad.net/photo/bricscad-opendcl?xg_source=activity) as a great notice.
Title: Re: Bricscad and wxWidgets
Post by: It's Alive! on March 08, 2010, 08:24:52 PM
You are right! it does not load.  :-o
I will post a message on OpenDCL's site   
Title: Re: Bricscad and wxWidgets
Post by: It's Alive! on March 08, 2010, 08:29:08 PM
Keep an eye on this thread
http://www.opendcl.com/forum/index.php?topic=1197.0
 
Title: Re: Bricscad and wxWidgets
Post by: It's Alive! on March 09, 2010, 04:32:21 AM
avico,

See Owen's responce here;
http://www.opendcl.com/forum/index.php?topic=1197.0

PM me if you need a copy that works with your version  :-)
Title: Re: Bricscad and wxWidgets
Post by: pkohut on August 31, 2010, 04:58:34 AM
There are a number of ways to instance controls in WxWidgets. The docs and most online tutorials show a method which uses event tables and EVT_-macros, very much like we do in MFC. However, there is a newer, more capable method using Connect(...), which is "dynamic event routing",  http://wiki.wxwidgets.org/Example_Of_Using_Connect_For_Events. If you use wxWidgets 2.9 or above you can switch to using wxEvtHandler::Bind instead of Connect (http://wiki.wxwidgets.org/Events  see: Using Connect)

In the first link, "Example of Using Connect for Events", put a dozen or so controls on the form and the code will get unwieldy. So I would suggest looking at wxFormBuilder (a GUI builder), and the code it will generate for you automatically (very nice).

Basically it will create a base class, with all the initialization code generated (you don't touch this code ***), and you derive from the base to implement any special behaviors or overrides. If later a control needs to be added or removed, just load the "*.fbp" file into wxFormBuilder, make the change and save. The newly generated base class files will overwrite the older ones.

*** Like with must GUI builders and code generators, you hit a wall and they can't do something out of the box. For me I wanted some of the new wxAux controls, and resorted to editing the base class by hand to get the new functionality. Once edited that way all future edits must be done by hand as well, otherwise regenerating the base class would mean losing code.  So, up front I try and get wxFormBuild to do as much work as possible before applying hand edits, afterward changes are mostly easy one or two off changes.  Now, having sat back to write this post and reflect, I should just write another layer of inheritance to initialize any controls that wxFormBuilder can't handle, and let it handle the base class for all the others.  (Full wxAux support is available in upcoming wxFormbuilder 3.2)

The latest WxFormBuilder 3.1 links are at http://wxformbuilder.org/?page_id=27.
Title: Re: Bricscad and wxWidgets
Post by: It's Alive! on August 31, 2010, 07:52:14 AM
I will have to take a look at wxFormBuilder, any tips on persisting dialog data?
Title: Re: Bricscad and wxWidgets
Post by: pkohut on August 31, 2010, 08:18:37 AM
I will have to take a look at wxFormBuilder, any tips on persisting dialog data?

Not off the top, but I think it might be built into the framework.
Title: Re: Bricscad and wxWidgets
Post by: pkohut on August 31, 2010, 10:13:24 AM
I will have to take a look at wxFormBuilder, any tips on persisting dialog data?

Not off the top, but I think it might be built into the framework.

I think I misunderstood your question. If not here's the link
http://docs.wxwidgets.org/trunk/overview_persistence.html
Title: Re: Bricscad and wxWidgets
Post by: It's Alive! on August 31, 2010, 11:13:16 AM
That's it! you're awesome!  8-)
Title: Re: Bricscad and wxWidgets
Post by: jgr on September 01, 2010, 11:02:35 PM
wxWidgets can be used by .Net (PInvoke) to create a dockable window in Bricscad?
I've looked at wxnet.sourceforge.net but i do not understand nothing.

Thanks.
Title: Re: Bricscad and wxWidgets
Post by: It's Alive! on September 01, 2010, 11:22:17 PM
I have never tried, I think that would be pretty hard.
Title: Re: Bricscad and wxWidgets
Post by: pkohut on September 02, 2010, 02:34:31 AM
Daniel,

The document below has a simple example of Model-View which handles printing, clipboard, undo/redo. Sections 4 and 5. This is done without using the doc/view framework provided in wxWidgets. So perfect for the type of UI's we may write for Autocad.

http://biolpc22.york.ac.uk/pub/docs/tutorials/MartinBernreuther/wxIntro.pdf

The available document/view framework is explained at
http://docs.wxwidgets.org/2.6/wx_docviewoverview.html