I made one of these threads a few months ago, but I never solved this problem because I was offered a work-around that was a better choice at the time. But now I'm back to this problem. And although there might be a way to work-around this one, I really don't want. I really want to get this right, because it'll come in so useful. I have a custom CSortListCtrl class that derives from CMFCListCtrl and a custom CSortHeaderCtrl class that derives from CMFCHeaderCtrl. I want to replace the header control in the list control with my custom header control, but can't seem to get it right. So far, this is the code I have in the custom list control.
I've also tried having i_header as a pointer and creating it right before subclassing, and that didn't work either. I also tried overriding the GetHeaderCtrl() function to return my header ctrl, but that gives me a runtime exception that causes the program to crash. I've also tried using this line which I found online, but same error.
Code:
i_header.SubclassDlgItem(0, this);
I feel like I've ready every tutorial on the internet and can't get it right. What am I missing?
EDIT: I should mention that the code I posted compiles, but doesn't actually subclass, as my override functions aren't called.
The window must not already be attached to an MFC object when this function is called.
Given that you call GetSafeHwnd() to get the window handle, the window is already attached to a CWnd instance. Try detaching the window first in combination with overriding the GetHeaderCtrl function.
Cheers, D Drmmr
Please put [code][/code] tags around your code to preserve indentation and make it more readable.
As long as man ascribes to himself what is merely a posibility, he will not work for the attainment of it. - P. D. Ouspensky
I tried detaching the header control in various ways and that didn't work.
VictorN, that is the exact code I'm using, but it doesn't seem to work. It runs, but my custom header control functions aren't being called. Maybe it's with my override?
SortHeaderCtrl.cpp
Code:
#include "stdafx.h"
#include "Scrip Pro.h"
#include "SortHeaderCtrl.h"
BEGIN_MESSAGE_MAP(CSortHeaderCtrl, CMFCHeaderCtrl)
END_MESSAGE_MAP()
IMPLEMENT_DYNAMIC(CSortHeaderCtrl, CMFCHeaderCtrl)
/// <summary>
/// Default constructor.
/// </summary>
CSortHeaderCtrl::CSortHeaderCtrl()
{
}
/// <summary>
/// Default destructor.
/// </summary>
CSortHeaderCtrl::~CSortHeaderCtrl()
{
}
/// <summary>
/// Called by the framework to draw the sorting arrow for the column.
/// </summary>
/// <param name="pDC">Device context to draw to</param>
/// <param name="rectArrow">Size of the arrow</param>
void CSortHeaderCtrl::OnDrawSortArrow( CDC* pDC, CRect rectArrow )
{
pDC->FillSolidRect(rectArrow, RGB(255,255,255));
}
SortHeaderCtrl.h
Code:
#pragma once
class CSortHeaderCtrl : public CMFCHeaderCtrl
{
DECLARE_DYNAMIC(CSortHeaderCtrl)
public:
CSortHeaderCtrl();
virtual ~CSortHeaderCtrl();
protected:
DECLARE_MESSAGE_MAP()
virtual void OnDrawSortArrow(CDC* pDC, CRect rectArrow);
};
If I set a breakpoint in the OnDrawSortArrow function, it never gets hit. The only thing I'm thinking it could be is that I'm using CMFCListctrl not CListCtrl. But I really need to use CMFCListCtrl. Also, the latter is the parent class of the former, so how could that cause so many issues?
i don't know.
Could you prepare a small test project reproducing such a behavior and post it to Forum?
Yeah, I was actually experimenting with a test project the other day. I added the subclassing (still doesn't work) and uploaded it. There's a lot of files in the project, but the only classes that should be of consideration are CChildFrame, CListCtrlEx and CHeaderCtrlEx.
I developed this in VS2008 under Windows 7.
I'm still trying to search on window subclassing, but I'm coming up with nothing. It's quite frustrating. :/
PS. I know the file is named as a .zip file, but it's actually a .7z file. I had to rename because the forum wouldn't accept .7z files and the actual .zip was too big. So just rename it to .7z.
If you want to subclass the header control in your own CMFCHeaderCtrl-derived class (let's say it CMyMFCHeaderCtrl), all you have to do is:
In the class derived from CMFCListCtrl (CMyMFCListCtrl), add a member of type CMyMFCHeaderCtrl, let's say it m_headerCtrl; this will replace CMFCListCtrl::m_wndHeader.
Override CMFCListCtrl::GetHeaderCtrl and return m_headerCtrl.
Override CMFCListCtrl::InitHeader to subclass the header control.
My friend, you are a life saver. Worked like a charm. I can't believe that this didn't show up in any of my 100+ searches. :/ Oh well, at least it's now documented for people in the future.
Thank you to everybody for your help, I appreciate it.
* The Best Reasons to Target Windows 8
Learn some of the best reasons why you should seriously consider bringing your Android mobile development expertise to bear on the Windows 8 platform.