Custom CTreeView

Intrebari legate de programarea cu biblioteci precum MFC, ATL, WTL si GDI+.
mesajflaviu
Membru++
Membru++
Posts: 687
Joined: 10 Sep 2008, 21:40
Judet: Cluj

Custom CTreeView

Post by mesajflaviu » 16 Jun 2014, 12:14

Se poate seta un CTreeView (CTreeCtrl) sa contina check-box-uri (setand stilul TVS_CHECKBOXES) ... dar exista posiblitatea de a pune acele check-box-uri doar pe unele item-uri, nu pe toate ? Banui ca ar trebui redesenat controlul, dar nu imi dau seama cum, si daca asta ar fi solutia cea mai buna ...



User avatar
Ovidiu Cucu
Fondator
Fondator
Posts: 3776
Joined: 11 Jul 2007, 16:10
Judet: Iaşi
Location: Iasi
Contact:

Re: Custom CTreeView

Post by Ovidiu Cucu » 16 Jun 2014, 16:01

Nu trebuie redesenat controlul.
Daca vrei sa ascunzi un checkbox dintr-un treeview cu stilul TVS_CHECKBOXES, dupa ce inserezi item-ul (sau oricand dupa aceea) ii setezi indexul pentru image state pe 0.

Code: Select all

    HTREEITEM hItem = m_treeCtrl.InsertItem(_T("ZUZU-ZUZU"), hParent);
    // INDEXTOSTATEIMAGEMASK(2) - draws ckecked state icon
    // INDEXTOSTATEIMAGEMASK(1) - draws unckecked state icon
    // INDEXTOSTATEIMAGEMASK(0) - no state icon (hide the check box)
    m_treeCtrl.SetItemState(hItem, INDEXTOSTATEIMAGEMASK(0), TVIS_STATEIMAGEMASK);

mesajflaviu
Membru++
Membru++
Posts: 687
Joined: 10 Sep 2008, 21:40
Judet: Cluj

Re: Custom CTreeView

Post by mesajflaviu » 17 Jun 2014, 10:31

Nu m-am gandit ca ar fi asa simplu ... abia astept sa incerc asta !!! Multumesc !

User avatar
Ovidiu Cucu
Fondator
Fondator
Posts: 3776
Joined: 11 Jul 2007, 16:10
Judet: Iaşi
Location: Iasi
Contact:

Re: Custom CTreeView

Post by Ovidiu Cucu » 17 Jun 2014, 16:13

Am observat o chestie care tine probabil de implementarea controlului: chestia de mai sus nu functioneaza decat dupa ce controlul devine vizibil.
Asa ca, daca ai de populat (cel putin partial) tree-ul la inceput, folosesti un mesaj custom pe care-l postezi din OnInitDialog.
De exemplu, cam asa:

Code: Select all

// MyDialog.h

class CMyDialog : public CDialog
{
    enum
    {
        WM_POPULATE_TREE = WM_APP + 1,
        // ...
    };
    // ...
    afx_msg LRESULT OnPopulateTree(WPARAM wParam, LPARAM lParam);
    // ...
};

Code: Select all

// MyDialog.cpp
// ...

BEGIN_MESSAGE_MAP(CDE_STERSDlg, CDialog)
    // ...
    ON_MESSAGE(WM_POPULATE_TREE, &CMyDialog::OnPopulateTree)
END_MESSAGE_MAP()
// ...

BOOL CMyDialog::OnInitDialog()
{
    CDialog::OnInitDialog();
    // ...
    PostMessage(WM_POPULATE_TREE);
    return TRUE;
}

LRESULT CMyDialog::OnPopulateTree(WPARAM wParam, LPARAM lParam)
{
    HTREEITEM hItem = NULL;
    // ...
    // insert item
    hItem = m_treeCtrl.InsertItem(_T("TRILU-LIRU"), hParent);
    // hide checkbox
    m_treeCtrl.SetItemState(hItem, INDEXTOSTATEIMAGEMASK(0), TVIS_STATEIMAGEMASK);
    // ...

    return 0;
}

mesajflaviu
Membru++
Membru++
Posts: 687
Joined: 10 Sep 2008, 21:40
Judet: Cluj

Re: Custom CTreeView

Post by mesajflaviu » 18 Jun 2014, 10:40

Spre rusinea mea, inca n-am reusit sa incerc solutia de la inceput ... sper sa apuc azi, dar acuma cu ultimele observatii sant convins ca va merge la sigur ... ma inclin :whorship:

mesajflaviu
Membru++
Membru++
Posts: 687
Joined: 10 Sep 2008, 21:40
Judet: Cluj

Re: Custom CTreeView

Post by mesajflaviu » 18 Jun 2014, 11:48

Am incercat codul de mai sus, se pare ca nu am facut eu ceva OK, pare ca nu functioneaza:

Code: Select all

void CMyTree::OnInitialUpdate() 
{
	CTreeView::OnInitialUpdate();

	// TODO: Add your specialized code here and/or call the base class

	PostMessage(WMU_POPULATETREE);
}

BOOL CMyTree::PreCreateWindow(CREATESTRUCT& cs) 
{
	// TODO: Add your specialized code here and/or call the base class

	cs.style |= TVS_HASLINES | TVS_LINESATROOT | TVS_HASBUTTONS | TVS_CHECKBOXES;

	return CTreeView::PreCreateWindow(cs);
}

LRESULT CMyTree::OnPopulateTree(WPARAM wParam, LPARAM lParam)
{
	HTREEITEM hItem = NULL;
	CTreeCtrl& TreeCtrl = GetTreeCtrl();

	HTREEITEM hRoot = TreeCtrl.InsertItem(_T("Root"));
	TreeCtrl.SetItemState(hItem, INDEXTOSTATEIMAGEMASK(0), TVIS_STATEIMAGEMASK);
	hItem = TreeCtrl.InsertItem(_T("Item 1"), hRoot);
//	TreeCtrl.SetItemState(hItem, INDEXTOSTATEIMAGEMASK(0), TVIS_STATEIMAGEMASK);
	hItem = TreeCtrl.InsertItem(_T("Item 2"), hRoot);
	TreeCtrl.SetItemState(hItem, INDEXTOSTATEIMAGEMASK(0), TVIS_STATEIMAGEMASK);
	TreeCtrl.Expand(hRoot, TVE_EXPAND);

	return 0;
}
evident, codul se apeleaza, am verificat asta ...

mesajflaviu
Membru++
Membru++
Posts: 687
Joined: 10 Sep 2008, 21:40
Judet: Cluj

Re: Custom CTreeView

Post by mesajflaviu » 18 Jun 2014, 13:11

O sa incerc sa reproduc totul pe un exemplu de test, si revin ...

mesajflaviu
Membru++
Membru++
Posts: 687
Joined: 10 Sep 2008, 21:40
Judet: Cluj

Re: Custom CTreeView

Post by mesajflaviu » 18 Jun 2014, 15:03

Ciudat ... pe aplicatia de test merge ... hmm ...
Attachments
Test.zip
(34.73 KiB) Downloaded 340 times

mesajflaviu
Membru++
Membru++
Posts: 687
Joined: 10 Sep 2008, 21:40
Judet: Cluj

Re: Custom CTreeView

Post by mesajflaviu » 18 Jun 2014, 15:09

Am luat stilul jos de la aplicatia reala, m-am gandit ca e de acolo, tot asa face ... mai trebuie sa sap.

mesajflaviu
Membru++
Membru++
Posts: 687
Joined: 10 Sep 2008, 21:40
Judet: Cluj

Re: Custom CTreeView

Post by mesajflaviu » 24 Jun 2014, 12:36

Cred ca am gasit cauza ... in aplicatia reala am mai multe tipuri de documente, iar cel in care am tree-ul buclucas il pornesc asa:

Code: Select all

void CMainFrame::OnFileMyDocumenttemplate() 
{
	// TODO: Add your command handler code here

	CMultiDocTemplate* pDocTemplate = NULL;
	POSITION pos = NULL, posTemplate = NULL, posDoc = NULL, posView = NULL;

	posTemplate = AfxGetApp()->GetFirstDocTemplatePosition();
	pos = AfxGetApp()->GetFirstDocTemplatePosition();
	pDocTemplate = (CMultiDocTemplate*)AfxGetApp()->GetNextDocTemplate(pos);
	if(pos)
	{
		pDocTemplate = (CMultiDocTemplate*)AfxGetApp()->GetNextDocTemplate(pos);
		if(pDocTemplate)
			pDocTemplate->OpenDocumentFile(NULL);
	}
}
nu imi dau seama ce nu ii place ...

mesajflaviu
Membru++
Membru++
Posts: 687
Joined: 10 Sep 2008, 21:40
Judet: Cluj

Re: Custom CTreeView

Post by mesajflaviu » 24 Jun 2014, 12:44

Am incercat si asa:

Code: Select all

void CMainFrame::OnFileMyDocumenttemplate() 
{
	// TODO: Add your command handler code here

	CMultiDocTemplate* pDocTemplate = NULL;
	POSITION pos = NULL, posTemplate = NULL, posDoc = NULL, posView = NULL;

	posTemplate = AfxGetApp()->GetFirstDocTemplatePosition();
	pos = AfxGetApp()->GetFirstDocTemplatePosition();
	pDocTemplate = (CMultiDocTemplate*)AfxGetApp()->GetNextDocTemplate(pos);
	if(pos)
	{
		pDocTemplate = (CMultiDocTemplate*)AfxGetApp()->GetNextDocTemplate(pos);
		if(pDocTemplate)
		{
			CDocument* pMyDoc = pDocTemplate->OpenDocumentFile(NULL);
			if(NULL != pMyDoc)
			{
				pos = pMyDoc->GetFirstViewPosition();
				::PostMessage(pMyDoc->GetNextView(pos)->m_hWnd, WMU_POPULATETREE, 0, 0);
			}
		}
	}
}
tot nu merge ...

mesajflaviu
Membru++
Membru++
Posts: 687
Joined: 10 Sep 2008, 21:40
Judet: Cluj

Re: Custom CTreeView

Post by mesajflaviu » 24 Jun 2014, 14:33

Am pus codul si in view-ul din dreapta splitt-ului:

Code: Select all

void CSecondView::OnInitialUpdate() 
{
	//TODO: This code navigates to a popular spot on the web.
	//Change the code to go where you'd like.

	CView::OnInitialUpdate();

	CDocument* pDoc = GetDocument();
	POSITION pos = pDoc->GetFirstViewPosition();
	CView* pView = pDoc->GetNextView(pos);
	::PostMessage(pView->m_hWnd, WMU_POPULATETREE, 0, 0);
}
nu merge si pace ... am tree-ul, dar peste tot vad checkbox-uri ...

mesajflaviu
Membru++
Membru++
Posts: 687
Joined: 10 Sep 2008, 21:40
Judet: Cluj

Re: Custom CTreeView

Post by mesajflaviu » 25 Jun 2014, 10:31

Ceva e ciudat ... am doua document template, fiecare cu cate un treeview in care pun checkbox-uri doar la unele item-uri ... pe care il deschid primul, merge ... daca deschid al doilea doc template, nu mai merge ...
Attachments
Test.zip
(66.75 KiB) Downloaded 345 times

mesajflaviu
Membru++
Membru++
Posts: 687
Joined: 10 Sep 2008, 21:40
Judet: Cluj

Re: Custom CTreeView

Post by mesajflaviu » 25 Jun 2014, 11:03

Chiar daca am un singur document template, intr-o aplicatie MDI, primul document deschis are item-uri in treeviewe-ul cum trebuie (unele cu checkbox-uri, unele fara), cand deschid al doilea document, toate checkbox-urile din treeview au checkbox-uri ... atasez o aplicatie simple de test pentru exemplificare ...
Attachments
Test.zip
(65.87 KiB) Downloaded 321 times

User avatar
Ovidiu Cucu
Fondator
Fondator
Posts: 3776
Joined: 11 Jul 2007, 16:10
Judet: Iaşi
Location: Iasi
Contact:

Re: Custom CTreeView

Post by Ovidiu Cucu » 25 Jun 2014, 14:57

Incearca asa:

Code: Select all

LRESULT CLeftView::OnPopulateTree(WPARAM wParam, LPARAM lParam)
{
    // ...
    treeCtrl.RedrawWindow(); // <-- add this

    HTREEITEM hRoot = treeCtrl.InsertItem(_T("Root - Doc template 1"));
    treeCtrl.SetItemState(hRoot, INDEXTOSTATEIMAGEMASK(0), TVIS_STATEIMAGEMASK);
    // ...

    return 0;
}

Post Reply