Delphi XE2. 64-bit. RBuilder 14.03 EAccessViolation in menu pop-up painting
Hello everybody,
I tried to use RB 14.03 in a Delphi XE2 64-bit program. I have found the
following issue. Attempt to open a top menu item in the report designer
raises the EAccessViolation exception in ppTBX.pas
procedure TBXPopupNCPaintProc(Wnd: HWND; DC: HDC; AppData: Longint);
var
R, R2: TRect;
Canvas: TCanvas;
View: TppTBPopupView;
PopupInfo: TppTBXPopupInfo;
ParentViewer: TppTBItemViewer;
begin
Assert(DC <> 0, 'TBXPopupNCPaintProc');
Canvas := TCanvas.Create;
try
Canvas.Handle := DC;
FillChar(PopupInfo, SizeOf(PopupInfo), 0);
View := TppTBPopupView(AppData); // !!!! THE BEGINNING OF THE FAILURE
!!!!
PopupInfo.WindowHandle := View.Window.Handle; /// !!! EAccessViolation
!!!!
......
end;
There is the following declaration in ppTB2Common.
THandleWMPrintNCPaintProc = procedure(Wnd: HWND; DC: HDC; AppData: Longint);
It is called in the following style:
procedure TppTBXPopupWindow.WMNCPaint(var Message: TMessage);
var
DC: HDC;
begin
DC := GetWindowDC(Handle);
try
Assert(DC <> 0, 'TppTBXPopupWindow.WMNCPaint');
SelectNCUpdateRgn(Handle, DC, HRGN(Message.WParam));
TBXPopupNCPaintProc(Handle, DC, NativeInt(Self.View)); // !!! DATA
CORRUPTION !!!
finally
ReleaseDC(Handle, DC);
end;
end;
There are five to ten similar procedures declared according to this
prototype and scattered across the sources. They are called by various
painting methods. The problem is that a TObject value is always passed as
the AppData parameter. The value is converted explicitly into a LongInt
compatible value (and here corruption happens) and inside of the procedure
it is converted back already corrupted. The solution is to change the data
type of the AppData parameter to TObject and do not do any conversions. The
correct function will look like the one below:
THandleWMPrintNCPaintProc = procedure(Wnd: HWND; DC: HDC; AppData: TObject);
procedure TppTBXPopupWindow.WMNCPaint(var Message: TMessage);
...
begin
...
TBXPopupNCPaintProc(Handle, DC, View); // !!! NO DATA CORRUPTION !!!
...
end;
procedure TBXPopupNCPaintProc(Wnd: HWND; DC: HDC; AppData: TObject);
...
begin
...
View := AppData as TppTBPopupView;
...
end;
I tried to use RB 14.03 in a Delphi XE2 64-bit program. I have found the
following issue. Attempt to open a top menu item in the report designer
raises the EAccessViolation exception in ppTBX.pas
procedure TBXPopupNCPaintProc(Wnd: HWND; DC: HDC; AppData: Longint);
var
R, R2: TRect;
Canvas: TCanvas;
View: TppTBPopupView;
PopupInfo: TppTBXPopupInfo;
ParentViewer: TppTBItemViewer;
begin
Assert(DC <> 0, 'TBXPopupNCPaintProc');
Canvas := TCanvas.Create;
try
Canvas.Handle := DC;
FillChar(PopupInfo, SizeOf(PopupInfo), 0);
View := TppTBPopupView(AppData); // !!!! THE BEGINNING OF THE FAILURE
!!!!
PopupInfo.WindowHandle := View.Window.Handle; /// !!! EAccessViolation
!!!!
......
end;
There is the following declaration in ppTB2Common.
THandleWMPrintNCPaintProc = procedure(Wnd: HWND; DC: HDC; AppData: Longint);
It is called in the following style:
procedure TppTBXPopupWindow.WMNCPaint(var Message: TMessage);
var
DC: HDC;
begin
DC := GetWindowDC(Handle);
try
Assert(DC <> 0, 'TppTBXPopupWindow.WMNCPaint');
SelectNCUpdateRgn(Handle, DC, HRGN(Message.WParam));
TBXPopupNCPaintProc(Handle, DC, NativeInt(Self.View)); // !!! DATA
CORRUPTION !!!
finally
ReleaseDC(Handle, DC);
end;
end;
There are five to ten similar procedures declared according to this
prototype and scattered across the sources. They are called by various
painting methods. The problem is that a TObject value is always passed as
the AppData parameter. The value is converted explicitly into a LongInt
compatible value (and here corruption happens) and inside of the procedure
it is converted back already corrupted. The solution is to change the data
type of the AppData parameter to TObject and do not do any conversions. The
correct function will look like the one below:
THandleWMPrintNCPaintProc = procedure(Wnd: HWND; DC: HDC; AppData: TObject);
procedure TppTBXPopupWindow.WMNCPaint(var Message: TMessage);
...
begin
...
TBXPopupNCPaintProc(Handle, DC, View); // !!! NO DATA CORRUPTION !!!
...
end;
procedure TBXPopupNCPaintProc(Wnd: HWND; DC: HDC; AppData: TObject);
...
begin
...
View := AppData as TppTBPopupView;
...
end;
This discussion has been closed.
Comments
This will be fixed for the next maintenance release, thanks for reporting
this issue. In the future, please post questions to a single destination,
use either support@ or the newsgroup - but not both.
-
Nard Moseley
Digital Metaphors
Best regards,
Nard Moseley
Digital Metaphors
www.digital-metaphors.com