GDI+ : Drawing objects over TabControl

Hi,

I've been working my way around GDI+ for a couple of weeks now. I made a little application where user can choose among several shapes and then move/place chosen shape using mouse, building this way a customized furniture set. The area where user can place each shape chosen is delimited by a panel control for which I defined the background color as having transparent. Everything is going smooth but...

As second step, I added a tab control in order to have in first tab, the drawing area where use can place graphically each piece chosen and a second tab, the estimate or cost list of his customized furniture set. My problem is that I can't seem to find a way to draw over the tab control. Even if I've set tabcontrol as well as each of it's tab pages as having transparent background, I can't see any pieces drawn as I used before. I know that it has something to do with the tab control because when I set it visible property to false, I can see my objects drawn again. Any hint

Thanks in advance for your help,

Stephane



Answer this question

GDI+ : Drawing objects over TabControl

  • Dan Dieckmann

    There are differencies, but C# looks like native language for every C++ programmer.
  • mmaas

    Hi again Alex,

    Just a quick additionnal note. Following last reply, I modified my application and moved all code under "Form1::Paint" event handler subroutine into new event handler "Pnl_DrawingArea->Paint" subroutine. I then deleted "Form1::Paint" subroutine as well as the correponding event handler. I then adjusted coordinates calculation, compiled and made a few tests.

    Everything is displayed nicely except the fact that I have 2 sets of drawings, one displayed correctly and "related" to my DrawingArea panel control coordinates and another set, which shouldn't be there, located just like if it was painted according to my form coordinates...

    Any idea why the objects are displayed/painting that way It really gives me the impression that when I issue a Pnl_DrawingArea->Invalidate() it launch the corresponding paint event with Pnl_DrawingArea coordinates and maybe at the same time a Form1::Invalidate() statement is launched starting that same Pnl_DrawingArea->Paint subroutine again but with Form1 coordinates. Any idea

    Thanks again,

    Stephane


  • Number4

    I think form Paint event should be empty. If all drawing is done on the panel, form should redraw itself using default background color. Maybe I don't understand something in your program, you need to explain this and show some code.
  • Kundan5441

    Hi Alex,

    Many thanks for your help. A last question, is C# really different from C++

    Stephane


  • SeanDr_MS

    I still don't understand why drawing area should be transparent. Suppose that it has white background color, and you draw object with black color. It should be visible. What happens in the Paint event handler

    This article shows how to do something similar in C#, maybe it can help:

    http://www.codeproject.com/csharp/drawtools.asp


  • Myyrddraal

    Hi Alex,

    I have unfortunately no explanation of why graphicspath objects can't be drawn over panel, tabcontrol or probably any other types of window controls. I even made a little test this morning before posting my last reply and could verify that when commenting line

    "this->Pnl_DrawingArea->BackColor = System::Drawing::Color::Transparent;"

    my graphicspath wasn't drawn on screen. If I removed the comment and activated back this same line, I could see my graphicspath back again. It really seems to me that GDI cannot draw over window controls. Here is a snippet of my Form1_Paint event handler:

    private: System::Void Form1_Paint(System::Object * sender, System::Windows::Forms::PaintEventArgs * e)
    {
    Graphics* Cur_Graph = e->Graphics;
    Init_Graph(Cur_Graph);
    for(Int16 module_item = 0; module_item < Lst_modules->Count; module_item++)
    {
    CL_Modules* pelm_module = dynamic_cast<CL_Modules*>(Lst_modules->Item[module_item]);
    if(module_item == Sel_Module)
    pelm_module->Draw_Figure(Cur_Graph,Display_Mode::Select);
    else if(module_item == Del_Module)
    pelm_module->Draw_Figure(Cur_Graph,Display_Mode::Delete);
    else
    pelm_module->Draw_Figure(Cur_Graph,Display_Mode::Normal);
    }
    //Cur_Graph->Dispose(); <-- Graphics Object not disposed because part of PaintEventArgs
    }

    In Draw_Figure function, I only set brush and pen objects according to "Display" mode and then "draw" corresponding figure using FillPath() and DrawPath() methods.

    Any comments or tricks

    Stephane


  • d_maram

    Hi Alex,

    In fact, maybe after writing last e-mail which I'm not 100% sure, I got rid of the Form paint handler and created the new paint handler for Pnl_DrawingArea panel giving me the following line of code:

    this->Pnl_DrawingArea->Paint += new System::Windows::Forms::PaintEventHandler(this, &Form1::Pnl_DrawingArea_Paint);

    Also within paint routine, I have following code for creating graphics instance:

    private: System::Void Pnl_DrawingArea_Paint(System::Object* sender, System::Windows::Forms::PaintEventArgs* e)

    {

    Graphics* Cur_Graph = e->Graphics;

    ...

    Anything I should change I think not. Your opinion

    Finally, to answer your question. Yes I'm using Visual C++ 2005. In fact, I already tried to convert application to C++/CLI but at that time there wasn't any conversion tool available neither much good articles on the subject and, after doing it manually, I got a lot of errors. I tried to solve them starting from the few articles I could find on the Net but had to abandon. I then decided to wait for good book to come out before going on with the conversion. Do you know if there is any conversion tool finally available

    Concerning C#, yes I got a look at it when starting with Visual Studio but have been said that C++ was a more complete programming tool. Your opinion

    Thanks again for your help,

    Stephane


  • marclerman

    Why do you need transparent background
  • chadinsky

    Now your code looks OK.

    There is no conversion tool between C++ 2003 and 2005. I suggest you to make conversion manually, this is straightforward. Just remove backward compatibility flag and fix all errors. In any case you need to do this.

    About C# vs C++ - it is just my opinion, I prefer to work in C# when it is possible and use C++ for interoperability and hardware access.


  • Satheesh Kumar

    Hi,

    My drawing surface, if I can describe it this way, is visually delimited on screen by a panel object. Before I set it's color to transparent, I couldn't see any object drawn within it's limits. Here is a code snippet on how I've set that panel:

    this->Pnl_DrawingArea->BackColor = System::Drawing::Color::Transparent;

    this->Pnl_DrawingArea->BorderStyle = System::Windows::Forms::BorderStyle::Fixed3D;

    this->Pnl_DrawingArea->CausesValidation = false;

    this->Pnl_DrawingArea->Enabled = false;

    this->Pnl_DrawingArea->Location = System::Drawing::Point(122, 6);

    this->Pnl_DrawingArea->Name = S"Pnl_DrawingArea";

    this->Pnl_DrawingArea->Size = System::Drawing::Size(481, 385);

    this->Pnl_DrawingArea->TabIndex = 3;

    I have right now the same kind of problem with the tab control. If I force the graphicspath object to be drawn out of the limits of the tab control I can see it without problem. It seems like I can't draw anything over the tab control object, even if I've set it backcolor property to transparent like I did with the panel object. Any hint

    Thanks for your help,

    Stephane


  • Daniel at SCANA

    Hi Alex,

    I think we maybe have a clue here! I noticed following your reply that there was effectively a "Paint" method for a panel object. Sorry I didn't know that. Newbie!

    I added a paint event to my "DrawingArea" panel control.

    "this->Pnl_DrawingArea->Paint += new System::Windows::Forms::PaintEventHandler(this, &Form1::Form1_Paint);

    To test the machine, I also removed the transparent backcolor property from my panel object. I then compiled and finally ran the whole thing. Effectively, I could now see my graphics drawn like I used so far except the fact that everything is now shifted up/right, which I can easily explain by the "origin" point which therefore refer not to my window but to my panel object...

    I will modify program to take into account this new origin "shift" in my calculations and will come back with results.

    Maybe a last point. If the painting of my graphic area is now done within Pnl_DrawingArea->Paint handler, should I remove the "Form1->Paint" handler

    "this->Paint += new System::Windows::Forms::PaintEventHandler(this, &Form1::Form1_Paint);"

    I'm not sure if, as an example, when I minimize my window and restore it back, the Pnl_DrawingArea->Paint event will be triggered or not. Your comment

    Many thanks for your help,

    Stephane


  • c0dem0nkey1519

    You draw in the form Paint event handler. In your first post you write that you draw on the Panel control. If you want to draw on the Panel control, do this in it's Paint event handler and not in Form1_Paint.

    This can explain why results of drawing are invisible, unless panel is transparent.


  • pschmidt

    Hi again Alex,

    First many thanks for follow-up. Reading your last reply ligthed up my bulb I think...;) I just made the following changes at a few places in my code realizing that it was definitely the source of my problems:

    I changed

    Graphics* Cur_Graph = this->CreateGraphics();

    for

    Graphics* Cur_Graph = this->Pnl_DrawingArea->CreateGraphics();

    BTW, do you have any references of good books or articles on GDI+

    Many thanks again for your help. More than appreciated!

    Stephane


  • Corbin Hoenes

    Still not 100% correct.

    this->Pnl_DrawingArea->Paint += new System::Windows::Forms::PaintEventHandler(this, &Form1::Form1_Paint);

    Graphics* Cur_Graph = this->Pnl_DrawingArea->CreateGraphics();

    You draw Pnl_DrawingArea in the form Paint handler. You need to remove form Paint handler and create Pnl_DrawingArea Paint handler:

    this->Pnl_DrawingArea->Paint += new System::Windows::Forms::PaintEventHandler(this, &Form1::Pnl_DrawingArea Paint);

    Inside of Pnl_DrawingArea Paint function you can draw directly to e->Graphics without using CreateGraphics. Every control must paint itself in it's own Paint event handler, otherwise you have some unwanted effects.

    BTW, why do you do this in C++ First, you use old C++ syntax which is completely changed in 2005 version, which requires rewriting the program. Second, we need C++ only to access unmanaged resources. If you make pure .NET application, C# is much better.


  • GDI+ : Drawing objects over TabControl