文章目录
一、基于MFC的程序
1.建立一个MFC的工程文件
①使用工具
Visual Studio 2019
②建立过程
打开Virtual Studio 2019后,点击创建新项目,然后在搜索框中输入MFC,接着选择MFC应用,选择完成后,点击下一步
接下来就是配置新项目
然后是对MFC应用程序类型的选择,根据自己的需求选择,本程序是选择的对话框类型
直接点击完成,一个基于MFC的对话框类型的程序就创建完成
③设计界面过程
在资源管理器中找到资源文件,在资源文件中找到后缀为rc的文件,点击该文件
进入资源视图后,找到下图红框中的文件,点击它
将出现的界面中的控件删除
接下来,点击界面左侧的工具箱,然后,选择对话框编辑器,选择自己所需要的控件,进行界面设置
这就是设计完成的界面,点击界面中的确定按钮,就可以跳转到编写代码的地方,进行代码编写阶段
2.编写代码
①代码
程序大多数代码已经由工具自动生成,主要是完成对控件通知处理的代码
void CGuessNumberDlg::OnBnClickedButton2()
{
// TODO: 在此添加控件通知处理程序代码
srand(time(0));
int randNumber;
do {
randNumber = rand();//生成一个随机数
} while (randNumber < 1 || randNumber>10);//判断该数是否在1-10之间
CString randNumber1,edit1;
randNumber1.Format(_T("%d"), randNumber);//将随机数类型转换成字符型
SetDlgItemText(IDC_STATIC5, randNumber1);
GetDlgItemText(IDC_EDIT4, edit1);
SetDlgItemText(IDC_STATIC3, edit1);
//弹出一个消息提示框,提示看猜测是否正确
if (_ttoi(edit1) == randNumber) {
MessageBox(_T("恭喜你,猜测正确!"));
}
else {
MessageBox(_T("很遗憾,你猜测错误!"));
}
}
②分析代码
整个MFC程序是一个猜数字的一个小游戏,通过在界面的编辑出输入一个数字,输入数字可以是任何数字,通过比较输入的数字与随机生成的数字,看两个是否相等,如果相等就表示猜测正确,否则表示猜测错误。采用消息框的方式表示猜测的结果。
整个程序中包含对话框类(CGuessNumberDlg ),应用程序类(CGuessNumberApp) ,其中应用程序类继承应用程序基类(CWinApp),对话框类继承对话框基类(CDialogEx)。在CGuessNumberApp中,定义一个对话框对象,来创建一个对话框。
③效果呈现
二、采用命令工具cl.exe,linker.exe实现编译链接
1.准备工作(设置环境变量)
在电脑桌面,右击此电脑,选择属性进入控制面板主页
接下来,在系统变量中,找到Path,点击Path进行编辑
在电脑文件中找到cl.exe所在位置,并复制该路径
2.命令行工具cl.exe,linker.exe编译链接一个Window API程序
Window API 程序参考:https://blog.csdn.net/qq_43279579/article/details/108714380
在cmd中执行cl编译Window API程序的时候,总会报windows.h包括路径集,多番查找资料过后,总算解决这个问题。
解决方法参考:
在Windows命令行中使用cl.exe——如何设置环境变量
尽管,windows.h 不包括路径集的问题解决了,但是出现了新的问题。这个问题并未得到解决。
这问题再次被解决了,将t1.cpp复制放在一个新的地方
解决后,cl编译会得到下面图中红框中的文件。
接下来,使用link链接obj文件得到exe文件,执行exe文件,就可以的到一个Window API 的窗口程序。
link t1.obj
网上都说是因为没有添加依赖库的原因,但是,加上依赖库仍旧不能够解决这个问题。
如何查看依赖库:
点击项目,选择属性,找到链接器,选择输入
很开心这个问题又得到了解决,由于之前的项目是由VC下形成的,所以我又重新写了一个简单的窗口,这次在cmd上进行终于没有了错误。
结果显示:
3.命令行工具cl.exe,linker.exe编译链接一个MFC程序
cl.exe编译器将cpp文件编译成obj文件
在cmd中执行cl的命令进行编译,始终存在着一些问题,查找很多资料,问题都没有得到解决。
在不放弃的努力之下,cl 终于没有错误了
cl编译是成功的,会得到图片红框中的文件。
然后,用link链接这些obj文件,得到exe文件。但是,接下来就出现新的错误了。
解决方法:
由于命令链接它不会主动去找进入的入口(appmodul.cpp 和 winwain.cpp ),它需要自己书写一个进入的入口,所以在GuessNumber.cpp中添加下面这些代码。
extern int AFXAPI AfxWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
_In_ LPTSTR lpCmdLine, int nCmdShow);
extern "C" int WINAPI
_tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
_In_ LPTSTR lpCmdLine, int nCmdShow)
#pragma warning(suppress: 4985)
{
// call shared/exported WinMain
return AfxWinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow);
}
int AFXAPI AfxWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
_In_ LPTSTR lpCmdLine, int nCmdShow)
{
ASSERT(hPrevInstance == NULL);
int nReturnCode = -1;
CWinThread* pThread = AfxGetThread();
CWinApp* pApp = AfxGetApp();
// AFX internal initialization
if (!AfxWinInit(hInstance, hPrevInstance, lpCmdLine, nCmdShow))
goto InitFailure;
// App global initializations (rare)
if (pApp != NULL && !pApp->InitApplication())
goto InitFailure;
// Perform specific initializations
if (!pThread->InitInstance())
{
if (pThread->m_pMainWnd != NULL)
{
TRACE(traceAppMsg, 0, "Warning: Destroying non-NULL m_pMainWnd\n");
pThread->m_pMainWnd->DestroyWindow();
}
nReturnCode = pThread->ExitInstance();
goto InitFailure;
}
nReturnCode = pThread->Run();
InitFailure:
#ifdef _DEBUG
// Check for missing AfxLockTempMap calls
if (AfxGetModuleThreadState()->m_nTempMapLock != 0)
{
TRACE(traceAppMsg, 0, "Warning: Temp map lock count non-zero (%ld).\n",
AfxGetModuleThreadState()->m_nTempMapLock);
}
AfxLockTempMaps();
AfxUnlockTempMaps(-1);
#endif
AfxWinTerm();
return nReturnCode;
}
结果显示:
三、总结
相对于Window API的方式,MFC大大减少代码量。MFC是将Windo-w API封装成类,使用更加方便。总的来说,MFC方式要比Window API的更有优势。在使用命令行工具cl.exe,linker.exe实现编译链接的过程遇到了许多的问题,查找了许多资料也没有得到解决。大多数解决方法都是在设置环境变量上下功夫,但是即使添加了环境变量后,仍然还是会出现查找不到的情况。所有问题终于都完全解决了,原来环境变量每次改变了之后,后端都要重新打开一次,才有效。难怪每次改为系统变量后,再次执行,都没有得到解决。还好自己没在第一次失败后,就放任不管了。
四、参考资料
1.MFC简单的猜数字程序
2. windows命令行形式使用MSVC的C编译工具cl.exe-方法一
3. windows 控制台下运行cl命令
4. 从”fatal error C1034: 不包括路径集“学到的内容
5. VS2017实现简单的MFC窗口程序及用cl.exe和link.exe编译链接