Print Page | Close Window

How to use CXTHeaderCtrl

Printed From: Codejock Forums
Category: Codejock Products
Forum Name: Toolkit Pro
Forum Description: Topics Related to Codejock Toolkit Pro
URL: http://forum.codejock.com/forum_posts.asp?TID=8334
Printed Date: 08 May 2024 at 10:17pm
Software Version: Web Wiz Forums 12.04 - http://www.webwizforums.com


Topic: How to use CXTHeaderCtrl
Posted By: adrien
Subject: How to use CXTHeaderCtrl
Date Posted: 07 October 2007 at 4:51pm

Hi

The documentation on CXTHeaderCtrl isn't clear, and I'm having problems.
 
Documentation doesn't show SetStyle() function, but it exists. 
 
When I create a CXTHeaderCtrl as a member of another class, then I get a blow-up when that object is deleted.
 
The themes is the main problem. 
 
It says I must call a windows API call SubclassWindow.  There is no such API. 
 
* There is a CWnd::SubclassWindow, but this is no use if I already created the control.  Why must I call this anyway? 
* Must I only call this if I derived from CXTHeaderCtrl. 
* Must I derive from CXTHeaderCtrl (and if so why????)
 
Thanks

Adrien



Replies:
Posted By: kstowell
Date Posted: 07 October 2007 at 6:00pm

Hi Adrien,

You can subclass the CXTHeaderCtrl by calling the following method:

virtual bool CXTListCtrl::SubclassHeader(bool bBoldFont = false)

Once the header is subclassed, you can then call the following method to access a pointer to the header control:

CXTFlatHeaderCtrl* CXTListCtrl::GetFlatHeaderCtrl() const

NOTE: The CXTFlatHeaderCtrl class is actually obsolete and you should use CXTHeaderCtrl instead. The CXTFlatHeaderCtrl is only provided for backward compatibility with older versions.

The reason why the header control is not automatically instanciated when the CXTListCtrl object is created, is because there may be some cases where a user does not want to use the CXTHeaderCtrl.

Also, it is not necessary to derive a class from CXTHeaderCtrl in order to use it, however you can. You can also instanciate the CXTHeaderCtrl separately from the CXTListCtrl. The "ListCtrl" sample under the "Controls" section demonstrates this. Take a look at the "ListCtrlDlg.cpp" file, you will see the following code:

// Get the windows handle to the header control for the
// list control then subclass the control.
HWND hWndHeader = m_listCtrl.GetDlgItem(0)->GetSafeHwnd();
m_header.SubclassWindow(hWndHeader);
// add bitmap images.
m_header.SetBitmap(0, IDB_COLUMN_0, FALSE, RGB(0,255,0));
m_header.SetBitmap(1, IDB_COLUMN_1, FALSE, RGB(0,255,0));
m_header.SetBitmap(2, IDB_COLUMN_2, FALSE, RGB(0,255,0));
// enable auto sizing.
m_header.EnableAutoSize(TRUE);
m_header.ResizeColumnsToFit();

Hope this helps,



-------------
Kirk Stowell, President and CEO
CODEJOCK SOFTWARE SOLUTIONS<


Posted By: adrien
Date Posted: 07 October 2007 at 8:13pm
Thanks for that info.
 
I'm getting a few crashes though.  When the app exits I get an assert
 
 ASSERT(m_factoryList.m_pHead == 0);
in XTThemeManager.cpp(325)
 
and then an access violation exception in
 
AFXTLS.CPP(52) from CSimpleList::Remove() which has come from CXTThemeManagerStyleFactory::~CXTThemeManagerStyleFactory() call to m_hostList.RemoveAll(); 
 
m_hostList.m_pHead are NULL in this case.
 
but in CSimpleList::Remove, m_pHead is 0xfeeefeee (deleted memory) which is being dereferenced (in GetNextPtr)
 


Posted By: adrien
Date Posted: 07 October 2007 at 8:20pm
PS, I'm not using this in a list control.  It's just a header control for a custom control I've written.
 
Code for CXTListBase::SubclassHeader doesn't help either
 
bool CXTListBase::SubclassHeader(bool bBoldFont/*= false*/)
{
 // if we are not in report mode return false.
 if ((GetWindowLong(m_pListCtrl->m_hWnd, GWL_STYLE) & LVS_TYPEMASK) != LVS_REPORT)
  return false;
 // header was already subclassed!
 if (::IsWindow(m_flatHeader.GetSafeHwnd()))
  return false;
 // Get the windows handle to the header control for the
 // list control then subclass the control.
 HWND hWndHeader = _xtGetHeaderCtrl()->GetSafeHwnd();
 if (!m_flatHeader.SubclassWindow (hWndHeader))
  return false;
 // finish header initialization.
 m_flatHeader.InitializeHeader(bBoldFont);
 return true;
}
All it's doing is calling CWnd::SubclassHeader, but only if the control already hasn't been created.  So how do we just use a CXTHeaderCtrl?  It seems what you need to do is.
 
1. Create some other control (not CXTHeaderCtrl).
2. Subclass it to be a CXTHeaderCtrl by having another object of type CXTHeaderCtrl say m_Header, and calling m_Header.SubclassWindow(hWndOfOtherCtrl)
 
my code is:
 
 m_Header.Create(HDS_HOTTRACK | HDS_HORZ | CCS_TOP | WS_CHILD | WS_VISIBLE, CRect(0,0,0,0), this, 1);
 m_Header.InitializeHeader(FALSE);
 m_Header.SetTheme(new CXTHeaderCtrlThemeOffice2003());
 
 HDITEM item;
...
 m_Header.InsertItem(0, &item);
 
 
 


Posted By: kstowell
Date Posted: 08 October 2007 at 10:52am
Originally posted by adrien adrien wrote:

PS, I'm not using this in a list control.  It's just a header control for a custom control I've written.
 
This is could be the problem. The CXTHeaderCtrl was created as a companion to CXTListCtrl and CXTListView class, and most likely will not work when subclassed for other controls.
 
Instead of subclassing the header by calling CWnd::SubclassWindow(HWND) have you tried to create the header and position it manually? You may have better results.
 
if (!m_header.Create([args]))
    return FALSE;
 
then:
 
m_header.SetWindowPos([args]);
 
Regards,


-------------
Kirk Stowell, President and CEO
CODEJOCK SOFTWARE SOLUTIONS<


Posted By: adrien
Date Posted: 08 October 2007 at 3:10pm
Hi
 
yes,that's what I ended up doing.
 
It's just that the code blows up when the app exits.  I think there's a bug somewhere in the CJ framework which isn't removing style factories when things using them are destroyed.
 
At the moment to stop it crashing (it still asserts though, which is really annoying) I had to new the instance of the CXTHeaderCtrl and not delete it (so leak).
 
Since it derives from CHeaderCtrl, it should be usable like CHeaderCtrl, which works fine in this case (just no styles).


Posted By: kstowell
Date Posted: 08 October 2007 at 3:52pm
If you can send me a sample app, I can debug it and try to provide a more stable solution for you. You can send it to mailto:support@codejock.com - support@codejock.com if you like, just put it to my attention.
 
Cheers,


-------------
Kirk Stowell, President and CEO
CODEJOCK SOFTWARE SOLUTIONS<


Posted By: Algae
Date Posted: 14 March 2008 at 1:48pm
I've subclassed the CXTListHeader before and haven't had trouble with it.

However, if you are getting the dreaded CXTThemeManager assert:

ASSERT(m_factoryList.m_pHead == 0);

the manager is only trying to tell you that things are not cleaning up.  It's just a little obscure is all.

Usually this problem has happened to me when I created a modeless dialog and forgot to add the cleanup to it. For example we can create a dialog (assume it is themed):

void CMainFrame::OnMyModelessDlg()
{
    CMyModelessDlg*dlg = new CMyModelessDlg(AfxGetMainWnd());
    dlg->Create(CMyModelessDlg::IDD);
    dlg->ShowWindow(SW_SHOW);
}

Now, if you exit the program it will assert in CXTThemeManager! Unless we add this to the CMyModelessDlg class:

void CMyModelessDlg::PostNcDestroy()
{   
    CXTPDialog::PostNcDestroy();
    delete this;
}

That will clean things up and the assert no longer happens.






Print Page | Close Window

Forum Software by Web Wiz Forums® version 12.04 - http://www.webwizforums.com
Copyright ©2001-2021 Web Wiz Ltd. - https://www.webwiz.net