对于一个MFC程序来说,在vs2019下做开发的话,可能比较重要的就四个文件,分别是应用程序类c文件和对话框类c文件,应用程序类.h文件和对话框类.h文件
其中
应用程序类负责 程序入口、初始化、主消息循环
对话框类负责 界面控件、业务逻辑、用户交互
命名规则:如果你新建项目时取名FlashTool,那么VS会自动生成:
CFlashToolApp → FlashTool.h / FlashTool.cpp
CFlashToolDlg → FlashToolDlg.h / FlashToolDlg.cpp
其中具体界面控件摆放,可以在编辑器里可视化操作
cpp
// MFCApplicationMathDlg.cpp: 实现文件
//
#include "pch.h"
#include "framework.h"
#include "MFCApplicationMath.h"
#include "MFCApplicationMathDlg.h"
#include "afxdialogex.h"
#include <atlimage.h>
#include <gdiplus.h> // 添加 GDI+ 头文件
#include <vector> // 如果使用 vector
#pragma comment(lib, "gdiplus.lib") // 链接 GDI+ 库
using namespace Gdiplus;
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// 用于应用程序"关于"菜单项的 CAboutDlg 对话框
class CAboutDlg : public CDialogEx
{
public:
CAboutDlg();
// 添加这个方法:用于设置主窗口指针
void SetMainDialog(CMFCApplicationMathDlg* pMainDlg)
{
m_pMainDlg = pMainDlg;
}
// 对话框数据
#ifdef AFX_DESIGN_TIME
enum { IDD = IDD_ABOUTBOX };
#endif
protected:
virtual void DoDataExchange(CDataExchange* pDX);
virtual BOOL OnInitDialog();
afx_msg void OnPaint();
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
protected:
DECLARE_MESSAGE_MAP()
private:
Gdiplus::Image* m_pImage; // 图片指针
CMFCApplicationMathDlg* m_pMainDlg; // 主窗口指针
public:
afx_msg void OnBnClickedClearSon();
afx_msg void OnBnClickedOk();
};
// CAboutDlg 构造函数 - 初始化所有成员变量
CAboutDlg::CAboutDlg()
: CDialogEx(IDD_ABOUTBOX)
, m_pImage(nullptr)
, m_pMainDlg(nullptr) // 初始化主窗口指针为 nullptr
{
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
}
BOOL CAboutDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
// 使用 GDI+ 加载图片
m_pImage = Gdiplus::Image::FromFile(_T("E:\\test.png"));
if (m_pImage == nullptr || m_pImage->GetLastStatus() != Gdiplus::Ok)
{
delete m_pImage;
m_pImage = nullptr;
TRACE(_T("图片加载失败: E:\\test.png\n"));
}
return TRUE;
}
BOOL CAboutDlg::OnEraseBkgnd(CDC* pDC)
{
return TRUE; // 不擦除背景,避免闪烁
}
void CAboutDlg::OnPaint()
{
CPaintDC dc(this);
// 获取对话框客户区大小
CRect rect;
GetClientRect(&rect);
// 创建 GDI+ 图形对象
Gdiplus::Graphics graphics(dc.m_hDC);
// 用对话框背景色填充
Gdiplus::SolidBrush brush(Gdiplus::Color(240, 240, 240)); // 浅灰色背景
graphics.FillRectangle(&brush, 0, 0, rect.Width(), rect.Height());
if (m_pImage != nullptr)
{
// 获取图片原始尺寸
int imgWidth = m_pImage->GetWidth();
int imgHeight = m_pImage->GetHeight();
// 计算居中位置
int x = (rect.Width() - imgWidth) / 2;
int y = (rect.Height() - imgHeight) / 2;
// 绘制图片
graphics.DrawImage(m_pImage, x, y, imgWidth, imgHeight);
}
else
{
// 图片加载失败,显示文字
CFont* pOldFont = dc.SelectObject(GetFont());
dc.SetBkMode(TRANSPARENT);
CString strMsg;
strMsg.Format(_T("图片加载失败\n\n请检查路径: E:\\test.png\n\n图片格式: 支持 PNG、JPG、BMP"));
CRect textRect = rect;
textRect.DeflateRect(20, 20);
dc.DrawText(strMsg, textRect, DT_CENTER | DT_WORDBREAK);
dc.SelectObject(pOldFont);
}
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
ON_WM_PAINT()
ON_WM_ERASEBKGND()
ON_BN_CLICKED(IDC_CLEAR_SON, &CAboutDlg::OnBnClickedClearSon)
ON_BN_CLICKED(IDOK, &CAboutDlg::OnBnClickedOk)
END_MESSAGE_MAP()
// CAboutDlg 清除按钮响应函数
void CAboutDlg::OnBnClickedClearSon()
{
// 检查主窗口指针是否有效
if (m_pMainDlg != nullptr && ::IsWindow(m_pMainDlg->GetSafeHwnd()))
{
// 清除主窗口中的编辑框内容(计算器显示屏)
m_pMainDlg->SetDlgItemText(IDC_EDIT1, _T(""));
// 重新启用编辑框(如果之前被禁用了)
m_pMainDlg->GetDlgItem(IDC_EDIT1)->EnableWindow(TRUE);
}
else
{
MessageBox(_T("主窗口指针无效,无法清除"), _T("错误"), MB_OK | MB_ICONERROR);
}
}
// CMFCApplicationMathDlg 对话框
CMFCApplicationMathDlg::CMFCApplicationMathDlg(CWnd* pParent /*=nullptr*/)
: CDialogEx(IDD_MFCAPPLICATIONMATH_DIALOG, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CMFCApplicationMathDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CMFCApplicationMathDlg, CDialogEx)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_BUTTON19, &CMFCApplicationMathDlg::OnBnClickedButton19)
ON_BN_CLICKED(IDC_BUTTON10, &CMFCApplicationMathDlg::OnBnClickedButton10)
ON_BN_CLICKED(IDC_BUTTON11, &CMFCApplicationMathDlg::OnBnClickedButton11)
ON_BN_CLICKED(IDC_BUTTON12, &CMFCApplicationMathDlg::OnBnClickedButton12)
ON_BN_CLICKED(IDC_BUTTON13, &CMFCApplicationMathDlg::OnBnClickedButton13)
ON_BN_CLICKED(IDC_BUTTON14, &CMFCApplicationMathDlg::OnBnClickedButton14)
ON_BN_CLICKED(IDC_BUTTON15, &CMFCApplicationMathDlg::OnBnClickedButton15)
ON_BN_CLICKED(IDC_BUTTON16, &CMFCApplicationMathDlg::OnBnClickedButton16)
ON_BN_CLICKED(IDC_BUTTON17, &CMFCApplicationMathDlg::OnBnClickedButton17)
ON_BN_CLICKED(IDC_BUTTON18, &CMFCApplicationMathDlg::OnBnClickedButton18)
ON_BN_CLICKED(IDC_BUTTON20, &CMFCApplicationMathDlg::OnBnClickedButton20)
ON_BN_CLICKED(IDC_BUTTON21, &CMFCApplicationMathDlg::OnBnClickedButton21)
ON_BN_CLICKED(IDC_BUTTON22, &CMFCApplicationMathDlg::OnBnClickedButton22)
ON_BN_CLICKED(IDC_BUTTON23, &CMFCApplicationMathDlg::OnBnClickedButton23)
ON_BN_CLICKED(IDC_BUTTON24, &CMFCApplicationMathDlg::OnBnClickedButton24)
ON_COMMAND(ID_32771, &CMFCApplicationMathDlg::On_author)
ON_BN_CLICKED(IDC_BUTTON25, &CMFCApplicationMathDlg::OnBnClickedButton25)
ON_BN_CLICKED(IDC_BUTTON1, &CMFCApplicationMathDlg::OnBnClickedButton1)
END_MESSAGE_MAP()
// CMFCApplicationMathDlg 消息处理程序
BOOL CMFCApplicationMathDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
// 注意:GDI+ 的初始化建议移到 CWinApp::InitInstance() 中
// 这里仅作为示例,实际使用时可能会重复初始化
static bool bGdiPlusStarted = false;
if (!bGdiPlusStarted)
{
GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
bGdiPlusStarted = true;
}
// 将"关于..."菜单项添加到系统菜单中。
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != nullptr)
{
BOOL bNameValid;
CString strAboutMenu;
bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
ASSERT(bNameValid);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// 设置此对话框的图标
SetIcon(m_hIcon, TRUE);
SetIcon(m_hIcon, FALSE);
// 加载菜单
CMenu menu;
menu.LoadMenuW(IDR_MENU1);
SetMenu(&menu);
menu.Detach();
return TRUE;
}
void CMFCApplicationMathDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.SetMainDialog(this); // 传递主窗口指针给关于对话框
dlgAbout.DoModal();
}
else
{
CDialogEx::OnSysCommand(nID, lParam);
}
}
void CMFCApplicationMathDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this);
SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialogEx::OnPaint();
}
}
HCURSOR CMFCApplicationMathDlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
}
// 数字按钮处理函数
void CMFCApplicationMathDlg::OnBnClickedButton10()
{
CString strCurrent;
GetDlgItemText(IDC_EDIT1, strCurrent);
strCurrent += _T("0");
SetDlgItemText(IDC_EDIT1, strCurrent);
}
void CMFCApplicationMathDlg::OnBnClickedButton11()
{
CString strCurrent;
GetDlgItemText(IDC_EDIT1, strCurrent);
strCurrent += _T("1");
SetDlgItemText(IDC_EDIT1, strCurrent);
}
void CMFCApplicationMathDlg::OnBnClickedButton12()
{
CString strCurrent;
GetDlgItemText(IDC_EDIT1, strCurrent);
strCurrent += _T("2");
SetDlgItemText(IDC_EDIT1, strCurrent);
}
void CMFCApplicationMathDlg::OnBnClickedButton13()
{
CString strCurrent;
GetDlgItemText(IDC_EDIT1, strCurrent);
strCurrent += _T("3");
SetDlgItemText(IDC_EDIT1, strCurrent);
}
void CMFCApplicationMathDlg::OnBnClickedButton14()
{
CString strCurrent;
GetDlgItemText(IDC_EDIT1, strCurrent);
strCurrent += _T("4");
SetDlgItemText(IDC_EDIT1, strCurrent);
}
void CMFCApplicationMathDlg::OnBnClickedButton15()
{
CString strCurrent;
GetDlgItemText(IDC_EDIT1, strCurrent);
strCurrent += _T("5");
SetDlgItemText(IDC_EDIT1, strCurrent);
}
void CMFCApplicationMathDlg::OnBnClickedButton16()
{
CString strCurrent;
GetDlgItemText(IDC_EDIT1, strCurrent);
strCurrent += _T("6");
SetDlgItemText(IDC_EDIT1, strCurrent);
}
void CMFCApplicationMathDlg::OnBnClickedButton17()
{
CString strCurrent;
GetDlgItemText(IDC_EDIT1, strCurrent);
strCurrent += _T("7");
SetDlgItemText(IDC_EDIT1, strCurrent);
}
void CMFCApplicationMathDlg::OnBnClickedButton18()
{
CString strCurrent;
GetDlgItemText(IDC_EDIT1, strCurrent);
strCurrent += _T("8");
SetDlgItemText(IDC_EDIT1, strCurrent);
}
void CMFCApplicationMathDlg::OnBnClickedButton19()
{
CString strCurrent;
GetDlgItemText(IDC_EDIT1, strCurrent);
strCurrent += _T("9");
SetDlgItemText(IDC_EDIT1, strCurrent);
}
void CMFCApplicationMathDlg::OnBnClickedButton20()
{
CString strCurrent;
GetDlgItemText(IDC_EDIT1, strCurrent);
strCurrent += _T("+");
SetDlgItemText(IDC_EDIT1, strCurrent);
}
void CMFCApplicationMathDlg::OnBnClickedButton21()
{
CString strCurrent;
GetDlgItemText(IDC_EDIT1, strCurrent);
strCurrent += _T("-");
SetDlgItemText(IDC_EDIT1, strCurrent);
}
void CMFCApplicationMathDlg::OnBnClickedButton22()
{
CString strCurrent;
GetDlgItemText(IDC_EDIT1, strCurrent);
strCurrent += _T("*");
SetDlgItemText(IDC_EDIT1, strCurrent);
}
void CMFCApplicationMathDlg::OnBnClickedButton23()
{
CString strCurrent;
GetDlgItemText(IDC_EDIT1, strCurrent);
strCurrent += _T("/");
SetDlgItemText(IDC_EDIT1, strCurrent);
}
void CMFCApplicationMathDlg::OnBnClickedButton24()
{
CString strExpression;
GetDlgItemText(IDC_EDIT1, strExpression);
if (strExpression.IsEmpty())
return;
strExpression.TrimRight(_T("="));
double result = 0;
TCHAR op = 0;
double firstNum = 0, secondNum = 0;
int opPos = -1;
for (int i = 0; i < strExpression.GetLength(); i++)
{
TCHAR ch = strExpression[i];
if (ch == '+' || ch == '-' || ch == '*' || ch == '/')
{
op = ch;
opPos = i;
break;
}
}
if (opPos != -1)
{
CString strFirst = strExpression.Left(opPos);
CString strSecond = strExpression.Mid(opPos + 1);
firstNum = _ttof(strFirst);
secondNum = _ttof(strSecond);
switch (op)
{
case '+': result = firstNum + secondNum; break;
case '-': result = firstNum - secondNum; break;
case '*': result = firstNum * secondNum; break;
case '/':
if (secondNum == 0)
{
SetDlgItemText(IDC_EDIT1, _T("错误:除数不能为0"));
return;
}
result = firstNum / secondNum;
break;
}
CString strResult;
if (result == (int)result)
strResult.Format(_T("%d"), (int)result);
else
strResult.Format(_T("%g"), result);
SetDlgItemText(IDC_EDIT1, strResult);
}
else
{
SetDlgItemText(IDC_EDIT1, _T("表达式错误"));
}
}
// 菜单"关于"响应函数
void CMFCApplicationMathDlg::On_author()
{
// 在堆上创建对话框(不能用局部变量)
CAboutDlg* pDlg = new CAboutDlg();
// 传递主窗口指针
pDlg->SetMainDialog(this);
// 创建非模态对话框(IDD_ABOUTBOX 是你的对话框资源ID)
pDlg->Create(IDD_ABOUTBOX, this);
// 显示窗口
pDlg->ShowWindow(SW_SHOW);
}
// 清除按钮响应函数
void CMFCApplicationMathDlg::OnBnClickedButton25()
{
SetDlgItemText(IDC_EDIT1, _T(""));
GetDlgItem(IDC_EDIT1)->SetFocus();
}
// 禁用编辑框按钮(示例功能)
void CMFCApplicationMathDlg::OnBnClickedButton1()
{
GetDlgItem(IDC_EDIT1)->EnableWindow(FALSE);
}
void CAboutDlg::OnBnClickedOk()
{
std::vector<HWND> vecNotepads;
// 找到所有记事本
EnumWindows([](HWND hWnd, LPARAM lParam) -> BOOL {
TCHAR szClass[256];
GetClassName(hWnd, szClass, 256);
if (_tcscmp(szClass, _T("Notepad")) == 0)
{
((std::vector<HWND>*)lParam)->push_back(hWnd);
}
return TRUE;
}, (LPARAM)&vecNotepads);
if (vecNotepads.empty())
{
MessageBox(_T("没有找到任何记事本窗口"), _T("提示"), MB_OK);
return;
}
// 获取当前时间
CTime now = CTime::GetCurrentTime();
CString strTime = now.Format(_T("%Y-%m-%d %H:%M:%S"));
// 要追加的内容
CString strText;
strText.Format(_T("[%s] 批量追加的内容"), strTime);
int nCount = 0;
for (HWND hNotepad : vecNotepads)
{
if (::IsWindow(hNotepad))
{
::SetForegroundWindow(hNotepad);
::BringWindowToTop(hNotepad);
Sleep(150);
// Ctrl+End
keybd_event(VK_CONTROL, 0, 0, 0);
keybd_event(VK_END, 0, 0, 0);
Sleep(20);
keybd_event(VK_END, 0, KEYEVENTF_KEYUP, 0);
keybd_event(VK_CONTROL, 0, KEYEVENTF_KEYUP, 0);
Sleep(50);
// 换行
keybd_event(VK_RETURN, 0, 0, 0);
Sleep(10);
keybd_event(VK_RETURN, 0, KEYEVENTF_KEYUP, 0);
Sleep(50);
// 输入内容
for (int i = 0; i < strText.GetLength(); i++)
{
INPUT ip = { 0 };
ip.type = INPUT_KEYBOARD;
ip.ki.wVk = 0;
ip.ki.wScan = strText[i];
ip.ki.dwFlags = KEYEVENTF_UNICODE;
SendInput(1, &ip, sizeof(INPUT));
ip.ki.dwFlags = KEYEVENTF_UNICODE | KEYEVENTF_KEYUP;
SendInput(1, &ip, sizeof(INPUT));
Sleep(5);
}
nCount++;
}
}
CString strMsg;
strMsg.Format(_T("已向 %d 个记事本追加内容\n时间戳:%s"), nCount, strTime);
MessageBox(strMsg, _T("完成"), MB_OK);
}
这是一个简易计算器的对话框类c文件