-- +-[ Kontra, Gergely<kgergely@mcl.hu> PhD student Room IB113 ]---------+ | http://www.mcl.hu/~kgergely "Olyan langesz vagyok, hogy | | Mobil:(+36 20) 356 9656 ICQ: 175564914 poroltoval kellene jarnom" | +-- Magyar php mirror es magyar php dokumentacio: http://hu.php.net --+ -------------- next part -------------- A non-text attachment was scrubbed... Name: wxruby.zip Type: application/x-zip-compressed Size: 10605 bytes Desc: not available Url : http://rubyforge.org/pipermail/wxruby-users/attachments/20031113/25f9502e/wxruby.bin
Compiler: Visual Studio 6 wxVersion: wxMSW-2.4.2 wxruby version: 0.1.0 There is a fundamental issue currently with wxPaintDC in wxruby on wxMSW-2.4.x. The paint DC needs to be forcibly destroyed in order for the proper DC commands (the Win32 BeginPaint and EndPaint) to execute. This is easy in C++ because DC are supposed to be created on the stack. However, in wxRuby, DC''s are created dynamically (like all other objects). This wreaks havoc on the display system in Windows (not on any other platform however). My solution was the following modifications in wxruby - 1) I added a ''release'' method to PaintDC. In WxPaintDC::DefineClass, I added the following: VALUE WxPaintDC::Release(VALUE self) { wxPaintDC *ptr; Data_Get_Struct(self, wxPaintDC, ptr); delete ptr; ptr = NULL; DATA_PTR(self) = ptr; return Qnil; } Note this deletes the DC, but leaves the reference pointing to a null pointer. 2) I modified WxDC::free to be the following: void WxDC::free(VALUE self) { wxDC *ptr; Data_Get_Struct(self, wxDC, ptr); if (ptr != NULL) delete ptr; } This ensures the pointer is not deleted twice. 3) I added in wxBufferedPaintDC, which provides a double buffered device context. On OS X, this wasn''t necessary, but Windows flickers like mad if it isn''t there. I wasn''t sure if this was the ''right thing'', since it requires a call to ''release'' whenever you are done with the paint DC and that isn''t very wxWindows like. wxPython uses the BufferedPaintDC, but from what I could tell they encourage ignoring the ''paint'' event completely. I''m including a diff from the CVS. I really didn''t comment any of it, so I can make it look a lot prettier if you like. Nick -------------- next part -------------- Index: dc.cpp ==================================================================RCS file: /var/cvs/wxruby/wxruby/src/dc.cpp,v retrieving revision 1.1.1.1 diff -r1.1.1.1 dc.cpp 13a14>14a16,17> #include "wx/dcbuffer.h" >136c139 < delete ptr; ---> if (ptr != NULL) delete ptr;1125a1129> rb_define_method(rubyClass, "release", VALUEFUNC(WxPaintDC::Release),0);1134a1139,1149> WxPaintDC::Release(VALUE self) > { > wxPaintDC *ptr; > Data_Get_Struct(self, wxPaintDC, ptr); > delete ptr; > ptr = NULL; > DATA_PTR(self) = ptr; > return Qnil; > } > > VALUE1156a1172,1226> > > //------------------------------------------------------------------------------- > void WxBufferedPaintDC::DefineClass() > { > if(rubyClass) > return; > WxWindowDC::DefineClass(); > rubyClass = rb_define_class_under(GetWxModule(),"BufferedPaintDC", WxWindowDC::rubyClass); > rb_define_alloc_func(rubyClass,WxBufferedPaintDC::alloc); > rb_define_singleton_method(rubyClass, "new", VALUEFUNC(new1), 1); > rb_define_method(rubyClass, "initialize", VALUEFUNC(WxBufferedPaintDC::init), 1); > rb_define_method(rubyClass, "release", VALUEFUNC(WxBufferedPaintDC::Release),0); > } > > VALUE > WxBufferedPaintDC::alloc(VALUE self) > { > return Data_Wrap_Struct(self, 0, 0, 0); > } > > VALUE > WxBufferedPaintDC::Release(VALUE self) > { > wxBufferedPaintDC *ptr; > Data_Get_Struct(self, wxBufferedPaintDC, ptr); > delete ptr; > ptr = NULL; > DATA_PTR(self) = ptr; > return Qnil; > } > > VALUE > WxBufferedPaintDC::init(VALUE self,VALUE vwindow) > { > wxWindow *window; > Data_Get_Struct(vwindow, wxWindow, window); > wxBufferedPaintDC *ptr; > Data_Get_Struct(self, wxBufferedPaintDC, ptr); > ptr = new wxBufferedPaintDC(window); > DATA_PTR(self) = ptr; > return self; > } > > VALUE WxBufferedPaintDC::rubyClass; > > class ZAutoDefineWxWxBufferedPaintDC > { > public: > ZAutoDefineWxWxBufferedPaintDC() > { > WxBufferedPaintDC::DefineClass(); > } > }; > static ZAutoDefineWxWxBufferedPaintDC x6;\ No newline at end of file Index: dc.h ==================================================================RCS file: /var/cvs/wxruby/wxruby/src/dc.h,v retrieving revision 1.1.1.1 diff -r1.1.1.1 dc.h 133a134,144> static VALUE Release(VALUE self); > > static void DefineClass(); > static VALUE rubyClass; > }; > > class WxBufferedPaintDC { > public: > static VALUE alloc(VALUE self); > static VALUE init(VALUE self,VALUE vwindow); > static VALUE Release(VALUE self);
Nick wrote:> There is a fundamental issue currently with wxPaintDC in wxruby on > wxMSW-2.4.x. The paint DC needs to be forcibly destroyed in order for > the proper DC commands (the Win32 BeginPaint and EndPaint) to execute.Ah, yes. I remember debugging problems around that in the Windows 3.1 days, when we were using C instead of C++.> This is easy in C++ because DC are supposed to be created on the stack. > However, in wxRuby, DC''s are created dynamically (like all other > objects). This wreaks havoc on the display system in Windows (not on any > other platform however).It sounds like a perfect use for the Ruby "blocks as transactions" pattern. I don''t remember how PaintDC is used from Ruby, but could we hide any misuse of it, by creating some kind of wrapper that you would use like this: def onPaint withPaintDC do | dc | dc.blah dc.foo dc.bar ... end end The withPaintDC method would obtain the wxPaintDC, yield with it, and release it. There would be no other way to obtain a PaintDC in Ruby, because this is the only safe way to work with it. Does that make sense? Can it be done? Kevin
Nick Kral wrote:> Kevin Smith wrote: >> >> def onPaint >> withPaintDC do | dc | >> dc.blah >> dc.foo >> dc.bar >> ... >> end >> end >> > Do you think the withPaintDC method should be part of the Wx module of > the wxPaintDC class? I like the idea of putting it inside the class > because (A) classes are fun, and (B) it goes along with how the File > class'' open method works.Good question. I would have to go back and learn about PaintDC again. I suppose it could be something like: def onPaint PaintDC.open do | dc | ... end end We would have to make PaintDC.initialize be private.> Either way it sounds a lot better than adding an ugly ''release'' method.Cool. I think so too. Kevin
[Regarding the code submission of .t files for the drag and drop classes] I spent a few hours integrating these files into wxRuby, at least to the point that make succeeds. I had to make several changes to wxpp.rb to support abstract classes, and I had to figure out some clever ways around some unfortunate ways these classes worked. I hope that work will pay off with some of the other classes that have not yet been converted to .t files. I declared DataObject and TextDropTarget to be abstract classes, and certain methods within them are marked as abstract instead of just virtual. This causes wxpp to automatically generate a "Helper" class with each abstract class declared. That gets it to compile, but if you actually try to use the class it will probably crash. What we need to do now is implement those abstract methods in the helper class, and have them invoke a comparable method in the ruby object that has wrapped that object. My brain is too tired to do this right now. Maybe I''ll try in a few days. It would be great if every new class we add has at least a trivial sample app showing someone how it can be used. Perhaps you (Gergely) could write up a sample dragdrop.rb program that we could use. Even if it doesn''t run correctly yet, it would help me see how the classes are supposed to work. Let me know if you have any problems with the stuff I checked in. Kevin
wxruby CVS (current from CVS as of 10:00 AM CST) On Win32, I''m getting this error with the new DataObject:. This is what I see from VC6 droptarget.cpp(72) : error C2259: ''wxDropTarget'' : cannot instantiate abstract c lass due to following members: c:\nick\wxWindows-2.4.2\/include\wx/msw/ole/droptgt.h(40) : see declarat ion of ''wxDropTarget'' droptarget.cpp(72) : warning C4259: ''enum wxDragResult __thiscall wxDropTargetBa se::OnData(int,int,enum wxDragResult)'' : pure virtual function was not defined c:\nick\wxWindows-2.4.2\/include\wx/dnd.h(187) : see declaration of ''OnData'' droptarget.cpp(72) : error C2259: ''wxDropTarget'' : cannot instantiate abstract c lass due to following members: c:\nick\wxWindows-2.4.2\/include\wx/msw/ole/droptgt.h(40) : see declarat ion of ''wxDropTarget'' droptarget.cpp(72) : warning C4259: ''enum wxDragResult __thiscall wxDropTargetBa se::OnData(int,int,enum wxDragResult)'' : pure virtual function was not defined c:\nick\wxWindows-2.4.2\/include\wx/dnd.h(187) : see declaration of ''OnData'' This is what I see from MinGW g++ -Os -I/mingw//lib/wx/include/msw-2.4 -I/mingw//include -D__WXMSW__ -mthreads -DWXUSINGDLL=1 -fno-pcc-struct-return -I. -IC:/Nick/msys/1.0/local/lib/ruby/1.8/i386-mingw32 -IC:/Nick/msys/1.0/local/lib/ruby/1.8/i386-mingw32 -I. -I/usr/local/mingw/include -c droptarget.cpp droptarget.cpp: In static member function `static bool WxDropTarget::constructor0(int, VALUE*, long unsigned int)'': droptarget.cpp:72: cannot allocate an object of type `wxDropTarget'' droptarget.cpp:72: because the following virtual functions are abstract: c:/nick/mingw/include/wx/dnd.h:187: virtual wxDragResult wxDropTargetBase::OnData(int, int, wxDragResult) make: *** [droptarget.o] Error 1 It looks like DropTarget is abstract in wxMSW. I''ll see if there is a neat hack for this. Nick Kevin Smith wrote:> [Regarding the code submission of .t files for the drag and drop classes] > > I spent a few hours integrating these files into wxRuby, at least to > the point that make succeeds. I had to make several changes to wxpp.rb > to support abstract classes, and I had to figure out some clever ways > around some unfortunate ways these classes worked. I hope that work > will pay off with some of the other classes that have not yet been > converted to .t files. > > I declared DataObject and TextDropTarget to be abstract classes, and > certain methods within them are marked as abstract instead of just > virtual. This causes wxpp to automatically generate a "Helper" class > with each abstract class declared. That gets it to compile, but if you > actually try to use the class it will probably crash. > > What we need to do now is implement those abstract methods in the > helper class, and have them invoke a comparable method in the ruby > object that has wrapped that object. My brain is too tired to do this > right now. Maybe I''ll try in a few days. > > It would be great if every new class we add has at least a trivial > sample app showing someone how it can be used. Perhaps you (Gergely) > could write up a sample dragdrop.rb program that we could use. Even if > it doesn''t run correctly yet, it would help me see how the classes are > supposed to work. > > Let me know if you have any problems with the stuff I checked in. > > Kevin > > _______________________________________________ > wxruby-users mailing list > wxruby-users@rubyforge.org > http://rubyforge.org/mailman/listinfo/wxruby-users > > >
On 1116, Kevin Smith wrote:> Let me know if you have any problems with the stuff I checked in.Yep. Methods.cpp needs wx/image.h And it doesn''t even compile :( droptarget.cpp: In static member function `static bool WxDropTarget::constructor0(int, VALUE*, long unsigned int)'': droptarget.cpp:72: cannot allocate an object of type `wxDropTarget'' droptarget.cpp:72: because the following virtual functions are abstract: d:/programs/wxWin/include/wx/dnd.h:187: virtual wxDragResult wxDropTargetBase::OnData(int, int, wxDragResult) make: *** [droptarget.o] Error 1 rm togglebutton.cpp Gergo -- +-[ Kontra, Gergely<kgergely@mcl.hu> PhD student Room IB113 ]---------+ | http://www.mcl.hu/~kgergely "Olyan langesz vagyok, hogy | | Mobil:(+36 20) 356 9656 ICQ: 175564914 poroltoval kellene jarnom" | +-- Magyar php mirror es magyar php dokumentacio: http://hu.php.net --+
Thanks to you and Nick for reporting this. I made droptarget an abstract class, which required a few more changes to wxpp.rb. They are checked in, so let me know if they now compile under Windows. Kevin KONTRA Gergely wrote:> On 1116, Kevin Smith wrote: > > >>Let me know if you have any problems with the stuff I checked in. > > > Yep. > Methods.cpp needs wx/image.h > > And it doesn''t even compile :( > droptarget.cpp: In static member function `static bool > WxDropTarget::constructor0(int, VALUE*, long unsigned int)'': > droptarget.cpp:72: cannot allocate an object of type `wxDropTarget'' > droptarget.cpp:72: because the following virtual functions are > abstract: > d:/programs/wxWin/include/wx/dnd.h:187: virtual wxDragResult > wxDropTargetBase::OnData(int, int, wxDragResult) > make: *** [droptarget.o] Error 1 > rm togglebutton.cpp > > Gergo >