用MFC做一個界面,用到了串列控制元件,因為要讓串列的內容根據不同的選擇而有所變化,所以想要自己定義一個函式而不是在OnInitDialog函式中直接加,但是現在發現如果不在OnInitDialog函式中加,整個串列控制元件的內容是空的,如圖1所示。只有當在OnInitDialog函式中直接加時,串列控制元件才有內容,如圖2所示。但是,此時串列控制元件雖然有內容,卻并不能實作讓串列的內容根據不同的選擇而有所變化,該怎么解決呢?

圖1

圖2
uj5u.com熱心網友回復:
當然可以了,你在任何時候都可以更新控制元件資料,但是,如果在執行緒里更新控制元件內容,盡量使用發送自定義訊息,不要直接對UI上的控制元件進行更改,否則可能出錯!你這里要實作你的操作,可以增加一個滑鼠單擊事件,在該事件函式內對右邊的CtrlList控制元件更新!
uj5u.com熱心網友回復:
首先,感謝您的回答,現在的問題是:不在OnInitDialog函式直接添加,現在的串列控制元件完全是空的,如圖1所示,我現在就是想讓串列控制元件能有內容,并且不在OnInitDialog函式中添加
uj5u.com熱心網友回復:
CListCtrl::DeleteAllItemsCListCtrl::DeleteColumn
后 重新 init
uj5u.com熱心網友回復:
不在OnInitDialog函式中添加,你也可以在按鍵回應函式中追加啊!不想按鍵回應函式追加,也可以在建構式中,把要顯示的內容扯訓到一個成員變數中。然后再OnInitDialog函式中讀取成員變數內容不就完了嗎!!
uj5u.com熱心網友回復:
樹形控制元件有洗掉樹形控制元件中的所有節點的DeleteAllItems( )、洗掉樹形控制元件中的某個節點的DeleteItem(HTREEITEM hItem),那么除了有獲取選中節點的標簽文本字串的 GetSelectedItem(),有沒有獲取所有節點的標簽文本字串的方法呢?換句話來說就是,既然有點擊洗掉和全部洗掉,那么有沒有點擊選擇和全部選擇呢?回答這個問題的同樣可以得到問題點數!!!uj5u.com熱心網友回復:
"有沒有獲取所有節點的標簽文本字串的方法呢?“沒有 要 一個一個 獲取
uj5u.com熱心網友回復:
你可以使用自制函式,在OnInitDialog呼叫uj5u.com熱心網友回復:
遍歷所有Item,一個個獲取
uj5u.com熱心網友回復:
兄Dei,可能你沒有聽懂我的回答,我的意思是你更新控制元件顯示內容,在任何時候都可以,不一定在初始化對話框的函式內,結合你的應用場景,你想什么時候添加,就在你的事件回應函式內添加,就是說你在你程式對話框啟動后的任何地方,就是在OnInitDialog之后,想改變它的時候就發一個自定義訊息就可以了,在訊息處理函式中操作控制元件顯示內容!
舉例:一個button,你雙擊會在對話框類里產生一個單擊事件回應函式,你就可以在那個按鈕下更新任UI上的何控制元件!
我感覺你的問題是在于:你不清楚對話框創建程序和windows訊息機制!(或許)
uj5u.com熱心網友回復:
樹形控制元件有洗掉樹形控制元件中的所有節點的DeleteAllItems( )、洗掉樹形控制元件中的某個節點的DeleteItem(HTREEITEM hItem),那么除了有獲取選中節點的標簽文本字串的 GetSelectedItem(),有沒有獲取所有節點的標簽文本字串的方法呢?換句話來說就是,既然有點擊洗掉和全部洗掉,那么有沒有點擊選擇和全部選擇呢?回答這個問題的同樣可以得到問題點數!!!
遍歷所有Item,一個個獲取
能不能給段遍歷的代碼,在網上找了一些都不能得到想要的效果,感徑訓是對這個還是不太了解。
下面兩張圖是我的樹和我寫的遍歷樹的代碼,但是還是不完善,能不能幫幫忙完善一下或者給個思路!現在還不能得到以“C”開頭的文本!!

圖1

圖2
uj5u.com熱心網友回復:
我現在的代碼:vector<string> vec;
vec.clear();
// TODO: Add your control notification handler code here
HTREEITEM hRoot = m_treeCtrl.GetRootItem(); //根節點
HTREEITEM hTreeItemChlid1=m_treeCtrl.GetChildItem(hRoot);//得到根節點的子節點(第一個)
HTREEITEM hTreeItemChlid=m_treeCtrl.GetChildItem(hTreeItemChlid1);//得到子節點的子節點(第一個)
while (hTreeItemChlid!=NULL)
{
CString temp=m_treeCtrl.GetItemText(hTreeItemChlid);//獲取節點上的文本
vec.push_back(string(temp));//壓入容器
hTreeItemChlid=m_treeCtrl.GetNextSiblingItem(hTreeItemChlid);//得到子節點的兄弟節點
}
for(int i=0;i<vec.size();i++)
{
cout<<vec[i]<<endl;
}
uj5u.com熱心網友回復:
void CTreeCtrlDlg::WalkTreeCtrl(HTREEITEM hParent)
{
HTREEITEM hChild,hNext;
CString str;
// enter all child
hChild=m_TreeCtrl.GetChildItem(hParent);
str=m_TreeCtrl.GetItemText(hChild);
// output child
afxDump << str << "\n";
while (hChild)
{
if(m_TreeCtrl.ItemHasChildren(hChild)) WalkTreeCtrl(hChild);
hNext=m_TreeCtrl.GetNextSiblingItem(hChild);
hChild=hNext;
}
}
void CTreeCtrlDlg::OnButton1()
{
// TODO: Add your control notification handler code here
HTREEITEM hParent=m_TreeCtrl.GetRootItem();
CString str=m_TreeCtrl.GetItemText(hParent);
// output root
afxDump << str << "\n";
//
WalkTreeCtrl(hParent);
}
uj5u.com熱心網友回復:
注意if(m_TreeCtrl.ItemHasChildren(hChild)) WalkTreeCtrl(hChild);
遞回·
uj5u.com熱心網友回復:
“給定一個小點的輸入,完整單步跟蹤(同時按Alt+7鍵查看Call Stack里面從上到下列出的對應從里層到外層的函式呼叫歷史)一遍。”是理解遞回函式作業原理的不二法門!遞回函式關注以下幾個因素
·退出條件
·引數有哪些
·回傳值是什么
·區域變數有哪些
·全域變數有哪些
·何時輸出
·會不會導致堆疊溢位
uj5u.com熱心網友回復:
下面是全路徑輸出
//
void CTreeCtrlDlg::GetTreePath(HTREEITEM hItem)
{
CString Path;
CString tmp;
while (hItem)
{
tmp=m_TreeCtrl.GetItemText(hItem);
Path=tmp+"\\"+Path;
// get parent
hItem=m_TreeCtrl.GetParentItem(hItem);
}
if(Path.Right(1)=="\\") Path=Path.Left(Path.GetLength()-1);
// AfxMessageBox(treepath);
afxDump << Path << "\n";
return;
}
//
void CTreeCtrlDlg::WalkTreeCtrl(HTREEITEM hParent)
{
HTREEITEM hChild;
CString str;
// enter all child
if(hParent==0) hChild=m_TreeCtrl.GetRootItem();
else hChild=m_TreeCtrl.GetChildItem(hParent);
//
while (hChild)
{
GetTreePath(hChild);
if(m_TreeCtrl.ItemHasChildren(hChild)) WalkTreeCtrl(hChild);
hChild=m_TreeCtrl.GetNextSiblingItem(hChild);
}
}
void CTreeCtrlDlg::OnButton1()
{
// TODO: Add your control notification handler code here
WalkTreeCtrl(0);
}
結果
Root
Root\Child1
Root\Child1\Child2
Root\Child1\Child2\Child3
Root\Child1\Child2\Child3\Child4
Root\Child1\Child2\Child3\Child5
uj5u.com熱心網友回復:
如何利用遞回添加父子節點給樹形控制元件呢?各位大神幫幫忙!本來想再發一個求助帖的,但是不知道怎么回事被刪帖了,只能趁著這個求助帖還沒結貼,又有這么多熱心的朋友幫忙,謝謝啦!
這個問題我會追加得分的!!!謝謝啦!
希望這個回復不要再被刪了!!
uj5u.com熱心網友回復:
你已經有個 tree 了 ?uj5u.com熱心網友回復:
你已經有個 tree 了 ?
沒有tree,所以想利用遞回添加父子節點給樹形控制元件,得到一個tree
uj5u.com熱心網友回復:
不知道你的意思是不是選擇樹形控制元件,則重繪串列控制元件的資料?如果是,那么就實作NM_CLICK事件即可。
具體步驟:
Step1.添加NM_CLICK訊息回應函式
Step2.樹形控制元件使用GetSelectedItem獲取當前選擇項
Step3.遍歷樹形控制元件節點,回圈判斷是哪個節點被選擇
Step4.顯示對應節點 資料到串列控制元件即可。
uj5u.com熱心網友回復:
不知道你的意思是不是選擇樹形控制元件,則重繪串列控制元件的資料?
如果是,那么就實作NM_CLICK事件即可。
具體步驟:
Step1.添加NM_CLICK訊息回應函式
Step2.樹形控制元件使用GetSelectedItem獲取當前選擇項
Step3.遍歷樹形控制元件節點,回圈判斷是哪個節點被選擇
Step4.顯示對應節點 資料到串列控制元件即可。
就是現在我已經在MFC上添加了樹形控制元件了,但是還沒往里加節點,所以我想問問怎么把父子節點通過vector加進樹形控制元件里,我是把節點的父子關系寫在了文本里,然后從文本里讀取資料到vector里,現在就是想把vector里的有關父子的節點添加到樹形控制元件,請幫忙看看能否做到這一點,謝謝啦!
uj5u.com熱心網友回復:
“我是把節點的父子關系寫在了文本里”能否 看看 這個 文本 ?
uj5u.com熱心網友回復:
不知道你的意思是不是選擇樹形控制元件,則重繪串列控制元件的資料?
如果是,那么就實作NM_CLICK事件即可。
具體步驟:
Step1.添加NM_CLICK訊息回應函式
Step2.樹形控制元件使用GetSelectedItem獲取當前選擇項
Step3.遍歷樹形控制元件節點,回圈判斷是哪個節點被選擇
Step4.顯示對應節點 資料到串列控制元件即可。
就是現在我已經在MFC上添加了樹形控制元件了,但是還沒往里加節點,所以我想問問怎么把父子節點通過vector加進樹形控制元件里,我是把節點的父子關系寫在了文本里,然后從文本里讀取資料到vector里,現在就是想把vector里的有關父子的節點添加到樹形控制元件,請幫忙看看能否做到這一點,謝謝啦!
可以的,但文本最好是XML格式的會比較好。
uj5u.com熱心網友回復:
0 Root A1 A B1
1 A B2
1 A B3
2 B1 C1
2 B1 C2
2 B2 C4
2 B2 C6
2 B3 C7
2 B3 C8
uj5u.com熱心網友回復:
Root 0 0A 1 0
B1 2 1
B2 3 1
B3 4 1
C1 5 2
C2 6 2
C4 7 3
C6 8 3
C7 9 4
C8 10 4
uj5u.com熱心網友回復:
1 A 02 B1 1
3 B2 1
4 B3 1
5 C1 2
6 C2 2
7 C4 3
8 C6 3
9 C7 4
10 C8 4
uj5u.com熱心網友回復:
按結果Root
Root\Child1
Root\Child1\Child2
Root\Child1\Child2\Child3
Root\Child1\Child2\Child3\Child4
Root\Child1\Child2\Child3\Child5
書寫 txt !
插入 時 ,根據名(root) 看 有沒有 這個 hItem, 有就 不插入 ,沒有就 插入 ,插入 成功后 ,保存 這個 hItem ,這樣快些。
慢的辦法就是,根據名(root)遍歷tree ,取名 比較 ,再插入。
uj5u.com熱心網友回復:
用 xml 的 方法 參考“EditXML.rar”
https://download.csdn.net/download/schlafenhamster/8685007
“本程式 決議XML 檔案, 并可以 修改 屬性值.
使用 MSXML2”
uj5u.com熱心網友回復:
以上三個就是我的文本檔案內容了,不知道哪一個可以實作我要的功能,或者其他人有什么更好的想法按結果
Root
Root\Child1
Root\Child1\Child2
Root\Child1\Child2\Child3
Root\Child1\Child2\Child3\Child4
Root\Child1\Child2\Child3\Child5
書寫 txt !
插入 時 ,根據名(root) 看 有沒有 這個 hItem, 有就 不插入 ,沒有就 插入 ,插入 成功后 ,保存 這個 hItem ,這樣快些。
慢的辦法就是,根據名(root)遍歷tree ,取名 比較 ,再插入。
非常感謝您提供的辦法,請問一下,如果用遍歷要怎么做呢?
uj5u.com熱心網友回復:
其實就是 用 path 找到 那個 要 插入 的 hTreeItemuj5u.com熱心網友回復:
其實就是 用 path 找到 那個 要 插入 的 hTreeItem
可以說得詳細一點兒嗎?或者是給我給一段代碼看看,謝謝啦!
uj5u.com熱心網友回復:
給你 寫了一個
// in ".h"
// CString m_TreePath;
// HTREEITEM m_hTiFound;
void CTreeCtrlDlg::OnButton1()
{
m_TreeCtrl.DeleteAllItems();
//
CStringArray aStr;
aStr.Add("R");
aStr.Add("R\\C1");
aStr.Add("R\\C2");
aStr.Add("R\\C1\\G1");
aStr.Add("R\\C1\\G2");
aStr.Add("R\\C2\\G2");
//
for(int i=0;i<aStr.GetSize();i++)
{//
CString tmp=aStr[i];
int at=tmp.ReverseFind('\\');
if(at==-1)
{
m_TreeCtrl.InsertItem(tmp,6,0,TVI_ROOT);
continue;
}
else
{
CString tmpPath=tmp.Left(at);
at++;
CString tmpInsert=tmp.Right(tmp.GetLength()-at);
m_hTiFound=0;
FindTreeItem(0,tmpPath);
if(m_hTiFound)
{
m_TreeCtrl.InsertItem(tmpInsert,6,0,m_hTiFound);
}
else
{
AfxMessageBox("Tree path not found !");
}
}
}
}
// not return anything !
void CTreeCtrlDlg::FindTreeItem(HTREEITEM hParent,CString &SearchPath)
{
HTREEITEM hChild;
// enter all child
if(hParent==0) hChild=m_TreeCtrl.GetRootItem();
else hChild=m_TreeCtrl.GetChildItem(hParent);
//
while (hChild)
{
GetTreePath(hChild);
if(SearchPath==m_TreePath)
{
m_hTiFound=hChild;// global !
break;
}
if(m_TreeCtrl.ItemHasChildren(hChild)) FindTreeItem(hChild,SearchPath);
hChild=m_TreeCtrl.GetNextSiblingItem(hChild);
}
}
uj5u.com熱心網友回復:
C=child G=grandSonuj5u.com熱心網友回復:
補 一個
//
void CTreeCtrlDlg::GetTreePath(HTREEITEM hItem)
{
CString Path;
CString tmp;
while (hItem)
{
tmp=m_TreeCtrl.GetItemText(hItem);
Path=tmp+"\\"+Path;
// get parent
hItem=m_TreeCtrl.GetParentItem(hItem);
}
// delete last '\'
if(Path.Right(1)=="\\") Path=Path.Left(Path.GetLength()-1);
// output Path
// afxDump << Path << "\n";
m_TreePath=Path;
return;
}
uj5u.com熱心網友回復:
給你 寫了一個
// in ".h"
// CString m_TreePath;
// HTREEITEM m_hTiFound;
void CTreeCtrlDlg::OnButton1()
{
m_TreeCtrl.DeleteAllItems();
//
CStringArray aStr;
aStr.Add("R");
aStr.Add("R\\C1");
aStr.Add("R\\C2");
aStr.Add("R\\C1\\G1");
aStr.Add("R\\C1\\G2");
aStr.Add("R\\C2\\G2");
//
for(int i=0;i<aStr.GetSize();i++)
{//
CString tmp=aStr[i];
int at=tmp.ReverseFind('\\');
if(at==-1)
{
m_TreeCtrl.InsertItem(tmp,6,0,TVI_ROOT);
continue;
}
else
{
CString tmpPath=tmp.Left(at);
at++;
CString tmpInsert=tmp.Right(tmp.GetLength()-at);
m_hTiFound=0;
FindTreeItem(0,tmpPath);
if(m_hTiFound)
{
m_TreeCtrl.InsertItem(tmpInsert,6,0,m_hTiFound);
}
else
{
AfxMessageBox("Tree path not found !");
}
}
}
}
// not return anything !
void CTreeCtrlDlg::FindTreeItem(HTREEITEM hParent,CString &SearchPath)
{
HTREEITEM hChild;
// enter all child
if(hParent==0) hChild=m_TreeCtrl.GetRootItem();
else hChild=m_TreeCtrl.GetChildItem(hParent);
//
while (hChild)
{
GetTreePath(hChild);
if(SearchPath==m_TreePath)
{
m_hTiFound=hChild;// global !
break;
}
if(m_TreeCtrl.ItemHasChildren(hChild)) FindTreeItem(hChild,SearchPath);
hChild=m_TreeCtrl.GetNextSiblingItem(hChild);
}
}
請問一下,m_TreePath和m_hTiFound代表什么,在哪定義?
uj5u.com熱心網友回復:
// in ".h" 在 CTreeCtrlDlg 頭檔案中 定義。// CString m_TreePath;
// HTREEITEM m_hTiFound;
m_TreePath 即路徑
m_hTiFound Tree Item Found
如
aStr.Add("R\\C1"); 會被分成 2部分
m_TreePath=“R”;
所以 FindTreeItem 找文字為 “R”的 m_hTiFound ,如果 找到 則 插入 “C1”
要插入的 是 “C1”
這樣 定義的 txt 只要 保證 路徑 存在 就可 插入, 后插入 的 項 在 txt 中的 位置 比較隨意 。
uj5u.com熱心網友回復:
// in ".h" 在 CTreeCtrlDlg 頭檔案中 定義。
// CString m_TreePath;
// HTREEITEM m_hTiFound;
m_TreePath 即路徑
m_hTiFound Tree Item Found
如
aStr.Add("R\\C1"); 會被分成 2部分
m_TreePath=“R”;
所以 FindTreeItem 找文字為 “R”的 m_hTiFound ,如果 找到 則 插入 “C1”
要插入的 是 “C1”
這樣 定義的 txt 只要 保證 路徑 存在 就可 插入, 后插入 的 項 在 txt 中的 位置 比較隨意 。
按你這個怎么只有一個R出來,沒有C1,C2。。。呢?麻煩啦!
uj5u.com熱心網友回復:
// in ".h" 在 CTreeCtrlDlg 頭檔案中 定義。
// CString m_TreePath;
// HTREEITEM m_hTiFound;
m_TreePath 即路徑
m_hTiFound Tree Item Found
如
aStr.Add("R\\C1"); 會被分成 2部分
m_TreePath=“R”;
所以 FindTreeItem 找文字為 “R”的 m_hTiFound ,如果 找到 則 插入 “C1”
要插入的 是 “C1”
這樣 定義的 txt 只要 保證 路徑 存在 就可 插入, 后插入 的 項 在 txt 中的 位置 比較隨意 。
按你這個怎么只有一個R出來,沒有C1,C2。。。呢?麻煩啦!
哈哈哈,忘了加“m_TreeCtrl.ModifyStyle(NULL,TVS_HASBUTTONS | TVS_HASLINES | TVS_LINESATROOT);”這個!
uj5u.com熱心網友回復:
“CStringArray aStr;aStr.Add("R");
aStr.Add("R\\C1");
aStr.Add("R\\C2");
aStr.Add("R\\C1\\G1");
aStr.Add("R\\C1\\G2");
aStr.Add("R\\C2\\G2");”
這個怎么和我的txt文本檔案結合使用呢?
就是當我想要改變樹的分支情況時,只需要改變txt文本檔案就能實作,不用改動代碼?
uj5u.com熱心網友回復:
"只需要改變txt文本檔案就能實作"按上面的 格式 寫 Txt 檔案,
保存時 使用 給你的 void CTreeCtrlDlg::WalkTreeCtrl(HTREEITEM hParent)
(即 16 樓的 代碼)
uj5u.com熱心網友回復:
//
void CTreeCtrlDlg::WalkTreeCtrl(HTREEITEM hParent)
{
HTREEITEM hChild;
CString str;
// enter all child
if(hParent==0) hChild=m_TreeCtrl.GetRootItem();
else hChild=m_TreeCtrl.GetChildItem(hParent);
//
while (hChild)
{
#if 1 // need path
GetTreePath(hChild);
afxDump << m_TreePath << "\n";// 在這里把 path 寫入 TXT檔案 !
#else // no path
str=m_TreeCtrl.GetItemText(hChild);
// output
// afxDump << str << "\n";
#endif
if(m_TreeCtrl.ItemHasChildren(hChild)) WalkTreeCtrl(hChild);
hChild=m_TreeCtrl.GetNextSiblingItem(hChild);
}
}
uj5u.com熱心網友回復:
你的那個 txt 格式 是 累贅 的,不 直接。uj5u.com熱心網友回復:
你的那個 txt 格式 是 累贅 的,不 直接。
那應該怎么寫呢?我的意思是在不改動代碼的前提下,能夠修改樹形控制元件的結構,通過修改組態檔的方法
uj5u.com熱心網友回復:
用 筆記本 寫一個 TreePath.txt 內容 如下:R
R\C1
R\C1\G1
R\C1\G2
R\C2
R\C2\G1
R\C2\G2
R\C2\G2\X1
讀檔案
// in ".h"
// CString m_TreePath;
// HTREEITEM m_hTiFound;
void CTreeCtrlDlg::OnButton1()
{// read Tree Path
m_TreeCtrl.DeleteAllItems();
//
CStdioFile f;
f.Open("TreePath.txt",CFile::modeRead);
CString tmp;
while(f.ReadString(tmp))
{
if(tmp.IsEmpty()) continue;
int at=tmp.ReverseFind('\\');
if(at==-1)
{
if(m_TreeCtrl.GetRootItem())
{// has a root !
AfxMessageBox(tmp + " can't be a Second root item,only one root item allowed!");
}
else
{
HTREEITEM hroot=m_TreeCtrl.InsertItem(tmp,6,0,TVI_ROOT);
//afxDump << m_TreeCtrl.GetItemText(hroot) << "\n";
}
continue;
}
else
{
CString tmpPath=tmp.Left(at);
at++;
CString tmpInsert=tmp.Right(tmp.GetLength()-at);
m_hTiFound=0;
FindTreeItem(0,tmpPath);
if(m_hTiFound)
{
m_TreeCtrl.InsertItem(tmpInsert,6,0,m_hTiFound);
}
else
{
AfxMessageBox(tmpPath + " Tree path not found !");
}
}
}
f.Close();
}
寫 檔案
//
void CTreeCtrlDlg::WalkTreeCtrl(HTREEITEM hParent,CStdioFile &file)
{
HTREEITEM hChild;
CString str;
// enter all child
if(hParent==0) hChild=m_TreeCtrl.GetRootItem();
else hChild=m_TreeCtrl.GetChildItem(hParent);
//
while (hChild)
{// need path
GetTreePath(hChild);
m_TreePath += "\n";
if(file) file.WriteString((LPCSTR)m_TreePath);
if(m_TreeCtrl.ItemHasChildren(hChild)) WalkTreeCtrl(hChild,file);
hChild=m_TreeCtrl.GetNextSiblingItem(hChild);
}
}
////////////////////////////////
void CTreeCtrlDlg::OnButton2()
{// save tree path to txt
CStdioFile f;
f.Open("TreePath1.txt",CFile::modeCreate | CFile::modeWrite);
WalkTreeCtrl(0,f);
f.Close();
}
uj5u.com熱心網友回復:
uj5u.com熱心網友回復:
uj5u.com熱心網友回復:
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/64000.html
標籤:界面
