Zum Inhalt springen

Empfohlene Beiträge

Geschrieben

Ich habe ein ListView mit 10 subItems erstellt und habe es schon mit einigen Zeilen befüllen lassen.

Jetzt möchte ich aber noch items hinzufügen können. Wie funktioniert das, bei mir liefert es immer ein -1 zurück.

Ich hätte das mit einem SetItem Macro versucht und eine LVITEM struct verwendet.

Dann wollte ich die Zeile mit dem Macro SetTextItem befüllen wollen.

Vielen Dank im voraus.

Geschrieben

Ich glaube ich habe etwas gefunden in der MSDN. Nur leider weis ich nicht ganz wie ich das verwenden soll, da ich 2 verschiedene structs verwendet.

Eine davon verwendet schon das WM_NOTIFY.

Wie könnte ich den folgenden Code umschreiben um ohne dem WM_NOTIFY arbeiten zu können?

Hier der Link zur Info:

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/commctls/listview/listview_using.asp

Hier das Beispiel von der MSDN:

// This code snippet adds three items, each with three

// subitems, to a list-view control. 

// hWndListView - handle to the list-view control.

// The following application-specific structure, 

// PETINFO, is used in the snippet.


typedef struct tagPETINFO

{

char szKind[10];

char szBreed[50];

char szPrice[20];

}PETINFO;


// A PETINFO variable is declared and initialized as

// follows:


PETINFO rgPetInfo[ ] = 

{

{"Dog", "Poodle", "$300.00"},

{"Cat", "Siamese", "$100.00"},

{"Fish", "Angel Fish", "$10.00"},

};


// Some code to create the list-view control.

// Initialize LVITEM members that are common to all

// items. 

lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM | LVIF_STATE; 

lvI.state = 0; 

lvI.stateMask = 0; 


// Initialize LVITEM members that are different for each item. 

for (index = 0; index < 3; index++)

{

   	lvI.iItem = index;

	lvI.iImage = index;

	lvI.iSubItem = 0;

	lvI.lParam = (LPARAM) &rgPetInfo[index];

	lvI.pszText = LPSTR_TEXTCALLBACK; // sends an

	                                  // LVN_GETDISP

                                      // message.									  

if(ListView_InsertItem(hWndListView, &lvI) == -1)

return NULL;

}


// Because the application specifies LPSTR_TEXTCALLBACK, it

// sends LVN_GETDISPINFO notification messages. The 

// application must process these notification messages and

// supply the text for the subitems.

// The text is stored in a previously listed

// application-defined structure called PETINFO. 


case WM_NOTIFY:

  switch (((LPNMHDR) lParam)->code)

  {

  case LVN_GETDISPINFO:

    switch (((LPNMLVDISPINFO)lParam)->item.iSubItem)

    {

    case 0:

      plvdi->item.pszText =

	    rgPetInfo[plvdi->item.iItem].szKind;

      break;


    case 1:

      plvdi->item.pszText =

	    rgPetInfo[plvdi->item.iItem].szBreed;

      break;


    case 2:

      plvdi->item.pszText =

	    rgPetInfo[plvdi->item.iItem].szPrice;

      break;


    default:

      break;

    }

    return 0;

  }


// NOTE: in addition to setting pszText to point to 

// the item text, you could copy the item text into pszText 

// using StringCchCopy. For example:

// StringCchCopy(rgPetInfo[plvdi->item.iItem].szKind, 

//                          sizeof(rgPetInfo[plvdi->item.iItem].szKind), 

//                          plvdi->item.pszText);

Danke schon mal.

Geschrieben

Dieser Code hilft dir nur, wenn du ein virtuelles ListControl brauchst. Falls du nicht weißt, was das ist, brauchst du es sehr wahrscheinlich nicht. ;)

Fehler in deinem Code können wir nur finden, wenn du uns den Code zeigst.

Geschrieben

Also ich weis nicht was ein virtuelles ListView ist. Genau so weis ich auch nicht wie du das erkennst, dass es für ein virtuelles ListView gehört.

Kannst du mir sagen an was man das kennt???? :confused:

void InsertItem_func(HWND hwnd_Dlg)

{

   LPLVITEM  lvItem;

   HWND hwnd_ListView = NULL, hwnd_Parent = NULL;

   long  Index = 0;

   TCHAR szIndex[10] = "";


   hwnd_Parent = GetParent(hwnd_Dlg);

   hwnd_ListView = Dlg..(hwnd_Parent, ID_LISTVIEW);

   lvItem = (struct _LVITEM *) malloc(sizeof(_LVITEM));

   Index = ListView_InsertItem(hwnd_ListView, lvItem); //Hier bekomme ich immer ein -1 als Ergebnis


   //ListView_SetItemText(HWND hwnd, int i, int iSubItem, LPCSTR pszText);

   wsprintf(szIndex, "%d", Index);

   ListView_SetItemText(hwnd_ListView, Index, 0, szIndex);

   ListView_SetItemText(hwnd_ListView, Index, 1, dsh.szpName);

   ListView_SetItemText(hwnd_ListView, Index, 2, dsh.szpFilmlength);

...

}

So irgendwie habe ich das versucht zu lösen.

Aber jetzt habe ich gelesen das ListView_SetItemText eine LVN_GETDISPINFO notification message auslöst und ich glaub da wird ein WM_NOTIFY ausgelöst.

Vorschläge???

Geschrieben
Also ich weis nicht was ein virtuelles ListView ist. Genau so weis ich auch nicht wie du das erkennst, dass es für ein virtuelles ListView gehört.

Kannst du mir sagen an was man das kennt???? :confused:

Ein virtuelles ListControl hält die anzuzeigenden Daten nicht selbst vor, sondern fragt immer beim Parent nach. Dazu schickt es die Nachricht LVN_GETDISPINFO.

LPLVITEM lvItem;

lvItem = (struct _LVITEM *) malloc(sizeof(_LVITEM));

Mal davon abgesehen, dass es hier nicht notwendig ist, Speicher vom Heap anzufordern (du könntest auch eine lokale LVITEM-Variable benutzen):

Du musst die Struktur mit Daten füllen. Setz alle Member auf 0, bis auf iItem, den setzt du auf den Index, wo das Item eingefügt werden soll. Den Text kannst du gleich mit angeben, musst du aber nicht.

Geschrieben

Ich glaube ich habe so ein virtuelles ListView eingebaut.

Bei so einem ListView werden nur die Daten geholt, die im Fenster Platz haben, verstehe ich das richtig??

Erst wenn ich hinuterscrolle werden die nächsten Daten eingelesen?

Kann es deswegen erst dann zu Fehler kommen, wenn man weiter hinuterscrollt, die wie folgt kurz beschrieben sind.

1. Ist der Text auf eine bestimmte Länge begrenzt, weil wenn ich zu der Zeilennummer 67 gescrollt habe meldet mein Programm einen Fehler (read konnte nicht durchgeführt werden) und beendet sich.

2. Bei der Zeilennummer 187 beendet sich mein Programm mit dem Fehler:

unbekannter Softwarefehler und eine Fehlernummer dazu, ich glaub das war 409.

Diese Fehler bekomme ich wenn ich die Schauspieler in das ListView auch eintragen lasse. Die Schauspieler werden zu jedem Film wie folgt eingetragen:

z. B.: id Filmbezeichnung ... Schauspieler Kurztext

1 film1 Actor1; Actor2; Actor3; ... kurze Beschreibung

Habe ich vielleicht zu viele Daten in das ListView schon geschrieben?

Muss ich mehr Speicher für das ListView anfordern?

Geht das überhaupt oder wird das von Windows intern erledigt?

Ich hoffe ich habe nicht zu verwirrend geschrieben.

Danke schon mal.

Geschrieben
Ich glaube ich habe so ein virtuelles ListView eingebaut.

Bei so einem ListView werden nur die Daten geholt, die im Fenster Platz haben, verstehe ich das richtig??

Erst wenn ich hinuterscrolle werden die nächsten Daten eingelesen?

Wenn du mit "Einlesen" das Anfordern vom Parentfenster mittels Notifikation meinst, ja.

Habe ich vielleicht zu viele Daten in das ListView schon geschrieben?

Muss ich mehr Speicher für das ListView anfordern?

Geht das überhaupt oder wird das von Windows intern erledigt?

Wenn du wirklich ein virtuelles ListView hast, dann brauchst du gar keine Daten hineinzuschreiben. Du brauchst auch keinen Speicher anzufordern.

Zeig mal deine LVN_GETDISPINFO-Behandlung.

Geschrieben

So habe ich die LVN_GETDISPINFO - Behandlung eingebaut:

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)

{

	static HINSTANCE		hInstance;

	static HWND				hwndStatus, hwndStatusBar, hwndListView, hwndComboBox;

	LPSTR						lpstr = "String1";

	int						ComboBox_Index = 0, i = 0;

	TCHAR						*dbName = "film_dbtest";


   switch(message)

   {  case WM_CREATE:

				hwndListView = CreateListView(hinst, hwnd);

				InitListView(hwndListView);

				hwnd_ListView = hwndListView;


				break;

				}

			}


			break;


		case WM_NOTIFY:

			return ListViewNotify(hwnd, lParam);


		case WM_SIZE:


		case WM_COMMAND:

			switch(LOWORD(wParam))

			{	

				case IDM_FILE_LOGIN:

					DialogBox(hInstance, TEXT("LoginBox"), hwnd, LoginDlg);

					break;

				case IDM_FILE_END:

					DestroyWindow(hwnd);

					break;

				case IDM_EDIT_DS_ADD:

					DialogBox(hInstance, TEXT("Datensatz_h"), hwnd, DatensatzHDlg);

					ListViewItem_add(hwndListView);

					break;

				case IDM_EDIT_DS_CHANGE:

					DialogBox(hInstance, TEXT("Datensatz_ae"), hwnd, DatensatzAEDlg);

					break;

				case IDM_EDIT_DS_CLEAR:

					DialogBox(hInstance, TEXT("Datensatz_l"), hwnd, DatensatzLDlg);

					break;

				case IDM_EDIT_SEARCH:

					DialogBox(hInstance, TEXT("SearchBox"), hwnd, DatensatzSearchDlg);

					break;

			}

			return 0;

      case WM_DESTROY:

			verbindung_schliessen();

         PostQuitMessage(0);

         return 0;

   }

   return DefWindowProc(hwnd, message, wParam, lParam);

}
So füge ich ein weiteres Item ein:
void ListViewItem_add(HWND hwnd_ListView)

{

/*

typedef struct _LVITEM { 

    UINT   mask; 

    int    iItem; 

    int    iSubItem; 

    UINT   state; 

    UINT   stateMask; 

    LPTSTR  pszText; 

    int    cchTextMax; 

    int    iImage; 

    LPARAM lParam;

#if (_WIN32_IE >= 0x0300)

    int iIndent;

#endif

} LVITEM, FAR *LPLVITEM; 

*/


	LPLVITEM	lvItem;

	TCHAR		szItem[10] = "";

	TCHAR		*szpTemp = NULL;

	TCHAR		*szpBindestrich = " - ", *szpStrichpunkt = "; ";

	long		lIndex = 0, i = 0, j = 0, anzahl_zeichen = 0;


	lvItem = (LPLVITEM) malloc(sizeof(LPLVITEM));

	lvItem->mask = 0;

	lvItem->iSubItem = 0;

	lvItem->state = 0;

	lvItem->stateMask = 0;

	lvItem->pszText = "";

	lvItem->cchTextMax = 0;

	lvItem->iImage = 0;


	lvItem->iItem = ListView_GetItemCount(hwnd_ListView) + 1;

	lIndex = ListView_InsertItem(hwnd_ListView, lvItem);


	for(i = 0; i < 10; i++)

	{

		switch(i)

		{

			case 0:

				wsprintf(szItem, "%d", lIndex);

				MessageBox(NULL, szItem, TEXT("Itemidex"), MB_OK);


				lvItem->pszText = szItem;

				ListView_SetItemText(hwnd_ListView, lIndex, i, szItem);

				break;				


			case 1:

				ListView_SetItemText(hwnd_ListView, lIndex, i, dsh.szpid);

				break;


....

			case 6:

				//Audio

				j = 0;

				anzahl_zeichen = 0;

				while(*(dsh.szpSprache + j) != NULL || *(dsh.szpAQuality + j) != NULL)

				{

					anzahl_zeichen +=	strlen(*(dsh.szpSprache + j)) + 

											strlen(szpBindestrich) +

											strlen(*(dsh.szpAQuality + j)) +

											strlen(szpStrichpunkt);

					j++;

				}

				szpTemp = (TCHAR *) malloc(sizeof(TCHAR) * (anzahl_zeichen + 1));

				j = 0;

				while(*(dsh.szpSprache + j) != NULL || *(dsh.szpAQuality + j) != NULL)

				{

					if (j == 0) strcpy(szpTemp, *(dsh.szpSprache + j));

					else strcat(szpTemp, *(dsh.szpSprache + j));


					strcat(szpTemp, szpBindestrich);

					strcat(szpTemp, *(dsh.szpAQuality + j));

					strcat(szpTemp, szpStrichpunkt);

					j++;

				}

				ListView_SetItemText(hwnd_ListView, lIndex, i, szpTemp);

				free(szpTemp);

				break;


			case 7:

				//Schauspieler

				j = 0;

				anzahl_zeichen = 0;

				while(*(dsh.szpActor + j) != NULL)

				{

					anzahl_zeichen +=	strlen(*(dsh.szpActor + j)) + strlen(szpStrichpunkt);

					j++;

				}

				szpTemp = (TCHAR *) malloc(sizeof(TCHAR) * (anzahl_zeichen + 1));

				j = 0;

				while(*(dsh.szpActor + j) != NULL)

				{

					if (j == 0) strcpy(szpTemp, *(dsh.szpActor + j));

					else strcat(szpTemp, *(dsh.szpActor + j));


					strcat(szpTemp, szpStrichpunkt);

					j++;

				}

				ListView_SetItemText(hwnd_ListView, lIndex, i, szpTemp);

				free(szpTemp);

				break;


....

			case 10:

				ListView_SetItemText(hwnd_ListView, lIndex, i, dsh.szpText);

				break;

		}

	}

}

Das neue Item wird hinzugefügt, nur der Text wird nicht richtig dargestellt bzw wenn ich zu dem neuen Item scrolle beendet sich mein Programm mit einem Fehler: read kann nicht ausgeführt werden.

Ich denke das es mit dem WM_NOTIFY zusammen hängt, da 2 verschiedene structs verwendet werden.

Geschrieben

Habe noch etwas vergessen.

So sieht das ListViewNotify(hwnd, lParam) aus:

LRESULT ListViewNotify(HWND hWnd, LPARAM lParam)

{

	LPNMHDR  lpnmh = (LPNMHDR) lParam;

	HWND     hwndListView = GetDlgItem(hWnd, ID_LISTVIEW);

	unsigned long	j = 0;

	unsigned long	anzahl_zeichen = 0;

	TCHAR		*szpTemp = NULL;

	TCHAR		*szpBindestrich = " - ", *szpStrichpunkt = "; ";


	switch(lpnmh->code)

   {

		case LVN_GETDISPINFO:

      {

			LV_DISPINFO *lpdi = (LV_DISPINFO *)lParam;

			TCHAR szString[MAX_PATH];


			if(lpdi->item.iSubItem)

         {

				if(lpdi->item.mask & LVIF_TEXT)

            {

					if (lpdi->item.iSubItem == 1)

						lstrcpy(lpdi->item.pszText, dbD_ptr[lpdi->item.iItem].szpid);


					if (lpdi->item.iSubItem == 2)

						lstrcpy(lpdi->item.pszText, dbD_ptr[lpdi->item.iItem].szpName);


					if (lpdi->item.iSubItem == 3)

						lstrcpy(lpdi->item.pszText, dbD_ptr[lpdi->item.iItem].szpFilmlength);


					if (lpdi->item.iSubItem == 4)

						lstrcpy(lpdi->item.pszText, dbD_ptr[lpdi->item.iItem].szpVQuality);


					if (lpdi->item.iSubItem == 5)

						lstrcpy(lpdi->item.pszText, dbD_ptr[lpdi->item.iItem].szpGenre);


					if (lpdi->item.iSubItem == 6)

					{	

						j = 0;

						anzahl_zeichen = 0;

						for(j = 0; j < dbD_ptr[lpdi->item.iItem].iAudio_count; j++)

						{

							anzahl_zeichen +=	strlen(*(dbD_ptr[lpdi->item.iItem].szpSprache + j)) + 

													strlen(szpBindestrich) +

													strlen(*(dbD_ptr[lpdi->item.iItem].szpAQuality + j)) +

													strlen(szpStrichpunkt);


						}

						szpTemp = (TCHAR *) malloc(sizeof(TCHAR) * (anzahl_zeichen + 1));

						//j = 0;

						for(j = 0; j < dbD_ptr[lpdi->item.iItem].iAudio_count; j++)

						{

							if (j == 0) strcpy(szpTemp, *(dbD_ptr[lpdi->item.iItem].szpSprache + j));

							else strcat(szpTemp, *(dbD_ptr[lpdi->item.iItem].szpSprache + j));


							strcat(szpTemp, szpBindestrich);

							strcat(szpTemp, *(dbD_ptr[lpdi->item.iItem].szpAQuality + j));

							strcat(szpTemp, szpStrichpunkt);

						}

						lstrcpy(lpdi->item.pszText, szpTemp);

						free(szpTemp);

					}


					if (lpdi->item.iSubItem == 7)

					{	

						//wsprintf(szString, "Schauspieler - Column %d", lpdi->item.iItem + 1, lpdi->item.iSubItem);

						//lstrcpy(lpdi->item.pszText, szString);

						j = 0;

						anzahl_zeichen = 0;

						for(j = 0; j < dbD_ptr[lpdi->item.iItem].iActor_count; j++)

						{

							anzahl_zeichen +=	strlen(*(dbD_ptr[lpdi->item.iItem].szpActor + j)) + 

													strlen(szpStrichpunkt);


						}

						szpTemp = (TCHAR *) malloc(sizeof(TCHAR) * (anzahl_zeichen + 1));

						for(j = 0; j < dbD_ptr[lpdi->item.iItem].iActor_count; j++)

						{

							if (j == 0) strcpy(szpTemp, *(dbD_ptr[lpdi->item.iItem].szpActor + j));

							else strcat(szpTemp, *(dbD_ptr[lpdi->item.iItem].szpActor + j));


							strcat(szpTemp, szpStrichpunkt);

						}

						lstrcpy(lpdi->item.pszText, szpTemp);

						free(szpTemp);

					}


					if (lpdi->item.iSubItem == 8)

					{	

						//wsprintf(szString, "Besitzer - Column %d", lpdi->item.iItem + 1, lpdi->item.iSubItem);

						lstrcpy(lpdi->item.pszText, dbD_ptr[lpdi->item.iItem].szpUser);

					}


					if (lpdi->item.iSubItem == 9)

					{	

						//wsprintf(szString, "Medienanzahl - Column %d", lpdi->item.iItem + 1, lpdi->item.iSubItem);

						lstrcpy(lpdi->item.pszText, dbD_ptr[lpdi->item.iItem].szpAnzahl);

					}


					if (lpdi->item.iSubItem == 10)

					{	

						//wsprintf(szString, "Kurzbeschreibung - Column %d", lpdi->item.iItem + 1, lpdi->item.iSubItem);

						lstrcpy(lpdi->item.pszText, dbD_ptr[lpdi->item.iItem].szpText);

					}

            }

         }

			else

         {

				if(lpdi->item.mask & LVIF_TEXT)

            {

					wsprintf(szString, "%d", lpdi->item.iItem + 1);

					lstrcpy(lpdi->item.pszText, szString);

            }


         }

      }

      return 0;


   case LVN_ODCACHEHINT:

      {

      LPNMLVCACHEHINT   lpCacheHint = (LPNMLVCACHEHINT)lParam;

      /*

      This sample doesn't use this notification, but this is sent when the 

      ListView is about to ask for a range of items. On this notification, 

      you should load the specified items into your local cache. It is still 

      possible to get an LVN_GETDISPINFO for an item that has not been cached, 

      therefore, your application must take into account the chance of this 

      occurring.

      */

      }

      return 0;


   case LVN_ODFINDITEM:

      {

      LPNMLVFINDITEM lpFindItem = (LPNMLVFINDITEM)lParam;

      /*

      This sample doesn't use this notification, but this is sent when the 

      ListView needs a particular item. Return -1 if the item is not found.

      */

      }

      return 0;

   }


return 0;

}

Geschrieben

int item.cchTextMax steht, wie groß der Puffer für den Text ist. Wenn du mehr brauchst, musst du pszText selbst zuweisen. Dieser Speicher muss solange unverändert bereit stehen, bis das Element entfernt wird oder zwei weitere LVN_GETDISPINFO-Nachrichten eingetroffen sind.

Geschrieben

Deine Aussage verstehe ich nicht ganz. :confused:

Kannst du mir das nochmal etwas genauer erklären??

Kann ich für jedes neue Item eine andere Grösse eingeben bzw. für jedes subItem?

Wenn ich diese Grösse (int item.cchTextMax ) verändere muss ich dann ein malloc durchführen und dann den Text in die Variable pszText kopieren mit strcpy??

Ist das bezogen auf mein ListViewNotify bezogen oder wie ich ein weiters Element einfüge.

Dieser Speicher muss solange unverändert bereit stehen, bis das Element entfernt wird oder zwei weitere LVN_GETDISPINFO-Nachrichten eingetroffen sind.

Warum gerade 2 weitere Nachrichten bzw. entfernt wird???

Entfernt: von der struct oder von dem angezeigten Bereich?

Danke schon mal.

Geschrieben

Wenn du eine LVN_GETDISPINFO-Nachricht bekommst, steht in der LVITEM-Struktur schon ein Puffer für den Text bereit. Wie groß der ist, steht in item.cchTextMax.

Wenn du mehr Platz brauchst, musst du selbst einen Puffer bereitstellen und item.pszText darauf zeigen lassen.

Ich verstehe nicht, warum du beim Hinzufügen der Items überhaupt schon Texte hineinschreibst. Wenn du unbedingt ein virtuelles ListControl haben musst, dann wird es dich schon fragen, wenn es Texte braucht.

Wie und wo stellst du eigentlich sicher, dass du schon genügend Einträge in dbD_ptr eingelesen hast?

Warum gerade 2 weitere Nachrichten bzw. entfernt wird???
So steht's in der MSDN Library. Keine Ahnung, warum.

Entfernt: von der struct oder von dem angezeigten Bereich?

Weder noch. Entfernt aus dem ListControl.

Geschrieben

Also kann ich item.cchTextMax nicht verändern?

Wenn du mehr Platz brauchst, musst du selbst einen Puffer bereitstellen und item.pszText darauf zeigen lassen.

Das könnte ich z. B.: dann so lösen:

item.pszText = dsh.pszName

ist das richtig?

Ich verstehe nicht, warum du beim Hinzufügen der Items überhaupt schon Texte hineinschreibst. Wenn du unbedingt ein virtuelles ListControl haben musst, dann wird es dich schon fragen, wenn es Texte braucht.

Ein virtuelles ListControl muss ich nicht wirklich haben, aber das habe ich gefunden und habe es deshalb eingebaut.

Wie könnte ich die Texte hineinschreiben, wenn ich das nicht sofort mache.

Komme ich da nicht mit dem WM_NOTIFY und der struct dbD_ptr in konflikt??

Für dbD_ptr wird in 5 Funktionen die Daten eingelesen - kommen von einer MySQL Datenbank.

1. Funktion sieht wie folgt aus:

void filmtable_data()

{

   unsigned long  anzahl_reihen = 0;

   unsigned int	i = 0, j = 0;

   int		iIndex = 0, iLength = 0;

   MYSQL_ROW	row;  

   MYSQL_RES	*mysql_res;

   TCHAR		*query;

   TCHAR		*select = "SELECT * FROM filmtable WHERE besitzerid = ";

   TCHAR		*select1 = "SELECT * FROM filmtable "

		"order by besitzerid, videoformatid, filmbezeichnung";


   query = (TCHAR *) malloc(strlen(select1) + 1);

   strcpy(query, select1);

   /* Jetzt die Anfrage an den Datenbankserver */

   mysql_query(mysql, query);

   check_error();

   /* Daten der Anfrage abholen */

   mysql_res = mysql_store_result(mysql);

   check_error();

   /* Anzahl der gefundenen Datensätze ermitteln */

   anzahl_reihen = (unsigned long) mysql_num_rows (mysql_res);

   iDatensaetze = anzahl_reihen;


   dbD_ptr = (struct _dbDaten *) malloc(sizeof(_dbDaten) * anzahl_reihen);

   /* Gefundener Datensatz bzw. Datensätze ausgeben */

   while ((row = mysql_fetch_row (mysql_res)) != NULL)  

   {	/* Einzelne Spalten der Zeile ausgeben */

		for (i = 0;  i < mysql_num_fields(mysql_res);  i ++)

			switch(i)

			{	

				case 0: 

					//Hier kann man die ID erfassen

					dbD_ptr[j].id = str2int(row[i]);

					dbD_ptr[j].szpid = (TCHAR *) malloc(sizeof(TCHAR) * (strlen(row[i]) + 1));

					wsprintf(dbD_ptr[j].szpid, "%s", row[i]);


					break;


				case 1: 

					//Filmbezeichnung

					dbD_ptr[j].szpName = (TCHAR *) malloc(sizeof(TCHAR) * (strlen(row[i]) + 1));

					wsprintf(dbD_ptr[j].szpName, "%s", row[i]);

					break;


				case 2: 

					//Filmlänge

					dbD_ptr[j].szpFilmlength = (TCHAR *) malloc(sizeof(TCHAR) * (strlen(row[i]) + 1));

					wsprintf(dbD_ptr[j].szpFilmlength, "%s", row[i]);						

					break;


				case 3: 

					//VideoformatID

					dbD_ptr[j].iVformatID = str2int(row[i]);

					if (dbD_ptr[j].iVformatID)

					{

						dbD_ptr[j].szpVQuality = (TCHAR *) malloc(sizeof(TCHAR) * (strlen(*(video.format + (dbD_ptr[j].iVformatID - 1))) + 1));

						wsprintf(dbD_ptr[j].szpVQuality, "%s", *(video.format + (dbD_ptr[j].iVformatID - 1)));

					}

					break;


				case 4: 

					//FilmartID

					dbD_ptr[j].iGenreID = str2int(row[i]);

					if (dbD_ptr[j].iGenreID)

					{

						dbD_ptr[j].szpGenre = (TCHAR *) malloc(sizeof(TCHAR) * (strlen(*(genre.art + dbD_ptr[j].iGenreID - 1)) + 1));

						wsprintf(dbD_ptr[j].szpGenre, "%s", *(genre.art + dbD_ptr[j].iGenreID - 1));

					}

					break;


				case 5: 

					//BesitzerID

					dbD_ptr[j].iBesitzerID = str2int(row[i]);

					dbD_ptr[j].szpUser = (TCHAR *) malloc(sizeof(TCHAR) * (strlen(*(besitzer.user + dbD_ptr[j].iBesitzerID - 1)) + 1));

					wsprintf(dbD_ptr[j].szpUser, "%s", *(besitzer.user + dbD_ptr[j].iBesitzerID - 1));

					break;


				case 6: 

					//Medienanzahl

					dbD_ptr[j].szpAnzahl = (TCHAR *) malloc(sizeof(TCHAR) * (strlen(row[i]) + 1));

					strcpy(dbD_ptr[j].szpAnzahl, row[i]);

					break;


				case 7: 

					//Kurzbeschreibung

					dbD_ptr[j].szpText = (TCHAR *) malloc(sizeof(TCHAR) * (strlen(row[i]) + 1));							

					strcpy(dbD_ptr[j].szpText, row[i]);

					break;

				}

 			j++;

      }

   /* Speicherplatz wieder freigeben */

   mysql_free_result(mysql_res);

   free(query);

}

Diese Daten lese ich noch bevor das ListView erzeugt wird ein.

//Füllen der struct _dbDaten

filmtable_data();

//Audiodaten abfragen und speichern

audiotable_count();

audiotable_data();

//Schauspielerdaten abfragen und speichern

schauspieler_count();

schauspieler_data();

Geschrieben
Also kann ich item.cchTextMax nicht verändern?

Es ergibt keinen Sinn, cchTextMax zu verändern.

Das könnte ich z. B.: dann so lösen:

item.pszText = dsh.pszName

ist das richtig?

Wenn dsh.pszName lange genug verfügbar ist, ja.

Ein virtuelles ListControl muss ich nicht wirklich haben, aber das habe ich gefunden und habe es deshalb eingebaut.

Schlecht. Mit dem virtuellen ListControl sollte man nur arbeiten, wenn man einen guten Grund dafür hat, z.b. wenn man häufig Objekte am Anfang oder in der Mitte entfernt. Da muss ein nicht-virtuelles ListControl viel umkopieren, und das dauert.

Diese Daten lese ich noch bevor das ListView erzeugt wird ein.
Gibt es einen Grund dafür? Wenn du die Daten erst dann einlesen würdest, wenn du sie einfügen kannst, bräuchtest du kein virtuelles ListControl und könntest auf das Array dbD_ptr komplett verzichten.

Du kannst auch alles vorher einlesen und dafür dein Array benutzen, aber ein virtuelles ListControl brauchst du dann immer noch nicht.

Geschrieben

Ich habe mich jetzt ein wenig schlau gemacht in der MSDN.

Damit ich kein virtuelles ListView mehr habe müsste ich den Style LVS_ONERDATA herausnehmen.

Dann bekommt man auch keine LVN_GETDISPINFO - Nachrichten mehr.

Ist hoffentlich richtig so?

Um Daten zu dem virtuellen ListView hinzufügen zu können müsste ich mein dynamisches dbD_ptr - Array immer wieder vergrössern und kann auch nicht, wie ich wollte, die Message LVM_SETITEMTEXT verwenden, die ich in der Funktion

void ListViewItem_add(HWND hwnd_ListView)

verwende.

Das sind Gründe um kein virtuelles ListView zu verwenden, zumindest zur Zeit.

Hast du einige Tipps, wie ich "schnell" und unkompliziert die Daten in ein normales ListView eintragen kann, oder muss ich jede einzelne Zeile, so wie ich es mit der Funktion ListViewItem_add(HWND hwnd_ListView) mache, einfügen?

Danke.

PS: Hoffentlich bekomme ich den Umbau ohne viele Seufzer hin ;)

Geschrieben

Wenn es jemanden interessiert, so füge ich meine Struct in das ListView ein.

Vielleicht hat jemand Verbesserungsvorschläge.

void ListView_add_Data(HWND hwnd_ListView)

{

	unsigned long	i = 0, j = 0, n = 0;

	unsigned long	anzahl_zeichen = 0;

	long				lIndex = 0;

	TCHAR		*szpTemp = NULL, sz_vid[10] = "";

	TCHAR		*szpBindestrich = " - ", *szpStrichpunkt = "; ";

	TCHAR		szString[MAX_PATH] = "";

	LVITEM	lvItem;


	lvItem.mask = LVIF_TEXT;

	for(n = 0; n < iDatensaetze; n++)

	{

		for(i = 0; i < 11; i++)

		{

			switch(i)

			{

				case 0:

					//BOOL ListView_SetItem(HWND hwnd, const LPLVITEM pitem);

					wsprintf(sz_vid, "%d", n + 1);

					lvItem.iItem = n;

					lvItem.iSubItem = i;

					lvItem.pszText = sz_vid;

					lIndex = ListView_InsertItem(hwnd_ListView, &lvItem);

					ListView_SetItemText(hwnd_ListView, n, i, sz_vid);

					break;


				case 1:

					ListView_SetItemText(hwnd_ListView, n, i, dbD_ptr[n].szpid);

					break;


				case 2:

					ListView_SetItemText(hwnd_ListView, n, i, dbD_ptr[n].szpName);

					break;


				case 3:

					ListView_SetItemText(hwnd_ListView, n, i, dbD_ptr[n].szpFilmlength);

					break;


				case 4:

					ListView_SetItemText(hwnd_ListView, n, i, dbD_ptr[n].szpVQuality);

					break;


				case 5:

					ListView_SetItemText(hwnd_ListView, n, i, dbD_ptr[n].szpGenre);

					break;


				case 6:

					j = 0;

					anzahl_zeichen = 0;

					for(j = 0; j < dbD_ptr[n].iAudio_count; j++)

					{

						anzahl_zeichen +=	strlen(*(dbD_ptr[n].szpSprache + j)) + 

												strlen(szpBindestrich) +

												strlen(*(dbD_ptr[n].szpAQuality + j)) +

												strlen(szpStrichpunkt);			

					}

					szpTemp = (TCHAR *) malloc(sizeof(TCHAR) * (anzahl_zeichen + 1));

					for(j = 0; j < dbD_ptr[n].iAudio_count; j++)

					{

						if (j == 0) strcpy(szpTemp, *(dbD_ptr[n].szpSprache + j));

						else strcat(szpTemp, *(dbD_ptr[n].szpSprache + j));


						strcat(szpTemp, szpBindestrich);

						strcat(szpTemp, *(dbD_ptr[n].szpAQuality + j));

						strcat(szpTemp, szpStrichpunkt);

					}


					ListView_SetItemText(hwnd_ListView, n, i, szpTemp);

					free(szpTemp);

					break;


				case 7:

					j = 0;

					anzahl_zeichen = 0;


					for(j = 0; j < dbD_ptr[n].iActor_count; j++)

					{

						anzahl_zeichen +=	strlen(*(dbD_ptr[n].szpActor + j)) + 

												strlen(szpStrichpunkt);


					}

					szpTemp = (TCHAR *) malloc(sizeof(TCHAR) * (anzahl_zeichen + 1));

/*

					if (szpTemp == NULL)

					{

						MessageBox(NULL, TEXT("Zu wenig Speicher"), TEXT("Speicher?"), MB_OK);

						szpTemp = (TCHAR *) malloc(sizeof(TCHAR) * 30);

						wsprintf(szpTemp, "%s", "zu wenig Speicher");

					}

					else

					{

*/

					for(j = 0; j < dbD_ptr[n].iActor_count; j++)

					{

						if (j == 0) strcpy(szpTemp, *(dbD_ptr[n].szpActor + j));

						else strcat(szpTemp, *(dbD_ptr[n].szpActor + j));


						strcat(szpTemp, szpStrichpunkt);

					}


					ListView_SetItemText(hwnd_ListView, n, i, szpTemp);

					free(szpTemp);

					break;


				case 8:

					ListView_SetItemText(hwnd_ListView, n, i, dbD_ptr[n].szpUser);

					break;


				case 9:

					ListView_SetItemText(hwnd_ListView, n, i, dbD_ptr[n].szpAnzahl);

					break;


				case 10:

					ListView_SetItemText(hwnd_ListView, n, i, dbD_ptr[n].szpText);

					break;

			}//ende switch(i)

		} //ende for(j = 0; j < 11; j++)

	} //ende for(i = 0; i < iDatensaetze; i++)


}

Viel Spaß damit. :)

Geschrieben

Die innere for-Schleife und das switch sind unnötig, du könntest das auch so machen:


for(n = 0; n < iDatensaetze; n++)
{
wsprintf(sz_vid, "%d", n + 1);
lvItem.iItem = n;
lvItem.iSubItem = 0;
lvItem.pszText = sz_vid;
lIndex = ListView_InsertItem(hwnd_ListView, &lvItem);
//ListView_SetItemText(hwnd_ListView, n, 0, sz_vid);

ListView_SetItemText(hwnd_ListView, n, 1, dbD_ptr[n].szpid);

ListView_SetItemText(hwnd_ListView, n, 2, dbD_ptr[n].szpName);

ListView_SetItemText(hwnd_ListView, n, 3, dbD_ptr[n].szpFilmlength);
// usw...
[/CODE]

SetItemText für die erste Spalte brauchst du nicht, den Text gibst du ja schon bei InsertItem an.

Geschrieben

Ich dachte mit dem InsertItem wird nur eine neue Zeile eingefügt, jodch kein Text. Geht aus der SDK bzw. MSDN nicht wirklich hervor - zumindest für mich.

Oder mein Englisch ist ein wenig rost-durch-drungen. ;)

Ich weis nicht warum ich die 2. for-Schleife und das switch eingebaut habe. Ich denk mal in der hektig gestern, habe da wohl zu wenig überlegt.

Danke für die Tipps.

Dein Kommentar

Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...