在Win32编程时不免会出现错误,最头痛的就是不知道错哪里,为什么会错,微软同样想到这个事情,为此,提供了一个不错的函数GetLastError(),此函数可以返回上一次出错的错误代码。
比如下面这段代码:
#include<windows.h>
LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
{
return DefWindowProc(hwnd,message,wParam,lParam);
}
BOOL InitApp(HINSTANCE hInstance,WNDCLASS *wndclass)
{
wndclass->cbClsExtra=0; //无附加窗口类内存
wndclass->cbWndExtra=0; //无附加窗口内存
wndclass->hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
wndclass->hCursor=LoadCursor(NULL,IDC_ARROW);
wndclass->hIcon=LoadIcon(NULL,IDI_APPLICATION);
wndclass->hInstance=hInstance;
wndclass->lpfnWndProc=WndProc;
wndclass->lpszClassName=TEXT("NewStart");
wndclass->lpszMenuName=NULL;
wndclass->style=WS_HSCROLL|CS_HREDRAW; //应该这里故意写错 但是编译能过
return RegisterClass(wndclass);
}
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd)
{
char buf[500];
BOOL fOK;
HWND hwnd;
DWORD dwErr,systemLocale;
HLOCAL hLocal=NULL;
MSG msg;
WNDCLASS wndclass;
int flag;
if(InitApp(hInstance,&wndclass)==NULL)
{
dwErr=GetLastError();
wsprintf(buf,L"%d",dwErr);
MessageBox(NULL,buf,TEXT("Error Report"),MB_OK);
return 0;
}
hwnd=CreateWindow(TEXT("NewStart"),TEXT("Hello!"),WS_SYSMENU|WS_VISIBLE,CW_USEDEFAULT,CW_USEDEFAULT,400,300,NULL,NULL,hInstance,NULL);
ShowWindow(hwnd,nShowCmd);
UpdateWindow(hwnd);
while((flag=GetMessage(&msg,hwnd,0,0))!=0&&flag!=-1)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
GetLastError()会返回一个错误号 87 然后你可以通过msdn查到这个错误编号的意思为 参数不正确 的确是这样的,并且如果你调试这段代码查看$err或者是dwErr都可以得到这个错误编号,如果你在这些变量后加上,hr可以得到87对应的错误解释
当你想让程序执行过程中显示错误解释,那就要用到另一个函数FormatMessage(),代码如下:
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd)
{
char buf[500];
BOOL fOK;
HWND hwnd;
DWORD dwErr,systemLocale;
HLOCAL hLocal=NULL;
MSG msg;
WNDCLASS wndclass;
int flag;
if(InitApp(hInstance,&wndclass)==NULL)
{
dwErr=GetLastError();
systemLocale=MAKELANGID(LANG_NEUTRAL,SUBLANG_NEUTRAL);
fOK=FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS|FORMAT_MESSAGE_ALLOCATE_BUFFER,
NULL,dwErr,systemLocale,(LPWSTR)&hLocal,0,NULL);
MessageBox(NULL,(LPCWSTR)LocalLock(hLocal),TEXT("hello"),MB_OK);
return 0;
}
hwnd=CreateWindow(TEXT("NewStart"),TEXT("Hello!"),WS_SYSMENU|WS_VISIBLE,CW_USEDEFAULT,CW_USEDEFAULT,400,300,NULL,NULL,hInstance,NULL);
ShowWindow(hwnd,nShowCmd);
UpdateWindow(hwnd);
while((flag=GetMessage(&msg,hwnd,0,0))!=0&&flag!=-1)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
这里要解释一些东西:
HLOCAL是一个指向内存块的句柄,初始化为0;
MAKELANGID在msdn上的解释是This macro creates a language identifier from a primary language identifier and a sub-language identifier.
就是可以通过这个函数创建语言标示符,而他有2个参数,第一语言标示符和子语言标示符,我们这里的LANG_NEUTRAL,SUBLANG_NEUTRAL联合放在一起的值等于0,也就是操作系统的默认语言。
FORMAT_MESSAGE_FROM_SYSTEM:这个宏是告诉FormatMessage,我们希望获得一个与一个系统定义的错误代码对应额字符串。
FORMAT_MESSAGE_IGNORE_INSERTS:这个宏允许我们获得含有%占位符的消息。
FORMAT_MESSAGE_ALLOCATE_BUFFER: 这个宏告诉该函数分配一足够容纳错误文本描述的内存。
FormatMessage将错误信息存在hLocal处。
FormatMessage这个函数其实功能很强大,其他具体的用法建议看msdn:http://msdn.microsoft.com/en-us/library/ms679351(VS.85).aspx
LocalLock() msdn上的解释为Locks a local memory object and returns a pointer to the first byte of the object's memory block。
也就是说这个函数可以用来锁定一个内存对象,并且返回这项这个对象内存块的首地址。