[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