(1)第1章對程序錯誤的處理
[將書上的摘抄一些,便於自己理解]
1. 既然是寫程序,就不能避免錯誤,了解windows的錯誤處理是debug的必修課,也就是通過錯誤處理和返回我們能夠知道編寫的函數運行成還是失敗,按照書上所說,微軟編譯了一個所有可能的錯誤代碼的列表,並且為每個錯誤代碼分配了一個3 2位的號碼。
G e t L a s t E r r o r函數:
DWORD GetLastError(); //返回線程的3 2位錯誤代碼
當Wi n d o w s函數運行失敗時,應該立即調用G e t L a s t E r r o r函數。如果調用另一個Wi n d o w s函數,它的值很可能被改寫。
2. 32位錯誤代碼的域(從高位31到低位0)如下表示:
位 | 31~30 | 29 | 28 | 27~16 | 15~0 |
內容含義 | 嚴重性 0=成功 1=供參考 2=警告 3=錯誤 | 0=微軟定義的代碼 1=客戶定義的代碼 | 保留 必須是0 | 設備代碼 微軟定義 | 異常代碼 微軟定義 |
3.查看錯誤代碼含義的示例
書上的是c++的,MFC一貫讓我很迷糊,所以後續示例都用delphi重寫.
unit UnitErrorShow; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;type TFormErrorShow = class(TForm) Label1: TLabel; EditCode: TEdit; chkTop: TCheckBox; MemoShow: TMemo; btnLookup: TButton; procedure btnLookupClick(Sender: TObject); procedure chkTopClick(Sender: TObject); private { Private declarations } public {Public declarations } end; var FormErrorShow: TFormErrorShow; implementation {$R *.dfm} function MAKELANGID(_p, _s: Word): DWORD; begin Result := (_s shl 10) or (_p); end; procedure TFormErrorShow.btnLookupClick(Sender: TObject); var dwError: DWORD; hlocal: THandle; fOk: DWORD; hDll: HMODULE; begin MemoShow.Clear; hlocal := 0; try dwError := StrToInt(EditCode.Text); except ShowMessage(‘輸入有錯誤,請輸入數字!‘); EditCode.SetFocus; end; fOk := FormatMessage(// FORMAT_MESSAGE_FROM_SYSTEM or FORMAT_MESSAGE_ALLOCATE_BUFFER, // nil, // dwError, // MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // PChar(@hlocal), // 0, // nil); //ShowMessage(IntToStr(hlocal)); {判斷是否為網絡相關錯誤} if (fOk = 0) then begin hDll := LoadLibraryEx(‘netmsg.dll‘, 0, DONT_RESOLVE_DLL_REFERENCES); if (hDll <> 0) then begin FormatMessage(// FORMAT_MESSAGE_FROM_HMODULE or FORMAT_MESSAGE_FROM_SYSTEM, // @hDll, // dwError, // MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), // PChar(@hlocal), // 0, // nil); FreeLibrary(hDll); end; end; if hlocal <> 0 then begin MemoShow.Lines.Add(PChar(LocalLock(hlocal))); LocalFree(hlocal); end else begin MemoShow.Lines.Add(‘不可識別的錯誤代碼!‘); end; end; procedure TFormErrorShow.chkTopClick(Sender: TObject); begin if chkTop.Checked = True then Self.FormStyle := fsStayOnTop else Self.FormStyle := fsNormal; end; end.
[摘錄]如果F o r m a t M e s s a g e函數運行成功,那麽錯誤代碼的文本描述就位於內存塊中,將它拷貝到對話框底部的滾動窗口中。如果F o r m a t M e s s a g e函數運行失敗,設法查看N e t M s g . d l l模塊中的消息代碼,以了解該錯誤是否與網絡有關。使用N e t M s g . d l l 模塊的句柄,再次調用F o r m a t M e s s a g e函數。
這樣重寫以後,思路清晰了很多,但是有一個問題,我沒有在delphi中找到MAKELANGID函數(看來對delphi的函數還需要下大功夫),在VS中,它定義的是一個宏,因此只能自己寫一個函數.後邊還會有很多的需要轉換的東西,感覺VCL確實比MFC要好用,至少在一般的win32程序中,我會首選VCL,這樣也有一個好處,如果用的是VC,那麽我或許只是照抄了一邊,但現在,我需要面對可能出現的變量重定義問題,無形之中就把delphi中的東西也過了一邊,加深了印象.
(1)第1章對程序錯誤的處理