• (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重写.

    1

    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中的东西也过了一边,加深了印象.

  • 相关阅读:
    [AT2064] [agc005_f] Many Easy Problems
    [AT2304] [agc010_c] Cleaning
    [AT2172] [agc007_e] Shik and Travel
    [AT2148] [arc063_c] Integers on a Tree
    [AT2363] [agc012_c] Tautonym Puzzle
    未能从程序集“netstandard, Version=2.0.0.0......”中加载类型“...”。
    Android Studio设置国内镜像代理
    新建一个浏览器APP
    Android Studio在Make Project时下载Grandle特别慢
    用JS添加和删除class类名
  • 原文地址:https://www.cnblogs.com/iicc/p/7672724.html
Copyright © 2020-2023  润新知