// BitButton.cpp : implementation file // /* this implements a custom button class, displaying ioport states, an io port can be in 4 states: direction value input high input low output high output low the user must be able to change the direction, and the output value. tap+hold will change the direction tap will change the value. how to distinguish between states: input/output: - think/thin border - different background color - different border color value - check / no check - filled / empty - style dependent on input/output remark about window events: they occur in one of these orders: 1) down, up, click, doubleclick, up, click [ top, release, tap, release in quick succession ] 2) down, taphold [ hold long and leave ] 3) down, taphold, up [ hold short and leave, or hold long and release ] 4) down, taphold, up, clicked [ hold short and release ] 5) down, up [ hold briefly and leave ] 6) up [ enter, release ] 7) down, up, click [ hold briefly and release ] - normal click "enter" : enter button region while holding button "release" : release button "leave" : leave button region while holding button "hold short" : hold 1 - 2 'taphold-animations' "hold long" : hold 2 - 3 'taphold-animations' "hold briefly": hold < 1 'taphold-animations' */ #include "stdafx.h" #include "resource.h" #include "BitController.h" #include "BitButton.h" #include "debug.h" #include #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif #define DEBUGEVENTS while (0) debug ///////////////////////////////////////////////////////////////////////////// // CBitButton CBitButton::CBitButton() { m_bOutput= false; m_bValue= false; } CBitButton::~CBitButton() { } BEGIN_MESSAGE_MAP(CBitButton, CButton) //{{AFX_MSG_MAP(CBitButton) ON_CONTROL_REFLECT(BN_CLICKED, OnClicked) ON_WM_LBUTTONDBLCLK() ON_WM_LBUTTONDOWN() ON_WM_LBUTTONUP() ON_WM_MOUSEMOVE() //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CBitButton message handlers void CBitButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) { CBrush br; COLORREF color= m_bOutput?0x00000000: 0x000000ff; CDC dc; dc.Attach(lpDrawItemStruct->hDC); if (m_bValue) dc.FillSolidRect(&lpDrawItemStruct->rcItem, color); else { CBrush br; br.CreateSolidBrush(color); dc.FrameRect(&lpDrawItemStruct->rcItem, &br); } } BOOL CBitButton::Create(const RECT& rect, CWnd* pParentWnd, UINT nID, bool bEnabled) { // !! CE does not support BS_BITMAP -> use BS_OWNERDRAW return CWnd::Create(L"BUTTON", L"", WS_CHILD|WS_VISIBLE|BS_OWNERDRAW|(bEnabled?0:WS_DISABLED) , rect, pParentWnd, nID); } void CBitButton::SetController(BitController *controller) { m_controller= controller; } void CBitButton::OnClicked() { DEBUGEVENTS("button %d clicked\n", this->GetDlgCtrlID()); } void CBitButton::OnLButtonDblClk(UINT nFlags, CPoint point) { DEBUGEVENTS("button %d left doubleclicked f=%08lx (%d,%d)\n", this->GetDlgCtrlID(), nFlags, point.x, point.y); CButton::OnLButtonDblClk(nFlags, point); } void CBitButton::OnLButtonDown(UINT nFlags, CPoint point) { DEBUGEVENTS("button %d left down f=%08lx (%d,%d)\n", this->GetDlgCtrlID(), nFlags, point.x, point.y); int bit= this->GetDlgCtrlID(); if (SHRecognizeGesture(point, false)) { DEBUGEVENTS("taphold\n"); m_bOutput= ! m_bOutput; if (m_controller) m_controller->SetOutput(bit, m_bValue); //debug("changed to %hs\n", m_bOutput?"output":"input"); /* this->SetButtonStyle(WS_CHILD|WS_VISIBLE|(m_bOutput?(BS_CHECKBOX):(BS_PUSHLIKE))); if (m_bOutput) { this->SetCheck(m_bValue?BST_CHECKED:BST_UNCHECKED); } else { this->SetState(m_bValue); } */ this->RedrawWindow(); } else if (m_bOutput) { m_bValue= !m_bValue; if (m_controller) m_controller->SetValue(bit, m_bValue); //debug("changed to %hs\n", m_bValue?"high":"low"); //this->SetCheck(m_bValue?BST_CHECKED:BST_UNCHECKED); this->RedrawWindow(); } CButton::OnLButtonDown(nFlags, point); } void CBitButton::OnLButtonUp(UINT nFlags, CPoint point) { DEBUGEVENTS("button %d left up f=%08lx (%d,%d)\n", this->GetDlgCtrlID(), nFlags, point.x, point.y); CButton::OnLButtonUp(nFlags, point); } void CBitButton::SetOutput(bool bOutput) { if (m_bOutput!=bOutput) { m_bOutput= bOutput; this->RedrawWindow(); } } void CBitButton::SetValue(bool bValue) { if (m_bValue!=bValue) { m_bValue= bValue; this->RedrawWindow(); } } void CBitButton::OnMouseMove(UINT nFlags, CPoint point) { DEBUGEVENTS("bit %d mouse move %08lx (%d,%d)\n", this->GetDlgCtrlID(), nFlags, point.x, point.y); CButton::OnMouseMove(nFlags, point); }