Solved

Changing the title of a CListCtrl column at run-time

Posted on 2000-04-10
14
1,059 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
Threat Intelligence Starter Resources

Integrating threat intelligence can be challenging, and not all companies are ready. These resources can help you build awareness and prepare for defense.

 
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

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Suggested Solutions

Introduction: Ownerdraw of the grid button.  A singleton class implentation and usage. Continuing from the fifth article about sudoku.   Open the project in visual studio. Go to the class view – CGridButton should be visible as a class.  R…
Introduction: Hints for the grid button.  Nested classes, templated collections.  Squash that darned bug! Continuing from the sixth article about sudoku.   Open the project in visual studio. First we will finish with the SUD_SETVALUE messa…
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.
Illustrator's Shape Builder tool will let you combine shapes visually and interactively. This video shows the Mac version, but the tool works the same way in Windows. To follow along with this video, you can draw your own shapes or download the file…

746 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

9 Experts available now in Live!

Get 1:1 Help Now