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

Reply via email to