My code skips lines in the 64 bits version

Greetings,
I have the following code which works well in 32 bits but fails in 64 bits:
Sub WinHook(WinHandle As Integer)
#if TargetWindows then
dim p As Ptr=AddressOf WindowProc //Another method defined in the same module

#if Target32Bit then
  Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hWnd As Integer, ByVal nIndex As Integer, ByVal dwNewLong As Ptr) As Integer
  lpPrevWndProc=SetWindowLong(WinHandle,-4,p) //lpPrevWndProc: a property of the module, as an integer.
#else
  Declare Function SetWindowLongPtr lib "user32" (ByVal hWnd as Integer,ByVal nIndex as integer,ByVal dwNewLong as Ptr) as Integer
  MsgBox "1: "+str(WinHandle)
  lpPrevWndProc=SetWindowLongPtr(WinHandle,-4,p)
  MsgBox "2: "+str(lpPrevWndProc)
#endif

#endif
End Sub
In 64 bits, I get the MsgBox "1: "+str(WinHandle) but not the second one, like if the code skips out of the method. I have no clue what this means. Any idea?

It would be helpful to post the code formatted like that:

[code]Sub WinHook(WinHandle As Integer)
#if TargetWindows then
dim p As Ptr=AddressOf WindowProc //Another method defined in the same module

#if Target32Bit then
Declare Function SetWindowLong Lib “user32” Alias “SetWindowLongA” (ByVal hWnd As Integer, _
ByVal nIndex As Integer, ByVal dwNewLong As Ptr) As Integer
lpPrevWndProc=SetWindowLong(WinHandle,-4,p) //lpPrevWndProc: a property of the module, as an integer.
#else
Declare Function SetWindowLongPtr lib “user32” (ByVal hWnd as Integer,ByVal nIndex as integer, _
ByVal dwNewLong as Ptr) as Integer
MsgBox "1: "+str(WinHandle)
lpPrevWndProc=SetWindowLongPtr(WinHandle,-4,p)
MsgBox "2: "+str(lpPrevWndProc)
#endif
#endif
End Sub[/code]

you could wrap each of the calls in a try…catch
Maybe p isnt the right size for a Ptr in this function call?
If an exception occurs here, it will go to unhandled exceptions

Don’t know if it’s the solution, but nIndex is defined as int. int is a 32 bit signed integer. Xojo Integer is int64 in 64bit so you need to declare it as int32.

Declare Function SetWindowLongPtr lib "user32" (ByVal hWnd as Integer,ByVal nIndex as int32,ByVal dwNewLong as Ptr) as Integer

[quote=283240:@Eli Ott]It would be helpful to post the code formatted like that:
[/quote]
Thanks for pointing that out.

[quote=283242:@jim mckay]Don’t know if it’s the solution, but nIndex is defined as int. int is a 32 bit signed integer. Xojo Integer is int64 in 64bit so you need to declare it as int32.
[/quote]
Good idea, but I even tried changing all of them to int32 and it made no difference. Thanks.

[quote=283241:@Jeff Tullin]you could wrap each of the calls in a try…catch
Maybe p isnt the right size for a Ptr in this function call?
If an exception occurs here, it will go to unhandled exceptions[/quote]
You’re right. I’m already catching exceptions in the app class, which explains why the code was skipping the remaining lines (for the record, I’ve already seen weird things like that in the past, without any code for handling exceptions).

Indeed, I have an exception: Could not load SetWindowLongPtr from User32. That’s strange as it’s how it is supposed to be. Both the SetWindowLong documentation (https://msdn.microsoft.com/en-us/library/windows/desktop/ms644898(v=vs.85).aspx) and the SetWindowLongPtr one (https://msdn.microsoft.com/en-us/library/windows/desktop/ms644898(v=vs.85).aspx) say we should use the one with Ptr, yet this call can’t be loaded. What am I missing?
Thank you!

Should you also be using an alias to SetWindowLongPtrW or SetWindowLongPtrA like you did with SetWindowLong?

And the MS docs seem to indicate that you don’t need to have two different calls in your code as SetWindowLongPtr will call SetWindowLong on 32-bit Windows.

Yes, as Paul stated, that should do it for 32bit and 64bit:

Declare Function SetWindowLongPtr Lib "user32" Alias "SetWindowLongA" _ (ByVal hWnd as Integer,ByVal nIndex as integer, ByVal dwNewLong as Ptr) as Integer

Hmm… They are loading fine now, but the calls return 0 which indicate a problem. GetLastError returns 0 so I’m not sure what I have to look for.

Yes, I’ve read that too. I made two distinct calls because, since the 64 bits one didn’t work, I wanted to keep at least a good one.
Thank you.

[quote=283255:@Eli Ott]Yes, as Paul stated, that should do it for 32bit and 64bit:

Declare Function SetWindowLongPtr Lib "user32" Alias "SetWindowLongA" _ (ByVal hWnd as Integer,ByVal nIndex as integer, ByVal dwNewLong as Ptr) as Integer[/quote]
Thank you. Now I have to figure out why the result is 0.

Could you post why? This could be interesting for others having the same issue.

I haven’t yet figured it out, sorry; else, I’d reported the solution, of course. Since GetLastError returns 0, I have no clue as what goes wrong. Anyway, the 64 bits version also breaks the ability of my app to deal with extended clipboard data, so I guess I’ll just stay with the 32 bits version which goes better (originally, I had an OutOfMemory exception while my app was taking several screenshots so I thought I’d try with 64 bits).

NIndex needs to be int32. You’re using integer which is int64 under 64 bit and will fail.

Yes, you are correct. My bad. nIndex is an C int, which is Int32 in Xojo.

I have not done subclassing and hooking in Xojo so I do not know whether what I have here would help.

At the start of the Sub, there is:

Sub WinHook(WinHandle As Integer)

I think WinHandle should be a 32-bit Long (Int32). Using Integer data type in a 64-bit environment, WinHandle become a Int64.

Some where down the codes in the Sub, and in a 64-bit environment:

[quote]Declare Function SetWindowLongPtr lib “user32” (ByVal hWnd as Integer,ByVal nIndex as integer, _
ByVal dwNewLong as Ptr) as Integer
MsgBox "1: "+str(WinHandle)[/quote]

Then WinHandle (an Int64) is passed into SetWindowLongPtr which requires an Int32:

[quote]lpPrevWndProc=SetWindowLongPtr(WinHandle,-4,p)
MsgBox "2: "+str(lpPrevWndProc)
[/quote]
Is this why Msgbox “2: …” does not show up?

nIndex needs to be Int32, not Integer which compiles to Int64 in 64bit-compiles:

Declare Function SetWindowLongPtr Lib "user32" Alias "SetWindowLongA" _ (ByVal hWnd as Integer, ByVal nIndex as Int32, ByVal dwNewLong as Ptr) as Integer

Original post deleted.

I read MS docs again and I think I may be wrong on this so I delete this post. There seems some confusion on Declares for 32-bit and 64-bit Windows.