On Draw buttons
On Draw buttons
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?
Re:On Draw buttons
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.
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.
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();
}
Re:On Draw buttons
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:
Re:On Draw buttons
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:
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:
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.
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
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();
}