MFC TVN_ITEMEXPANDING doesn't call the handler function - mfc

I have a CTreeCtrl and I like to use its TVN_ITEMEXPANDING message, but the handler function never calls.
CsetkliensDlg.h
afx_msg void OnItemExpanding(NMHDR* pNmhdr,LRESULT *lResult);
CsetkliensDlg.cpp
BEGIN_MESSAGE_MAP(CCsetkliensDlg, CDialogEx)
ON_NOTIFY_REFLECT(TVN_ITEMEXPANDING, &CCsetkliensDlg::OnItemExpanding)
END_MESSAGE_MAP()
...
void CCsetkliensDlg::OnItemExpanding(NMHDR* pNmhdr,LRESULT *lResult)
{
AfxMessageBox("almafa");
}
The items have childs.

You are trying to catch a notification in the parent dialog so you should use ON_NOTIFY instead of ON_NOTIFY_REFLECT.
Of course then your message map will be something lik:
ON_NOTIFY( TVN_ITEMEXPANDING, CTREECTRL_RESOURCES_ID, ONHandlerFunction)
You can use the reflection mechanism but then the handler should be in a CTreeCtrl derived class.

Related

How to catch a new item selection in a class that derives CComboBox

I have a class that derives CComboBox and I want it to handle internally when the user selects another item. I know that I can catch the selection in the parent control with ON_CBN_SELCHANGE, but I want to handle the selection change within the combobox itself, so that I can use the private implementation details of my own derived combobox class to interpret the new selection.
Is this possible and how I can I do this?
In header:
afx_msg LRESULT OnSelchange();
in cpp file:
BEGIN_MESSAGE_MAP(CComboBoxExt, CComboBox)
ON_CONTROL_REFLECT_EX(CBN_SELCHANGE, OnSelchange)
END_MESSAGE_MAP()
LRESULT CComboBoxExt::OnSelchange()
{
// TODO: Add your control notification handler code here
// do your job ...
return Default();
}

I overrided WM_CLOSE, how to came out from application now

I am a new bie to windows programming, I written an applicatoin with single dialog. In that I override the CWnd::OnClose to do some stuff before exiting from application.after that I need to get out from application. But It will also be called if I post or send a message with WM_CLOSE event from overridden method, so how to get out from application now.
class MyDlg : public CDialogEx
{
public:
afx_msg void OnClose();
};
BEGIN_MESSAGE_MAP(MyDlg , CDialogEx)
ON_WM_CLOSE ()
END_MESSAGE_MAP()
void MyDlg:: OnClose()
{
//what code I should write here to exit from application.
}
after you do your stuff write this:
__super::OnClose();

WM_KILLFOCUS for a modal dialog does not work

In my application I have a standard MFC modal dialog. I'd like close that dialog when the user clicks outside the dialog window. For that purpose I put ON_MESSAGE(WM_KILLFOCUS, OnKillFocus) in the dialog's message map hy hand (the class wizard does not offer that option):
BEGIN_MESSAGE_MAP(CTestTreeCtrlDlg, CDialog)
//{{AFX_MSG_MAP(CTestTreeCtrlDlg)
ON_NOTIFY(TVN_SELCHANGED, IDC_TREE1, OnSelchangedTree)
//}}AFX_MSG_MAP
ON_MESSAGE(WM_KILLFOCUS, OnKillFocus)
END_MESSAGE_MAP()
...
void CTestTreeCtrlDlg::OnKillFocus()
{
...
}
Now if I click outside the dialog, the latter of course looses focus, but the OnKillFocus method won't get called for some reason.
Thank you patriiice !
WM_ACTIVATE does the job:
BEGIN_MESSAGE_MAP(CTestTreeCtrlDlg, CDialog)
//{{AFX_MSG_MAP(CTestTreeCtrlDlg)
ON_NOTIFY(TVN_SELCHANGED, IDC_TREE1, OnSelchangedTree)
//}}AFX_MSG_MAP
ON_WM_ACTIVATE()
END_MESSAGE_MAP()
...
void CTestTreeCtrlDlg::OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized)
{
CDialog::OnActivate(nState, pWndOther, bMinimized);
if (nState == WA_INACTIVE)
OnOK() ;
}
Quick search -> http://www.itlisting.org/5-windows/964b01901673b4b0.aspx
I am pretty sure it is a better approach to do this.

How to handle events for dynamically created objects in MFC?

I am wondering how I can handle an event for a dynamically created variable, e.g. a list control.
CListCtrl* pList = new CListCtrl();<br/>
pList->Create(...);
How can I handle the event LVN_ITEMCHANGED for pList?
OnLvnItemchangedList(NMHDR *pNMHDR, LRESULT *pResult)
{
//do stuff
}
Do I have to create an extended CListCtrl or is there some other way? I would prefer not creating a extended class.
LVN_ITEMCHANGED is sent through WM_NOTIFY message from control to its parent so you just need to add LVN_ITEMCHANGE handler function in parent's class (e.g. CMyDlg):
In header file:
class CMyDlg : public CDialog
{
...
protected:
afx_msg void OnLvnItemChanged(NMHDR *pNMHDR, LRESULT *pResult);
...
}
In source file:
BEGIN_MESSAGE_MAP(CMyDlg, CDialog)
...
ON_NOTIFY(LVN_ITEMCHANGED, IDC_LIST, &CMyDlg::OnLvnItemChanged)
...
END_MESSAGE_MAP()
...
void CMyDlg::OnLvnItemchanged(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
*pResult = 0;
... // examine *pNMLV members for item's information
}
It does not matter how CListCtrl control is created (through resource editor or dynamically), approach is the same. Just make sure you are using correct control ID in ON_NOTIFY message map entry. (ID passed to Create/CreateEx or defined in Properties in resource editor).

How to make child control handle accelerator command of parent CView

I have a CFormView, and a child CListCtrl control. I can handle
accelerator events, like Ctrl+C, Ctrl+V ... in CFormView without
problem, by defining below message handler:
ON_COMMAND(ID_EDIT_COPY, &CMyFormView::OnEditCopy)
Now I want my CListCtrl handle these commands differently. I want to
implement OnEditCopy in CListCtrl class, rather than implement logic
in the view class. How can I pass the accelerator events from CView to
child control, when CListCtrl is on focus? I tried like:
ON_CONTROL_REFLECT(ID_EDIT_COPY, &CMyListCtrl::OnEditCopy)
But it doesn't work.
Alternative you can override PreTranslateMessage() on CMyListCtrl and call TranslateAccelerator()
BOOL CMyListCtrl::PreTranslateMessage(MSG* pMsg)
{
if (m_hAccelTable)
{
if (::TranslateAccelerator(m_hWnd, m_hAccelTable, pMsg))
return(TRUE);
}
return CListCtrl::PreTranslateMessage(pMsg);
}
It requires acccess to the global accelerator-resource on the mainframe, or that you load the accelerator again. Then your CMyListCtrl will receive the WM_COMMAND messages specified in the accelerator table.
http://support.microsoft.com/kb/222829
Use same ON_COMMAND macro in CMyListCtrl.
ON_COMMAND(ID_EDIT_COPY, &CMyListCtrl::OnEditCopy)
All you have to do is overriding OnCmdMsg method.
BOOL CMyFormView::OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo)
{
if (GetFocus() == m_myListCtrl
&& m_myListCtrl->OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))
return TRUE;
return CMyFormView::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
}
(m_myListCtrl is the CMyListCtrl instance pointer.)
This make all WM_COMMAND message first handled in m_myListCtrl if its the focus window.