Core summary of Windows core programming (First chapter error handling) (2018.5.26)

Source: Internet
Author: User

Frontier

Learning Windows core programming is the only way to step into the Windows Programming Hall, 2018 winter vacation relive the knowledge of computer operating system, the former has been learning Windows program design, the basis of the so-called iron to take hot, so I went into the Windows core programming pit, haha ~

Learning Goals

Each chapter of the study must be clear a goal, is you finish this chapter after you can do? OK, let's go through the first chapter of error handling step-by-step. The following are the learning objectives of this chapter:
1. Understanding the error mechanism of Windows functions
2. Understanding the use of GetLastError and SetLastError functions
3. Understanding FormatMessage function Usage and parameter description
4. Through the above learning, write out the error code into the error message code example.
5. Combined with the Errorshow sample program given by Windows core programming, analyze the 4th code of your own writing.

Error mechanisms for Windows functions

Windows core Programming the first chapter of this book is the simplest, although simple, but we can not be proud, because we want to conquer this book with an open-minded attitude to learn and summarize, and then apply.
We all know that when invoking a Windows function, it validates the arguments we pass to it, validates the pass and starts the task. If an invalid parameter is passed in, or if the operation cannot be performed for other reasons, the return value of the function indicates that the function failed for some reason. For example: The most classic function is the CreateFile function, if the open file fails, then the return value of the function will be Invalid_handle_value (-1).

HANDLE hFile=CreateFile(TEXT("c:\\fish"),0,0,NULL,OPEN_EXISTING,0,NULL);

The following shows the data type of the return value used by most Windows functions:

> VOID:这个函数不可能失败!> BOOL:FALSE失败;TRUE成功。> HANDLE:失败返回NULL,否则返回非零句柄。如果有特殊说明,则可能为特殊值例如:INVALID_HANDLE_VALUE。> PVOID:返回一个内存地址,失败为NULL> LONG/DWORD:应该根据SDK说明来确定函数状况。

It can be found that although the return value of the function tells us that the function failed to execute, it does not tell us why the function failed to call. So, Microsoft edited a list of all possible error codes and assigned a 32-bit number to each error code, in fact the error code is a DWORD (unsigned long) type value. Each error code then defines an error message, which is saved in the WinError.h header file. The header section of the WinError.h header file is truncated below:

#define ERROR_SUCCESS                    0L#define NO_ERROR 0L                                                 // dderror#define SEC_E_OK                         ((HRESULT)0x00000000L)//// MessageId: ERROR_INVALID_FUNCTION//// MessageText://// Incorrect function.//#define ERROR_INVALID_FUNCTION           1L    // dderror//// MessageId: ERROR_FILE_NOT_FOUND//// MessageText://// The system cannot find the file specified.//#define ERROR_FILE_NOT_FOUND             2L//// MessageId: ERROR_PATH_NOT_FOUND//// MessageText://// The system cannot find the path specified.//#define ERROR_PATH_NOT_FOUND             3L//// MessageId: ERROR_TOO_MANY_OPEN_FILES//// MessageText://// The system cannot open the file.//#define ERROR_TOO_MANY_OPEN_FILES        4L
GetLastError and SetLastError functions

Well, here we have a certain understanding of the error mechanism of Windows functions, then we will find a way to get the error code and set the error code.
The GetLastError function gets the last error code of the calling thread.
Function prototype: DWORD WINAPI GetLastError (void);
Return value: Returns the last error code for the thread. The error code is a 32-bit unsigned long integer (DWORD).
Note: After a Windows function fails, you should call GetLastError immediately, because it is possible that the next function call will affect the error code value.
The SetLastError function is used to set the most recent error code for the calling thread.
Function prototype: void WINAPI SetLastError ( in DWORD dwerrcode);
Parameter: The error code for the DWORD type.
Note: Use the GetLastError function to return the previous error code for the thread, and the SetLastError function to set the error code.

(1) I will give an example after using the above GetLastError and SetLastError functions. Now, introduce a watch window for Visual Studio, previously learning C and C + + I seldom use this feature, usually look at the local Variables window, and then debug the next procedure to see the changes in each variable. Now give an example of how Visual Studio's Watch window is used. The left name of the Watch 1 window in the picture is my own input, for example: count, hmodule, $err, HR.

(2) We can see that I put the breakpoint in the definition of the count, when I entered the debugging phase when 1000, in fact, the WinError.h header file does not have 1000 of this code value definition, then this formatmessage function call will be error. Then click Step over to proceed to the next statement.

(3) The count variable can be found to be initialized to 0 successfully. The display is undefined, as hmodule is not executed inside the conditional statement. At this point, I then click Step over to the next statement, this time the FormatMessage function has been completed, see the value of $err.hr into the error code plus error code description information. Can summarize $err is to show the function call failed error code, and HR is the error code description information, you can also write only $err, then it is not the error code information, only the error code.

(4) If we write a function to call other people, this function may be wrong, then we need to point out the error to the caller, then we can call the SetLastError function ourselves in the function, then our function returns false or null or other appropriate value. Note that the SetLastError parameter is a DWORD type value. The error code consists of several fields, which are mapped below:

FormatMessage function

Here is a summary of the parameters that I have for the FormatMessage function:

The FormatMessage function is the function of converting the GetLastError function to the string information (the error message is the number code).

Function Prototypes:

DWORD WINAPI FormatMessage (
inch DWORD DwFlags,
_inopt lpcvoid lpsource,
inch DWORD Dwmessageid,
inch DWORD Dwlanguageid,
out LPTSTR lpbuffer,
inch DWORD NSize,
_inopt va_list *arguments
);

Parameter 1: Flag bit
Format_message_allocate_buffer 0x00000100
If this flag bit is set, then the parameter lpbuffer (the initialized pointer variable) must be called as a parameter in the form of (LPTSTR) &lpbuffer, and when the function executes successfully, the function automatically allocates a block of memory that contains the string we want, Then the pointer points to the memory block, so we can reference the string.

Format_message_argument_array 0x00002000
This flag bit represents the parameter arguments just an array, not a parameter of this type va_list.

Format_message_from_hmodule 0x00000800
This flag indicates that this function receives a DLL module and finds the string from the DLL module.

Format_message_from_string 0x00000400
From a string, look for the message string.

Format_message_from_system 0x00001000
Gets the message string from the system, not the message string from a specified string or DLL.

Format_message_ignore_inserts 0x00000200
This indicates whether argument is useful, if this flag is set, then argument will be ignored by the function, if the flag bit is not set, then you must provide the values of these placeholders in the *argument parameter.

Parameter 2:lpsource:
Where do I get the message string? If the message string is obtained from the system, this parameter is null.
Parameter 3:dwmessageid:
Message index
Parameter 4:dwlanguageid:
The language type of the message.
Parameter 5:lpbuffer:
The memory block pointer that accepts the message.
Parameter 6:nsize:
The size of the memory block to accept the message, in bytes.
Parameter 7:*arguments:
The value of some variables in the message.
Return value: Returns the character count of the character message if the function call succeeds. Otherwise, 0 is returned.

Self-written code example (with note description)

This example uses the MFC Simple dialog box, which uses the FormatMessage function to translate the error code into error code information and paste the error code information into the static text control. Below is the OK button click event Processing, important or the implementation of this internal code, for MFC does not make too much to explain, in fact, I am only small white +1 of MFC, I mainly learn the development of QT interface.

void Cmfcapplication1dlg::onbnclickedok () {//TODO: In this Add control notification handler code TCHAR *str=null;//message string buffer This->updatedat    A (1);    /* FormatMessage function is set to the parameter, the function is to pass in the error code, the function will return the corresponding system or DLL file or string in the error code information string.    The return value of the function is a DWORD-type value that returns the number of characters in a string if the function call succeeds, or 0 if it fails.    So this defines a return value for the Count store FormatMessage function.    */DWORD count = 0; Count=formatmessage (Format_message_from_system | Format_message_ignore_inserts |    Format_message_allocate_buffer, NULL, m_value, NULL, (LPTSTR) &str, 0, NULL); The function call succeeds if (count) {THIS->SETDLGITEMTEXTW (Idc_static1, (LPCTSTR) LocalLock (str));//text in the static text control is set to the error code obtained by the letter    LocalFree (str);//If the FormatMessage function automatically allocates memory blocks through functions to store error code information, call the LocalFree function to release the memory.        }//Function call failed because the failure of the above call could be because the input error code is not in the system definition, then look for the network error code information, here Load network error code information DLL file else {//Load network error code DLL file, name to remember        hmodule hmodule = LoadLibrary (TEXT ("Netmsg.dll")); The load succeeds if (hmodule) {//calls the FormatMessage function again, but the flag of parameter 1 is different, the first flag becomes a format_mesSage_from_hmodule count = FormatMessage (Format_message_from_hmodule | Format_message_ignore_inserts |            Format_message_allocate_buffer, hmodule, m_value, NULL, (LPTSTR) &str, 0, NULL); The function call succeeds if (count) {//In the text of the static text control is set to the obtained error code information This->setdlgitemtex                TW (Idc_static1, (LPCTSTR) LocalLock (str)); LocalFree (str);//release function automatically allocated memory block} freelibrary (hmodule);//release memory block of dynamic link library file}}//If the above two different source paths    Path can not get the information corresponding to the error code, then output a line of error text if (count = = 0) {THIS->SETDLGITEMTEXTW (Idc_static1, (LPCTSTR) L "No error code information found"); }}
Errorshow Sample Program
DWORD dwerror = Getdlgitemint (hwnd, Idc_errorcode, NULL, FALSE);//Gets the value of the input box, that is, the error code value hlocal hlocal = NULL; Buffer that gets the error message string//hlocal=handle=void *, these three are the same//use the default system locale Si      nCE We look for Windows messages. Note:this Makelangid combination has 0 as value DWORD SystemLocale = Makelangid (lang_neutral, sublang_neutral);// Language//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 the function call fails, take another approach, that is, the dynamic link library file 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.")); }
Summarize

After the above study, the first chapter of Windows core programming is finished, and so on. The difference between our analysis of our own examples and the Errorshow sample program is not very large, but the logic of the FormatMessage sample program is more rigorous. Also, if there are children's shoes are learning Windows core programming, we can exchange learning, I am not but studious research, but also need to constantly learn to improve themselves. Can contact me through QQ, we continue to progress together!
qq:764238383

Core summary of Windows core programming (First chapter error handling) (2018.5.26)

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.