Forum Discussion

alt66's avatar
alt66
New Contributor
12 years ago

WinAPI32

I have been trying to call the Windows API function:
GetTextExtentPoint32

But the first issue is it receives / returns a pointer (reference) to a structure (struct) containing two long (I4) variables so when I tried this way, using Win32Api plug in, but I had no way in vbscript to declare such structure:



hwnd = UIObject.handle

dc = Win32Api.GetDC(hwnd)

ret = Win32Api.GetTextExtentPoint32(dc, UIObject.Text , Len(UIObject.Text), TextSize)  

Call Win32Api.ReleaseDC(hwnd,dc)



In this case if TextSize is unidefined, it stays undefined after the call, and there is no error, if it points to a class with two variants it sends an error



Then I tried the more longer and cumbersome method to call any function in any dll, it allows to create the structures and make the call(s) after a long list of definition and setup steps:



' Calls definitions

   Set uddl = DLL.DefineDLL("USER32")

   Call uddl.DefineProc("GetDC", vt_i4, vt_i4)

   Call uddl.DefineProc("ReleaseDC", vt_i4, vt_i4, vt_i4)

   Set ULib = DLL.Load("USER32")

   

   Set ddll = DLL.DefineDLL("GDI32")

   dsize = DLL.DefineType("SIZE", vt_i4, "X", vt_i4, "Y")

   Call ddll.DefineProc("GetTextExtentPoint32A", vt_i4, vt_lpstr, vt_int, dsize, vt_b1)

   Call ddll.DefineAlias("GetTextExtentPoint32", "GetTextExtentPoint32A")

   Set Lib = DLL.Load("GDI32")  

   

   ' Parameters setup

   hwnd = UIObject.handle

   dc = ULib.GetDC(hwnd)

   Set lpstr = DLL.New("LPSTR", 256)

   lpstr.Text = UIObject.Text

   ln = Len(lpstr.Text)

   Set TextSize = DLL.New("SIZE")

   

   ' Actual call

   Call Lib.GetTextExtentPoint32(dc, lpstr , ln, TextSize)

   

   Call ULib.ReleaseDC(hwnd, dc)



And the result of all of this is a cryptic message when the actual call is made:



An exception occurred: 0xC0000005; class: ; description: ''



I am using the latest Test Complete 9 version (downloaded as free trial last week) and I am still wondering what is wrong with the code. Does any body knows?



 


5 Replies

  • HKosova's avatar
    HKosova
    SmartBear Alumni (Retired)

    Hi Luis,

    I have been trying to call the Windows API function: GetTextExtentPoint32But the first issue is it receives / returns a pointer (reference) to a structure (struct) containing two long (I4) variables so when I tried this way, using Win32Api plug in, but I had no way in vbscript to declare such structure:

    hwnd = UIObject.handle
    dc = Win32Api.GetDC(hwnd)
    ret = Win32Api.GetTextExtentPoint32(dc, UIObject.Text , Len(UIObject.Text), TextSize) 
    Call Win32Api.ReleaseDC(hwnd,dc)

    In this case if TextSize is unidefined, it stays undefined after the call, and there is no error, if it points to a class with two variants it sends an error


    You need to initialize the TextSize variable as a tagSIZE structure instance:

    Set TextSize = Win32API.tagSIZE

    In this case, it will correctly receive the output value, and you'll be able to get the string dimensions as TextSize.cx and TextSize.cy.

  • alt66's avatar
    alt66
    New Contributor
    Helen,



    Thanks for you reply. I added the TextSize variable initialization:



       hwnd = UIObject.handle

       dc = Win32Api.GetDC(hwnd)

       ln = Len(UIObject.Text)

       Set TextSize = Win32API.tagSIZE

       ret = Win32Api.GetTextExtentPoint32(dc, UIObject.Text , ln, TextSize)

       Call Win32Api.ReleaseDC(hwnd,dc)

     



    And I put debugged the code chacking the TextSize variable before and after the call, in both cases it points to an object but it is empty, I never see the cx and cy members that should be there. I guess I am using the wrong structure name, I tried with TSize too getting the same results. I wonder if you know another way to create a size structure in vbscript





    Luis
  • HKosova's avatar
    HKosova
    SmartBear Alumni (Retired)
    Hi Luis,



    You should be able to access the cx and cy fields in scripts:

    Call Log.Message(TextSize.cx)

    Call Log.Message(TextSize.cy)


    Not sure why they aren't visible to the debugger though. I've filled in a bug report for developers to look into this.
  • alt66's avatar
    alt66
    New Contributor
    Helen,



    Wow, it is working!! Thanks!!



    I just have a question, I am testing the code and it returns a text height (cy) of 16 using the default text for .NET controls (8.25 points Microsoft Sans Serif). and the label in which the text is contained is just 13 in height, in contrast the length against the cx values seems right (so far). Thus I am thinking I have an different units issue, do you know what units is returning in every case? 



    Luis