Author Topic: How would I translate this winapi function to Oxygen?  (Read 4686 times)

0 Members and 1 Guest are viewing this topic.

kryton9

  • Guest
How would I translate this winapi function to Oxygen?
« on: June 29, 2011, 10:09:52 PM »
I tried to figure this out, but got nowhere.

int __cdecl wsprintf(  __out  LPTSTR lpOut,  __in   LPCTSTR lpFmt,  __in    ...);

Here is what I have:
extern cdecl lib "User32.dll" int wsprintf( __out  LPTSTR lpOut,  __in   LPCTSTR lpFmt, __in ... ); end extern

I also tried:
extern cdecl lib "User32.dll" int wsprintf(byref  lpOut as asiiz, byref lpFmt as string,byval ... as any ); end extern

But no luck, thanks.

Charles Pegge

  • Guest
Re: How would I translate this winapi function to Oxygen?
« Reply #1 on: June 29, 2011, 11:41:33 PM »
Kent,

There is an Ansi version wsprintfA and unicode version  wsprintfW

The prototype given is not a fixed prototype. Oxygen does not support this "..." thing yet, but I use a workaround here to make a low level call to the function which will take any number of params of any type without complaint.
Cdecl functions require the caller to perform stack cleanup. This is done by restoring the stack pointer register esp to its prior value

Code: OxygenBasic
  1. declare function wsprintf cdecl lib "user32.dll" alias "wsprintfA" (zstring*result,zstring*format) as sys '... generic params
  2.  
  3. function test()
  4.   zstring output[1024]
  5.   sys pf,psp
  6.   string s="Result: "
  7.   sys n=1234
  8.   pf=@wsprintf
  9.   psp=esp 'remember stack pointer
  10.  call pf @output,"%s%d", *s, n
  11.   esp=psp 'restore stack pointer
  12.  print output
  13.   print "ok"
  14. end function
  15.  
  16.  
  17. test
  18.  

Charles

http://msdn.microsoft.com/en-us/library/ms647550(v=vs.85).aspx

« Last Edit: June 30, 2011, 12:07:24 AM by Charles Pegge »

kryton9

  • Guest
Re: How would I translate this winapi function to Oxygen?
« Reply #2 on: June 29, 2011, 11:47:22 PM »
I am glad I asked for help!  I think an infinite amount of chimps could have typed out a work by Shakespeare before I could have figured that one out!

kryton9

  • Guest
Re: How would I translate this winapi function to Oxygen?
« Reply #3 on: June 30, 2011, 12:25:33 AM »
I can't get it to format decimal, strange.
Code: OxygenBasic
  1. declare function wsprintf cdecl lib "user32.dll" alias "wsprintfA" (zstring *result,zstring *format) as sys '... generic params
  2.  
  3. function test()  
  4.   zstring output[1024]  
  5.   sys pf,psp  
  6.   string s="Result: "  
  7.   float n=1234.5678
  8.   pf=@wsprintf  
  9.   psp=esp 'remember stack pointer  
  10.  call pf @output,"%s%.2d", *s, n  
  11.   esp=psp 'restore stack pointer  
  12.  print output  
  13.   print "ok"  
  14. end function  
  15.  
  16.  
  17. test

Peter

  • Guest
Re: How would I translate this winapi function to Oxygen?
« Reply #4 on: June 30, 2011, 01:31:00 AM »
Hi Kent,


'Wrong  > declare function wsprintf cdecl lib "user32.dll" alias "wsprintfA" (zstring *result,zstring *format) as sys '... generic params 

 Declare Function wsprintf Lib "user32.dll" (ByVal lpstr As String, ByVal lpcstr As String, ByRef OptionalArguments as Any) As Long
 
 Function Test()   
  zstring output[1024]   
  sys pf,psp   
  string s="Result: "   
  float n=1234.5678 
  pf=@wsprintf   
  psp=esp 'remember stack pointer   
  call pf @output,"%s%.2d", *s, n   
  esp=psp 'restore stack pointer   
  print output   
  print "ok"   
End Function
   
Test()     

 
 

kryton9

  • Guest
Re: How would I translate this winapi function to Oxygen?
« Reply #5 on: June 30, 2011, 01:45:08 AM »
thanks Peter, but it didn't work.

[attachment deleted by admin]

Charles Pegge

  • Guest
Re: How would I translate this winapi function to Oxygen?
« Reply #6 on: June 30, 2011, 08:23:08 PM »
Hi Kent and Peter,

I have implemented Ellipsis at last. (I spent a long time refactoring C declaration parsing)

Here is my test code for the latest Oxygen (in progress version).

I have never used this function before so I am not familiar with the formatting options. All the term parameters are passed without checking or conversion so you must provide exactly what the format expects at the right reference level.

Code: OxygenBasic
  1.  
  2.   '=============
  3.  'ELLIPSIS DEMO
  4.  '=============
  5.  
  6.   'http://msdn.microsoft.com/en-us/library/ms647550(v=vs.85).aspx
  7.  '
  8.  '
  9.  'WORKS WITH ANY OF THESE ALTERNATIVE DECLARATIONS
  10.  '================================================
  11.  
  12.   'declare function wsprintf cdecl lib "user32.dll" alias "wsprintfA" (byref result as zstring , byref format as zstring, ... ) as sys
  13.  'declare function wsprintf cdecl lib "user32.dll" alias "wsprintfA" (result as zstring , format as zstring, ... ) as sys
  14.  'declare function wsprintf cdecl lib "user32.dll" alias "wsprintfA" (zstring *result,*format, ... ) as sys
  15.  
  16.   'library "user32.dll"
  17.  'declare function wsprintf cdecl alias "wsprintfA" (zstring *result,*format, ... ) as sys
  18.  'library ""
  19.  
  20.   'sys alias "wsprintfA" lib "user32.dll" cdecl wsprintf (char *result,*format, ... )
  21.  'sys wsprintf cdecl alias "wsprintfA" lib "user32.dll" (char *result,*format, ... )
  22.  sys wsprintf alias "wsprintfA" lib "user32.dll" (char *result,*format, ... )
  23.   '
  24.  
  25.   'TEST
  26.  '====
  27.  
  28.  
  29.   zstring output[1024]
  30.   string s="Result: "
  31.   sys n=1234
  32.   wsprintf output,"%s%d", *s,123
  33.  
  34.   print output
  35.  
  36.  

Charles
« Last Edit: June 30, 2011, 08:36:15 PM by Charles Pegge »

kryton9

  • Guest
Re: How would I translate this winapi function to Oxygen?
« Reply #7 on: June 30, 2011, 09:16:42 PM »
I'll check it out tomorrow, let you have time to update the files on the server. Looking forward to testing it though! Thanks.

kryton9

  • Guest
Re: How would I translate this winapi function to Oxygen?
« Reply #8 on: July 01, 2011, 02:55:13 AM »
Charles, the ... is working nicely. It is a very nice handy addition because you see that in so many winapi functions. I am sure it was a brain teaser to get working.

Unfortunately it isn't working correctly in terms of %d, which is for decimal values.   %.2d  means show the number with 2 decimals so that 1234.5678  would be formatted 1234.56
But once this function works you will have a powerful command to make a nice format function for oxygen that is proven.

Charles Pegge

  • Guest
Re: How would I translate this winapi function to Oxygen?
« Reply #9 on: July 01, 2011, 04:39:20 AM »

Kent,

 looking at the MSDN link, it specified d as decimal signed integer. This print function does not appear to support floats, only strings and integers.

Have I missed something?

Might be better off making our own. At least it will be portable.

Charles

Charles Pegge

  • Guest
Re: How would I translate this winapi function to Oxygen?
« Reply #10 on: July 01, 2011, 10:22:59 AM »

Here is an elementary example of an fmt function:

it handles strings, integers, singles and doubles.

Code: OxygenBasic
  1.  
  2.   function fmt(string sf,...) as string
  3.   '===================================
  4.  sys     nv at [ebp+12] 'sys
  5.  bstring sv at [ebp+12] 'string
  6.  single  fv at [ebp+12] 'single
  7.  double  dv at [edi]    'double
  8.  sys i, d=1, le=len sf
  9.   string sp="  "
  10.   do
  11.     i++ : if i>le then exit do
  12.     select asc sf,i
  13.     case "s" : function+=    sv[d]  sp : d++
  14.     case "n" : function+=str(nv[d]) sp : d++
  15.     case "f" : function+=str(fv[d]) sp : d++
  16.     case "d"
  17.       lea edi,[ebp+8]
  18.       mov eax,d
  19.       shl eax,2
  20.       add edi,eax
  21.       function+=str(dv) sp : d+=2
  22.     end select
  23.   end do
  24.   end function
  25.  
  26.  
  27.   'TEST
  28.  '====
  29.  
  30.   'literal floating point numbers are double
  31.  
  32.   print fmt "sndd","Result:", 42, 1.25, pi
  33.  
  34.  

Charles

kryton9

  • Guest
Re: How would I translate this winapi function to Oxygen?
« Reply #11 on: July 01, 2011, 11:15:50 AM »
Thanks Professor of Oxygen, that is super!

Charles Pegge

  • Guest
Re: How would I translate this winapi function to Oxygen?
« Reply #12 on: July 01, 2011, 08:38:16 PM »
This is a cleaner version, but I had to correct Oxygen's sizeof sys so it returns 4 for 32 bit platforms and 8 for 64 bit.

No assembly code or arrays are used in this one.

Code: OxygenBasic
  1.  
  2.  
  3.   function fmt(string sf,...) as string
  4.   '====================================
  5.  sys p=@sf+sizeof sys
  6.   sys     nv at p 'integers
  7.  bstring sv at p 'string
  8.  single  fv at p 'single
  9.  double  dv at p 'double
  10.  sys i
  11.   sys le=len sf
  12.   string sp="  "
  13.   do
  14.     i++ : if i>le then exit do
  15.     select asc sf,i
  16.     case "s" : function+=    sv  sp : p+=sizeof sys
  17.     case "n" : function+=str(nv) sp : p+=sizeof sys
  18.     case "f" : function+=str(fv) sp : p+=sizeof single
  19.     case "d" : function+=str(dv) sp : p+=sizeof double
  20.     end select
  21.   end do
  22.   end function
  23.  
  24.  
  25.   'TEST
  26.  '====
  27.  
  28.   'literal floating points are Double
  29.  
  30.   print fmt "sndd","Result:", 42, 1.25, pi
  31.  
  32.  

Charles
« Last Edit: July 01, 2011, 08:40:19 PM by Charles Pegge »

kryton9

  • Guest
Re: How would I translate this winapi function to Oxygen?
« Reply #13 on: July 01, 2011, 10:22:13 PM »
That's nice Charles. But the reason we needed format was really to format decimal numbers, since Oxygen handles the other variable types so nicely compared to C.

Here is what I am using for now:
Code: OxygenBasic
  1. function format$(double f, byte d) as string
  2.     string l = trunc(f)
  3.     string r = frac(f)
  4.     return (str(l)+"."+mid(str(r),3,d))
  5. end function

Your program compiles fine, but nothing shows up. It runs then terminates.
« Last Edit: July 01, 2011, 11:29:15 PM by kryton9 »