最近正在学习windows核心编程,书中的事例代码原先一直无法在vc6.0运行,经过几天的调试终于可以编译过了。
无法编译的原因主要有以下几点:
1、vc6.0自带的SDK版本太低。
2、vc6.0环境目录中未包括sal.h库文件的目录
3、未安装vs6sp5
告诉大家一个超省事超简单的办法:就是直接用vs2010等版本直接打开下边的事例程序,即可编译。因为编译器中已配置好了SDK库,vc6.0需要配置SDK是因为它包含的SDK版本太低的原因。
好了,接下来,直接看windows核心编程中的第一个事例程序。
01-ErrorShow
程序界面
程序的启动点
int WINAPI _tWinMain(HINSTANCE hinstExe, HINSTANCE, PTSTR pszCmdLine, int) {
HWND hwnd = FindWindow(TEXT("#32770"), TEXT("Error Show"));//查找是否已有实例运行
if (IsWindow(hwnd))
{
// An instance is already running, activate it and send it the new #
SendMessage(hwnd, ESM_POKECODEANDLOOKUP, _ttoi(pszCmdLine), 0);
}
else
{
DialogBoxParam(hinstExe, MAKEINTRESOURCE(IDD_ERRORSHOW), //创建对话框
NULL, Dlg_Proc, _ttoi(pszCmdLine));
}
return(0);
}
Dlg回调函数Dlg_Proc如下:
INT_PTR WINAPI Dlg_Proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
switch (uMsg)
{
chHANDLE_DLGMSG(hwnd, WM_INITDIALOG, Dlg_OnInitDialog);//在此截获WM_INITDIALOG消息,进入Dlg初始化函数Dlg_OnInitDialog
chHANDLE_DLGMSG(hwnd, WM_COMMAND, Dlg_OnCommand);//在此截获WM_COMMAND消息,在Dlg_OnCommand函数中统一处理
case ESM_POKECODEANDLOOKUP://激活程序,并显示wParam错误码对应的英文解释。
SetDlgItemInt(hwnd, IDC_ERRORCODE, (UINT) wParam, FALSE);//设置编辑框的内容为wParam
FORWARD_WM_COMMAND(hwnd, IDOK, GetDlgItem(hwnd, IDOK), BN_CLICKED, //发送消息,相当于用户点击了IDOK按钮
PostMessage);
SetForegroundWindow(hwnd);//将创建指定窗口的线程设置到前台,并且激活该窗口
break;
}
return(FALSE);
}
Dlg初始化函数Dlg_OnInitDialog如下:
BOOL Dlg_OnInitDialog(HWND hwnd, HWND hwndFocus, LPARAM lParam) {
chSETDLGICONS(hwnd, IDI_ERRORSHOW);//加载现实图标
// Don't accept error codes more than 5 digits long
Edit_LimitText(GetDlgItem(hwnd, IDC_ERRORCODE), 5);//设置错误码不超过5位数
// Look up the command-line passed error number
SendMessage(hwnd, ESM_POKECODEANDLOOKUP, lParam, 0);//激活窗口
return(TRUE);
}
WM_COMMAND消息处理函数如下:
void Dlg_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify) {
switch (id)
{
case IDCANCEL:
EndDialog(hwnd, id);
break;
case IDC_ALWAYSONTOP:
SetWindowPos(hwnd, IsDlgButtonChecked(hwnd, IDC_ALWAYSONTOP)
? HWND_TOPMOST : HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
break;
case IDC_ERRORCODE:
EnableWindow(GetDlgItem(hwnd, IDOK), Edit_GetTextLength(hwndCtl) > 0);
break;
case IDOK:
// Get the error code
DWORD dwError = GetDlgItemInt(hwnd, IDC_ERRORCODE, NULL, FALSE);
HLOCAL hlocal = NULL; // Buffer that gets the error message string
// Get the error code's textual description
BOOL fOk = FormatMessage(//读取错误代码
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER,
NULL, dwError, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
(PTSTR) &hlocal, 0, NULL);
if (!fOk) {
// Is it a network-related error?
HMODULE hDll = LoadLibraryEx(TEXT("netmsg.dll"), NULL,
DONT_RESOLVE_DLL_REFERENCES);
if (hDll != NULL) {
FormatMessage(
FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_FROM_SYSTEM,//通过错误码格式化输出错误文本
hDll, dwError, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
(PTSTR) &hlocal, 0, NULL);
FreeLibrary(hDll);
}
}
if (hlocal != NULL) {
SetDlgItemText(hwnd, IDC_ERRORTEXT, (PCTSTR) LocalLock(hlocal));
LocalFree(hlocal);
} else {
SetDlgItemText(hwnd, IDC_ERRORTEXT, TEXT("Error number not found."));
}
break;
}
}
程序很简单,但是对于只会MFC的程序员们是个学习windows编程消息机制的好例子。
接下来,我将用一个mfc程序来实现以上功能,完全借用以上代码,使用mfc来实现是想告诉大家,学windows核心编程绝对不是为了用api做界面,不然,就windows编程就将因你而倒退n年。记住学习windows核心编程的意义在于学习底层编程。
1、新建一个基于对话框的mfc程序,在工程中添加以上的现实界面,并包含以下头文件
#include <Windowsx.h>
#include <tchar.h>
2、添加Look up按钮的响应函数,并在响应函数中添加如下代码:
void CErrorShowDlg::OnLookupBtn()
{
// TODO: Add extra validation here
CString strText(_T(""));
GetDlgItem(IDC_ERRORCODE)->GetWindowText(strText);
DWORD dwError = _ttol(strText);
HLOCAL hlocal = NULL; // Buffer that gets the error message string
// Get the error code's textual description
BOOL fOk = FormatMessage(
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER,
NULL, dwError, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
(PTSTR) &hlocal, 0, NULL);
if (!fOk)
{
// Is it a network-related error?
HMODULE hDll = LoadLibraryEx(TEXT("netmsg.dll"), NULL,
DONT_RESOLVE_DLL_REFERENCES);
if (hDll != NULL) {
FormatMessage(
FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_FROM_SYSTEM,
hDll, dwError, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
(PTSTR) &hlocal, 0, NULL);
FreeLibrary(hDll);
}
}
if (hlocal != NULL)
{
GetDlgItem(IDC_ERRORTEXT)->SetWindowText((PCTSTR) LocalLock(hlocal));
LocalFree(hlocal);
}
else
{
GetDlgItem(IDC_ERRORTEXT)->SetWindowText(TEXT("Error number not found."));
}
}
呵呵,我们的工作做完了,是不是更简单了?mfc框架可不是白搭的,如果不能快速开发界面程序,那它也就没有存在的意义了。
windows核心编程源码:
http://download.csdn.net/detail/fksec/4209539
windows核心编程Error Show程序mfc版本(vc6.0需要配置SDK环境,vs2010可直接打开编译,vs2010以下版本未知)
http://download.csdn.net/detail/windows_nt/5393173