回到90年代,当我第一次开始使用MFC时,我曾经动态链接我的应用程序并发送了相关的MFC DLL.这引起了我一些问题(DLL地狱!)而我改为静态链接 - 不仅仅是为了MFC,而是为了CRT和ATL.除了更大的EXE文件之外,静态链接从来没有给我带来任何问题 - 那么其他人是否有任何缺点?有没有充分的理由重新访问动态链接?我的应用程序现在主要是STL/Boost FWIW.
当消息泵中抛出异常时,我们遇到的问题是Windows静默地吃异常并允许应用程序继续运行.例如,我们创建了一个测试MFC MDI应用程序,并覆盖了OnDraw:
void CTestView::OnDraw(CDC* /*pDC*/)
{
*(int*)0 = 0; // Crash
CTestDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;
// TODO: add draw code for native data here
}
Run Code Online (Sandbox Code Playgroud)
在运行应用程序时,您会发现一个令人讨厌的错误消息,但实际上您什么也得不到.该程序似乎运行得很好,但是如果你检查输出窗口,你会看到:
Test.exe中0x13929384处的第一次机会异常:0xC0000005:访问冲突写入位置0x00000000.
Test.exe中0x77c6ee42的第一次机会异常:0xC0150010:当前执行的线程未激活的激活上下文无效.
我知道为什么我收到应用程序上下文异常,但为什么要静默处理?这意味着我们的应用程序在使用时可能会遇到严重问题,但我们永远不会知道它,因为我们的用户永远不会报告任何问题.
我使用Visual Studio打开了现有的MFC项目,当我构建时,我收到以下错误消息:
Error 1 error MSB8031: Use of MBCS encoding in MFC projects require an additional library to be downloaded and installed. Please see http://go.microsoft.com/fwlink/?LinkId=286820 for more information. C:\Program Files\MSBuild\Microsoft.Cpp\v4.0\v120\Microsoft.CppBuild.targets
Run Code Online (Sandbox Code Playgroud)
这是关于什么的?
我创建了一个应用程序,在其中我使用窗口过程来跟踪窗口中的所有控件.
我的问题是,我如何将焦点初始设置为窗口中第一个创建的控件?
使用Windows MFC C++.我有一个第三方应用程序,它在我的CWinApp派生类中调用用户定义的方法.在InitInstance()之后调用此方法.如果此方法中存在错误,则抛出异常并捕获到try/catch块中,我想从catch块退出应用程序.什么是规范和正确的退出方式?
更新:
Serge我认为是正确的,在InitInstance()中返回false是退出应用程序的正确方法.但是,现在假设我想从CDialog派生类的OnInitDialog()处理程序退出,这是正确的方法.
更新2
对我来说,我发现调用PostMessage(WM_CLOSE)是我的非模态CDialog派生类的最佳方法.我试过的所有其他戒烟方法都会在某些情况下引发一些例外情况.
这是我如何使用它的一个例子:
BOOL SomeDialog::OnInitDialog()
{
CDialog::OnInitDialog();
::OleInitialize(nullptr);
try
{
// ...load settings file here
}
catch(...)
{
PostMessage(WM_CLOSE);
return TRUE;
}
// return TRUE unless you set the focus to a control
return TRUE;
}
Run Code Online (Sandbox Code Playgroud) Windows API使用GetLastError()机制来检索有关错误或失败的信息.我正在考虑使用相同的机制来处理错误,因为我正在为专有模块编写API.我的问题是API更好地直接返回错误代码?不会GetLastError()有任何特别的优势?考虑下面的简单Win32 API示例:
HANDLE hFile = CreateFile(sFile,
GENERIC_WRITE, FILE_SHARE_READ,
NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
DWORD lrc = GetLastError();
if (lrc == ERROR_FILE_EXISTS)
{
// msg box and so on
}
}
Run Code Online (Sandbox Code Playgroud)
当我编写自己的API时,我意识到GetLastError()机制意味着CreateFile()必须在所有出口点设置最后一个错误代码.如果有许多退出点并且其中一个可能错过,则这可能会有一点容易出错.愚蠢的问题,但这是如何完成或有某种设计模式呢?
另一种方法是为函数提供一个额外的参数,它可以直接填写错误代码,因此GetLastError()不需要单独的调用.另一种方法可以如下.我将坚持使用上面的Win32 API,这是分析器的好例子.在这里,我将格式更改为此(假设).
result = CreateFile(hFile, sFile,
GENERIC_WRITE, FILE_SHARE_READ,
NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
if (result == SUCCESS)
{
// hFile has correct value, process it
}
else if (result == FILE_ALREADY_EXIT )
{
// display …Run Code Online (Sandbox Code Playgroud) 我知道一些C++和C,我现在正在使用的项目是很多MFC编程.有经验的人可以告诉我学习MFC的先决条件.
另外,最好的资料来源是什么?
任何特定的书籍或视频系列?
我知道这个问题太笼统,但答案可能会帮助我(或其他任何正在挖掘MFC的人)
谢谢!
我正在收到#error WINDOWS.H.MFC应用程序不能#include windows.h但我不知道如何找出因为这个文件正在发生
谢谢
为什么我会看到一些使用CStrings不同声明的代码.
有些人使用这种格式
char a_c_string [];
Run Code Online (Sandbox Code Playgroud)
而其他人使用
CString another_c_string;
Run Code Online (Sandbox Code Playgroud)
有区别吗?我发现的所有引用都CStrings像我在第一个例子中所做的那样声明它,我只看到它在论坛上以其他方式完成,人们在这里举例说明.
mfc ×10
c++ ×8
windows ×4
winapi ×2
coding-style ×1
exception ×1
exit ×1
linker ×1
mbcs ×1
message-pump ×1
quit ×1
setfocus ×1
string ×1
visual-c++ ×1