Réponse acceptée !
EditListView.cpp :
//***************************************************************************************
//***************************************************************************************
#include <windows.h>
#include <commctrl.h>
#include "Resource.h"
//=======================================================================================
//=======================================================================================
#define COLUMN_COUNT 5
#define LINE_COUNT 50
//=======================================================================================
//=======================================================================================
HINSTANCE g_hAppInstance = NULL;
HWND g_hDlgMain = NULL;
HWND g_hListView = NULL;
WNDPROC g_pfnOldListViewProc = NULL;
HWND g_hListViewEdit = NULL;
LVITEM g_lviListViewEdit = {0};
//=======================================================================================
//=======================================================================================
int CALLBACK DlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
void OnInitDialog();
void OnCommand(UINT nIdCtrl, UINT nNotifyCode, HWND hCtrl);
LRESULT CALLBACK ListViewProc(HWND hCtrl, UINT uMsg, WPARAM wParam, LPARAM lParam);
void OnListViewLButtonDown(UINT nFlags, short x, short y);
void UpdateEditItemData();
//***************************************************************************************
//***************************************************************************************
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow)
{
g_hAppInstance = hInstance;
INITCOMMONCONTROLSEX iccex = {0};
iccex.dwSize = sizeof(INITCOMMONCONTROLSEX);
iccex.dwICC = ICC_LISTVIEW_CLASSES;
InitCommonControlsEx(&iccex);
DialogBox(g_hAppInstance, MAKEINTRESOURCE(IDD_MAIN), NULL, DlgProc);
return 0;
}
//***************************************************************************************
//***************************************************************************************
int CALLBACK DlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch(uMsg)
{
case WM_INITDIALOG :
g_hDlgMain = hDlg;
OnInitDialog();
return 0;
case WM_COMMAND :
OnCommand(LOWORD(wParam), HIWORD(wParam), (HWND)lParam);
return 0;
}
return 0;
}
//***************************************************************************************
//***************************************************************************************
void OnInitDialog()
{
// récupération ListView, modification de sa WndProc
g_hListView = GetDlgItem(g_hDlgMain, IDC_LISTVIEW);
g_pfnOldListViewProc = (WNDPROC)SetWindowLong(g_hListView, GWL_WNDPROC, (LONG)ListViewProc);
int nColumn, nLine;
char szText[32];
// ajout de colonnes
LVCOLUMN lvc = {0};
lvc.mask = LVCF_FMT|LVCF_WIDTH|LVCF_TEXT|LVCF_SUBITEM;
lvc.fmt = LVCFMT_LEFT;
lvc.cx = 80;
lvc.pszText = szText;
for(nColumn = 0; nColumn < COLUMN_COUNT; nColumn++)
{
wsprintf(szText, "Column %d", nColumn+1);
SendMessage(g_hListView, LVM_INSERTCOLUMN, nColumn, (LPARAM)&lvc);
}
// ajout de lignes
LVITEM lvi = {0};
lvi.mask = LVIF_TEXT;
lvi.pszText = szText;
for(nLine = 0; nLine < LINE_COUNT; nLine++)
{
for(nColumn = 0; nColumn < COLUMN_COUNT; nColumn++)
{
// ajout item
lvi.iItem = nLine;
lvi.iSubItem = nColumn;
wsprintf(szText, "Item %d %d", nLine+1, nColumn+1);
if(nColumn == 0)
SendMessage(g_hListView, LVM_INSERTITEM, 0, (LPARAM)&lvi);
else
SendMessage(g_hListView, LVM_SETITEM, 0, (LPARAM)&lvi);
}
}
}
//***************************************************************************************
//***************************************************************************************
void OnCommand(UINT nIdCtrl, UINT nNotifyCode, HWND hCtrl)
{
switch(nIdCtrl)
{
case IDOK :
EndDialog(g_hDlgMain, IDOK);
return;
case IDCANCEL :
EndDialog(g_hDlgMain, IDCANCEL);
return;
}
}
//***************************************************************************************
//***************************************************************************************
LRESULT CALLBACK ListViewProc(HWND hCtrl, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch(uMsg)
{
// mise à jour de l'Edit ou début d'un nouvel Edit
case WM_LBUTTONDOWN :
if(g_hListViewEdit != NULL)
UpdateEditItemData();
else
OnListViewLButtonDown(wParam, LOWORD(lParam), HIWORD(lParam));
break;
// mise à jour de l'Edit
case WM_HSCROLL : // no break
case WM_VSCROLL :
if(g_hListViewEdit != NULL)
UpdateEditItemData();
break;
}
// traitement par défaut
return CallWindowProc(g_pfnOldListViewProc, hCtrl, uMsg, wParam, lParam);
}
//***************************************************************************************
//***************************************************************************************
void OnListViewLButtonDown(UINT nFlags, short x, short y)
{
// nombre d'items au total
int nTotalCount = SendMessage(g_hListView, LVM_GETITEMCOUNT, 0, 0);
// premier item visible
int nFirstVisible = SendMessage(g_hListView, LVM_GETTOPINDEX, 0, 0);
// nombre d'items visibles
int nVisibleCount = SendMessage(g_hListView, LVM_GETCOUNTPERPAGE, 0, 0);
if(nVisibleCount + nFirstVisible > nTotalCount)
nVisibleCount = nTotalCount - nFirstVisible;
// on recherche sur qu'elle ligne se trouve la souris
for(int nLine = nFirstVisible; nLine < nFirstVisible+nVisibleCount; nLine++)
{
// rectangle entourrant la ligne à tester
RECT rcLine;
rcLine.left = LVIR_BOUNDS;
SendMessage(g_hListView, LVM_GETITEMRECT, nLine, (LPARAM)&rcLine);
// si la souris n'est pas dans ce rectangle, on continue
POINT pt = {x, y};
if(!PtInRect(&rcLine, pt))
continue;
// on sélectionne l'item correspondant
LVITEM lvi = {0};
lvi.mask = LVIF_STATE;
lvi.state = LVIS_SELECTED|LVIS_FOCUSED;
lvi.stateMask = LVIS_SELECTED|LVIS_FOCUSED;
lvi.iItem = nLine;
lvi.iSubItem = 0;
SendMessage(g_hListView, LVM_SETITEM, 0, (LPARAM)&lvi);
// recherche du numéro de la colonne ou se trouve la souris
int x0 = 0;
int nColumn = 0;
int nColumnWidth;
while(nColumn < COLUMN_COUNT)
{
nColumnWidth = SendMessage(g_hListView, LVM_GETCOLUMNWIDTH, nColumn, 0);
if(x >= x0 && (x < x0+nColumnWidth))
break;
x0 += nColumnWidth;
nColumn++;
}
// récupération de l'item associé
char szText[256];
memset(&g_lviListViewEdit, 0, sizeof(LVITEM));
g_lviListViewEdit.mask = LVIF_TEXT;
g_lviListViewEdit.iItem = nLine;
g_lviListViewEdit.iSubItem = nColumn;
g_lviListViewEdit.pszText = szText;
g_lviListViewEdit.cchTextMax = 256;
SendMessage(g_hListView, LVM_GETITEM, 0, (LPARAM)&g_lviListViewEdit);
// création d'une zone d'édition
g_hListViewEdit = CreateWindowEx(0, "EDIT", "", WS_BORDER|WS_VISIBLE|WS_CHILD,
x0, rcLine.top, nColumnWidth, rcLine.bottom- rcLine.top,
g_hListView, NULL, g_hAppInstance, NULL);
// changement de la police de caractères
HFONT hFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
SendMessage(g_hListViewEdit, WM_SETFONT, (WPARAM)hFont, TRUE);
// on affiche le texte, on le sélectionne et on donne le focus
SetFocus(g_hListViewEdit);
SetWindowText(g_hListViewEdit, szText);
SendMessage(g_hListViewEdit, EM_SETSEL, 0, -1);
}
}
//***************************************************************************************
//***************************************************************************************
void UpdateEditItemData()
{
// récupération du texte rentré dans la zone d'édition
char szText[256];
GetWindowText(g_hListViewEdit, szText, 256);
// affectation
g_lviListViewEdit.pszText = szText;
SendMessage(g_hListView, LVM_SETITEM, 0, (LPARAM)&g_lviListViewEdit);
// destruction de la zone d'édition
DestroyWindow(g_hListViewEdit);
g_hListViewEdit = NULL;
// on redessine la liste
InvalidateRect(g_hListView, NULL, FALSE);
UpdateWindow(g_hListView);
}
EditListView.rc :
//Microsoft Developer Studio generated resource script.
//
#include "Resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "winresrc.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// French (France) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_FRA)
#ifdef _WIN32
LANGUAGE LANG_FRENCH, SUBLANG_FRENCH
#pragma code_page(1252)
#endif //_WIN32
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE DISCARDABLE
BEGIN
"Resource.h\0"
END
2 TEXTINCLUDE DISCARDABLE
BEGIN
"#include ""winresrc.h""\r\n"
"\0"
END
3 TEXTINCLUDE DISCARDABLE
BEGIN
"\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_MAIN DIALOG DISCARDABLE 0, 0, 330, 230
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Dialog"
FONT 8, "MS Sans Serif"
BEGIN
CONTROL "ListView",IDC_LISTVIEW,"SysListView32",LVS_REPORT |
LVS_SINGLESEL | WS_BORDER | WS_TABSTOP,10,10,310,210
END
/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO DISCARDABLE
BEGIN
IDD_MAIN, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 323
TOPMARGIN, 7
BOTTOMMARGIN, 223
END
END
#endif // APSTUDIO_INVOKED
#endif // French (France) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED
Resource.h
//{{NO_DEPENDENCIES}}
// Microsoft Developer Studio generated include file.
// Used by EditListView.rc
//
#define IDD_MAIN 101
#define IDC_LISTVIEW 1000
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 102
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1001
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif