I was looking solution for changing grid to display one cell i few lines (like a richeditbox).
I don't need formatting, I only want to display one cell splitted to few lines.
In control based on winapi ListView it's possible, but it's necessery to change one procedure - DrawItemProcedure.
I have a sample in basic, but I don't know how to translate it to HMG. Maybe some guru from C programming can help?
Code: Select all
' ListView CustomDraw Multiline
' compile Windows - Allan
' Is to make the Details column multiline....where required
$include "windows.inc"
$include "commctrl.inc"
CONST STATIC_1 = 1
CONST EDIT_2 = 2
CONST STATIC_3 = 3
CONST EDIT_4 = 4
CONST LV_DISP = 5
CONST BTN_ADD = 6
UINT g_OldDlgProc
declare EBDLGPROC(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam),LRESULT
const LBS_MULTILINE = WS_CHILD|WS_VISIBLE|WS_VSCROLL|LBS_OWNERDRAWVARIABLE|LBS_NOINTEGRALHEIGHT
const LISTITEMDATA_TIME_LEN = 10
TYPE LISTITEMDATA
ISTRING time[LISTITEMDATA_TIME_LEN] ' up to 8 characters here: "10.00 AM"
ISTRING text[1] ' "Ring Head Office regards promotional campaign"
ENDTYPE
DIALOG d1
CREATEDIALOG d1,0,0,365,256,0x80CA0880,0,"ListView Custom Draw",&d1_handler
CONTROL d1,@STATIC,"Time",23,12,28,15,0x5000010B,STATIC_1
CONTROL d1,@EDIT,"",64,10,70,20,0x50810080,EDIT_2
CONTROL d1,@STATIC,"Details",23,45,35,14,0x5000010B,STATIC_3
CONTROL d1,@EDIT,"",62,42,276,39,0x50810044,EDIT_4
CONTROL d1,@BUTTON,"Add",264,11,70,20,0x50010000,BTN_ADD
CONTROL d1,@LISTBOX,"",19,92,325,148,0,LV_DISP
' Show the Dialog and Wait For it To close
DOMODAL d1
' End program
END
SUB d1_handler
HWND hwndList
SELECT @MESSAGE
CASE @IDINITDIALOG
hwndList = GetControlHandle(d1, LV_DISP)
' call InitList to initialize the listbox.
' NOTE: the variable 'hwndList' will change
InitList(hwndList, 60)
'SendMessage(hwndList, LB_DELETESTRING, 0, 0)
'the first row item and sub items
InsertListItem(hwndList,"10.00 AM", "Ring Head Office regards promotional campaign")
'the second row item and sub items
InsertListItem(hwndList,"11.30 AM","Appointment with Sales Team")
'the third row item and sub items
InsertListItem(hwndList,"1.30 PM","Meet Adrian from Calcat at Airport and hand over the Overseas Portfolio for next Seasons Promotional Campaign")
'the fourth row item and sub items
InsertListItem(hwndList,"3.30 PM","Advise Head Office on todays events")
InsertListItem(hwndList,"00.00 AM","something")
InsertListItem(hwndList,"00.01 AM","something")
InsertListItem(hwndList,"00.02 AM","something")
InsertListItem(hwndList,"00.03 AM","something")
CASE @IDCLOSEWINDOW
hwndList = GetControlHandle(d1, LV_DISP)
' remove memory-items
RemoveAllListItems(hwndList)
CLOSEDIALOG d1,@IDOK
CASE @IDCONTROL
hwndList = GetControlHandle(d1, LV_DISP)
SELECT @CONTROLID
CASE EDIT_2
/* respond to edit notifications here */
CASE EDIT_4
/* respond to edit notifications here */
CASE BTN_ADD
IF @NOTIFYCODE = 0
/*button clicked*/
InsertListItem(hwndList,GetControlText(d1, EDIT_2),GetControlText(d1, EDIT_4))
ENDIF
ENDSELECT
ENDSELECT
RETURN
ENDSUB
sub InitList(HWND hwndList byref, int ColumnWidth)
HWND hwndParent
int ListId
HFONT hFont
WINRECT rc
hwndParent = GetParent(hwndList)
ListId = GetWindowLong(hwndList, GWL_ID)
' hide the present listbox and create new one, without LBS_HASSTRINGS flag.
' Emergence forces the LBS_HASSTRINGS flag, so we need to create a new box.
' size and position
GetWindowRect(hwndList, &rc)
MapWindowPoints(0, d1.hwnd, &rc, 2)
' also duplicate current font
hFont = SendMessage(hwndList, WM_GETFONT, 0, 0)
' this will resize all controls and remove gui font from all controls
'DestroyWindow(hwndList)
' so better is to hide the old listbox
_ShowWindow(hwndList, SW_HIDE)
' kill also listbox ID
SetWindowLong(hwndList, GWL_ID, 0)
' subclass the dialog, because we need WM_DRAWITEM
g_OldDlgProc = SetWindowLong(d1.hwnd, GWL_WNDPROC, &ForwardDrawItemProc)
' create new listbox
hwndList = CreateWindow(WC_LISTBOX, NULL, LBS_MULTILINE, _
rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top, _
hwndParent, ListId, _hinstance, 0)
' save first column width
SetProp(hwndList, "colw", ColumnWidth)
' restore font
SendMessage(hwndList, WM_SETFONT, hFont, 0)
return
endsub
sub MeasureListItem(HWND hwndList, int wParam, MEASUREITEMSTRUCT mis),BOOL
' this is called once for every inserted listbox item.
' we need to return width and height for current item;
' TODO: remove the FirstColWidth parameter
pointer itemdata
pointer pText
int FirstColWidth
HDC hdc
WINRECT rc
HFONT font
int maxWidth
FirstColWidth = GetProp(hwndList, "colw")
' pointer to LISTITEMDATA
itemdata = SendMessage(hwndList, LB_GETITEMDATA, mis.itemID, 0)
' get width and height of our listbox
GetClientRect(hwndList, &rc)
' item width = listbox width
mis.itemWidth = rc.right
'remove first column from rectangle
' rc.left = FirstColWidth
rc.right -= FirstColWidth
pText = "A"
hdc = GetDC(hwndList)
font = SelectObject(hdc, SendMessage(hwndList, WM_GETFONT, 0, 0))
if (itemdata)
pText = *<LISTITEMDATA>itemData.text
endif
' get text height
maxWidth = rc.right
mis.itemHeight = DrawText(hdc, pText, -1, &rc, DT_WORDBREAK|DT_CALCRECT) + 2
SelectObject(hdc, font)
ReleaseDC(hwndList, hdc)
return true
endsub
sub DrawListItem(HWND hwndList, int wParam, DRAWITEMSTRUCT dis),BOOL
pointer itemdata
WINRECT rc
COLORREF BkColor
int FirstColWidth
FirstColWidth = GetProp(hwndList, "colw")
' pointer to LISTITEMDATA
itemdata = SendMessage(hwndList, LB_GETITEMDATA, dis.itemID, 0)
' draw selection background if the item is selected
if (dis.itemAction & ODA_SELECT)
BkColor = GetSysColorBrush(IIF(dis.itemState & ODS_SELECTED, COLOR_HIGHLIGHT, COLOR_WINDOW))
CopyRect(&rc, &dis.rcItem)
rc.top++
FillRect(dis.hDC, &rc, BkColor)
endif
' do not draw text background in DrawText()
SetBkMode(dis.hDC, TRANSPARENT)
' draw first column aligned to right
CopyRect(&rc, &dis.rcItem)
rc.top++
rc.right = FirstColWidth - 4
DrawText(dis.hDC, *<LISTITEMDATA>itemData.time, -1, &rc, DT_RIGHT)
' draw second column
CopyRect(&rc, &dis.rcItem)
rc.top++
rc.left = FirstColWidth + 4
DrawText(dis.hDC, *itemData.text, -1, &rc, DT_WORDBREAK)
' draw grid lines
HBRUSH hbr
HPEN pen
hbr = SelectObject(dis.hDC, GetStockObject(NULL_BRUSH))
pen = SelectObject(dis.hDC, CreatePen(PS_SOLID, 1, rgb(128,128,198))) /*grid color*/
' horizontal
MoveToEx(dis.hDC, 0, rc.bottom, NULL)
_LineTo(dis.hDC, rc.right, rc.bottom)
' vertical
MoveToEx(dis.hDC, FirstColWidth, rc.top, NULL)
_LineTo(dis.hDC, FirstColWidth, rc.bottom)
' vertical again
MoveToEx(dis.hDC, dis.rcItem.right-1, rc.top, NULL)
_LineTo(dis.hDC, dis.rcItem.right-1, rc.bottom)
DeleteObject(SelectObject(dis.hDC, pen))
SelectObject(dis.hDC, hbr)
return true
endsub
sub InsertListItem(HWND hwndList, string time, string text)
pointer itemdata
itemdata = new(char, len(LISTITEMDATA) + len(text))
if (itemdata)
strncpy(*<LISTITEMDATA>itemdata.time, time, LISTITEMDATA_TIME_LEN)
*<LISTITEMDATA>itemdata.time[8] = 0
*<LISTITEMDATA>itemdata.text = text
SendMessage(hwndList, LB_ADDSTRING, 0, itemdata)
endif
return
endsub
sub RemoveListItem(HWND hwndList, int index)
pointer itemdata
itemdata = SendMessage(hwndList, LB_GETITEMDATA, index, 0)
delete itemdata
return
endsub
sub RemoveAllListItems(HWND hwndList)
int index
index = SendMessage(hwndList, LB_GETCOUNT, 0, 0)
while (index)
index--
RemoveListItem(hwndList, index)
wend
return
endsub
sub ForwardDrawItemProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam),LRESULT
if ((uMsg = WM_MEASUREITEM) and (*<MEASUREITEMSTRUCT>lParam.CtlType = ODT_LISTBOX))
return MeasureListItem(GetDlgItem(hwnd, wParam), wParam, *<MEASUREITEMSTRUCT>lParam)
endif
if ((uMsg = WM_DRAWITEM) and (*<DRAWITEMSTRUCT>lParam.CtlType = ODT_LISTBOX))
return DrawListItem(*<DRAWITEMSTRUCT>lParam.hwndItem, wParam, *<DRAWITEMSTRUCT>lParam)
endif
return !<EBDLGPROC>g_OldDlgProc(hwnd, uMsg, wParam, lParam)
endsub