?
Solved

Changing the title of a CListCtrl column at run-time

Posted on 2000-04-10
14
Medium Priority
?
1,118 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
Moving data to the cloud? Find out if you’re ready

Before moving to the cloud, it is important to carefully define your db needs, plan for the migration & understand prod. environment. This wp explains how to define what you need from a cloud provider, plan for the migration & what putting a cloud solution into practice entails.

 
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 400 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: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering 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

Introduction: Dialogs (1) modal - maintaining the database. Continuing from the ninth article about sudoku.   You might have heard of modal and modeless dialogs.  Here with this Sudoku application will we use one of each type: a modal dialog …
In this post we will learn different types of Android Layout and some basics of an Android App.
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.
In this video you will find out how to export Office 365 mailboxes using the built in eDiscovery tool. Bear in mind that although this method might be useful in some cases, using PST files as Office 365 backup is troublesome in a long run (more on t…

719 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