ShowDropdownList; QM_ComboBox and QM_Edit controls

ShowDropdownList

QM_ComboBox control

QM_Edit control

IQmDropdown

Using in exe

Function ShowDropdownList

#ShowDropdownList ICsv'csv [int&iSelected] [ARRAY(byte)&aChecked] [funcFlags] [hwndHost] [RECT&rDD] [cbFunc] [cbParam] [IQmDropdown&dd]
#ShowDropdownListSimple $csv [int&iSelected] [ARRAY(byte)&aChecked] [funcFlags] [hwndHost] [RECT&rDD]

 

Shows a temporary top-level window containing a list of items that can be selectable (like in ComboBox controls), check box (more like in multi-select ListBox controls) or disabled (can be used as headers, separators etc). By default all items are selectable. Items can have icons, colors, etc.

 

ShowDropdownListSimple is a simplified version of ShowDropdownList. It uses a CSV string as its first parameter, and several parameters are removed. Everything else is identical.

 

Returns one or more of these values (as flags):

flag name flag value  
QMDDRET_SELOK 1 Selected a selectable item (clicked or with Enter or Tab).
QMDDRET_CHECKCHANGED 2 Changed check box states.
QMDDRET_SELCHANGED 4 Changed the selected item. Can be only together with QMDDRET_SELOK.
QMDDRET_NOERRORS 0x100 DDL was shown (no errors).

Returns 0 if DDL could not be shown. For example, an invalid argument.

 

Parameters

csv - sets control properties, adds list items. With ShowDropdownList it is an ICsv variable; it also receives results, if iSelected/aChecked not used. With ShowDropdownListSimple it is a CSV string. Below is described the CSV format of the ICsv variable or CSV string.

 

First row - control properties. Columns:

 

Other CSV rows - list items. Columns:

 

With ShowDropdownListSimple, csv must be valid CSV string. If a cell text contains special characters (comma (,), double quote ("), new line), it must be enclosed in double quotes. Double quotes in cell text must be replaced with two double quotes.

 

In numeric cells you can use decimal numbers, hexadecimal numbers (like "0xE"), and expressions with operator | (like "1|4|0x300").

 

CSV control flags and item flags have numeric named constants, defined in \System\Declarations\QmDll. The names can be used in CSV if it is F-string, for example str csv=F",,{QMDD_CHECKBOXES1|QMDD_AUTOCOLORS}[]...".

 

iSelected - variable that sets and receives selected item index.

aChecked - array variable that sets checked item states. Elements of checked items contain flag 1.

funcFlags - function flags:

hwndHost - host control handle. The DDL will be below or above the host control, and will have its width and font.

rDD - a RECT variable. If used:

Other parameters

cbFunc, cbParam - address of a callback function, and a value to pass to it. It will be called to notify about various events. Must begin with:

function# cbParam QMDROPDOWNCALLBACKDATA&x

cbParam - cbParam of ShowDropdownList.

x - event info.

type QMDROPDOWNCALLBACKDATA IQmDropdown'dd code itemIndex itemState

dd - IQmDropdown variable. You can call functions x.dd.Check, x.dd.IsChecked etc.

code - event code:

  • 1,2 - a check box state changed. itemIndex is item index. itemState is 1 if the item now is checked, 0 if not. When the user checks/unchecks, code is 1; when function Check does it, code is 2. Return 0.

 

dd - a variable that receives IQmDropdown interface pointer. Valid only while the DDL is visible. When ShowDropdownList returns, it sets the variable to 0. For example, if you call ShowDropdownList in a dialog procedure, and want to close the DDL when the procedure receives some message, you can call dd.Close then. Also you can call dd.Check, dd.IsChecked etc.

 

Other features

Keyboard shortcuts (can use them only if hwndHost is used and is active and belongs to current thread):

 

Examples

 Shows drop-down list and gets the selected item index.
str imagelist="$qm$\il_qm.bmp" ;;tip: to see images in QM code editor, check toolbar button "Images in code editor"
str csv=
F
 ,{imagelist}
 one,1
 two,2
 three

int iSelected
int R=ShowDropdownListSimple(csv iSelected)
out F"R=0x{R}, selected={iSelected}"

 

 Shows drop-down list with check boxes; uses a 32-bit variable to get checked items.
str icons="$qm$\new.ico[]$qm$\copy.ico[]$system$\shell32.dll,4"
str csv=
F
 ,"{icons}",2
 one,1
 two,2
 three,,1

int checked
int R=ShowDropdownListSimple(csv checked)
out F"R=0x{R} checkBoxes=0x{checked}"

int i
for i 0 3
	if(checked>>i&1) out F"item {i} is checked"

 

 Shows drop-down list with check boxes and gets checked items from CSV.
str csv=
 ,,1
 one,1
 two,2
 three,,1

ICsv x._create; x.FromString(csv)

int R=ShowDropdownList(x)
out F"R=0x{R}"
 x.ToString(_s); out _s

int i
for i 1 x.RowCount
	if(x.CellInt(i 2)&1) out F"item {i-1} is checked"

 

QM_ComboBox control

Controls of window class QM_ComboBox are ComboBox controls with a better drop-down list. Can have images, check boxes (multiple selections), etc. For the drop-down list part the control uses function ShowDropdownList.

 

To add a QM_ComboBox control to a dialog, use the Dialog Editor. To set and get control data (properties and list items), use dialog variables created by the Dialog Editor.

 

Example dialog

 

\Dialog_Editor

str dd=
 BEGIN DIALOG
 0 "" 0x90C80AC8 0x0 0 0 224 136 "Dialog"
 3 QM_ComboBox 0x54230243 0x0 8 8 96 213 ""
 4 QM_ComboBox 0x54230242 0x0 8 28 96 213 ""
 5 QM_ComboBox 0x54230243 0x0 8 48 96 213 ""
 6 QM_ComboBox 0x54230243 0x0 8 68 96 213 ""
 1 Button 0x54030001 0x4 116 116 48 14 "OK"
 2 Button 0x54030000 0x4 168 116 48 14 "Cancel"
 END DIALOG
 DIALOG EDITOR: "" 0x2040300 "*" "" "" ""

str controls = "3 4 5 6"
str qmcb3 qmcb4 qmcb5 qmcb6
 Simplest. Adds three items and selects Mercury (index 0).
qmcb3="0[]Mercury[]Venus[]Earth"
 With icons. Adds three items, selects Mercury, and in the drop-down list displays the first three images from the imagelist file.
str imagelist="$qm$\il_qm.bmp" ;;tip: to see images in QM code editor, check toolbar button "Images in code editor"
qmcb4=F"0,{imagelist}[]Mercury,0[]Venus,1[]Earth,2"
 With check boxes. Adds three items, checks Mercury (its item flags contain 1), and sets control text to "Mercury".
qmcb5=",,1[]Mercury,,1[]Venus,,0[]Earth"
 With check boxes, using a 32-bit number to check items. Adds three items, checks Mercury and Earth (first and third bits in 0x5 are 1), and sets control text to "Mercury, Earth".
qmcb6=
 0x5,,3
 Mercury
 Venus
 Earth

if(!ShowDialog(dd 0 &controls)) ret

out qmcb3
out qmcb4
out qmcb5
out qmcb6

 

How to set control properties and list items

Assign a CSV string to the dialog control variable before calling ShowDialog.

 

First CSV row - control properties. Columns:

 

Other CSV rows - list items. Columns:

 

It must be valid CSV string. If a cell text contains special characters (comma (,), double quote ("), new line), it must be enclosed in double quotes. Double quotes in cell text must be replaced with two double quotes. To create valid CSV at run time, use an ICsv variable.

 

In numeric cells you can use decimal numbers, hexadecimal numbers (like "0xE"), and expressions with operator | (like "1|4|0x300").

 

List items in the CSV are optional. For example, you may want just to set control properties. You can add items later, when handling CBN_DROPDOWN notification in dialog procedure. If on CBN_DROPDOWN you don't add items, the control will not show a drop-down list. On CBN_DROPDOWN you can instead call ShowDropdownList, or show a message box, popup menu, whatever, or do nothing; but for this purpose probably it is better to use QM_Edit control.

 

If you want to set control data in dialog procedure, use function DT_SetControl or CB_Add or CB_INSERTITEM messages. Function str.setwintext sets editable control text.

 

How to get control data

When ShowDialog returns on OK, the dialog control variable contains a string in a format that depends on control style and flags.

 

By default it is:

If used control flag 0x100, it is initial CSV string (you can use ICsv to parse it), modified depending on user-made selection:

 

If you want to get control data in dialog procedure, use function DT_GetControl. Function str.getwintext gets control text.

 

Styles, messages and notifications

The control is based on standard ComboBox control (except the drop-down list part) and supports the most important its features.

 

Supported ComboBox styles: CBS_DROPDOWN (editable), CBS_DROPDOWNLIST (read-only), CBS_SORT, CBS_AUTOHSCROLL, CBS_LOWERCASE, CBS_UPPERCASE. Cannot be CBS_SIMPLE or owner-draw.

 

Supported ComboBox messages: CB_GETDROPPEDSTATE, CB_ADDSTRING, CB_INSERTSTRING, CB_DELETESTRING, CB_RESETCONTENT, CB_GETCOUNT, CB_GETCURSEL, CB_GETITEMDATA, CB_SETITEMDATA, CB_GETLBTEXT, CB_GETLBTEXTLEN, CB_SHOWDROPDOWN, CB_GETCOMBOBOXINFO, CB_GETCUEBANNER, CB_GETEDITSEL, CB_LIMITTEXT, CB_SETCUEBANNER, CB_SETEDITSEL.

 

The control supports QM CB_ functions (CB_SelectedItem etc). The functions send the above messages.

 

Partially supported ComboBox messages: CB_GETITEMHEIGHT, CB_SETITEMHEIGHT - only if wParam is -1. Messages that modify the list fail and return -1 when the list is dropped down. CB_GETDROPPEDWIDTH and CB_SETDROPPEDWIDTH not supported but automatic width can be specified in CSV (column 6, flag 0x40).

 

Other messages: LB_SETSEL sets item check state. LB_GETSEL gets item check state.

 

Supported ComboBox notifications: CBN_CLOSEUP, CBN_DROPDOWN, CBN_EDITCHANGE, CBN_EDITUPDATE, CBN_KILLFOCUS, CBN_SELCHANGE, CBN_SELENDCANCEL, CBN_SELENDOK, CBN_SETFOCUS.

 

The above messages, notifications and styles are documented in the MSDN Library.

 

Other notifications

The control also sends other notifications using WM_NOTIFY message, where lParam is address of a NMQMCB variable. Its first member hdr is of type NMHDR (documented in MSDN). Values of other members depend on notification code (hdr.code).

 

type NMQMCB NMHDR'hdr IQmDropdown'dd itemIndex itemState

 

Notification codes:

 

Other features

Incremental search. When the user changes editable control text while the drop-down list is shown, the control highlights the first item whose text begins with or contains the new text. Use Enter or Tab to select it. Only if without check boxes.

 

Adds large number of items much faster than ComboBox.

 

Shows "..." and infotip for clipped items.

 

Keyboard and mouse shortcuts:

 

Keyboard shortcuts in drop-down list:

 

QM_Edit control

Controls of window class QM_Edit are Edit controls that can have one or two buttons next to the edit field.

 

By default the control has an arrow button, similar as in ComboBox controls. When pressed, the control sends CBN_DROPDOWN command message to the parent dialog. The dialog procedure then can show a drop-down list (see example) or do whatever, and then set control text if need. The control itself does not show a drop-down list etc.

 

The control also can have another button (user button). When clicked, the control sends BN_CLICKED command message to the parent dialog. The dialog procedure then can do whatever, for example show a "Open file" dialog (see example) and set control text.

 

To add a QM_Edit control to a dialog, use the Dialog Editor. To set/get control text before/after ShowDialog, use dialog variables created by the Dialog Editor. Dialog variables contain control text. To set/get control text in dialog procedure, you can use str.setwintext/str.getwintext or DT_SetControl/DT_GetControl.

 

The control supports all Edit control styles, messages and notifications.

 

Messages specific to QM_Edit control:

 

WM_COMMAND notifications specific to QM_Edit control:

 

Keyboard and mouse shortcuts:

 

You can replace existing Edit controls with QM_Edit controls:

 

To create a multiline control, add styles ES_MULTILINE, ES_WANTRETURN, ES_AUTOVSCROLL, WS_VSCROLL and WS_EX_LEFTSCROLLBAR. Remove ES_AUTOHSCROLL if need to wrap lines.

 

Example

\Dialog_Editor

str dd=
 BEGIN DIALOG
 0 "" 0x90C80AC8 0x0 0 0 224 136 "Dialog"
 3 QM_Edit 0x56030080 0x200 8 8 96 12 ""
 4 QM_Edit 0x56030080 0x200 8 28 208 12 ""
 1 Button 0x54030001 0x0 168 116 48 14 "OK"
 END DIALOG
 DIALOG EDITOR: "" 0x2040300 "*" "" "" ""

str controls = "3 4"
str qme3 qme4
qme3="zero"
if(!ShowDialog(dd &sub.DlgProc &controls _hwndqm)) ret
out qme3
out qme4


#sub DlgProc
function# hDlg message wParam lParam

sel message
	case WM_INITDIALOG
	SendDlgItemMessage hDlg 4 QMEM_SETBUTTON 0 0 ;;add user button "open folder" and remove arrow
	SendDlgItemMessage hDlg 4 EM_SETCUEBANNER 0 @" File"
	
	case WM_COMMAND goto messages2
ret
 messages2
sel wParam
	case CBN_DROPDOWN<<16|3 ;;pressed the arrow button
	 show drop-down list, like ComboBox
	lpstr o=":5 $qm$\il_qm.bmp"
	str s=F"0,{o}[]zero,1[]one,2[]two,28"
	ICsv x._create; x.FromString(s)
	int i R=ShowDropdownList(x i 0 1 lParam)
	if(R&QMDDRET_SELOK=0) ret
	s=x.Cell(i+1 0); s.setwintext(lParam)
	
	case 4 ;;clicked the user button (BN_CLICKED)
	str sFile
	if(OpenSaveDialog(0 sFile)) sFile.setwintext(lParam)
ret 1

 

Interface IQmDropdown

Can be used in callbacks, notifications, etc, while the drop-down list is shown.

 

interface# IQmDropdown :IUnknown
	Check(i flags)
	#IsChecked(i)
	#Select(i [flags])
	Close([flags])
	Update(iFirst [iLast] [flags])
	[g]#Hwnd()
	[g]#HwndLV()
	[g]#SelectedItem()
	[g]ARRAY(byte)ItemStates()
	[g]ICsv'Csv()
	{A461B246-3C33-4398-915B-0B834A60A670}

 


Check(i flags)

 

Changes checkbox state of item i.

Returns 1. Returns 0 if i is invalid or the item is not a check box.

flags: 0 uncheck, 1 check, 2 toggle, 0x100 don't call cbFunc.


#IsChecked(i)

 

Returns 1 if item i is checked, 0 if not.


#Select(i [flags])

 

Selects/highlights item i.

Returns new selected item index.

flags: 1 don't ensure visible, 2 skip disabled down, 4 skip disabled up.

If i is invalid (eg -1), removes selection and returns -1. Also if the item is disabled, if not used flag 2 or 4.

Does not close the window. Call Close for it.


Close([flags])

 

Closes the DDL window.

flags: 1 OK (close like when the user clicks a selectable item or presses Enter or Tab).


Update(iFirst [iLast] [flags])

 

Redraws one or more list items.

Call this function to apply changes to item properties in csv that you get with Csv.

iFirst - 0-based index of first item to update.

iLast - 0-based index of last item to update. If omitted or <= iFirst, updates only iFirst.

flags: 1 item flags (third column) changed in csv. Don't need this flag if changed other columns (colors, text etc).


[g]#Hwnd()

 

Gets drop-down window handle. It is a top-level window.


[g]#HwndLV()

 

Gets listview control handle. It is a child window.


[g]#SelectedItem()

 

Gets the currently highlighted item index or -1.


[g]ARRAY(byte)ItemStates()

 

Gets array of item check states and other states/styles. Elements contain item flags from csv passed to ShowDropdownList (or from CSV string passed to QM_ComboBox control). These flags are updated: 1 checked, 0x80 check box state changed.


[g]ICsv'Csv()

 

Gets the csv variable passed to ShowDropdownList (or an ICsv variable created from CSV string passed to QM_ComboBox control). You can change item text, icon, tooltip, colors and indent: modify item cells in csv and call Update. You can add more columns, but don't add/remove rows and don't modify the first row (control properties).

How to use in exe

All these functions, iterfaces and controls can be used in exe too. All they live in a QM dll qmgrid.dll, which it is not available on computers where QM is not installed.

 

You can add the dll to exe. Add this line somewhere near the beginning of exe code:

 

ExeQmGridDll

 

When creating exe, it adds qmgrid.dll to exe resources. At run time it extracts to the temporary folder and loads.

 

If you don't want to add the dll to exe: take qmgrid.dll from QM folder; add to a zip file or setup program together with exe; on other computers extract them to the same folder. If you use the controls in dialogs or with CreateControl, exe loads the dll when need, else you can load it with LoadLibrary.

 

You can add imagelist and icon files to exe resources. In "Make Exe" dialog check "Auto add files..." and in macro add unique resource id numbers to file paths, like ":5 $my qm$\imagelist.bmp". Alternatively you can use macro resources. In the Resources dialog you can import files and create a resource string like "resource:<macro5>image:imagelist" or "image:imagelist". The file/resource name must be in a separate variable (see example), not directly in CSV string. If you don't want to add files to exe, make sure that they are available on computers where exe will run.

 

Example

str imagelist=":5 $qm$\il_qm.bmp" ;;5 is a resource id, can be 1-0xffff
str csv=
F
 ,{imagelist}
 one,1
 two,2
 three