Hello Charles
when i was doing the combobox control program, i notice that O2 uses zstring (which i think is a legacy from C style coding)
the question is that why we cannot use wstring or string but we must stick to zstring ?
i have tried string and it didn't work out for the combobox but it works for the Listbox control.
Hi Chris,
Could you try initialising the array of strings in global space first, and see whether this works in ComboBox
int i
dim string ArrayCB(20) : for i=1 to 20 : ArrayCB(i)="" : next
Fixed.
Hello Charles
i tried using your method but gotten a parameters mismatch error during compilation
please see the attachment
' Od_Combbox.o2bas
' Owner drawn Combobox
$ filename "Od_Combbox.exe"
use rtl64
#lookahead
' %review
uses O2Common
uses dialogs
' identifiers
% IDC_Combobox = 101
' The program logo icon is obtained from the resource file
' the 400 must corespondence to the 400 in the rc file
% IDI_LOGO 400
sys hDlg , hCombobox
' Will need this Array dimensioning macro
' otherwise results would be garbage
' Dim_zstring ArrayCB , 20, 30
string ArrayCB(20)
'=======================
FUNCTION O2Main
Dialog( 150, 70, 160, 75, "Ownerdrawn ComboBox ", WS_CAPTION OR WS_SYSMENU )
' Add in the combo box
sys CBBStyle = WS_CHILD or WS_VSCROLL or WS_TABSTOP OR CBS_DROPDOWNLIST OR _
CBS_HASSTRINGS or CBS_OWNERDRAWFIXED
COMBOBOX( "" ,IDC_Combobox, 10, 10, 60, 50, CBBStyle, WS_EX_CLIENTEDGE or WS_EX_ACCEPTFILES , 0 )
sys ebStyle = WS_CHILDWINDOW or WS_VISIBLE or BS_DEFPUSHBUTTON or WS_DLGFRAME
CONTROL "Exit", IDCANCEL,"Button", ebStyle , 85, 35, 30, 14
hDlg = CreateModalDialog( 0, @DlgProc, 0 )
END FUNCTION
'============================
' Main callback function
Function DlgProc( hDlg, uint uMsg, sys wParam, lParam ) as sys callback
zstring SelString , wAnswer
Long jj , CBIndex
hCombobox = GetDlgItem(hDlg, IDC_Combobox)
SELECT CASE uMsg
CASE WM_INITDIALOG
' display the program icon
sys hInstance = GetModuleHandle(NULL)
sys hIcon = LoadIcon(hInstance, IDI_Logo)
'Set Icon to Main Window
SendMessage(hDlg, WM_SETICON, ICON_BIG, hIcon)
' Setup the combobox elements
' BuildArrayCB
' Initialise the ArrayCB
sys i
for i=1 to 20 : ArrayCB(i) ="" : next i
BuildArrayCBst
For jj = 1 to 20
' SendMessage(hCombobox, CB_ADDSTRING, 0, ArrayCB[jj] )
SendMessage(hCombobox, CB_ADDSTRING, 0, ArrayCB(jj) )
Next jj
' set cursor to the first element of the combobox
SendMessage(hCombobox, CB_SETCURSEL, 0, 0)
CASE WM_ERASEBKGND
' added to display background color for the main window
' for a Light Yellow background
MainWindBGColor = 6
hBGDC = wParam
' Pass the DC of the region to be repaint
DrawGradient hBGDC
FUNCTION = 1
EXIT FUNCTION
CASE WM_COMMAND
SELECT CASE LOword(wParam)
CASE IDCANCEL
EndDialog( hDlg, null )
CASE IDC_Combobox
IF HIWORD(WPARAM) = CBN_SELENDOK THEN
' user selected something
CBindex = SendMessage(hComboBox, CB_GETCURSEL, 0, 0)
SendMessage(hComboBox, CB_GETLBTEXT, CBindex, @SelString)
wAnswer = TRIM(SelString)
Mbox " Selected : " + wAnswer , 0
END IF
END SELECT
CASE WM_DRAWITEM
' for owner drawn combo box
IF LOword(wParam) = IDC_Combobox THEN
OwnerDrwCombo hCombobox, WPARAM, LPARAM
END IF
END SELECT
END FUNCTION
'===================================
' Owner drawn procedure for the combo box
FUNCTION OwnerDrwCombo(sys BYVAL hWnd , sys BYVAL wParam , sys BYVAL lParam ) AS LONG
Zstring zTxt
RECT rct
DRAWITEMSTRUCT lpdis at lParam
IF lpdis.itemID = &HFFFFFFFF& THEN
'When it is an empty list -- just exit
EXIT FUNCTION
END IF
SELECT CASE lpdis.itemAction
CASE ODA_DRAWENTIRE, ODA_SELECT
'CLEAR BACKGROUND
IF ( lpdis.itemState AND ODS_SELECTED) = 0 OR _
( lpdis.itemState AND ODS_COMBOBOXEDIT) THEN
'When not selected
'text background
SetBkColor lpdis.hDC, O2c_AZURE
'text color
SetTextColor lpdis.hDC, GetSysColor( COLOR_WINDOWTEXT)
'clear background
FillRect lpdis.hDC, lpdis.rcItem,GetSysColorBrush( COLOR_WINDOW)
ELSE
' When the item is selected
' set the text background
SetBkColor lpdis.hDC, O2c_Light_Yellow
'set the text color
SetTextColor lpdis.hDC, O2c_MAGENTA
END IF
'Get the item text
SendMessage hWnd, CB_GETLBTEXT, lpdis.itemID, VARPTR(zTxt)
DrawText lpdis.hDC, zTxt, LEN(zTxt), lpdis.rcItem, _
DT_SINGLELINE OR DT_LEFT OR DT_VCENTER
' Focus rectangle and bullet must be drawn after the text
' otherwise these will overlap by the text
IF ( lpdis.itemState AND ODS_SELECTED) THEN
' when selected , set cordinates of bullet
' Draw the bullet pointer at the right end
' Note that you need to adjust these parameters to suit the
' size of each combobox and do some tests to fine tune
rct.Left = +106
rct.Right = lpdis.rcItem.Right + 25
rct.top = lpdis.rcItem.top +6
rct.bottom = lpdis.rcItem.bottom - 6
'Draw a round focus rectangle -- make it look like a bullet
RoundRect( lpdis.hDC, rct.Left, rct.top, rct.Right, rct.bottom, 48, 48)
'draw a focus rectangle around all
CALL DrawFocusRect( lpdis.hDC, lpdis.rcItem)
END IF
FUNCTION = TRUE
END SELECT
END FUNCTION
'====================================
Sub BuildArrayCB
' Setup the Combobox elements
' using ArrayCB
ArrayCB[1] = "One"
ArrayCB[2] = "Two"
ArrayCB[3] = "Three"
ArrayCB[4] = "Four"
ArrayCB[5] = "Five"
ArrayCB[6] = "Six"
ArrayCB[7] = "Seven"
ArrayCB[8] = "Eight"
ArrayCB[9] = "Nine"
ArrayCB[10] = "Ten"
ArrayCB[11] = "Eleven"
ArrayCB[12] = "Twelve"
ArrayCB[13] = "Thirteen"
ArrayCB[14] = "Fourteen"
ArrayCB[15] = "Fifteen"
ArrayCB[16] = "Sixteen"
ArrayCB[17] = "Seventeen"
ArrayCB[18] = "Eighteen"
ArrayCB[19] = "Nineteen"
ArrayCB[20] = "Twenty"
End Sub
Sub BuildArrayCBst
' Setup the Combobox elements
' using ArrayCB
ArrayCB(1) = "One"
ArrayCB(2) = "Two"
ArrayCB(3) = "Three"
ArrayCB(4) = "Four"
ArrayCB(5) = "Five"
ArrayCB(6) = "Six"
ArrayCB(7) = "Seven"
ArrayCB(8) = "Eight"
ArrayCB(9) = "Nine"
ArrayCB(10) = "Ten"
ArrayCB(11) = "Eleven"
ArrayCB(12) = "Twelve"
ArrayCB(13) = "Thirteen"
ArrayCB(14) = "Fourteen"
ArrayCB(15) = "Fifteen"
ArrayCB(16) = "Sixteen"
ArrayCB(17) = "Seventeen"
ArrayCB(18) = "Eighteen"
ArrayCB(19) = "Nineteen"
ArrayCB(20) = "Twenty"
End Sub
'----------------------------------
' Program starts
init_common_controls()
O2Main
Hello Charles
in what situation do we use zstring ?
what is the difference between zstring and the normal string ?
Sorry. You will need the square brackets because I used a C-style declaration.
int i
string ArrayCB[ 20 ] : for i=1 to 20 : ArrayCB( i )="" : next
zstring is the same as char. Still useful for making char buffers for windows stuff.
Thanxx Charles,
Now it works
i'm confused by the square and round brackets as use in O2 arrays.
in PB, we only use the round brackets for arrays.
Can you please elaborate when and where to use the square brackets for arrays with an example ?
Thanxx
You can use either square or round brackets for arrays. The only time it matters is when dimensioning an array c-style.
When the compiler sees:
int a(...)
it assumes it is a function declaration rather than an array.
Thanxx a lot Charles
Do you mean that when we do dimensioning or type assignment ,
we must use square brackets
for example
String ArrayCB[300]
Int myAry[450]
whilst normal working conditions for array
we use round brackets for example
For i = 1 to 45
myAry(i) = i + 233
Next i
are these principles correct ?
Yes, Chris.
If you prefer to dimension with round brackets, use dim
dim String ArrayCB(300)
dim Int myAry(450)
Thanxx a lot Charles