1. Miguel Leeuwe
  2. PowerBuilder
  3. Monday, 24 January 2022 18:37 PM UTC

Not too long ago Appeon has updated the documentation / help to now state correctly that the Handle() function returns a Longptr value.

I see a lot of use of the function in the PFCs. We use Ulong for window handles (while the type of a handles and pointers are signed, as I've been told) and also Long variables.
Thinking of 64 bit compilation, could we run into problems and should we change all of the types to longptr where appropiate?

Another question I have, is whether we should be replacing "Get- and SetWindowLong(W)" calls to "Get- and SetWindowLongPtr", (excluding the "W", since compilationg would automatically take care of calling the correct function on 32 bit and 64): https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setwindowlongptrw


I know this would be a hell of a job, it'll probably be a bit over my head to do this alone, and it would require a lot of testing.

Any ideas on how to tackle this or do you think we can safely run 64 bit executables without running into any problems?

regards,

MiguelL

Accepted Answer
Miguel Leeuwe Accepted Answer Pending Moderation
  1. Tuesday, 25 January 2022 16:09 PM UTC
  2. PowerBuilder
  3. # Permalink

Hi all, Bruce, John, Benjamin, Mark and Chris. I'm marking this as resolved. It's become clear we have to keep using Get- and SetWindowLongW/A in powerbuilder. (and that we have to use either ulong or preferably longptr variables for the windows handles).

Thank you all for your great information!

regards.

Comment
There are no comments made yet.
Chris Pollach @Appeon Accepted Answer Pending Moderation
  1. Monday, 24 January 2022 19:55 PM UTC
  2. PowerBuilder
  3. # 1

Hi Miguel;

   Interesting ... I have been thinking of changing all my uLong object pointers to LongPtr as well in my STD framework for a while now. Just haven't had the time to test this but it holds well in theory. Easy for me to implement though all SDK calls made by the framework are performed through one object - the "App Controller".

Regards ... Chris

Comment
  1. Miguel Leeuwe
  2. Tuesday, 25 January 2022 12:23 PM UTC
Hi Chris,

Do you think in that case that we should also replace GetWindowLong(A or W) with the GetWindowLongPtr(A or W) external function?

regards
  1. Helpful
  1. Chris Pollach @Appeon
  2. Tuesday, 25 January 2022 15:47 PM UTC
No idea at the moment but I did note that API for future consideration.
  1. Helpful
There are no comments made yet.
John Fauss Accepted Answer Pending Moderation
  1. Monday, 24 January 2022 20:29 PM UTC
  2. PowerBuilder
  3. # 2

You raise several points on which I would like to comment, Miguel:

Thinking of 64 bit compilation, could we run into problems and should we change all of the types to longptr where appropiate?

Yes, one can run into problems and yes, the code in the PFC should be updated.

Although Windows handles are 64 bits in a 64-bit process, I've yet to see the value of a handle in a 64-bit process that would not fit in a 32-bit PB Long/ULong variable... the upper four bytes have always been zero, to date. However, there is NO guarantee this will always be true. As soon as Windows assigns a value for a handle that exceeds 32-bits in length, the current code in the PFC likely fails.

It isn't just API function values that contain handles. If a structure contains a handle, that structure member needs to be of type Longptr as well. In some cases where the structure also contains a member that specifies the in-memory length/size of the structure, the structure size increases when the process is 64-bit. This can be due to Long/ULong -> Longptr, but also to structure member padding influences.

As for the second issue you raised regarding the use of SetWindowLongPtr (and GetWindowLongPtr), one needs to keep in mind how this equivalency is implemented in C/C++. It is done via #define:

#define SetWindowLongPtr    SetWindowLong
#define GetWindowLongPtr    GetWindowLong

and 

#define SetWindowLong    SetWindowLongW
//  or
#define SetWindowLong    SetWindowLongA

// depending on whether the code is compiled for Unicode or ANSI.

I suspect there is no actual DLL entry point named "SetWindowLongPtr", just as there is no entry point named SetWindowLong. Because this particular API interacts with character/string information, there are ANSI and Unicode functions:

SetWindowLongW (Unicode)
SetWindowLongA (ANSI)

The PB compiler will not resolve the external function name SetWindowLongPtr as does a C/C++ compiler. An ALIAS FOR clause in the PB external function declaration is required if the actual DLL entry point name is not used as the name of the external function, in order for the correct entry point can be called at execution time.

Comment
  1. Miguel Leeuwe
  2. Tuesday, 25 January 2022 11:23 AM UTC
Hi John,

Okay that makes sense, so I'd have to add the W and A variants for the function to the pfc's platform object. This is something I'll do in my local pfe classes and try it out for some time before migrating that into the pfc classes.

regards.
  1. Helpful
  1. Miguel Leeuwe
  2. Tuesday, 25 January 2022 11:28 AM UTC
One last thing:

I do think that the Get- and SetWindowLongPtrA and -W exist. Maybe it's a typo you made?

Also ... should be replace Get- and SetWindowLongA and -W with the Get- and SetWindowLongPtrA and -W?

regards
  1. Helpful
  1. Bruce Armstrong
  2. Tuesday, 25 January 2022 14:37 PM UTC
As John indicated, GetWindowLongPtr is not a function, it's a C++ macro. Unless you're using C++ to write your code, there's no C++ complier to convert that into the proper call. We should continue to use SetWindowLongW
  1. Helpful 1
There are no comments made yet.
Bruce Armstrong Accepted Answer Pending Moderation
  1. Monday, 24 January 2022 20:34 PM UTC
  2. PowerBuilder
  3. # 3

>>Thinking of 64 bit compilation, could we run into problems and should we change all of the types to longptr where appropiate?

I've got two PFC based applications running in 64 bit mode.  I had to modify a number of API calls, but I didn't do anything with any Handle calls and they're working fine.

I've done a search of the PFC code and I'm only finding a couple of instances where the Handle function is used.  One is in the multiplatform server where it evaluates the size of a text field and the other is in the drag/drop logic for the treeview control.  Nether are functions my app uses.  I don't see other usages than that.  I see a lot of use of the word "handle" in comments (e.g., "this function handles .....").  But only those limited uses of the actual function.

>>Another question I have, is whether we should be replacing "Get- and SetWindowLong(W)" calls to "Get- and SetWindowLongPtr", (excluding the
>>"W", since compilationg would automatically take care of calling the correct function on 32 bit and 64): https://docs.microsoft.com/en-
>>us/windows/win32/api/winuser/nf-winuser-setwindowlongptrw

That reference to it being handled automatically at compilation is referencing C++ project.  We can't depend on that in PowerBuilder API external function delcarations.

Comment
  1. Miguel Leeuwe
  2. Tuesday, 25 January 2022 11:29 AM UTC
I might have overestimated the amount of occurrences of the use of Handle() in the pfcs, so I'll have a closer look. Anyway, if all use a uLong datatype, we should be on the safe side. My only doubt is if we should use Get- and SetWindowLongPTR(A/W) instead of the version without "ptr".
  1. Helpful
There are no comments made yet.
Benjamin Gaesslein Accepted Answer Pending Moderation
  1. Tuesday, 25 January 2022 10:20 AM UTC
  2. PowerBuilder
  3. # 4

Windows always uses 32 bit handles so 64 and 32-bit applications can share them. This is unlikely to change, according to Microsoft docs:

https://docs.microsoft.com/en-us/windows/win32/winprog64/interprocess-communication

64-bit versions of Windows use 32-bit handles for interoperability. When sharing a handle between 32-bit and 64-bit applications, only the lower 32 bits are significant, so it is safe to truncate the handle (when passing it from 64-bit to 32-bit) or sign-extend the handle (when passing it from 32-bit to 64-bit). Handles that can be shared include handles to user objects such as windows (HWND), handles to GDI objects such as pens and brushes (HBRUSH and HPEN), and handles to named objects such as mutexes, semaphores, and file handles.

Comment
  1. Miguel Leeuwe
  2. Tuesday, 25 January 2022 16:07 PM UTC
Then again ... For example you say we should use setWindowLongPtr and John and Bruce say it doesn't exist in Powerbuilder-land.

" Bruce Armstrong

Bruce Armstrong Tuesday, 25 January 2022 14:37 PM UTC Accept as Answer

As John indicated, GetWindowLongPtr is not a function, it's a C++ macro. Unless you're using C++ to write your code, there's no C++ complier to convert that into the proper call. We should continue to use SetWindowLongW "



I guess I'll stick to NOT trying to use that function.

:)
  1. Helpful
  1. Benjamin Gaesslein
  2. Wednesday, 26 January 2022 07:13 AM UTC
Yeah, it seems like the ...Ptr functions do not exist in the 32 bit user32.dll, indeed. So in order to use them, one would have to ensure the bitness of the application first and then either call GetWindowLongPtr or GetWindowLong accordingly.
  1. Helpful 1
  1. Miguel Leeuwe
  2. Wednesday, 26 January 2022 07:30 AM UTC
yes, it's a shame not ALL functions exist in both of the user32.dll libraries. Anyway, I've got that working already. it's not that hard to accomplish by using a method such as the one described by Chris. Maybe even easier would be to simply define a function "of_GetWindowLong" in your application manager. That function does the check you mention on bitness and calls one or the other. The only thing is that you'd have to replace all of your GetWindowLong calls with that function, but in my experience, there's not that many in an application.
  1. Helpful
There are no comments made yet.
Miguel Leeuwe Accepted Answer Pending Moderation
  1. Tuesday, 25 January 2022 11:34 AM UTC
  2. PowerBuilder
  3. # 5

Finally I'd like to mention bugs (now solved?) like this one: https://www.appeon.com/standardsupport/search/view?id=3736 where Rudolf has done all the work for Appeon and what kind of makes me even more reluctant to use the datatype (apart from my own obvious lack of understanding).

happy coding!

Comment
There are no comments made yet.
Miguel Leeuwe Accepted Answer Pending Moderation
  1. Tuesday, 25 January 2022 12:22 PM UTC
  2. PowerBuilder
  3. # 6

I've had a better look at the pfc classes and this is what I found:

 ---------- Search: Searching Library D:\_GitHub\PB\2021-master\pfcwnsrv\pfcwnsrv.pbl for 'handle('    (11:56:59)
 ---------- 12 Matches Found On "handle(":
NEEDS CHANGE: pfcwnsrv.pbl(pfc_n_cst_winsrv_style).of_clientsize.0049:   of_ClientSize(Handle(iw_requestor), rl_Width, rl_Height)
NEEDS CHANGE: pfcwnsrv.pbl(pfc_n_cst_winsrv_style).of_describe.0048:   of_describe(Handle(iw_requestor), rs_style[])
NEEDS CHANGE: pfcwnsrv.pbl(pfc_n_cst_winsrv_style).of_describe.0044:  of_describe(Handle(vw_describe), rs_style[])
NEEDS CHANGE: pfcwnsrv.pbl(pfc_n_cst_winsrv_style).of_style.0043:  of_style(Handle(vw_style), vul_style, vb_style)
			ALSO USES GET- AND SETWINDOWLONG INSTEAD OF THE "...PTR" VARIANT OF THE FUNCTION.
NEEDS CHANGE: pfcwnsrv.pbl(pfc_n_cst_winsrv_style).of_style.0046:   of_style(Handle(iw_requestor), vul_style, vb_style)
NEEDS CHANGE: pfcwnsrv.pbl(pfc_n_cst_winsrv_style).of_style_extended.0047:   of_style_Extended(Handle(iw_requestor), vul_styleExtended, vb_styleExtended)
NEEDS CHANGE: pfcwnsrv.pbl(pfc_n_cst_winsrv_style).of_style_extended.0044:  of_style_Extended(Handle(vw_styleExtended), vul_styleExtended, vb_styleExtended)
NEEDS CHANGE: pfcwnsrv.pbl(pfc_n_cst_winsrv_style).of_clientsize.0046:   of_clientSize(Handle(vw_clientSize), rl_width, rl_height)
NEEDS CHANGE: pfcwnsrv.pbl(pfc_n_cst_winsrv_style).of_isstyle_extended.0048:   lb_isStyleExtended = of_isStyle_Extended(Handle(vw_isStyleExtended), vul_StyleExtended)
NEEDS CHANGE: pfcwnsrv.pbl(pfc_n_cst_winsrv_style).of_isstyle_extended.0051:   lb_isStyleExtended  = of_isStyle_Extended(Handle(iw_requestor), vul_styleExtended)
NEEDS CHANGE: pfcwnsrv.pbl(pfc_n_cst_winsrv_style).of_isstyle.0049:   lb_isStyle     = of_isStyle(Handle(iw_requestor), vul_style)
NEEDS CHANGE: pfcwnsrv.pbl(pfc_n_cst_winsrv_style).of_isstyle.0047:   lb_isStyle    = of_isStyle(Handle(vw_isStyle), vul_Style)
 ---------- Done 12 Matches Found On "handle(":
 ---------- Finished Searching Library D:\_GitHub\PB\2021-master\pfcwnsrv\pfcwnsrv.pbl for 'handle('    (11:56:59)

 ---------- Search: Searching Library D:\_GitHub\PB\2021-master\pfcmain\pfcmain.pbl for 'handle('    (11:58:22)
 ---------- 2 Matches Found On "handle(":
NEEDS CHANGE: pfcmain.pbl(pfc_w_response)pfc_preopen.0046:   lul_hWnd      = Handle(this)
 ---------- Done 2 Matches Found On "handle(":
 ---------- Finished Searching Library D:\_GitHub\PB\2021-master\pfcmain\pfcmain.pbl for 'handle('    (11:58:22)

 ---------- Search: Searching Library D:\_GitHub\PB\2021-master\pfcapsrv\pfcapsrv.pbl for 'handle('    (11:58:52)
 ---------- 8 Matches Found On "handle(":
// What about the CloseHandle() API which also expects a handle parameter?: pfcapsrv.pbl(pfc_n_cst_filesrvunicode).of_setlastwritedatetime.0063:  CloseHandle(ll_handle)
// What about the CloseHandle() API which also expects a handle parameter?: pfcapsrv.pbl(pfc_n_cst_filesrvunicode).of_setcreationdatetime.0063:  CloseHandle(ll_handle)
// What about the CloseHandle() API which also expects a handle parameter?: pfcapsrv.pbl(pfc_n_cst_filesrvunicode).of_setlastaccessdate.0055:  CloseHandle(ll_handle)
NEEDS CHANGE: pfcapsrv.pbl(pfc_n_cst_platformunicode).of_GetTextSize.0070:   lul_Handle = Handle(lst_Temp)
// HAS NOTHING TO DO WITH HANDLE(): pfcapsrv.pbl(pfc_n_cst_tvsrv_levelsource)pfc_refreshlevel.0061:   ll_handle = this.of_GetHandle(lds_source, ll_row, ai_level)
// HAS NOTHING TO DO WITH HANDLE(): pfcapsrv.pbl(pfc_n_cst_tvsrv_levelsource).of_gethandle.0063:  Return of_GetHandle(ads_obj, al_row, li_level)
 ---------- Done 8 Matches Found On "handle(":
 ---------- Finished Searching Library D:\_GitHub\PB\2021-master\pfcapsrv\pfcapsrv.pbl for 'handle('    (11:58:52)

Depending on the conclusions we come to, we might want to change this.

One thing has to be said though: since (almost?) all seem to be using uLong datatype for the arguments to functions, we might get away with it.

For now I'm not going to change anything, maybe a better strategy is to just wait until things stop working and then fix those?

regards,

MiguelL

Comment
There are no comments made yet.
John Fauss Accepted Answer Pending Moderation
  1. Tuesday, 25 January 2022 15:34 PM UTC
  2. PowerBuilder
  3. # 7

My first recommendation is to avoid making changes to Windows API calls in the PFC unless you have confidence in what you are changing.

Thank you, Bruce, for reiterating what I stated earlier: There is no DLL entry point named Get/SetWindowLongPtr, Get/SetWindowLongPtrA, or Get/SetWindowLongPtrW. Through C++ sleight-of-hand, these resolve to either Get/SetWindowLongA or Get/SetWindowLongW.

As a test, here is an example erroneous PB external function declaration:

FUNCTION Longptr GetWindowLong ( &
   Longptr hWnd, &
   Long    nIndex &
   ) LIBRARY "user32.dll" ALIAS FOR "GetWindowLongPtrW"

PB will attempt to invoke a function named GetWindowLongPtrW in user32.dll. The result is:

By changing the name in the ALIAS FOR clause to "GetWindowLongW", the external function can be called successfully.

When reading Windows API documentation, you have to keep in mind the material is written for C/C++ developers. For whatever reason(s), Microsoft does some mighty funky things with #define statements in the myriad of WinAPI-related header files, such as winuser.h.

One last comment: I very much appreciate Benjamin's post that clarifies the internal use of 32-bit and 64-bit handles. This confirms what I have observed in practice. Although it appears that continued use of PB ULong's/Long's for Windows handles should work properly, I strongly feel the Longptr datatype should be used, for two reasons:

1. Windows handles in API structures need to be Longptr. If Windows is expecting a 64-bit integer as a structure member and you use a 32-bit integer, this can/will affect the location of other structure members.

2. Many developers look to the PFC as an example on how to properly code things. Therefore, the PFC should be code using best practices. While using Long's/ULong's might work for now and in the foreseeable future, doing so is NOT technically corrrect... Values that hold Windows handles should be defined as Longptr. This is essentially how they are defined in the Windows API. For example, "HWND" is a type definition that translates to "HANDLE":

typedef HANDLE HWND;

and "HANDLE" is itself a type definition that translates to "PVOID":

typedef PVOID HANDLE;

and PVOID is (surprise!) itself a type definition that translates as a pointer to void:

typedef void *PVOID;

So handles to windows and other kinds of handles within Windows all resolve to a pointer to void... which is a 32-bit integer in a 32-bit process or a 64-bit integer in a 64-bit process... in other words, a PB Longptr.

Windows handles in the PFC (and elsewhere) should be defined as Longptr in PB.

Source: https://docs.microsoft.com/en-us/windows/win32/winprog/windows-data-types

 

 

Comment
  1. Mark Goldsmith
  2. Tuesday, 25 January 2022 21:44 PM UTC
Thanks John for the follow-up. While I can't dispute what's included in the winuser.h header file, I'm thinking as far as entry point names are concerned (EG GetWindowLongPtrA and GetWindowLongPtrW) this may not be quite correct, unless something else is going on I'm not aware of. Seems also to suggest otherwise here, https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getwindowlongptra, unless that too is part of the skullduggery or I'm misreading it, lol.



As I'm sure you're aware, there are two versions of user32.dll, one located in SysWOW64 for 32 bit applications and one located in System32 for 64 bit applications (on a 64 bit Windows OS). The former does NOT have these entry points and so a 32 bit compiled app making these API calls will fail, as you've shown in your example. However, these don't fail for a 64 bit compiled app and so these entry points appear to exist in the 64 bit version of user32.dll and can be seen with a DLL viewer (or maybe they are succeeding for a different reason or more skullduggery). Certainly would be easier to test with a 64 bit PB IDE but you'll find if you compile a 64 bit app those external function calls no longer fail. Actually, even the Get/SetWindowLongA and Get/SetWindowLongW functions will still work with a 64 bit app as these are also included in the 64 bit user32.dll.



So, there certainly could be something going on in the C/ C++ development environment which would lead one to believe these entry points do not exist. However, as a Windows API call they do work from PowerBuilder when used in a 64 bit compiled app without generating an error....very curious.
  1. Helpful 1
  1. John Fauss
  2. Wednesday, 26 January 2022 02:39 AM UTC
Mark,, I always appreciate your insights and input! I verified that yes, you can successfully use an external function declaration in 64-bit for API function GetWindowLongPtrW. Like you, what I do not understand is WHY that works. Using DLL Explorer from NirSoft, I examined the list of entry points in the user32.dll from both the System32 (the 64-bit) folder and the SysWOW64 (the 32-bit) folder. Of the functions in question, only the entry points for GetWindowLongA, GetWindowLongW, SetWindowLongA and SetWindowLongW in both user32.dll's are defined... No xxxWindowLongPtrx functions are listed.



What allows the 64-bit call to GetWindowLongPtrW to work? I don't know. Why does it work in 64-bit and not in 32-bit? I don't know. What I do know is that by calling these four functions (GetWindowLongA, GetWindowLongW, SetWindowLongA and SetWindowLongW) from PB in either 32-bit or 64-bit using the proper datatype works.
  1. Helpful 2
  1. Mark Goldsmith
  2. Wednesday, 26 January 2022 02:59 AM UTC
I agree that it's a bit odd based upon what you've also shared as to why it does in fact work in 64 bit. Since we can't post pictures in comments I'm going to post a reply with an image of how I saw, what would seem to be, the existence of the entry points. Believe me, I'm still not convinced myself, especially when it comes to Microsoft, that it is as it appears to be but that's what led me to want to attempt to create the 64 bit app to test.

Thanks again John, really appreciate the observations you add to any discussion! BTW, the other piece of the discussion was around the use of the Longptr datatype and I too agree that's what should be used versus ULong and Long.
  1. Helpful 1
There are no comments made yet.
Chris Pollach @Appeon Accepted Answer Pending Moderation
  1. Tuesday, 25 January 2022 18:44 PM UTC
  2. PowerBuilder
  3. # 8

Hi Miguel;

   FYI: there are also other considerations when running a PB App in 64bit mode. For example ....

FUNCTION Long SHBrowseForFolder ( sr_BROWSEINFO64 lpBrowseInfo64 )   LIBRARY "SHELL32.dll"ALIAS FOR "SHBrowseForFolderW"
FUNCTION Int   SetForegroundWindow ( LongLong  hwnd ) LIBRARY "user32.dll"

   In the above examples, I had to create a 64bit compliant structure and instead of a LongPTR, I had to use a LongLong.

   I refactored the STD Framework though starting in PB 12.6 to extend the 32bit App Controller into a 64bit descendant. Then the framework instantiates the correct bitness controller. As the framework starts up it finds out if the App and O/S are truly running in 64bit mode vs 32bit. The 64bit controller (like the PFC App Manager) handles all SDK calls. So the 64bit version just needs to remap some of the SDK calls where required. If the developer knows from the start that there App will only be 64bit - then they can create their App Controller from inheriting for the "nc_app_controller64_master" right up front.

Regards ... Chris

 

 

Comment
  1. Miguel Leeuwe
  2. Tuesday, 25 January 2022 18:52 PM UTC
Thanks Chris,

That looks like a useful resource on how to declare our external functions! So when do you have to use LongLong ? (I feel like I've opened Pandora's box with this Q&A)

:)

  1. Helpful
  1. Chris Pollach @Appeon
  2. Tuesday, 25 January 2022 19:43 PM UTC
Yes, I think that we may have a little bit of Pandora working with us on this one ... LOL

I am not sure why I chose LongLong vs LongPTR. I will go back now and see if LongPTR works OK. That would be a more consistent implementation.
  1. Helpful 2
  1. Miguel Leeuwe
  2. Tuesday, 25 January 2022 21:06 PM UTC
:)
  1. Helpful
There are no comments made yet.
Mark Goldsmith Accepted Answer Pending Moderation
  1. Wednesday, 26 January 2022 03:35 AM UTC
  2. PowerBuilder
  3. # 9

Per my last post, here is where the entry points in question seem to be available:

Regards,

Mark

Comment
  1. Miguel Leeuwe
  2. Wednesday, 26 January 2022 05:53 AM UTC
Thank you Mark, I really appreciate your input!

So it turns out that MOST API functions are defined in both the 32 and 64 bit versions, but ... NOT ALL. I find that some MS BS. Why not make our lives easier. MS does seem to advertise to use the ptr variants of the function.

These guys seem to have a similar discussion: https://github.com/microsoft/win32metadata/issues/142

regards
  1. Helpful
  1. Mark Goldsmith
  2. Wednesday, 26 January 2022 13:16 PM UTC
You're welcome Miguel and thanks for that link...adds some additional context and clearly others have been caught off guard by the differences between the DLL versions.
  1. Helpful 1
There are no comments made yet.
Miguel Leeuwe Accepted Answer Pending Moderation
  1. Wednesday, 26 January 2022 07:41 AM UTC
  2. PowerBuilder
  3. # 10

BTW, the PB help says this (just search on "64"):

... longptr is not a full-fledged PowerBuilder datatype. You can use it to hold/pass window handles, database handles, and other objects that are essentially memory addresses. Doing complex operations on longptr type might not work. If you want to represent/compute 8-byte long integers, use longlong....

If you search on "Dbhandle" in the PB help, you'll see 2 entries listed. One for "odbc" and another for "powerscript". I don't really see how the one for 'odbc' would be a different function than the one for 'powerscript'. One states that the function returns a LONG and the other states it returns an Ulong.

What should it be: long, ulong or longptr ?

Is there a way to find out what it really returns (other than by creating a support ticket)?

regards,

MiguelL

Comment
  1. Miguel Leeuwe
  2. Wednesday, 26 January 2022 12:22 PM UTC
In the end, I've created a ticket to find an answer on this question as this post has become waaaay too long.

https://www.appeon.com/standardsupport/track/view?id=7849
  1. Helpful
  1. Mark Goldsmith
  2. Wednesday, 26 January 2022 13:26 PM UTC
Yes I recall seeing that in the Help before and it's interesting given Microsoft's similar comments on its LongPtr data type:

" Note

LongPtr is not a true data type because it transforms to a Long in 32-bit environments, or a LongLong in 64-bit environments. LongPtr should be used to represent pointer and handle values in Declare statements and enables writing portable code that can run in both 32-bit and 64-bit environments."
  1. Helpful 1
There are no comments made yet.
John Fauss Accepted Answer Pending Moderation
  1. Wednesday, 26 January 2022 19:30 PM UTC
  2. PowerBuilder
  3. # 11

I'm reasonably sure that by now most everyone has grown weary of this thread - BUT... there was an interesting side issue left unresolved: Why do the Get/SetWindowLongPtrX API functions work from called from a 64-bit PB app and not from a 32-bit app? I now have the answer!

It appears the "DLL Explorer" utility published by NirSoft that I found/used has an issue or two (or more). Today I found an alternative utility named DUMPBIN that is supplied as a Visual Studio command line utility. Using it, I see now that indeed, the 64-bit version of user32.dll contains entry points that are missing from the 32-bit version. Shown below is what DUMPBIN reports for the entry points whose names begin with "GetWindowLong". The first command reports on the 64-bit version of user32.dll that resides in the C:\Windows\System32 folder and the second command reports on the 32-bit version of user32.dll that resides in the C:\Windows\SysWOW64 folder.

This explains why the external function declaration for the Get/SetWindowLongPtrX API functions work successfully in 64-bit and fail in 32-bit.

It is a tad disconcerting, however, to find this sort of difference between the 32-bit and 64-bit implementation of Windows.

Comment
  1. Miguel Leeuwe
  2. Wednesday, 26 January 2022 19:48 PM UTC
Hi, well it was "kinda" explained where I said: (if you check the link below, there's a discussion on this exact same topic):

"

Miguel Leeuwe Wednesday, 26 January 2022 05:53 AM UTC

So it turns out that MOST API functions are defined in both the 32 and 64 bit versions, but ... NOT ALL. I find that some MS BS. Why not make our lives easier. MS DOES seem to advertise to use the ptr variants of the function.

These guys seem to have a similar discussion: https://github.com/microsoft/win32metadata/issues/142

"

Thanks for pointing out the nirsoft tool problem, "these guys" also use DumpBin.

regards
  1. Helpful
There are no comments made yet.
  • Page :
  • 1


There are no replies made for this question yet.
However, you are not allowed to reply to this question.