Page 1 of 1

CControlBar in CChildFrame

Posted: 12 Dec 2011, 12:29
by mesajflaviu
Se poate pune un CControlBar intr-un CChildFrame ? Am luat de aici un control derivat din CControlBar si am incercat sa il pun intr-un ChildFrame similar cum se pune intr-un CMainFrame :

Code: Select all

// ChildFrm.h
//protected:
	CControlBarExt m_wndControlBar;
	CTestDialog m_cDialog;

Code: Select all

int CChildFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
	if(CMDIChildWnd::OnCreate(lpCreateStruct) == -1)return -1;

	// TODO: Add your specialized creation code here

	if(! m_wndControlBar.Create(this, &m_cDialog, CString("ControlBar Demo"), IDD_DIALOG1))
	{
		TRACE0("Failed to create dialogbar\n");
		return -1;      // fail to create
	}

	m_wndControlBar.SetBarStyle(m_wndControlBar.GetBarStyle() | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);
	m_wndControlBar.EnableDocking(0);
	DockControlBar(&m_wndControlBar);

	return 0;
}
... nu merge asa ... apoi am incercat sa pun acest ControlBar in CChildFrame din CView ... cu aceleasi rezultate (atasasez acesta incercare pentru exemplificare).

Re: CControlBar in CChildFrame

Posted: 12 Dec 2011, 13:21
by Ovidiu Cucu
Ai luat si tu un articol de pe vremea cand toata lumea se juca cu putulica-n nisip cautand tot felul de cool-effects. :)
E facut cu o versiune anterioara lui VS6.0 si te umple de asserturi si crapelnite.
Chiar iti trebuie asa ceva?

Eu zic, in general e suficient un dialogbar direct de la mama lui (CDialogBar).
Daca totusi vrei sa mai adaugi si ceva cool pe ici pe colo, derivezi din CDialogBar si dupa aia mai vorbim...

Re: CControlBar in CChildFrame

Posted: 12 Dec 2011, 13:46
by mesajflaviu
Si un dialogbar ar fi bun, nu zic nu, dar inca n-am vazut unul care sa poata fi dimensionabil la runtime ... ma uit un pic sa vad.

Re: CControlBar in CChildFrame

Posted: 12 Dec 2011, 14:06
by Ovidiu Cucu
mesajflaviu wrote:Si un dialogbar ar fi bun, nu zic nu, dar inca n-am vazut unul care sa poata fi dimensionabil la runtime ... ma uit un pic sa vad.
Pai nu e dimensionabil, tre sa-l faci tu. La fel a facut si nenea ala care-a derivat direct din CControlBar.
Ai putintica rabdare, mai lasa un pic google, sa ma uit si eu ce si cum a vrut el sa faca, apoi iti spun cum cred ca e mai bine.

Re: CControlBar in CChildFrame

Posted: 12 Dec 2011, 15:34
by Ovidiu Cucu
Ok, hai sa pastram deocamdata ce ai luat de pe CG, care pana la urma si cu mici bibileli functioneaza.
Am observat ca ai incercat mai intai sa creezi controlbar-ul pe CChildFrame::OnCreate. Nu ti-a mers pentru ca ai uitat un EnableDocking pentru frame.
Te-ai mutat apoi in clasa view-ului unde ai mai facut o greseala: ai pus view-ul ca parinte pentru controlbar ceea ce nu-i corect pentru ca view-ul nu stie cei aia docking.
Deci, mutam tot inapoi in frame, avem grija sa nu uitam ceva si scriem cam asa:

Code: Select all

int CChildFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
   if(CMDIChildWnd::OnCreate(lpCreateStruct) == -1)
      return -1;
   
   if(! m_wndControlBar.Create(this, &m_cDialog, _T("ControlBar Demo"), IDD_DIALOG1))
   {
      TRACE0("Failed to create dialogbar\n");
      return -1;      // fail to create
   }
   
   m_wndControlBar.SetBarStyle(m_wndControlBar.GetBarStyle() | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);
   
   m_wndControlBar.EnableDocking(CBRS_ALIGN_ANY); // <-- aici ii pusesesi 0
   EnableDocking(CBRS_ALIGN_ANY); // <-- ai uitat asta
   
   DockControlBar(&m_wndControlBar);
   
   return 0;
}
Acuma merje.
O mica bibileala am mai facut: am schimbat CControlBarExt::Create si am pus LPCTSTR pszTitle in loc de CString& pTitle. Cred ca te-ai prins de ce. ;)
Pot sa-i scoti si 'virtual' ca oricum n-are sens.

Re: CControlBar in CChildFrame

Posted: 12 Dec 2011, 19:41
by mesajflaviu
De mai mult timp ma intrebam daca merge un CControlBar intr-un child frame, si cum la prima incercare n-am reusit ( si acum vad de ce ), am cautat in lung si in lat, si am gasit ceva asemanator in care control-bar-ul era pus din CView, nu din CChidFrame ... Acum merge asa cum trebuie. Mii de multumiri !!!

Re: CControlBar in CChildFrame

Posted: 13 Dec 2011, 10:20
by Ovidiu Cucu
Pana la urma, orice e posibil inclusiv de pus un controlbar, sa zicem, intr-un buton. :)
Problema e ca, un buton n-a fost proiectat pentru asa ceva iar efortul ar fi prea mare.
In "arhitectura" SDI/MDI, cele care sunt facute pentru a doca in ele controlbar-uri sunt frame-urile.
Celelalte au alta destinatie si orice incercare de a o schimba inseamna "scarchinare cu chiciorul".

Ar trebui sa-mi cer un pic scuze de la nenea care-a scris articolul ala in CG. Vina lui e ca nu si-a testat bine aplicatia demo care crapa daca nu apesi pe unde trebuie si in ordinea care trebuie. In rest e Ok, clasa lui de controlbar functioneaza daca o folosesti cum trebuie. Poate ar fi trebit sa puna niste assert-uri ca sa nu-ti dea voie sa pui parinte altceva decat un frame. Si o mica chestie de "design": pentru ca a pornit de la un dialog template, cred ca ar fi fost mai bine ca sa deriveze din CDialogBar. Ar fi fost si o alternativa fara dialog tempate, un fel de "CTreeControlBar" derivat direct din CControlBar.

In fine, nimc nu-i perfect, merge asa cum e...

Re: CControlBar in CChildFrame

Posted: 13 Dec 2011, 22:05
by mesajflaviu
Ovidiu Cucu wrote: Ar trebui sa-mi cer un pic scuze de la nenea care-a scris articolul ala in CG. Vina lui e ca nu si-a testat bine aplicatia demo care crapa daca nu apesi pe unde trebuie si in ordinea care trebuie. In rest e Ok, clasa lui de controlbar functioneaza daca o folosesti cum trebuie. Poate ar fi trebit sa puna niste assert-uri ca sa nu-ti dea voie sa pui parinte altceva decat un frame. Si o mica chestie de "design": pentru ca a pornit de la un dialog template, cred ca ar fi fost mai bine ca sa deriveze din CDialogBar. Ar fi fost si o alternativa fara dialog tempate, un fel de "CTreeControlBar" derivat direct din CControlBar.

In fine, nimc nu-i perfect, merge asa cum e...
Intradevar poate era mai eficient sa porneasca de la un CDialogBar ( iesea un control mai specializat, de ex.CTreeControlBar ), insa aceasta abordare este poate mai versatila, in sensul ca in acel dialog din CControlBar poate fi pus usor orice control ...

Si intradevar, acest control nu e testat suficient ! In cazul implementarii in CChildFrame apare o anomalie : controlul din dialog apare in stanga-sus ecranului (am atasat exemplul pentru exemplificare) si nu inteleg de ce ... am incercat sa modific parametrii MoveWindow(...) si SetWindowPos(...) din CControlBarExt::OnWindowPosChanged insa fara efect ... am incercat in CTestDialog::OnSize(...) sa mut controlul ( m_Tree in cazul meu ) dar degeaba ... imi scapa ceva, dar nu stiu ce :?:

O alta chestie interesanta : la rularea in mod debug, dupa inchidere am urmatorul mesaj :

Code: Select all

Warning: calling DestroyWindow in CDialog::~CDialog --
	OnDestroy or PostNcDestroy in derived class will not be called.
am rezolvat-o cu apelarea DestroyWindow(); in destructorul ~CTestDialog(), dar nu inteleg de ce am acest mesaj.

Orice ajutor este binevenit.

Re: CControlBar in CChildFrame

Posted: 14 Dec 2011, 00:16
by Ovidiu Cucu
Uita-te te rog mai intai la ce este o fereasta "child".
Trebue dialogul nostru sa fie child? Eu zic ca da.
Este child dialogul tau? Eu zic ca nu.

Re: CControlBar in CChildFrame

Posted: 14 Dec 2011, 09:31
by mesajflaviu
Doi iepuri dintr-o lovitura : acum merge cum trebuie controlul si nu mai am nici acel mesaj warning ... si ce simplu era ! :oops:

Re: CControlBar in CChildFrame

Posted: 14 Dec 2011, 10:00
by Ovidiu Cucu
Ai scapat si de acel warning, care iti spunea ca, in momentul cand s-a ajuns in destructorul din clasa de baza (CDialog), fereastra dialogului nu a fost inca distrusa.
Ok, o va face acel destructor insa te atentioneaza ca "ai fentat" cate ceva din flow-ul din framework si in consecinta PostNcDestroy, care este o functie virtuala apelata dupa WM_NCDESTROY (ultimul mesaj pe care-l primeste o fereastra inainte de-asi da duhul) nu a mai fost apelata. Daca ai de facut acolo ceva curatenie atunci poate fi naspa. Sper ca-i clar. :)

Si ca tot vorbeam mai devreme de assert-uri: nu strica, la creartea dialogului in CControlBarExt::Create:

Code: Select all

BOOL CControlBarExt::Create(CWnd* pParentWnd, CDialog* pDialog, ...
{
   //...
   m_pDialog->Create(nID, this);
   ASSERT(m_pDialog->GetStyle() & WS_CHILD); // the dialog must be a child, dude! 
   // ...
Asta te-ar fi ajutat sa gasesti mai repede greseala de care discutam acum.

La fel, spuneam mai devreme ca nu ar fi stricat un assert care sa nu-ti dea voie sa pui control bar-ul intr-un view sau in orice altceva care nu-i un frame:

Code: Select all

BOOL CControlBarExt::Create(CWnd* pParentWnd, CDialog* pDialog, ...
{
   //...
   ASSERT_KINDOF(CFrameWnd, pParentWnd); // parent window must be a frame, dude!
   //...
Si-or mai fi de-om mai gasi. ;)
Assert-urile sunt foarte bune pentru ca te ajuta sa gasesti la timp erori de programare si sau "design".
Bineinteles daca-s unde unde trebuie si nu de aiurea.

Si o mica observatie la
mesajflaviu wrote:Intradevar poate era mai eficient sa porneasca de la un CDialogBar ( iesea un control mai specializat, de ex.CTreeControlBar ), insa aceasta abordare este poate mai versatila, in sensul ca in acel dialog din CControlBar poate fi pus usor orice control ...
Mai "versatil" nu inseamna neaparat "mai bun". O clasa CCameleon care sa poata fi sau verde sau albastra (in cazul nostru un controlbar care sa poata avea sau un tree sau altceva ce-or mai vrea muschii nostri) nu-i neaparat solutia cea mai fericita.
In mod sigur vei da in curand de alte probleme... garantez. ;)

Cel mai bine ar fi sa ai sa ai ceva de genul CTreeBar derivat direct din CControlBar (sau mai bine dintr-o clasa intermediara sa-i zicem CCommonControlBar, care sa se ocupe doar de sizare si de desenarea acelui grip).
Daca vrei un listbox inautru, no probem faci alta: CListBoxBar, s.a.m.d.
Si scapi draq si de acel dialog template care nu cotine altceva dect un tree, in schimb te baga in belele daca nu esti atent la stiluri (si-or mai fi).

Re: CControlBar in CChildFrame

Posted: 14 Dec 2011, 21:17
by mesajflaviu
Cu fiecare post, invatam meserie ! :idea:

Re: CControlBar in CChildFrame

Posted: 17 Dec 2011, 18:22
by Ovidiu Cucu
Mergand pe una din ideile de mai inainte am facut putina ordine.
Am pus ce tine de docare intr-o clasa generica, numita CCommonControlBar derivata direct din CControlBar.
In afara de cateva mici modificari, contine codul din articolul de la Codeguru (http://www.codeguru.com/cpp/w-d/docking ... .php/c1451).
Din asta, derivez cate o clasa pentru fiecare tip de controlbar (CTreeCtrlBar, CListBoxBar, etc).
Avantajul acestei abordari consta si in faptul ca poti prinde notificarile de la control in clasa frame-ului, documentului sau a view-ului ca si la celelalte controlbar-uri deja implementsate in MFC fara sa fie nevoie sa faci tu alte briz-brizuri.
Control Bars Demo.jpg
Control Bars Demo.jpg (43.8 KiB) Viewed 11022 times
Vezi aplicatia demo atasata si daca sunt nelamuriri/probleme/comentarii/observatii, te rog sa-mi spui.
ControlBars_Demo.zip
(60.95 KiB) Downloaded 383 times