October 31, 2025, 11:37:49 AM

News:

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


Listbox small bitmaps

Started by aurelCB, June 08, 2010, 01:37:12 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

aurelCB

Hi people ...
I wanna add small bitmap image before text in lisbox item.
I've search trough forum but i only found one example for ownerdraw listbox for Aurora with
subclassing.Then i just look into Aurora examples and found one simpatic example for combobox
with small bitmaps before text in combox items called 'ComboboxEx_Example'.
This small program enable bitmaps on very easy way- is something like this posibile in IWBasic to?
Or maby someone already have some example with listbox bitmaps?
Any help will be ok...

thanks advance .... :)
Aurel

sapero

Hi, I've created one for you :)
It uses the new subclassing API's from Windows XP: SetWindowSubclass, DefSubclassProc, RemoveWindowSubclass

$include "windowssdk.inc"
$include "commctrl.inc"
CONST LISTBOX_1 = 1000
DIALOG d1
CREATEDIALOG d1,0,0,300,202,0x80CB0080,0,"Caption",&d1_handler
CONTROL d1,@LISTBOX,"ListBox1",13,10,173,175,0x50A10140|LBS_OWNERDRAWFIXED,LISTBOX_1

$define SUBCLASS1_ID 12345 ' any number

HBITMAP g_image1 = LoadImage("D:\\download\\home.bmp", @IMGBITMAP)
DOMODAL d1
if (g_image1) then DeleteImage(g_image1, @IMGBITMAP)

SUB d1_handler
SELECT @MESSAGE
CASE @IDINITDIALOG
SetWindowSubclass(d1.hwnd, &MySubclassProc, SUBCLASS1_ID, 0)
CENTERWINDOW d1
OnInitDialog()

CASE @IDCLOSEWINDOW
RemoveWindowSubclass(d1.hwnd, &MySubclassProc, SUBCLASS1_ID)
CLOSEDIALOG d1,@IDOK

CASE @IDCONTROL
SELECT @CONTROLID
CASE LISTBOX_1
/* respond to control notifications here */
ENDSELECT
ENDSELECT
RETURN
ENDSUB


sub OnInitDialog()
' add some string, saving its indexes
int item_1_index = SendMessage(d1, LB_ADDSTRING, 0, "item 1", LISTBOX_1)
int item_2_index = SendMessage(d1, LB_ADDSTRING, 0, "item 2", LISTBOX_1)
' assign images
SendMessage(d1, LB_SETITEMDATA, item_1_index, g_image1, LISTBOX_1)
'SendMessage(d1, LB_SETITEMDATA, item_2_index, g_image2, LISTBOX_1)
endsub


sub MySubclassProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam,UINT_PTR uIdSubclass,DWORD_PTR dwRefData)
int imageWidth, imageHeight
int itemWidth, itemHeight
int TextPadding

select (uMsg)
case WM_DRAWITEM
if( (*<DRAWITEMSTRUCT>lParam.CtlType = ODT_LISTBOX) _
and (*<DRAWITEMSTRUCT>lParam.CtlID = LISTBOX_1) _
and (*<DRAWITEMSTRUCT>lParam.itemID >= 0))
' set default text.padding.left
TextPadding = 2

' Erase item background
FillRect(*<DRAWITEMSTRUCT>lParam.hDC, &*<DRAWITEMSTRUCT>lParam.rcItem, _
GetSysColorBrush(IIF(*<DRAWITEMSTRUCT>lParam.itemState & ODS_SELECTED, _
COLOR_HIGHLIGHT, COLOR_WINDOW)))

' check if this item has assigned image
if (*<DRAWITEMSTRUCT>lParam.itemData)
' get the size of image
GetBitmapSize *<DRAWITEMSTRUCT>lParam.itemData, imageWidth, imageHeight

' get item width and height
itemWidth = *<DRAWITEMSTRUCT>lParam.rcItem.right - *<DRAWITEMSTRUCT>lParam.rcItem.left
itemHeight = *<DRAWITEMSTRUCT>lParam.rcItem.bottom - *<DRAWITEMSTRUCT>lParam.rcItem.top

' put the image into device context, so we can Blt' it
HDC hDevCtx = CreateCompatibleDC(*<DRAWITEMSTRUCT>lParam.hDC)
HGDIOBJ imageOld = SelectObject(hDevCtx, *<DRAWITEMSTRUCT>lParam.itemData)

' show the image ...
int top = *<DRAWITEMSTRUCT>lParam.rcItem.top
' ... centered vertically, if possible ...
if (imageHeight < itemHeight) then top += ((itemHeight-imageHeight) / 2)

' clip image
imageWidth  = __min(imageWidth, itemWidth)
imageHeight = __min(imageHeight,itemHeight)

BitBlt(*<DRAWITEMSTRUCT>lParam.hDC, /*target device context: listbox*/_
*<DRAWITEMSTRUCT>lParam.rcItem.left, /*target X: left aligned*/_
top,         /*target Y*/_
imageWidth,  /*target width*/_
imageHeight, /*target height*/_
hDevCtx,     /*source device context: image*/_
0, 0,        /*source X,Y*/_
SRCCOPY)

' deselect the image from device context
SelectObject(hDevCtx, imageOld)
DeleteDC(hDevCtx)

TextPadding = (imageWidth + 4 /*small space*/)
endif

' any text to draw?
HWND hwndListbox = *<DRAWITEMSTRUCT>lParam.hwndItem
' number of characters
int cchText = _SendMessage(hwndListbox, LB_GETTEXTLEN, *<DRAWITEMSTRUCT>lParam.itemID, 0)
if (cchText)
' get the string
pointer pText = new(TCHAR, cchText+1)
_SendMessage(hwndListbox, LB_GETTEXT, *<DRAWITEMSTRUCT>lParam.itemID, pText)
' setup text coordinates, equal to *<DRAWITEMSTRUCT>lParam.rcItem
WINRECT rc
CopyRect(&rc, &*<DRAWITEMSTRUCT>lParam.rcItem)
' skip the image
rc.left += TextPadding
UINT bkMode = SetBkMode(*<DRAWITEMSTRUCT>lParam.hDC, TRANSPARENT)
DrawText(*<DRAWITEMSTRUCT>lParam.hDC, pText, cchText, &rc, DT_SINGLELINE|DT_VCENTER)
SetBkMode(*<DRAWITEMSTRUCT>lParam.hDC, bkMode)
delete pText
endif
' do not forward this message to default handlers, we handled it
return 0
endif
endselect
return DefSubclassProc(hWnd, uMsg, wParam, lParam)
endsub

aurelCB

WOW that looks very complex for me...
Thanks Sapero i will study this and compare with - one bcx code which i have.
Aurora seems that have same thing included internaly as i see in that combbox example.

LarryMc

Aurel

What makes the Aurora example look so much easier is the combobox ability is a windows thing I believe.

Really has nothing to do with IWB vs Aurora.

Sapero can correct me if I'm wrong.

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

sapero

A listbox control was originally designed to display text only. This applies also to combobox, because it uses a listbox as child/popup window.
ComboBoxEx is yet another control. It uses ownerdrawn combobox and is able to display images, including indentaton, so the internal listbox can display simple trees.

Do you mean ComboBoxEx_Example.src example?

aurelCB

June 09, 2010, 03:35:40 AM #5 Last Edit: June 09, 2010, 04:07:52 AM by aurelCB
Yes Sapero this example, and yes you are right in some other languages technic to do this is very similiar.
thanks....

by the way i think that i use wrong control for what i need, i think that better option will be treeview control.

Aurel