Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

Owner Draw Buttons

Posted on 1997-06-26
14
Medium Priority
?
2,038 Views
Last Modified: 2013-11-19
If I give a button an ownerdraw property, how do I get it to display itself within my dialog box?  I've got a DrawItem routine in my CButton inherited class where I do my customization, but I can't seem to get the button to draw itself.  Is there some basic code necessary for displaying a plain vanilla owner draw button apart from any customization?
0
Comment
Question by:bhonneus
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
14 Comments
 
LVL 2

Expert Comment

by:rajesh032097
ID: 1302316
Did you use SubClassWindow() function in your OnInitDialog() to associate your own button class with the control?
Also use CDC functions to draw wahtever you want inside the control.

0
 
LVL 2

Expert Comment

by:rajesh032097
ID: 1302317
You can use SubclassDlgItem as well.
0
 

Author Comment

by:bhonneus
ID: 1302318
Yes, I did.  I also tried (separately) using the Data Exchange macro which should have been equivalent.  In both cases my DrawItem function got called but the button was not drawn (sorry I didn't clarify this before).

Do I need to override the OnPaint from my CButton derived class?  Currently, I'm not doing this.
0
Moving data to the cloud? Find out if you’re ready

Before moving to the cloud, it is important to carefully define your db needs, plan for the migration & understand prod. environment. This wp explains how to define what you need from a cloud provider, plan for the migration & what putting a cloud solution into practice entails.

 

Author Comment

by:bhonneus
ID: 1302319
Yes, I know.  It still doesn't work using either or both.  What about my question regarding OnPaint?
0
 
LVL 2

Expert Comment

by:rajesh032097
ID: 1302320
Can you provide essential part of your overridden DrawItem() function ?
0
 

Author Comment

by:bhonneus
ID: 1302321
Sure.  Here it is.  The commented out lines were also tried at various times, without success:

void ODButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
      CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
      
      pDC->SetBkColor (RGB(0,255,0)); // Green background
//      lpDrawItemStruct->hDC = pDC->Detach();
//      SetRedraw(TRUE);
//      RedrawWindow();
}

0
 

Author Comment

by:bhonneus
ID: 1302322
Sure.  Here it is.  The commented out lines were also tried at various times, without success:

void ODButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
      CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
      
      pDC->SetBkColor (RGB(0,255,0)); // Green background
//      lpDrawItemStruct->hDC = pDC->Detach();
//      SetRedraw(TRUE);
//      RedrawWindow();
}

0
 
LVL 2

Expert Comment

by:rajesh032097
ID: 1302323
The code seems right, and is working fine in my application.
You don't have to override OnPaint().
Please reject the answer.
I think you should put more light on what's happening exactly because it's very difficult to make out what might have gone wrong with these details.

 
0
 

Author Comment

by:bhonneus
ID: 1302324
Ok.  I've created a sample app with MFC 4.2 which is a simple dialog box with an owner draw button.  The resource code excerpt follows:

IDD_TESTBUTTON_DIALOG DIALOGEX 0, 0, 185, 92
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
EXSTYLE WS_EX_APPWINDOW
CAPTION "TestButton"
FONT 8, "MS Sans Serif"
BEGIN
    DEFPUSHBUTTON   "OK",IDOK,128,7,50,14
    PUSHBUTTON      "Cancel",IDCANCEL,128,23,50,14
    CONTROL         "Button1",IDC_BUTTON1,"Button",BS_OWNERDRAW | WS_TABSTOP,
                    37,30,62,18
END

I'm not customizing anything in the dialog class except for the OnInitDialog:

BOOL CTestButtonDlg::OnInitDialog()
{
     // This is my code
      VERIFY(m_odButton.SubclassDlgItem(IDC_BUTTON1, this));
     // This is my code

//      CDialog::OnInitDialog();

      // Set the icon for this dialog.  The framework does this automatically
      //  when the application's main window is not a dialog
      SetIcon(m_hIcon, TRUE);                  // Set big icon
      SetIcon(m_hIcon, FALSE);            // Set small icon
      
      // TODO: Add extra initialization here
      
      return TRUE;  // return TRUE  unless you set the focus to a control
}

My ODButton class just has one overridden function which is the DrawItem.  When I run the app, the dialog box comes up without the IDC_BUTTON1 drawn.

0
 
LVL 4

Expert Comment

by:AVaulin
ID: 1302325
See SAMPLES\MFC\GENERAL\CTRLTEST example how to use owner draw buttons. Good luck.
0
 

Author Comment

by:bhonneus
ID: 1302326
I just tried modifying the CTRLTEST example.  My sample app is using a CButton derived class, not CBitmapButton which CTRLTEST uses.  So I thought that by changing one of the buttons in CTRLTEST to CButton that I should be able to get it to work and then compare the code to my app.  It didn't work.

I changed one of the CBitmapButton objects in the OwnerButton Test1 dialog to a CButton.  I kept it owner draw and removed all code which dealt with the bitmaps to that button.  Running the test caused an assertion failure and failed to draw the button.

I've upped the points to 100 since this seems like a more difficult problem than I originally anticipated.
0
 

Accepted Solution

by:
rpb earned 200 total points
ID: 1302327
Here is some code that works for me:

void CColourButton::DrawItem(LPDRAWITEMSTRUCT lpDrawStruct)
{
   CDC* pDrawDC = CDC::FromHandle(lpDrawStruct->hDC);
      
   UINT state = lpDrawStruct->itemState;
   if ((state & ODS_SELECTED))
      DrawButtonDown(pDrawDC);
   else
      DrawButtonUp(pDrawDC);
}

And then in each of these functions you can do something like:


void CColourButton::DrawButtonUp(CDC* pDC)
{
   CBrush newBrush;
   CBrush* pOldBrush = NULL;
   CPen drawPen(PS_SOLID, 1, RGB(128, 128, 128));

   // This is a member variable in this case
   GetWindowRect(&m_buttonSize);

   // Draw a nice round rectangle in light grey
   pDC->SelectObject(GetStockObject(LTGRAY_BRUSH));
   pDC->SelectObject(GetStockObject(BLACK_PEN));
   pDC->RoundRect(0, 0, m_buttonSize.Width(), m_buttonSize.Height(), 4, 4);

   // This is the colour of our brush (another member variable)
   newBrush.CreateSolidBrush(m_colour);

   pOldBrush = (CBrush *) pDC->SelectObject(&newBrush);
   pDC->Rectangle(7, 7, m_buttonSize.Width() - 6, m_buttonSize.Height() - 6);
   pDC->SelectObject(pOldBrush);

   // You could now draw the 3D lines if required...
}

Then in your resource file you will want something like this:

   CONTROL "Colour...",ID_COL_BUTTON,"Button",BS_OWNERDRAW | WS_GROUP | WS_TABSTOP,45,145,39,14

This should then draw a grey button with a coloured rectangle in the middle
0
 

Author Comment

by:bhonneus
ID: 1302328
Thanks.  I didn't realize that I had to explicitly draw the button step by step.  What everyone else told me up to now seemed to indicate that Windows had all the info it needed.  I'll play around with this and see what I can come up with!
0
 
LVL 2

Expert Comment

by:rajesh032097
ID: 1302329
Yes,
I didn't realize I should mention that all the painting needs to be done by yourself.
0

Featured Post

Survive A High-Traffic Event with Percona

Your application or website rely on your database to deliver information about products and services to your customers. You can’t afford to have your database lose performance, lose availability or become unresponsive – even for just a few minutes.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction: Dynamic window placements and drawing on a form, simple usage of windows registry as a storage place for information. Continuing from the first article about sudoku.  There we have designed the application and put a lot of user int…
Introduction: Dialogs (2) modeless dialog and a worker thread.  Handling data shared between threads.  Recursive functions. Continuing from the tenth article about sudoku.   Last article we worked with a modal dialog to help maintain informat…
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
In this video, Percona Solutions Engineer Barrett Chambers discusses some of the basic syntax differences between MySQL and MongoDB. To learn more check out our webinar on MongoDB administration for MySQL DBA: https://www.percona.com/resources/we…

721 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question