Solved

Changing the title of a CListCtrl column at run-time

Posted on 2000-04-10
14
1,066 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
 
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
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 
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

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

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

Introduction: The undo support, implementing a stack. Continuing from the eigth article about sudoku.   We need a mechanism to keep track of the digits entered so as to implement an undo mechanism.  This should be a ‘Last In First Out’ collec…
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 …
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.
Internet Business Fax to Email Made Easy - With  eFax Corporate (http://www.enterprise.efax.com), you'll receive a dedicated online fax number, which is used the same way as a typical analog fax number. You'll receive secure faxes in your email, f…

911 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

Need Help in Real-Time?

Connect with top rated Experts

16 Experts available now in Live!

Get 1:1 Help Now