Parameter Passing Error

Started by gian young, June 24, 2004, 09:37:20 PM

Previous topic - Next topic

gian young

Hi can anyone help me through the following.

This is more of a PowerBasic complier question than Firefly but thought I would start here.

I am using PB 7.02 with Win XP Pro and Firefly ver 1.05 and attempting to use the WIN API functions "BeginPaint" and "EndPaint" during a WM_PAINT event.

Both functions require a pointer to be passed to a PAINTSTRUCT structure.

My problem is I cannot get past the PB complier without drawing an error.

My FireFly generated code looks a bit like this:

Function FORM1_PICTURE1_WM_PAINT (ControlIndex As Long, hWndForm As Dword, hWndControl As Dword) As Long

Dim ps As PAINTSTRUCT
Dim psPtr As PAINTSTRUCT Pointer

psPtr = VarPtr(ps)

BeginPaint (HWND_FORM1_PICTURE1, psPtr)

'Other Code for the Picture painting exercise

EndPaint (HWND_FORM1_PICTURE1, psPtr)

End Function

When I try to compile, the PB complier jams up on the Beginpaint PAINTSTRUCT pointer and reports 433 or 480 errors and despite all the variations I have tried (ie ByCopy, ByRef, ByVal etc) will not allow me pass this pointer.

Am I missing something, any help or suggestions appreciated.

Gian Young
Australia

Jose Roca


Function FORM1_PICTURE1_WM_PAINT (ControlIndex As Long, hWndForm As Dword, hWndControl As Dword) As Long

Dim ps As PAINTSTRUCT

BeginPaint (HWND_FORM1_PICTURE1, ps)

'Other Code for the Picture painting exercise

EndPaint (HWND_FORM1_PICTURE1, ps)

End Function

gian young

Hi, Thank you for whoever posted the last reply and your interest in helping.

Unfortunately I have already tried that and I get an Error 443

Error description = TO expected.


Regards
Gian Young

gian young

Further to the problem I reported, after trying a few more variations I have managed to get past the compiler road block and for anyone interested the following code fixed it.

I believe part of my problem was not treating the Win API functions with respect.

The BeginPaint Function declare from the WinAPI is as follows

'DECLARE FUNCTION BeginPaint LIB "USER32.DLL" ALIAS "BeginPaint" (BYVAL hWnd AS DWORD, lpPaint AS PAINTSTRUCT) AS LONG

My new code is:-

Function FORM1_PICTURE1_WM_PAINT (ControlIndex As Long, hWndForm As Dword, hWndControl As Dword) As Long

Dim di As Long  
Dim ps As PAINTSTRUCT
Dim psPtr As PAINTSTRUCT Pointer
   
psPtr = VarPtr(ps)
   
di = BeginPaint (HWND_FORM1_PICTURE1, @psPtr)
   
'Other picture painting code here
   
di = EndPaint (HWND_FORM1_PICTURE1, @psPtr)   


End Function

Thankyou Jose for your assistance

Regards
Gian Young
Australia

Roger Garstang

So, was the pointer still needed, or did Jose's code work with just the di added.  Odd why it needed a return value...could be that it returns a "handle to a display device context" because a lot of api functions I use return values and I don't deal with them.  I probably should to handle errors, but my code is perfect  :D Yeah right!

Jose Roca

Since the parameter is declared [ByRef] lpPaint AS PAINTSTRUCT, when you pass ps the compiler passes a pointer to this structure.

A short example of usage, where hWnd is the handle of the window and hDc the handle of the device context of this window returned by BeginPaint. What  the example does is to erase the background of the window.

local  hDc       as dword
local  pPaint    AS PAINTSTRUCT
local  hBrush    as dword
local  rc        as RECT

GetClientRect(hWnd, rc)
hDc = BeginPaint(hWnd, pPaint)
hBrush = CreateSolidBrush(GetSysColor(%COLOR_BTNFACE))
FillRect hDc, rc, hBrush
DeleteObject hBrush
EndPaint hWnd, pPaint

Sorry if I was not more verbose in my earlier post, but I was in a hurry and I only intended to correct the most obvious error, that was that you weren't passing correctly the pointer to the PAINTSTRUCT structure. If a parameter is declared ByRef, the compiler passes a pointer to it; if the parameter were declared ByVal as DWORD, then you will need to pass VARPTR(ps), i.e. the value of the pointer; if it were declared as DWORD then you will need to pass BYVAL VARPTR(ps). So you need to know how the compiler works and to pay attention of how the parameter is declared, or you can override parameter checking using ByVal, i.e. BYVAL VARPTR(ps) will always pass a pointer to the PAINTSTRUCT structure, regardless of how the parameter has been declared in the function, but the fact that the documentation says that you have to pass a pointer doesn't mean that you need to pass a variable of the type pointer, in this case what you have to pass is the address of the PAINTSTRUCT structure; how do you it is up to you.

P.S. The latest versions compilers allow you to use EndPaint(hWnd, pPaint) instead of EndPaint hWnd, pPaint when you want to ignore the result of the function. This change has been made to allow to use the same syntax regardless if a function or procedure has been declared in the standard format or as a macro.

gian young

I appreciate the dialog and the solutions offered on this subject, this is a good learning exercise for me.

I have relied on the PB include file Win32API.Inc for my API Function Declarations. As an example the BeginPaint Function from the PB Win32API.Inc is declared as below.

DECLARE FUNCTION BeginPaint LIB "USER32.DLL" ALIAS "BeginPaint" (BYVAL hWnd AS DWORD, lpPaint AS PAINTSTRUCT) AS LONG

As seen the pointer to the PAINTSTRUCT is not declared as a Dword but is a little ambiguous in the way it reads. In this case as Jose indicates I have found that using ByVal Varptr(ps) works, I have also found that the BeginPaint function does return a handle and has to be treated as a proper function to get past the PB compiler.

Thank for all the help.

Gian Young
Australia