当前位置: 代码迷 >> 综合 >> GetLastError()和FormatMessage()
  详细解决方案

GetLastError()和FormatMessage()

热度:86   发布时间:2023-12-08 03:41:08.0
在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对应的错误解释

image

当你想让程序执行过程中显示错误解释,那就要用到另一个函数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。

也就是说这个函数可以用来锁定一个内存对象,并且返回这项这个对象内存块的首地址。