Solved

Changing the title of a CListCtrl column at run-time

Posted on 2000-04-10
14
1,091 Views
Last Modified: 2013-11-20
I have to change the title for a column in a CListCtrl control at run-time. I try to use CListCtrl::GetColumn(…) and CListCtrl::SetColumn(…). Although I followed the code shown for CListCtrl::GetColumn in MSDN (slightly modified), my app keeps crashing somewhere inside GetColumn (the error is an unhandled exception in my_app.exe – COMCTL32.DLL – Access violation).
The code I’m using looks like:

CListCtrl *pListCtrl = (CListCtrl *) GetDlgItem(IDC_MY_LIST_CONTROL);

LVCOLUMN col;
CString strTemp = _T("");
_TCHAR buffer[100];  // 100 chars enough space for the column title
col.pszText = buffer;
col.mask = LVCF_TEXT;

// get first column's attributes
pListCtrl->GetColumn(0, &col);   // MY APP CRASHES INSIDE THIS FUNCTION

// load new string value
strTemp.LoadString( IDS_NEW_TITLE_FOR_THE_COLUMN );

// copy the strings
_tcscpy( col.pszText, LPCTSTR(strTemp) );

// set back the column's attributes
pListCtrl->SetColumn(0, &col);


Does anybody have any clue?
 
0
Comment
Question by:Mensana
  • 5
  • 3
  • 2
  • +3
14 Comments
 

Expert Comment

by:bertp
ID: 2702167
My guess is that the GetDlgItem  call isr returning a CWnd* to CWnd object .. (and not a CWnd* to a  CListCtrl as your code suggests)

I would create a CListCtrl object
and attach the window handle of a window you know to be valid for this type of object

Probably something like this will work


CWmd *pTemp = GetDlgItem(IDC_MY_LIST_CONTROL);

CListCtrl MyList;
MyList.Attach(pTemp->m_hWnd);
 

LVCOLUMN col;
CString strTemp = _T("");
_TCHAR buffer[100];  // 100 chars enough space for the column title
col.pszText = buffer;
col.mask = LVCF_TEXT;

// get first column's attributes
MyList.GetColumn(0, &col);    

// load new string value
strTemp.LoadString( IDS_NEW_TITLE_FOR_THE_COLUMN );

// copy the strings
_tcscpy( col.pszText, LPCTSTR(strTemp) );

// set back the column's attributes
MyList.SetColumn(0, &col);
MyList.Detach();

 


 

 
0
 

Expert Comment

by:bertp
ID: 2702219
Just checked my copy of "Programming Windows with MFC, second edition" by Jeff Prosise and he discusses this matter a bit on page 403

HTH, Good Luck!
Bert
0
 
LVL 1

Author Comment

by:Mensana
ID: 2702241
For bertp:

There is nothing wrong with GetDlgItem. I know, plenty of people solving problems on this site are not that happy with GetDlgItem. But belive me, I never had any special problem with it. For example this is the code that I use to create three columns and to assign titles to each column:

// create the header for this list control
CListCtrl *pListCtrl = (CListCtrl *) GetDlgItem(IDC_MY_LIST_CONTROL);
CString strTemp = _T("");  // used to set the caption for the columns

strTemp.LoadString( IDS_FIRST_COLUMN_TITLE );
ListCtrl -> InsertColumn(0, strTemp, LVCFMT_LEFT, 100);
strTemp.LoadString( IDS_SECOND_COLUMN_TITLE );
pListCtrl -> InsertColumn(1, strTemp, LVCFMT_RIGHT, 100);
strTemp.LoadString( IDS_THIRD_COLUMN_TITLE );
pListCtrl -> InsertColumn(2, strTemp, LVCFMT_RIGHT, 100);

Just for your satisfaction, I tried a different approach, which is similar to what you suggest me to do (that happened before I posted the problem):

I’ve declared a CListCtrl protected member in my class:

class CMyDlg : public CDialog
{
// …
protected:
CListCtrl _lstControl;
// …
};

then the OnInitDialog looked something like:

BOOL CMyDlg::OnInitDialog()
{
   CDialog::OnInitDialog();

   // …

   _lstControl.SubclassDlgItem( IDC_MY_LIST_CONTROL, this );

   // …

   return TRUE;  // return TRUE  unless you set the focus to a control
}

Later I’ve tried to get and set back all the column attributes using the _lstControl variable. It wouldn’t work either. CWnd::SubclassDlgItem does exactly the same thing as CWnd::Attach (there are minor differences). But, I think, the problem is somewhere else.

Thank you, anyway.
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 1

Author Comment

by:Mensana
ID: 2702243
For bertp:

There is nothing wrong with GetDlgItem. I know, plenty of people solving problems on this site are not that happy with GetDlgItem. But belive me, I never had any special problem with it. For example this is the code that I use to create three columns and to assign titles to each column:

// create the header for this list control
CListCtrl *pListCtrl = (CListCtrl *) GetDlgItem(IDC_MY_LIST_CONTROL);
CString strTemp = _T("");  // used to set the caption for the columns

strTemp.LoadString( IDS_FIRST_COLUMN_TITLE );
ListCtrl -> InsertColumn(0, strTemp, LVCFMT_LEFT, 100);
strTemp.LoadString( IDS_SECOND_COLUMN_TITLE );
pListCtrl -> InsertColumn(1, strTemp, LVCFMT_RIGHT, 100);
strTemp.LoadString( IDS_THIRD_COLUMN_TITLE );
pListCtrl -> InsertColumn(2, strTemp, LVCFMT_RIGHT, 100);

Just for your satisfaction, I tried a different approach, which is similar to what you suggest me to do (that happened before I posted the problem):

I’ve declared a CListCtrl protected member in my class:

class CMyDlg : public CDialog
{
// …
protected:
CListCtrl _lstControl;
// …
};

then the OnInitDialog looked something like:

BOOL CMyDlg::OnInitDialog()
{
   CDialog::OnInitDialog();

   // …

   _lstControl.SubclassDlgItem( IDC_MY_LIST_CONTROL, this );

   // …

   return TRUE;  // return TRUE  unless you set the focus to a control
}

Later I’ve tried to get and set back all the column attributes using the _lstControl variable. It wouldn’t work either. CWnd::SubclassDlgItem does exactly the same thing as CWnd::Attach (there are minor differences). But, I think, the problem is somewhere else.

Thank you, anyway.
0
 
LVL 1

Author Comment

by:Mensana
ID: 2702250
For bertp:

There is nothing wrong with GetDlgItem. I know, plenty of people solving problems on this site are not that happy with GetDlgItem. But belive me, I never had any special problem with it. For example this is the code that I use to create three columns and to assign titles to each column:

// create the header for this list control
CListCtrl *pListCtrl = (CListCtrl *) GetDlgItem(IDC_MY_LIST_CONTROL);
CString strTemp = _T("");  // used to set the caption for the columns

strTemp.LoadString( IDS_FIRST_COLUMN_TITLE );
ListCtrl -> InsertColumn(0, strTemp, LVCFMT_LEFT, 100);
strTemp.LoadString( IDS_SECOND_COLUMN_TITLE );
pListCtrl -> InsertColumn(1, strTemp, LVCFMT_RIGHT, 100);
strTemp.LoadString( IDS_THIRD_COLUMN_TITLE );
pListCtrl -> InsertColumn(2, strTemp, LVCFMT_RIGHT, 100);

Just for your satisfaction, I tried a different approach, which is similar to what you suggest me to do (that happened before I posted the problem):

I’ve declared a CListCtrl protected member in my class:

class CMyDlg : public CDialog
{
// …
protected:
CListCtrl _lstControl;
// …
};

then the OnInitDialog looked something like:

BOOL CMyDlg::OnInitDialog()
{
   CDialog::OnInitDialog();

   // …

   _lstControl.SubclassDlgItem( IDC_MY_LIST_CONTROL, this );

   // …

   return TRUE;  // return TRUE  unless you set the focus to a control
}

Later I’ve tried to get and set back all the column attributes using the _lstControl variable. It wouldn’t work either. CWnd::SubclassDlgItem does exactly the same thing as CWnd::Attach (there are minor differences). But, I think, the problem is somewhere else.

Thank you, anyway.
0
 
LVL 1

Author Comment

by:Mensana
ID: 2702256
I don’t know what the heck happened. I posted the same comment three times!?! Sorry…
0
 

Expert Comment

by:bertp
ID: 2702294
Too bad that wasn't it!  I haven't used a CListCtrl before but your code seems pretty straightforward. Sorry but I can't think of anything else to suggest

 Be careful with GetDlgItem() anyway... That dog will sometimes bite ya ;-)

Good Luck!
Bert
0
 
LVL 2

Accepted Solution

by:
paulburns earned 100 total points
ID: 2702338
LVCOLUMN col;
_TCHAR buffer[100];  // 100 chars enough space for the column title
col.pszText = buffer;

// ADD THIS >>>>>>>>>>>>
col.cchTextMax = 100;
// ADD THIS <<<<<<<<<<<<

col.mask = LVCF_TEXT;

// get first column's attributes
pListCtrl->GetColumn(0, &col);   // MY APP CRASHES INSIDE THIS FUNCTION

0
 
LVL 11

Expert Comment

by:mikeblas
ID: 2702406
The problem is that you're not setting cchTextMax in your LVCOLUMN structure.

..B ekiM
0
 
LVL 8

Expert Comment

by:VinExpert
ID: 2702740
Hi,

Try this code

CListCtrl *list = (CListCtrl *)GetDlgItem(IDC_LIST1);
      CHeaderCtrl* pHeader = (CHeaderCtrl*)list->GetDlgItem(0);
      
      HDITEM hi;
      hi.pszText = "Hello";
      hi.cchTextMax = 5;
      hi.mask = HDI_TEXT;
      pHeader->SetItem(0, &hi); //Change first column
      pHeader->SetItem(1, &hi);//Change 2nd column

I think, that will solve Ur problem.

VinExpert
0
 
LVL 3

Expert Comment

by:V_Bapat
ID: 2703260
I tried the code you posted initially. I did not find any problem with it. It is working without setting cchTextMax also. I am changing the text on click of a button.
BTW, where is this code present? I mean where are you trying to change the text?

Vicky
0
 
LVL 11

Expert Comment

by:mikeblas
ID: 2704030
V_Bapat> It is working without setting cchTextMax also.

You're lucky.  cchTextMax is uninitialized. For you, it's luckily containing some useful value.

..B ekiM
0
 
LVL 1

Author Comment

by:Mensana
ID: 2704562
Sorry guys, my company had a “little” problem with the Internet Proxy Server and I couldn’t see what your responses were. Now am back on-line.
paulburns and mikeblas were right. As soon as I set the cchTextMax member of LVCOLUMN structure everything started magically to work. Because paulburns gave the solution first, the points will go to him.
For V_Bapat: I created a small project were I tried to test the same thing. It worked there and it crashed only when I tried to debug the code (you know, I tried to see what’s inside LVCOLUMN structure).
mikeblas is right: sometimes the uninitialized member cchTextMax has a value that is useful.
Thank you all for your time.
0
 
LVL 3

Expert Comment

by:V_Bapat
ID: 2708165
Yeah. I think Mike is right.
0

Featured Post

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
bobThere java chalenge 45 95
how to monitor remote shell execution on linux 9 106
Doc'in system (example?) BA 7 120
EvenOdd challenge 10 144
In this article, I'll describe -- and show pictures of -- some of the significant additions that have been made available to programmers in the MFC Feature Pack for Visual C++ 2008.  These same feature are in the MFC libraries that come with Visual …
If you use Adobe Reader X it is possible you can't open OLE PDF documents in the standard. The reason is the 'save box mode' in adobe reader X. Many people think the protected Mode of adobe reader x is only to stop the write access. But this fe…
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
Finds all prime numbers in a range requested and places them in a public primes() array. I've demostrated a template size of 30 (2 * 3 * 5) but larger templates can be built such 210  (2 * 3 * 5 * 7) or 2310  (2 * 3 * 5 * 7 * 11). The larger templa…

740 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question