Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "WinAPI";
Текущий архив: 2003.06.19;
Скачать: [xml.tar.bz2];

Вниз

Помогите с ListView и LVN_ENDLABELEDIT - нет моих больше сил!   Найти похожие ветки 

 
DVM   (2003-04-19 23:55) [0]

Есть такая проблема: никак не могу заставить ListView сохранять результат редактирования подписи под значком.

Собственно упрощенный код такой:

program ListViewDemo;

uses windows, messages, Commctrl;

type

TMyItem = packed record
Name : PChar;
Path : PChar;
Param : PChar;
PathToIcon : PChar;
end;

PMyItem = ^TMyItem;

var
wc : TWndClassEx;
hMainWnd : HWND;
Mesg : TMsg;
hListView:hWnd;
hEdit, HIcon, himlLarge:THandle;
InitCtrls: TInitCommonControlsEx;
nmhdr:PNMHdr;
lpLvdi:PLVDispInfo;

i:integer;

TempItem:PMyItem;
Items : array [0..2] of TMyItem;

lvi : TLVItemA;

function WindowProc(wnd:HWND; Msg : Integer; Wparam:Wparam; Lparam:Lparam):Lresult; stdcall;
begin
case msg of
WM_NOTIFY:
begin
nmhdr:=PNMHdr(lParam);
lpLvdi:=PLVDispInfo(nmhdr);
TempItem:=PMyItem(lpLvdi.item.lParam);
case nmhdr.code of
LVN_GETDISPINFO:
begin
if (lpLvdi.item.mask and LVIF_TEXT)=1 then
begin
case lpLvdi.item.iSubItem of
0: lpLvdi.item.pszText := TempItem^.Name;
end;
end;
end;

LVN_BEGINLABELEDIT:
begin
result:=0;
end;

LVN_ENDLABELEDIT:
if (lpLvdi.item.iItem<>-1) and (lpLvdi.item.pszText<>nil) then
lstrcpy(TempItem.Name,lpLvdi.item.pszText);
end;
end;
wm_destroy :
Begin
postquitmessage(0);
exit;
Result:=0;
End;
else Result:=DefWindowProc(wnd,msg,wparam,lparam);
end;
End;

//Продолжение следует...


 
DVM   (2003-04-20 00:00) [1]

//...продолжение

begin
wc.cbSize:=sizeof(wc);
wc.style:=cs_hredraw or cs_vredraw;
wc.lpfnWndProc:=@WindowProc;
wc.cbClsExtra:=0;
wc.cbWndExtra:=0;
wc.hInstance:=HInstance;
wc.hIcon:=LoadIcon(0,idi_application);
wc.hCursor:=LoadCursor(0,idc_arrow);
wc.hbrBackground:=COLOR_BTNFACE+1;
wc.lpszMenuName:=nil;
wc.lpszClassName:="ListViewDemo";
if RegisterClassEx (wc) = 0 then exit;
hMainWnd:=CreateWindowEx(0, "ListViewDemo", "ListViewDemo", ws_overlappedwindow,
1, 1, 400, 300, 0, 0, Hinstance, nil);
if hMainWnd = 0 then exit;
ShowWindow(hMainWnd,CmdShow); UpdateWindow(hMainWnd);

InitCtrls.dwICC := ICC_LISTVIEW_CLASSES;
InitCtrls.dwSize := sizeof(TInitCommonControlsEx);
InitCommonControlsEx(InitCtrls);

hListView:=CreateWindowEx(LVS_EX_HEADERDRAGDROP,
WC_LISTVIEW,
"",
LVS_SINGLESEL or lvs_icon or ws_child or ws_visible
or ws_border or LVS_SHOWSELALWAYS or LVS_EDITLABELS,
0,0,300,250,
hMainWnd,
0,Hinstance,nil);

himlLarge := ImageList_Create(GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON), ILC_COLOR32 or ILC_MASK, 1, 1);
ListView_DeleteAllItems(hListView);
HIcon:= LOADICON(0,IDI_EXCLAMATION);
ImageList_AddIcon(himlLarge, HIcon);
ListView_SetImageList(hListView, himlLarge, LVSIL_NORMAL );

Items[0].Name:="aaa";
Items[1].Name:="bbb";
Items[2].Name:="ccc";

lvi.mask := LVIF_TEXT or LVIF_IMAGE or LVIF_PARAM;

lvi.pszText := LPSTR_TEXTCALLBACK;

for i:=0 to 2 do
begin
lvi.iItem := i;
lvi.iSubItem := 0;
lvi.cchTextMax := 40;
lvi.lParam := longint(@Items[i]);
lvi.iImage := 0;
ListView_InsertItem(hListView, lvi);
end;

While GetMessage(Mesg,0,0,0) do
begin
TranslateMessage(Mesg);
DispatchMessage(Mesg);
end;
end.


 
DVM   (2003-04-20 00:03) [2]

Проблема в том, что вот здесь:

LVN_ENDLABELEDIT:
if (lpLvdi.item.iItem<>-1) and (lpLvdi.item.pszText<>nil)
then lstrcpy(TempItem.Name,lpLvdi.item.pszText);

lpLvdi.item.pszText все время пустой. Что за дела???





 
Suntechnic   (2003-04-20 06:04) [3]

>DVM ©
Он и должен быть пустым, если ты Cancel жмёшь после редактирования. А в остальном всё прекрасно работает (в смысле, что не пустой).


 
Suntechnic   (2003-04-20 06:10) [4]

Да... если тебя всё-таки интересует почему подпись не обновляется, то ты кое-что забыл. А именно вызвать что-то типа вот этого
ListView_SetItemText(nmhdr.hwndFrom, lpLvdi.item.iItem, lpLvdi.item.iSubItem, lpLvdi.item.pszText); после lstrcpy.

Потому как
When label editing is canceled or completed, a list view control sends its parent window an LVN_ENDLABELEDIT notification message. The parent window is responsible for updating the item label if it keeps the new label.




 
DVM   (2003-04-20 11:00) [5]


> Он и должен быть пустым, если ты Cancel жмёшь после редактирования.
> А в остальном всё прекрасно работает (в смысле, что не пустой).

У Вас вышеприведенный код работает? Я проверял сразу после после окончания редактирования значение переменной lpLvdi.item.pszText - там пусто. Соответственно надпись под значком исчезает, т.к. в элемент массива Items[], откуда список берет подписи к значкам ничего не попадает.



> Да... если тебя всё-таки интересует почему подпись не обновляется,
> то ты кое-что забыл. А именно вызвать что-то типа вот этого
>
> ListView_SetItemText(nmhdr.hwndFrom, lpLvdi.item.iItem,
> lpLvdi.item.iSubItem, lpLvdi.item.pszText); после lstrcpy.

С этой строкой все конечно работает.
А это разве надо? Ведь в моем случае список САМ должен обновится, т.к. он использует LVN_GETDISPINFO и при первой же перерисовке он значения подписей получет из элементов массива, связанных со значками.





 
DVM   (2003-04-20 11:12) [6]

Мне надо положить новое значение подписи в массив элементов, связанный со значками списка, так как в последствии название к значку будет браться оттуда.
Когда я пишу так все работает:
LVN_ENDLABELEDIT:
if (lpLvdi.item.iItem<>-1) and (lpLvdi.item.pszText<>nil) then
begin
TempItem.Name:=pchar("*****");
end;
Подпись под значком обновляется сама и становится "*****"
Но вот такая запись ни к чему не приводит:
LVN_ENDLABELEDIT:
if (lpLvdi.item.iItem<>-1) and (lpLvdi.item.pszText<>nil) then
begin
TempItem.Name:=lpLvdi.item.pszText;
end;




 
Suntechnic   (2003-04-20 15:25) [7]

>DVM ©
Ты вон о чём оказывается. Надо ж об этом с самого начала и писать, а том не лично облом сидеть и разбираться в локиге программы. Теперь по сути...

Конечно же проблема не в lpLvdi.item.pszText, там всегда содержится строка и никакой это не ноль. Тут проблема в другом.

LVN_ENDLABELEDIT:
if (lpLvdi.item.iItem<>-1) and (lpLvdi.item.pszText<>nil)
then lstrcpy(TempItem.Name,lpLvdi.item.pszText);


А память кто под строку будет выделять в вышеуказанной строке? lstrcpy всего лишь копирует в вышеуказанное место, в выделением памяти она не занимается. TempItem.Name:=lpLvdi.item.pszText - так тожу писать нельзя ибо мы всего-лишь присвоили указатель на строку, а выделением строки тоже не занимались. Это обычные операции с null-terminated строкой, которые так хорошо известны любому с-шнику. Я вообще-то по Delphi не крупный специалист, поэтому как именно решить проблему сказать точно не могу, но направление мысли дать могу:

LVN_ENDLABELEDIT:
if (lpLvdi.item.iItem<>-1) and (lpLvdi.item.pszText<>nil) then
begin
TempItem.Name:= StrAlloc(lstrlen(lpLvdi.item.pszText) + 1);
lstrcpy(TempItem.Name,lpLvdi.item.pszText);
end;


Вот если так напишешь, то это работать будет, только тут есть один нюанс. На лицо memory leak так как память под строку мы выделили, а DisposeAlloc так и не вызвали. Вообще подумай, где под строку выделять память и где её освобождать.


 
DVM   (2003-04-20 20:04) [8]

Спасибо, я вообще то и сам в том же направлении копал. Указатели и нуль-теминэйт строки - это то, в чем я плохо пока разбираюсь.



Страницы: 1 вся ветка

Форум: "WinAPI";
Текущий архив: 2003.06.19;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.47 MB
Время: 0.009 c
8-60281
Карелин Артем
2003-03-07 06:39
2003.06.19
Чем показать картинки в 100 мегов?


1-60119
killer
2003-06-06 12:36
2003.06.19
Можно ли в ListBox и Memo?


14-60342
LiLa Ananda
2003-06-02 10:03
2003.06.19
С чего начинается...


1-60219
BDRON
2003-06-05 14:48
2003.06.19
Кириллица в заголовке


3-60085
denary
2003-05-29 01:38
2003.06.19
Как сделать частичную замену в строке?





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский