Автор: Maks150988
Дата сообщения: 20.08.2011 18:01
Доброго времени суток. Расширил функционал ListBox. Создал свою структуру для каждого элемента наподобие ListView.
type
tagLISTBOXEXITEMW = packed record
mask : UINT;
state : UINT;
pszText : LPWSTR;
cchTextMax: Integer;
iImage : Integer;
end;
PListBoxExItemW = ^TListBoxExItemW;
TListBoxExItemW = tagLISTBOXEXITEMW;
Обрабатываю сообщения по вставке/удалению строк.
function CtrlWndProc_LbAddString(pcp: P_CTRL_PRO; hWnd: HWND; uMsg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT;
var
iCount: Integer;
bRet : Boolean;
begin
Result := CallWindowProcW(@pcp.CtrlProc, hWnd, uMsg, wParam, lParam);
bRet := (Result <> LB_ERR) and (Result <> LB_ERRSPACE);
if bRet then
begin
iCount := SendMessageW(hWnd, LB_GETCOUNT, 0, 0);
SetLength(pcp.ItemData, iCount);
pcp.ItemData[Result].state := 0;
pcp.ItemData[Result].iImage := I_IMAGENONE;
pcp.ItemData[Result].pszText := '';
pcp.ItemData[Result].cchTextMax := 0;
RedrawWindow(hWnd, nil, 0, RDW_INVALIDATE or RDW_UPDATENOW or RDW_ERASE);
end;
end;
function CtrlWndProc_LbInsertString(pcp: P_CTRL_PRO; hWnd: HWND; uMsg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT;
var
iCount: Integer;
bRet : Boolean;
begin
Result := CallWindowProcW(@pcp.CtrlProc, hWnd, uMsg, wParam, lParam);
bRet := (Result <> LB_ERR) and (Result <> LB_ERRSPACE);
if bRet then
begin
iCount := SendMessageW(hWnd, LB_GETCOUNT, 0, 0);
SetLength(pcp.ItemData, iCount);
if (Result < (iCount - 1)) then
CopyMemory(
@pcp.ItemData[Result + 1],
@pcp.ItemData[Result],
(iCount - 1 - Result) * SizeOf(pcp.ItemData[0])
);
pcp.ItemData[Result].state := 0;
pcp.ItemData[Result].iImage := I_IMAGENONE;
pcp.ItemData[Result].pszText := '';
pcp.ItemData[Result].cchTextMax := 0;
RedrawWindow(hWnd, nil, 0, RDW_INVALIDATE or RDW_UPDATENOW or RDW_ERASE);
end;
end;
function CtrlWndProc_LbDeleteString(pcp: P_CTRL_PRO; hWnd: HWND; uMsg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT;
begin
Result := CallWindowProcW(@pcp.CtrlProc, hWnd, uMsg, wParam, lParam);
if (Result <> LB_ERR) then
begin
if (wParam < Result) then
CopyMemory(
@pcp.ItemData[wParam],
@pcp.ItemData[wParam + 1],
(Result - wParam) * SizeOf(pcp.ItemData[0])
);
SetLength(pcp.ItemData, Result);
RedrawWindow(hWnd, nil, 0, RDW_INVALIDATE or RDW_UPDATENOW or RDW_ERASE);
end;
end;
function CtrlWndProc_LbResetContent(pcp: P_CTRL_PRO; hWnd: HWND; uMsg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT;
begin
Result := CallWindowProcW(@pcp.CtrlProc, hWnd, uMsg, wParam, lParam);
SetLength(pcp.ItemData, 0);
RedrawWindow(hWnd, nil, 0, RDW_INVALIDATE or RDW_UPDATENOW or RDW_ERASE);
end;
Теперь необходимо вставить в элемент ListBox свою структуру.
pszText := 'SendMessageW(GetDlgItem(hWnd, IDC_LISTBOX), LB_EX_SETITEMINFO, i, Integer(@info))';
i := SendMessageW(GetDlgItem(hWnd, IDC_LISTBOX), LB_ADDSTRING, 0, Integer(LPWSTR(pszText)));
ZeroMemory(@info, SizeOf(TListBoxExItemW));
info.mask := LBIF_TEXT or LBIF_IMAGE or LBIF_STATE;
info.iImage := 2;
info.state := LBIS_UNCHECKED;
info.pszText := LPWSTR(pszText);
info.cchTextMax := lstrlenW(info.pszText) + 1;
SendMessageW(GetDlgItem(hWnd, IDC_LISTBOX), LB_EX_SETITEMINFO, i, Integer(@info))
Пытаюсь получить содержимое буфера.
SetLength(pszText, MAX_PATH);
ZeroMemory(@info, SizeOf(TListBoxExItemW));
info.mask := LBIF_TEXT;
info.pszText := LPWSTR(pszText);
info.cchTextMax := MAX_PATH;
SendMessageW(GetDlgItem(hWnd, IDC_LISTBOX), LB_EX_GETITEMINFO, iItem, Integer(@info));
MessageBoxW(hWnd, LPWSTR(psztext), nil, MB_OK);
Получается хрень какая-то. Собственно не понимаю как с пойнтерами работать. Мне нужно присваивать указатели или выделять под них память? Вобщем подскажите как правильнее надо. Ну и если память выделять то GetMem или что-нибудь из WinApi типа ClobalLock + до кучи.