No announcement yet.


  • Filter
  • Time
  • Show
Clear All
new posts

  • GetEnhMetafileDescription

    I have a problem with the PB declaration of the GetEnhMetafileDescription
    function. In the Win32API file, the string field is declared as
    lpszDescription AS ASCIIZ. For the benefit of those who have not
    used this function, the metafile description consists of two strings
    separated by double null terminators;

    (String #1)/0/0(String#2)/0

    The problem I am having is that when I pass an asciiz to the function,
    I only get the first string value and the asciiz variable seems to
    drop the second. I know this because I created a description record
    which is 54 character long. When I call the function in PB, I only get 35 characters.
    The return value of the function tells me that 54 were passed back to the buffer.
    Does an ASCIIZ variable truncate an input buffer when it encounters
    a null terminator in the character buffer?

    I have used this function without problem in VB, however, in VB you need
    to use a fixed length string instead of ASCIIZ.

    Heres a small code segment:
    dim tempstr as ASCIIZ*256
    ml& = GetEnhMetaFileDescription(mfh&, 0,BYVAL 0)
    'ml& contains the size of the required buffer, In my case = 54
    IF (ml& <> 0) THEN
      tempstr= STRING$(ml&," ")
      di& = GetEnhMetaFileDescription(mfh&, ml&,tempstr)
      'di& tells how many characters were actually copied, 54 in my case     
    end if
    msgbox str$(len(tempstr)) 'this says 35, should be 54


  • #2
    Exactly. ASCIIZ string are strings *terminated* with a NULL byte, so they are working exactly as intended.

    ASCIIZ strings are not the best choice when you want to manipulate data that contains embedded null ($NUL/CHR$(0)) bytes.

    If you do create (or are passed) an ASCIIZ string with embedded null bytes, then you need to work with the data another way, such as using PEEK$(VARPTR(Asciizstring),Count) or using pointers and read/write the string data directly from the ASCIIZ's string memory location.

    In the particular case above, it is better to use either a fixed-length string (and pass the string address with BYVAL VARPTR(FixedString), or use a dynamic string (which must be prefilled with the expected/maximum number of characters before passing BYVAL STRPTR(DynamicString$) to the API function.

    Since you are already know or have selected the maximum size of the buffer, changing the code to work with a fixed-length string instead of a ASCIIZ string is a simple change.

    As the API function is declared as expecting an ASCIIZ, all you need to do is pass a pointer to the fixed-length string storage with BYVAL VARPTR(FixedString).

    I hope this helps!

    PowerBASIC Support
    mailto:[email protected][email protected]</A>
    mailto:[email protected]


    • #3
      Thanks Lance, I tried using your approach previously but with no
      success. However, after reading your reply, I tried again and this
      time it worked. Go figure! This begs the question though, why does
      the PB file use the ASCIIZ parameter. Why not use
      Byval as string in the declaration so the function will return the
      the entire buffer directly without massaging the function?




      • #4
        In the original C declaration for GetEnhMetaFileDescription, the lpszDescription parameter is an LPTSTR type, which directly corresponds to the ASCIIZ type in PowerBASIC. Here, you are passing the address of a string buffer, not a string, so it is not possible to declare this parameter AS STRING instead. As Lance points out, there are a number of work-arounds you can use via BYVAL at the time the function is called. This is a special meaning of BYVAL that, roughly speaking, disables type checking. We can't build the same BYVAL into the function declaration, where it would mean "pass by value": not the same thing.

        In any case where you're calling a DLL designed for a different language, issues like this will come up. No fear, it gets easier with practice!

        Tom Hanlin
        PowerBASIC Staff


        • #5
          Tom, thanks for the reply. I'm totally clear on the subject now and
          have the function working correctly. However, I must correct my orginal post.
          The format of the enhanced metafile description is as follows:

          (string #1)/0(string #2)/0/0

          The double null terminator goes at the end of the string, not in
          the middle as I originally stated.

          Thanks again,