An error occurred while obtaining windowsapi

Source: Internet
Author: User
Tags format message

Getlasterror or other errors returned by the API

Formatmessage is used to format the error information for display.

DWORD winapi formatmessage (

_ In DWORD dwflags,

_ In lpcvoid lpsource,

_ In DWORD dwmessageid,

_ In DWORD dwlanguageid,

_ Out lptstr lpbuffer,

_ In DWORD nsize,

_ In va_list * arguments

);

When using this function, make it clear: Where is the message resource you want to process, and what is your message id.

Dwflags: the formatting option that provides guidance for the lpsource parameter value. The low-level value specifies how the function processes the row conversion in the output buffer, or you can specify the maximum width of the output string. Its bit identifier is as follows:
Format_message_allocate_buffer
The lpbuffer parameter is a pvoid pointer. The nsize parameter specifies the minimum value allocated to the output message buffer. Note: When you do not use this buffer (lpbuffer), use localfree to release it.
 
Format_message_argument_array
The arguments parameter is not a va_list structure, but it represents an array pointer. This identifier cannot be used for 64-bit integer values. If you want to use 64-bit integer values, you must use the va_list struct.
 
Format_message_from_hmodule
The lpsource parameter is a handle that contains the message-Table Resources Module (DLL. If the lpsource handle is null, the system automatically searches for the message resource of the current process file.
This identifier cannot be shared with format_message_from_string.
If no resource table exists in the module, the function fails to be executed and the error error_resource_type_not_found value is returned.
 
Format_message_from_string
The lpsource parameter points to a string that contains the message definition. this message definition may contain insert sequence, just as the message table resource contains the message text. and this identifier is not used with format_message_from_hmodule or format_message_from_system.

Format_message_from_system
The function will search for the system message-Table resources. If this identifier defines format_message_from_hmodule at the same time, if the function does not find the required message in the module, it will be searched in the system. This identifier cannot be used with format_message_from_string.
When this identifier is set, you can use the getlasterror function return value to search for the message text of this error code in the system-defined error.
 
Format_message_ignore_inserts
The insertion sequence in the message definition will be ignored. This identifier is very useful in obtaining a formatted message. If this identifier is set, the arguments parameter will be ignored.
 
As described above, the dwflags parameter sets the low value. You can use the following values to set the low value:
0: there will be no limit on the width of the output row.
Format_message_max_width_mask: limits the width of the output line and uses hard encoding.

Lpsource:
This value is where message-Table resources comes from and depends on dwflags. For details, see format_message_from_hmodule and format_message_from_string. If these two identifiers are not set, lpsource will be ignored.

Dwmessageid: The identifier of the message to be formatted. When format_message_from_string is set for dwflags, this parameter is ignored.
Dwageid: format the message language identifier.
Lpbuffer:
A buffer pointer to accept formatted messages. When dwflags includes the format_message_allocate_buffer identifier, this function will use the localalloc function to allocate a buffer. lpbuffer needs to accept an address to use this buffer. (Here, you must specify the address for passing parameters ).
Nsize:
If format_message_allocate_buffer is not set, this parameter specifies the messages in the output buffer, in tchars. If format_message_allocate_buffer is set, this parameter sets the minimum value of the output buffer in units of tchars. The output buffer cannot exceed 64 KB.
Arguments:
The value in an array is used as the insert value in the formatted message. For details, see msdn

Example 1:
 
Using System Message Resources to report errors is also the most useful part of this function.
 
[CPP] view plaincopyprint?
# Include <windows. h>
# Include <strsafe. h>

Void errorexit (lptstr lpszfunction)
{
// Retrieve the system error message for the last-error code

Lpvoid lpmsgbuf;
Lpvoid lpdisplaybuf;
Dword dw = getlasterror ();

Formatmessage (
Format_message_allocate_buffer |
Format_message_from_system |
Format_message_ignore_inserts,
Null,
DW,
Makelangid (lang_neutral, sublang_default ),
(Lptstr) & lpmsgbuf,
0, null );

// Display the error message and exit the process

Lpdisplaybuf = (lpvoid) localalloc (lmem_zeroinit,
(Lstrlen (lpctstr) lpmsgbuf) + lstrlen (lpctstr) lpszfunction) + 40) * sizeof (tchar ));
Stringcchprintf (lptstr) lpdisplaybuf,
Localsize (lpdisplaybuf ),
Text ("% s failed with error % d: % s "),
Lpszfunction, DW, lpmsgbuf );
MessageBox (null, (lpctstr) lpdisplaybuf, text ("error"), mb_ OK );

Localfree (lpmsgbuf );
Localfree (lpdisplaybuf );
Exitprocess (DW );
}

Void main ()
{
// Generate an error

If (! Getprocessid (null ))
Errorexit (text ("getprocessid "));
}
 
 
We can see the function option dwflags
The output buffer is allocated by the function for format_message_allocate_buffer, respectively,
Format_message_from_system indicates that the program will search for the required message in the system message table resource,
The format_message_ignore_inserts program will ignore the insertion sequence in the searched message.
 
The lpsource value is null, and no Module Value and string are directly input. Therefore, it is null. For details, refer to the above Parameter Parsing.
 
Dwmessageid is DW, that is, the return value of getlasterror. Is the ID of the message resource.
 
Dwageid is set to local default
 
Note the following in the lpbuffer output buffer & why? Because lpvoid lpmsgbuf is only a pointer object, you must pass its address to the lpbuffer parameter.

Note: because the value of the lpbuffer parameter is the buffer dynamically allocated by the formatmessage function, localfree is required when it is not used.
 
 
Example 2:
 
Message Resources in the formatting module. The loaded module requires message resources. If format_message_from_system is passed in the formatmessage function, if the message module does not have the required resources, the function will be searched in the system. If no format_message_from_system exists and the message module does not have the required resources, the function call fails.
# Include <windows. h>
# Include <stdio. h>

# Include <lmerr. h>

Void
Displayerrortext (
DWORD dwlasterror
);

# Define rtn_ OK 0
# Define rtn_usage 1
# Define rtn_error 13

Int _ cdecl main (INT argc, char * argv [])
{
If (argc! = 2 ){
Fprintf (stderr, "Usage: % S <error number> \ n", argv [0]);
Return rtn_usage;
}
Displayerrortext (atoi (argv [1]);
Return rtn_ OK;
}
Void displayerrortext (DWORD dwlasterror)
{
Hmodule = NULL; // default to system source
Lpstr messagebuffer;
DWORD dwbufferlength;

DWORD dwformatflags = format_message_allocate_buffer |
Format_message_ignore_inserts |
Format_message_from_system;

//
// If dwlasterror is in the network range,
// Load the message source.
//
If (dwlasterror> = nerr_base & dwlasterror <= max_nerr ){
Hmodule = LoadLibraryEx (text ("netmsg. dll"), null, load_library_as_datafile );
If (hmodule! = NULL)
Dwformatflags | = format_message_from_hmodule;
}
//
// Call formatmessage () to allow for message
// Text to be acquired from the system
// Or from the supplied module handle.
//
If (dwbufferlength = formatmessagea (
Dwformatflags,
Hmodule, // module to get message from (null = System)
Dwlasterror,
Makelangid (lang_neutral, sublang_default), // default language
(Lpstr) & messagebuffer,
0,
Null
))
{
DWORD dwbyteswritten;

//
// Output Message string on stderr.
//
Writefile (
Getstdhandle (std_error_handle ),
Messagebuffer,
Dwbufferlength,
& Dwbyteswritten,
Null
);

//
// Free the buffer allocated by the system.
//
Localfree (messagebuffer );
}

//
// If we loaded a message source, unload it.
//
If (hmodule! = NULL)
Freelibrary (hmodule );
}

 
The previous two examples are often used, so there is still a parameter in formatmessage that we have not used, arguments. Under what circumstances should we use it?
We have explained in detail the meanings of each parameter. Let's take a look at two msdn examples of using this value:
# Ifndef Unicode
# Define Unicode
# Endif

# Include <windows. h>
# Include <stdio. h>

Void main (void)
{
Lpwstr pmessage = l "% 1! *. * S! % 4% 5! * S! ";
Dword_ptr pargs [] = {(dword_ptr) 4, (dword_ptr) 2, (dword_ptr) l "bill", // % 1! *. * S! Refers back to the first insertion string in pmessage
(Dword_ptr) l "Bob", // % 4 refers back to the second insertion string in pmessage
(Dword_ptr) 6, (dword_ptr) l "bill"}; // % 5! * S! Refers back to the third insertion string in pmessage
Const DWORD size = 100 + 1;
Wchar buffer [size];


If (! Formatmessage (format_message_from_string | format_message_argument_array,
Pmessage,
0,
0,
Buffer,
Size,
(Va_list *) pargs ))
{
Wprintf (L "format message failed with 0x % x \ n", getlasterror ());
Return;
}

// Buffer contains "Bi Bob Bill ".
Wprintf (L "formatted message: % s \ n", buffer );
}

 
According to the description of the arguments parameter in msdn, the insertion sequence here follows % N [! Format_specifier!]
This format. If format_specifer is not clear, you can view the printf output format.
Lpwstr pmessage = l "% 1! *. * S! % 4% 5! * S! ";
The meaning is as follows:
% 1! *. * S! % 1: returns the value of the string at the first position of the array,
! *. * S! Is [! Format_specfier!] So we want to know the meaning of *. * s,
According to the printf output format, we can know that the first asterisk * indicates the output width, and the dot (.) indicates that the following Asterisk is the output precision.
Therefore, we can see the first three values of the array pargs, 4, 2, and Bill. 4 is the width to be formatted, 2 is the precision to be formatted, and Bill is the string to be formatted.
% 4 is the string of the fourth value of the array. It does not have format_specifier. Therefore, the default output width and accuracy are used.
% 5! * S! The output string is the string that obtains the fifth value of the array. The width is 6.

 
Msdn also provides an example of using the va_list type:
[CPP] view plaincopyprint?
# Ifndef Unicode
# Define Unicode
# Endif

# Include <windows. h>
# Include <stdio. h>

Lpwstr getformattedmessage (lpwstr pmessage ,);

Void main (void)
{
Lpwstr pbuffer = NULL;
Lpwstr pmessage = l "% 1! *. * S! % 3% 4! * S! ";

// The variable length arguments correspond directly to the format
// Strings in pmessage.
Pbuffer = getformattedmessage (pmessage, 4, 2, l "bill", l "Bob", 6, l "bill ");
If (pbuffer)
{
// Buffer contains "Bi Bob Bill ".
Wprintf (L "formatted message: % s \ n", pbuffer );
Localfree (pbuffer );
}
Else
{
Wprintf (L "format message failed with 0x % x \ n", getlasterror ());
}
}

// Formats a message string using the specified message and variable
// List of arguments.
Lpwstr getformattedmessage (lpwstr pmessage ,)
{
Lpwstr pbuffer = NULL;

Va_list ARGs = NULL;
Va_start (ARGs, pmessage );

Formatmessage (format_message_from_string |
Format_message_allocate_buffer,
Pmessage,
0,
0,
(Lpwstr) & pbuffer,
0,
& ARGs );

Va_end (ARGs );

Return pbuffer;
}

 
We have read all the usage methods, but we may also want to see what the argument uses as described above.
In the message text of a message resource, we may use the insertion sequence to make message text display more flexible.
For example, we define a message text in a message resource as follows:
% 1! *. * S! % 4% 5! * S!
The code for calling the message module is as follows:
[CPP] view plaincopyprint?
Dword_ptr pargs [] = {(dword_ptr) 4, (dword_ptr) 2, (dword_ptr) l "bill", // % 1! *. * S! Refers back to the first insertion string in pmessage
(Dword_ptr) l "Bob", // % 4 refers back to the second insertion string in pmessage
(Dword_ptr) 6, (dword_ptr) l "bill"}; // % 5! * S! Refers back to the third insertion string in pmessage
If (hdll! = NULL ){

Fok = formatmessage (
Format_message_from_hmodule | format_message_argument_array |
Format_message_allocate_buffer,
Hdll, dwerror, systemlocale,
(Ptstr) & hlocal, 0, (va_list *) pargs );
Freelibrary (hdll );
}
}

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.