過年前,從china-pub買的。一直也沒有安下心來讀。看今年找工作的境況,也不得不抓把緊了。也愿與c++博客的各位朋友分享我的學習心得。
步入主題。
這一章開篇介紹了windows函數(shù)的幾種返回值:VOID,BOOL,HANDLE,PVOID,LONG/DWORD。讓我們明白,僅僅通過返回值,我們是不能清楚函數(shù)調(diào)用為什么會失敗的。
windows內(nèi)部,函數(shù)檢測到錯誤會采用什么機制呢?它是采用“線程本地存儲區(qū)”的機制來講相應的錯誤代碼與“主調(diào)線程”關聯(lián)到一起。它可以使不同的線程能獨立運行,不會出現(xiàn)相互干擾對方的錯誤代碼的情況。
函數(shù)返回的時候,其返回值會指出已發(fā)生的一個錯誤。
我們查看具體是什么錯誤,在相應的函數(shù)執(zhí)行完成后調(diào)用GetLastError()即可。
windows中,錯誤有三種表示:
一個消息ID(如ERROR_PATH_NOT_FOUND)
消息文本(如the system cannot find the path specified)
一個編號(盡量避免使用)
調(diào)試程序的時候,我們可以配置watch窗口,讓它始終顯示線程的上一個錯誤代碼和錯誤的文本描述。如$err,hr。hr是要顯示錯誤代碼的消息文本。不過我在windows mobile的環(huán)境下沒有成功,沒有弄清楚為什么。
那么我們怎么在自己的程序中顯示消息文本呢?文章介紹了利用FormatMessage函數(shù)。這里我也介紹一下這個函數(shù)的用法:
(下面的介紹摘自:http://m.shnenglu.com/bidepan2023/archive/2008/02/03/42433.html)
DWORD FormatMessage(
DWORD dwFlags,
LPCVOID lpSource,
DWORD dwMessageId,
DWORD dwLanguageId,
LPTSTR lpBuffer,
DWORD nSize,
va_list* Arguments
);
dwFlags:
# FORMAT_MESSAGE_ALLOCATE_BUFFER // 此函數(shù)會分配內(nèi)存以包含描述字串。
# FORMAT_MESSAGE_FROM_SYSTEM, // 在系統(tǒng)的id映射表中尋找描述字串
# FORMAT_MESSAGE_FROM_HMODULE // 在其他資源模塊中尋找描述字串
# FORMAT_MESSAGE_FROM_STRING // 消息ID是個字串,不是個DWORD
#FORMAT_MESSAGE_IGNORE_INSERTS // 允許我們獲得含有%占位符的消息,不傳遞這個標志,就必須在Arguments參數(shù)中提供這些占位符的信息
通常為:FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM
lpSource:
# 指定了FORMAT_MESSAGE_FROM_HMODULE的話,此參數(shù)表示模塊的HANDLE
# 指定了FORMAT_MESSAGE_FROM_STRING的話,此參數(shù)表示id字串
通常為:NULL
dwMessageId:
消息ID;如果指定FORMAT_MESSAGE_FROM_STRING,將被忽略。
dwLanguageId:
消息描述所用的語言
通常為:0表示自動選擇
lpBuffer:
#如果未指定FORMAT_MESSAGE_ALLOCATE_BUFFER,則為自己提供的緩沖區(qū)
#否則為系統(tǒng)LocalAlloc分配,需要被用戶LocalFree
nSize:
#如果未指定FORMAT_MESSAGE_ALLOCATE_BUFFER,則為自己提供的緩沖區(qū)大小
#否則為系統(tǒng)LocalAlloc分配之最小緩沖區(qū)大小
Arguments:
通常不使用
例子:
void ShowError()


{
DWORD dwError = GetLastError();

HLOCAL hlocal = NULL;

// Use the default system locale since we look for Windows messages.
// Note: this MAKELANGID combination has 0 as value
DWORD systemLocale = MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL);

BOOL 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 (fOk && (hlocal != NULL))

{
OutputDebugString((PCTSTR) LocalLock(hlocal));
LocalFree(hlocal);
}
}
這個是書中的例子的代碼,我只是將它歸結(jié)為了一個函數(shù)ErrorShow。這樣我們在一個函數(shù)的后面調(diào)用,直接可以知道錯誤的原因。不過環(huán)境我是在smart device 的DEBUG環(huán)境下調(diào)時的,OutputDebugString會輸出相應的字符串。
這個例子中同時展示了FormatMessage的兩種用法。觀察一下第二個參數(shù)就明白了。
visual studio 也提供了一個查詢錯誤的小工具,為Error Lookup。通過以上的示例,我們就知道其相應的工作原理呢。
這本書的源碼的下載地址:http://wintellect.com/Books.aspx
大家如果對windows 編程感興趣的話,不妨下來看看。
posted on 2009-02-20 00:24
Sandy 閱讀(2328)
評論(4) 編輯 收藏 引用 所屬分類:
windows學習