文章目录
1.预备知识
1.Visual Studio 的程序调试方法
Visual Studio是一种集成开发环境(IDE),它可以用于开发、调试和部署软件。在本实验中,我们将使用 Visual Studio 来编写和调试 MFC(Microsoft Foundation Classes)应用程序。
在 Visual Studio 中,可以使用以下方法进行程序调试:
- 设置断点:通过在代码中插入断点来暂停程序执行,以便检查变量的值、跟踪代码执行路径等。
- 单步调试:在断点处按下 F11 键,逐行执行程序,以便详细了解程序的执行过程。
- 监视:可以在调试期间监视并跟踪变量的值。
- 输出窗口:可以使用输出窗口输出调试信息,以便在调试期间查看。
2.MFC 消息映射的操作步骤
消息映射是 MFC 中处理窗口消息的机制。每当发生一个消息(比如鼠标移动、键盘按下等),MFC 会自动调用与该消息相关联的处理函数。
在 MFC 中,创建消息映射的步骤如下:
- 在主对话框类的头文件中声明消息处理函数。
- 在消息映射表中添加消息处理函数的映射条目。
消息映射的处理函数需要遵循特定的命名规则,如 OnMouseMove()
、OnKeyDown()
等。
3.在 MFC 程序中处理键盘和鼠标消息的方法
在 MFC 程序中,可以通过消息映射机制来处理键盘和鼠标消息。以下是处理常见消息的方法:
处理鼠标消息
- 鼠标移动(
OnMouseMove()
):当鼠标在窗口中移动时调用。 - 左键按下(
OnLButtonDown()
):当鼠标左键按下时调用。 - 右键按下(
OnRButtonDown()
):当鼠标右键按下时调用。
处理键盘消息
- 键盘按下(
OnKeyDown()
):当键盘上的某个键按下时调用。
在处理键盘消息时,可以使用 GetKeyState()
函数检查某个特定的键是否按下,如 SHIFT 键和 CTRL 键。
2.实验目的
- 掌握在 Visual Studio 的程序调试方法;
- 掌握 MFC 消息映射的操作步骤;
- 掌握在 MFC 程序中处理键盘和鼠标消息的方法。
3.实验内容
请编写一个多文档程序,要求如下:
- 在客户区时刻显示记录鼠标的位置状态,如果出现点击,则显示一个消息框,提示用户按下的是鼠标的哪个键
- 当用户按下 SHIFT 或 CTRL 键时,显示一个消息框,提示用户按下的是哪个键
4.代码实现
首先利用向导构建多文档程序框架,并将项目取名为Ex1
。
然后在类向导里添加相应事件如下:
1.鼠标移动消息
void CEx1View::OnMouseMove(UINT nFlags, CPoint point)
{
CView::OnMouseMove(nFlags, point);
// CPaintDC p(this);
// Invalidate();
auto p = GetDC();
CBrush brush(RGB(255, 255, 255));
p->SelectObject(&brush);
p->PatBlt(0, 0, 500, 500, WHITENESS);
CString s;
s.Format(TEXT("鼠标位于 ( %d , %d )"), point.x, point.y);
p->SetDCPenColor(BLACKNESS);
p->TextOut(100, 100, s);
// RedrawWindow(nullptr, nullptr, RDW_FRAME | RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASE);
}
2.鼠标点击消息
void CEx1View::OnLButtonDown(UINT nFlags, CPoint point)
{
/*std::string s("鼠标左键在 ( ");
(((s += std::to_string(point.x)) += ", ") += std::to_string(point.y)) += " ) 按下!";
MessageBox(s.c_str());*/
/*CString s;
s.Format(TEXT("鼠标左键在 ( %d , %d )按下!"), point.x, point.y);
MessageBox(s);*/
MessageBox(TEXT("鼠标左键按下!"));
CView::OnLButtonDown(nFlags, point);
}
void CEx1View::OnRButtonDown(UINT nFlags, CPoint point)
{
/*CString s;
s.Format(TEXT("鼠标右键在 ( %d , %d )按下!"), point.x, point.y);
MessageBox(s);*/
MessageBox(TEXT("鼠标右键按下!"));
CView::OnRButtonDown(nFlags, point);
}
3.键盘按下消息
void CEx1View::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
/*if (GetKeyState(VK_SHIFT) < 0)
MessageBox(TEXT("按下Shift键!"));
else if (GetKeyState(VK_CONTROL) < 0)
MessageBox(TEXT("按下Ctrl键!"));*/
switch (nChar)
{
case VK_SHIFT:
MessageBox(TEXT("按下Shift键!"));
break;
case VK_CONTROL:
MessageBox(TEXT("按下Ctrl键!"));
};
CView::OnKeyDown(nChar, nRepCnt, nFlags);
}
4.打印初始点
void CEx1View::OnPaint()
{
CPaintDC dc(this);
CPoint p;
GetCursorPos(&p);
CString s;
s.Format(TEXT("鼠标位于 ( %d , %d )"), p.x, p.y);
dc.TextOut(100, 100, s);
}
5.运行结果
1.在客户区时刻显示记录鼠标的位置状态
2.用户按下鼠标左键
3.用户按下鼠标右键
4.用户按下Shift键
5.用户按下Ctrl键
6.总结
1.实验中遇到的困难
如何格式化在屏幕中打印鼠标光标位置的问题
最开始想到的并不是MFC框架下的CString
类,而是标准库的string
类来格式化输出。但运行调试时出现了形参实参不匹配的问题以及多字节和宽字节的矛盾的问题。这是因为在创建项目时使用的是宽字节编码,而std::string
是多字节,这中间出现了编码转换的问题,可以使用宏TEXT
进行转换,但使用TEXT
对std::string
的c_str()
返回的C风格字符串转换时会报错。因此最终使用了MFC框架下的CString
类进行格式化输出。
如何在鼠标移动时清除上次已打印的光标位置文字的问题
只需要在每次打印之前将整个区域用白色填充即可,因此定义了CBrush
对象来实现功能。
如何打印初始光标位置的问题
重写函数void CEx1View::OnPaint()
即可,使用GetCursorPos
函数来获取当前位置。
2.心得体会
在本次实验中,我通过使用 Visual Studio 和 MFC 框架,学习了在 MFC 程序中处理键盘和鼠标消息的方法。通过实验,我掌握了 Visual Studio 的程序调试方法,包括设置断点、单步调试等。我还学会了如何利用消息映射机制处理鼠标和键盘消息,以及如何使用相关的函数和类来实现相应的功能。
在实验过程中,我遇到了一些困难,比如如何格式化输出光标位置、如何在鼠标移动时清除之前的文本等问题。通过查阅相关文档和调试代码,我成功解决了这些问题。
通过本次实验,我深刻理解了消息映射的概念和操作步骤,更加熟悉了 Visual Studio 的调试功能。我相信这些知识和经验将对我以后的学习和工作有很大帮助。
总的来说,本次实验让我对 MFC 鼠标和键盘编程有了更深入的了解,不仅加深了对相关知识的理解,还锻炼了我的问题解决能力和动手实践的能力。我相信这些收获将成为我继续学习和探索更复杂程序开发的基础。