这几天开始阅读《window核心编程》,读完第一章,作者实现一个查询Windows错误码的查询。程序思路很简单,网上下载源代码看看~~~~!!
打开上个世纪写的代码,FUCK!简直是天书!!虽然,我没有把《Windows程序设计》这本书看完,但是,我自以为看看这种win32小程序的代码,百度一下函数功能,还是看得懂的!!现实还是很残酷呀!!
先说一说作者的源代码,作者为书中所有的小程序引用了“CmnHdr.h”和“WindowX.h”,前者是作者自己定义的头文件,主要是关于编译器和连接器的配置,后者是Windows自带的一个头文件,包含大量宏定义,主要的作用是简化代码(包括消息处理宏,子控件宏,API宏)。由于这些宏太tm长了,所以接下来我的代码没有使用这些宏,而是一个正常的思路实现这个小工具!同时,我会总结一下程序中用到的各种函数,已备以后查阅!
PS:为了实现这个程序,我看了《程序设计》第九章,到第11章,整整100多页!!好吧,我是菜鸡!
这是这是程序的界面:
整个程序基于对话框实现,包括两个静态控件,一个编辑控件,一个按钮和一个复选按钮;
主要的功能肯定就是获取错误码的描述;
其他小的设定还有:程序只能运行一个实例以及让程序置顶
关于程序只能运行一个实例:网上有很多方法,我们利用最简单的:利用函数FindWindow根据程序名查找窗体,如果成功说名已经有程序实例运行了,我们发送一个消息,让对话框过程把焦点设定到这个正在运行的例程!
int WINAPI WinMain(HINSTANCE hIns,HINSTANCE hPrevInstance,PSTR szCmdLine,int iCmdShow)
{
//保证应用程序只有一个活动的例程
HWND hwnd=FindWindow(NULL,TEXT("ERR Show"));
if(IsWindow(hwnd))
{
SendMessage(hwnd,ESM_POKECODEANDLOOKUP,NULL,0);
}else
{
DialogBoxParam(hIns,MAKEINTRESOURCE(IDD_ERR),NULL,DlgProc,NULL);
}
return(0);
}
ESM_POKECODEANDLOOKUP
是自定义的一个消息,他接受到这个消息的对话框把自己设定为焦点
case ESM_POKECODEANDLOOKUP:
SetForegroundWindow(hDlg);//将对话框设定到前台并且使他获得焦点
break;
关于函数
DialogBoxParam(hIns,MAKEINTRESOURCE(IDD_ERR),NULL,DlgProc,NULL);
他创建的是一个非模态的对话框,这里对话框资源号是IDD_ERR,这个对话框没有父窗口,对话框过程为DlgProc。
对话框过程和窗口过程有很大不同,具体来说有三点:
1.窗口过程返回值是LRESULT,一般在程序中我们返回0或者返回消息给程序处理(return DefWindowProc(.....));对话框返回TRUE和FALSE(表示这个消息对话框是否处理了);
2.对话框没有过WM_PAINT和WM_DESTORY以及WM_CREATE消息;
3.对话框用WM_INITDIALOG消息取代WM_CREATE;
由于这个对话框和窗口类不太一样,好像消息循环我们看不到,我们不能通过发送WM_CLOSED结束对话框。我们使用函数
case IDCANCEL:
<span style="white-space:pre"> </span>EndDialog(hDlg,0);//关闭对话框窗口
<span style="white-space:pre"> </span>return TRUE;
对话框上头的小按钮能产生IDCANCEL消息
通过上面这些函数,基本上我们就有一个简单的框架了,剩下的我们只需添加对话框的子控件的消息响应,就能实现其他功能了!
让对话框始终置顶,实现这个功能只需要一个函数,
case IDC_CHECK1:
SetWindowPos(hDlg, IsDlgButtonChecked(hDlg, IDC_CHECK1)
? HWND_TOPMOST : HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
return TRUE;
我们结束复选按钮的消息利用SetWindowPos函数让对话框的Z位置顶:
HWND_TOP:将窗口置于Z序的顶部。
HWND_TOPMOST:将窗口置于所有非顶层窗口之上。即使窗口未被激活窗口也将保持顶级位置。
程序的主要功能获取错误码的描述,通过函数FormatMessage实现!
case WM_COMMAND:
switch(LOWORD(wParam))
{
case IDC_BUTTON1:
dwError=GetDlgItemInt(hDlg,IDC_EDIT1,NULL,FALSE);//把对话框中指定控制的文本转换为一个整形值
fOk = FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM|//从系统获取错误码信息
FORMAT_MESSAGE_IGNORE_INSERTS|//或的%占位符信息
FORMAT_MESSAGE_ALLOCATE_BUFFER,//为信息分配一块内存
NULL,dwError,systemLocale,(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) {
fOk = FormatMessage(
FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_IGNORE_INSERTS |
FORMAT_MESSAGE_ALLOCATE_BUFFER,
hDll, dwError, systemLocale,
(PTSTR) &hlocal, 0, NULL);
FreeLibrary(hDll);
}
}
if(hlocal!=NULL)
{
SetDlgItemText(hDlg,IDC_ERRD,(PCTSTR)LocalLock(hlocal));
LocalFree(hlocal);
}else
{
SetDlgItemText(hDlg,IDC_ERRD,TEXT("未发现这个错误码的描述信息"));
}
return TRUE;