[DUG] Access violation in TTntCustomListView (Delphi 7)
Ross Levis
ross at stationplaylist.com
Tue Nov 4 17:46:47 NZDT 2014
Thanks for your help Jolyon.
It appears to be TNT version 2.3.0. I don’t think it has been updated since 2007 and I installed it last year I think.
Here is the entire CNNotify procedure. I hope this helps.
procedure TTntCustomListView.CNNotify(var Message: TWMNotify);
var
Item: TTntListItem;
begin
if (not Win32PlatformIsUnicode) then
inherited
else begin
with Message do
begin
case NMHdr^.code of
HDN_TRACKW:
begin
NMHdr^.code := HDN_TRACKA;
try
inherited;
finally
NMHdr^.code := HDN_TRACKW;
end;
end;
LVN_GETDISPINFOW:
begin
// call inherited without the LVIF_TEXT flag
CurrentDispInfo := PLVDispInfoW(NMHdr);
try
OriginalDispInfoMask := PLVDispInfoW(NMHdr)^.item.mask;
PLVDispInfoW(NMHdr)^.item.mask := PLVDispInfoW(NMHdr)^.item.mask and (not LVIF_TEXT);
try
NMHdr^.code := LVN_GETDISPINFOA;
try
inherited;
finally
NMHdr^.code := LVN_GETDISPINFOW;
end;
finally
if (OriginalDispInfoMask and LVIF_TEXT <> 0) then
PLVDispInfoW(NMHdr)^.item.mask := PLVDispInfoW(NMHdr)^.item.mask or LVIF_TEXT;
end;
finally
CurrentDispInfo := nil;
end;
// handle any text info
with PLVDispInfoW(NMHdr)^.item do
begin
if (mask and LVIF_TEXT) <> 0 then
begin
Item := GetItemW(PLVDispInfoW(NMHdr)^.item);
if iSubItem = 0 then
WStrLCopy(pszText, PWideChar(Item.Caption), cchTextMax - 1)
else begin
with Item.SubItems do begin
if iSubItem <= Count then
WStrLCopy(pszText, PWideChar(Strings[iSubItem - 1]), cchTextMax - 1)
else pszText[0] := #0;
end;
end;
end;
end;
end;
LVN_ODFINDITEMW:
with PNMLVFindItem(NMHdr)^ do
begin
if ((lvfi.flags and LVFI_PARTIAL) <> 0) or ((lvfi.flags and LVFI_STRING) <> 0) then
PWideFindString := TLVFindInfoW(lvfi).psz
else
PWideFindString := nil;
lvfi.psz := nil;
NMHdr^.code := LVN_ODFINDITEMA;
try
inherited; {will Result in call to OwnerDataFind}
finally
TLVFindInfoW(lvfi).psz := PWideFindString;
NMHdr^.code := LVN_ODFINDITEMW;
PWideFindString := nil;
end;
end;
LVN_BEGINLABELEDITW:
begin
Item := GetItemW(PLVDispInfoW(NMHdr)^.item);
if not CanEdit(Item) then Result := 1;
if Result = 0 then
begin
FEditHandle := ListView_GetEditControl(Handle);
FDefEditProc := Pointer(GetWindowLongW(FEditHandle, GWL_WNDPROC));
SetWindowLongW(FEditHandle, GWL_WNDPROC, LongInt(FEditInstance));
end;
end;
LVN_ENDLABELEDITW:
with PLVDispInfoW(NMHdr)^ do
if (item.pszText <> nil) and (item.IItem <> -1) then
Edit(TLVItemA(item));
LVN_GETINFOTIPW:
begin
NMHdr^.code := LVN_GETINFOTIPA;
try
inherited;
finally
NMHdr^.code := LVN_GETINFOTIPW;
end;
end;
else
inherited;
end;
end;
end;
end;
Many thanks,
Ross.
From: delphi-bounces at listserver.123.net.nz [mailto:delphi-bounces at listserver.123.net.nz] On Behalf Of Jolyon Smith
Sent: Tuesday, 4 November 2014 9:10 a.m.
To: NZ Borland Developers Group - Delphi List
Subject: Re: [DUG] Access violation in TTntCustomListView (Delphi 7)
What version of TNT are you using ?
There is nothing intrinsically wrong with the line on which the error is occurring, which suggests that the problem is with the parameters involved. Given that it is a write op to a NIL address, this points the finger at the destination of the WStrLCopy()... the pszText member of the item data.
There is potential for the pszText parameter to be invalid, if the LVIF_TEXT flag is not set in the notification mask. According to the community additions on the MSDN ref for the LVN_DISPINFO notification (http://msdn.microsoft.com/en-us/library/windows/desktop/bb774818(v=vs.85).aspx), this is specifically the case on Windows 8 when list selection changes, as would occur when keying up/down through the list, for example.
So far, everything seems to point in the same direction....
However, the code you have quoted above is conditional on the LVIF_TEXT flag being set, but there is code that precedes this in TNT which invokes the inherited implementation of the CNNotify handler, removing and re-instating the LVIF_TEXT flag in the process.
The reason I ask about the version you are using is that in the version I am looking at (2.3.0) this preceding code appears to handle the LVIF_TEXT flag correctly, only re-applying the LVIF_TEXT flag if it was originally set. But I wonder if you have some version of the TNT code which perhaps contains a flaw in this area and is adding this flag when it shouldn't ?
Or is it possible that your copy of the source has been modified from the TNT original in a way that might have introduced such a flaw ?
It might be helpful to post the entire LVN_GETDISPINFOW handler from the CNNotify() method, to be sure.
On 3 November 2014 20:06, Ross Levis <ross at stationplaylist.com> wrote:
I hope someone can help. I’m using the freeware TNT controls with D7 for a TTntListView component. This is working fine for many users but one user experiences a crash when simply using the keyboard to move up and down the listview. He is using Win8 64-bit as I do here, but I can’t duplicate it.
It is a virtual listview using OnData. Here is a portion of a MadExcept log. Can provide more if required.
exception message : Access violation at address 0050DA73 in module 'SPLStudio.exe'. Write of address 00000000.
main thread ($d88):
0050da73 SPLStudio.exe TntWideStrUtils 180 +10 WStrLCopy
0053e20e SPLStudio.exe TntComCtrls 2104 +46 TTntCustomListView.CNNotify
004f304f SPLStudio.exe Controls 4645 +53 TControl.WndProc
004f6d5e SPLStudio.exe Controls 6342 +33 TWinControl.WndProc
004c04a5 SPLStudio.exe ComCtrls 14815 +12 TCustomListView.WndProc
0053dee4 SPLStudio.exe TntComCtrls 2023 +98 TTntCustomListView.WndProc
00539335 SPLStudio.exe TntControls 666 +19 TWinControlTrap.WindowProc
004f2d5a SPLStudio.exe Controls 4552 +5 TControl.Perform
004f6f20 SPLStudio.exe Controls 6388 +6 DoControlMsg
004f772f SPLStudio.exe Controls 6579 +1 TWinControl.WMNotify
...
Code in TntComCtrls.pas where it crashes updating a list item caption...
// handle any text info
with PLVDispInfoW(NMHdr)^.item do
begin
if (mask and LVIF_TEXT) <> 0 then
begin
Item := GetItemW(PLVDispInfoW(NMHdr)^.item);
if iSubItem = 0 then
>>>>> WStrLCopy(pszText, PWideChar(Item.Caption), cchTextMax - 1)
else begin
with Item.SubItems do begin
if iSubItem <= Count then
WStrLCopy(pszText, PWideChar(Strings[iSubItem - 1]), cchTextMax - 1)
else pszText[0] := #0;
end;
end;
end;
end;
Any ideas appreciated.
Thanks,
Ross,
_______________________________________________
NZ Borland Developers Group - Delphi mailing list
Post: delphi at listserver.123.net.nz
Admin: http://delphi.org.nz/mailman/listinfo/delphi
Unsubscribe: send an email to delphi-request at listserver.123.net.nz with Subject: unsubscribe
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://listserver.123.net.nz/pipermail/delphi/attachments/20141104/976b4e32/attachment-0001.html
More information about the Delphi
mailing list