Hey Milosz: Thanks very much for the detailed informaion about expose_event. And the describtion about "Graphics" in Mono is very helpful too. :) Now i know that when handling the expose_event, we should create a "Context" every time . It is like that when we handle the WM_PAINT msg on micro windows, we should call "BeginPaint" to get the DC ervey time. I think they have the same strategy. BTW, I prefer GtkMM to MFC. Now thanks everyone who replys my message, and i get what i want , just as following code shows:
#include <gtkmm/drawingarea.h> #include <gtkmm/main.h> #include <gtkmm/window.h> #include <cairomm/context.h> #include <iostream> class MyArea : public Gtk::DrawingArea { public: MyArea(); virtual ~MyArea(); protected: //Override default signal handler: virtual bool on_expose_event(GdkEventExpose* event); virtual bool on_button_press_event (GdkEventButton* event); private: Cairo::RefPtr<Cairo::Context> cr_; }; MyArea::MyArea() { add_events(Gdk::BUTTON_PRESS_MASK); } MyArea::~MyArea() { } bool MyArea::on_button_press_event(GdkEventButton* event) { if(!cr_){ Glib::RefPtr<Gdk::Window> window = get_window(); cr_ = window->create_cairo_context(); } cr_->move_to(0, 0); cr_->line_to(event->x, event->y); cr_->stroke(); } bool MyArea::on_expose_event(GdkEventExpose* event) { Glib::RefPtr<Gdk::Window> window = get_window(); Cairo::RefPtr<Cairo::Context> cr = window->create_cairo_context(); cr->set_line_width(10.0); cr->move_to(0, 0); cr->line_to(100, 100); cr->stroke(); return true; } int main(int argc, char** argv) { Gtk::Main kit(argc, argv); Gtk::Window win; win.set_title("DrawingArea"); MyArea area; win.add(area); area.show(); Gtk::Main::run(win); return 0; } 2008/12/4 Milosz Derezynski <[EMAIL PROTECTED]> > > > 2008/12/4 BC Zhu <[EMAIL PROTECTED]> > >> Cairo::RefPtr<Cairo::Context> cr = window->create_cairo_context();// >> The above sentence indicate me that cr is an smart pointer , so i can >> keep it as a class memeber or pass it as an argument to anthoer function, if >> this i can used it anywhere, and doesn't need to call " >> get_window()->create_cairo_context()" again and again. May be " >> get_window()->create_cairo_context()" is a cheap action, but according to >> the rule "DONOT REPEAT YOURSELF", i think its better to creat it one time, >> and use it any where. >> > > Hey BC, > > Generally this rule is right, but I do think that there are implications > with widget window double buffering. > > From the GTK+ FAQ at library.gnome.org ( > http://library.gnome.org/devel/gtk/stable/gtk-question-index.html): > > "If you create a cairo context outside the expose handler, it is backed by > the GDK window itself, not the double-buffering pixmap." > > Now this isn't an exact response to what you are asking, but what this > implies to me is that the specific drawable you create the cairo context for > in the expose handler is not guaranteed to be the same thing that you need > to draw in the next call of expose, and so forth. > > Also, this example for Cairo in Mono (yes, it is Mono, but the relevant > point is not about Mono, but the way Cairo/Gtk+ interaction works) > clearly states that reusing the same Cairo Context (in the example it's of > class type Cairo.Graphics) over multiple calls of expose will not work: > "Don't try to keep Graphics across multiple expose events, this will not > work due to double-buffering." > > > M. > > >> >> 2008/12/3 Milosz Derezynski <[EMAIL PROTECTED]> >> >> It does not seem neccessary to create 2 separate Cairo Contexts: >>> >>> class MyArea : public Gtk::DrawingArea >>> { >>> public: >>> virtual ~MyArea(); >>> protected: >>> //Override default signal handler: >>> virtual bool on_expose_event( >>> >>>> GdkEventExpose* event); >>>> }; >>>> MyArea::MyArea() >>>> { >>>> } >>>> MyArea::~MyArea() >>>> { >>>> } >>>> bool MyArea::on_expose_event(GdkEventExpose* event) >>>> { >>>> // This is where we draw on the window >>>> Cairo::RefPtr<Cairo::Context> cr = window->create_cairo_context(); >>>> cr->set_line_width(10.0); >>>> cr->move_to(0, 0); >>>> cr->line_to(100, 100); >>>> cr->stroke(); >>>> return true; >>>> } >>>> >>> >>> This will work equally well. Is there any specific reason why you want to >>> keep the surface member in the class and use it the way you wrote it in the >>> preceding mail? >>> >>> M. >>> >>> >>> 2008/12/3 BC Zhu <[EMAIL PROTECTED]> >>> >>>> Now i am using Gtkmm. I want to maintain a reference to Cairo::Context >>>> or Cairo::Surface, so i can draw something on it anywhere. >>>> I am trying to do this , but failed. >>>> With following code , i am trying to keep a reference to >>>> Cairo:::Surface,but when on_expose_event was called secondly , it will >>>> fail. >>>> And i have tried to maintain a reference to Cairo::Context too, but >>>> failed either. >>>> Could some body give me an advice? >>>> Thanks in advance! >>>> >>>> >>>> class MyArea : public Gtk::DrawingArea >>>> { >>>> public: >>>> virtual ~MyArea(); >>>> protected: >>>> //Override default signal handler: >>>> virtual bool on_expose_event(GdkEventExpose* event); >>>> private: >>>> Cairo::RefPtr<Cairo::Surface> surf_; >>>> }; >>>> MyArea::MyArea() >>>> { >>>> } >>>> MyArea::~MyArea() >>>> { >>>> } >>>> bool MyArea::on_expose_event(GdkEventExpose* event) >>>> { >>>> // This is where we draw on the window >>>> if(!surf_){ >>>> Glib::RefPtr<Gdk::Window> window = get_window(); >>>> Cairo::RefPtr<Cairo::Context> cr = >>>> window->create_cairo_context(); >>>> surf_ = cr->get_target(); >>>> } >>>> Cairo::RefPtr<Cairo::Context> cr = Cairo::Context::create(surf_); >>>> cr->set_line_width(10.0); >>>> cr->move_to(0, 0); >>>> cr->line_to(100, 100); >>>> cr->stroke(); >>>> return true; >>>> } >>>> >>>> >>>> -- >>>> Best Regards >>>> Bicen.Zhu >>>> >>>> _______________________________________________ >>>> gtkmm-list mailing list >>>> gtkmm-list@gnome.org >>>> http://mail.gnome.org/mailman/listinfo/gtkmm-list >>>> >>>> >>> >>> >>> -- >>> Please note that according to the German law on data retention, >>> information on every electronic information exchange with me is >>> retained for a period of six months. >>> [Bitte beachten Sie, dass dem Gesetz zur Vorratsdatenspeicherung zufolge >>> jeder elektronische Kontakt mit mir sechs Monate lang gespeichert wird.] >>> >> >> >> >> -- >> Best Regards >> Bicen.Zhu >> > > > > -- > Please note that according to the German law on data retention, > information on every electronic information exchange with me is > retained for a period of six months. > [Bitte beachten Sie, dass dem Gesetz zur Vorratsdatenspeicherung zufolge > jeder elektronische Kontakt mit mir sechs Monate lang gespeichert wird.] > -- Best Regards Bicen.Zhu
_______________________________________________ gtkmm-list mailing list gtkmm-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtkmm-list