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. How can I get graphics through message WM_NCPAINT ?

How can I get graphics through message WM_NCPAINT ?

Scheduled Pinned Locked Moved C#
questiongraphics
8 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.
  • W Offline
    W Offline
    wangier
    wrote on last edited by
    #1

    For repainting the nonclient area myself, I process the message WM_NCPAINT. But the value got from wParam always is 1. Why? How can I get the nonclient area's graphics?

    H 1 Reply Last reply
    0
    • W wangier

      For repainting the nonclient area myself, I process the message WM_NCPAINT. But the value got from wParam always is 1. Why? How can I get the nonclient area's graphics?

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

      If you have a reference to the non-client area, you can use Control.CreateGraphics to return a Graphics object for any control. Remember to call Graphics.Dispose on it when you're done, though.

      -----BEGIN GEEK CODE BLOCK----- Version: 3.21 GCS/G/MU d- s: a- C++++ UL@ P++(+++) L+(--) E--- W+++ N++ o+ K? w++++ O- M(+) V? PS-- PE Y++ PGP++ t++@ 5 X+++ R+@ tv+ b(-)>b++ DI++++ D+ G e++>+++ h---* r+++ y+++ -----END GEEK CODE BLOCK-----

      W 2 Replies Last reply
      0
      • H Heath Stewart

        If you have a reference to the non-client area, you can use Control.CreateGraphics to return a Graphics object for any control. Remember to call Graphics.Dispose on it when you're done, though.

        -----BEGIN GEEK CODE BLOCK----- Version: 3.21 GCS/G/MU d- s: a- C++++ UL@ P++(+++) L+(--) E--- W+++ N++ o+ K? w++++ O- M(+) V? PS-- PE Y++ PGP++ t++@ 5 X+++ R+@ tv+ b(-)>b++ DI++++ D+ G e++>+++ h---* r+++ y+++ -----END GEEK CODE BLOCK-----

        W Offline
        W Offline
        wangier
        wrote on last edited by
        #3

        I know I can get the form's graphics with CreateGraphics(). Can I get the title bar's graphics? or How can I determine the title bar's retangle? The wParam gotten from WM_NCPAINT always is 1.

        H 1 Reply Last reply
        0
        • H Heath Stewart

          If you have a reference to the non-client area, you can use Control.CreateGraphics to return a Graphics object for any control. Remember to call Graphics.Dispose on it when you're done, though.

          -----BEGIN GEEK CODE BLOCK----- Version: 3.21 GCS/G/MU d- s: a- C++++ UL@ P++(+++) L+(--) E--- W+++ N++ o+ K? w++++ O- M(+) V? PS-- PE Y++ PGP++ t++@ 5 X+++ R+@ tv+ b(-)>b++ DI++++ D+ G e++>+++ h---* r+++ y+++ -----END GEEK CODE BLOCK-----

          W Offline
          W Offline
          wangier
          wrote on last edited by
          #4

          I found the graphics using Control.CreateGraphics only contains the client area, not contains the title bar.

          1 Reply Last reply
          0
          • W wangier

            I know I can get the form's graphics with CreateGraphics(). Can I get the title bar's graphics? or How can I determine the title bar's retangle? The wParam gotten from WM_NCPAINT always is 1.

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

            Right, I didn't catch that before. The wParam in the WM_NCPAINT message should be 1 if the entire window frame needs repainting (covered in the docs for WM_NCPAINT). Also in that same doc is an example that you could easily use after importing a couple Win32 functions (I can't think of or find any .NET equivalents). P/Invoke GetDCEx (optionally ReleaseDC, but Graphics.Dispose would free the handle). and pass hwnd, (HRGN)wParam, and DCX_WINDOW|DCX_INTERSECTRGN. Even though hwnd is 1, this supposedly works (at least according the docs). I tried a quick example and got minimal success. Of course, I threw it together quickly. I also found on that Graphics.FromHwnd works when passing the Message.HWnd field from the overridden DefWndProc for my form. Hopefully this helps somewhat. Good luck!

            -----BEGIN GEEK CODE BLOCK----- Version: 3.21 GCS/G/MU d- s: a- C++++ UL@ P++(+++) L+(--) E--- W+++ N++ o+ K? w++++ O- M(+) V? PS-- PE Y++ PGP++ t++@ 5 X+++ R+@ tv+ b(-)>b++ DI++++ D+ G e++>+++ h---* r+++ y+++ -----END GEEK CODE BLOCK-----

            W 1 Reply Last reply
            0
            • H Heath Stewart

              Right, I didn't catch that before. The wParam in the WM_NCPAINT message should be 1 if the entire window frame needs repainting (covered in the docs for WM_NCPAINT). Also in that same doc is an example that you could easily use after importing a couple Win32 functions (I can't think of or find any .NET equivalents). P/Invoke GetDCEx (optionally ReleaseDC, but Graphics.Dispose would free the handle). and pass hwnd, (HRGN)wParam, and DCX_WINDOW|DCX_INTERSECTRGN. Even though hwnd is 1, this supposedly works (at least according the docs). I tried a quick example and got minimal success. Of course, I threw it together quickly. I also found on that Graphics.FromHwnd works when passing the Message.HWnd field from the overridden DefWndProc for my form. Hopefully this helps somewhat. Good luck!

              -----BEGIN GEEK CODE BLOCK----- Version: 3.21 GCS/G/MU d- s: a- C++++ UL@ P++(+++) L+(--) E--- W+++ N++ o+ K? w++++ O- M(+) V? PS-- PE Y++ PGP++ t++@ 5 X+++ R+@ tv+ b(-)>b++ DI++++ D+ G e++>+++ h---* r+++ y+++ -----END GEEK CODE BLOCK-----

              W Offline
              W Offline
              wangier
              wrote on last edited by
              #6

              Please check following codes, it dosen'g work properly, the title bar is still empty. ( the method PanitNonClientArea(Graphics, RectangleF) can work properly. ) protected override void WndProc(ref Message m) { Graphics g; RectangleF rectf; Point pt; switch (m.Msg) { case WMConsts.WM_NCPAINT : IntPtr hrgn = m.WParam; if ( hrgn != (IntPtr)1 ) { Region rgn = Region.FromHrgn(hrgn); g = CreateGraphics(); rectf = rgn.GetBounds(g); PaintNonClientArea(g, rectf); } else { g = CreateGraphics(); rectf = new RectangleF(0,-23, Width, 23); PaintNonClientArea(g, rectf); g.Dispose(); } //base.WndProc(ref m); break; default : base.WndProc (ref m); break; } }

              H 1 Reply Last reply
              0
              • W wangier

                Please check following codes, it dosen'g work properly, the title bar is still empty. ( the method PanitNonClientArea(Graphics, RectangleF) can work properly. ) protected override void WndProc(ref Message m) { Graphics g; RectangleF rectf; Point pt; switch (m.Msg) { case WMConsts.WM_NCPAINT : IntPtr hrgn = m.WParam; if ( hrgn != (IntPtr)1 ) { Region rgn = Region.FromHrgn(hrgn); g = CreateGraphics(); rectf = rgn.GetBounds(g); PaintNonClientArea(g, rectf); } else { g = CreateGraphics(); rectf = new RectangleF(0,-23, Width, 23); PaintNonClientArea(g, rectf); g.Dispose(); } //base.WndProc(ref m); break; default : base.WndProc (ref m); break; } }

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

                As a quick note, and this may be trivial, but all implementations I've seen (including in Win32) always call the "base" WndProc or DefWndProc. You're only doing it if the message isn't WM_NCPAINT. Also, the docs for WM_NCPAINT say that it calls the DefWindowProc, which is DefWndProc in the Control class. Did you try putting a breakpoint in your code to see if it's even getting there? If not, you might try moving this to an override of DefWndProc instead of WndProc. I don't know, maybe both callbacks get it. As I said in my previous post, I had some success. I forgot to mention that I was using Graphics.FromHwnd instead of CreateGraphics. This seemed to work in most cases. I was able to ruin the nonclient area, but could never paint in it. Apparently, I was able to create a Graphics object successfully, but I would always get an exception when creating a Region from the wParam, which would explain why I couldn't paint anything (I couldn't get the bounds in which to paint).

                -----BEGIN GEEK CODE BLOCK----- Version: 3.21 GCS/G/MU d- s: a- C++++ UL@ P++(+++) L+(--) E--- W+++ N++ o+ K? w++++ O- M(+) V? PS-- PE Y++ PGP++ t++@ 5 X+++ R+@ tv+ b(-)>b++ DI++++ D+ G e++>+++ h---* r+++ y+++ -----END GEEK CODE BLOCK-----

                W 1 Reply Last reply
                0
                • H Heath Stewart

                  As a quick note, and this may be trivial, but all implementations I've seen (including in Win32) always call the "base" WndProc or DefWndProc. You're only doing it if the message isn't WM_NCPAINT. Also, the docs for WM_NCPAINT say that it calls the DefWindowProc, which is DefWndProc in the Control class. Did you try putting a breakpoint in your code to see if it's even getting there? If not, you might try moving this to an override of DefWndProc instead of WndProc. I don't know, maybe both callbacks get it. As I said in my previous post, I had some success. I forgot to mention that I was using Graphics.FromHwnd instead of CreateGraphics. This seemed to work in most cases. I was able to ruin the nonclient area, but could never paint in it. Apparently, I was able to create a Graphics object successfully, but I would always get an exception when creating a Region from the wParam, which would explain why I couldn't paint anything (I couldn't get the bounds in which to paint).

                  -----BEGIN GEEK CODE BLOCK----- Version: 3.21 GCS/G/MU d- s: a- C++++ UL@ P++(+++) L+(--) E--- W+++ N++ o+ K? w++++ O- M(+) V? PS-- PE Y++ PGP++ t++@ 5 X+++ R+@ tv+ b(-)>b++ DI++++ D+ G e++>+++ h---* r+++ y+++ -----END GEEK CODE BLOCK-----

                  W Offline
                  W Offline
                  wangier
                  wrote on last edited by
                  #8

                  I found that there is not difference between WndProc and DefWndProc. Sometimes the WM_NCPAINT 's wParam is 1. In this case, it will not be successful to create a Region. I found the graphics retrived not the same between IntPtr hdc = GetWindowDC(m.HWnd) Graphics g = Graphics.FromHDC(hdc) and Graphics g = Graphics.FromHWnd(hdc)

                  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