Atlanta Custom Software Development 

 
   Search        Code/Page
 

User Login
Email

Password

 

Forgot the Password?
Services
» Web Development
» Maintenance
» Data Integration/BI
» Information Management
Programming
  Database
Automation
OS/Networking
Graphics
Links
Tools
» Regular Expr Tester
» Free Tools

How to use FormatMessage API to format string with placeholder (para with %)
[ All Languages » VB »  String]

Total Hit ( 5562)

Rate this article:     Poor     Excellent 

 Submit Your Question/Comment about this article

Rating


 


FormatMessage is a very powerful API. In this article we will explore possible use of FormatMessage API. Some possible use of FormatMessage api is
  • Getting API error description from Error Code
  • Reading Message String from Resource of DLL or Exe
  • Replacing placeholders in a string with multiple insert strings.

The FormatMessage function formats a message string. The function requires a message definition as input. The message definition can come from a buffer passed into the function. It can come from a message table resource in an already-loaded module. Or the caller can ask the function to search the system's message table resource(s) for the message definition. The function finds the message definition in a message table resource based on a message identifier and a language identifier. The function copies the formatted message text to an output buffer, processing any embedded insert sequences if requested.

Here is the declaration of FormatMessage api, There are 2 different versions of FormatMessage one is FormatMessageA (Ansi version) and FormatMessageW (Unicode version). Here we will use ANSI version.

Click here to copy the following block
Private Declare Function FormatMessage Lib "kernel32" Alias "FormatMessageA" ( _
    ByVal dwFlags As Long, _
    lpSource As Any, _
    ByVal dwMessageId As Long, _
    ByVal dwLanguageId As Long, _
    ByVal lpBuffer As String, _
    ByVal nSize As Long, _
    Arguments As Long) As Long

Parameters Description

  • dwFlags
    [in] Formatting options, and how to interpret the lpSource parameter. The low-order byte of dwFlags specifies how the function handles line breaks in the output buffer. The low-order byte can also specify the maximum width of a formatted output line.
    This parameter can be one or more of the following values.
    • FORMAT_MESSAGE_ALLOCATE_BUFFER The lpBuffer parameter is a pointer to a PVOID pointer, and that the nSize parameter specifies the minimum number of TCHARs to allocate for an output message buffer. The function allocates a buffer large enough to hold the formatted message, and places a pointer to the allocated buffer at the address specified by lpBuffer. The caller should use the LocalFree function to free the buffer when it is no longer needed.
    • FORMAT_MESSAGE_IGNORE_INSERTS Insert sequences in the message definition are to be ignored and passed through to the output buffer unchanged. This flag is useful for fetching a message for later formatting. If this flag is set, the Arguments parameter is ignored.
    • FORMAT_MESSAGE_FROM_STRING The lpSource parameter is a pointer to a null-terminated message definition. The message definition may contain insert sequences, just as the message text in a message table resource may. Cannot be used with FORMAT_MESSAGE_FROM_HMODULE or FORMAT_MESSAGE_FROM_SYSTEM.
    • FORMAT_MESSAGE_FROM_HMODULE The lpSource parameter is a module handle containing the message-table resource(s) to search. If this lpSource handle is NULL, the current process's application image file will be searched. Cannot be used with FORMAT_MESSAGE_FROM_STRING.
    • FORMAT_MESSAGE_FROM_SYSTEM The function should search the system message-table resource(s) for the requested message. If this flag is specified with FORMAT_MESSAGE_FROM_HMODULE, the function searches the system message table if the message is not found in the module specified by lpSource. Cannot be used with FORMAT_MESSAGE_FROM_STRING.
    • If this flag is specified, an application can pass the result of the GetLastError function to retrieve the message text for a system-defined error.
    • FORMAT_MESSAGE_ARGUMENT_ARRAY The Arguments parameter is not a va_list structure, but is a pointer to an array of values that represent the arguments.
    • This flag cannot be used with 64-bit argument values. If you are using 64-bit values, you must use the va_list structure.

  • lpSource
    [in] Location of the message definition. The type of this parameter depends upon the settings in the dwFlags parameter. This parameter cab be any of the following values

  • dwMessageId
    [in] Message identifier for the requested message. This parameter is ignored if dwFlags includes FORMAT_MESSAGE_FROM_STRING.
  • dwLanguageId
    [in] Language identifier for the requested message. This parameter is ignored if dwFlags includes FORMAT_MESSAGE_FROM_STRING.
  • lpBuffer
    [out] Pointer to a buffer that receives the null-terminated string that specifies the formatted message. If dwFlags includes FORMAT_MESSAGE_ALLOCATE_BUFFER, the function allocates a buffer using the LocalAlloc function, and places the pointer to the buffer at the address specified in lpBuffer. This buffer cannot be larger than 64K bytes.
  • nSize
    [in] If the FORMAT_MESSAGE_ALLOCATE_BUFFER flag is not set, this parameter specifies the size of the output buffer, in TCHARs. If FORMAT_MESSAGE_ALLOCATE_BUFFER is set, this parameter specifies the minimum number of TCHARs to allocate for an output buffer. The output buffer cannot be larger than 64K bytes.
  • Arguments
    [in] Pointer to an array of values that are used as insert values in the formatted message. A %1 in the format string indicates the first value in the Arguments array; a %2 indicates the second argument; and so on. The interpretation of each value depends on the formatting information associated with the insert in the message definition. The default is to treat each value as a pointer to a null-terminated string.


Here is an example, How to replace placeholders with insert strings.

Step-By-Step Example

- Create a standard exe project
- Add the following code in form1

Click here to copy the following block
Private Const FORMAT_MESSAGE_ALLOCATE_BUFFER = &H100
Private Const FORMAT_MESSAGE_IGNORE_INSERTS = &H200
Private Const FORMAT_MESSAGE_FROM_STRING = &H400
Private Const FORMAT_MESSAGE_FROM_HMODULE = &H800
Private Const FORMAT_MESSAGE_FROM_SYSTEM = &H1000
Private Const FORMAT_MESSAGE_ARGUMENT_ARRAY = &H2000
Private Const FORMAT_MESSAGE_MAX_WIDTH_MASK = &HFF
Private Const LOAD_LIBRARY_AS_DATAFILE = &H2

Private Declare Function FormatMessage Lib "kernel32" Alias "FormatMessageA" ( _
    ByVal dwFlags As Long, _
    lpSource As Any, _
    ByVal dwMessageId As Long, _
    ByVal dwLanguageId As Long, _
    ByVal lpBuffer As String, _
    ByVal nSize As Long, _
    Arguments As Long) As Long

Public Function GetFormattedString(strSource As String, Inserts()) As String
  'Loads a resource string replacing %n sequences with strings
  'from the Inserts argument(s). (First insert is %1, next %2, etc.)
  Dim sSource As String, sBuf As String, sAnsiInserts() As String
  Dim i As Integer, iLB As Integer, iUB As Integer
  Dim lpInserts() As Long, lBufSize As Long, lRet As Long
  
  'sSource = LoadResString(lResID)
  sSource = strSource
  
  lBufSize = Len(sSource) + 1
  iLB = LBound(Inserts): iUB = UBound(Inserts)
  ReDim lpInserts(iLB To iUB)
  ReDim sAnsiInserts(iLB To iUB)
  
  For i = iLB To iUB
    sAnsiInserts(i) = StrConv(Inserts(i), vbFromUnicode)
    lpInserts(i) = StrPtr(sAnsiInserts(i))
    lBufSize = lBufSize + Len(Inserts(i))
  Next
  
  sBuf = String(lBufSize, 0)
  
  lRet = FormatMessage(FORMAT_MESSAGE_FROM_STRING Or FORMAT_MESSAGE_ARGUMENT_ARRAY, _
    ByVal sSource, 0&, 0&, sBuf, lBufSize, lpInserts(0))
  GetFormattedString = Left$(sBuf, lRet)
End Function


Private Sub Form_Load()
  Dim v()
  v = Array("C:", "20")
  MsgBox GetFormattedString("Drive %1 has only %2 MB left", v)
End Sub


Submitted By : Nayan Patel  (Member Since : 5/26/2004 12:23:06 PM)

Job Description : He is the moderator of this site and currently working as an independent consultant. He works with VB.net/ASP.net, SQL Server and other MS technologies. He is MCSD.net, MCDBA and MCSE. In his free time he likes to watch funny movies and doing oil painting.
View all (893) submissions by this author  (Birth Date : 7/14/1981 )


Home   |  Comment   |  Contact Us   |  Privacy Policy   |  Terms & Conditions   |  BlogsZappySys

© 2008 BinaryWorld LLC. All rights reserved.