OK, I think I got the edit working. Thank you, you have been very helpful.
I will try to implement those char tests later.
Here is how the code looks like now (still basic, without the char tests). I believe it's extremely helpful to whoever is looking for something similar.
ListViewProc:
Code:
long _stdcall ListViewProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch(message){
case WM_LBUTTONDOWN:
{
if (hEdit != NULL){SendMessage(hEdit,WM_KILLFOCUS,0,0);};
LVHITTESTINFO itemclicked;
long x, y;
x = (long)LOWORD(lParam);
y = (long)HIWORD(lParam);
itemclicked.pt.x = x;
itemclicked.pt.y = y;
int lResult = ListView_SubItemHitTest(hwnd,&itemclicked);
if (lResult!=-1){
RECT subitemrect;
ListView_GetSubItemRect(hwnd,itemclicado.iItem,itemclicado.iSubItem,LVIR_BOUNDS,&subitemrect);
int altura = subitemrect.bottom - subitemrect.top;
int largura = subitemrect.right - subitemrect.left;
if (itemclicado.iSubItem==0){largura=largura/4;};
hEdit = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "",
WS_CHILD|WS_VISIBLE|ES_WANTRETURN,
subitemrect.left, subitemrect.top, largura, 1.5*altura, hwnd, 0, GetModuleHandle(NULL), NULL);
if(hEdit == NULL)
MessageBox(hwnd, "Could not create edit box.", "Error", MB_OK | MB_ICONERROR);
SetFocus(hEdit);
EOldProc = (WNDPROC)SetWindowLong(hEdit, GWL_WNDPROC, (LONG)EditProc);
iItem = itemclicked.iItem;
iSubItem = itemclicked.iSubItem;
}
return 0;
break;
}
}
return CallWindowProc(LVOldProc, hwnd, message, wParam, lParam);
}
See here that I send WM_KILLFOCUS to hEdit if one already exists (so that the hEdit sets the item's text and gets destroyed before LBUTTONDOWN does anything else, since, as you said, WM_KILLFOCUS needs to be processed before LBUTTONDOWN). LBUTTONDOWN does the hittesting and stores the iItem and iSubItem information.
EditProc:
Code:
long _stdcall EditProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch(message){
case WM_KILLFOCUS:
{
LV_DISPINFO lvDispinfo;
ZeroMemory(&lvDispinfo,sizeof(LV_DISPINFO));
lvDispinfo.hdr.hwndFrom = hwnd;
lvDispinfo.hdr.idFrom = GetDlgCtrlID(hwnd);
lvDispinfo.hdr.code = LVN_ENDLABELEDIT;
lvDispinfo.item.mask = LVIF_TEXT;
lvDispinfo.item.iItem = iItem;
lvDispinfo.item.iSubItem = iSubItem;
lvDispinfo.item.pszText = NULL;
char szEditText[10];
GetWindowText(hwnd,szEditText,10);
lvDispinfo.item.pszText = szEditText;
lvDispinfo.item.cchTextMax = lstrlen(szEditText);
SendMessage(GetParent(GetDlgItem(b,MATRIZ)),WM_NOTIFY,(WPARAM)MATRIZ,(LPARAM)&lvDispinfo); //the LV ID and the LVs Parent window's HWND
DestroyWindow(hwnd);
break;
}
}
return CallWindowProc(EOldProc, hwnd, message, wParam, lParam);
}
When hEdit receives WM_KILLFOCUS, it sends iItem/iSubItem/text information to the ListView via LVN_ENDLABELEDIT and destroys itself.
Look at the WM_NOTIFY intercepted by the main window proc:
Code:
case WM_NOTIFY:
{
if(((LPNMHDR)z)->code == LVN_ENDLABELEDIT){
LVITEM LvItem;
LV_DISPINFO* dispinfo = (LV_DISPINFO*)z;
char text[10]="";
LvItem.iItem = dispinfo->item.iItem;
LvItem.iSubItem = dispinfo->item.iSubItem;
LvItem.pszText = dispinfo->item.pszText;
SendDlgItemMessage(w,MATRIZ,LVM_SETITEMTEXT,(WPARAM)LvItem.iItem,(LPARAM)&LvItem); // put new text
}
break;
}
Here, MATRIZ is the ID chosen for the ListView.
It seems to be working fine by now. If anything goes wrong I will let you know.