List View

I am creating a list view control in my application; however, upon adding items/subitems, the application is crashing. I commented out the ListView_InsertItem(this->LvWnd, &this->LvItem) macro, it worked properly but without having any items been added

Can anyone suggest a good tutorial that I can follow other than the one in MSDN?

Thanks in advance
what does error say?
The application is crashing. Upon debudding it is showing the below:
Unhandled exception at 0x74c2c85f in BSolutionsApps.exe: 0xC0000005: Access violation reading location 0xcccccccc.


The Call Stack in the debugger shows the below:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
-> 	comctl32.dll!74c2c85f() 	
 	[Frames below may be incorrect and/or missing, no symbols loaded for comctl32.dll]	
 	comctl32.dll!74c2c8c7() 	
 	comctl32.dll!74cb193e() 	
 	comctl32.dll!74c82ef8() 	
 	comctl32.dll!74c9671b() 	
 	comctl32.dll!74c280a7() 	
 	comctl32.dll!74c28cf3() 	
 	comctl32.dll!74c28d75() 	
 	comctl32.dll!74c28e4e() 	
 	comctl32.dll!74c285e4() 	
 	comctl32.dll!74c27ec3() 	
 	comctl32.dll!74c27c19() 	
 	comctl32.dll!74c27b74() 	
 	comctl32.dll!74c27cb2() 	
>	msvcr90d.dll!_unlock(int locknum=19)  Line 376	C
 	msvcr90d.dll!_unlock_file(_iobuf * pf=0x50231448)  Line 318 + 0x14 bytes	C
 	msvcr90d.dll!fclose(_iobuf * stream=0x50231448)  Line 60 + 0x9 bytes	C
 	msvcr90d.dll!fclose(_iobuf * stream=0x50231448)  Line 59 + 0xc bytes	C
 	0021f1d0()	
 	user32.dll!7771c4e7() 	
 	user32.dll!7771c5e7() 	
 	user32.dll!7771c590() 	
 	user32.dll!77711b31() 	
 	user32.dll!77711b57() 	
 	BsolControls.dll!BsolControls::BsolListView::BsolListViewProcedure(HWND__ * hWnd_p=0x003f0892, unsigned int msg_p=15, unsigned int wParam_p=0, long lParam_p=0)  Line 203 + 0x1f bytes	C++
 	user32.dll!7771c4e7() 	
 	user32.dll!77715f9f() 	
 	user32.dll!7771c590() 	
 	user32.dll!77714f0e() 	
 	user32.dll!77714f7d() 	
 	ntdll.dll!77ca6fce() 	
 	user32.dll!77714ec3() 	
 	user32.dll!77715d0c() 	
 	user32.dll!77715d33() 	
 	BSolutionsApps.exe!WinMain(HINSTANCE__ * hInst_p=0x00cb0000, HINSTANCE__ * hPrevInstance_p=0x00000000, char * lpCmdLine_p=0x00392c58, int nCmdShow_p=1)  Line 80 + 0xc bytes	C++
 	BSolutionsApps.exe!__tmainCRTStartup()  Line 578 + 0x35 bytes	C
 	BSolutionsApps.exe!WinMainCRTStartup()  Line 403	C
 	kernel32.dll!7640ed6c() 	
 	ntdll.dll!77cc377b() 	
 	ntdll.dll!77cc374e() 	



Regards,
Can we have a link to the MSDN tutorial that you are working with? Usually those are pretty solid as long as you're using MS-VS or the MS compiler, but even when using MingW the only issue I run into is missing libraries. Also this piece of code here: ...&this->LvItem is the most convoluted thing I've seen in a long time, you realize you're passing a dereferenced piece of data by reference right? Now there might be a good reason to do this, but I'd like to see the original code if you don't mind.
Aside?

In case you don't already know...

If you're using Visual Studio, at least up until 2010, you can enable the symbol server so you get symbols for the system DLLs.

Menu: Tool > Options

Options Dialog: Debugging > Symbols

Then check the "Microsoft Symbol Server" box and fill in the path for the local cache.

It can take a while the first time you debug a Windows app after this, while it populates the cache, but afterwards it's more or less back to normal speed.

I'm not sure how this works with Visual Studio 2012; the MSDN entry I linked to above only seems to apply to 2003, 2005, 2008, and 2010.

(Edit: just checked Visual Studio 2012, and the options is in the same place.)

Andy

How to: Use a Symbol Server
http://msdn.microsoft.com/en-us/library/b8ttk8zy%28v=vs.100%29.aspx
Last edited on
Access violation reading location 0xcccccccc
well, check if this->LvWnd and &this->LvItem are correct (not empty, etc). It seems that error is here.
tath has a good point, the way you wrote it "ListView_InsertItem()" doesn't appear to be a member function, but in order for the keyword 'this' to mean anything it sort of has to be.
The link to the MSDN tutorial is:
http://msdn.microsoft.com/en-us/library/hh298346(v=vs.85).aspx

Regarding ...&this->LvItem:
LvItem is of LVITEM type and it is a member of my List View class. In the ListView_InsertItem macro, I am passing the address of the LVITEM.

Regading the missing libraries, I suspected to be the cause, however, it was working before. My list view was showing the items properly but it was crashing upon scrolling the vertical scroll bar.

Regarding the code, there are a lot of classes that I had developed and I think it will be difficult to follow, anyway below are some pieces:

The code of my ListView header:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#ifndef _BSOLLISTVIEW_H_INCLUDED_
#define _BSOLLISTVIEW_H_INCLUDED_

#include "BsolTextField.h"

namespace BsolControls {
	class BsolListView {
		private:
			HWND		LvWnd;
			int			LvNumCol;
			LVCOLUMN	LvColumn;
			LVITEM		LvItem;
			BsolClass	LvClass;


		public:
			DLL_BSOLCTRL BsolListView (BsolClass * class_p);		// Constructor					// Initialize columns of List View
			DLL_BSOLCTRL HWND BsolLvCreate (BsolWindow * prntWnd_p);
			DLL_BSOLCTRL HWND BsolLvGetWnd ();
			DLL_BSOLCTRL LVCOLUMN BsolLvGetColumn ();
			DLL_BSOLCTRL LVITEM BsolLvGetItem ();
			DLL_BSOLCTRL BsolClass * BsolLvGetClass ();
//			DLL_BSOLCTRL HWND BsolLvGetPrntWnd ();
			DLL_BSOLCTRL int BsolLvGetNumCol();

			DLL_BSOLCTRL void BsolLvSetWnd (HWND wnd_p);
			DLL_BSOLCTRL void BsolLvSetColumn (LVCOLUMN lvCol_p);
			DLL_BSOLCTRL void BsolLvSetItem (LVITEM lvItm_p);
			DLL_BSOLCTRL void BsolLvSetClass (BsolClass * class_p);
//			DLL_BSOLCTRL void BsolLvSetPrntWnd (HWND wnd_p);
			DLL_BSOLCTRL void BsolLvSetNumCol(int num_p);

			DLL_BSOLCTRL long BsolLvInitColumns ();
			DLL_BSOLCTRL long BsolLvInitItems ();

			DLL_BSOLCTRL static WNDPROC	BsolGetLvWndProc ();
			DLL_BSOLCTRL static long BsolListViewProcedure (HWND hWnd_p, UINT msg_p, WPARAM wParam_p, LPARAM lParam_p);
	};
}
#endif // _BSOLLISTVIEW_H_INCLUDED_ 


The cpp file is below:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#include "BsolListView.h"

//Globale Variables:
WNDPROC lvOriginWndProc_g;

// Old globale variable already defined in other file
extern BsolEventHandler * lvEventHandler_g;
extern const int maxMsgNum_g;

namespace BsolControls {
	BsolListView::BsolListView (BsolClass * class_p) {
		this->LvClass.BsolSetClass (class_p->ctrlName, class_p->ctrlId, class_p->ctrlText, 
									class_p->X, class_p->Y, class_p->width, class_p->hight, 
									class_p->ctrlLTR, class_p->ctrlStyle, class_p->rowNum, 
									class_p->extra1, class_p->extra2, class_p->extra3);
		this->LvWnd = NULL;
		this->LvNumCol = class_p->extra1;
	}

	HWND BsolListView::BsolLvCreate (BsolWindow * prntWnd_p) {
		DWORD style_v, styleEx_v;
		int X_v, Y_v, W_v, H_v, ctrlId_v;

		X_v = this->LvClass.X;
		Y_v = this->LvClass.Y;
		W_v = this->LvClass.width;
		H_v = this->LvClass.hight;
		ctrlId_v = this->LvClass.ctrlId;

		styleEx_v = LVS_EX_FULLROWSELECT;
		style_v = WS_CHILD | //WS_SIZEBOX | //WS_SYSMENU | 
//				  WS_BORDER | WS_CAPTION | 
				  LVS_OWNERDATA | LVS_EDITLABELS | LVS_REPORT;// | LVS_EX_GRIDLINES;

		this->LvWnd = CreateWindowEx(styleEx_v, WC_LISTVIEW, TEXT("List Of Values"),
									 style_v, X_v, Y_v, W_v, H_v, 
									 prntWnd_p->BsolGetWndHandle(), 
									 (HMENU)ctrlId_v, prntWnd_p->BsolGetInstance(), NULL);

		lvOriginWndProc_g = (WNDPROC)BsolMSDN_SetWindowLong (this->LvWnd, GWL_WNDPROC, 
															 (long)BsolListViewProcedure, 
															 TEXT("BsolListView:SetWindowLong"));

	INITCOMMONCONTROLSEX icex;
	
	icex.dwSize = sizeof(INITCOMMONCONTROLSEX);
	icex.dwICC = ICC_STANDARD_CLASSES | ICC_COOL_CLASSES | ICC_LISTVIEW_CLASSES;

		// Initialize ListView Columns
		this->BsolLvInitColumns();

		// Initialize ListView Items
		this->BsolLvInitItems();

		ShowWindow (this->LvWnd, SW_SHOW);

		return this->LvWnd;
	}

	// Initialize Columns of List View
	long BsolListView::BsolLvInitColumns () {
		WCHAR szText[256];     // Temporary buffer.
		int iCol;

		// Initialize the LVCOLUMN structure.
		// The mask specifies that the format, width, text,
		// and subitem members of the structure are valid.
		this->LvColumn.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;

		// Add the columns.
		for (iCol = 0; iCol < this->LvNumCol; iCol++) {
			this->LvColumn.iSubItem = iCol;
			this->LvColumn.pszText = szText;
			this->LvColumn.cx = 100;               // Width of column in pixels.

			if ( iCol < 2 )
				this->LvColumn.fmt = LVCFMT_LEFT;  // Left-aligned column.
			else
				this->LvColumn.fmt = LVCFMT_RIGHT; // Right-aligned column.

			// Load the names of the column headings from the string resources.
			LoadString(NULL, //eArgs_p->ehIns,
					   2650 + iCol,
					   szText,
					   sizeof(szText)/sizeof(szText[0]));

			// Insert the columns into the list view.
			if (ListView_InsertColumn(this->LvWnd, iCol, &this->LvColumn) == -1)
				return FALSE;
		}

		return 1;
	}

	// Inserting Items into List View
	long BsolListView::BsolLvInitItems () {
		int index = -1;
		
		// Initialize LVITEM members that are common to all items.
		this->LvItem.pszText   = 0;// LPSTR_TEXTCALLBACK; // Sends an LVN_GETDISPINFO message.
		this->LvItem.mask      = LVIF_TEXT | LVIF_IMAGE |LVIF_STATE;
		this->LvItem.stateMask = 0;
		this->LvItem.iSubItem  = 0;
		this->LvItem.state     = 0;

		// Initialize LVITEM members that are different for each item.
		for (int i = 0; i < 2; i++) {
			this->LvItem.iItem  = i;
			this->LvItem.iImage = i;

			// Insert items into the list.
			index = ListView_InsertItem(this->LvWnd, &this->LvItem);

			if (index == -1) 
				return FALSE;
		}
		return index;
	}

	. . .

	long BsolListView::BsolListViewProcedure (HWND hWnd_p, UINT msg_p, WPARAM wParam_p, LPARAM lParam_p) {
		char * msgStr_v;
		BsolEventHandler::BsolEventArgs eArgs_v;

		msgStr_v = BsolPrintWindowMessages (msg_p, "---------- BsolListView");

		for (int i = 0; i < maxMsgNum_g; i++) {
			if (lvEventHandler_g->eHandler[i].mCode == msg_p) {
				eArgs_v.ehWnd = hWnd_p;
				eArgs_v.eMsg = msg_p;
				eArgs_v.ewParam = wParam_p;
				eArgs_v.elParam = lParam_p;

				lvEventHandler_g->eHandler[i].functionPtr(&eArgs_v);
				break;
			}
		}

		return CallWindowProc (lvOriginWndProc_g, hWnd_p, msg_p, wParam_p, lParam_p);
	}
}


Hope the posted code would help.

Regards,
Below is handling of ON_NOTIFY msg in the parent window of the List View:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
long BsolFrmOnNotify (BsolEventHandler::BsolEventArgs * eArgs_p) {
	LPWSTR rgLOV_v[4][3];

	switch (((LPNMHDR) eArgs_p->elParam)->code) {
		NMLVDISPINFO * plvdi;

		rgLOV_v[0][0] = TEXT("AAAA");  rgLOV_v[0][1] = TEXT("M"); rgLOV_v[0][2] = TEXT("32");
		rgLOV_v[1][0] = TEXT("BBBB"); rgLOV_v[1][1] = TEXT("F"); rgLOV_v[1][2] = TEXT("31");
		rgLOV_v[2][0] = TEXT("ZZZZ"); rgLOV_v[2][1] = TEXT("F"); rgLOV_v[2][2] = TEXT("23");
		rgLOV_v[3][0] = TEXT("LLLL");   rgLOV_v[3][1] = TEXT("M"); rgLOV_v[3][2] = TEXT("22");

		case LVN_GETDISPINFO:

			plvdi = (NMLVDISPINFO*)eArgs_p->elParam;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            			plvdi->item.pszText = rgLOV_v[plvdi->item.iItem][plvdi->item.iSubItem];
			switch (plvdi->item.iSubItem) {
				case 0:
					plvdi->item.pszText = rgLOV_v[plvdi->item.iItem][0];
					break;

				case 1:
					plvdi->item.pszText = rgLOV_v[plvdi->item.iItem][1];
					break;

				case 2:
					plvdi->item.pszText = rgLOV_v[plvdi->item.iItem][2];
					break;

				default:
					break;
			}
			break;
		default://			plvdi = (NMLVDISPINFO*)eArgs_p->elParam;
			return BsolFrmOnDefaultMsg (eArgs_p);
	}
	return 0;
}


Regards,
Tath, Thanks for you update.

However, I checked if this->LvWnd and &this->LvItem, they are not empty.
Furthermore, the application is creating and showing the Listview properly (I am able to see the list view before the application crashes), but, upon displaying its items, it is crashing and giving the above mentioned access violation.
Andy, thanks for your very helpfull update. I had loaded the symbols and here we go the new Call Stack flow while debugging the application:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
->	comctl32.dll!CMarkup::GetLinkRect()  - 0xbfb78 bytes	
 	comctl32.dll!StringCchCopyW()  + 0x2c bytes	
 	comctl32.dll!_CCReturnDispInfoText@12()  + 0x8a4a0 bytes	
 	comctl32.dll!CLVItemStore::OnGetItem()  + 0x21d bytes	
 	comctl32.dll!CLVView::v_RecomputeLabelSize()  + 0xaf bytes	
 	comctl32.dll!CLVReportView::_GetCXLabel()  + 0x349 bytes	
 	comctl32.dll!CLVReportView::GetRects()  + 0x3b04b bytes	
 	comctl32.dll!CLVReportView::v_DrawItem()  + 0x61 bytes	
 	comctl32.dll!CLVDrawItemManager::DrawItem()  + 0x1c6 bytes	
 	comctl32.dll!CLVDrawManager::_PaintItems()  + 0x81b bytes	
 	comctl32.dll!CLVDrawManager::_PaintWorkArea()  + 0xa7 bytes	
 	comctl32.dll!CLVDrawManager::_OnPaintWorkAreas()  + 0x52 bytes	
 	comctl32.dll!CLVDrawManager::_OnPaint()  + 0x90 bytes	
 	comctl32.dll!CLVDrawManager::OnPaint()  + 0x5d bytes	
 	comctl32.dll!CListView::WndProc()  - 0x81d4 bytes	
 	comctl32.dll!CListView::s_WndProc()  + 0x38 bytes	
 	user32.dll!_InternalCallWinProc@20()  + 0x23 bytes	
 	user32.dll!_UserCallWinProcCheckWow@32()  + 0xb3 bytes	
 	user32.dll!_CallWindowProcAorW@24()  + 0x51 bytes	
 	user32.dll!_CallWindowProcW@20()  + 0x1b bytes	
 	BsolControls.dll!BsolControls::BsolListView::BsolListViewProcedure(HWND__ * hWnd_p=0x00050416, unsigned int msg_p=15, unsigned int wParam_p=0, long lParam_p=0)  Line 224 + 0x1f bytes	C++
 	user32.dll!_InternalCallWinProc@20()  + 0x23 bytes	
 	user32.dll!_UserCallWinProcCheckWow@32()  - 0x6595 bytes	
 	user32.dll!_DispatchClientMessage@20()  + 0x4b bytes	
 	user32.dll!___fnDWORD@4()  + 0x24 bytes	
 	ntdll.dll!_KiUserCallbackDispatcher@12()  + 0x2e bytes	
 	user32.dll!_DispatchClientMessage@20() 	
 	user32.dll!_NtUserDispatchMessage@4()  + 0xc bytes	
 	user32.dll!_DispatchMessageWorker@8()  - 0x6e00 bytes	
 	user32.dll!_DispatchMessageW@4()  + 0xf bytes	
 	BSolutionsApps.exe!WinMain(HINSTANCE__ * hInst_p=0x01250000, HINSTANCE__ * hPrevInstance_p=0x00000000, char * lpCmdLine_p=0x003f3fe8, int nCmdShow_p=1)  Line 80 + 0xc bytes	C++
 	BSolutionsApps.exe!__tmainCRTStartup()  Line 578 + 0x35 bytes	C
 	BSolutionsApps.exe!WinMainCRTStartup()  Line 403	C
 	kernel32.dll!@BaseThreadInitThunk@12()  + 0x12 bytes	
 	ntdll.dll!___RtlUserThreadStart@8()  + 0x27 bytes	
 	ntdll.dll!__RtlUserThreadStart@8()  + 0x1b bytes	


Hope this would help.
Regards,
Thanks all for you updates especially for Andy.

Andy, when I enabled the symbols, it showed me that the problem in some how in the labels of the item. So I checked the value of the array holding the label text, it appeared to be empty.

Now the problem is solved. All what did is modifying the code in OnNotify function. I initialized the array holding the item text outside the switch instead of initializing it inside the switch (check the original code posted above).
Below is the code of function handling OnNotify msgs after adjustment:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
long BsolFrmOnNotify (BsolEventHandler::BsolEventArgs * eArgs_p) {
	LPWSTR rgLOV_v[5][3];
		rgLOV_v[0][0] = L"AAAA";  rgLOV_v[0][1] = TEXT("M"); rgLOV_v[0][2] = TEXT("32");
		rgLOV_v[1][0] = TEXT("BBBB"); rgLOV_v[1][1] = TEXT("F"); rgLOV_v[1][2] = TEXT("31");
		rgLOV_v[2][0] = TEXT("ZZZZ"); rgLOV_v[2][1] = TEXT("F"); rgLOV_v[2][2] = TEXT("22");
		rgLOV_v[3][0] = TEXT("LLLL");   rgLOV_v[3][1] = TEXT("F"); rgLOV_v[3][2] = TEXT("21");

	switch (((LPNMHDR) eArgs_p->elParam)->code) {
		NMLVDISPINFO * plvdi;

		case LVN_GETDISPINFO:

			plvdi = (NMLVDISPINFO*)eArgs_p->elParam;
//plvdi->item.pszText = rgLOV_v[plvdi->item.iItem][plvdi->item.iSubItem];
			switch (plvdi->item.iSubItem) {
				case 0:
					plvdi->item.pszText = rgLOV_v[plvdi->item.iItem][0];
					break;

				case 1:
					plvdi->item.pszText = rgLOV_v[plvdi->item.iItem][1];
					break;

				case 2:
					plvdi->item.pszText = rgLOV_v[plvdi->item.iItem][2];
					break;

				default:
					break;
			}
			break;
		default://			plvdi = (NMLVDISPINFO*)eArgs_p->elParam;
			return BsolFrmOnDefaultMsg (eArgs_p);
	}
	return 0;
}


Although it is weird, but it is work.

I would appreciate if any one can justify and/or clarify what is the problem in initializing the array inside the switch.

Regards,
If does.

Before I was distracted by the noise and hadn't really looked at your code in any detail. But now it's sunk in that you're using a virtual list (I can see you're using the LVS_OWNERDATA style and processing the LVN_GETDISPINFO notification.)

With a virtual list view, you do not add actual items to the list. You just tell the control how many pretend lines (virtual lines) you have (using ListView_SetItemCountEx) and then it calls you back when it needs the data.

You should also check that BsolFrmOnNotify is safe when it's called with invalid row and column indices. (Esp. line 15 of the BsolFrmOnNotify fragment, which is way, way off screen.)

But do you want to use a virtual list view? Or not??

Andy

PS I don't see why you have the LVCOLUMN or LVITEM class members. Wouldn't these be better as local variable??

Virtual ListView via API
http://bcbcaq.freeservers.com/virtual_listview.html

Displaying the dictionary, part 3: Using an owner-data listview
http://blogs.msdn.com/b/oldnewthing/archive/2005/06/15/429338.aspx

Displaying the dictionary, part 2: Using text callbacks
http://blogs.msdn.com/b/oldnewthing/archive/2005/06/14/428892.aspx

Displaying the dictionary, part 1: Naive version
http://blogs.msdn.com/b/oldnewthing/archive/2005/06/13/428534.aspx
Last edited on
Andy,

Thanks for your update..

Regarding my code, I was initially now using owner-data listview and was just trying to have the listview working. But now since it already worked (don't know what and where was the error), so I will move now to use owner-data listview and will be checking those links in order to have it implemented properly.

Regarding the LVCOLUMN and LVITEM, I defined them as class members since I don't know if I would need to reference them while adding some user customization. I am still somehow new in windows programming and I am discovering things while coding the template of my application.

Thanks again..
Ahmad
Topic archived. No new replies allowed.