May 12, 2024, 05:40:39 AM

News:

Own IWBasic 2.x ? -----> Get your free upgrade to 3.x now.........


Listview Demo

Started by LarryMc, August 05, 2008, 07:17:46 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

LarryMc

Sapero
You worked on this code on the old forums in 2005.
When I try to run it in EB now and I get a ton of errors.
Do you happen to have a copy that runs now?
$include "windows.inc"
autodefine "off"
WINDOW d1
OpenWindow d1,0,0,295,230,@caption,d1,"Advanced TreeView demo",&handler
CONTROL d1,@TREEVIEW,"Static",18,3,252,188,0x50800027|TVS_CHECKBOXES,1
UINT TreeBkColor, TvLastHitItems
INT  bDragging      :' drag running
UINT TVhwnd         :' handle to tree
UINT hDragItem      :' handle to dragged tree item
UINT hDragImageList :' handle to drag imagelist
UINT hImageList     :' handle to imagelist
UINT handle[15]     :' item handles
TVhwnd = GetDlgItem(d1.hwnd, 1)
AddItems()
TreeBkColor = rgb(210,210,210)
SetWindowColor d1, TreeBkColor
SendMessage d1, TVM_SETINDENT, 8, 0, 1
TreeView_SetBkColor(TVhwnd, TreeBkColor)
TreeView_SetLineColor(TVhwnd, 0)
TreeView_SetTextColor(TVhwnd, 0x8FFFFF)
TreeView_SetItemHeight(TVhwnd, 16)
'messagebox 0, hex$(TreeView_GetTextColor(TVhwnd)), ""
While hImageList=0
   hImageList = ImageList_LoadImage(0, "tree.bmp", 10/*each image size*/, 2/*images*/, 0x808080/*color mask*/, IMAGE_BITMAP, LR_LOADFROMFILE|LR_LOADTRANSPARENT)
   IF hImageList = 0
      IF URLDownloadToFileA(0, "http://people.freenet.de/ibasic/tree.bmp", GetStartPath+"tree.bmp", 0, 0)
         hImageList=1
      Endif
   Endif
Wend
starttimer d1, 500
'TreeView_SetImageList(TVhwnd, TVSIL_NORMAL, hImageList)
'TreeView_SetImageList(TVhwnd, TVSIL_STATE, hImageList)
'TreeView_Collapse(TVhwnd, handle[0])
TreeView_SetCheckState(TVhwnd, handle[0], 1)
TreeView_SetCheckState(TVhwnd, handle[1], 1)
TreeView_SetCheckState(TVhwnd, handle[2], 1)
TreeView_SetItemState(TVhwnd, handle[0], TVIS_BOLD, TVIS_BOLD)
TreeView_SetItemState(TVhwnd, handle[3], TVIS_BOLD, TVIS_BOLD)
TreeView_SetItemState(TVhwnd, handle[6], TVIS_BOLD, TVIS_BOLD)
WaitUntil d1.hwnd=0
ImageList_Destroy(hImageList)
'-------------------------
Sub handler
   POINT pt
   Select @message
      Case @idcreate
         CenterWindow d1
      Case @idtimer
         setcaption d1, "item [0] checked: "+str$(TreeView_GetCheckState(TVhwnd, handle[0]))
      Case @IDCLOSEWINDOW
         CloseWindow d1
      Case @idlbuttonup
         IF bDragging Then TVStopDraghandler()
      Case @IDMOUSEMOVE
         IF bDragging Then TvMoveDragImage()
      Case @IDCONTROL
         Select @CONTROLID
            Case 1
               Select @NOTIFYCODE
                  Case NM_CUSTOMDRAW
                     Return TVSubclassDrag(*<NMTVCUSTOMDRAW>@lParam)
                  Case TVN_BEGINDRAG
                     TVBeginDrag(d1.hwnd, TVhwnd, *<NMTREEVIEW>@lparam)
                  case @nmrclick
                     GetMouseCoords(d1.hwnd, pt)
                     contextmenu d1, pt.x, pt.y
                     menuitem "nix! :)", 0, 1000
                     endmenu
               EndSelect
         EndSelect
   EndSelect
   Return
EndSub
'-------------------------
Sub TVSubclassDrag(lParam:NMTVCUSTOMDRAW),uint
   Select lParam.nmcd.dwDrawStage
      Case CDDS_PREPAINT
         ' Need to process this case and set pResult to CDRF_NOTIFYITEMDRAW,
         ' otherwise parent will never receive CDDS_ITEMPREPAINT notification.
         Return CDRF_NOTIFYITEMDRAW
      Case CDDS_ITEMPREPAINT
         Select lParam.iLevel
            Case 0 :' painting all 0-level items blue
               IF (lParam.nmcd.uItemState & (CDIS_FOCUS | CDIS_SELECTED))
                  lParam.clrText = RGB(0, 0, 0)
                  lParam.clrTextBk = RGB(0, 255, 0)
               Else
                  lParam.clrText = RGB(0, 0, 255)
               Endif
               Return CDRF_NEWFONT
            Case 1 :' painting all 1-level items red
               IF (lParam.nmcd.uItemState & (CDIS_FOCUS | CDIS_SELECTED))
                  lParam.clrText = RGB(0, 0, 0)
                  lParam.clrTextBk = RGB(255, 255, 0)
               Else   
                  lParam.clrText = RGB(255, 0, 0)
               Endif
               Return CDRF_NEWFONT
            Case 2 :' painting all 2-level items green
               IF (lParam.nmcd.uItemState & (CDIS_FOCUS | CDIS_SELECTED))
                  lParam.clrText = RGB(0, 0, 0)
                  lParam.clrTextBk = RGB(0, 255, 255)
               Else   
                  lParam.clrText = RGB(255, 255, 0)
               Endif
               Return CDRF_NEWFONT
         EndSelect
         Return CDRF_NEWFONT
   EndSelect
     
   Return CDRF_DODEFAULT
EndSub
'-------------------------
Sub TVBeginDrag(parent:uint, hTree:uint, nmtv:NMTREEVIEW)
   WINRECT rc
   UINT dwLevel, dwIndent
   TVhwnd = hTree
   ' get the handle to currend item
   hDragItem = nmtv.itemNew.hItem
   'Tell the tree-view control to create an image to use for dragging
   hDragImageList = TreeView_CreateDragImage(TVhwnd, hDragItem)
   'Get the bounding rectangle of the item being dragged
   TreeView_GetItemRect(TVhwnd, nmtv.itemNew.hItem, rc, TRUE)
   'Get the heading level and the amount that the child items are indented
   dwLevel = nmtv.itemNew.lParam
   dwIndent = TreeView_GetIndent(TVhwnd)
   'Start the drag operation
   ImageList_BeginDrag(hDragImageList, 0, 0, 0)
   ImageList_DragEnter(0, 50, 50)
   'direct mouse input to the parent window
   bDragging = TRUE
   SetCapture(parent)
   Return
EndSub
'-------------------------
Sub TvMoveDragImage()
   POINT pt
   TVHITTESTINFO tvh
   ImageList_DragLeave(0)
   GetCursorPos(tvh.pt)
   GetCursorPos(pt)
   tvh.flags = TVHT_ONITEM
   ScreenToClient(TVhwnd, tvh.pt)
   TvLastHitItems = TreeView_HitTest(TVhwnd, tvh)
   IF TvLastHitItems Then TreeView_SelectItem(TVhwnd, TvLastHitItems)
   ImageList_DragEnter(0, pt.x, pt.y)
   Return
EndSub
'-------------------------
Sub TVStopDraghandler
   TVHITTESTINFO tvh
   TVINSERTSTRUCT tvis
   ISTRING txt[261]
   bDragging = FALSE
   ImageList_DragLeave(TVhwnd)
   ImageList_EndDrag()
   ImageList_Destroy(hDragImageList)
   ReleaseCapture()
   ' get item handle from mouse position
   GetCursorPos(tvh.pt)
   ScreenToClient(TVhwnd, tvh.pt)
   tvh.flags = TVHT_ONITEM
   TreeView_HitTest(TVhwnd, tvh)
   IF tvh.hItem and (tvh.hItem <> hDragItem)
      TVcopyItem(/*source*/TVhwnd, hDragItem,  /*dest*/TVhwnd, tvh.hItem,  /*flags*/TVI_LAST)
      TreeView_DeleteItem(TVhwnd, hDragItem)
   Endif
   Return
EndSub
'-------------------------
Sub TVcopyItem(tree_handle_from:uint, hItem_from:uint, tree_handle_to:uint, hItem_to:uint, flags:uint/* TVI_LAST... */)
   UINT hChild, hNew
   TVINSERTSTRUCT tvis
   ISTRING txt[261]
   IF (hItem_from = hItem_to) Then Return
   IF (tree_handle_from * hItem_from * tree_handle_to * hItem_to) = 0 Then Return
   ' get the item
   tvis.tvi.hItem      = hItem_from
   tvis.tvi.mask       = TVIF_CHILDREN | TVIF_HANDLE | TVIF_IMAGE | TVIF_STATE | TVIF_TEXT | TVIF_PARAM
   tvis.tvi.stateMask  = 0xFFFF :' all TVIS_
   tvis.tvi.pszText    = txt
   tvis.tvi.cchTextMax = 260
   TreeView_GetItem(tree_handle_from, tvis.tvi)
   ' copy the item to new position
   tvis.hParent      = hItem_to
   tvis.hInsertAfter = flags
   hNew = TreeView_InsertItem(tree_handle_to, tvis)
   ' enum and move all sub/child items
   hChild = TreeView_GetChild(tree_handle_from, hItem_from)
   While hChild
      TVcopyItem(tree_handle_from, hChild, tree_handle_to, hNew, flags)
      hChild = TreeView_GetNextSibling(tree_handle_from, hChild)
   Wend
   Return
EndSub
'-------------------------
Sub AddItems
'   UINT handle[9]
   handle[0] = tvInsertItem(d1, 1, "root item 1", 0)
   handle[1] = tvInsertItem(d1, 1, "subitem 1.1", handle[0])
   handle[2] = tvInsertItem(d1, 1, "subitem 1.1.1", handle[1])
   handle[3] = tvInsertItem(d1, 1, "root item 2", 0)
   handle[4] = tvInsertItem(d1, 1, "subitem 2.1", handle[3])
   handle[5] = tvInsertItem(d1, 1, "subitem 2.1.1", handle[4])
   handle[6] = tvInsertItem(d1, 1, "root item 3", 0)
   handle[7] = tvInsertItem(d1, 1, "subitem 3.1", handle[6])
   handle[8] = tvInsertItem(d1, 1, "subitem 3.2", handle[6])
   handle[9] = tvInsertItem(d1, 1, "subitem 3.3", handle[6])
   handle[10] = tvInsertItem(d1, 1, "subitem 3.4", handle[6])
   handle[11] = tvInsertItem(d1, 1, "subitem 3.2.1", handle[8])
   handle[12] = tvInsertItem(d1, 1, "subitem 3.2.2", handle[8])
   handle[13] = tvInsertItem(d1, 1, "subitem 3.2.3", handle[8])
   handle[14] = tvInsertItem(d1, 1, "subitem 3.2.4", handle[8])
   TreeView_Expand(TVhwnd, handle[0])
   TreeView_Expand(TVhwnd, handle[1])
   TreeView_Expand(TVhwnd, handle[3])
   TreeView_Expand(TVhwnd, handle[4])
   TreeView_Expand(TVhwnd, handle[6])
   Return
EndSub


Larry
LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library

sapero

I got it working, and also updated the image on freenet server. Added a protection to prevent dropping items to its child nodes (tvIsChildOf).
The blue and red circle represents a checkbox, the red one is for 'unchecked' state. This is set by TVSIL_STATE.

LarryMc

Many thanks Sapero ;D

Larry
LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library

LarryMc

Sapero
Tried to run it and got these errors:

QuoteCompiling...
treevcopy.eba
File: commctrl.inc (367) duplicate declaration - HIMAGELIST
File: commctrl.inc (368) duplicate declaration - BOOL
File: commctrl.inc (370) duplicate declaration - int
File: commctrl.inc (371) duplicate declaration - BOOL
File: commctrl.inc (373) duplicate declaration - int
File: commctrl.inc (375) duplicate declaration - int
File: commctrl.inc (376) duplicate declaration - COLORREF
File: commctrl.inc (377) duplicate declaration - COLORREF
File: commctrl.inc (378) duplicate declaration - BOOL
File: commctrl.inc (406) duplicate declaration - BOOL
File: commctrl.inc (407) duplicate declaration - BOOL
File: commctrl.inc (408) duplicate declaration - int
File: commctrl.inc (409) duplicate declaration - BOOL
File: commctrl.inc (410) duplicate declaration - BOOL
File: commctrl.inc (411) duplicate declaration - BOOL
File: commctrl.inc (412) duplicate declaration - HICON
File: commctrl.inc (413) duplicate declaration - HIMAGELIST
File: commctrl.inc (414) duplicate declaration - HIMAGELIST
File: commctrl.inc (424) duplicate declaration - BOOL
File: commctrl.inc (425) duplicate declaration - BOOL
File: commctrl.inc (426) duplicate declaration
File: commctrl.inc (427) duplicate declaration - BOOL
File: commctrl.inc (428) duplicate declaration - BOOL
File: commctrl.inc (429) duplicate declaration - BOOL
File: commctrl.inc (430) duplicate declaration - BOOL
File: commctrl.inc (431) duplicate declaration - BOOL
File: commctrl.inc (432) duplicate declaration - HIMAGELIST
File: commctrl.inc (465) duplicate declaration - BOOL
File: commctrl.inc (466) duplicate declaration - BOOL
File: commctrl.inc (467) duplicate declaration - BOOL
File: commctrl.inc (468) duplicate declaration - HIMAGELIST
File: commctrl.inc (469) duplicate declaration - HIMAGELIST
File: C:\_EBDev\projects\treeviewdrag\treevcopy.eba (56) Warning: undeclared function 'INDEXTOSTATEIMAGEMASK'
Error(s) in compiling C:\_EBDev\projects\treeviewdrag\treevcopy.eba

Any ideas?

Larry
LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library

LarryMc

Oops! ::)
I still had an old controlpk.incc in the bin directory.

Now when I try to compile I just get this:
QuoteCompiling...
treevcopy.eba
File: C:\_EBDev\projects\treeviewdrag\treevcopy.eba (56) Warning: undeclared function 'INDEXTOSTATEIMAGEMASK'
C:\_EBDev\projects\treeviewdrag\treevcopy.a:519: error: symbol `INDEXTOSTATEIMAGEMASK' undefined
C:\_EBDev\projects\treeviewdrag\treevcopy.a:2299: error: phase error detected at end of assembly.
Error(s) in assembling C:\_EBDev\projects\treeviewdrag\treevcopy.a

Larry
LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library

sapero

There is updated SDK pak to download, be sure to backup your bass.inc if you have newer than 2.2.
Or just add this function:
sub INDEXTOSTATEIMAGEMASK(int i),int
   return i<<12
endsub

LarryMc

LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library

LarryMc

Sapero

I was using this code of your's to try and get my bitmaps to work and I'm not having any luck.
I stripped out all the drag related code because I don't need that.

My bitmap is 160 x 60
I set itemheight to 70 to allow a little spacing between images and that works.
problem is if I use a number greater than 1/2 the width I don't det anything for a image and if I double click where it is suppose to be I get a fault message and crash.
If I set it to 80 or less  that portion of the image shows and double clicking on it doesn't hurt anything.
here's the code I'm using
$include "windowssdk.inc"
$include "commctrl.inc"
autodefine "off"
WINDOW d1
OpenWindow d1,0,0,295,230,@caption,d1,"Advanced TreeView demo",&handler
CONTROL d1,@TREEVIEW,"Static",18,3,252,188,0x50800027|TVS_CHECKBOXES,1
UINT TreeBkColor, TvLastHitItems
UINT TVhwnd         :' handle to tree
UINT hImageList     :' handle to imagelist
UINT handle[15]     :' item handles
TVhwnd = GetDlgItem(d1.hwnd, 1)
AddItems()
TreeBkColor = rgb(210,210,210)
SetWindowColor d1, TreeBkColor
SendMessage d1, TVM_SETINDENT, 8, 0, 1
SendMessageA(TVhwnd, TVM_SETBKCOLOR, 0, TreeBkColor)
SendMessageA(TVhwnd, TVM_SETLINECOLOR, 0, 0)
SendMessageA(TVhwnd, TVM_SETTEXTCOLOR, 0, 0x0000FF)
SendMessageA(TVhwnd, TVM_SETITEMHEIGHT, 70, 0)
'messagebox 0, hex$(TreeView_GetTextColor(TVhwnd)), ""
While hImageList=0
   'hImageList = ImageList_LoadImage(0, GetStartPath+"tree.bmp", 10/*each image size*/, 2/*images*/, 0x808080/*color mask*/, IMAGE_BITMAP, LR_LOADFROMFILE|LR_LOADTRANSPARENT)
   hImageList = ImageList_LoadImage(0, GetStartPath+"0025.bmp", 80/*each image size*/, 10/*images*/, 0x000000/*color mask*/, IMAGE_BITMAP, LR_LOADFROMFILE|LR_MONOCHROME)

   IF hImageList = 0
      IF URLDownloadToFileA(0, "http://people.freenet.de/ibasic/tree.bmp", GetStartPath+"tree.bmp", 0, 0)
         hImageList=1
      Endif
   Endif
Wend
starttimer d1, 500
'SendMessageA(TVhwnd, TVM_SETIMAGELIST, TVSIL_NORMAL, hImageList)
SendMessageA(TVhwnd, TVM_SETIMAGELIST, TVSIL_STATE, hImageList)
'TreeView_Collapse(TVhwnd, handle[0])
TreeView_SetCheckState(TVhwnd, handle[0], 1)
TreeView_SetCheckState(TVhwnd, handle[1], 1)
TreeView_SetCheckState(TVhwnd, handle[2], 1)
TreeView_SetCheckState(TVhwnd, handle[3], 1)
TreeView_SetCheckState(TVhwnd, handle[4], 1)
TreeView_SetCheckState(TVhwnd, handle[5], 1)
TreeView_SetItemState(TVhwnd, handle[0], TVIS_BOLD, TVIS_BOLD)
TreeView_SetItemState(TVhwnd, handle[1], TVIS_BOLD, TVIS_BOLD)
TreeView_SetItemState(TVhwnd, handle[2], TVIS_BOLD, TVIS_BOLD)
TreeView_SetItemState(TVhwnd, handle[3], TVIS_BOLD, TVIS_BOLD)
TreeView_SetItemState(TVhwnd, handle[4], TVIS_BOLD, TVIS_BOLD)
TreeView_SetItemState(TVhwnd, handle[5], TVIS_BOLD, TVIS_BOLD)
WaitUntil d1.hwnd=0
ImageList_Destroy(hImageList)

sub TreeView_SetItemState(HWND hwndTV,HTREEITEM hItem,UINT state,UINT stateMask),UINT
TVITEM tvi
tvi.mask = TVIF_STATE
tvi.hItem = hItem
tvi.state = state
tvi.stateMask = stateMask
return SendMessageA(hwndTV, TVM_SETITEM, 0, &tvi)
endsub

sub TreeView_SetCheckState(HWND hwndTV,HTREEITEM hItem,BOOL fCheck),UINT
'return TreeView_SetItemState(hwndTV, hItem, INDEXTOSTATEIMAGEMASK(IIF(fCheck,2,1)), TVIS_STATEIMAGEMASK)
return TreeView_SetItemState(hwndTV, hItem, INDEXTOSTATEIMAGEMASK(IIF(fCheck,1,1)), TVIS_STATEIMAGEMASK)

endsub

sub TreeView_GetCheckState(HWND hwndTV, HTREEITEM hItem),UINT
return (SendMessageA(hwndTV, TVM_GETITEMSTATE, hItem, TVIS_STATEIMAGEMASK) >> 12) -1
endsub

'-------------------------
Sub handler
   POINT pt
   Select @message
      Case @idcreate
         CenterWindow d1
      Case @idtimer
         setcaption d1, "item [0] checked: "+str$(TreeView_GetCheckState(TVhwnd, handle[0]))
      Case @IDCLOSEWINDOW
         CloseWindow d1
      Case @IDCONTROL
         Select @CONTROLID
            Case 1
               Select @NOTIFYCODE

                  case @nmrclick
                     GetCursorPos(&pt)
                     ScreenToCLient(d1.hwnd, &pt)
                     contextmenu d1, pt.x, pt.y
                     menuitem "nix! :)", 0, 1000
                     endmenu
               EndSelect
         EndSelect
   EndSelect
   Return
EndSub
'-------------------------


'-------------------------

'-------------------------
Sub AddItems
'   UINT handle[9]
   handle[0] = tvInsertItem(d1, 1, "root item 1", 0)
   handle[1] = tvInsertItem(d1, 1, "root item 2", 0)
   handle[2] = tvInsertItem(d1, 1, "root item 3", 0)
   handle[3] = tvInsertItem(d1, 1, "root item 4", 0)
   handle[4] = tvInsertItem(d1, 1, "root item 5", 0)
   handle[5] = tvInsertItem(d1, 1, "root item 6", 0)

  ' SendMessageA(TVhwnd, TVM_EXPAND, TVE_EXPAND, handle[0])
   'SendMessageA(TVhwnd, TVM_EXPAND, TVE_EXPAND, handle[1])
   'SendMessageA(TVhwnd, TVM_EXPAND, TVE_EXPAND, handle[2])
   Return
EndSub

Attached are my bitmap and the best I can get it to display.

Larry
LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library

sapero

April 02, 2009, 12:41:59 PM #8 Last Edit: April 02, 2009, 04:18:02 PM by sapero
I'm not sure why it crashes, but it does in comctl32.dll. It loads the number of images from imagelist and divides something by zero (calculated).
Probably the height of state-image must be equal or greater than width, or width and height cannot exceed 80 pixels.
Maybe better you use owner drawn listbox, or implement your own control.

By the way, the 10 in ImageList_LoadImage is invalid, you cannot load 10 * 80px images from a 160px bitmap.
All the Treeview_* functions are already defined in commctrl.inc, but the TreeView_SetCheckState macro has a hard bug (fixed today 2 April). I have uploaded the new headers.

LarryMc

I decided that since it was showing only 1/2 of my image that I would reduce my image by 1/2.

To my surprise it only displayed 1/2 of the smaller image.

Maybe everyone else knew this but me.
iit appears that since this is suppose to be a state image it expects one 1/2 of the image to be the set image and the other half is the reset image.

I took my image and stretched the canvas so it had another image space and it displayed the one I wanted just like I wanted.

Larry
LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library