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 / C++ / MFC
  4. Ultimate Toolbox's drawing style

Ultimate Toolbox's drawing style

Scheduled Pinned Locked Moved C / C++ / MFC
c++comgraphicstutorialquestion
12 Posts 5 Posters 2 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 Offline
    S Offline
    sawerr
    wrote on last edited by
    #1

    Hi I have downloaded Ultimate Toolbox( http://www.codeproject.com/KB/MFC/UltimateToolbox.aspx[^] source code. And i see that for drawing controls, some of controls source code overrode OnDrawItem and put drawing code in there, some of them in OnPaint message handler, some of them both. How does a control developer make decision when only Onpaint or only Drawitem or both of them must be used? Is this relative to control(for example drawing a custom buton is different combobox or etc.) or relative to drawing style? Could you please give me some trick? Thanks...

    S J N 3 Replies Last reply
    0
    • S sawerr

      Hi I have downloaded Ultimate Toolbox( http://www.codeproject.com/KB/MFC/UltimateToolbox.aspx[^] source code. And i see that for drawing controls, some of controls source code overrode OnDrawItem and put drawing code in there, some of them in OnPaint message handler, some of them both. How does a control developer make decision when only Onpaint or only Drawitem or both of them must be used? Is this relative to control(for example drawing a custom buton is different combobox or etc.) or relative to drawing style? Could you please give me some trick? Thanks...

      S Offline
      S Offline
      Saurabh Garg
      wrote on last edited by
      #2

      For questions related a particular article you should use the comments section at the bottom of the article. -Saurabh

      M 1 Reply Last reply
      0
      • S Saurabh Garg

        For questions related a particular article you should use the comments section at the bottom of the article. -Saurabh

        M Offline
        M Offline
        Maximilien
        wrote on last edited by
        #3

        This is a general MFC question (could be completly unrelated to Dundas toolbox), so I think this is a valid place to ask.

        This signature was proudly tested on animals.

        1 Reply Last reply
        0
        • S sawerr

          Hi I have downloaded Ultimate Toolbox( http://www.codeproject.com/KB/MFC/UltimateToolbox.aspx[^] source code. And i see that for drawing controls, some of controls source code overrode OnDrawItem and put drawing code in there, some of them in OnPaint message handler, some of them both. How does a control developer make decision when only Onpaint or only Drawitem or both of them must be used? Is this relative to control(for example drawing a custom buton is different combobox or etc.) or relative to drawing style? Could you please give me some trick? Thanks...

          J Offline
          J Offline
          James R Twine
          wrote on last edited by
          #4

          Some controls do not have the concept of an "item."  For example, an edit control does not have a DrawItem message (IIRC), while a ComboBox does.    You may have to handle both because of what you are allowed to touch in each message handler, and because of what "phase" in the drawing process you are at.  For example, you may not be able to successfully custom-draw the drop-down button on a combobox during the DrawItem phase -- maybe it gets overwritten/redrawn after that phase completes.    Peace!

          -=- James
          Please rate this message - let me know if I helped or not! * * * If you think it costs a lot to do it right, just wait until you find out how much it costs to do it wrong!
          Remember that Professional Driver on Closed Course does not mean your Dumb Ass on a Public Road!
          See DeleteFXPFiles

          S 1 Reply Last reply
          0
          • J James R Twine

            Some controls do not have the concept of an "item."  For example, an edit control does not have a DrawItem message (IIRC), while a ComboBox does.    You may have to handle both because of what you are allowed to touch in each message handler, and because of what "phase" in the drawing process you are at.  For example, you may not be able to successfully custom-draw the drop-down button on a combobox during the DrawItem phase -- maybe it gets overwritten/redrawn after that phase completes.    Peace!

            -=- James
            Please rate this message - let me know if I helped or not! * * * If you think it costs a lot to do it right, just wait until you find out how much it costs to do it wrong!
            Remember that Professional Driver on Closed Course does not mean your Dumb Ass on a Public Road!
            See DeleteFXPFiles

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

            James R. Twine wrote:

            Some controls do not have the concept of an "item." For example, an edit control does not have a DrawItem message (IIRC), while a ComboBox does.

            I confused here. Yes some control have concept of an item. Like combobox, Listbox...We can add items(strings, color) to that controls so they have DrawItem virtual method. But why does CButton class have virtual DrawItem method? What can we add such a control so it has a concept of an "item"? Thanks for answer.

            J 1 Reply Last reply
            0
            • S sawerr

              James R. Twine wrote:

              Some controls do not have the concept of an "item." For example, an edit control does not have a DrawItem message (IIRC), while a ComboBox does.

              I confused here. Yes some control have concept of an item. Like combobox, Listbox...We can add items(strings, color) to that controls so they have DrawItem virtual method. But why does CButton class have virtual DrawItem method? What can we add such a control so it has a concept of an "item"? Thanks for answer.

              J Offline
              J Offline
              James R Twine
              wrote on last edited by
              #6

              Yes, some of the controls do not make sense, Button and Static controls have an item draw message, even though it might not make much sense.  Also, lots of virtual functions exist on the CWnd base class that may not apply to all of its derives classes, like CWnd::OnDrawItem.    Peace!

              -=- James
              Please rate this message - let me know if I helped or not! * * * If you think it costs a lot to do it right, just wait until you find out how much it costs to do it wrong!
              Remember that Professional Driver on Closed Course does not mean your Dumb Ass on a Public Road!
              See DeleteFXPFiles

              S 1 Reply Last reply
              0
              • J James R Twine

                Yes, some of the controls do not make sense, Button and Static controls have an item draw message, even though it might not make much sense.  Also, lots of virtual functions exist on the CWnd base class that may not apply to all of its derives classes, like CWnd::OnDrawItem.    Peace!

                -=- James
                Please rate this message - let me know if I helped or not! * * * If you think it costs a lot to do it right, just wait until you find out how much it costs to do it wrong!
                Remember that Professional Driver on Closed Course does not mean your Dumb Ass on a Public Road!
                See DeleteFXPFiles

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

                OK. If i turn back my question in my firstpost: How does a control developer make decision when only Onpaint or only Drawitem or both of them must be used? Is this relative to control(for example drawing a custom buton is different combobox or etc.) or relative to drawing style? Can we say that: If a control has owner draw property we must paint items of control in DrawItem method (like this : http://msdn.microsoft.com/en-us/visualc/bb838680.aspx[^] but if we want draw combobox itself, we must handle that in OnPaint Handler. We mustn't draw items in onpaint if it support ownerdraw ?? I asked this because i am not sure about my logic. Because for example in that application(custom button) http://www.codeproject.com/KB/buttons/roundbuttons.aspx[^] he made all the drawing in the DrawItem method. Thanks for help...

                1 Reply Last reply
                0
                • S sawerr

                  Hi I have downloaded Ultimate Toolbox( http://www.codeproject.com/KB/MFC/UltimateToolbox.aspx[^] source code. And i see that for drawing controls, some of controls source code overrode OnDrawItem and put drawing code in there, some of them in OnPaint message handler, some of them both. How does a control developer make decision when only Onpaint or only Drawitem or both of them must be used? Is this relative to control(for example drawing a custom buton is different combobox or etc.) or relative to drawing style? Could you please give me some trick? Thanks...

                  N Offline
                  N Offline
                  Nibu babu thomas
                  wrote on last edited by
                  #8

                  sawerr wrote:

                  some of controls source code overrode OnDrawItem and put drawing code in there

                  Well OnDrawItem is mainly provdided to facilitate owner drawing controls without sub classing them. An e.g. would be a tab control, we can owner draw a tab control without sub classing it using this function. Signature of OnDrawItem is as follows, nIDCtl points to the ID of the controls that's meant to owner drawn. So here you will get the id of your tab control and you can owner draw it here. afx_msg void OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct); There is another option, that's by subclassing and overriding DrawItem virtual function. Note that DrawItem get's called by OnDrawItem. Stack trace to DrawItem virtual member function is as follows...

                  CListBoxEx::DrawItem(tagDRAWITEMSTRUCT * 0x0012f6d4) line 20
                  CListBox::OnChildNotify(unsigned int 43, unsigned int 1000, long 1242836, long * 0x00000000) line 125
                  CWnd::SendChildNotifyLastMsg(long * 0x00000000) line 2683
                  CWnd::ReflectLastMsg(HWND__ * 0x0004089a, long * 0x00000000) line 2721
                  CWnd::OnDrawItem(int 1000, tagDRAWITEMSTRUCT * 0x0012f6d4) line 1156 + 14 bytes
                  CLearnDrawingDlg::OnDrawItem(int 1000, tagDRAWITEMSTRUCT * 0x0012f6d4) line 46
                  CWnd::OnWndMsg(unsigned int 43, unsigned int 1000, long 1242836, long * 0x0012f4f0) line 1930

                  sawerr wrote:

                  How does a control developer make decision when only Onpaint or only Drawitem or both of them must be used?

                  DrawItem messages makes things easier for developers, we get OD flags that tells which action requires painting. For e.g. ODS_CHECKED ODS_FOCUS ODS_DISABLED. We just have to do the painting stuff. But if we are going via OnPaint then we are on our own, we've got to find out when an item is selected, when it's in focus, when it's disabled based on every paint event that we get. Maybe even scrolling too. So that's for the tough guys. ;) So basically for quick and easy painting things we got via OnDrawItem, or DrawItem else for full control we go via OnPaint. This is my understanding on this topic!

                  sawerr wrote:

                  downloaded Ultimate Toolbox

                  I did have the privilege of working on this project with Nishant! Didn't do much development though. :) My first i

                  S 1 Reply Last reply
                  0
                  • N Nibu babu thomas

                    sawerr wrote:

                    some of controls source code overrode OnDrawItem and put drawing code in there

                    Well OnDrawItem is mainly provdided to facilitate owner drawing controls without sub classing them. An e.g. would be a tab control, we can owner draw a tab control without sub classing it using this function. Signature of OnDrawItem is as follows, nIDCtl points to the ID of the controls that's meant to owner drawn. So here you will get the id of your tab control and you can owner draw it here. afx_msg void OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct); There is another option, that's by subclassing and overriding DrawItem virtual function. Note that DrawItem get's called by OnDrawItem. Stack trace to DrawItem virtual member function is as follows...

                    CListBoxEx::DrawItem(tagDRAWITEMSTRUCT * 0x0012f6d4) line 20
                    CListBox::OnChildNotify(unsigned int 43, unsigned int 1000, long 1242836, long * 0x00000000) line 125
                    CWnd::SendChildNotifyLastMsg(long * 0x00000000) line 2683
                    CWnd::ReflectLastMsg(HWND__ * 0x0004089a, long * 0x00000000) line 2721
                    CWnd::OnDrawItem(int 1000, tagDRAWITEMSTRUCT * 0x0012f6d4) line 1156 + 14 bytes
                    CLearnDrawingDlg::OnDrawItem(int 1000, tagDRAWITEMSTRUCT * 0x0012f6d4) line 46
                    CWnd::OnWndMsg(unsigned int 43, unsigned int 1000, long 1242836, long * 0x0012f4f0) line 1930

                    sawerr wrote:

                    How does a control developer make decision when only Onpaint or only Drawitem or both of them must be used?

                    DrawItem messages makes things easier for developers, we get OD flags that tells which action requires painting. For e.g. ODS_CHECKED ODS_FOCUS ODS_DISABLED. We just have to do the painting stuff. But if we are going via OnPaint then we are on our own, we've got to find out when an item is selected, when it's in focus, when it's disabled based on every paint event that we get. Maybe even scrolling too. So that's for the tough guys. ;) So basically for quick and easy painting things we got via OnDrawItem, or DrawItem else for full control we go via OnPaint. This is my understanding on this topic!

                    sawerr wrote:

                    downloaded Ultimate Toolbox

                    I did have the privilege of working on this project with Nishant! Didn't do much development though. :) My first i

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

                    OK. So Can we say: "Use OwnerDraw Method when we can, and OnPaint when we have to"? I think DrawItem MEthod is not only for "items". We can paint/make entire control. Right? For example we can make elliptic buttons in ownerdraw(): CRect rect = lpDrawItemStruct->rcItem; dc.Ellipse(rect); Also we can change the combobox's items drawing style. But can we change style of combobox itself, not only items with only ownerdraw method?Or, If we want this, must we use onpaint handler? I tried this code for listbox:

                    void CMyListBox::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
                    {

                    // TODO:  Add your code to draw the specified item
                    CRect rect = lpDrawItemStruct->rcItem;
                    CDC dc;
                    dc.Attach(lpDrawItemStruct->hDC);
                    dc.Ellipse(&rect);
                    

                    }

                    it draws a circle in the listbox, not draw elliptic listbox. But same code makes elliptic button. IS that a right scenario to see that when we need onpaint and can't be done such a thing with DrawItem Method? We can draw entire button with ownerdraw method, but we can't draw Listbox or combobox with ownerdraw, only it is items? Thanks for all answers...

                    N 1 Reply Last reply
                    0
                    • S sawerr

                      OK. So Can we say: "Use OwnerDraw Method when we can, and OnPaint when we have to"? I think DrawItem MEthod is not only for "items". We can paint/make entire control. Right? For example we can make elliptic buttons in ownerdraw(): CRect rect = lpDrawItemStruct->rcItem; dc.Ellipse(rect); Also we can change the combobox's items drawing style. But can we change style of combobox itself, not only items with only ownerdraw method?Or, If we want this, must we use onpaint handler? I tried this code for listbox:

                      void CMyListBox::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
                      {

                      // TODO:  Add your code to draw the specified item
                      CRect rect = lpDrawItemStruct->rcItem;
                      CDC dc;
                      dc.Attach(lpDrawItemStruct->hDC);
                      dc.Ellipse(&rect);
                      

                      }

                      it draws a circle in the listbox, not draw elliptic listbox. But same code makes elliptic button. IS that a right scenario to see that when we need onpaint and can't be done such a thing with DrawItem Method? We can draw entire button with ownerdraw method, but we can't draw Listbox or combobox with ownerdraw, only it is items? Thanks for all answers...

                      N Offline
                      N Offline
                      Nibu babu thomas
                      wrote on last edited by
                      #10

                      sawerr wrote:

                      I think DrawItem MEthod is not only for "items". We can paint/make entire control. Right?

                      You are limited in DrawItem function. The point is that it's just a helper function. The master of these functions is OnPaint or WM_PAINT message.

                      sawerr wrote:

                      For example we can make elliptic buttons in ownerdraw(): CRect rect = lpDrawItemStruct->rcItem; dc.Ellipse(rect);

                      You are not free to draw anything anytime in DrawItem functions. There is a rule. You draw based on the flag's that's passed in. So if the flag tells you draw entire client area (ODA_DRAWENTIRE)then go around splashing colors, else if it's just to paint a focus rect (ODA_FOCUS) then you can't do that. Now you may ask how to know if have to draw a focus rect or remove a focus rect, that's why we have the state flag ODS_FOCUS. Do the same in OnPaint in and you will what I meant.

                      sawerr wrote:

                      IS that a right scenario to see that when we need onpaint and can't be done such a thing with DrawItem Method? We can draw entire button with ownerdraw method, but we can't draw Listbox or combobox with ownerdraw, only it is items?

                      Can you rephrase this question? :) My brain just fell apart!

                      Nibu babu thomas Microsoft MVP for VC++ Code must be written to be read, not by the compiler, but by another human being. Programming Blog: http://nibuthomas.wordpress.com

                      S 1 Reply Last reply
                      0
                      • N Nibu babu thomas

                        sawerr wrote:

                        I think DrawItem MEthod is not only for "items". We can paint/make entire control. Right?

                        You are limited in DrawItem function. The point is that it's just a helper function. The master of these functions is OnPaint or WM_PAINT message.

                        sawerr wrote:

                        For example we can make elliptic buttons in ownerdraw(): CRect rect = lpDrawItemStruct->rcItem; dc.Ellipse(rect);

                        You are not free to draw anything anytime in DrawItem functions. There is a rule. You draw based on the flag's that's passed in. So if the flag tells you draw entire client area (ODA_DRAWENTIRE)then go around splashing colors, else if it's just to paint a focus rect (ODA_FOCUS) then you can't do that. Now you may ask how to know if have to draw a focus rect or remove a focus rect, that's why we have the state flag ODS_FOCUS. Do the same in OnPaint in and you will what I meant.

                        sawerr wrote:

                        IS that a right scenario to see that when we need onpaint and can't be done such a thing with DrawItem Method? We can draw entire button with ownerdraw method, but we can't draw Listbox or combobox with ownerdraw, only it is items?

                        Can you rephrase this question? :) My brain just fell apart!

                        Nibu babu thomas Microsoft MVP for VC++ Code must be written to be read, not by the compiler, but by another human being. Programming Blog: http://nibuthomas.wordpress.com

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

                        OK. DRAWITEMSTRUCT has got a hDC member which identifies a device context. Is that Device Context for drawing shapes or etc. things to the surface of the control or redraw control itself. For example:

                        void CMyButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
                        {
                        CDC *pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
                        CRect rect;
                        GetClientRect(&rect);
                        rect.DeflateRect(20,50);
                        pDC->Ellipse(rect);
                        }

                        That code draws an ellipse to the surface of the button, not elliptic button. Because when i clicked out of ellipse buttonclicked handler invoked. I tried same thing for OnPaint() -->> CPaintDC dc(this); It gave me same result. 1-) Is there a way to get DC for drawing control itself, not its surface? 2-)If yes, how can i understand which DC is for surface of control and which DC is for draw a control? Thanks for all helps...

                        N 1 Reply Last reply
                        0
                        • S sawerr

                          OK. DRAWITEMSTRUCT has got a hDC member which identifies a device context. Is that Device Context for drawing shapes or etc. things to the surface of the control or redraw control itself. For example:

                          void CMyButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
                          {
                          CDC *pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
                          CRect rect;
                          GetClientRect(&rect);
                          rect.DeflateRect(20,50);
                          pDC->Ellipse(rect);
                          }

                          That code draws an ellipse to the surface of the button, not elliptic button. Because when i clicked out of ellipse buttonclicked handler invoked. I tried same thing for OnPaint() -->> CPaintDC dc(this); It gave me same result. 1-) Is there a way to get DC for drawing control itself, not its surface? 2-)If yes, how can i understand which DC is for surface of control and which DC is for draw a control? Thanks for all helps...

                          N Offline
                          N Offline
                          Nibu babu thomas
                          wrote on last edited by
                          #12

                          sawerr wrote:

                          1-) Is there a way to get DC for drawing control itself, not its surface?

                          So you want to change the shape of the control itself! For that you've got to call SetWindowRgn. You can use functions in CRgn class to create a region your window. To create an elliptical dialog you just have to call SetWindowRgn with a region parameter from OnInitDialog. Read this for more information.[^]

                          sawerr wrote:

                          2-)If yes, how can i understand which DC is for surface of control and which DC is for draw a control?

                          There is nothing like surface and a control dc. It's just one control dc which is just used for painting on top of a control.

                          Nibu babu thomas Microsoft MVP for VC++ Code must be written to be read, not by the compiler, but by another human being. Programming Blog: http://nibuthomas.wordpress.com

                          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