|
不错不错
|
|
|
|
|
|
[code]/ LedButton.cpp : implementation file
//
#include "stdafx.h"
#include "LedButton.h"
#include ".\ledbutton.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
CLedButton::CLedButton(void)
{
m_bDepressed = false;
m_bCenterAlign = true;
m_nMargin = DEFAULT_MARGIN;
m_bReadOnly = false;
}
CLedButton::~CLedButton(void)
{
}
BEGIN_MESSAGE_MAP(CLedButton, CButton)
ON_CONTROL_REFLECT(BN_CLICKED, OnBnClicked)
END_MESSAGE_MAP()
void CLedButton::PreSubclassWindow(void)
{
CButton::PreSubclassWindow();
ModifyStyle(0, BS_OWNERDRAW);
CRect rect;
GetClientRect(rect);
LOGFONT lf;
GetFont()->GetLogFont(&lf);
m_nRadius = lf.lfHeight;
if(m_nRadius == 0)
m_nRadius = 15;
else if(m_nRadius < 0)
m_nRadius = (-1)*m_nRadius;
m_nRadius = (int)(rect.bottom * 0.5) - 5;
if(m_nRadius > 6)
m_nRadius = 6;
m_ptCenter.x = rect.left + m_nRadius + 1;
if(m_bCenterAlign)
m_ptCenter.y = rect.top + (int)(rect.Height() * 0.5 + 0.5);
else
m_ptCenter.y = rect.top + m_nRadius+1;
}
void CLedButton::SetImage(UINT uBmpRes, UINT nImageWidth)
{
m_imgList.Create(uBmpRes, nImageWidth);
m_szImage = m_imgList.GetImageDimension();
m_ptCenter.x = 1; // m_ptCenter.x - rcImage.cx / 2;
m_ptCenter.y = m_ptCenter.y - m_szImage.cy/2;
if(m_nMargin < m_szImage.cx)
m_nMargin = 5 + m_szImage.cx;
}
void CLedButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
ASSERT(lpDrawItemStruct != NULL);
if(lpDrawItemStruct->itemAction != ODA_DRAWENTIRE)
return;
CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
CRect rcItem = lpDrawItemStruct->rcItem;
int nSavedDC = pDC->SaveDC();
pDC->SelectStockObject(NULL_BRUSH);
pDC->FillSolidRect(rcItem, ::GetSysColor(COLOR_BTNFACE));
if(m_bDepressed)
m_imgList.Draw(pDC, 1, m_ptCenter);
else
m_imgList.Draw(pDC, 0, m_ptCenter);
CString strText;
GetWindowText(strText);
CSize szExtent;
CPoint pt;
CRect rcText;
CRect rcClient;
GetClientRect(&rcClient);
rcText = rcClient;
rcText.left += m_nMargin;
rcText.right -= 2;
if(!strText.IsEmpty())
{
pDC->SetBkMode(TRANSPARENT);
pDC->DrawText(strText, rcText, DT_LEFT | DT_NOPREFIX | DT_WORDBREAK | DT_CALCRECT);
int nHeight = rcText.Height();
rcText.top = rcClient.top + (int)((rcClient.Height() - rcText.Height()) * 0.5 + 0.5);
rcText.bottom = rcText.top + nHeight;
pDC->DrawText(strText, rcText, DT_LEFT | DT_NOPREFIX | DT_WORDBREAK);
m_rcText = rcText;
}
rcText.right += 2;
pDC->RestoreDC(nSavedDC);
}
bool CLedButton::IsDepressed(void)
{
return m_bDepressed;
}
bool CLedButton::SetState(bool bPressed)
{
if(bPressed != m_bDepressed)
{
m_bDepressed = bPressed;
SetCheck(bPressed ? BST_CHECKED : BST_UNCHECKED);
RedrawWindow();
}
return m_bDepressed;
}
void CLedButton::SetReadOnly(bool bReadOnly)
{
m_bReadOnly = bReadOnly;
}
void CLedButton::OnBnClicked(void)
{
if(!m_bReadOnly)
SetState(m_bDepressed ? false : true);
}
[/code]
That was the Source File...
[code]class CLedButton : public CButton
{
public:
CLedButton(void);
virtual ~CLedButton(void);
public:
void SetImage(UINT idBmp, UINT nWidthOfOneImage);
public:
bool SetState(bool bPressed);
bool IsDepressed(void);
void SetReadOnly(bool bReadOnly = true);
protected:
virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
virtual void PreSubclassWindow(void);
protected:
int m_nMargin;
int m_nRadius;
CPoint m_ptCenter;
CRect m_rcText;
bool m_bDepressed;
bool m_bCenterAlign;
bool m_bReadOnly;
CRGBImageList m_imgList;
CSize m_szImage;
protected:
afx_msg void OnBnClicked(void);
DECLARE_MESSAGE_MAP()
};[/code]
Na dann mal viel Spaß mit den verbesserungen
|
|
|
|
|
I use MFC and VS ver. 6.0. Eveything works fine until I
add more buttons in a dialog box. One or two controls work but more controls (and thier variables) will cause
anomally in the real time behavior of the application (it uses real-time
multimedia functions).
Some more information:
1. Its a big application - the exeutable relaease is around 2 mbytes and has
many resources(static MFC link).
2. In the debug version there are no problems(shared MFC link).
Thanks in advance
Lesi
|
|
|
|
|
I tried to used your class and added a checkbox control to a CFormView.
However, it did not show the bitmap but an orginary checkbox...
I tried to added the following code
<br />
m_ButtonLED.SetImage(IDB_LEDGREEN, 15);<br />
m_ButtonLED.Depress(TRUE);<br />
I tried to applied the code to OnInitialUpdate() and OnDraw(), both of them did not work out...
Can anyone tell me how to use this class in a CFormView? I sure someone did it before... Thanks a lot!;)
Help! I need somebody help!
Would you please help me?
|
|
|
|
|
Thanks for this nice job, it has been very helpfull for me.
But with small modification you can keep the tab order and disable button functionality:
Add the folowing entry in the message map :
<br />
BEGIN_MESSAGE_MAP(CLedButton, CButton)<br />
ON_WM_GETDLGCODE()<br />
END_MESSAGE_MAP()<br />
then return the wanted value in the associated call back, for exemple :
<br />
UINT CLedButton::OnGetDlgCode( )<br />
{<br />
Invalidate();<br />
return DLGC_RADIOBUTTON;<br />
}<br />
Then in the paint method use ::GetFocus() to know if the control has the focus and use textRect to draw dot line other the text.
In this method you can also call IsWindowEnabled( ) to know if a gray text is needed.
|
|
|
|
|
I was trying to create CLedButtons in Runtime and used the following code.
The snip below works with CButton, with CLedButton it doesn't. Anyone an idea why? thanks a lot -
CLedButton *tst;
tst = new CLedButton;
tst->Create(_T("Text"), WS_CHILD|WS_VISIBLE, CRect(10,10,20,20), this, IDC_CHK_TST);
|
|
|
|
|
I am think of using this class to create led buttons on a dialog bar, I just need some help to how to place the bitmaps on the buttons that is located on a dialog bar control.
any info would be most helpful
|
|
|
|
|
This is obviously badly hacked code originating from Chris Maunders excellent CRoundbutton class. Its obviously not a bad idea and id rather see it posted than not. However 'plagiarism' is a poor form of vanity. You should have said something like 'Hi, im a total beginner and I hacked chris' code and came up with this half baked class that sort of works. Are there any real programmers out there willing to take this idea and implement it properly?'. I may have a go myself at some point, although im sure there are plenty of others who could do better than this. To get the buttons to click on and off for example, all you need is something like :
void CLedButton::OnLButtonDown(UINT nHitTest, CPoint point)
{
SetCheck(!GetCheck());
RedrawWindow();
CButton::OnLButtonDown(nHitTest, point);
}
While Im here ive a question for everyone :
Is there any way of accessing the dc for the default radio button itself?
I dont mean the whole button (which is easy eg letting the parent receive the WM_CTLCOLORSTATIC message). How is the white circle created and where. And can it be accessed? Can the black dot check be accessed? I want to be able to change the colour of the dot in the radio button without recourse to BS_OWNERDRAW and bitmaps. Anybody have any ideas about this?
"Life begins at 140"
|
|
|
|
|
You gotta love a comment like this coming from somebody that cant even come up with a decent handle of his own. Worse, the creep has to use some other persons name in what I can only guess was a lame ass attempt to give himself some creditabilty. So sad.
|
|
|
|
|
Great Class. It was just what I was looking for.
Some of my checkbox indicators needed to toggle between red/green. I was going to use the SetImage method to change them.
Fortunatly, I realized that a new bitmap with red in the first position and green in the position would toggle just by setting depress true or false.
I made the new .bmp as a 256 color thing as now we have two sets of colors in the pallet. The LEDs looked crummy with 16 colors.
Anyway, it works like a charm.
Thanks, Mark Kozel
|
|
|
|
|
There are two lines of code that should be modified so that the bmp and the text are positioned vertically in their correct position.
The issue is that you should be subtracting and not adding to get to the center...
in void CLedButton::PreSubclassWindow() :
// m_ptCenter.y = rect.top+(int)(rect.Height()*0.5+0.5); // old
m_ptCenter.y = rect.top+(int)(rect.Height()*0.5-0.5); // new
and in void CLedButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) :
// textRect.top = clientRect.top+(int)((clientRect.Height()-textRect.Height())*0.5+0.5);
textRect.top = clientRect.top+(int)((clientRect.Height()-textRect.Height())*0.5-0.5);
|
|
|
|
|
You're right,
but it's not because I am adding 0.5,
it is because I'm adding the value to the rect.top position.
I should have been substracting the value to the rect.bottom position instead !
http://www.softLion.com
|
|
|
|
|
If I do docking, how I can show LED Button and control?
---------------------------------------------------------
I study MFC, and I intereted in your LED Button Source.
So, I made the dialog of your LED Button docked.
but, I can't see your bitmap LED Button. and contol,
How can I do? Please Help Me!!!!
pcstone@shinbiro.com
|
|
|
|
|
You need to update the display
by drawing the button in your ondraw function.
|
|
|
|
|
hi author,
I tried to use your code in one of my programs,
it worked, however with
setbitmap(IDB_IMAGE, 100) for example.
depress(true);
how do i destroy the image, to get a next image on the led button, it keeps giving me an assertion error.
thanks for your code, need reply pretty soon.
|
|
|
|
|
Just modify the CLedButton::SetImage function in LedButton.cpp so you will have:
void CLedButton::SetImage(UINT idBmp, UINT nWidthOfOneImage)
{
m_imgList.DeleteImageList();
m_imgList.Create( idBmp, nWidthOfOneImage );
m_rcImage = m_imgList.GetImageDimension();
m_ptCenter.x = 1; //m_ptCenter.x - rcImage.cx/2;
m_ptCenter.y = m_ptCenter.y - m_rcImage.cy/2;
if( m_nMargin
|
|
|
|
|
I am proposing a small changes to the class functions in the author's suggestion:
CRGBImageList()
{
m_dcMem.CreateCompatibleDC(NULL);
m_old = NULL;
m_hImage = NULL;
}
virtual ~CRGBImageList()
{
DeleteImageList();
m_dcMem.DeleteDC();
}
void DeleteImageList()
{
if( m_hImage )
{
m_dcMem.SelectObject(m_old);
m_old = NULL;
m_bmp.Detach();
::DeleteObject(m_hImage);
m_hImage = NULL;
}
}
BOOL Create( UINT idBitmap, UINT nWidth )
{
DeleteImageList(); //**** NEW ****
m_hImage = (HBITMAP)::LoadImage( AfxGetInstanceHandle(), MAKEINTRESOURCE(idBitmap), IMAGE_BITMAP, 0, 0, LR_LOADTRANSPARENT|LR_LOADMAP3DCOLORS );
if( !m_hImage ) return FALSE;
m_bmp.Attach(m_hImage);
m_width = nWidth;
//CSize size = m_bmp.GetBitmapDimension(); //Must be set by SetBitmapDimension: unusable here.
m_bmp.GetObject(sizeof(BITMAP),&m_bmpInfo);
m_height = m_bmpInfo.bmHeight;
m_old = m_dcMem.SelectObject(&m_bmp);
return TRUE;
}
|
|
|
|