coda
Junior Member
Posts: 74
|
Post by coda on Jul 3, 2023 0:11:04 GMT -5
I know it isn't possible with native LB code but is it possible to ghost and unghost individual combobox list items using api calls? I know I have done this in the past with individual menu items. Does an equivalent technique exist for combobox items? Any help greatly appreciated.
|
|
|
Post by Rod on Jul 3, 2023 5:30:49 GMT -5
The usual way is to manage the array$ and remove unavailable items then reload. Thus the combobox only ever displays available items. If you want to ghost you might be better off using radiobuttons or checkboxes which can be disabled.
|
|
|
Post by Walt Decker on Jul 3, 2023 9:52:04 GMT -5
Yes. You do that by sending messages to the combo box control via User32.dll function SendMessageA(ComboboxHandle, Message, wParam, Lparam).
Messages sent: ' CB.ADDSTRING = HEXDEC("&H0143") <--- add a string at the bottom CB.DELETESTRING = HEXDEC("&H0144") <--- delete a string at index number CB.INSERTSTRING = HEXDEC("&H014A") <--- insert a string at index number'
Example - delete a string: CALLDLL #user32, "SendMessageA", CmbHndl AS ULONG, CB.DELETESTRING AS ULONG, 3 AS LONG, 0 AS LONG, RetVal AS VOID
Example - insert a string: CALLDLL #user32, "SendMessageA", CmbHndl AS ULONG, CB.INSERTSTRING AS ULONG, 6 AS LONG, Item$ AS PTR, RetVal AS VOID
Example - add a string: CALLDLL #user32, "SendMessageA", CmbHndl AS ULONG, CB.ADDSTRING AS ULONG, 0 AS LONG, Item$ AS PTR, RetVal AS VOID
EDIT: Item numbers in Windoz are zero based. Item numbers in LB are one based. Subtract 1(one) from the LB item number to get the Widoz item number.
However, LB does not use the combo box resources to select data items, it uses the array attached to the combo box. So you have to update that as well otherwise you will get a runtime error and your app will crash.
|
|
coda
Junior Member
Posts: 74
|
Post by coda on Jul 3, 2023 23:41:49 GMT -5
Thanks Rod for the suggestion. Appreciated. This really feels like a job for comboboxes however and I do kind of need my users to know that other options are available should they make other choiices. Thankyou so much yet again, Walt. I'm wanting to ghost the items, however, not remove them.
|
|
|
Post by tsh73 on Jul 4, 2023 1:46:03 GMT -5
It looks like there is no easy way to do it (gray things out). How about marking items, say with n/a?
item 1 [n/a] item 2 item 3 item 4 [n/a] item 5 item 6
|
|
|
Post by Rod on Jul 4, 2023 8:42:08 GMT -5
It is possible to roll your own combobox. However having done so I am not sure the ghosted out idea is that effective/intuitive. Folks expect a combobox to list choices, not unavailable choices.
global combo,maxn cbarray$(1)="One" cbarray$(2)="Two" cbarray$(3)="Three" cbarray$(4)="Four" cbarray$(5)="Five" cbarray$(6)="Six" cb(4)=1 'ghosted maxn=6
'nomainwin WindowWidth = 550 WindowHeight = 410 UpperLeftX=int((DisplayWidth-WindowWidth)/2) UpperLeftY=int((DisplayHeight-WindowHeight)/2) graphicbox #main.cb, 240, 50, 150, 20 graphicbox #main.ls, 240, 70, 150, 100 open "combobox study" for window as #main #main "trapclose quit" #main.ls "down ; font courier_new 10 regular" #main.cb "down ; font courier_new 10 regular"
call clearcombo h$,x,y #main.cb "when leftButtonDown checkcombo" wait
'this toggles the combobox on and off sub checkcombo h$,x,y if combo then call clearcombo h$,x,y else call selectcombo h$,x,y end sub
'this shows the dropdown and allows selection sub selectcombo h$,x,y #main.cb "cls ; fill white ; place 130 -1 ; backcolor cyan ; color black ; boxfilled 150 20" #main.cb "place 136 12 ;\v" #main.ls "show" #main.ls "when mouseMove highlight" #main.ls "when leftButtonDown pick" #main.ls "backcolor white ; color black ; place 0 10" y=15 'text height for n= 1 to maxn if cb(n)=0 then #main.ls "color black" else #main.ls "color darkgray" #main.ls "place 5 ";y;" ;\";cbarray$(n) y=y+15 next #main.ls "setfocus" combo=1 end sub
'this clears the combo sub clearcombo h$,x,y #main.cb "cls ; fill white ; place 130 -1 ; backcolor white ; color black; boxfilled 150 20" #main.cb "place 136 12 ;\v" #main.ls "when mouseMove" #main.ls "when leftButtonDown" #main.ls "hide" combo=0 end sub
'this highlights items under the cursor sub highlight h$,x,y yy=int(y/15)+1 y=15 for n= 1 to maxn if yy=n and cb(n)=0 then #main.ls "backcolor blue ; color white" if yy=n and cb(n)=1 then #main.ls "backcolor cyan ; color white" if yy<>n and cb(n)=0 then #main.ls "backcolor white ; color black" if yy<>n and cb(n)=1 then #main.ls "backcolor white ; color darkgray" #main.ls "place 5 ";y;" ;\";cbarray$(n) y=y+15 next end sub
'if the user picks an item it is displayed sub pick h$,x,y if cb(int(y/15)+1)=0 then #main.cb "cls ; fill white ; place 130 -1 ; backcolor cyan ;color black ; boxfilled 150 20" #main.cb "place 136 12 ;\v" #main.cb "backcolor blue ; color white ; place 5 15 ;\";cbarray$(int(y/15)+1) end if end sub
sub quit h$ Close #main END end sub
|
|
|
Post by Walt Decker on Jul 4, 2023 9:20:23 GMT -5
In order to gray out items the style has to be changed to CBS_OWNERDRAWFIXED or CBS_OWNERDRAWVARIABLE. Then you have to get get a handle and a DC for the combox. You have to get the text for the item of interest, change the text color for the item and redraw the text. That has to be done each time the physical aspect of the item changes. Do you really want to go that route?
EDIT: After further thought, I think the only way it can be done is through a dll that will capture the WM_MEASUREITEM and WM_DRAWITEM messages and act on them. I know that when one changes the style of an LB button to WM_USERDRAW the button disappears and when one changes the style of a static control to WM_USERDRAW the text in the control changes to "[userdrawn]" regardless of the supplied text. This implies that LB will do strange things to list and combobox controls when their style is changed to a user drawn style.
|
|
coda
Junior Member
Posts: 74
|
Post by coda on Jul 8, 2023 2:50:50 GMT -5
Thankyou tsh73. Something similar with a disallowing of the selection of those items may be the best option in the end. Wow, Rod... that's some of the best programming-foo I have seen in a long time. Miraculous! Also an option. Thanks so much, Walt. So if I understand correctly, it's probably not possible because of an unexpected interaction between Windows and LB... that's rather sad....
|
|