ilovehellworld 2023-03-06 13:56 采纳率: 57.1%
浏览 98
已结题

支持毫秒的时间控件类, 帮我写个demo

网上下载了这个支持毫秒的时间控件类,不知道怎么使用? 请帮我用VS2008 Unicode+mfc写个demo,谢谢!

#pragma once
#include "afxwin.h"

class CTimeWnd :
    public CWnd
{
public:
    enum Value
    {
        valHours = 0,
        valMinutes,
        valSeconds,
        valMilliseconds,
        valCount
    };

    DECLARE_MESSAGE_MAP()

    int m_nValue[valCount];
    int m_nValueMax[valCount];
    double m_dPower[valCount];
private:
    CRect m_Rect[valCount];
    int m_nCurSel;
    int m_nOldSel;
    CFont *m_pFont;
    bool m_bFocus;
    CSpinButtonCtrl m_Spin;

public:
    CTimeWnd(void);
    virtual ~CTimeWnd(void);
    CString GetString(int nType);
    void SetFont(CFont *pFont, BOOL bRedraw =false);
    CFont *GetFont();    
    double GetTime();
    int GetValue(int nType);
    void SetValue(int nType, int nVal);
    void SetTime(double dTime);
    virtual BOOL PreTranslateMessage(MSG *pMsg);
    virtual void PreSubclassWindow();
    afx_msg void OnPaint();
    afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
    afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
    afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
    afx_msg void OnKillFocus(CWnd *pNewWnd);
    afx_msg void OnDeltaposSpin1(NMHDR *pNMHDR, LRESULT *pResult);
    afx_msg void OnSize(UINT nType, int cx, int cy);
    afx_msg void OnCaptureChanged(CWnd *pWnd);
    afx_msg void OnEnable(BOOL bEnable);
private:
    bool IsCountValid(int nCount);
    void ChangeChar(UINT nChar, int refer);
    void ChangeSpin(int nDelta);
    void DrawSingleString(CDC *pDC, CString &str, CRect &rc, int *pOffset = NULL, bool bSelect = false);
    int GetNumberCount(int num);
    bool IsFocus();
    void ReDraw(bool bNeedBk = true);
};


#include "StdAfx.h"
#include "TimeWnd.h"

CTimeWnd::CTimeWnd(void)
{
    for (int i=0; i<valCount; i++)
    {
        m_nValue[i] = 0;
        m_Rect[i].SetRectEmpty();
    }
    m_nValueMax[valHours] = 24;
    m_nValueMax[valMinutes] = 60;
    m_nValueMax[valSeconds] = 60;
    m_nValueMax[valMilliseconds] = 1000;

    m_dPower[valHours] = 3600;
    m_dPower[valMinutes] = 60;
    m_dPower[valSeconds] = 1;
    m_dPower[valMilliseconds] = 0.001;

    m_nCurSel = -1;
    m_nOldSel = 0;
    m_pFont = NULL;
    m_bFocus = false;
}

CTimeWnd::~CTimeWnd(void)
{
}

BEGIN_MESSAGE_MAP(CTimeWnd, CWnd)

ON_WM_PAINT()
    ON_WM_CREATE()
    ON_WM_LBUTTONDOWN()
    ON_WM_KEYDOWN()
    ON_NOTIFY(UDN_DELTAPOS, 1051, &CTimeWnd::OnDeltaposSpin1)
    ON_WM_KILLFOCUS()
    ON_WM_SIZE()
    ON_WM_CAPTURECHANGED()
    ON_WM_ENABLE()
END_MESSAGE_MAP()

void CTimeWnd::OnDeltaposSpin1(NMHDR *pNMHDR, LRESULT *pResult)
{
    LPNMUPDOWN pNMUpDown = reinterpret_cast<LPNMUPDOWN>(pNMHDR);
    *pResult = 0;
    SetFocus();
    ChangeSpin(pNMUpDown->iDelta*(-1));
}

void CTimeWnd::ChangeSpin(int nDelta)
{
    if(m_nCurSel == -1)
    {
        m_nCurSel = m_nOldSel;
    }
    if (nDelta > 0)
    {
        m_nValue[m_nCurSel] = (m_nValue[m_nCurSel]+nDelta)%m_nValueMax[m_nCurSel];
    }
    else
    {
        m_nValue[m_nCurSel] = (m_nValue[m_nCurSel]+nDelta+m_nValueMax[m_nCurSel])%m_nValueMax[m_nCurSel];
    }
    ReDraw(true);
}

void CTimeWnd::OnPaint()
{
    CPaintDC dc(this); // device context for painting
    CRect rcBounds;   
    GetClientRect(&rcBounds);   
    CPen penWhite;   
    penWhite.CreatePen(PS_SOLID, 1, RGB(127,157,185));   
    CPen *pOldPen = dc.SelectObject(&penWhite); 
    dc.FillSolidRect(rcBounds, RGB(255,255,255));
    dc.MoveTo(rcBounds.left, rcBounds.top);   
    dc.LineTo(rcBounds.right-1, rcBounds.top);   
    dc.LineTo(rcBounds.right-1, rcBounds.bottom-1);   
    dc.LineTo(rcBounds.left, rcBounds.bottom-1);   
    dc.LineTo(rcBounds.left, rcBounds.top);  
    CString    str = NULL;
    int xoffset = 5;
    CRect rc;
    rc.SetRectEmpty();
    for(int i=0; i<valCount; i++)
    {
        str = GetString(i);
        rc = rcBounds;
        DrawSingleString(&dc,str,rc,&xoffset,(i == m_nCurSel));
        m_Rect[i] = rc;
        if (i != valCount-1)
        {
            rc = rcBounds;
            str = _T(":");
            DrawSingleString(&dc, str, rc, &xoffset);
        }
    }
    dc.SelectObject(pOldPen); 
}

void CTimeWnd::PreSubclassWindow()
{
    CWnd::PreSubclassWindow();
}

int CTimeWnd::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
    if (CWnd::OnCreate(lpCreateStruct) == -1)
        return -1;

    m_Spin.Create(UDS_ALIGNRIGHT|UDS_AUTOBUDDY|WS_VISIBLE, CRect(0,0,20,19), this, 1051);
    m_Spin.SetBuddy(this);

    return 0;
}

void CTimeWnd::OnLButtonDown(UINT nFlags, CPoint point)
{
    for (int i=0; i<valCount; i++)
    {
        if (m_Rect[i].PtInRect(point))
        {
            if (m_nCurSel == i)break;
            ReDraw(false);
            m_nCurSel = i;
            ReDraw(true);
            break;
        }
    }
    SetFocus();
    m_bFocus = true;
    CWnd::OnLButtonDown(nFlags, point);
}

void CTimeWnd::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
     if (m_nCurSel == -1)
    {
        m_nCurSel = m_nOldSel;
    }
    if ((nChar>='0') && (nChar<='9'))
    {
        ChangeChar(nChar, '0');
    }
    else if ((nChar>=VK_NUMPAD0) && (nChar<=VK_NUMPAD9))
    {
        ChangeChar(nChar, VK_NUMPAD0);
    }
    ReDraw(true);
    CWnd::OnKeyDown(nChar, nRepCnt, nFlags);
}

CString CTimeWnd::GetString(int nType)
{
    CString str = NULL;
    int nCount = 0;
    int nZero = 0;
    nCount = GetNumberCount(m_nValueMax[nType]-1);
    nZero = nCount - GetNumberCount(m_nValue[nType]) ;
    m_nValue[nType] %= m_nValueMax[nType];
    str.Format(_T("%d"), m_nValue[nType]);
    while (nZero--)
    {
        str = _T("0") + str;
    }
    return str;
}

void CTimeWnd::DrawSingleString(CDC *pDC, CString &str, CRect &rc, int *pOffset/*= -1*/, bool bSelect/* = false*/)
{
    int nHeight = rc.Height();
    int offset = 0;
    if (pOffset == NULL)
    {
        offset = rc.left;
    }
    else
    {
        offset = *pOffset;
    }
    CFont *pOldFont = NULL;
    if (m_pFont)
    {
        pOldFont = pDC->SelectObject(m_pFont);
    }
    pDC->DrawText(str, rc, DT_CALCRECT);
    rc.MoveToXY(offset, (nHeight - rc.Height())/2);
    COLORREF clr;
    int nMode = 0;
    BOOL bEnable = IsWindowEnabled();
    if (bSelect && bEnable)
    {
        pDC->FillSolidRect(rc, RGB(49,106,197));
        clr = pDC->SetTextColor(RGB(255,255,255));
        nMode = pDC->SetBkMode(TRANSPARENT);
    }
    else
    {
        pDC->FillSolidRect(rc, RGB(255,255,255));
    }
    if (bEnable)
         pDC->DrawState(CPoint(rc.left, rc.top), CSize(rc.Width(), rc.Height()), str, DSS_NORMAL, TRUE, 0, (HBRUSH)NULL);
    else
        pDC->DrawState(CPoint(rc.left, rc.top), CSize(rc.Width(), rc.Height()), str, DSS_DISABLED, TRUE, 0, (HBRUSH)NULL);
    offset += rc.Width();
    if (bSelect)
    {
        pDC->SetTextColor(clr);
        pDC->SetBkMode(nMode);
    }
    if (pOffset) *pOffset = offset;
    if (pOldFont) pDC->SelectObject(pOldFont);
}

void CTimeWnd::OnKillFocus(CWnd *pNewWnd)
{
    CWnd::OnKillFocus(pNewWnd);
    ReDraw(false);
    m_nOldSel = m_nCurSel;
    m_nCurSel = -1;
    m_bFocus = false; 
}

void CTimeWnd::ReDraw(bool bNeedBk/*= true*/)
{
    if (m_nCurSel == -1)
    {
        return;
    }
    CDC *pDC = GetDC();
    CString str = GetString(m_nCurSel);
    CRect   rcBounds;   
    GetClientRect(&rcBounds);   
    rcBounds.left = m_Rect[m_nCurSel].left;
    rcBounds.right = m_Rect[m_nCurSel].right;
    DrawSingleString(pDC, str, rcBounds, NULL, bNeedBk);
    ReleaseDC(pDC);
}

void CTimeWnd::SetFont(CFont *pFont, BOOL bRedraw/*=false*/)
{
    m_pFont = pFont;
    if (bRedraw)
    {
        Invalidate();
    }
}

CFont *CTimeWnd::GetFont()
{
    return m_pFont;
}

void CTimeWnd::ChangeChar(UINT nChar, int refer)
{
    if (!IsCountValid(m_nCurSel)) return;
    int iCharValue = nChar - refer;
    int iTemVal = m_nValue[m_nCurSel] * 10 + iCharValue;
    m_nValue[m_nCurSel] = (iTemVal >= m_nValueMax[m_nCurSel]) ? iCharValue : iTemVal;
}


BOOL CTimeWnd::PreTranslateMessage(MSG *pMsg)
{
    if (pMsg->message == WM_KEYDOWN)
    {
        if (pMsg->wParam == VK_UP)
        {
            ChangeSpin(1);
            return true;
        }
        if (pMsg->wParam == VK_DOWN)
        {
            ChangeSpin(-1);
            return true;
        }
        if (pMsg->wParam == VK_LEFT)
        {
            ReDraw(false);
            m_nCurSel = (m_nCurSel + valCount - 1) % valCount;
            ReDraw(true);
            return true;
        }
        if (pMsg->wParam == VK_RIGHT)
        {
            ReDraw(false);
            m_nCurSel = (m_nCurSel + 1) % valCount;
            ReDraw(true);
            return true;
        }
        if (pMsg->wParam == VK_END)
        {        
            m_nValue[m_nCurSel] = m_nValueMax[m_nCurSel];
        }
        if (pMsg->wParam == VK_HOME)
        {
            m_nValue[m_nCurSel] = 0;
        }
    }
    return CWnd::PreTranslateMessage(pMsg);
}

double CTimeWnd::GetTime()
{
    double dTime = 0;
    for (int i=0; i<valCount; i++)
    {
        dTime += m_nValue[i] * m_dPower[i];
    }
    return dTime;
}

int CTimeWnd::GetValue(int nType)
{
    if (!IsCountValid(nType)) 
        return 0;
    else 
        return m_nValue[nType];
}

void CTimeWnd::SetValue(int nType, int nVal)
{
    if ((!IsCountValid(nType)) || nVal<0) return;
    else m_nValue[nType] = nVal % m_nValueMax[nType];
}

void CTimeWnd::SetTime(double dTime)
{
    int nTemVal = 0;
    for (int i=0; i<valCount; i++)
    {
        m_nValue[i] = (int)((dTime - nTemVal) / m_dPower[i]);
        nTemVal += m_nValue[i];
        m_nValue[i] %= m_nValueMax[i]; 
    }
}

bool CTimeWnd::IsFocus()
{
    return m_bFocus;
}

void CTimeWnd::OnSize(UINT nType, int cx, int cy)
{
    CWnd::OnSize(nType, cx, cy);
    m_Spin.MoveWindow(cx-19, 1, 18, cy-2);
}

void CTimeWnd::OnCaptureChanged(CWnd *pWnd)
{
    CWnd::OnCaptureChanged(pWnd);
}

void CTimeWnd::OnEnable(BOOL bEnable)
{
    CWnd::OnEnable(bEnable);
    Invalidate();
    m_Spin.EnableWindow(bEnable);
}

int CTimeWnd::GetNumberCount(int num)
{
    int i = 0;
    if (num == 0)
    {
        return 1;
    }
    while (num)
    {
        num /= 10;    
        i++;
    };
    return i;
}

bool CTimeWnd::IsCountValid(int nCount)
{
    if ((nCount>=0) && (nCount<valCount))
    {
        return true;
    }
    return false;
}

  • 写回答

6条回答 默认 最新

  • b2b160 2023-03-06 15:49
    关注

    demo上传到csdn了https://download.csdn.net/download/b2b160/87537455

    img

    //CTimeWndDemoDlg.h定义
    #include "TimeWnd.h"
    
    CTimeWnd m_wndTime;
    
    //CTimeWndDemoDlg.cpp
    //创建
    if( !m_wndTime.Create( _T("Static"),_T(""),WS_CHILD|WS_VISIBLE|SS_NOTIFY,rt,this,1001) )
            MessageBox(_T("Error"));
    
    //获取时间
    double dTime = m_wndTime.GetTime();
        CString str;
        str.Format( _T("Time:%f, %d:%d:%d:%d"), dTime,m_wndTime.GetValue(0),m_wndTime.GetValue(1),m_wndTime.GetValue(2),m_wndTime.GetValue(3) );
        MessageBox(str);
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论 编辑记录
查看更多回答(5条)

报告相同问题?

问题事件

  • 系统已结题 3月17日
  • 已采纳回答 3月9日
  • 创建了问题 3月6日

悬赏问题

  • ¥15 请问我该如何添加自己的数据去运行蚁群算法代码
  • ¥20 用HslCommunication 连接欧姆龙 plc有时会连接失败。报异常为“未知错误”
  • ¥15 网络设备配置与管理这个该怎么弄
  • ¥20 机器学习能否像多层线性模型一样处理嵌套数据
  • ¥20 西门子S7-Graph,S7-300,梯形图
  • ¥50 用易语言http 访问不了网页
  • ¥50 safari浏览器fetch提交数据后数据丢失问题
  • ¥15 matlab不知道怎么改,求解答!!
  • ¥15 永磁直线电机的电流环pi调不出来
  • ¥15 用stata实现聚类的代码