CControlBar in CChildFrame

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

CControlBar in CChildFrame

Post by mesajflaviu » 12 Dec 2011, 12:29

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).
Attachments
TestControlBarChild.zip
(103.31 KiB) Downloaded 352 times



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

Re: CControlBar in CChildFrame

Post by Ovidiu Cucu » 12 Dec 2011, 13:21

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...

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

Re: CControlBar in CChildFrame

Post by mesajflaviu » 12 Dec 2011, 13:46

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.

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

Re: CControlBar in CChildFrame

Post by Ovidiu Cucu » 12 Dec 2011, 14:06

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.

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

Re: CControlBar in CChildFrame

Post by Ovidiu Cucu » 12 Dec 2011, 15:34

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.

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

Re: CControlBar in CChildFrame

Post by mesajflaviu » 12 Dec 2011, 19:41

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 !!!

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

Re: CControlBar in CChildFrame

Post by Ovidiu Cucu » 13 Dec 2011, 10:20

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...

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

Re: CControlBar in CChildFrame

Post by mesajflaviu » 13 Dec 2011, 22:05

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.
Attachments
TestControlBarChild.zip
(105.83 KiB) Downloaded 352 times

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

Re: CControlBar in CChildFrame

Post by Ovidiu Cucu » 14 Dec 2011, 00:16

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.

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

Re: CControlBar in CChildFrame

Post by mesajflaviu » 14 Dec 2011, 09:31

Doi iepuri dintr-o lovitura : acum merge cum trebuie controlul si nu mai am nici acel mesaj warning ... si ce simplu era ! :oops:

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

Re: CControlBar in CChildFrame

Post by Ovidiu Cucu » 14 Dec 2011, 10:00

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).

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

Re: CControlBar in CChildFrame

Post by mesajflaviu » 14 Dec 2011, 21:17

Cu fiecare post, invatam meserie ! :idea:

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

Re: CControlBar in CChildFrame

Post by Ovidiu Cucu » 17 Dec 2011, 18:22

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 10675 times
Vezi aplicatia demo atasata si daca sunt nelamuriri/probleme/comentarii/observatii, te rog sa-mi spui.
ControlBars_Demo.zip
(60.95 KiB) Downloaded 375 times

Post Reply