void CHomework2View::OnFast(UINT_PTR nIDEvent) { // TODO: 在此添加命令处理程序代码 switch(nIDEvent) { case -3: { KillTimer(-3); SetTimer(-4,50,NULL); } case -2: { KillTimer(-2); SetTimer(-3,100,NULL); } case -1: { KillTimer(-1); SetTimer(-2,150,NULL); } case 0: { KillTimer(0); SetTimer(-1,200,NULL); } case 1: { KillTimer(1); SetTimer(0,250,NULL); } case 2: { KillTimer(2); SetTimer(1,300,NULL); } case 3: { KillTimer(1); SetTimer(2,350,NULL); } case 4: { KillTimer(1); SetTimer(3,400,NULL); } case 5: { KillTimer(1); SetTimer(4,450,NULL); } default:break; } }
时间: 2023-05-22 17:02:40 浏览: 102
这是基于 MFC 的定时器事件处理函数。根据传入的 nIDEvent 参数选择不同的定时器编号,并分别调用 SetTimer 和 KillTimer 函数来创建和删除定时器。具体的时间间隔由第三个参数决定。在每个 case 中,需要使用 break 语句来避免进入下一个 case 中执行代码。
相关问题
VC mfc单文档中代码如下void CMyView::OnDraw(CDC* pDC) { CMyDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); for (int i=0;i<points.size();i++){ color=RGB(rand()%256,rand()%256,rand()%256); r=rand()%46+5; br.CreateSolidBrush(color); pDC->SelectObject(&br); pDC->Ellipse(points[i].x-r,points[i].y-r,points[i].x+r,points[i].y+r); br.DeleteObject(); } // TODO: add draw code for native data here } ///////////////////////////////////////////////////////////////////////////// // CMyView printing BOOL CMyView::OnPreparePrinting(CPrintInfo* pInfo) { // default preparation return DoPreparePrinting(pInfo); } void CMyView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) { // TODO: add extra initialization before printing } void CMyView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) { // TODO: add cleanup after printing } ///////////////////////////////////////////////////////////////////////////// // CMyView diagnostics #ifdef _DEBUG void CMyView::AssertValid() const { CView::AssertValid(); } void CMyView::Dump(CDumpContext& dc) const { CView::Dump(dc); } CMyDoc* CMyView::GetDocument() // non-debug version is inline { ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CMyDoc))); return (CMyDoc*)m_pDocument; } #endif //_DEBUG ///////////////////////////////////////////////////////////////////////////// // CMyView message handlers void CMyView::OnLButtonDown(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default center=point; r=rand()%46+5;//r=5~50 color=RGB(rand()%256,rand()%256,rand()%256); points.push_back(center); SetTimer(1,200,NULL); CView::OnLButtonDown(nFlags, point); } void CMyView::OnLButtonUp(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default CView::OnLButtonUp(nFlags, point); } void CMyView::rise() { for(int i=0;i<points.size();i++) { points[i].y-=5; if(points[i].y<-r) { points.erase(points.begin()+i); i--; } } } void CMyView::OnTimer(UINT nIDEvent) { // TODO: Add your message handler code here and/or call default if(nIDEvent==1){ RedrawWindow(); rise(); } CView::OnTimer(nIDEvent); },运行效果中圆在上升过程中颜色和大小不停的变换,应怎么修改此代码使得圆在上升过程中的大小和颜色不会变换,完整步骤及代码
要使圆在上升过程中大小和颜色不会变换,可以将颜色和大小的变化单独提取出来,放到循环外面进行定义,然后再在循环内部进行圆的上升操作。具体实现方式如下:
1. 在头文件中定义变量:
```cpp
// 头文件中定义变量
COLORREF color; // 圆的颜色
int r; // 圆的半径
```
2. 在`OnDraw`函数中修改绘制圆的代码:
```cpp
void CMyView::OnDraw(CDC* pDC)
{
CMyDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// 绘制圆
for (int i = 0;i < points.size();i++)
{
// 保持颜色和大小不变
color = RGB(0, 0, 255); // 蓝色
r = 20;
// 绘制圆
CPen pen(PS_SOLID, 1, color);
CBrush brush(color);
pDC->SelectObject(&pen);
pDC->SelectObject(&brush);
pDC->Ellipse(points[i].x - r, points[i].y - r, points[i].x + r, points[i].y + r);
}
}
```
在这个代码中,我们将颜色和大小的变化都删除了,直接将颜色设置为蓝色,大小设置为20。这样就可以让圆在上升过程中保持颜色和大小不变了。
完整修改后的代码如下:
MyView.h文件:
```cpp
#pragma once
#include "MyDoc.h"
#include <vector>
class CMyView : public CView
{
protected: // create from serialization only
CMyView() noexcept;
DECLARE_DYNCREATE(CMyView)
// Attributes
public:
CMyDoc* GetDocument() const;
// Operations
public:
// Overrides
public:
virtual void OnDraw(CDC* pDC) override;
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
protected:
virtual void OnInitialUpdate() override; // called first time after construct
virtual void OnUpdate(CView* /*pSender*/, LPARAM /*lHint*/, CObject* /*pHint*/) override;
// Implementation
public:
virtual ~CMyView();
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif
protected:
// Generated message map functions
protected:
DECLARE_MESSAGE_MAP()
public:
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
afx_msg void OnTimer(UINT_PTR nIDEvent);
void rise();
};
#ifndef _DEBUG // debug version in MyView.cpp
inline CMyDoc* CMyView::GetDocument() const
{ return reinterpret_cast<CMyDoc*>(m_pDocument); }
#endif
```
MyView.cpp文件:
```cpp
#include "pch.h"
#include "framework.h"
#include "My.h"
#include "MyDoc.h"
#include "MyView.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
IMPLEMENT_DYNCREATE(CMyView, CView)
BEGIN_MESSAGE_MAP(CMyView, CView)
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_WM_TIMER()
END_MESSAGE_MAP()
// CMyView construction/destruction
CMyView::CMyView() noexcept
{
// TODO: add construction code here
}
CMyView::~CMyView()
{
}
BOOL CMyView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
return CView::PreCreateWindow(cs);
}
// CMyView drawing
void CMyView::OnDraw(CDC* pDC)
{
CMyDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// 绘制圆
for (int i = 0;i < points.size();i++)
{
// 保持颜色和大小不变
color = RGB(0, 0, 255); // 蓝色
r = 20;
// 绘制圆
CPen pen(PS_SOLID, 1, color);
CBrush brush(color);
pDC->SelectObject(&pen);
pDC->SelectObject(&brush);
pDC->Ellipse(points[i].x - r, points[i].y - r, points[i].x + r, points[i].y + r);
}
}
void CMyView::OnInitialUpdate()
{
CView::OnInitialUpdate();
// TODO: Add your specialized code here and/or call the base class
}
void CMyView::OnUpdate(CView* /*pSender*/, LPARAM /*lHint*/, CObject* /*pHint*/)
{
CMyDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;
// TODO: Add your specialized code here and/or call the base class
}
// CMyView diagnostics
#ifdef _DEBUG
void CMyView::AssertValid() const
{
CView::AssertValid();
}
void CMyView::Dump(CDumpContext& dc) const
{
CView::Dump(dc);
}
CMyDoc* CMyView::GetDocument() const // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CMyDoc)));
return (CMyDoc*)m_pDocument;
}
#endif //_DEBUG
// CMyView message handlers
void CMyView::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
center = point;
r = rand() % 46 + 5;
color = RGB(rand() % 256, rand() % 256, rand() % 256);
points.push_back(center);
SetTimer(1, 200, NULL);
CView::OnLButtonDown(nFlags, point);
}
void CMyView::OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
CView::OnLButtonUp(nFlags, point);
}
void CMyView::rise()
{
for (int i = 0;i < points.size();i++)
{
points[i].y -= 5;
if (points[i].y < -r)
{
points.erase(points.begin() + i);
i--;
}
}
}
void CMyView::OnTimer(UINT_PTR nIDEvent)
{
// TODO: Add your message handler code here and/or call default
if (nIDEvent == 1) {
RedrawWindow();
rise();
}
CView::OnTimer(nIDEvent);
}
```
这样修改后,圆在上升过程中的大小和颜色就不会变换了。
windows系统上开发CAN上位机界面工具MFC实现与代码示例
下面是一个简单的MFC界面工具,用于与CAN总线通信。本示例使用了Peak的PCAN-USB接口,但是您可以根据需要更改实现以适应您使用的硬件。
首先,您需要包含以下头文件:
```c++
#include "afxwin.h"
#include "PCANBasic.h"
#include <vector>
```
接下来,您需要添加以下变量:
```c++
TPCANHandle m_PcanHandle; // CAN接口句柄
TPCANMsg m_TxMsg; // 发送CAN消息
TPCANMsg m_RxMsg; // 接收CAN消息
std::vector<std::string> m_CanBaudrateList; // CAN波特率列表
std::vector<std::string> m_CanMsgTypeList; // CAN消息类型列表
```
在对话框类中,您需要添加以下代码:
```c++
class CCanToolDlg : public CDialogEx
{
// ...
public:
CCanToolDlg(CWnd* pParent = NULL); // 标准构造函数
virtual ~CCanToolDlg();
// 对话框数据
#ifdef AFX_DESIGN_TIME
enum { IDD = IDD_CAN_TOOL_DIALOG };
#endif
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
// 实现
protected:
HICON m_hIcon;
// 生成的消息映射函数
virtual BOOL OnInitDialog();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
DECLARE_MESSAGE_MAP()
private:
BOOL InitPcan(); // 初始化PCAN接口
void DisplayCanBaudrateList(); // 显示CAN波特率列表
void DisplayCanMsgTypeList(); // 显示CAN消息类型列表
void WriteCanMsg(); // 发送CAN消息
void ReadCanMsg(); // 接收CAN消息
CComboBox m_CanBaudrateCombo; // CAN波特率选择框
CComboBox m_CanMsgTypeCombo; // CAN消息类型选择框
CEdit m_CanIdEdit; // CAN ID编辑框
CEdit m_CanDataEdit; // CAN数据编辑框
CButton m_SendBtn; // 发送按钮
CListBox m_MsgListBox; // 消息列表框
};
```
在对话框类的构造函数中,您需要初始化以下变量:
```c++
CCanToolDlg::CCanToolDlg(CWnd* pParent /*=NULL*/)
: CDialogEx(IDD_CAN_TOOL_DIALOG, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
// 初始化CAN接口
m_PcanHandle = PCAN_USBBUS1;
m_TxMsg.ID = 0x123;
m_TxMsg.LEN = 8;
m_TxMsg.MSGTYPE = MSGTYPE_STANDARD;
ZeroMemory(m_TxMsg.DATA, sizeof(m_TxMsg.DATA));
m_RxMsg.ID = 0x0;
m_RxMsg.LEN = 0;
m_RxMsg.MSGTYPE = MSGTYPE_STANDARD;
ZeroMemory(m_RxMsg.DATA, sizeof(m_RxMsg.DATA));
// 初始化CAN波特率列表
m_CanBaudrateList.push_back("1 MBit/sec");
m_CanBaudrateList.push_back("500 KBit/sec");
m_CanBaudrateList.push_back("250 KBit/sec");
m_CanBaudrateList.push_back("125 KBit/sec");
m_CanBaudrateList.push_back("100 KBit/sec");
m_CanBaudrateList.push_back("50 KBit/sec");
m_CanBaudrateList.push_back("20 KBit/sec");
m_CanBaudrateList.push_back("10 KBit/sec");
// 初始化CAN消息类型列表
m_CanMsgTypeList.push_back("Standard");
m_CanMsgTypeList.push_back("RTR");
}
```
在OnInitDialog函数中,您需要调用初始化CAN接口,显示CAN波特率列表和CAN消息类型列表的函数,并将它们与对应的控件关联起来:
```c++
BOOL CCanToolDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
// 添加 "关于..." 菜单项。
// IDM_ABOUTBOX 必须在系统命令范围内。
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
// 执行此操作
SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, FALSE); // 设置小图标
// TODO: 在此添加额外的初始化代码
if (!InitPcan())
{
AfxMessageBox(_T("PCAN initialization failed!"));
return FALSE;
}
DisplayCanBaudrateList();
DisplayCanMsgTypeList();
m_CanBaudrateCombo.SetCurSel(0);
m_CanMsgTypeCombo.SetCurSel(0);
return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}
```
在InitPcan函数中,您需要初始化PCAN接口并打开它:
```c++
BOOL CCanToolDlg::InitPcan()
{
TPCANStatus status;
// Initialize PCAN interface
status = CAN_Initialize(m_PcanHandle, PCAN_BAUD_1M, 0, 0, 0);
if (status != PCAN_ERROR_OK)
return FALSE;
// Start the PCAN interface
status = CAN_Start(m_PcanHandle);
if (status != PCAN_ERROR_OK)
{
CAN_Uninitialize(m_PcanHandle);
return FALSE;
}
return TRUE;
}
```
在DisplayCanBaudrateList函数中,您需要将CAN波特率列表显示在对应的控件中:
```c++
void CCanToolDlg::DisplayCanBaudrateList()
{
for (std::vector<std::string>::iterator it = m_CanBaudrateList.begin(); it != m_CanBaudrateList.end(); it++)
{
CString str(it->c_str());
m_CanBaudrateCombo.AddString(str);
}
}
```
在DisplayCanMsgTypeList函数中,您需要将CAN消息类型列表显示在对应的控件中:
```c++
void CCanToolDlg::DisplayCanMsgTypeList()
{
for (std::vector<std::string>::iterator it = m_CanMsgTypeList.begin(); it != m_CanMsgTypeList.end(); it++)
{
CString str(it->c_str());
m_CanMsgTypeCombo.AddString(str);
}
}
```
在WriteCanMsg函数中,您需要从控件中获取CAN消息数据并发送它:
```c++
void CCanToolDlg::WriteCanMsg()
{
CString strId, strData;
int nId = 0;
// Get CAN ID
m_CanIdEdit.GetWindowTextW(strId);
if (strId.IsEmpty())
{
AfxMessageBox(_T("Please input CAN ID!"));
return;
}
nId = _tcstoul(strId, NULL, 16);
if (nId > 0x7FF)
{
AfxMessageBox(_T("CAN ID should be less than or equal to 0x7FF!"));
return;
}
m_TxMsg.ID = nId;
// Get CAN data
m_CanDataEdit.GetWindowTextW(strData);
if (strData.IsEmpty())
{
AfxMessageBox(_T("Please input CAN data!"));
return;
}
CString strDataByte;
for (int i = 0; i < 8; i++)
{
strDataByte = strData.Mid(i * 2, 2);
if (strDataByte.IsEmpty())
{
ZeroMemory(m_TxMsg.DATA + i, 1);
}
else
{
m_TxMsg.DATA[i] = _tcstoul(strDataByte, NULL, 16);
}
}
// Get CAN message type
int nMsgType = m_CanMsgTypeCombo.GetCurSel();
if (nMsgType == -1)
{
AfxMessageBox(_T("Please select CAN message type!"));
return;
}
m_TxMsg.MSGTYPE = (nMsgType == 0 ? MSGTYPE_STANDARD : MSGTYPE_RTR);
// Send CAN message
TPCANStatus status = CAN_Write(m_PcanHandle, &m_TxMsg);
if (status != PCAN_ERROR_OK)
{
AfxMessageBox(_T("CAN message sending failed!"));
return;
}
// Display CAN message in message list box
CString strMsg;
strMsg.Format(_T("Tx: %03X %02X %02X %02X %02X %02X %02X %02X %02X"), m_TxMsg.ID, m_TxMsg.DATA[0], m_TxMsg.DATA[1], m_TxMsg.DATA[2], m_TxMsg.DATA[3], m_TxMsg.DATA[4], m_TxMsg.DATA[5], m_TxMsg.DATA[6], m_TxMsg.DATA[7]);
m_MsgListBox.AddString(strMsg);
}
```
在ReadCanMsg函数中,您需要接收CAN消息并在消息列表框中显示它:
```c++
void CCanToolDlg::ReadCanMsg()
{
TPCANStatus status;
while (TRUE)
{
// Receive CAN message
status = CAN_Read(m_PcanHandle, &m_RxMsg, NULL);
if (status != PCAN_ERROR_OK && status != PCAN_ERROR_QRCVEMPTY)
break;
if (status == PCAN_ERROR_QRCVEMPTY)
break;
// Display CAN message in message list box
CString strMsg;
strMsg.Format(_T("Rx: %03X %02X %02X %02X %02X %02X %02X %02X %02X"), m_RxMsg.ID, m_RxMsg.DATA[0], m_RxMsg.DATA[1], m_RxMsg.DATA[2], m_RxMsg.DATA[3], m_RxMsg.DATA[4], m_RxMsg.DATA[5], m_RxMsg.DATA[6], m_RxMsg.DATA[7]);
m_MsgListBox.AddString(strMsg);
}
}
```
最后,在对话框类中添加以下消息处理函数:
```c++
void CCanToolDlg::OnBnClickedSendBtn()
{
WriteCanMsg();
}
afx_msg void CCanToolDlg::OnTimer(UINT_PTR nIDEvent)
{
if (nIDEvent == 1)
{
ReadCanMsg();
}
CDialogEx::OnTimer(nIDEvent);
}
void CCanToolDlg::OnDestroy()
{
CDialogEx::OnDestroy();
// Stop the PCAN interface
CAN_Stop(m_PcanHandle);
// Uninitialize the PCAN interface
CAN_Uninitialize(m_PcanHandle);
}
void CCanToolDlg::OnCbnSelchangeCanBaudrateCombo()
{
int nBaudrate = m_CanBaudrateCombo.GetCurSel();
if (nBaudrate == -1)
return;
switch (nBaudrate)
{
case 0:
CAN_Initialize(m_PcanHandle, PCAN_BAUD_1M, 0, 0, 0);
break;
case 1:
CAN_Initialize(m_PcanHandle, PCAN_BAUD_500K, 0, 0, 0);
break;
case 2:
CAN_Initialize(m_PcanHandle, PCAN_BAUD_250K, 0, 0, 0);
break;
case 3:
CAN_Initialize(m_PcanHandle, PCAN_BAUD_125K, 0, 0, 0);
break;
case 4:
CAN_Initialize(m_PcanHandle, PCAN_BAUD_100K, 0, 0, 0);
break;
case 5:
CAN_Initialize(m_PcanHandle, PCAN_BAUD_50K, 0, 0, 0);
break;
case 6:
CAN_Initialize(m_PcanHandle, PCAN_BAUD_20K, 0, 0, 0);
break;
case 7:
CAN_Initialize(m_PcanHandle, PCAN_BAUD_10K, 0, 0, 0);
break;
}
}
void CCanToolDlg::OnBnClickedReadBtn()
{
SetTimer(1, 100, NULL);
}
```
这是一个简单的MFC界面工具,用于与CAN总线通信。您可以根据需要进行修改和调整。
阅读全文