MFC_系统对话框(CFileDialog、字符编码转化ANSI-UTF8-Unicode、Window记事本demo练习)

1. 系统文件对话框(CFileDialog)

CFileDialog类的构造函数如下:

CFileDialog( BOOL bOpenFileDialog, 
			LPCTSTR lpszDefExt = NULL, LPCTSTR lpszFileName = NULL, DWORD dwFlags = OFN_HIDEREADONLY |
			OFN_OVERWRITEPROMPT, LPCTSTR lpszFilter = NULL, CWnd* pParentWnd = NULL 
);

其中处理第一个以外都是默认参数。
第一个参数如果是TRUE就是系统打开对话框,带FALSE就是系统另存为对话框。

这两个对话框属于模态对话框.

系统打开对话框如下:

void CSystemWinDlg::OnBnClickedBntChoice()
{
	// TODO: 在此添加控件通知处理程序代码
	CFileDialog dlg(TRUE);
	dlg.DoModal();
}

在这里插入图片描述
系统另存为对话框如下:

void CSystemWinDlg::OnBnClickedBntChoice()
{
	// TODO: 在此添加控件通知处理程序代码
	CFileDialog dlg(FALSE);
	dlg.DoModal();
}

在这里插入图片描述
构造函数中:

  1. 第二个参数代表对话框默认打开的文件.
  2. 第三个参数代表默认文件名
  3. 第四个参数dwFlags代表了系统对话框的属性,eg(可以选择多个文件,文件必须存在等等)
  4. lpszFilter:是过滤器,代表对话框可以过滤掉一些文件。这个参数类型是字符串。
    这个字符串格式如下:文本|过滤类型(多个过滤类型用分号隔开)|文本|过滤类型||(||代表结束)
    eg:
void CSystemWinDlg::OnBnClickedBntChoice()
{
	// TODO: 在此添加控件通知处理程序代码
	CFileDialog dlg(FALSE, L"txt", L"Test", OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT
		, L"文本文件(*.txt)|*.txt|音乐文件(*.mp3、*.wav)|(*.mp3;*.wav)|所有文件(*.*)|*.*||");
	dlg.DoModal();
}

在这里插入图片描述


成员函数:

  1. GetFileName:获取选择的文件名字
  2. GetPathName:获取选择文件的路径
  3. GetFileExt:获取文件拓展名
  4. GetFileTitle:获取文件名
  5. GetStartPosition:返回POSITION类型,返回文件首位置。适合用在系统对话框选择可以多选文件时。
  6. GetNextPathName:获得POSITION位置的文件名,同时会让POSITION自动+1。(类似迭代器)
void CSystemWinDlg::OnBnClickedBntChoice()
{
	// TODO: 在此添加控件通知处理程序代码
	CFileDialog dlg(TRUE, L"txt", L"Test", OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT| OFN_ALLOWMULTISELECT
		, L"文本文件(*.txt)|*.txt|音乐文件(*.mp3、*.wav)|(*.mp3;*.wav)|所有文件(*.*)|*.*||");
	dlg.DoModal();

	POSITION pos = dlg.GetStartPosition();
	while (pos) {
		CString str = dlg.GetNextPathName(pos);
		MessageBox(str);
	}
}

2. 字符编码

  • 多字节编码:为了扩展编码可以表示的字符,引入了双字节字符集。如果第一个字节为0x81->0x9F之间 或 0xE0->0xFC之间需要检测下一个字节,拼接起来才能确定这个文字。

  • Unicode编码:在1988年创立。主要分为UTF-8、UTF-16、UTF-32

  1. UTF-8:有一些字符编码为一个字节,有些编码为二个字节,有些编码为三个字节
  2. UTF-16:将所有的字符编码为两个字节
  3. UTF-32:将所有字符编码为四个字节

Unicode编码需要在字符串、字符前加L。代表宽字符类型wchar_t,Window默认按照UTF-16进行编码(Uncode)。每个宽字符两个字节。

在MFC中
CHAR=>char
WCHAR=>wchar_t
TCHAR:如果定义了Unicode编码TCHAR=>wchar_t
如果没有定义Unicode编码这个工程是ANSI工程(多字节编码),TCHAR=>char
在这里插入图片描述

通用宏TEXT、_T

  1. TEXT在Unicode编码中:
    TEXT <=> __TEXT <=> L##quote

  2. TEXT在ANSI工程中:
    TEXT <=> __TEXT <=> quote

所以采用TEXT宏可以自动适配工程使用的编码集
在这里插入图片描述

同样_T这个宏功能与TEXT宏作用相同。

C语言对应宽字符函数对应:

ANSI: strlen、strcpy、strcmp、strcat
Unicode:wcslen、wcscpy、wcscmp、wcscat(宽字符)

字符集转化

字符集转化主要使用两个函数:WideCharToMultiByte和MultiByteToWideChar

字符集转化大致分为如下部分,Unicode编码就是UTF-16编码

  1. ANSI <=> Unicode
  2. ANSI <=> UTF-8
  3. Unicode <=> UTF-8

ANSI转化Unicode核心代码:

#pragma once

#include"framework.h"

class ChangeCharSet{
private:
	wchar_t* w_charbuff;
	char* charbuff;
public:
	ChangeCharSet()
		:w_charbuff(nullptr), charbuff(nullptr)
	{}
	~ChangeCharSet() {
		if (w_charbuff != nullptr) {
			delete[] w_charbuff;
			w_charbuff = nullptr;
		}
		if (charbuff != nullptr) {
			delete[] charbuff;
			charbuff = nullptr;
		}
	}

	//ANSI=>Unicode
	wchar_t* AnsiToUnicode(const char* str) {
		//-1会自动推导字符串长度
		if (w_charbuff != nullptr) {
			delete[] w_charbuff;
			w_charbuff = nullptr;
		}
		DWORD dsize = ::MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
		w_charbuff = new wchar_t[dsize];
		::MultiByteToWideChar(CP_ACP, 0, str, -1, w_charbuff, dsize);
		return w_charbuff;
	}

	//Uncode=>ANSI
	char* UnicodeToAnsi(const wchar_t* w_str) {
		if (charbuff != nullptr) {
			delete[] charbuff;
			charbuff = nullptr;
		}
		DWORD dsize = ::WideCharToMultiByte(CP_ACP, 0, w_str, -1, NULL, 0, NULL, NULL);
		charbuff = new char[dsize];
		::WideCharToMultiByte(CP_ACP, 0, w_str, -1, charbuff, dsize, NULL, NULL);
		return charbuff;
	}
};

Unicode转化为UTF-8:

class ChangeCharSet{
private:
	wchar_t* w_charbuff;
	char* charbuff;
public:
	ChangeCharSet()
		:w_charbuff(nullptr), charbuff(nullptr)
	{}
	~ChangeCharSet() {
		if (w_charbuff != nullptr) {
			delete[] w_charbuff;
			w_charbuff = nullptr;
		}
		if (charbuff != nullptr) {
			delete[] charbuff;
			charbuff = nullptr;
		}
	}

	//Unicode=>UTF-8
	char* UnicodeToUTF_8(const wchar_t* w_str) {
		if (charbuff != nullptr) {
			delete[] charbuff;
			charbuff = nullptr;
		}
		DWORD dsize = ::WideCharToMultiByte(CP_UTF8, 0, w_charbuff, -1, NULL, 0, NULL, NULL);
		charbuff = new char[dsize];
		::WideCharToMultiByte(CP_UTF8, 0, w_charbuff, -1, charbuff, dsize, NULL, NULL);
		return charbuff;
	}

	//UTF-8=>Unicode
	wchar_t* UTF_8ToUnicode(const char* str) {
		if (w_charbuff != nullptr) {
			delete[] w_charbuff;
			w_charbuff = nullptr;
		}
		DWORD dsize = ::MultiByteToWideChar(CP_UTF8, 0, str, -1, NULL, 0);
		w_charbuff = new wchar_t[dsize];
		::MultiByteToWideChar(CP_UTF8, 0, str, -1, w_charbuff, dsize);
		return w_charbuff;
	}
}

ANSI转化为UTF-8:

ANSI不能直接转化为UTF-8、ANSI需要先转化为Unicode,再由Unicode转化为UTF-8。
可以直接复用上面的成员函数。

class ChangeCharSet{
private:
	wchar_t* w_charbuff;
	char* charbuff;
public:
	ChangeCharSet()
		:w_charbuff(nullptr), charbuff(nullptr)
	{}
	~ChangeCharSet() {
		if (w_charbuff != nullptr) {
			delete[] w_charbuff;
			w_charbuff = nullptr;
		}
		if (charbuff != nullptr) {
			delete[] charbuff;
			charbuff = nullptr;
		}
	}

	//ANSI=>Unicode
	wchar_t* AnsiToUnicode(const char* str) {
		//-1会自动推导字符串长度
		if (w_charbuff != nullptr) {
			delete[] w_charbuff;
			w_charbuff = nullptr;
		}
		DWORD dsize = ::MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
		w_charbuff = new wchar_t[dsize];
		::MultiByteToWideChar(CP_ACP, 0, str, -1, w_charbuff, dsize);
		return w_charbuff;
	}

	//Uncode=>ANSI
	char* UnicodeToAnsi(const wchar_t* w_str) {
		if (charbuff != nullptr) {
			delete[] charbuff;
			charbuff = nullptr;
		}
		DWORD dsize = ::WideCharToMultiByte(CP_ACP, 0, w_str, -1, NULL, 0, NULL, NULL);
		charbuff = new char[dsize];
		::WideCharToMultiByte(CP_ACP, 0, w_str, -1, charbuff, dsize, NULL, NULL);
		return charbuff;
	}

	//Unicode=>UTF-8
	char* UnicodeToUTF_8(const wchar_t* w_str) {
		if (charbuff != nullptr) {
			delete[] charbuff;
			charbuff = nullptr;
		}
		DWORD dsize = ::WideCharToMultiByte(CP_UTF8, 0, w_charbuff, -1, NULL, 0, NULL, NULL);
		charbuff = new char[dsize];
		::WideCharToMultiByte(CP_UTF8, 0, w_charbuff, -1, charbuff, dsize, NULL, NULL);
		return charbuff;
	}

	//UTF-8=>Unicode
	wchar_t* UTF_8ToUnicode(const char* str) {
		if (w_charbuff != nullptr) {
			delete[] w_charbuff;
			w_charbuff = nullptr;
		}
		DWORD dsize = ::MultiByteToWideChar(CP_UTF8, 0, str, -1, NULL, 0);
		w_charbuff = new wchar_t[dsize];
		::MultiByteToWideChar(CP_UTF8, 0, str, -1, w_charbuff, dsize);
		return w_charbuff;
	}

	//ANSI=>UTF-8
	char* AnsiToUTF_8(const char* str) {
		//ANSI=>Uncode
		w_charbuff = AnsiToUnicode(str);
		//Unicode=>UTF-8
		charbuff = UnicodeToUTF_8(w_charbuff);
		return charbuff;
	}

	//UTF-8=>ANSI
	char* UTF_8ToAnsi(const char* str) {
		//UTF-8->Unicode
		w_charbuff = UTF_8ToUnicode(str);
		//Unicode->ANSI
		charbuff = UnicodeToAnsi(w_charbuff);
		return charbuff;
	}
};

3. DEMO Windows记事本

需要注意:
记事本内的文字编码是Unicode,保存记事本内容后,保存文件编码为ANSI。

平台:windows 10

开发工具:Visual studio 2022

核心功能:保存txt文件,读取txt文件。更改记事本内容的颜色,大小。替换查找记事本的文本

核心功能代码:


// NotePadeDemoDlg.cpp: 实现文件
//
#include "framework.h"
#include "NotePadeDemo.h"
#include "NotePadeDemoDlg.h"
#include "afxdialogex.h"
#include"ChangeCharSet.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

//向系统注册消息
static UINT NEAR WM_FINDREPLACE = ::RegisterWindowMessage(FINDMSGSTRING);


// CNotePadeDemoDlg 对话框

CNotePadeDemoDlg::CNotePadeDemoDlg(CWnd* pParent /*=nullptr*/)
	: CDialogEx(IDD_NOTEPADEDEMO_DIALOG, pParent)
{
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
	m_choice = RGB(0, 0, 0);//默认选择颜色是黑色
	m_flag = FALSE;
	nStartIndex = 0;
	nEndIndex = 0;
}

void CNotePadeDemoDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CNotePadeDemoDlg, CDialogEx)
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDOK, &CNotePadeDemoDlg::OnBnClickedOk)
	ON_WM_SIZE()
	ON_COMMAND(ID_OPEN, &CNotePadeDemoDlg::OnMenuOpen)
	ON_COMMAND(ID_SAVE_AS, &CNotePadeDemoDlg::OnMenuSaveAs)
	ON_COMMAND(ID_CHANGE_COLOUR, &CNotePadeDemoDlg::OnChangeColour)
	ON_WM_CTLCOLOR()
	ON_COMMAND(ID_CHANGE_TITLE, &CNotePadeDemoDlg::OnChangeTitle)
	ON_COMMAND(ID_EXIT, &CNotePadeDemoDlg::OnExit)
	ON_COMMAND(ID_FIND, &CNotePadeDemoDlg::OnFind)
	ON_COMMAND(ID_REPLACE, &CNotePadeDemoDlg::OnReplace)
	ON_REGISTERED_MESSAGE(WM_FINDREPLACE, &CNotePadeDemoDlg::OnFindReplace)
END_MESSAGE_MAP()


// CNotePadeDemoDlg 消息处理程序

BOOL CNotePadeDemoDlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();

	// 设置此对话框的图标。  当应用程序主窗口不是对话框时,框架将自动
	//  执行此操作
	SetIcon(m_hIcon, TRUE);			// 设置大图标
	SetIcon(m_hIcon, FALSE);		// 设置小图标

	// TODO: 在此添加额外的初始化代码
	// 
	//设置字体
	HFONT hfont = CreateFont(32, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET
		, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH
		, L"黑体");
	//获取控件
	HWND hwnd = ::GetDlgItem(this->m_hWnd, IDC_EDIT);

	//设置字体大小
	::SendMessage(hwnd, WM_SETFONT, WPARAM(hfont), 0);

	return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
}

// 如果向对话框添加最小化按钮,则需要下面的代码
//  来绘制该图标。  对于使用文档/视图模型的 MFC 应用程序,
//  这将由框架自动完成。

void CNotePadeDemoDlg::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 CNotePadeDemoDlg::OnQueryDragIcon()
{
	return static_cast<HCURSOR>(m_hIcon);
}


void CNotePadeDemoDlg::OnBnClickedOk()
{
	// TODO: 在此添加控件通知处理程序代码
	//CDialogEx::OnOK();
}


void CNotePadeDemoDlg::OnSize(UINT nType, int cx, int cy)
{
	CDialogEx::OnSize(nType, cx, cy);

	// TODO: 在此处添加消息处理程序代码
	//获取控件
	CWnd* wnd = GetDlgItem(IDC_EDIT);
	if (wnd != NULL) {
		wnd->MoveWindow(0, 0, cx, cy);
	}
}


//打开
void CNotePadeDemoDlg::OnMenuOpen()
{
	// TODO: 在此添加命令处理程序代码
	CFileDialog dlg(TRUE);
	if (IDCANCEL == dlg.DoModal()) {
		return;
	}

	CString strpath = dlg.GetPathName();

	//打开文件,以读取的方式打开文件,读取文件编码为ANSI
	CFile file;
	if (FALSE == file.Open(strpath, CFile::modeRead)) {
		MessageBox(TEXT("打开文件失败"), TEXT("警告"), MB_OK | MB_ICONWARNING);
		return;
	}
	char buff[255] = { 0 };
	CStringA msg;
	//一次读取一个字符
	while (file.Read(buff, 1)) {
		msg += buff;
	}

	ChangeCharSet charset;
	wchar_t* title_msg = charset.AnsiToUnicode(msg);
	//设置窗口
	SetDlgItemText(IDC_EDIT, title_msg);

	//设置窗口标题
	CString title;
	title.Format(TEXT("NodePadeDemo ——%s[%d字节]"), dlg.GetFileName(), file.GetLength());
	SetWindowText(title);

	file.Close();
}

//另存为
void CNotePadeDemoDlg::OnMenuSaveAs()
{
	// TODO: 在此添加命令处理程序代码
	CFileDialog dlg(FALSE, NULL, NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, NULL);
	if (IDCANCEL == dlg.DoModal()) {
		return;
	}
	CString path = dlg.GetPathName();
	CFile file;
	if (IDCANCEL == file.Open(path, CFile::modeCreate | CFile::modeWrite)) {
		MessageBox(TEXT("保存文件失败"), TEXT("警告"), MB_OK | MB_ICONWARNING);
		return;
	}

	//读取控件上的所有文本
	CString msg;
	GetDlgItemText(IDC_EDIT, msg);

	ChangeCharSet charset;
	char* title_msg = charset.UnicodeToAnsi(msg);
	//宽字符写入
	file.Write(title_msg, strlen(title_msg));
	file.Close();

	//退出程序
	CDialogEx::OnOK();
}


void CNotePadeDemoDlg::OnChangeColour()
{
	// TODO: 在此添加命令处理程序代码
	//弹出颜色系统框
	CColorDialog color;
	if (IDCANCEL == color.DoModal()) {
		return;
	}
	//获取选择的颜色
	this->m_choice = color.GetColor();
	//更改控件的颜色,通过发送WM_CTLCOLOR消息来改变颜色
}


HBRUSH CNotePadeDemoDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
	HBRUSH hbr = CDialogEx::OnCtlColor(pDC, pWnd, nCtlColor);

	switch (pWnd->GetDlgCtrlID()){
		case IDC_EDIT:
		{
			pDC->SetTextColor(m_choice);
			break;
		}
		default:
			break;
	}
	return hbr;
}


void CNotePadeDemoDlg::OnChangeTitle()
{
	// TODO: 在此添加命令处理程序代码
	CFontDialog dlg;
	if (IDCANCEL == dlg.DoModal()) {
		return;
	}

	//创建选择的字体
	CFont font;
	font.CreatePointFont(dlg.GetSize(), dlg.GetFaceName());

	//设置字体
	GetDlgItem(IDC_EDIT)->SetFont(&font);
}


void CNotePadeDemoDlg::OnExit()
{
	//退出程序
	CDialogEx::OnOK();
}

//查找对话框

void CNotePadeDemoDlg::OnFind()
{
	//非模态对话框
	CFindReplaceDialog* dlg = new CFindReplaceDialog;

	//TRUE代表是查找框,FALSE代表是替换框
	dlg->Create(TRUE, NULL, NULL);

	dlg->ShowWindow(SW_SHOW);

	//不需要delete,CFindReplaceDialog类内部处理了。不会导致内存泄漏

	//此外,还需要向系统注册一个消息
	this->m_flag = TRUE;
}


void CNotePadeDemoDlg::OnReplace()
{
	//非模态对话框
	CFindReplaceDialog* dlg = new CFindReplaceDialog;

	//TRUE代表是查找框,FALSE代表是替换框
	dlg->Create(FALSE, NULL, NULL);

	dlg->ShowWindow(SW_SHOW);

	this->m_flag = FALSE;
}

//处理查找和替换操作
LRESULT CNotePadeDemoDlg::OnFindReplace(WPARAM wparam, LPARAM lparam) {
	CFindReplaceDialog* lpfindReplace = CFindReplaceDialog::GetNotifier(lparam);  
	if (lpfindReplace == nullptr) {
		return 0;
	}
	//如果要退出窗口
	if (lpfindReplace->IsTerminating()) {
		return 0;
	}
	//获取需要查找字符串
	CString str_find = lpfindReplace->GetFindString();
	//获取要替换的字符串
	CString str_replaces = lpfindReplace->GetReplaceString();

	BOOL SearchDownFlag = lpfindReplace->SearchDown();//判断是否向下查找,TRUE代表向下查找

	BOOL MatchCass = lpfindReplace->MatchCase();//判断是否区分大小

	//获取记事本内的文本
	CString strContent;
	GetDlgItemText(IDC_EDIT, strContent);

	//获取记事本文本控件
	CEdit* lpEdit = (CEdit*)GetDlgItem(IDC_EDIT);

	//查找
	if (this->m_flag == TRUE) {
		//获取光标起始,结束位置
		lpEdit->GetSel(this->nStartIndex, this->nEndIndex);

		if (SearchDownFlag) {
			//向下查找
			//从结束位置开始向下找
			this->nStartIndex = strContent.Find(str_find, this->nEndIndex);
			if (this->nStartIndex != -1) {
				//找到了,标记这个字符串
				lpEdit->SetSel(this->nStartIndex, this->nStartIndex + str_find.GetLength());
				lpEdit->SetFocus();
			}
			else {
				从头开始找
				//this->nStartIndex = strContent.Find(str_find, 0);
					//文中没有这个字符串
				CString msg;
				msg.Format(L"在下文中没有找到%s这个字符串", str_find.GetString());
				MessageBox(msg, L"警告", MB_OK|MB_ICONWARNING);
				return 0;

				//else {
				//	//找到了,标记这个字符串
				//	MessageBox(L"在上文中找到这个字符串", L"提示");
				//	lpEdit->SetSel(this->nStartIndex, this->nStartIndex + str_find.GetLength());
				//	lpEdit->SetFocus();
				//}
			}
		}
		else {
			//向上查找,反转字符串
			strContent = strContent.MakeReverse();
			CString str_refind = str_find.MakeReverse();
			this->nStartIndex = strContent.Find(str_refind, strContent.GetLength() - this->nStartIndex);

			if (this->nStartIndex != -1) {
				//设置光标
				this->nEndIndex = strContent.GetLength() - this->nStartIndex;
				lpEdit->SetSel(nEndIndex - str_find.GetLength(), nEndIndex);
				lpEdit->SetFocus();
			}
			else {
				CString msg;
				msg.Format(L"在上文中没有找到%s这个字符串", str_find.GetString());
				MessageBox(msg, L"警告", MB_OK | MB_ICONWARNING);
				return 0;
			}
		}
	}
	//替换
	else {
		if (lpfindReplace->ReplaceCurrent()) {
			this->nStartIndex = strContent.Find(str_find);
			if (this->nStartIndex == -1) {
				MessageBox(L"查不到这个字符串", L"警告", MB_OK);
				return 0;
			}
			else {
				this->nEndIndex = this->nStartIndex + str_find.GetLength();

				//字符串剪切
				CString left = strContent.Left(nStartIndex);
				CString right = strContent.Right(strContent.GetLength() - nEndIndex);
				strContent = left + str_replaces + right;
				lpEdit->SetWindowText(strContent);
			}
		}

		//替换全部
		if (lpfindReplace->ReplaceAll()) {
			int ntimes = strContent.Replace(str_find, str_replaces);
			lpEdit->SetWindowText(strContent);
			CString msg;
			msg.Format(L"替换成功,替换了%d处", ntimes);
			MessageBox(msg, L"提示", MB_OK);
		}
	}
	return 0;
}

运行效果:
在这里插入图片描述
在这里插入图片描述

完整代码位置:
Github

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

NUC_Dodamce

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值