※本稿におけるTree ViewはCTreeViewではなくコモンコントロールのTree Viewである.MFCではCTreeCtrlである.
CTreeCtrlはWindows APIのTree-view (http://msdn.microsoft.com/en-us/library/windows/de... の薄いラッパーである.
MFCのソースを見ると,すべての関数はインラインでTree ViewにSendMessageしているだけである.
そのため機能はTree Viewに限定される.
CTreeCtrlはWindows APIのTree-view (http://msdn.microsoft.com/en-us/library/windows/de... の薄いラッパーである.
MFCのソースを見ると,すべての関数はインラインでTree ViewにSendMessageしているだけである.
そのため機能はTree Viewに限定される.
ダイアログでCTreeCtrl上の左クリックは通知されない(ON_LBUTTON_DOWN).
WindowsAPIの中で規定の動作で処理されてしまうからである.(Expand/Collapseやチェック)
このイベントをディスパッチするために,メッセージリフレクションを用いる.
どのようなメッセージがあるかはMSDNのTree Viewのリファレンスを見ればよい.
WindowsAPIの中で規定の動作で処理されてしまうからである.(Expand/Collapseやチェック)
このイベントをディスパッチするために,メッセージリフレクションを用いる.
どのようなメッセージがあるかはMSDNのTree Viewのリファレンスを見ればよい.
#define TVN_CHKCHANGE 1
ON_NOTIFICATION_REFLECT(NM_CLICK, &CTreeCtrlSub::OnNMClk)
void CTreeCtrlSub::OnNMClk(NMHDR *pNMHDR, LRESULT *pResult)
{
NMTREEVIEW *pNMTree = (NMTREEVIEW*)pNMHDR;
TVHITTESTINFO ht = {0};
DWORD pos = ::GetMessagePos();
ht.pt.x = LOWORD(pos);
ht.pt.y = HIWORD(pos);
::MapWindowPoints(HWND_DESKTOP, pNMHDR->hwndFrom, &ht.pt, 1);
HitTest(&ht); //なお,このHitTestもMFCではなくWindows内部で処理される(SendMessageしてるだけ)
// HitTestの結果,チェックボックス上(STATEICON)であればチェック状態を変更
if (TVHT_ONITEMSTATEICON & ht.flags)
{
this->SetCheck(ht.hItem, !GetCheck(ht.hItem));
}
if (ht.hItem)
{
// 当該項目を選択状態にし,親ウィンドウにメッセージを投げる
this->SelectItem(ht.hItem);
DWORD H = DWORD(TVN_CHKCHANGE) << 16;
DWORD L = DWORD( this->GetDlgCtrlID() );
WPARAM wParam = H + L;
this->GetParent()->PostMessage(WM_COMMAND, wParam, (LPARAM)this->GetSafeHwnd());
}
// 規定の動作は行わない
*pResult = 1;
}

コメントをかく