View Issue Details

IDProjectCategoryView StatusLast Update
0019439LazarusWidgetsetpublic2012-03-16 11:07
ReporterEdinAssigned ToVincent Snijders 
PrioritynormalSeveritymajorReproducibilityalways
Status resolvedResolutionfixed 
Product VersionProduct Build 
Target VersionFixed in Version0.9.31 (SVN) 
Summary0019439: Updates needed For Win64 bit
DescriptionWinows widgetset needs updating so that there aren't errors on Win64.

New in win64 bit are calls with extension "Ptr" like SetWindowLongPtr.
I discovered this when my dialog displayed an icon.
http://bugs.freepascal.org/view.php?id=19321
When calling something like SetClassLong the function fails without reporting and error!
When I call SetClassLongPtr it works.

I've browsed the Lazarus source and found many that need replacing.
Please update following

GetClassLong -> GetClassLongPtr
SetClassLong -> SetClassLongPtr

GetWindowLong -> GetWindowLongPtr
SetWindowLong -> SetWindowLongPtr

I see that some aren't even defined in winapih.inc.

This is from http://msdn.microsoft.com/en-us/library/ms633589%28v=VS.85%29.aspx
"Note To write code that is compatible with both 32-bit and 64-bit Windows,
use SetClassLongPtr. When compiling for 32-bit Windows, SetClassLongPtr is
defined as a call to the SetClassLong function"
TagsNo tags attached.
Fixed in Revision36074
LazTarget-
WidgetsetWin32/Win64
Attached Files

Relationships

related to 0019321 resolvedVincent Snijders bsDialog Form shows Icon 

Activities

Juha Manninen

2011-06-03 22:59

developer   ~0048800

Could you please provide a patch.

Edin

2011-06-04 04:28

reporter   ~0048806

Sorry don't know how to do that.
However i did search the code and this is what bothered me in my app, at least I think so.

\lcl\interfaces\win32\win32object.inc:450: SetClassLong(FAppHandle, GCL_HICONSM, LONG(Small));
\lcl\interfaces\win32\win32object.inc:453: SetClassLong(FAppHandle, GCL_HICON, LONG(Big));
\lcl\interfaces\win32\win32wsforms.pp:624: SetClassLong(Wnd, GCL_HICONSM, LONG(Small));
\lcl\interfaces\win32\win32wsforms.pp:627: SetClassLong(Wnd, GCL_HICON, LONG(Big));

There are however well over 100 places in the code that use 32bit calls.
Maybe this is something that needs to be done in a compiler.
The compiler for 64bit could redirect SetWindowLong -> SetWindowLongPtr.

I'm not an expert so I leave the solutions to you developers, but I'm just raising a red flag here and warning for potential problems.
Just for the record in case no one noticed this before.

Edin

2011-06-04 04:39

reporter   ~0048807

Last edited: 2011-06-04 04:40

In \lcl\interfaces\win32\win32debug.pp:155:
I found this:

{$ifdef CPU64}
  SetWindowLongPtr(window, GWL_USERDATA, PtrInt(AInfo));
{$else}
  SetWindowLong(window, GWL_USERDATA, PtrInt(AInfo));
{$endif}

Now that's the right way I guess, but I can't find many of those.
So updating is probably needed.

Vincent Snijders

2011-06-04 08:11

manager   ~0048809

Note that most of the time TWin32WidgetSet.SetWindowLong is used, which calls Windows.SetWindowLongPtr on win64. Only if the function from the windows unit is called directly, you must use the ifdef.

Juha Manninen

2011-06-04 08:15

developer   ~0048810

As your quote from msdn page says:
"Note To write code that is compatible with both 32-bit and 64-bit Windows,
use SetClassLongPtr. When compiling for 32-bit Windows, SetClassLongPtr is
defined as a call to the SetClassLong function"

It means the above {$ifdef CPU64} is useless and SetWindowLongPtr could be used always. Maybe it must be defined in binding libs for 32-bit Windows. (?)
Then, it could be easily fixed with a simple search/replace in all sources.

What means:
"I see that some aren't even defined in winapih.inc." ?

Edin

2011-06-04 15:58

reporter   ~0048824

ok so I see that in the win32winapih.inc
there's an override of the windows functions
function SetWindowLong(Handle: HWND; Idx: Integer; NewLong: PtrInt): PtrInt; override;
function GetWindowLong(Handle: HWND; Int: Integer): PtrInt; override;
and later there's a redirection in TWin32WidgetSet.SetWindowLong and Get...
Good. That takes care of those two.

Left are SetClassLong and GetClassLong.
Those aren't defined in win32winapih.inc to be overridden
or redirected in TWin32WidgetSet, but are called here:

procedure TWin32WidgetSet.AppSetIcon(const Small, Big: HICON);
class function TWin32WSCustomCalendar.CreateHandle(const AWinControl: TWinControl;
class procedure TWin32WSCustomForm.SetIcon(const AForm: TCustomForm; const Small, Big: HICON);

There are couple of them in each procedure.
I suggest you either update those procedures or define and override them like windowlong procedures. I guess updating is easier.

Ludo Brands

2011-06-04 16:51

developer   ~0048832

The windows unit uses ascfun.inc and unifun.inc. There you'll find (ascfun.inc):

{$ifdef cpu64}
function GetWindowLongPtrA(hWnd:HWND; nIndex:longint):LONG_PTR; external 'user32' name 'GetWindowLongPtrA';
function SetWindowLongPtrA(hWnd:HWND; nIndex:longint; dwNewLong:LONG_PTR):LONG_PTR; external 'user32' name 'SetWindowLongPtrA';
function GetClassLongPtrA(hWnd:HWND; nIndex:longint):LONG_PTR; external 'user32' name 'GetClassLongPtrA';
function SetClassLongPtrA(hWnd:HWND; nIndex:longint; dwNewLong:LONG_PTR):LONG_PTR; external 'user32' name 'SetClassLongPtrA';
{$else}
function GetWindowLongPtrA(hWnd:HWND; nIndex:longint):LONG_PTR; external 'user32' name 'GetWindowLongA';
function SetWindowLongPtrA(hWnd:HWND; nIndex:longint; dwNewLong:LONG_PTR):LONG_PTR; external 'user32' name 'SetWindowLongA';
function GetClassLongPtrA(hWnd:HWND; nIndex:longint):LONG_PTR; external 'user32' name 'GetClassLongA';
function SetClassLongPtrA(hWnd:HWND; nIndex:longint; dwNewLong:LONG_PTR):LONG_PTR; external 'user32' name 'SetClassLongA';
{$endif}

So you can use the Ptr versions everywhere.

Issue History

Date Modified Username Field Change
2011-05-28 18:06 Edin New Issue
2011-05-28 18:06 Edin Widgetset => Win32/Win64
2011-06-03 22:59 Juha Manninen LazTarget => -
2011-06-03 22:59 Juha Manninen Note Added: 0048800
2011-06-03 22:59 Juha Manninen Status new => feedback
2011-06-04 04:28 Edin Note Added: 0048806
2011-06-04 04:39 Edin Note Added: 0048807
2011-06-04 04:40 Edin Note Edited: 0048807
2011-06-04 08:11 Vincent Snijders Note Added: 0048809
2011-06-04 08:15 Juha Manninen Note Added: 0048810
2011-06-04 15:58 Edin Note Added: 0048824
2011-06-04 16:51 Ludo Brands Note Added: 0048832
2012-03-13 11:55 Vincent Snijders Relationship added related to 0019321
2012-03-13 11:56 Vincent Snijders Status feedback => acknowledged
2012-03-16 11:07 Vincent Snijders Fixed in Revision => 36074
2012-03-16 11:07 Vincent Snijders Status acknowledged => resolved
2012-03-16 11:07 Vincent Snijders Fixed in Version => 0.9.31 (SVN)
2012-03-16 11:07 Vincent Snijders Resolution open => fixed
2012-03-16 11:07 Vincent Snijders Assigned To => Vincent Snijders