Page 1 of 1

Call return gives "invalid memory access"

Posted: Tue Mar 14, 2006 12:18 pm
by Dare2
This code is Danilo's, modified for version 4.

It is giving me an invalid memory access on the ProceduRereturn in the callback.

Can anyone see if I have introduced something silly, missed something, or otherwise stuffed up?

Thanks!

Code: Select all

Procedure CreateListIconArrows(StartImage) 
  For img = 0 To 1 
    CreateImage(StartImage+img,16,16) 
    StartDrawing(ImageOutput(StartImage+img)) 
      background = GetSysColor_(#COLOR_BTNFACE) 
      FrontColor(RGB(Red(background),Green(background),Blue(background))) 
      Box(0,0,16,16) 
      If img = 0 : Start=7 : Else : Start = 2 : EndIf 
      For a = 6 To 10 
        Line(Start,a,13-Start*2,0,0) 
        Start+1 
      Next a 
    StopDrawing() 
  Next 
EndProcedure 


Procedure AddListIconColumn(gadget,pos,width,align,text$,hImage) 
  #LVCF_IMAGE = $10 
  #LVCFMT_COL_HAS_IMAGES = $8000 
  #LI_CENTERED = #LVCFMT_CENTER 
  #LI_LEFT     = #LVCFMT_LEFT 
  #LI_RIGHT    = #LVCFMT_RIGHT 
  Structure LVCOLUMN 
    lv.LV_COLUMN 
    iImage.l 
    iOrder.l 
  EndStructure 
  If GetObjectType_(hImage)=#OBJ_BITMAP 
    hImgL = SendMessage_(GadgetID(gadget),#LVM_GETIMAGELIST,#LVSIL_SMALL,0) 
    If hImgL=0 
      hImgL = ImageList_Create_(16,16,#ILC_COLOR32,1,1) 
      SendMessage_(GadgetID(gadget),#LVM_SETIMAGELIST,#LVSIL_SMALL,hImgL) 
    EndIf 
    idx = ImageList_Add_(hImgL,hImage,0) 
  Else 
    idx = hImage 
  EndIf 
  LVC.LVCOLUMN 
  LVC\lv\mask = #LVCF_IMAGE|#LVCF_TEXT|#LVCF_WIDTH|#LVCF_FMT 
  LVC\lv\fmt     = align|#LVCFMT_COL_HAS_IMAGES 
  LVC\lv\pszText = @text$ 
  LVC\lv\cchTextMax = Len(text$) 
  LVC\lv\iSubItem = pos 
  LVC\lv\cx   = width 
  LVC\iImage  = idx 
  LVC\iOrder  = pos 
  SendMessage_(GadgetID(gadget),#LVM_INSERTCOLUMN,pos,@LVC) 
EndProcedure 

Procedure GetListIconColumnImage(gadget,column) 
  LVC.LVCOLUMN 
  LVC\lv\mask = #LVCF_IMAGE 
  SendMessage_(GadgetID(gadget),#LVM_GETCOLUMN,column,@LVC) 
  ProcedureReturn LVC\iImage 
EndProcedure 

Procedure ChangeListIconColumnImage(gadget,column,Image_Index) 
  LVC.LVCOLUMN 
  LVC\lv\mask = #LVCF_IMAGE 
  LVC\iImage  = Image_Index 
  ProcedureReturn SendMessage_(GadgetID(gadget),#LVM_SETCOLUMN,column,@LVC) 
EndProcedure 

Procedure SetListIconColumnText(gadget,index,Text$) 
  lvc.LV_COLUMN 
  lvc\mask    = #LVCF_TEXT 
  lvc\pszText = @Text$ 
  SendMessage_(GadgetID(gadget),#LVM_SETCOLUMN,index,@lvc) 
EndProcedure 

Procedure SetListIconColumnWidth(gadget,index,new_width) 
  SendMessage_(GadgetID(gadget),#LVM_SETCOLUMNWIDTH,index,new_width) 
EndProcedure 

Procedure SetListIconColumnFormat(gadget,index,format) 
  lvc.LV_COLUMN 
  lvc\mask = #LVCF_FMT 
  Select format 
    Case 0: lvc\fmt = #LVCFMT_LEFT 
    Case 1: lvc\fmt = #LVCFMT_CENTER 
    Case 2: lvc\fmt = #LVCFMT_RIGHT 
  EndSelect 
  SendMessage_(GadgetID(gadget),#LVM_SETCOLUMN,index,@lvc) 
EndProcedure 

Procedure UpdatelParam(ListIconGadget,columns) 
  ItemCount = SendMessage_(ListIconGadget, #LVM_GETITEMCOUNT, 0, 0) 
  lvi.LV_ITEM 
  lvi\mask = #LVIF_PARAM 
  lvi\iItem = 0 
  While ItemCount>0 
    lvi\lParam = lvi\iItem 
    For SubItem = 0 To columns-1 
      lvi\iSubItem = SubItem 
      SendMessage_(ListIconGadget, #LVM_SETITEM, 0, @lvi) 
    Next SubItem 
    lvi\iItem +1 
    ItemCount -1 
  Wend 
EndProcedure 

Procedure ListIconSortFunction(lParam1,lParam2,lParamSort) 
  A$ = Space(200) 
  B$ = Space(200) 
  result = 0 
  lvi.LV_ITEM 
  lvi\iSubItem = lParamSort&$FFFF 
  lvi\pszText = @A$ 
  lvi\cchTextMax = 200 
  lvi\mask = #LVIF_TEXT 
  SendMessage_(GadgetID(0), #LVM_GETITEMTEXT,lParam1,@lvi) 
  lvi\pszText = @B$ 
  SendMessage_(GadgetID(0), #LVM_GETITEMTEXT,lParam2,@lvi) 
  If A$ = B$ 
    ProcedureReturn 0 ; equal 
  EndIf 
  x = (lParamSort>>16)&$FFFF 
  If x 
    If A$ > B$ 
      ProcedureReturn  1 
    Else 
      ProcedureReturn -1 
    EndIf 
  Else 
    If A$ > B$ 
      ProcedureReturn -1 
    Else 
      ProcedureReturn  1 
    EndIf 
  EndIf 
  ProcedureReturn result 
EndProcedure 

Procedure.l WinProc(hWnd,Msg,wParam,lParam) 
  result = #PB_ProcessPureBasicEvents 
  Select Msg 
    Case #WM_NOTIFY 
      *NMHDR.NMHDR = lParam 
      If *NMHDR\hWndFrom = GadgetID(0)
        If *NMHDR\code = #LVN_COLUMNCLICK 
          *NMLV.NMLISTVIEW = lParam 
          column = *NMLV\iSubItem 
          index  = GetListIconColumnImage(0,column) 
          ChangeListIconColumnImage(0,column,index!1) 
          SendMessage_(GadgetID(0),#LVM_SORTITEMS,column|((index)<<16),@ListIconSortFunction()) 
          UpdatelParam(GadgetID(0),5) 
        EndIf 
      EndIf 
  EndSelect 
  ProcedureReturn result  ; **************** Invalid Memory Access **************
EndProcedure 

CreateListIconArrows(0) 

OpenWindow(0,0,0,500,200,"",#PB_Window_SystemMenu|#PB_Window_ScreenCentered) 
  SetWindowCallback(@WinProc(),0) 
  CreateGadgetList(WindowID(0)) 
  ListIconGadget(0,0,0,500,200,"",0,#PB_ListIcon_FullRowSelect|#PB_ListIcon_AlwaysShowSelection) 
   AddListIconColumn(0,1,150,#LI_LEFT    ,"Column 1",ImageID(0)) ; add Image 0 
   AddListIconColumn(0,2,120,#LI_CENTERED,"Column 2",ImageID(1)) ; add Image 1 
   AddListIconColumn(0,3, 90,#LI_CENTERED,"Column 3",0)           ; use Image index 0 
   AddListIconColumn(0,4,105,#LI_RIGHT   ,"Column 4",1)           ; use Image index 1 
   For a = 0 To 100 
     A$ = "COLUMN 1, Row "+RSet(Str(  a  ),3,"0")+Chr(10) 
     x = Random($FFFF) 
     B$ =                  RSet(Str(  x  ),5,"0")+Chr(10) 
     x = Random($7FFFFFFF) 
     C$ =              "$"+RSet(Hex(  x  ),8,"0")+Chr(10) 
     D$ = "COL 4, Row "   +RSet(Str(100-a),3,"0") 
     AddGadgetItem(0,-1,Chr(10)+A$+B$+C$+D$) 
   Next 
   UpdatelParam(GadgetID(0),5) 
Repeat:Until WaitWindowEvent()=#PB_Event_CloseWindow

Posted: Tue Mar 14, 2006 12:50 pm
by gnozal
Since PB4, you can't use lvi\lParam anymore (because of the new GadgetItemData feature).

Posted: Tue Mar 14, 2006 1:28 pm
by Dare2
Aha!

Thanks gnozal! :)

Posted: Sun Apr 09, 2006 2:01 pm
by Ajm
I don't understand what should be used in its place ?

Could you please post the corrected code for PB4

Posted: Tue Apr 11, 2006 2:57 pm
by Ajm
@Dare2 Did you manage to get this to work ?
I have tried but can't get the columns to sort. :(

Posted: Tue Apr 11, 2006 3:05 pm
by gnozal
Something like this :

Code: Select all

Procedure UpdatelParam(ListHandle.l) ; don't need columns [#LVM_GETITEMCOUNT]
  Protected i.l, lTmp.l, lRecs.l, GadgetID.l
  GadgetID = GetDlgCtrlID_(ListHandle)
  lRecs = SendMessage_(ListHandle, #LVM_GETITEMCOUNT, 0, 0) 
  For i = 0 To lRecs - 1 
    SetGadgetItemData(GadgetID, i, i) 
  Next 
EndProcedure 
Structure PB_ListIconItem ; undocumented PB stuff
  UserData.l 
EndStructure
Procedure ListIconSortFunction(*item1.PB_ListIconItem, *item2.PB_ListIconItem, lParamSort)
  A$ = Space(200) 
  B$ = Space(200) 
  result = 0 
  lvi.LV_ITEM 
  lvi\iSubItem = lParamSort&$FFFF 
  lvi\pszText = @A$ 
  lvi\cchTextMax = 200 
  SendMessage_(GadgetID(0), #LVM_GETITEMTEXT,*item1\UserData,@lvi) 
  lvi\pszText = @B$ 
  SendMessage_(GadgetID(0), #LVM_GETITEMTEXT,*item2\UserData,@lvi)
  ; ...
EndProcedure

Posted: Tue Apr 11, 2006 5:21 pm
by Ajm
Cheers gnozal,

Its great when you can learn something new on this forum every day.
:D

Posted: Tue Apr 11, 2006 10:29 pm
by Dare2
Hi ajm,

Just saw this (I am not skimming posts these days) so sorry for no earlier answer.

However it is just as well gnozal responded before I did as that looks like a much better solution than the one I had (which wasn't a solution but a workaround - I used linked lists and sorted them/rebuilt the gadget).

Thanks gnozal.