ツリーコントロールの右クリック – プログラミング – Home

ツリーコントロールの右クリック
 
通知
すべてクリア

[解決済] ツリーコントロールの右クリック


Nezu
 Nezu
(@Nezu)
ゲスト
結合: 17年前
投稿: 44
Topic starter  

たびたびすみませんが、お願いします。

ツリーコントロールのアイテムを右クリックしたときに、
右クリックしたアイテム名を取得したいのですが、うまくいきません。

下記のように右クリックされたアイテムが、最下層のアイテムだった場合
アイテム名を取得するようにしたいのですが、
GetItemText()で空が返ってきてしまいます。
それどころか、最下層アイテムの判別もすべて通ってしまいます。

左クリック処理にまったく同じ処理を書いてみましたが、うまくいきました。
ご存じの方、ご教授ください。

void CHogeDlg::OnNMRclickTreeCtrl(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMTREEVIEW pNMTreeView = reinterpret_cast<LPNMTREEVIEW>(pNMHDR);

// 最下層のアイテムか?
if(pNMTreeView->itemNew.cChildren != 0)
{
*pResult = 0;
return;
}

// 選択アイテム名
CString strSelect = m_TreeCtrl.GetItemText(pNMTreeView->itemNew.hItem);
}

環境 2003 MFC


引用未解決
トピックタグ
aetos
(@aetos)
Noble Member
結合: 5年前
投稿: 1480
 

http://msdn.microsoft.com/en-us/library/bb773484(VS.85).aspx
pNMHDR を LPNMTREEVIEW にキャストしても大丈夫なようには見えませんけど。

アイテムの取得には CTreeCtrl::HitTest とか使うんじゃないかな。


返信引用
ロマ
 ロマ
(@ロマ)
ゲスト
結合: 18年前
投稿: 170
 

正式にはaetosさんが書いている通り、HitTestを使うべきですが、

HTREEITEM hItem = GetNextItem(TVGN_DROPHILITE);
if(!hItem) // 選択項目を右クリックした場合は、TVGN_DROPHILITEでは取れない
  hItem = GetNextItem(TVGN_CARET);
これで、どういう訳か、うまくいきます(xp)。


返信引用
Nezu
 Nezu
(@Nezu)
ゲスト
結合: 17年前
投稿: 44
Topic starter  

返信ありがとうございます。

aetosさん、ロマさん、それぞれの方法を試してみました。

HitTestを使った場合
void CHoge::OnNMRclickTree(NMHDR *pNMHDR, LRESULT *pResult)
{
CPoint pt;
GetCursorPos(&pt);
ScreenToClient(&pt);

UINT uFlag;
HTREEITEM item = m_Tree.HitTest(pt, &uFlag);
m_Tree.SelectItem(item);

// 選択アイテム名
CString strSelect = m_Tree.GetItemText(item); ←空が返る
}
取得できません。どこか悪いのでしょうか?

TVGN_DROPHILITEを使った場合、
正常に取得できました。
ただ、これを採用して良いか迷います。
やはり正式な方法(HisTest)のほうが良いでしょうか?


返信引用
maru
 maru
(@maru)
ゲスト
結合: 17年前
投稿: 358
 

人に聞く前に確かめるべきことがあると思うけど。
GetCursorPos(&pt); // 取得した座標はただしいか?
ScreenToClient(&pt); // 変換した座標は正しいか?

HTREEITEM item = m_Tree.HitTest(pt, &uFlag);
// 取得できたitemは正しいか? uFlag の値は?

ちなみにメッセージが発行された時のマウスの位置はGetMessagePos関数で取得します。

> TVGN_DROPHILITEを使った場合、
> 正常に取得できました。
> ただ、これを採用して良いか迷います。
> やはり正式な方法(HisTest)のほうが良いでしょうか?
マイクロソフトのドキュメントに記載されていないやりかたで出来たとしても、
何の保証もないと思いますが。


返信引用
ryo
 ryo
(@ryo)
ゲスト
結合: 23年前
投稿: 252
 

CTreeCtrlって、右クリックした段階で
アイテム選択されていませんでしたっけ?


返信引用
aetos
(@aetos)
Noble Member
結合: 5年前
投稿: 1480
 

> ScreenToClient(&pt); // 変換した座標は正しいか?

正しくないですねぇ。


返信引用
Nezu
 Nezu
(@Nezu)
ゲスト
結合: 17年前
投稿: 44
Topic starter  

皆さま、ありがとうございます。

m_Tree.ScreenToClient(&pt);
とすることで右クリックしたアイテムを取得することができました。
ありがとうございました。


返信引用
Nezu
 Nezu
(@Nezu)
ゲスト
結合: 17年前
投稿: 44
Topic starter  

か・い・け・つ


返信引用
ロマ
 ロマ
(@ロマ)
ゲスト
結合: 18年前
投稿: 170
 

maruさん
> マイクロソフトのドキュメントに記載されていないやりかたで出来たとしても、
> 何の保証もないと思いますが。

ryoさん
> CTreeCtrlって、右クリックした段階で
> アイテム選択されていませんでしたっけ?

msdnの説明が変ですね。

Default Tree-View Control Message Processing
 WM_RBUTTONDOWN
  Checks to see if an item was clicked and a drag operation was begun.
  If the operation has begun, it sends a TVN_BEGINRDRAG notification
  message to the parent window and highlights the drop target. Otherwise,
  it sends an NM_RCLICK notification message to the parent window. There
  is no return value.

実際には、WM_RBUTTONDOWNでDROPHILITEがつき、
TVN_BEGINDRAGでDROPHILITEが消えます。

エクスプローラのTreeViewは、なぜか、このDefaultProcessingを使わず、
TVM_HITTEST-->TVM_SELECTITEM(TVGN_DROPHILITE)の順で処理しているようです。


返信引用
....!
 ....!
(@....!)
ゲスト
結合: 15年前
投稿: 1
 

マウス操作による右クリックは対応出来たかも知れんが、
「Shift+F10」等のキーボードからの操作は問題無く対応出来てる?


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました