PlanetSquires Forums

Support Forums => Other Software and Code => Topic started by: Chris Cullen on May 10, 2005, 07:21:28 AM

Title: Problem with EnumPropEx on XP
Post by: Chris Cullen on May 10, 2005, 07:21:28 AM
I dunno if this is an XP thing, because the following code runs fine under windows 98!

Sub cjcEnumPropsEx(ByVal hWndForm As Long, ByRef cText As String)
Local hResult As Long
   
   hResult = EnumPropsEx(hWndForm,ByVal CodePtr(cjcPropEnumProcEx), ByVal VarPtr(cText))
   If hResult = -1 Then
       cText = "There are no Properties associated with this form"
   End If
End Sub


'------------------------------------------------------------------------------------------------------------------------
Function cjcPropEnumProcEx(ByVal hwnd As Long,lpszString As Asciiz, ByVal hData As Long, ByVal dwData As Dword) As Long
   Local pString As String Ptr
   pString = dwData
   @pString = @pString + lpszString + Chr$(13)
   Function = %True
End Function



Under windows XP I get a 'application must close...' windows and the thing bombs.  I've even changed the cjcPropEnumProcEx function to just do a MSGBOX showing the lpszString contents - still crashes.  If I change the msgbox to show VarPtr(lpszString) I always get a number, so its not a null pointer issue.  I'm a bit stumped.

Anyone come accross this before?

:cry:
Title: Problem with EnumPropEx on XP
Post by: Chris Cullen on May 10, 2005, 09:14:47 AM
As a bit more information:  I have created a very simple version of this program in PB8 using DDT and - it all works fine!   :?

I have isolated the problem to FireFly generated code.  I cannot see what an earth is the problem as the setprop/getprop stuff is nothing to do with FF.  The problem comes when accessing the memory pointed to by the lpstring parameter in the enumerating callback function.  As soon as I access that variable the exception occurs.

I am wondering if FF is corrupting something somewhere which is causing this problem!  I have my doubts, but I am baffled by this one.  This is such a simple thing to do and yet XP crashes everytime, and I've tried several machines with this!

I'll keep digging to see if I can solve this one, but any idea's would be gratefully recieved.  (I have tries using the IsBadReadPtr and IsBadStringPtr API's but I still get the GPF!)
Title: Problem with EnumPropEx on XP
Post by: TechSupport on May 10, 2005, 10:43:11 AM
I am not 100% sure but it probably relates to the fact that FireFly sets a prop in all controls/forms that it creates. It is called "FF_PTR". Maybe your function is iterating the window handle and picking up that prop when you actually mean to bypass it (i.e. I assume that you only want to pick up your own props and not FireFly's).

Likewise, if you have code that removes props then ensure that you do not remove any properties that you have not explicity set. You do not want to remove the FF_PTR prop by mistake.
Title: Problem with EnumPropEx on XP
Post by: Chris Cullen on May 11, 2005, 05:13:36 AM
Hi Paul

Actually it's an XP thing (suprise suprise  :roll: )

Here is the powerbasic forum link with the info and code to overcome the problem.

http://www.powerbasic.com/support/forums/Forum4/HTML/012065.html

I dunno what it is, but XP sends a pointer to a memory location which gives me a GPF as soon as I try and look at it.  Anyway, at least it's MS$ and not FF or PB!
Title: Problem with EnumPropEx on XP
Post by: Roger Garstang on May 11, 2005, 02:46:26 PM
You said it worked in DDT though didn't you?  I'm still with Paul on the prop possibly causing it.  If it is returned and you expect a function location which you call it will go boom.
Title: Problem with EnumPropEx on XP
Post by: Chris Cullen on May 11, 2005, 04:19:28 PM
Roger

The DDT thing was just a fluke!  It turns out that XP can set its own properties (so it would seem) and that this has happened in the FF example but not the PB one.  Anyway, the thing to remember is that it is the callback function which is being given a duff memory location (the one which holds the string of the property name).  If this is below BFFF then you cannot read this address, so any access to the lpString in my function will cause a GPF.  Anyway, Edwin reckons its a Atom which is being passed, and I would agree!  Mind you, when I tried his suggestion of using the GlobalAtom function to examine it - BANG! GPF again, so XP is really not very happy with me accessing that location at all - odd really because XP gave the address to me in the first place :roll:

Still, the answer was fairly simple in the end, just test for the address of the lpString being on or below BFFF and if so, DON'T TOUCH!

Others reckon that there are more enumeration functions which can do this kind of thing!  Ho Hum

Here are the finished functions for people to have a look at

SUB cjcEnumPropsEx(BYVAL hWndForm AS LONG, BYREF cText AS STRING)
   LOCAL hResult AS LONG

   hResult = EnumPropsEx(hWndForm,BYVAL CODEPTR(cjcPropEnumProcEx), BYVAL VARPTR(cText))
   IF hResult = -1 THEN
       cText = ""
   END IF
END SUB

'------------------------------------------------------------------------------------------------------------------------
FUNCTION cjcPropEnumProcEx(BYVAL hwnd AS LONG,lpszString AS ASCIIZ, BYVAL hData AS LONG, BYVAL dwData AS DWORD) AS LONG
   Local pString As String Ptr
   Local lpBuffer As Asciiz * 80
   pString = dwData

   '// Valid?
   If VarPtr( lpszString ) <= &hBFFF  Then
       @pString = @pString + "<!BadAdd: " + Format$(VarPtr(lpszString)) + ">" + $Cr
       Function = %True
       Exit Function
   End If
   
   '// Is it added as atom integer?, skip..
   GlobalGetAtomName VarPtr( lpszString ), lpBuffer, SizeOf( lpBuffer )
   If Trim$( lpBuffer ) > "" Then
       @pString=@pString+"<!atom:" + lpBuffer + ">"+$Cr
   Else
       @pString = @pString + lpszString + $Cr
   End If
   Function = %True
END FUNCTION

'------------------------------------------------------------------------------------------------------------------------
' Returns a count of the number of properties associated with a window and creates
' an array with the names in. Does not return any of the error type properties (bad address, atom etc)
'------------------------------------------------------------------------------------------------------------------------
Function cjcPropEnumArray(ByVal hWnd As Long, ByRef cArray() As String) As Long
   Local cText As String
   Register nCount As Long
   Register I As Long
   
   cjcEnumPropsEx(hWnd, cText)
   nCount = ParseCount(cText,$Cr)
   If ( IsFalse Len(cText) ) Or (nCount=0) Then
       Function = 0
       Exit Function
   End If
   
   ' Get count of lines and then break the string into the array
   ReDim cArray(nCount)
   Parse cText,cArray(),$Cr
   ' Now, remove any dudd entries and resize the array
   Do While I <= nCount
       If ( Left$(cArray(I),9) = "<!BadAdd:") Or ( Left$(cArray(I),7) = "<!atom:" ) Then
           Array Delete cArray(I)
           Decr nCount
           Decr I
       End If
       Incr I
   Loop
   ' We now need to resize the array if we have anything left
   If nCount Then
       ReDim Preserve cArray(nCount)
   End If
   Function = nCount    
End Function


Use with caution, the've worked for me OK but I have not had the time to really test them out!