Wie bekomm ich unterschiedlichen Text in die Spalten von ein ListView?
-
hallöchen,
ich hab da nen problem, und zwar bekomm ich es einfach nicht hin, den aus unterschiedlichen
Editbox ausgelesenen Text in jeweils eine Spalte reinzuschreiben. also:EBOX1: "Hallo"; EBOX2: "wie"; EBOX3: "gehts"; EBOX4: "?"; >>>Button klick!, Button klick!, Button klick!, Button klick! ... ListView: Column0 | Column1 | Column2 | Column3 | Column4 =============================================== 1 |Hallo |wie |gehts |? 2 |Hallo |wie |gehts |? 3 |Hallo |wie |gehts |? 4 |Hallo |wie |gehts |? ...ich weiss irgendwie nur wies mit einem wort geht:
for( int i = 0; i < 1; i++ ) { lvi.mask = LVIF_TEXT; lvi.iItem = i; lvi.iSubItem = 0; lvi.pszText = "test"; ListView_InsertItem( hLView, &lvi ); for ( int j=1; j<6; ++j ) { lvi.iSubItem = j; ListView_SetItem( hLView, &lvi); } }wer toll wenns mir einer veraten könnte

achja noch was, wenn ich in eine Zeile klicke möchte ich das diese komplett makiert
wird und nicht nur das erst Item.Dank euch schon mal, Gruß Tobi.
-
kann jetzt auch falsch sein, aber ich glaube du musst auch für die sub items insert item benutzen. damit alles angezeigt wird musst du das extented-style full row select setzen (schau mal in msdn).
-
Ich hatte auch das Problem in meinem aktuellen Projekt, ich kopier dir gerade mal ein paar Codeschnippsel raus, gug's dir an so funktioniet es, den Code kann man mit Sicherheit noch Geschwindigkeits optimieren, unabhängig davon funktioiert er einwandfrei. Ach als Anmerkung nicht die Spalten in einem Listview gehören zusammen, sondern die Zeilen sind jeweils ein Datensatz.
Das Fenster erzeugen:
Wnd_ServerList = CreateWindowEx(WS_EX_CLIENTEDGE, WC_LISTVIEW, "", WS_VISIBLE | WS_CHILD | LVS_REPORT | LVS_SHAREIMAGELISTS | LVS_SINGLESEL | LVS_SHOWSELALWAYS, dim.xpos_server, dim.ypos_server, dim.xwidth_server, YHEIGHT_SERVER, hWndParent, NULL, hInst, NULL ); SetWindowLong(Wnd_ServerList, GWL_ID, LIST_SERVERS); SendMessage (Wnd_ServerList, LVM_SETEXTENDEDLISTVIEWSTYLE, (WPARAM)0, (LPARAM) LVS_EX_SUBITEMIMAGES | LVS_EX_FULLROWSELECT);die Insertfunktion:
void Show_ServerData_onLOAD(int server_id){ //Datensatz einzeln einfügen int i,allplayer_id; LVITEM pitem; SOCKADDR_IN addr; addr.sin_addr.S_un.S_addr = serverinfo[server_id].ip; scan.num_gameservers_shown++; scan.num_players_max += serverinfo[server_id].max_clients; memset (&pitem, 0, sizeof(pitem)); serverinfo[server_id].visible = TRUE; pitem.mask = LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE; pitem.iItem = server_id; //hier eine Position angeben, dann funktioniert der Insert schneller pitem.iImage = 8 + user.choosen_game_current; //Game Icon pitem.iSubItem = 0; pitem.lParam = (LPARAM)server_id; //der iD des Datensatzes, gut wenn man weis wo es ist pitem.pszText = LPSTR_TEXTCALLBACK; SendMessage (Wnd_ServerList, LVM_INSERTITEM, 0, (LPARAM) (const LPLVITEM) &pitem); // SendMessage (Wnd_ServerList, LVM_SORTITEMS, 0, (LPARAM)SortFunc_ServerWnd); //sortiert einfügen, macht den Insert aber langsam, sortiers lieber am Schluss if (serverinfo[server_id].responding == TRUE){ scan.num_gameservers_responding++; : : :der Eventhandler:
case LIST_SERVERS: switch (((LPNMHDR) lParam)->code){ case LVN_GETDISPINFO: switch (((LPNMLVDISPINFOW)lParam)->item.iSubItem){ case 0: lstrcpyn ((LPTSTR)((LPNMLVDISPINFOW)lParam)->item.pszText, serverinfo[((LPNMLVDISPINFOW)lParam)->item.lParam].servername, lstrlen((LPCSTR)serverinfo[((LPNMLVDISPINFOW)lParam)->item.lParam].servername)+1); break; case 1: lstrcpyn ((LPTSTR)((LPNMLVDISPINFOW)lParam)->item.pszText, serverinfo[((LPNMLVDISPINFOW)lParam)->item.lParam].mapname, lstrlen((LPCSTR)serverinfo[((LPNMLVDISPINFOW)lParam)->item.lParam].mapname)+1); break; case 2: lstrcpyn ((LPTSTR)((LPNMLVDISPINFOW)lParam)->item.pszText, serverinfo[((LPNMLVDISPINFOW)lParam)->item.lParam].modname, lstrlen((LPCSTR)serverinfo[((LPNMLVDISPINFOW)lParam)->item.lParam].modname)+1); break; case 3: if (serverinfo[((LPNMLVDISPINFOW)lParam)->item.lParam].need_password == TRUE) { ((LPNMLVDISPINFOW)lParam)->item.mask |= LVIF_STATE; ((LPNMLVDISPINFOW)lParam)->item.state = 0; ((LPNMLVDISPINFOW)lParam)->item.stateMask = 0; ((LPNMLVDISPINFOW)lParam)->item.iImage = 7; sprintf (buff, "%d / %d", serverinfo[((LPNMLVDISPINFOW)lParam)->item.lParam].num_of_players, serverinfo[((LPNMLVDISPINFOW)lParam)->item.lParam].max_clients); lstrcpyn ((LPTSTR)((LPNMLVDISPINFOW)lParam)->item.pszText, buff, lstrlen((LPCSTR)buff)+1); }else{ ((LPNMLVDISPINFOW)lParam)->item.mask = LVIF_STATE | LVIF_IMAGE | LVIF_TEXT; ((LPNMLVDISPINFOW)lParam)->item.state = 0; ((LPNMLVDISPINFOW)lParam)->item.stateMask = 0; sprintf (buff, "%d / %d", serverinfo[((LPNMLVDISPINFOW)lParam)->item.lParam].num_of_players, serverinfo[((LPNMLVDISPINFOW)lParam)->item.lParam].max_clients); lstrcpyn ((LPTSTR)((LPNMLVDISPINFOW)lParam)->item.pszText, buff, lstrlen((LPCSTR)buff)+1); } break; case 4: ((LPNMLVDISPINFOW)lParam)->item.mask |= LVIF_STATE; ((LPNMLVDISPINFOW)lParam)->item.state = 0; ((LPNMLVDISPINFOW)lParam)->item.stateMask = 0; if (serverinfo[((LPNMLVDISPINFOW)lParam)->item.lParam].ping <= 150) { ((LPNMLVDISPINFOW)lParam)->item.iImage = 3; } else if (serverinfo[((LPNMLVDISPINFOW)lParam)->item.lParam].ping <= 300) { ((LPNMLVDISPINFOW)lParam)->item.iImage = 4; } else if (serverinfo[((LPNMLVDISPINFOW)lParam)->item.lParam].ping < 9999) { ((LPNMLVDISPINFOW)lParam)->item.iImage = 5; } else { ((LPNMLVDISPINFOW)lParam)->item.iImage = 6; } sprintf (buff, "%d", serverinfo[((LPNMLVDISPINFOW)lParam)->item.lParam].ping); lstrcpyn ((LPTSTR)((LPNMLVDISPINFOW)lParam)->item.pszText, buff, lstrlen((LPCSTR)buff)+1); break; case 5: { struct in_addr tmp; tmp.S_un.S_addr = serverinfo[((LPNMLVDISPINFOW)lParam)->item.lParam].ip; sprintf (buff, "%s:%d", inet_ntoa (tmp), serverinfo[((LPNMLVDISPINFOW)lParam)->item.lParam].port); lstrcpyn ((LPTSTR)((LPNMLVDISPINFOW)lParam)->item.pszText, buff, lstrlen((LPCSTR)buff)+1); break; } } } break;die pasende Sortierfunktion:
int CALLBACK SortFunc_ServerWnd(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort){ switch (srt.wnd[0].actual_col){ case 0: { char name1[LEN_CVARVALUE]; char name2[LEN_CVARVALUE]; strcpy(name1, serverinfo[(int)lParam1].servername); strcpy(name2, serverinfo[(int)lParam2].servername); if(srt.wnd[0].col[0].dir_z_a == TRUE){ return strcmp (String_tolower(name1), String_tolower(name2)); }else{ return strcmp (String_tolower(name2), String_tolower(name1)); } } case 1: { char map1[LEN_CVARVALUE]; char map2[LEN_CVARVALUE]; strcpy(map1, serverinfo[(int)lParam1].mapname); strcpy(map2, serverinfo[(int)lParam2].mapname); if(srt.wnd[0].col[1].dir_z_a == TRUE){ return strcmp (String_tolower(map1), String_tolower(map2)); }else{ return strcmp (String_tolower(map2), String_tolower(map1)); } } case 2: { char mod1[LEN_CVARVALUE]; char mod2[LEN_CVARVALUE]; strcpy(mod1, serverinfo[(int)lParam1].modname); strcpy(mod2, serverinfo[(int)lParam2].modname); if(srt.wnd[0].col[2].dir_z_a == TRUE){ return strcmp (String_tolower(mod1), String_tolower(mod2)); }else{ return strcmp (String_tolower(mod2), String_tolower(mod1)); } } case 3: { int invert = 1; if(srt.wnd[0].col[3].dir_z_a == TRUE){ invert = -1; } if (serverinfo[(int)lParam1].num_of_players < serverinfo[(int)lParam2].num_of_players){ return invert; }else if (serverinfo[(int)lParam1].num_of_players > serverinfo[(int)lParam2].num_of_players){ return (-1*invert); }else{ return 0; } } case 4: { int invert = 1; if(srt.wnd[0].col[4].dir_z_a == TRUE){ invert = -1; } if (serverinfo[(int)lParam1].ping < serverinfo[(int)lParam2].ping){ return invert; }else if (serverinfo[(int)lParam1].ping > serverinfo[(int)lParam2].ping){ return (-1*invert); }else{ return 0; } } case 5: { int invert = 1; if(srt.wnd[0].col[5].dir_z_a == TRUE){ invert = -1; } if ((u_int)serverinfo[(int)lParam1].ip_rev < (u_int)serverinfo[(int)lParam2].ip_rev){ return invert; }else if ((u_int)serverinfo[(int)lParam1].ip_rev > (u_int)serverinfo[(int)lParam2].ip_rev){ return (-1*invert); }else{ if ((u_short)serverinfo[(int)lParam1].port < (u_short)serverinfo[(int)lParam2].port){ return (-1*invert); }else if ((u_short)serverinfo[(int)lParam1].port > (u_short)serverinfo[(int)lParam2].port){ return invert; }else{ return 0; } } } default: return 0; } }
-
pitem.lParam = (LPARAM)server_id;
pitem.pszText = LPSTR_TEXTCALLBACK;das die stelle wos bei mir haengt.... ich weiss einfach net wozu des gut ist.. bzw wie das funktioniert! hier wird irgendwie der text übergeben und dann irgendwo ausgewertet.. ich weiss nur nicht wie man das macht....
Gruß Tobi.
-
schaut mal ich habe des jetzt so gelöst:
void SetWareText( HWND hLV, string index, string szWname, string szWnum, string szWcount, string szWprice, string szWdeposit ) { LV_ITEM lvi; lvi.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM | LVIF_STATE; lvi.state = 0; lvi.stateMask = 0; lvi.iImage = 0; lvi.mask = LVIF_TEXT; lvi.iItem = 0; lvi.iSubItem = 0; ListView_InsertItem( hLV, &lvi ); lvi.iSubItem = 0; // spalte strcpy( lvi.pszText, index.c_str() ); ListView_SetItem( hLV, &lvi); lvi.iSubItem = 1; // spalte strcpy( lvi.pszText, szWname.c_str() ); ListView_SetItem( hLV, &lvi); lvi.iSubItem = 2; // spalte strcpy( lvi.pszText, szWnum.c_str() ); ListView_SetItem( hLV, &lvi); lvi.iSubItem = 3; // spalte strcpy( lvi.pszText, szWcount.c_str() ); ListView_SetItem( hLV, &lvi); lvi.iSubItem = 4; // spalte strcpy( lvi.pszText, szWprice.c_str() ); ListView_SetItem( hLV, &lvi); lvi.iSubItem = 5; // spalte strcpy( lvi.pszText, szWdeposit.c_str() ); ListView_SetItem( hLV, &lvi); }aber irgendwie steht bei szWname immer "r." drin, jedes mal, wieso? eigentlich hab ich doch aber Tomate reingeschrieben?
-
pitem.lParam = (LPARAM)server_id; pitem.pszText = LPSTR_TEXTCALLBACK;mit lParam gebe ich jedem Item eine fortlaufende Nummer, wenn du nähmlch die Zeilen sortierst, weisst du sonst nicht welcher Item gerade wo ist, brauchst du aber nicht unbedingt, LPSTR_TEXTCALLBACK bedeutet der Text der angezeigt werden soll, wird erst im eventhandler übergeben, case 0 ist erste Spalte, case 1 ist zweite Spalte etc. hier wird erst festgelegt was wo reinkommt und nicht wenn du
SendMessage (Wnd_ServerList, LVM_INSERTITEM, 0, (LPARAM) (const LPLVITEM) &pitem);ausführst, da wird nur gesagt, daß ein Item eingefügt wird, aber nicht welcher Text dieser in den einzelnen Zellen der eingefügten Zeile stehen soll, hierfür ist
case LIST_SERVERS: switch (((LPNMHDR) lParam)->code){ case LVN_GETDISPINFO: switch (((LPNMLVDISPINFOW)lParam)->item.iSubItem){ case 0: lstrcpyn ((LPTSTR)((LPNMLVDISPINFOW)lParam)->item.pszText, serverinfo[((LPNMLVDISPINFOW)lParam)->item.lParam].servername, lstrlen((LPCSTR)serverinfo[((LPNMLVDISPINFOW)lParam)->item.lParam].servername)+1); break; case 1:zuständig, war für mich auch erst mal verwirrend, da ich zum ersten mal einen Listview benutzt habe.
achso das kannst du so net schreiben:
lvi.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM | LVIF_STATE; : lvi.mask = LVIF_TEXT;die letzte Zeile, macht alle Vorgaben deiner ersten Zeile zunichte, ist aber an dieser Stelle eh Wurscht, das einzige was du verstehen musst, ist daß das was in den Zellen stehen soll, erst in deinem Eventhandler von dir festgelegt wird, du brauchst hierfür aber irgend eine Struktur in die du deine Texte, Zahlen etc. reinkopierst, diese Struktur muss eben wärend der ganzen Laufzeit des Programmes verfügbar sein, da sonst LPSTR_TEXTCALLBACK wirkungslos ist, der große Vorteil hiervon ist daß du den Inhalt deiner Struktur im Hintergrund ändern kannst, dann einmal den Listview neu sortierst und schon sind alle Zellen auf dem aktuellen Stand deiner Datenstruktur.
-
so wie ich des gemacht habe:
lvi.state = 0; lvi.stateMask = 0; lvi.iImage = 0; lvi.mask = LVIF_TEXT; lvi.iItem = 0; lvi.iSubItem = 0; ListView_InsertItem( hLV, &lvi ); lvi.iSubItem = 0; // spalte strcpy( lvi.pszText, index.c_str() ); ListView_SetItem( hLV, &lvi); lvi.iSubItem = 1; // spalte strcpy( lvi.pszText, szWname.c_str() ); ListView_SetItem( hLV, &lvi); lvi.iSubItem = 2; // spalte strcpy( lvi.pszText, szWnum.c_str() ); ListView_SetItem( hLV, &lvi); lvi.iSubItem = 3; // spalte strcpy( lvi.pszText, szWcount.c_str() ); ListView_SetItem( hLV, &lvi); lvi.iSubItem = 4; // spalte strcpy( lvi.pszText, szWprice.c_str() ); ListView_SetItem( hLV, &lvi); lvi.iSubItem = 5; // spalte strcpy( lvi.pszText, szWdeposit.c_str() ); ListView_SetItem( hLV, &lvi);kann man das nicht auch anstatt des enventhandlers nehmen? oder ist da was dran auszu setzen?
noch was... ich habe fuer jede zeile eine indexnummer in der ersten spalte stehen..also 1,2,3 ... doch irgendwie wird in des listview so einsortiert das immer das letzte item obensteht und alle nachrutschen, das will ich aber nicht... das letzte soll unten angefügt werden.... brauch ich da die mit GETCURSEL ermitelte imnumer oder gehts auch mit nen flag?Gruß Tobi.
-
huhu keiner ne antwort fuer mich?
-
mal in meinen winapi wrapper nachschaun und fuer euch n bissl vereinfachen #gg
man muss erst ein item erstellen welche die item nummer als zahl bekommt, dann kann man lauter sub items erstellen welche sich nach dieser zahl richten, wenn man iItem immer 0 macht, wird es auch immer index 0 haben, dh oben sein
// Elemente hinzufuegen mit positionsangabe, zb for(int i=0, i<199, ++i) AddItem(i, _T("Element")); // i = index welche zeile // bool AddItem(const unsigned int& uiPos, const std::wstring& strName){ TCHAR *str = new TCHAR[strName.length()+1]; _tcsncpy_s(str, strName.length()+1, strName.c_str(), strName.length()); LVITEM item; item.mask = LVIF_COLUMNS|LVIF_TEXT; item.iSubItem = 0; item.cColumns = 0; item.iItem = uiPos; item.pszText = str; bool ret = (::SendMessage(m_Handle, LVM_INSERTITEM, 0, reinterpret_cast<LPARAM>(&item)) == -1) ? false : true; delete [] str; str = 0; return ret; }// subitem benennen for(int i=0, i<199, ++i) SetSubItemText(1, i, _T("Element")); // 1 = welche spalte // i = index welche zeile bool SetSubItemText(const unsigned int& uiNumber, const unsigned int& uiPos, const std::wstring& strName){ TCHAR *str = new TCHAR[strName.length()]; _tcsncpy_s(str, strName.length()+1, strName.c_str(), strName.length()); LVITEM item; item.mask = LVIF_COLUMNS|LVIF_TEXT; item.iSubItem = uiNumber; item.cColumns = 0; item.pszText = str; return (::SendMessage(m_Handle, LVM_SETITEMTEXT, uiPos, reinterpret_cast<LPARAM>(&item))) ? true : false; }
-
Ich kann dir diesen Artikel nur emfehlen http://www.codeproject.com/listctrl/listview.asp
Da steht einiges drin bestimmt auch was für dich
MfG schirrmie
-
@Mr Evil: Du mischt in Deinem Code aber UNICODE mit ANSI 'Snippets'. Also entweder vollständig kompatibel oder Du entscheidest Dich für eine Seite der Macht
.