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

GDI+ : Drawing objects over TabControl
Dan Dieckmann
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
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
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.