OnActivate()...

Intrebari despre programarea cu VC++ incluzand mediul de dezvoltare, instalare, setari, debugger, compilator, linker si documentatie.
radoo
Junior
Junior
Posts: 18
Joined: 14 Jul 2008, 15:38
Judet: Bistriţa-Năsăud

OnActivate()...

Post by radoo » 07 Jan 2009, 22:04

Salut, am o aplicatie MDI in care creez mai multe ferestre pe langa child`frame`ul creat de wizard. Am activat optiunea EnambleMDITabs si vreau ca de fiecare data cand ma mut dintr`un tab in altul sa ascund un pane si sa arat altul in functie de fereastra. Am incercat sa handluiesc mesajul WM_ACTIVATE cu OnActivate() insa functia asta se apeleaza de mai multe ori cand activez o fereastra sau chiar cand inchid aplicatia. Ce ar trebui sa folosesc sau cum ar trebui sa handluiesc WM_ACTIVATE pentru a se apela doar odata cand activez o fereastra? Mersi



User avatar
MrSmersh
Microsoft MVP
Microsoft MVP
Posts: 289
Joined: 20 Jul 2007, 10:18
Location: Timisoara
Contact:

Re: OnActivate()...

Post by MrSmersh » 07 Jan 2009, 22:48

Nu ar fi mai bine cu mesajul get focus?

radoo
Junior
Junior
Posts: 18
Joined: 14 Jul 2008, 15:38
Judet: Bistriţa-Năsăud

Re: OnActivate()...

Post by radoo » 07 Jan 2009, 22:58

Am incercat si cu OnSetFocus() si se intampla exact la fel...Ma intreb daca nu exista ceva mesaj care sa`mi indice cand se activeaza tab`urile...

User avatar
MrSmersh
Microsoft MVP
Microsoft MVP
Posts: 289
Joined: 20 Jul 2007, 10:18
Location: Timisoara
Contact:

Re: OnActivate()...

Post by MrSmersh » 08 Jan 2009, 00:40

Tab ziceai aaaa pai
TCN_SELCHANGE, TCN_SELCHANGED foloseste atunci, focus activate sint la un nivel mai jos... Sau chiar TCN_FOCUSCHANGE, desi daca am inteles bine ce vrei sa faci TCN_SELCHANGED e ce iti trebuie.

User avatar
Andreas
Membru
Membru
Posts: 117
Joined: 09 Nov 2008, 12:13
Judet: Timiş
Location: Timisoara

Re: OnActivate()...

Post by Andreas » 09 Jan 2009, 19:41

Problema ta este una interesanta, care creeaza putina confuzie.
Chiar daca aranjarea ferestrelor copil este sub forma "tabbed", asta nu inseamna ca avem de a face cu un tab control.
Deci nu avem mesaje TCN_x.
O alta confuzie/impediment este ca pe evenimentele de activate(childframe sau view), applicatia MDI trece prin "loop"-ul de ferestre pentru a face "unbold title" pentru ferestrele copil inactive si in final "bold title" pentru fereastra copil activa. Asa ca este "enervant" sa prindem activate-ul doar pentru fereastra care ne intereseaza.
Ne putem lega insa de altceva, Z order-ul ferestrelor copil: fereastra selectata este "the top-level child window".
Putem sa handle-uim asta, de exemplu, pe evenimentul de left mouse click in spatiul "non client":

Code: Select all

void CChildFrame::OnNcLButtonDown(UINT nHitTest, CPoint point)
{
	// TODO: Add your message handler code here and/or call default

	CWnd* pTop=this->GetParent()->GetTopWindow();
	CString sTitle;
	pTop->GetWindowText(sTitle);
	//AfxMessageBox(sTitle); //test fereastra corecta

	if(sTitle=="titlu_asociat_lui_pane1")
	  //show pane1, hide all other panes

	CMDIChildWnd::OnNcLButtonDown(nHitTest, point);
}
Succes!

radoo
Junior
Junior
Posts: 18
Joined: 14 Jul 2008, 15:38
Judet: Bistriţa-Năsăud

Re: OnActivate()...

Post by radoo » 09 Jan 2009, 23:14

Salut Andreas

Intr-adevar nu pot sa folosesc mesajele de tip TCN...e vorba despre noile clase de tab control din MFC feature pack...CMFCTabCtrl si CMFCBaseTabCtrl...am incercat intr-un fel si eu abordarea ta...putin diferit insa...testand daca punctul pe care am facut click se afla intr`un tab (GetTabFromPoint(CPoint&)...insa m-am lovit de aceeasi problema de care ma lovesc si acum la sugestia ta...fereastra nu raspunde la Mouse Click...nu`mi dau seama de ce inca...

Later edit: prinde mesajele de mouse click daca ferestrele nu`s in taburi atunci cand fac click pe bara, insa daca sunt puse in taburi si dau click pe tab, nu raspunde...

User avatar
MrSmersh
Microsoft MVP
Microsoft MVP
Posts: 289
Joined: 20 Jul 2007, 10:18
Location: Timisoara
Contact:

Re: OnActivate()...

Post by MrSmersh » 09 Jan 2009, 23:42

Recunosc am citit cam neatent...
Dar mi-am adus aminte de tehnica ce o foloseam la din astea cind nu stiam ce sa prind...
Pune Spy pe el si vezi ce mesaje vin...

Viorel
Microsoft MVP
Microsoft MVP
Posts: 293
Joined: 13 Jul 2007, 12:26

Re: OnActivate()...

Post by Viorel » 10 Jan 2009, 00:41

În locul mesajului WM_ACTIVATE încearcă WM_MDIACTIVATE, emis către clasa CChildFrame [http://msdn.microsoft.com/en-us/library/d1cbx7f1.aspx]. Acest mesaj este generat cînd o fereastră-copil devine activă sau inactivă, nu neapărat prin acţionarea unui tab.

User avatar
Andreas
Membru
Membru
Posts: 117
Joined: 09 Nov 2008, 12:13
Judet: Timiş
Location: Timisoara

Re: OnActivate()...

Post by Andreas » 10 Jan 2009, 14:37

Recunosc ca m-am pripit putin: solutia care ti-am sugerat-o a fost testata in VS2005 pe ferestre non-tabbed, si ma gandeam ca merge si in 2008, pe tabbed child windows. Deci trebuie sa rectific:

1. Intradevar avem de a face cu un CMFCTabCtrl care este fereastra de deasupra ferestrelor copil(fiasia cu tab-uri);
Am realizat asta urmarind mesajele cu Spy;
2. O idee ar fi fost sa subclasam acest control pentru a prinde mesajele care nu au handler-e in fereastra main frame;dar
3. Fereastra main frame este derivata din CMDIFrameWndEx care controleaza si tab-urile; numai ca
4. Wizard-ul nu ne ajuta sa adaugam facil un handler pentru un mesaj corespunzator; de ce?
5. Avem de a face cu un mesaj non-sistem care trebuie inregistrat si adaugat handler pentru prelucrare: mesajul in cuza este AFX_WM_CHANGE_ACTIVE_TAB observat tot cu Spy pe fereastra AfX:TabWnd; cum
Solutie:

1. In cpp-ul main frame-ului, in harta de mesaje se adauga:

Code: Select all

BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWndEx)
...
ON_REGISTERED_MESSAGE(AFX_WM_CHANGE_ACTIVE_TAB, &CMainFrame::OnTabChange)
...
2. Se declara in header-ul main frame-ului functia handler in sectiunea protected:

Code: Select all

afx_msg LRESULT OnTabChange(WPARAM wp, LPARAM lp);
3. Se defineste handler-ul OnTabChange:

Code: Select all

LRESULT CMainFrame::OnTabChange(WPARAM wp,LPARAM lp)
{

  return 0;
}
Si gata!

Trebuie subliniat inca o data ca event-urile de acivate in cazul mdi app. nu reprezinta o solutie pentru procesari de tip "once", pentru ca se declanseaza demai multe ori, inclusiv cele MDIACTIVATE.

Weekend placut si spor!

radoo
Junior
Junior
Posts: 18
Joined: 14 Jul 2008, 15:38
Judet: Bistriţa-Năsăud

Re: OnActivate()...

Post by radoo » 10 Jan 2009, 22:54

Intr-adevar functioneaza ok cu AFX_WM_CHANGE_ACTIVETAB. Mersi!.
Insa de ce il apeleaza inca o data pt fiecare fereastra cand inchid aplicatia?

User avatar
Andreas
Membru
Membru
Posts: 117
Joined: 09 Nov 2008, 12:13
Judet: Timiş
Location: Timisoara

Re: OnActivate()...

Post by Andreas » 11 Jan 2009, 12:20

Nu am raspuns clar. Probabil la inchiderea aplicatie, evenimentul de selectie de taburi este declansat la trecere prin sirul de ferestre copil pentru obtinerea/salvarea documentelor asociate fiecararei vizualizari.
Insa, poti sa controlezi executia handler-ului de schimbare de tab cand se inchide aplicatia, punand un flag pe evinementul de WM_SYSCOMMAND al main frame-ului care se trateaza inaintea schimbarii de tab pentru fiecare fereastra copil.

Am testat si ar trebui sa mearga!

radoo
Junior
Junior
Posts: 18
Joined: 14 Jul 2008, 15:38
Judet: Bistriţa-Năsăud

Re: OnActivate()...

Post by radoo » 12 Jan 2009, 15:11

Nu stii cum pot sa detectez ce obiect a declansat mesajul respectiv? Panourile de care ziceam ca o sa se activeze si dezactiveze sunt Tabbed Panes si cred ca main frame`ul prinde mesajele din ambele parti, iar programul crapa...

User avatar
Andreas
Membru
Membru
Posts: 117
Joined: 09 Nov 2008, 12:13
Judet: Timiş
Location: Timisoara

Re: OnActivate()...

Post by Andreas » 12 Jan 2009, 16:39

Cu Spy++...il gasesti instalat in VSx/Commonx/Tools...
Se pot filtra mesajele pentru fiecare fereastra(obiect)...

radoo
Junior
Junior
Posts: 18
Joined: 14 Jul 2008, 15:38
Judet: Bistriţa-Năsăud

Re: OnActivate()...

Post by radoo » 12 Jan 2009, 23:19

L-am rezolvat pana la urma, am urmarit valoarea parametrului LPARAM lp cand sunt trimise mesaje de la Tabbed Pane si cand sunt trimise de la Tab COntrolul main frame`ului si am remarcat ca are mereu aceeasi valoare pentru cele de la Tab Control'`ul main frame`ului(sper cel putin...) asa ca am pus conditie in handler`ul mesajului sa prelucreze mesajul doar daca lp are valoarea respectiva...oricum mersi pt hint`ul cu Spy++, nu stiam insa am remarcat ca nu apar mesajele AFX_WM_ACTIVATE_TAB cand urmaresc vreo fereastra sau vreun proces...

User avatar
Andreas
Membru
Membru
Posts: 117
Joined: 09 Nov 2008, 12:13
Judet: Timiş
Location: Timisoara

Re: OnActivate()...

Post by Andreas » 13 Jan 2009, 12:09

Mesajele AFX_x sunt transmise ferestrelor care sunt create de catre "extensii" ale MFC-ului, cum este si CMFCCtrlTab.
In Spy++, astfel de ferestre au prefixul "Afx:" ...

Post Reply