On Draw buttons

Programming, for all ages and all languages.
Post Reply
Tom

On Draw buttons

Post by Tom »

In a SDI C View app, lets say I put a button there and make it on draw, How would I make it look like a oval?
ark

Re:On Draw buttons

Post by ark »

Do you mean owner draw?

Well, first of all you'll want to create a new class, derived from CButton. When you create the button, do so with the BS_OWNERDRAW button style. Then you simply override CButton::DrawItem in your derived class.

Code: Select all


void COvalButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
  CDC dc;
  dc.Attach(lpDrawItemStruct->hDC);

  // do oval drawing stuff here

  dc.Detach();
}
Go to msdn.microsoft.com, or look at the MSDN library CDs if you have one, and look up CButton::DrawItem. It wouldn't really help things for me to repeat what it says there.
Tom

Re:On Draw buttons

Post by Tom »

Code: Select all

ok I did mean that but when I compile this:
class CMyBtn : CButton
{
public:
   void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
};
BOOL CAboutDlg::PreCreateWindow(CREATESTRUCT& cs) 
{
   CMyBtn btnmy;
   CRect rct( 80, 80, 120, 120 );
   CWnd* pWnd;

   btnmy.Create( _T("Hello"), BS_DEFPUSHBUTTON | BS_OWNERDRAW | WS_VISIBLE, rct, pWnd, IDC_BUTTON1 );
   return CDialog::PreCreateWindow(cs);
}

void CMyBtn::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
  CDC dc;
  dc.Attach(lpDrawItemStruct->hDC);

   COLORREF clrBlue = RGB( 0, 0, 255 );
   CBrush brBlue( clrBlue );

   dc.SelectObject( brBlue );

   dc.Rectangle( 85, 85, 115, 115 );

  dc.Detach();
}

I get this error:
Compiling...
C:\PROGRAM FILES\DEVSTUDIO\MyProjects\Btn\Btn.cpp(169) : error C2248:
'Create' : cannot access public member declared in class 'CButton'
ark

Re:On Draw buttons

Post by ark »

ok, several things...

1) don't do this stuff in PreCreateWindow...pre-create window is called before the about dialog has actually been created -- add a windows message handler for WM_INITDIALOG, if CAboutDlg is a CDialog derived class; otherwise add a WM_CREATE handler

2) under no circumstances should you ever pass an uninitialized pointer to a function (here, I'm referring to the local variable pWnd in CAboutDlg::PreCreateWindow)...because CAboutDlg is derived from CWnd, if I'm not mistaken, you can pass "this" to the button's Create function. You should do that anyway, since I assume you want the dialog to be the button's parent.

3) Don't declare the button as a local variable. It should be a member of the CAboutDlg class. If you declare it local, then its destructor will be called as soon as PreCreateWindow ends, and when the destructor is called for a window class, the attached window is destroyed, which means that even if you created the button successfully it would be destroyed before you could ever see it.

4) your declaration of the CMyBtn class should read as follows:

Code: Select all

class CMyBtn : public CButton
The missing "public" is actually what's causing the error message you're asking about, but I'm pointing out some things that will give you errors after that one is resolved, as well.

5) You need to modify your CMyBtn::DrawItem code:

Code: Select all

void CMyBtn::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
  CDC dc;
  dc.Attach(lpDrawItemStruct->hDC);

   COLORREF clrBlue = RGB( 0, 0, 255 );
   COLORREF clrOld;
   CBrush brBlue( clrBlue );
   CBrush* pbrOld;

   pbrOld = dc.SelectObject(&brBlue );

//   dc.Rectangle( 85, 85, 115, 115 );
   RECT rect;
   GetClientRect(&rect);
   dc.Rectangle(0, 0, rect.right, rect.bottom);

   clrOld = dc.SetBkColor(clrBlue);
   dc.DrawText(_T("Hello"), &rect, DT_SINGLELINE | DT_VCENTER | DT_CENTER);

   dc.SetBkColor(clrOld);
   dc.SelectObject(pbrOld);

  dc.Detach();
}
With an owner-drawn button, you have to do ALL the drawing yourself, including the button's label, the "depressed" state, the focused state, etc. About the only thing Windows does for you is draw a gray background.
Tom

Re:On Draw buttons

Post by Tom »

TY ;D I know where to come for Win32 programing help!
Post Reply