VC++开发应用程序常见问题解惑 在微软的开发工具中，VC仍然是目前最为流行的开发工具，有大量的开发人员利用VC进行项目开发。在开发VC应用程序时，我们会遇到一些常见问题，笔者经过总结，给出了通用的解决方法，希望能对大家有所帮助。 VC中有没有类拟DoEvents的函数？ 你可以使用这样的函数： BOOL CheckMessageQueue()
{　　　　MSG msg;
while(PeekMessage(&&msg, NULL, 0, 0, PM_REMOVE)){
if(msg.message==WM_QUIT)
return FALSE;
TranslateMessage(&&msg);
DispatchMessage(&&msg);
}
return TRUE;
}
调用PeekMessage取消息时，其它程序将有机会获得控制权，可以实现DoEvents的效果。但要注意这个函数返回值的含义，如果该函数返回FALSE，说明用户按下了关闭按钮。
在不拷贝文件的情况下，如何在C/C++中去掉文件尾部，也就是快速剪短文件？
在C/C++中，一般都有一个函数chsize或_chsize可以改变文件的大小。下面是一段例子：
int fh, result;
unsigned int nbytes = BUFSIZ;
//打开文件
if((fh=_open("c:\\testdata", _O_RDWR|_O_CREAT, _S_IREAD
| _S_IWRITE )) != -1)
{ printf("修改前文件长度: %ld\n", _filelength(fh));
if((result = _chsize(fh, 329678))==0)
printf("成功地修改了文件长度\n");
else
printf("改变文件长度出错\n");
printf("修改后文件长度: %ld\n", _filelength(fh));
_close( fh );}}
使用VC++ 5.0，如何在程序中设置按下Caps Lock 键，使得使用者在某Edit框里输入的字母自动为大写，输入后设置该键再按下，即恢复输入小写字母状态。
利用Windows API函数keybd_event可以模拟按下Caps Lock 键。下面的代码能够切换Caps Lock 键。
void SetCapsLock( BOOL bState )
{
BYTE keyState[256];
GetKeyboardState((LPBYTE)&&keyState);
if((bState &&&& !(keyState[VK_CAPITAL] && 1)) ||
(!bState &&&& (keyState[VK_CAPITAL] && 1)) )
{
// 模拟按下一个键
keybd_event( VK_CAPITAL,
0x45,
KEYEVENTF_EXTENDEDKEY | 0,
0 );
// 模拟放开一个键
keybd_event( VK_CAPITAL,
0x45,
KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP,
0);
}
}
// 当用户切换到Edit1控件，设置为大写状态
void CDlgDlg::OnSetfocusEdit1()
{SetCapsLock(TRUE);}
// 当用户离开Edit1控件，设置为小写状态
void CDlgDlg::OnKillfocusEdit1()
{ SetCapsLock(FALSE);}
不过，在这里建议采用另一种方法，即重载PreTranslateMessage函数，用户每输入一个字母就将其自动转换为大写，而不是修改Caps Lock 键，如：
BOOL CDlgDlg::PreTranslateMessage(MSG* pMsg)
{ if(pMsg-)message == WM_CHAR
&&&& pMsg-}hwnd == ::GetDlgItem(m_hWnd, IDC_EDIT1)}
{ pMsg-}wParam = toupper(pMsg-)wParam};}
return CDialog::PreTranslateMessage(pMsg);
}
在VC中有无方法可以像VFP一样加减日期，从而得出它们之间的时间差值？
可以使用CTime类来表示日期，如：
CTime t1( 1999, 3, 19, 22, 15, 0 ); // 1999年3月19日22:15
CTime t2( 1999, 3, 20, 22, 15, 0 ); // 1999年3月20日22:15
CTimeSpan ts = t2 - t1;
//对两个日期变量相减，差值保存在CTimeSpan变量中
ASSERT( ts.GetTotalSeconds() == 86400L );
应用程序中往往需要启动其他的程序运行，如何实现加载，有几种方法，哪一种比较好？
有三个SDK函数WinExec，ShellExecute，CreateProcess都可以实现加载。
其中WinExec最简单，两个参数，前一个指定路径，后一个指定显示方式，如果显示方式为SW_SHOWMAXMIZED，此时若加载一个无最大化按钮的程序，如计算器等等，就不会出现正常的窗体，但在任务列表里会出现。
ShellExecute比WinExex灵活，可以指定工作目录。
CreateProcess最复杂，一共有十个参数，不过大部分都可以用NULL代替，它可以指定进程的安全属性、继承信息、类的优先级等等。
总之，灵活性与简单性成反比，你可以依具体情况决定使用哪一个函数。
在CParentView中为WM_LBUTTONDOWN定义了一个句柄，但我建立一个新的CChildView时，句柄却得不到处理，为什么？
很可能在ChildView文件中的MESSAGE_MAP有问题，特别是用向导生成器就很容易会发生这种事情，如匹配 BEGIN_MESSAGE_MAP(Child,Parent)的参数中存在错误的基类。
另外还可以检查一下消息映象宏中的类名和父类名是否正确，如果你用自己的消息句柄手工代替了向导所做的，就必须保证没有写错，一个错误的参数或者加了一个“const”将会改变消息映象，从而造成不被正确调用。
在开发应用程序时，确定应用程序的路径非常重要，请问如何自动确定应用程序的路径呢？
可以用GetModuleFileName来获得应用程序的路径，不过这个函数将连同执行文件名一起返回，当然你只要利用串操作把最后的执行文件名去掉就可以了。
其实，在程序开发中，还可能用到以下一组目录，下面列出相应的调用函数，希望对你有所帮助。
Windows目录：
GetWindowsDirectory
Windows下的system目录：
GetSystemDirectory
temp目录：
GetTempPath
当前目录：
GetCurrentDirectory
系统参数往往决定了一些操作属性，那么如何在程序中实现系统参数的存取呢？
这里有一个很关键的SDK函数SystemParame-tersInfo。
调用该函数可以查询和设置系统参数，诸如按键的重复速率设置、鼠标双击延迟时间、图标字体以及桌面墙纸等等，特别是其中第一个参数决定了对哪一类系统参数的控制，如SPIF_GETICONTITLELOGFONT（图标标题字体）、SPI_SETDE-SKWALLPAPER（桌面墙纸）等等。
不过要说明的是，如果需确定当前屏幕分辨率，我们可以直接调用SDK函数GetSystemMetrics，该函数可以检索有关Windows显示信息，诸如标题大小、边界大小以及滚动条大小等等。
在VC编程开发时，如何控制应用程序提前结束？
在编程中这是一个经常要遇到的问题，基本思想是向窗口（窗口句柄可以用AfxGetMainWindow函数获得）发送 WM_CLOSE消息，调用 CWnd::OnClose成员函数，最好向用户提示是否保存修改过的数据。当然还可以用FindWindow函数来找窗口，但这不是一种好方法，因为它需要窗口标题栏内容作为参数，而无法处理标题栏自动改变，这样在事先不知道标题栏的情况下FindWindow就无能为力了。
另外如果希望应用程序不停地工作，要避免用户突然关掉系统，就需要主框架窗口类中使用消息WM_QUERYENDSE-SSION了，你需要完成相应的消息响应函数。
MFC可以发现内存漏洞，这个特性如何使用呢？
要发现内存漏洞，就必须利用Debug菜单中的Go选项，而不是Project菜单中的Execute选项，来运行应用程序，这样MFC会在程序终止时报告内存漏洞。如果没有，那么试试运行MFCTracer工具程序(在VC++程序组中)，并启动跟踪，然后返回应用程序。原先的Task Manager应用程序显示顶层窗口的列表。为了显示该列表，窗口必须可见、包含一个标题以及不能被其他窗口拥有。调用CWnd:: GetWindow可以检索顶层窗口的列表，调用IsWindow Visible、GetOwner以及GetWindowTextLength可以确定窗口是否应该在列表中。
（林琪 李海)