《windows核心编程》笔记(一)

1,windows对程序错误的处理,

int APIENTRY _tWinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPTSTR    lpCmdLine,int       nCmdShow)
{
    LPVOID lpMsgBuf;
    HANDLE hFile 
= ::CreateFile(_T("C:\\12.txt"),0,0,NULL,OPEN_EXISTING,0,NULL);//打开文件
    if(INVALID_HANDLE_VALUE==hFile)
    
{//文件不存在
        FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, GetLastError(),0, (LPTSTR) &lpMsgBuf,0,NULL);
        MessageBox( NULL, (LPCWSTR)lpMsgBuf, _T(
"错误信息"), MB_OK | MB_ICONINFORMATION );
        LocalFree( lpMsgBuf );
    }

        
return 0;
}

调试时,在Watch窗口输入“@err,hr”,就可以显示线程的最后错误代码的号码和该错误的描述信息。
2008060701.jpg

VC6.0还带了一个实用小程序,可以用来将错误代码转换为相应的文本描述信息。
2008060702.jpg

书中给出了一个模仿VC6自带的那个Error Lookup实用程序的示例:

#define ESM_POKECODEANDLOOKUP    (WM_USER + 100)  //用户自定义消息
const TCHAR g_szAppName[] = TEXT("Error Show");

BOOL Dlg_OnInitDialog(HWND hwnd, HWND hwndFocus, LPARAM lParam) 
{

   chSETDLGICONS(hwnd, IDI_ERRORSHOW);
//设置图标

   
// Don't accept error codes more than 5 digits long
   Edit_LimitText(GetDlgItem(hwnd, IDC_ERRORCODE), 5);//限制输入字符长度最大为

   
// Look up the command-line passed error number
   SendMessage(hwnd, ESM_POKECODEANDLOOKUP, lParam, 0);//发送初始错误代码消息
   return(TRUE);
}


void Dlg_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify) {

   
switch (id) 
   
{

   
case IDCANCEL:
      EndDialog(hwnd, id);
//关闭对话框窗口
      break;

   
case IDC_ALWAYSONTOP://始终在最前
      SetWindowPos(hwnd, IsDlgButtonChecked(hwnd, IDC_ALWAYSONTOP) ? HWND_TOPMOST : HWND_NOTOPMOST, 0000, SWP_NOMOVE | SWP_NOSIZE);
      
break;

   
case IDC_ERRORCODE: 
      EnableWindow(GetDlgItem(hwnd, IDOK), Edit_GetTextLength(hwndCtl) 
> 0);//设置“lookup"按钮是否enable
      break;

   
case IDOK:
      
// Get the error code
      DWORD dwError = GetDlgItemInt(hwnd, IDC_ERRORCODE, NULL, FALSE);//获取错误代码号码

      HLOCAL hlocal 
= NULL;   // Buffer that gets the error message string

      
// 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);//本地语言

      
// Get the error code's textual description
      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))
      
{
         SetDlgItemText(hwnd, IDC_ERRORTEXT, (PCTSTR) LocalLock(hlocal)); 
         LocalFree(hlocal);
      }
 
      
else 
      
{
         SetDlgItemText(hwnd, IDC_ERRORTEXT, TEXT(
"No text found for this error number."));
      }

      
break;
   }

}


INT_PTR WINAPI Dlg_Proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) 
{

   
switch (uMsg) 
   
{
      chHANDLE_DLGMSG(hwnd, WM_INITDIALOG, Dlg_OnInitDialog);
//初始化处理
      chHANDLE_DLGMSG(hwnd, WM_COMMAND,    Dlg_OnCommand);//命令处理

   
case ESM_POKECODEANDLOOKUP:
      SetDlgItemInt(hwnd, IDC_ERRORCODE, (UINT) wParam, FALSE);
//控件上设置错误代码
      FORWARD_WM_COMMAND(hwnd, IDOK, GetDlgItem(hwnd, IDOK), BN_CLICKED, PostMessage);//模拟按钮点击事件
      SetForegroundWindow(hwnd);//设置为最前的窗口
      break;
   }


   
return(FALSE);
}


int WINAPI _tWinMain(HINSTANCE hinstExe, HINSTANCE, PTSTR pszCmdLine, int
{

   HWND hwnd 
= FindWindow(TEXT("#32770"), TEXT("Error Show"));//寻址窗口
   if (IsWindow(hwnd)) 
   
{//已经存在
      
// An instance is already running, activate it and send it the new #
      SendMessage(hwnd, ESM_POKECODEANDLOOKUP, _ttoi(pszCmdLine), 0);
   }

   
else
   
{//新窗口
      DialogBoxParam(hinstExe, MAKEINTRESOURCE(IDD_ERRORSHOW),NULL, Dlg_Proc, _ttoi(pszCmdLine));
   }

   
return(0);
}

 

这里用到了几个宏定义,下面这个是用来指定消息处理函数的

// The normal HANDLE_MSG macro in WindowsX.h does not work properly for dialog
// boxes because DlgProc returns a BOOL instead of an LRESULT (like
// WndProcs). This chHANDLE_DLGMSG macro corrects the problem:
#define chHANDLE_DLGMSG(hWnd, message, fn)                 \
   
case (message): return (SetDlgMsgResult(hWnd, uMsg,     \
      HANDLE_##message((hWnd), (wParam), (lParam), (fn))))

下面这个是用来为窗口设置大/小图标

// Sets the dialog box icons
inline void chSETDLGICONS(HWND hWnd, int idi) 
{
   SendMessage(hWnd, WM_SETICON, ICON_BIG,  (LPARAM) 
      LoadIcon((HINSTANCE) GetWindowLongPtr(hWnd, GWLP_HINSTANCE), 
         MAKEINTRESOURCE(idi)));
   SendMessage(hWnd, WM_SETICON, ICON_SMALL, (LPARAM) 
      LoadIcon((HINSTANCE) GetWindowLongPtr(hWnd, GWLP_HINSTANCE), 
      MAKEINTRESOURCE(idi)));
}

posted on 2008-06-07 12:53  Phinecos(洞庭散人)  阅读(2074)  评论(1编辑  收藏  举报

导航