Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C#
  4. GDI+ nonrectangular forms problem

GDI+ nonrectangular forms problem

Scheduled Pinned Locked Moved C#
graphicswinformsregexhelpquestion
16 Posts 2 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • S sstoyan

    but my region starts from (0, 0) and i want to fill a region starting from (0, 0) too - so it does start from there, but when i give a bottom right corner of (150, 50) it does not match with the (150, 50) point i used for the region before! and this is my problem. i understand that the root coordinates are unchaged - thats what i count on - why does the fill go with wrong coords ?

    H Offline
    H Offline
    Heath Stewart
    wrote on last edited by
    #4

    You'll need to be a little more specific. If you can, please posts a couple of screenshots of what you have and (if you can muster it) what you'd like to see, as well as the contents of your OnPaint method and any methods called less frequently (preferrably, for performance) to calculate the region. This posting is provided "AS IS" with no warranties, and confers no rights. Software Design Engineer Developer Division Sustained Engineering Microsoft [My Articles] [My Blog]

    S 1 Reply Last reply
    0
    • H Heath Stewart

      You'll need to be a little more specific. If you can, please posts a couple of screenshots of what you have and (if you can muster it) what you'd like to see, as well as the contents of your OnPaint method and any methods called less frequently (preferrably, for performance) to calculate the region. This posting is provided "AS IS" with no warranties, and confers no rights. Software Design Engineer Developer Division Sustained Engineering Microsoft [My Articles] [My Blog]

      S Offline
      S Offline
      sstoyan
      wrote on last edited by
      #5

      how about some ASCII art ? :) the initial window: xxxxx xxxxx xxxxx xxxxx the nonrectangular window: yyy xxxxx xxxxx xxxxx i want the yyy part colored. and thats where the coords fail me - i get something like yyy yyyyx xxxxx xxxxx all the code i use is in my first post

      H 1 Reply Last reply
      0
      • S sstoyan

        how about some ASCII art ? :) the initial window: xxxxx xxxxx xxxxx xxxxx the nonrectangular window: yyy xxxxx xxxxx xxxxx i want the yyy part colored. and thats where the coords fail me - i get something like yyy yyyyx xxxxx xxxxx all the code i use is in my first post

        H Offline
        H Offline
        Heath Stewart
        wrote on last edited by
        #6

        The ASCII art's not bad, but next time enclose each segment in <PRE></PRE> tags so that it's truly ASCII art (fixed-width). :) Out of curiosity, are you drawing tabs for a custom tab control? If so, you should owner-draw tabs or at least not define the tabs themselves as controls. You can do it that way, but that's pretty heavy-weight compared to a single control (like the TabControl in the BCL) managing what's visible using components (like the TabPage in the BCL). One problem I see is that with the second block of code where you add a colored rectangle, you're not actually adding a rectangle. You're adding another polygon. The following extents do not a rectangle make (a little Yoda speak for you):

        {0,0} {100,0}
        {0,50} {150,50}

        Try making it an actual rectangle (changing 150 to 100, I'd assume) or drawing a polygon using the Graphics object passed to you from the PaintEventArgs in your OnPaint override and see if that works. This posting is provided "AS IS" with no warranties, and confers no rights. Software Design Engineer Developer Division Sustained Engineering Microsoft [My Articles] [My Blog]

        S 1 Reply Last reply
        0
        • H Heath Stewart

          The ASCII art's not bad, but next time enclose each segment in <PRE></PRE> tags so that it's truly ASCII art (fixed-width). :) Out of curiosity, are you drawing tabs for a custom tab control? If so, you should owner-draw tabs or at least not define the tabs themselves as controls. You can do it that way, but that's pretty heavy-weight compared to a single control (like the TabControl in the BCL) managing what's visible using components (like the TabPage in the BCL). One problem I see is that with the second block of code where you add a colored rectangle, you're not actually adding a rectangle. You're adding another polygon. The following extents do not a rectangle make (a little Yoda speak for you):

          {0,0} {100,0}
          {0,50} {150,50}

          Try making it an actual rectangle (changing 150 to 100, I'd assume) or drawing a polygon using the Graphics object passed to you from the PaintEventArgs in your OnPaint override and see if that works. This posting is provided "AS IS" with no warranties, and confers no rights. Software Design Engineer Developer Division Sustained Engineering Microsoft [My Articles] [My Blog]

          S Offline
          S Offline
          sstoyan
          wrote on last edited by
          #7

          hi, heath, thanx for bearing with me :) no this is not a custom tab control, but a non rectangular window. the intent is for the upper poligonal(nonrectangular) part to be used as a handle to mousedrag the window by. the first part of the code is in the contructor, and the second goes inside the OnPaint override. im copying the code again - in the constructor: GraphicsPath p = new GraphicsPath(); Point[] points = { new Point(0, 0), new Point(100, 0), new Point(150, 50), new Point(250, 50), new Point(250, 350), new Point(0, 350) }; p.AddPolygon(points); this.Region = new Region(p); in the Paint override: GraphicsPath p = new GraphicsPath(); Point[] points = { new Point(0, 0), new Point(100, 0), new Point(150, 50), new Point(0, 50)}; p.AddPolygon(points); g.FillPath(new SolidBrush(Color.Aqua), p); g.DrawPath(Pens.Red, p); if you paste this directly into a windows form application code you will see what i mean (i would have posted the entire solution if i knew how to do it here :)

          H 1 Reply Last reply
          0
          • S sstoyan

            hi, heath, thanx for bearing with me :) no this is not a custom tab control, but a non rectangular window. the intent is for the upper poligonal(nonrectangular) part to be used as a handle to mousedrag the window by. the first part of the code is in the contructor, and the second goes inside the OnPaint override. im copying the code again - in the constructor: GraphicsPath p = new GraphicsPath(); Point[] points = { new Point(0, 0), new Point(100, 0), new Point(150, 50), new Point(250, 50), new Point(250, 350), new Point(0, 350) }; p.AddPolygon(points); this.Region = new Region(p); in the Paint override: GraphicsPath p = new GraphicsPath(); Point[] points = { new Point(0, 0), new Point(100, 0), new Point(150, 50), new Point(0, 50)}; p.AddPolygon(points); g.FillPath(new SolidBrush(Color.Aqua), p); g.DrawPath(Pens.Red, p); if you paste this directly into a windows form application code you will see what i mean (i would have posted the entire solution if i knew how to do it here :)

            H Offline
            H Offline
            Heath Stewart
            wrote on last edited by
            #8

            You shouldn't be doing redundant calculations in your OnPaint override; you waste CPU cycles. If the GraphicsPath doesn't change, then don't keep recalculating it. OnPaint (or rather, the WM_PAINT window message) is called many, many times by the OS. To post code, simply copy and paste the code in between <PRE></PRE> tags and escape any characters like < with <, > with >, and & with & You also don't need VS.NET. I added csc.exe's directory (the Framework version directory) to my PATH environment variable (as well as the SDK's Bin directory) and do almost everything you'd see from me on this site using a vanilla text editor called VIM[^] and the command-line compiler. With a VIM script, I can post this easily to this site:

            using System;
            using System.Drawing;
            using System.Drawing.Drawing2D;
            using System.Windows.Forms;
             
            class Test : Form
            {
            static void Main()
            {
            Application.Run(new Test());
            }
             
            GraphicsPath grabHandle;
            Brush pathBrush = new SolidBrush(Color.Aqua);
            Pen pathPen = new Pen(Color.Red);
             
            Test()
            {
            GraphicsPath p = new GraphicsPath();
            Point[] points = new Point[] {
            new Point(0,0),
            new Point(100,0),
            new Point(150,50),
            new Point(250,50),
            new Point(250,350),
            new Point(0,350)};
            p.AddPolygon(points);
            this.Region = new Region(p);
             
            grabHandle = new GraphicsPath();
            points = new Point[] {
            new Point(0,0),
            new Point(100,0),
            new Point(150,50),
            new Point(0,50)};
            grabHandle.AddPolygon(points);
            }
             
            protected override void OnPaint(PaintEventArgs e)
            {
            base.OnPaint(e);
             
            Graphics g = e.Graphics;
            g.FillPath(pathBrush, grabHandle);
            g.DrawPath(pathPen, grabHandle);
            }
            }

            So far as I know, it appears to work just fine. If you need to post a picture of what you expect, drawing something up (may I suggest the free Paint.NET[^] application from Washington University and Microsoft) and post it online. Surely you have a site somewhere where you can post a simple image. If not, you can email it to me but only as a last resort (and never continue a thread from this si

            S 1 Reply Last reply
            0
            • H Heath Stewart

              You shouldn't be doing redundant calculations in your OnPaint override; you waste CPU cycles. If the GraphicsPath doesn't change, then don't keep recalculating it. OnPaint (or rather, the WM_PAINT window message) is called many, many times by the OS. To post code, simply copy and paste the code in between <PRE></PRE> tags and escape any characters like < with <, > with >, and & with & You also don't need VS.NET. I added csc.exe's directory (the Framework version directory) to my PATH environment variable (as well as the SDK's Bin directory) and do almost everything you'd see from me on this site using a vanilla text editor called VIM[^] and the command-line compiler. With a VIM script, I can post this easily to this site:

              using System;
              using System.Drawing;
              using System.Drawing.Drawing2D;
              using System.Windows.Forms;
               
              class Test : Form
              {
              static void Main()
              {
              Application.Run(new Test());
              }
               
              GraphicsPath grabHandle;
              Brush pathBrush = new SolidBrush(Color.Aqua);
              Pen pathPen = new Pen(Color.Red);
               
              Test()
              {
              GraphicsPath p = new GraphicsPath();
              Point[] points = new Point[] {
              new Point(0,0),
              new Point(100,0),
              new Point(150,50),
              new Point(250,50),
              new Point(250,350),
              new Point(0,350)};
              p.AddPolygon(points);
              this.Region = new Region(p);
               
              grabHandle = new GraphicsPath();
              points = new Point[] {
              new Point(0,0),
              new Point(100,0),
              new Point(150,50),
              new Point(0,50)};
              grabHandle.AddPolygon(points);
              }
               
              protected override void OnPaint(PaintEventArgs e)
              {
              base.OnPaint(e);
               
              Graphics g = e.Graphics;
              g.FillPath(pathBrush, grabHandle);
              g.DrawPath(pathPen, grabHandle);
              }
              }

              So far as I know, it appears to work just fine. If you need to post a picture of what you expect, drawing something up (may I suggest the free Paint.NET[^] application from Washington University and Microsoft) and post it online. Surely you have a site somewhere where you can post a simple image. If not, you can email it to me but only as a last resort (and never continue a thread from this si

              S Offline
              S Offline
              sstoyan
              wrote on last edited by
              #9

              dont worry i would bother you for something as silly as this :) i've compiled your code and i got what i have achieved already: http://viewmoresoft.com/rez1.jpg but my goal is http://viewmoresoft.com/rez2.jpg i've setup the form so it is without the title bar etc when i do a fill of the region it fills the entire visible area, but when i want to get my poligon filled it does it not the way i want. can you see what i am trying to achieve now ?

              H 1 Reply Last reply
              0
              • S sstoyan

                dont worry i would bother you for something as silly as this :) i've compiled your code and i got what i have achieved already: http://viewmoresoft.com/rez1.jpg but my goal is http://viewmoresoft.com/rez2.jpg i've setup the form so it is without the title bar etc when i do a fill of the region it fills the entire visible area, but when i want to get my poligon filled it does it not the way i want. can you see what i am trying to achieve now ?

                H Offline
                H Offline
                Heath Stewart
                wrote on last edited by
                #10

                In the future, please format your links to actually be links. The format toolbar below the message window is handy, and you can always use basic HTML elements when posting. Now that I have some idea of what you want, it's quite a easy. You didn't notice that width of the angled portion was exactly the same as the width of the Windows title bar? The window frame is the non-client portion, so when you were setting your clipping area amounts where adjusted. If you set Form.FormBorderStyle to FormBorderStyle.None you'll get what you want:

                using System;
                using System.Drawing;
                using System.Drawing.Drawing2D;
                using System.Windows.Forms;
                 
                class Test : Form
                {
                static void Main()
                {
                Application.Run(new Test());
                }
                 
                GraphicsPath grabHandle;
                Brush pathBrush = new SolidBrush(Color.Aqua);
                Pen pathPen = new Pen(Color.Red);
                 
                Test()
                {
                FormBorderStyle = FormBorderStyle.None;
                 
                GraphicsPath p = new GraphicsPath();
                Point[] points = new Point[] {
                new Point(0,0),
                new Point(100,0),
                new Point(150,50),
                new Point(250,50),
                new Point(250,350),
                new Point(0,350)};
                p.AddPolygon(points);
                this.Region = new Region(p);
                 
                grabHandle = new GraphicsPath();
                points = new Point[] {
                new Point(0,0),
                new Point(100,0),
                new Point(150,50),
                new Point(0,50)};
                grabHandle.AddPolygon(points);
                 
                Label lbl = new Label();
                Controls.Add(lbl);
                lbl.Location = new Point(8,58);
                lbl.Size = new Size(200, lbl.Height);
                lbl.Text = "Click anywhere to close";
                lbl.Click += new EventHandler(Clicked);
                }
                 
                void Clicked(object sender, EventArgs e)
                {
                Close();
                }
                 
                protected override void OnClick(EventArgs e)
                {
                base.OnClick(e);
                Close();
                }
                 
                protected override void OnPaint(PaintEventArgs e)
                {
                base.OnPaint(e);
                 
                Graphics g = e.Graphics;
                g.FillPath(pathBrush, grabHandle);
                g.DrawPath(pathPen, grabHandle);
                }
                }

                You'll need to adjust your border line, though. Because of a behavior similar to - if not related - to culling some lines won't be visible. You could thicken your border a little and contract it a pixel or two (depending on the new thickness), or you'll need to adjust it manually based on the thickness. This posting is provided "AS IS" with no warranties, and confers no rights. Software Design Engineer Developer Division Sustained Engineering

                S 1 Reply Last reply
                0
                • H Heath Stewart

                  In the future, please format your links to actually be links. The format toolbar below the message window is handy, and you can always use basic HTML elements when posting. Now that I have some idea of what you want, it's quite a easy. You didn't notice that width of the angled portion was exactly the same as the width of the Windows title bar? The window frame is the non-client portion, so when you were setting your clipping area amounts where adjusted. If you set Form.FormBorderStyle to FormBorderStyle.None you'll get what you want:

                  using System;
                  using System.Drawing;
                  using System.Drawing.Drawing2D;
                  using System.Windows.Forms;
                   
                  class Test : Form
                  {
                  static void Main()
                  {
                  Application.Run(new Test());
                  }
                   
                  GraphicsPath grabHandle;
                  Brush pathBrush = new SolidBrush(Color.Aqua);
                  Pen pathPen = new Pen(Color.Red);
                   
                  Test()
                  {
                  FormBorderStyle = FormBorderStyle.None;
                   
                  GraphicsPath p = new GraphicsPath();
                  Point[] points = new Point[] {
                  new Point(0,0),
                  new Point(100,0),
                  new Point(150,50),
                  new Point(250,50),
                  new Point(250,350),
                  new Point(0,350)};
                  p.AddPolygon(points);
                  this.Region = new Region(p);
                   
                  grabHandle = new GraphicsPath();
                  points = new Point[] {
                  new Point(0,0),
                  new Point(100,0),
                  new Point(150,50),
                  new Point(0,50)};
                  grabHandle.AddPolygon(points);
                   
                  Label lbl = new Label();
                  Controls.Add(lbl);
                  lbl.Location = new Point(8,58);
                  lbl.Size = new Size(200, lbl.Height);
                  lbl.Text = "Click anywhere to close";
                  lbl.Click += new EventHandler(Clicked);
                  }
                   
                  void Clicked(object sender, EventArgs e)
                  {
                  Close();
                  }
                   
                  protected override void OnClick(EventArgs e)
                  {
                  base.OnClick(e);
                  Close();
                  }
                   
                  protected override void OnPaint(PaintEventArgs e)
                  {
                  base.OnPaint(e);
                   
                  Graphics g = e.Graphics;
                  g.FillPath(pathBrush, grabHandle);
                  g.DrawPath(pathPen, grabHandle);
                  }
                  }

                  You'll need to adjust your border line, though. Because of a behavior similar to - if not related - to culling some lines won't be visible. You could thicken your border a little and contract it a pixel or two (depending on the new thickness), or you'll need to adjust it manually based on the thickness. This posting is provided "AS IS" with no warranties, and confers no rights. Software Design Engineer Developer Division Sustained Engineering

                  S Offline
                  S Offline
                  sstoyan
                  wrote on last edited by
                  #11

                  this is still not it :( this is what your code and mine so far achieve. sorry, maybe i have mislead you, but in my code i do use FormBorderStyle.None, havent pointed it out, my mistake. however what i want to achieve is this (the part in purple). do you see the difference? i am very thankfull for your time and help.

                  H 1 Reply Last reply
                  0
                  • S sstoyan

                    this is still not it :( this is what your code and mine so far achieve. sorry, maybe i have mislead you, but in my code i do use FormBorderStyle.None, havent pointed it out, my mistake. however what i want to achieve is this (the part in purple). do you see the difference? i am very thankfull for your time and help.

                    H Offline
                    H Offline
                    Heath Stewart
                    wrote on last edited by
                    #12

                    It looks fine on my machine. It's only simple math, after all. You're clip is only 50 pixels down from the top and your second GraphicsPath never extends beyond that. This is what I get on my machine (and the DPI should have nothing to do with it since you're using the same coordinate space for the clipping region and the drawing region). This posting is provided "AS IS" with no warranties, and confers no rights. Software Design Engineer Developer Division Sustained Engineering Microsoft [My Articles] [My Blog]

                    S 1 Reply Last reply
                    0
                    • H Heath Stewart

                      It looks fine on my machine. It's only simple math, after all. You're clip is only 50 pixels down from the top and your second GraphicsPath never extends beyond that. This is what I get on my machine (and the DPI should have nothing to do with it since you're using the same coordinate space for the clipping region and the drawing region). This posting is provided "AS IS" with no warranties, and confers no rights. Software Design Engineer Developer Division Sustained Engineering Microsoft [My Articles] [My Blog]

                      S Offline
                      S Offline
                      sstoyan
                      wrote on last edited by
                      #13

                      yes, it looks very good on the picture - exactly how i want it. but to my utter dismay i cannot achieve this locally. i tried through vs.2003, then with command line csc.exe - nothing helps, and all i do is copy & paste the code you posted ... amazing .... im using .Net Framework v.1.1.4322..an idea that just came up - could you post your compiled exe file? i decided to upload mine too, here. Change: this is insane - i run the application on another machine and it is fine there! so from the very beginning the problem was in the configuration on my machine, which is obvious now, because from the start my code was exactly as the one you posted. i guess i'll have to reinstall stuff.... thanx for your patience and support! have a very merry Christmas !

                      H 1 Reply Last reply
                      0
                      • S sstoyan

                        yes, it looks very good on the picture - exactly how i want it. but to my utter dismay i cannot achieve this locally. i tried through vs.2003, then with command line csc.exe - nothing helps, and all i do is copy & paste the code you posted ... amazing .... im using .Net Framework v.1.1.4322..an idea that just came up - could you post your compiled exe file? i decided to upload mine too, here. Change: this is insane - i run the application on another machine and it is fine there! so from the very beginning the problem was in the configuration on my machine, which is obvious now, because from the start my code was exactly as the one you posted. i guess i'll have to reinstall stuff.... thanx for your patience and support! have a very merry Christmas !

                        H Offline
                        H Offline
                        Heath Stewart
                        wrote on last edited by
                        #14

                        Good to know it's working. I just wanted to state that whether you use VS.NET or csc.exe there isn't any difference. VS.NET does not work "magic" like VS did for VB6 (the .frm files weren't the easiest to edit by hand). VS.NET uses the CodeDom to serialize code and the compilers use the same code to compile source. The VC++ compiler, on the other hand, is different between VS.NET and the Platform SDK, the latter of which doesn't have as good as optimization as the VS.NET compiler. This posting is provided "AS IS" with no warranties, and confers no rights. Software Design Engineer Developer Division Sustained Engineering Microsoft [My Articles] [My Blog]

                        S 1 Reply Last reply
                        0
                        • H Heath Stewart

                          Good to know it's working. I just wanted to state that whether you use VS.NET or csc.exe there isn't any difference. VS.NET does not work "magic" like VS did for VB6 (the .frm files weren't the easiest to edit by hand). VS.NET uses the CodeDom to serialize code and the compilers use the same code to compile source. The VC++ compiler, on the other hand, is different between VS.NET and the Platform SDK, the latter of which doesn't have as good as optimization as the VS.NET compiler. This posting is provided "AS IS" with no warranties, and confers no rights. Software Design Engineer Developer Division Sustained Engineering Microsoft [My Articles] [My Blog]

                          S Offline
                          S Offline
                          sstoyan
                          wrote on last edited by
                          #15

                          any idea why i have different results on different pc-s? my development pc is windows 2k server, i reinstalled the os, .net framework, .net sdk, and still cant get a correct window. no problems though on the xp i run on it for test

                          H 1 Reply Last reply
                          0
                          • S sstoyan

                            any idea why i have different results on different pc-s? my development pc is windows 2k server, i reinstalled the os, .net framework, .net sdk, and still cant get a correct window. no problems though on the xp i run on it for test

                            H Offline
                            H Offline
                            Heath Stewart
                            wrote on last edited by
                            #16

                            As I mentioned before, it could be your DPI (dots per inch, or PPI for pixels per inch in some other countries/regions). Check your monitor settings. Since you're using pixels for both GraphicsPaths I don't see how this would be a problem, though, so long as you have no form border. The Framework itself is agnostic to the platform (for those classes - like most - that are supported by every Windows platform) so its settings on the machine that are affecting your Form. Without being there on your computer it's hard to say. This posting is provided "AS IS" with no warranties, and confers no rights. Software Design Engineer Developer Division Sustained Engineering Microsoft [My Articles] [My Blog]

                            1 Reply Last reply
                            0
                            Reply
                            • Reply as topic
                            Log in to reply
                            • Oldest to Newest
                            • Newest to Oldest
                            • Most Votes


                            • Login

                            • Don't have an account? Register

                            • Login or register to search.
                            • First post
                              Last post
                            0
                            • Categories
                            • Recent
                            • Tags
                            • Popular
                            • World
                            • Users
                            • Groups