Code:
'¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ ' Some ComboBox fun. MS has given us %CB_SETDROPPEDWIDTH to set ' width of ComboBox's drop-list, but unfortunately, they made it ' left-aligned, so list stretches out to the right. Not so nice ' if list contains a scrollbar, for example. Typical MS logic.. ' ' This sample shows a way to force the list to be Right-aligned, ' so wider list stretches out to the left and scrollbar stays ' under drop-button. Much nicer that way, plus it's always fun ' to do "impossible" stunts with MS standard controls, IMHO.. [img]http://www.powerbasic.com/support/forums/smile.gif[/img] ' ' Public Domain sample by Borje Hagsten, February, 2003 ' ' Log, changes: ' Feb 4, 2003: cleaned up code under %WM_CTLCOLORLISTBOX. '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ #COMPILE EXE #INCLUDE "WIN32API.INC" DECLARE CALLBACK FUNCTION DlgProc() AS LONG '------------------------------------------------------------------ %AddCbLbWidth = 70 ' number of pixels to add to width.. '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ ' Main entrance '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ FUNCTION PBMAIN () AS LONG LOCAL hDlg AS DWORD, lRes AS LONG REDIM sArray(49) AS STRING 'for 50 items (zero based..) DIALOG NEW 0, "ComboBox trix",,, 102, 90, %WS_CAPTION OR %WS_SYSMENU, 0 TO hDlg '------------------------------------------------------------------ FOR lRes = 0 TO UBOUND(sArray) sArray(lRes) = "Standard list" + STR$(lRes) NEXT CONTROL ADD COMBOBOX, hDlg, 30, sArray(), 10, 5, 83, 80, _ %CBS_AUTOHSCROLL OR %CBS_DROPDOWN OR %WS_TABSTOP OR %WS_VSCROLL COMBOBOX SELECT hDlg, 30, 1 '------------------------------------------------------------------ FOR lRes = 0 TO UBOUND(sArray) sArray(lRes) = "Left-aligned wide list (MS way)" + STR$(lRes) NEXT CONTROL ADD COMBOBOX, hDlg, 31, sArray(), 10, 25, 83, 80, _ %CBS_AUTOHSCROLL OR %CBS_DROPDOWN OR %WS_TABSTOP OR %WS_VSCROLL CONTROL SEND hDlg, 31, %CB_GETDROPPEDWIDTH, 0, 0 TO lRes CONTROL SEND hDlg, 31, %CB_SETDROPPEDWIDTH, lRes + %AddCbLbWidth, 0 COMBOBOX SELECT hDlg, 31, 1 '------------------------------------------------------------------ FOR lRes = 0 TO UBOUND(sArray) sArray(lRes) = "Right-aligned wide list (Our way)" + STR$(lRes) NEXT CONTROL ADD COMBOBOX, hDlg, 32, sArray(), 10, 45, 83, 80, _ %CBS_AUTOHSCROLL OR %CBS_DROPDOWN OR %WS_TABSTOP OR %WS_VSCROLL COMBOBOX SELECT hDlg, 32, 1 '------------------------------------------------------------------ CONTROL ADD BUTTON, hDlg, %IDCANCEL, "&Quit", 48, 72, 50, 14 '------------------------------------------------------------------ DIALOG SHOW MODAL hDlg CALL DlgProc END FUNCTION '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ ' Main callback '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ CALLBACK FUNCTION DlgProc() AS LONG LOCAL rc AS RECT, rc2 AS RECT SELECT CASE CBMSG CASE %WM_CTLCOLORLISTBOX 'Note: WM_CTLCOLORLISTBOX is sent to parent when CB's list drops 'A problem is that it's sent for all lists, and that CB's drop-list 'actually is owned by the system - not the CB! CBLPARAM is list's 'handle, with no relation to CB, but since there can be only one dropped 'list (thanks for the tip, Lance) at a time, we can use %CB_GETDROPPEDSTATE 'to see if it belongs to our Combobox. And since this call is sent multiple 'times, we need to compare left positions to avoid multiple actions. IF SendMessage(GetDlgItem(CBHNDL, 32), %CB_GETDROPPEDSTATE, 0, 0) THEN 'make sure it's our combo GetWindowRect CBLPARAM, rc ' get list's RECT on screen GetWindowRect GetDlgItem(CBHNDL, 32), rc2 ' get combo's RECT on screen IF rc.nLeft = rc2.nLeft THEN ' compare left positions to avoid multiple actions rc.nLeft = rc2.nLeft - %AddCbLbWidth ' calculate new left pos rc.nRight = rc2.nRight - rc2.nLeft + %AddCbLbWidth ' calculate new width SetWindowPos CBLPARAM, 0, rc.nLeft, rc.nTop, _ ' set LB's new pos and width rc.nRight, rc.nBottom - rc.nTop, %SWP_NOZORDER END IF END IF CASE %WM_COMMAND ' <- a control is calling SELECT CASE CBCTL ' <- look at control's id CASE %IDCANCEL IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN 'end prog DIALOG END CBHNDL END IF END SELECT END SELECT END FUNCTION
------------------
http://www.tolkenxp.com/pb
Download: incLean, PBcodec, custom controls and code, etc.
Borje Hagsten - [email protected]
[This message has been edited by Borje Hagsten (edited February 03, 2003).]
Comment