MFC程序学习——MFC程序释放资源

Posted joker-yan

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MFC程序学习——MFC程序释放资源相关的知识,希望对你有一定的参考价值。



前言

最近课程比较忙,各种考试、实验什么的,之前打了一次省赛后就没时间去打CTF了,所以有点躺平~~

不过最近发现了MFC开发了乐趣,想去玩玩~~








一、手动添加资源

先注意到右侧的资源管理器,右键点击“first_mfc”(这个是我创建MFC项目时填的名字)

 

然后点击“自定义”,创建一个资源归类文件夹(我这里命名为“MYRES”)

 

 回到我们的资源管理器,发现成功建立一个资源管理文件夹。

然后就是添加我们想融合到我们的MFC程序的文件(可以是DLL文件、PNG、TXT等等)

这里我添加一个“333.txt”。具体步骤如下:

1、右键“MYRES”,选择“添加资源”

2、选择“导入”

3、选择项目的资源文件夹“res”下预先放好的文件“333.txt”(或者直接在本地找到具体路径也可以)

 4、点击确定后,选择资源类型“MYRES”(我们之前创建的资源管理文件夹)

添加成功后,对应的资源ID的宏定义为“IDR_MYRES3”(对应的宏定义会在virsual studio下自动生成,你也可以从“资源管理器”下找到具体对应的ID,其实就是一个整形数)








二、释放资源








1.利用MFC程序模板

先打开对话框,直接双击Dialog下的标记文件

 手动拖拉左边工具箱的“Button”到程序面板,(由于博主之前做过QT程序的开发,所以还算是比较容易接受)

后续,VS会生成对应的程序框架,为我们后续填充逻辑代码提供支持。

 双击打开该文件,

void CfirstmfcDlg::OnBnClickedButton1()//按钮1

	// TODO: 在此添加点击按钮后程序即将处理的代码
	char szSaveName[MAX_PATH] = "3334.txt";

	BOOL bRet = FreeMyResource(IDR_MYRES3, "MYRES", szSaveName);
	if (FALSE == bRet)
	
		::MessageBox(NULL, _T("Free Resource Error!"), _T("ERROR"), MB_OK);
	
	else
	
		::MessageBox(NULL, _T("Free Resource OK!"), _T("OK"), MB_OK);
	

这是利用VS生成Button1的框架后,博主填充的逻辑代码,

比较需要解释的就是后续利用到的FreeMyResource函数,以及全局函数MessageBox 

这里创建了两个函数: FreeRes_ShowError、FreeMyResource

由于这是博主第一次接触这种MFC程序,所以很多数据类型转换还不是很了解,如果解释的不对,望指正~~

void FreeRes_ShowError(char* pszText)


	LPTSTR szBuffer = new TCHAR[1024];
	::wsprintf(szBuffer,L"%hs Error[%d]\\n", (pszText), ::GetLastError());//宽字符
#ifdef _DEBUG
	::MessageBox(NULL, szBuffer, _T("ERROR"), MB_OK | MB_ICONERROR);
#endif

 上面使用了wsprintf()函数,将对应的字符串 “%hs Error[%d]\\n” 写入缓冲区szBuffer中,前面加了一个L,为什么,因为L代表了UNICODE字符串,而且我们是在unicode环境下编译的,还有为什么不是%s,而是%hs,(因为会报错~手动狗头),因为我们需要写入的是宽字符串,所以多加了一个h。

MessageBox()函数作用就是弹出一个报错窗口。

BOOL FreeMyResource(UINT uiResouceName, char* lpszResourceType, char* lpszSaveFileName)

	HRSRC hRsrc = ::FindResource(GetModuleHandle(NULL), MAKEINTRESOURCE(uiResouceName), CStringW(lpszResourceType));
	LPTSTR szBuffer = new TCHAR[1024];//这里是定义缓冲区大小

	if (hRsrc == NULL)
	
		FreeRes_ShowError("FindResource");
		return FALSE;
	
	DWORD dwSize = ::SizeofResource(NULL, hRsrc);
	if (0 >= dwSize)
	
		FreeRes_ShowError("SizeofResource");
		return FALSE;
	

	HGLOBAL hGlobal = ::LoadResource(NULL, hRsrc);
	if (NULL == hGlobal)
	
		FreeRes_ShowError("LoadResource");
		return FALSE;
	

	LPVOID lpVoid = ::LockResource(hGlobal);
	if (NULL == lpVoid)
	
		FreeRes_ShowError("LockResource");
		return FALSE;
	


	FILE* fp = NULL;
	fopen_s(&fp, lpszSaveFileName, "wb+");
	if (NULL == fp)
	
		FreeRes_ShowError("LockResource");
		return FALSE;
	
	fwrite(lpVoid, sizeof(char), dwSize, fp);
	fclose(fp);

	return TRUE;

上面的函数,基本上比较恶心到我的就是FindResource()了,里面的三个参数确立,花费了我好久~

查阅到的资源:

HRSRC FindResource (HMODULE hModule, LPCWSTR lpName, LPCWSTR lpType)
作用:确定模块中指定类型和名称的资源所在位置。

参数hModule[in]
处理包含资源的可执行文件模块。
若 hModule 为 NULL,则系统从当前进程的模块中装载资源。
lpName[in]指定资源名称。
lpType[in]指定资源类型。返回值
如果函数运行成功,那么返回值为指定资源信息块的句柄。可将这个句柄传递给LoadResource 函数来获得这些资源。
如果函数运行失败,则返回值为 NULL。

 第一个参数就直接指定当前运行的进程了(因为我们都把资源整合到最终的.exe中了),所以写NULL也可以,按我的写法也正确。

第二个参数就要指定对应的资源ID了,比如我们之前加入的333.txt,可以使用它对应的宏定义为“MYRES3”,也可以直接填写一个对应的资源ID数。

第三参数就是最恶心的了,它正好卡在我不熟悉的数据类型转换上,本来我是直接写的“MYRES”,这个是我们自定义的资源类型。(但是直接写会报错~~)

然后我就按照提示用强转(前面加上LPCWSTR),编译没问题,但是最终还是没有找到这个资源

 上面是我的报错信息,想知道具体出错的原因的,可以去查看这里有对应Error的ID下对应的原因

后面我仔细调整了一下它的数据类型,修改为

将char *str 转换为wchar_t字符。后面发现成功了,所以这里就是需要使用wchar_r类型的字符。

然后在代码对应的文件夹下发现了我们释放的文件“3334.txt”

 到此释放成功~









总结

希望后续有时间跟进学习,在兼顾学业的前提下再来学习新知识也是一种乐趣~

以上是关于MFC程序学习——MFC程序释放资源的主要内容,如果未能解决你的问题,请参考以下文章

MFC程序学习——MFC程序释放资源

MFC程序学习——MFC程序释放资源

MFC —— 资源文件释放(为了程序更简洁)

MFC —— 资源文件释放(为了程序更简洁)

如何为 MFC 线程设置超时

mfc HackerTools释放资源