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程序释放资源的主要内容,如果未能解决你的问题,请参考以下文章