Solved

Background button flashing ...

Posted on 1998-04-25
1
433 Views
Last Modified: 2013-11-19
I have created a class named CAlarmButton. This class permit to falsh
background when I call member function StartFlashing and stop it when
calling member function StopFlashing.
The StartFlashing function starts a timer which Invalidate the control.
The StopFlashing function stop the timer.

My problem is when I use more then one button and when I call StartFlashing
for each button, all button are not flashing in rhythm. I wan't that all button
flash in rhythm.

I have tried to start the timer when I construct the control, but the result
is the same !

How can I do this ?

You can find the code below.

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------

class CAlarmButton : public CButton
 {
  COLORREF  m_BackgroundColor1, m_BackgroundColor2, m_BackgroundColor, m_TextColor;
  BOOL      m_IsBackgroundFlashing;
  CBitmap  *m_pImage, *m_pMask;
  int       m_ImageW, m_ImageH;
  UINT      m_TextAlignment, m_ImageAlignment;
  BOOL      m_HoldState;
 
  // Construction
  public :
           CAlarmButton();

           void SetBackgroundColor(COLORREF BackgroundColor, BOOL First = TRUE);
           void SetTextColor(COLORREF TextColor);
           void StartFlashing(UINT Time = 1000);
           void StopFlashing();
           void SetBitmap(UINT ImageID, UINT MaskID = NULL);
           void SetTextAlignment(UINT Alignment = HCENTER | VCENTER);
           void SetImageAlignment(UINT Alignment = HCENTER | VCENTER);
           void HoldState(BOOL HoldState = FALSE);

  // Attributes
  public :

  // Operations
  public :
           BOOL ModifyStyle(DWORD dwRemove, DWORD dwAdd, UINT nFlags = 0);

  // Overrides
      // ClassWizard generated virtual function overrides
      //{{AFX_VIRTUAL(CAlarmButton)
      protected:
      virtual void PreSubclassWindow();
    virtual void DrawItem(LPDRAWITEMSTRUCT);
      //}}AFX_VIRTUAL

  // Implementation
  public :
           virtual ~CAlarmButton();

  // Generated message map functions
  protected :
      //{{AFX_MSG(CAlarmButton)
      afx_msg void OnTimer(UINT nIDEvent);
      afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
      afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
      //}}AFX_MSG

  DECLARE_MESSAGE_MAP()
 };

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------

CAlarmButton::CAlarmButton()
 {
  m_BackgroundColor  = m_BackgroundColor1 = RGB(198,198,198);
  m_BackgroundColor2 = RGB(255,0,0);
  m_TextColor        = RGB(0,0,0);

  m_IsBackgroundFlashing = FALSE;
  m_pImage               = NULL;
  m_pMask                = NULL;
  m_TextAlignment        = HCENTER | VCENTER;
  m_ImageAlignment       = HCENTER | VCENTER;
  m_HoldState            = FALSE;
 }

// --------------------------------------------------------------------------

CAlarmButton::~CAlarmButton()
 {
  if (m_pImage) delete m_pImage;
  if (m_pMask ) delete m_pMask;
 }

// --------------------------------------------------------------------------

void CAlarmButton::SetBackgroundColor(COLORREF BackgroundColor, BOOL First)
 {
  if (First) m_BackgroundColor1 = BackgroundColor;
  else m_BackgroundColor2 = BackgroundColor;
 }

// --------------------------------------------------------------------------

void CAlarmButton::StartFlashing(UINT Time)
 {
  SetTimer(TIMER_FLASHING, Time, NULL);
 }

// --------------------------------------------------------------------------

void CAlarmButton::StopFlashing()
 {
  KillTimer(TIMER_FLASHING);
  m_BackgroundColor = m_BackgroundColor1;
  Invalidate();
 }

// --------------------------------------------------------------------------

void CAlarmButton::SetBitmap(UINT ImageID, UINT MaskID)
 {
  if (m_pImage) delete m_pImage;
  if (m_pMask) delete m_pMask;

  m_pImage = m_pMask = NULL;

  if (ImageID)
   {
    m_pImage = new CBitmap;
    m_pImage->LoadBitmap(ImageID);

    BITMAP Bitmap;
    m_pImage->GetBitmap(&Bitmap);
    m_ImageW = Bitmap.bmWidth;
    m_ImageH = Bitmap.bmHeight;
   }
 
  if (MaskID)
   {
    m_pMask = new CBitmap;
    m_pMask->LoadBitmap(MaskID);
   }

  Invalidate();
 }

// --------------------------------------------------------------------------

void CAlarmButton::SetTextAlignment(UINT Alignment)
 {
  m_TextAlignment = Alignment;
  Invalidate();
 }

// --------------------------------------------------------------------------

void CAlarmButton::SetImageAlignment(UINT Alignment)
 {
  m_ImageAlignment = Alignment;
  Invalidate();
 }

// --------------------------------------------------------------------------

void CAlarmButton::HoldState(BOOL HoldState)
 {
  m_HoldState = HoldState;
 }

// --------------------------------------------------------------------------

BOOL CAlarmButton::ModifyStyle(DWORD dwRemove, DWORD dwAdd, UINT nFlags)
 {
  BOOL rcCode = CButton::ModifyStyle(dwRemove,dwAdd,nFlags);

  Invalidate();

  return rcCode;
 }

// --------------------------------------------------------------------------

BEGIN_MESSAGE_MAP(CAlarmButton, CButton)
      //{{AFX_MSG_MAP(CAlarmButton)
      ON_WM_TIMER()
      ON_WM_LBUTTONDOWN()
      ON_WM_LBUTTONUP()
      //}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CAlarmButton message handlers

void CAlarmButton::OnTimer(UINT nIDEvent)
 {
  if (m_IsBackgroundFlashing)
   {
    m_IsBackgroundFlashing = FALSE;
    m_BackgroundColor = m_BackgroundColor2;
   }
  else {
        m_IsBackgroundFlashing = TRUE;
        m_BackgroundColor = m_BackgroundColor1;
       }

  Invalidate();
             
  CButton::OnTimer(nIDEvent);
 }

// --------------------------------------------------------------------------

void CAlarmButton::PreSubclassWindow()
 {
  CButton::PreSubclassWindow();
  ModifyStyle(0, BS_OWNERDRAW);
 }

// --------------------------------------------------------------------------

void CAlarmButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
 {
  ASSERT(lpDrawItemStruct != NULL);

  CDC   *pMemDC;
  int    Offset,
         X,
         Y;
  CDC   *pDC    = CDC::FromHandle(lpDrawItemStruct->hDC);
  CRect  Rect   = lpDrawItemStruct->rcItem;
  UINT   State  = lpDrawItemStruct->itemState;
  UINT   nStyle = GetStyle();

  pDC->SelectStockObject(NULL_BRUSH);
  pDC->FillSolidRect(Rect, m_BackgroundColor);

  // Draw the focus rectangle around the button
  if ((State & ODS_FOCUS))
   {
    CRect FocusRect(Rect.left + 4, Rect.top + 4, Rect.right - 4, Rect.bottom - 4);
    pDC->DrawFocusRect(FocusRect);
   }

  // Draw Bitmap if one
  if (m_pImage != NULL)
   {
    pMemDC = new CDC;
    pMemDC->CreateCompatibleDC(pDC);

    Offset = 0;
    if (State & ODS_SELECTED) Offset++;

    if ((m_ImageAlignment & HLEFT) == HLEFT) X = 4;
    else if ((m_ImageAlignment & HCENTER) == HCENTER) X = (Rect.Width()  - m_ImageW) / 2;
         else if ((m_ImageAlignment & HRIGHT) == HRIGHT) X = Rect.Width() - m_ImageW - 4;

    if ((m_ImageAlignment & VTOP) == VTOP) Y = 4;
    else if ((m_ImageAlignment & VCENTER) == VCENTER) Y = (Rect.Height() - m_ImageH) / 2;
         else if ((m_ImageAlignment & VBOTTOM) == VBOTTOM) Y = Rect.Height() - m_ImageH - 4;

    if (X < 0) X=0;
    if (Y < 0) Y=0;

    X += Offset;
    Y += Offset;

    if (m_pMask != NULL)
     {
      pMemDC->SelectObject(m_pMask);
      pDC->BitBlt(X,Y,m_ImageW,m_ImageH,pMemDC,0,0,SRCAND);
     }

    pMemDC->SelectObject(m_pImage);
    if (m_pMask != NULL) pDC->BitBlt(X,Y,m_ImageW,m_ImageH,pMemDC,0,0,SRCINVERT);
    else pDC->BitBlt(X,Y,m_ImageW,m_ImageH,pMemDC,0,0,SRCCOPY);

    delete pMemDC;
   }

  // Draw the raised/sunken edges of the button
  if (nStyle & BS_FLAT)
   {
    pDC->DrawEdge(Rect,EDGE_ETCHED, BF_RECT);
   }
  else {
        if ((State & ODS_SELECTED))
         {
          pDC->Draw3dRect(Rect,RGB(0,0,0),RGB(255,255,255));
         }
        else {
              pDC->Draw3dRect(Rect,RGB(255,255,255),RGB(0,0,0));
             }
       }

  // Draw the text if there is any
  CString strText;
  GetWindowText(strText);

  if (!strText.IsEmpty())
   {
    CSize  Extent = pDC->GetTextExtent(strText);
    CPoint Pt;
   
    if ((m_TextAlignment & HLEFT) == HLEFT) Pt.x = 4;
    else if ((m_TextAlignment & HCENTER) == HCENTER) Pt.x = (Rect.Width() - Extent.cx) / 2;
         else if ((m_TextAlignment & HRIGHT) == HRIGHT) Pt.x = Rect.Width() - Extent.cx - 4;

    if ((m_TextAlignment & VTOP) == VTOP) Pt.y = 4;
    else if ((m_TextAlignment & VCENTER) == VCENTER) Pt.y = (Rect.Height() - Extent.cy) / 2;
         else if ((m_TextAlignment & VBOTTOM) == VBOTTOM) Pt.y = Rect.Height() - Extent.cy - 4;

    if (State & ODS_SELECTED) Pt.Offset(1,1);

    pDC->SetBkMode(TRANSPARENT);
    pDC->SetTextColor(m_TextColor);

    if (State & ODS_DISABLED)
     pDC->DrawState(Pt, Extent, strText, DSS_DISABLED, TRUE, 0, (HBRUSH)NULL);
    else
     pDC->TextOut(Pt.x, Pt.y, strText);
   }
 }
0
Comment
Question by:mike_marquet
1 Comment
 
LVL 10

Accepted Solution

by:
RONSLOW earned 20 total points
ID: 1302264
Get the system time and calculate the time for the first interval to make it in sync with the system time (eg. flash every second).

So, when you turn the alarm on.  If the system time is 0.4s after the second, then set the inital timer for 0.6s.  When the timer goes off, change the color and repeat the process (work out the time required until the next whole second and set the timer again).



0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
mixString challenge 36 111
Add content to output file 4 62
Line meaning 9 82
sumHeights2  challenge 7 87
Introduction: The undo support, implementing a stack. Continuing from the eigth article about sudoku.   We need a mechanism to keep track of the digits entered so as to implement an undo mechanism.  This should be a ‘Last In First Out’ collec…
Have you tried to learn about Unicode, UTF-8, and multibyte text encoding and all the articles are just too "academic" or too technical? This article aims to make the whole topic easy for just about anyone to understand.
This Micro Tutorial hows how you can integrate  Mac OSX to a Windows Active Directory Domain. Apple has made it easy to allow users to bind their macs to a windows domain with relative ease. The following video show how to bind OSX Mavericks to …
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.

920 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

Need Help in Real-Time?

Connect with top rated Experts

14 Experts available now in Live!

Get 1:1 Help Now