Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Listbox with [ENTER] and images not working
#1
In the below code you see a dialog with 2 listboxes (left and right), the right listbox is the problem.
The problem is that the right listbox is not working when the lines are activated with below comment

 ;; <============= activate this and right listbox does not render correctly

The code in the below state works and displays the listboxes and images.
But as soon as you activate one or both lines of the code with the ;; <====== comment, the right listbox does not render correctly.
This dialog also needs to restarts itself when an item in the left listbox is double clicked (or [ENTER]), that's why I already added that code. I did this just be sure it does not hamper with the code that renders the listboxes.

I added the 3 images I used as attachment.

There might be a very large problem behind this that requires to much to code, I don't know.
But if this would take to long then just skip this. But if there is a workable solution I would really love to know.


Function playlist_test
Code:
Copy      Help
;g1
;; below image resolutions: 64x64
str- imgs=
;F:\portableapps\quickmacrosportable_shared_items\_ICONS\test_image_0.png
;F:\portableapps\quickmacrosportable_shared_items\_ICONS\test_image_1.png
;F:\portableapps\quickmacrosportable_shared_items\_ICONS\test_image_2.png


str dd=
F
;BEGIN DIALOG
;0 "" 0x90C80A44 0x100 0 0 473 145 ""
;6 ListBox 0x54230151 0x200 3 2 194 131 ""
;8 ListBox 0x54230151 0x200 202 1 239 135 ""
;END DIALOG
;DIALOG EDITOR: "" 0x2040601 "*" "" "" ""

str controls = "6 8"
str lb6 lb8

lb6="list 1[]list 2[]list 3"
lb8="song 1[]song 2[]song 3"

int r=ShowDialog(dd &sub.DlgProc &controls)
if(r=3)
,goto g1
if(!r) ret

#sub DlgProc
function# hDlg message wParam lParam

ARRAY(int)-- t_act t_acb t_afont
if(DT_LbCbOwnerDraw(hDlg message wParam lParam 6 1 t_act t_acb 0xffff 0x1 t_afont)) ret 1
;if(DT_LbCbOwnerDraw(hDlg message wParam lParam 8 1 t_act t_acb 0xffff 0x1 t_afont)) ret 1  ;; <============= activate this and right listbox does not render correctly

str- imgs
CB_DrawImages hDlg message wParam lParam 8 imgs 1|16 64 64 DT_WORDBREAK

sel message
,case WM_INITDIALOG
,,;; Font style for both listboxes
,,__Font-- t_f1.Create("Tahoma" 12 1)
,,int v
,,for v 0 3
,,,t_afont[]=t_f1

,,;; Make sure [ENTER] can be used in listbox
,,SetWindowSubclass(id(6 hDlg) &sub.WndProc_Subclass_lbleft_enter 1 0)
,,;SetWindowSubclass(id(8 hDlg) &sub.WndProc_Subclass_lbright_enter 1 0) ;; <============= activate this and right listbox does not render correctly
,,
,case WM_DESTROY
,case WM_COMMAND goto messages2
ret
;messages2
sel wParam
,case IDOK
,case IDCANCEL

,;; In a later (final) version of this dialog needs to restart and reload the right listbox contents
,;; It's done when user double clicks (or [ENTER]) on left listbox. I already implented this so any conflicts
,;; regarding restarting dialog and rendering listboxes could be handled early on.
,case LBN_DBLCLK<<16|6
,,_i=LB_SelectedItem(lParam)
,,DT_Ok hDlg 3
,
ret 1

#sub WndProc_Subclass_lbright_enter ;;menu File -> New -> Templates -> Wndproc -> WndProc_Subclass
function# hwnd message wParam lParam uIdSubclass dwRefData

sel message    
,case WM_GETDLGCODE
,sel(wParam)
,,case [VK_SPACE] ret 0
,,case [VK_RETURN] ret DLGC_WANTALLKEYS ;;please send me WM_KEYDOWN instead of closing the dialog
,
,case WM_KEYDOWN
,sel(wParam) case [VK_RETURN,VK_SPACE] SendMessage GetParent(hwnd) WM_COMMAND LBN_DBLCLK<<16|GetDlgCtrlID(hwnd) hwnd; ret ;;to use the same code as for double-click
,;sel(wParam) case [VK_RETURN,VK_SPACE] SendMessage GetParent(hwnd) WM_COMMAND LBN_SELCHANGE<<16|GetDlgCtrlID(hwnd) hwnd; ret ;;to use the same code as for double-click

int R=DefSubclassProc(hwnd message wParam lParam)

sel message
,case WM_NCDESTROY
,RemoveWindowSubclass(hwnd &sub.WndProc_Subclass_lbright_enter uIdSubclass)
,
#sub WndProc_Subclass_lbleft_enter ;;menu File -> New -> Templates -> Wndproc -> WndProc_Subclass
function# hwnd message wParam lParam uIdSubclass dwRefData

sel message
,case WM_GETDLGCODE
,sel(wParam)
,,case [VK_SPACE] ret 0
,,case [VK_RETURN] ret DLGC_WANTALLKEYS ;;please send me WM_KEYDOWN instead of closing the dialog
,
,case WM_KEYDOWN
,sel(wParam) case [VK_RETURN,VK_SPACE] SendMessage GetParent(hwnd) WM_COMMAND LBN_DBLCLK<<16|GetDlgCtrlID(hwnd) hwnd; ret ;;to use the same code as for double-click
,;sel(wParam) case [VK_RETURN,VK_SPACE] SendMessage GetParent(hwnd) WM_COMMAND LBN_SELCHANGE<<16|GetDlgCtrlID(hwnd) hwnd; ret ;;to use the same code as for double-click

int R=DefSubclassProc(hwnd message wParam lParam)

sel message
,case WM_NCDESTROY
,RemoveWindowSubclass(hwnd &sub.WndProc_Subclass_lbleft_enter uIdSubclass)

ret R


Attached Files Image(s)
           
#2
did you have a look at this post?

http://www.quickmacros.com/forum/showthr...2#pid31482

an example of how to use with the code you have



Function playlist_test2

Code:
Copy      Help
;g1
;;;below image resolutions: 64x64
str- imgs=
;F:\portableapps\quickmacrosportable_shared_items\_ICONS\test_image_0.png
;F:\portableapps\quickmacrosportable_shared_items\_ICONS\test_image_1.png
;F:\portableapps\quickmacrosportable_shared_items\_ICONS\test_image_2.png



str dd=
;BEGIN DIALOG
;0 "" 0x90C80A44 0x100 0 0 473 145 ""
;6 ListBox 0x54230151 0x200 3 2 194 131 ""
;8 ListBox 0x54230151 0x200 202 1 239 135 ""
;END DIALOG
;DIALOG EDITOR: "" 0x2040601 "*" "" "" ""

str controls = "6 8"
str lb6 lb8
lb6="list 1[]list 2[]list 3"
lb8="song 1[]song 2[]song 3"
int r=ShowDialog(dd &sub.DlgProc &controls)
if(r=3)
,goto g1
if(!r) ret

#sub DlgProc
function# hDlg message wParam lParam

str- imgs
CB_ItemImageAndColor hDlg message wParam lParam 8 imgs 1|16 64 64 DT_WORDBREAK &sub.ColorCallback
CB_ItemImageAndColor hDlg message wParam lParam 6 0 1 0 0 DT_WORDBREAK &sub.ColorCallback

sel message
,case WM_INITDIALOG
,,;;;Font style for both listboxes
,,__Font-- t_f1.Create("Tahoma" 12 1)
,,t_f1.SetDialogFont(hDlg "6 8")    
,,;;;Make sure [ENTER] can be used in listbox
,,SetWindowSubclass(id(6 hDlg) &sub.WndProc_Subclass_lbleft_enter 1 0)
,,;SetWindowSubclass(id(8 hDlg) &sub.WndProc_Subclass_lbright_enter 1 0) ;; <============= activate this and right listbox does not render correctly
,,
,case WM_DESTROY
,case WM_COMMAND goto messages2
ret
;messages2
sel wParam
,case IDOK
,case IDCANCEL

,;;;In a later (final) version of this dialog needs to restart and reload the right listbox contents
,;;;It's done when user double clicks (or [ENTER]) on left listbox. I already implented this so any conflicts
,;;;regarding restarting dialog and rendering listboxes could be handled early on.
,case LBN_DBLCLK<<16|6
,,_i=LB_SelectedItem(lParam)
,,DT_Ok hDlg 3
,
ret 1

#sub WndProc_Subclass_lbright_enter ;;menu File -> New -> Templates -> Wndproc -> WndProc_Subclass
function# hwnd message wParam lParam uIdSubclass dwRefData

sel message
,case WM_GETDLGCODE
,sel(wParam)
,,case [VK_SPACE] ret 0
,,case [VK_RETURN] ret DLGC_WANTALLKEYS ;;please send me WM_KEYDOWN instead of closing the dialog
,
,case WM_KEYDOWN
,sel(wParam) case [VK_RETURN,VK_SPACE] SendMessage GetParent(hwnd) WM_COMMAND LBN_DBLCLK<<16|GetDlgCtrlID(hwnd) hwnd; ret ;;to use the same code as for double-click
,;sel(wParam) case [VK_RETURN,VK_SPACE] SendMessage GetParent(hwnd) WM_COMMAND LBN_SELCHANGE<<16|GetDlgCtrlID(hwnd) hwnd; ret ;;to use the same code as for double-click

int R=DefSubclassProc(hwnd message wParam lParam)

sel message
,case WM_NCDESTROY
,RemoveWindowSubclass(hwnd &sub.WndProc_Subclass_lbright_enter uIdSubclass)
,
#sub WndProc_Subclass_lbleft_enter ;;menu File -> New -> Templates -> Wndproc -> WndProc_Subclass
function# hwnd message wParam lParam uIdSubclass dwRefData

sel message
,case WM_GETDLGCODE
,sel(wParam)
,,case [VK_SPACE] ret 0
,,case [VK_RETURN] ret DLGC_WANTALLKEYS ;;please send me WM_KEYDOWN instead of closing the dialog
,
,case WM_KEYDOWN
,sel(wParam) case [VK_RETURN,VK_SPACE] SendMessage GetParent(hwnd) WM_COMMAND LBN_DBLCLK<<16|GetDlgCtrlID(hwnd) hwnd; ret ;;to use the same code as for double-click
,;sel(wParam) case [VK_RETURN,VK_SPACE] SendMessage GetParent(hwnd) WM_COMMAND LBN_SELCHANGE<<16|GetDlgCtrlID(hwnd) hwnd; ret ;;to use the same code as for double-click

int R=DefSubclassProc(hwnd message wParam lParam)

sel message
,case WM_NCDESTROY
,RemoveWindowSubclass(hwnd &sub.WndProc_Subclass_lbleft_enter uIdSubclass)

ret R

#sub ColorCallback
function# CBITEMCOLOR&c

;This is a sample callback function that can be used with CB_ItemImageAndColor.
;Shows how to set combo/list box item background and text colors depending on item text.
;The function will be called for each item when displaying it.
;c contains various info that can be useful to draw the item.
;To set colors, change c.bkColor and/or c.textColor.
;Also you can change c.dtFlags and c.text.

;c.text - item text. In/out.
;c.bkColor - item background color. In/out.
;c.textColor - item text color. In/out.
;c.hwnd - control handle.
;c.item - item index.
;c.itemData - item data. To set item data, use message CB_SETITEMDATA or LB_SETITEMDATA, documented in MSDN.
;c.selected - 1 if the item is selected, 0 if not.
;c.isLB - 1 if the control is listbox, 0 if combobox.
;c.dtFlags - DrawText flags. Documented in the MSDN Library on the Internet. In/out.
;c.param - an user-defined value, passed to CB_ItemColor.


if(c.selected) 
,c.bkColor=0
,c.textColor=0x00FFFF
,ret

sel c.text 2
,case "*list*" c.bkColor=ColorFromRGB(255 255 0)
,case "*song*" c.bkColor=0; c.textColor=0x00ff00


also need this function


Function CB_ItemImageAndColor
Code:
Copy      Help
;/
function# hDlg message wParam lParam ctrlId [$icons] [flags] [imgWidth] [imgHeight] [dtFlags] [callbackFunc] [param] ;;flags: 1 listbox (default combobox), 2 item data is image index, 4 icons is imagelist, 16 not icons (bmp, jpg, gif)

;Adds icons or bmp/jpg/gif images to a combo box or list box.
;Also can draw items with custom background and text colors.

;This is what you have to do to create a combo or list box:
;1. The dialog must be a smart dialog, ie with dialog procedure.
;2. In the dialog editor, add a combo or list box.
;3. In the Styles dialog:
;;;;For combo box, select CBS_OWNERDRAWFIXED and CBS_HASSTRINGS styles. Make sure that CBS_SORT is not selected (sorted combo boxes are not supported).
;;;;For list box, select LBS_OWNERDRAWFIXED and LBS_HASSTRINGS styles. Make sure that LBS_SORT is not selected (sorted list boxes are not supported).
;4. In the dialog procedure, insert CB_ItemImageAndColor before 'sel messages' line, for each such control. If need colors, create a callback function and pass its address.

;hDlg, message, wParam, lParam - hDlg, message, wParam, lParam.
;ctrlId - combo/list box id.
;icons - list of icon files. If flag 16 used, list of image files of type bmp, jpg or gif. If flag 4 used, imagelist file. Can be 0 if don't need images.
;flags:
;;;;1 the control is a listbox.
;;;;2 item image index is stored in item data (default - same as item index).
;;;;4 icons is .bmp file created with QM imagelist editor.
;;;;16 use bitmap (default - use icon). Don't use with flag 4.
;imgWidth, imgHeight - width and height of images. Default: 16 pixels.
;dtFlags - DrawText flags. Documented in the MSDN Library on the Internet. Xored with DT_NOPREFIX.
;callbackFunc - address of a callback function that sets text colors. Optional. See SampleCbItemColorProc.
;param - a user-defined value that will be passed to the callback function.


type CBITEMCOLOR str'text bkColor textColor hwnd item itemData !selected !isLB dtFlags param

int i n il hi hb hcb; str s
hcb=id(ctrlId hDlg)
if(!imgWidth and icons) imgWidth=16
if(!imgHeight) imgHeight=16

sel message
,case WM_CREATE
,SendMessage hcb iif(flags&1 LB_SETITEMHEIGHT CB_SETITEMHEIGHT) 0 imgHeight+2
,
,case WM_INITDIALOG
,if icons
,,if(flags&4)
,,,il=__ImageListLoad(icons)
,,else
,,,n=numlines(icons)
,,,il=ImageList_Create(imgWidth imgHeight ILC_MASK|ILC_COLOR32 0 n)
,,,for(i 0 n)
,,,,s.getl(icons -i)
,,,,if(flags&16)
,,,,,hb=LoadPictureFile(s 0); if(!hb) goto g1
,,,,,ImageList_Add(il hb 0)
,,,,,if(hb) DeleteObject hb
,,,,else
,,,,,hi=GetFileIcon(s 0 (imgWidth>=24 or imgHeight>=24))
,,,,,;g1
,,,,,ImageList_ReplaceIcon(il -1 iif(hi hi _dialogicon))
,,,,,if(hi) DestroyIcon hi
,,SetProp hcb "qm_il" il
,
,case WM_DESTROY
,if(icons) ImageList_Destroy RemoveProp(hcb "qm_il")
,
,case WM_DRAWITEM
,if(wParam=ctrlId) goto gDraw
ret

;gDraw
DRAWITEMSTRUCT* ds=+lParam
if(ds.itemID<0) ret
RECT r=ds.rcItem

CBITEMCOLOR c
c.hwnd=ds.hWndItem
c.item=ds.itemID
c.itemData=ds.itemData
c.isLB=ds.CtlType=ODT_LISTBOX
c.param=param
c.dtFlags=dtFlags^DT_NOPREFIX
c.selected=ds.itemState&(ODS_SELECTED|ODS_COMBOBOXEDIT)=ODS_SELECTED
c.bkColor=GetSysColor(iif(c.selected COLOR_HIGHLIGHT COLOR_WINDOW))
c.textColor=GetSysColor(iif(c.selected COLOR_HIGHLIGHTTEXT COLOR_WINDOWTEXT))
GetItemText c.hwnd c.item c.text c.isLB

if(callbackFunc) call callbackFunc &c

;background
__GdiHandle brush=CreateSolidBrush(c.bkColor)
FillRect ds.hDC &r brush
;icon
if icons
,il=GetProp(hcb "qm_il")
,int ii=iif(flags&2 ds.itemData ds.itemID)
,n=ImageList_GetImageCount(il); if(ii>=n) ii=n-1
,ImageList_Draw il ii ds.hDC r.left+1 r.top+1 0
;text
SetBkMode ds.hDC TRANSPARENT
SetTextColor ds.hDC c.textColor
r.left+imgWidth+4; r.top+2
DrawTextW ds.hDC @c.text -1 &r c.dtFlags
#3
My god man... that's some high level kung-fu coding you did there!
Thank you it works!!!!

EDIT:
When activating the below line (which can be found within the "case WM_INITDIALOG" part) the right listbox still doesn't work properly.

Code:
Copy      Help
SetWindowSubclass(id(8 hDlg) &sub.WndProc_Subclass_lbright_enter 1 0)

But I found a way around this, I put the below code under case IDOK:
Code:
Copy      Help
int hCheck=id(6 hDlg)
if(IsWindowEnabled(hCheck))
    _i=LB_SelectedItem(id(8 hDlg))
    out _i
ret

So now everything seems to work like it's supposed to with the listboxes having their text content rendered with font styling and showing the thumbnails.
#4
after looking further at the code the second subclass sub function is not needed as it does the same thing if you eliminate one of the subclass functions and call only one sub function for  both i think everything renders correctly  this renders both list boxes correctly

i think having 2 subfunctions doing the exact same thing was causing the conflict

Function playlist_test2a
Code:
Copy      Help
;g1
;;;below image resolutions: 64x64
str- imgs=
;$desktop$\test_image_0.png
;$desktop$\test_image_1.png
;$desktop$\test_image_2.png


str dd=
;BEGIN DIALOG
;0 "" 0x90C80A44 0x100 0 0 473 145 ""
;6 ListBox 0x54230151 0x200 3 2 194 131 ""
;8 ListBox 0x54230151 0x200 202 1 239 135 ""
;END DIALOG
;DIALOG EDITOR: "" 0x2040601 "*" "" "" ""

str controls = "6 8"
str lb6 lb8
lb6="list 1[]list 2[]list 3"
lb8="song 1[]song 2[]song 3"
int r=ShowDialog(dd &sub.DlgProc &controls)
if(r=3)
,goto g1
if(!r) ret

#sub DlgProc
function# hDlg message wParam lParam

str- imgs
CB_ItemImageAndColor hDlg message wParam lParam 8 imgs 1|16 64 64 DT_WORDBREAK &sub.ColorCallback
CB_ItemImageAndColor hDlg message wParam lParam 6 0 1 0 0 DT_WORDBREAK &sub.ColorCallback

sel message
,case WM_INITDIALOG
,,;;;Font style for both listboxes
,,__Font-- t_f1.Create("Tahoma" 12 1)
,,t_f1.SetDialogFont(hDlg "6 8")
,,;;;Make sure [ENTER] can be used in listbox
,,SetWindowSubclass(id(6 hDlg) &sub.WndProc_Subclass_lbleft_enter 1 0)
,,SetWindowSubclass(id(8 hDlg) &sub.WndProc_Subclass_lbleft_enter 1 0) ;; <============= activate this and right listbox does not render correctly
,,
,case WM_DESTROY
,case WM_COMMAND goto messages2
ret
;messages2
sel wParam
,case IDOK
,case IDCANCEL

,;;;In a later (final) version of this dialog needs to restart and reload the right listbox contents
,;;;It's done when user double clicks (or [ENTER]) on left listbox. I already implented this so any conflicts
,;;;regarding restarting dialog and rendering listboxes could be handled early on.
,case LBN_DBLCLK<<16|6
,,_i=LB_SelectedItem(lParam)
,,DT_Ok hDlg 3
,
ret 1

#sub WndProc_Subclass_lbleft_enter ;;menu File -> New -> Templates -> Wndproc -> WndProc_Subclass
function# hwnd message wParam lParam uIdSubclass dwRefData

sel message
,case WM_GETDLGCODE
,sel(wParam)
,,case [VK_SPACE] ret 0
,,case [VK_RETURN] ret DLGC_WANTALLKEYS ;;please send me WM_KEYDOWN instead of closing the dialog
,
,case WM_KEYDOWN
,sel(wParam) case [VK_RETURN,VK_SPACE] SendMessage GetParent(hwnd) WM_COMMAND LBN_DBLCLK<<16|GetDlgCtrlID(hwnd) hwnd; ret ;;to use the same code as for double-click
,;sel(wParam) case [VK_RETURN,VK_SPACE] SendMessage GetParent(hwnd) WM_COMMAND LBN_SELCHANGE<<16|GetDlgCtrlID(hwnd) hwnd; ret ;;to use the same code as for double-click

int R=DefSubclassProc(hwnd message wParam lParam)

sel message
,case WM_NCDESTROY
,RemoveWindowSubclass(hwnd &sub.WndProc_Subclass_lbleft_enter uIdSubclass)

ret R

#sub ColorCallback
function# CBITEMCOLOR&c

;This is a sample callback function that can be used with CB_ItemImageAndColor.
;Shows how to set combo/list box item background and text colors depending on item text.
;The function will be called for each item when displaying it.
;c contains various info that can be useful to draw the item.
;To set colors, change c.bkColor and/or c.textColor.
;Also you can change c.dtFlags and c.text.

;c.text - item text. In/out.
;c.bkColor - item background color. In/out.
;c.textColor - item text color. In/out.
;c.hwnd - control handle.
;c.item - item index.
;c.itemData - item data. To set item data, use message CB_SETITEMDATA or LB_SETITEMDATA, documented in MSDN.
;c.selected - 1 if the item is selected, 0 if not.
;c.isLB - 1 if the control is listbox, 0 if combobox.
;c.dtFlags - DrawText flags. Documented in the MSDN Library on the Internet. In/out.
;c.param - an user-defined value, passed to CB_ItemColor.


if(c.selected)
,c.bkColor=0
,c.textColor=0x00FFFF
,ret

sel c.text 2
,case "*list*" c.bkColor=ColorFromRGB(255 255 0)
,case "*song*" c.bkColor=0; c.textColor=0x00ff00
#5
Thank you!


Forum Jump:


Users browsing this thread: 1 Guest(s)