※本稿における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; }
コメントをかく