建立一個button在dialog上的時候,他預設只有兩種事件可以響應,一是BN_CLICKED,另一則是BN_DOUBLECLICKED,那我要滑鼠左鍵按下與彈上的事件該怎麼做呢?
VC6是這樣做的:
1.在原Dialog下新增一CMyButton類別,其父類別為CButton。
2.為MyButton類別添加WM_LBUTTONDOWN與WM_LBUTTONUP的消息響應。
3.在Dialog下宣告一個MyButton的成員變數。
4.在MyButton.cpp->CMyButton::OnLButtonDown 內編輯你要滑鼠左鍵按下時,要做什麼事。
2013/07/08
2013/07/04
[MFC] Tree Control Item 如何辨識唯一值
當我們在TreeCtrl上新增Item完後,若要在之後的操作中,判別此Item是否為唯一項目,目前只知道能用ItemText來判斷,但萬一ItemText非唯一值時,這樣的判斷方式就會有問題!
為了避免這樣的狀況發生,我在新增Item時,偷用一個欄位:lParam
先在.h定義一個與Item相關的其他訊息結構:
然後在.cpp內修改tree insert的部份:
當滑鼠拖曳某項Item時,會響應TVN_BEGINDRAG消息,這時從響應函式內將ID取出。
ps.方法1&2選一個用即可。
參考:StackOverflow how to create new Property for MFC(VC++) treeview Control?
為了避免這樣的狀況發生,我在新增Item時,偷用一個欄位:lParam
先在.h定義一個與Item相關的其他訊息結構:
typedef struct _treeItemInfo;
{
long nId;
//也可以放入其他需要紀錄的資訊,如 char sTextEx[8];
} ITEMINFO, *PITEMINFO;
然後在.cpp內修改tree insert的部份:
void CMyDlg::InsertNewItem()
{
HTREEITEM hSubItem;//新增Item後會回傳Item handle
TV_INSERTSTRUCT tvis;
TV_ITEM tvi;//set item member data
tvi.mask= TVIF_TEXT;
tvi.pszText= "test";//顯示在Item上的文字
//set insert struct;
member data
tvis.item= tvi;//insert items into CTreeCtrl
tvis.hParent= NULL;//此為根結點,故父節點為NULL
tvis.hInsertAfter= TVI_ROOT;//此為根結點
hSubItem = m_tree.InsertItem(tvis);
//方法1
PITEMINFO l_pItemEx = new ITEMINFO;
l_pItemEx->nId = 1000;
strcpy(l_pItemEx->sTextEx,"MyInfo");
m_tree.SetItemData( hSubItem, l_pItemEx);//將序號結構地址與此節點綁在一起
//方法2
DWORD dItemId = 1000;//表示Item序號
m_tree.SetItemData( hSubItem, dItemId);//將序號與此節點綁在一起
}
當滑鼠拖曳某項Item時,會響應TVN_BEGINDRAG消息,這時從響應函式內將ID取出。
void CMyDlg::OnTvnBegindrag(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMTREEVIEW pNMTreeView = reinterpret_cast LPNMTREEVIEW(pNMHDR);
*pResult = 0;
// TODO: 在此加入控制項告知處理常式程式碼
DWORD tmpId;
//方法1
HTREEITEM hDragItem = ((NM_TREEVIEW*)pNMHDR)->itemNew.hItem;
PITEMINFO l_pTmpItemEx = (PITEMINFO)m_tree.GetItemData(hDragItem);
tmpId = m_tree.GetItemData(hDragItem);
}
//方法2
TVITEM tvitem= ((NM_TREEVIEW*)pNMHDR)->itemNew;
tmpId = tvitem.lParam;
//取得ID後,作你想做的事吧!
ps.方法1&2選一個用即可。
參考:StackOverflow how to create new Property for MFC(VC++) treeview Control?
[MFC]多消息響應同一函式
以前的寫法都是 one message mapping one function,
但有時候其實多個消息要做的事情,都會對到同一個對象,只是做的動作不同,
例如對同一個表單做新增、刪除、修改、查詢這樣的狀況,
這時候就可以用 ON_COMMAND_RANGE囉~
舊做法:
//m_tree的add del modify只是示意,並非真的有此member function,詳見msdn CTreeCtrl
本篇參考:msdn ON_MESSAGE_RANGE
但有時候其實多個消息要做的事情,都會對到同一個對象,只是做的動作不同,
例如對同一個表單做新增、刪除、修改、查詢這樣的狀況,
這時候就可以用 ON_COMMAND_RANGE囉~
舊做法:
ON_COMMAND(ID_TREEITEM_ADD, &CMyDialog::OnTreeItemAdd)
ON_COMMAND(ID_TREEITEM_DEL, &CMyDialog::OnTreeItemDel)
ON_COMMAND(ID_TREEITEM_MODIFY, &CMyDialog::OnTreeItemModify)
void CMyDialog::OnTreeItemAdd()
{
m_tree.add(hItem);
}
void CMyDialog::OnTreeItemDel()
{
m_tree.delete(hItem);
}
void CMyDialog::OnTreeItemModify()
{
m_tree.Modify(hItem);
}
改為:
ON_COMMAND_RANGE(ID_TREEITEM_ADD,ID_TREEITEM_MODIFY, &CMyDialog::OnTreeItem)
//此作法需注意:ID_TREEITEM_ADD、ID_TREEITEM_DEL、ID_TREEITEM_MODIFY在resource.h中必須為連續數,如1、2、3。
void CMyDialog::OnTreeItem(UINT nID)
{
switch(nID)
{
case ID_TREEITEM_ADD:
m_tree.add(hItem);
break;
case ID_TREEITEM_DEL:
m_tree.del(hItem);
break;
case ID_TREEITEM_MODIFY:
m_tree.Modify(hItem);
break;
default:
break;
}
}
//m_tree的add del modify只是示意,並非真的有此member function,詳見msdn CTreeCtrl
本篇參考:msdn ON_MESSAGE_RANGE
訂閱:
文章 (Atom)