Cum accesez m_wndStatusBar din CDocument ?

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

Cum accesez m_wndStatusBar din CDocument ?

Post by mesajflaviu » 16 Feb 2009, 21:50

Buna . As vrea sa va intreb ceva : Cum as putea accesa variabila membru privata a clasei CMainFrame m_wndStatusBar din clasa CMyDoc ( derivata din CDocument ) intr-o aplicatie MDI ? Fiind variabila membru privata nu o pot accesa obisnuit prin pointerul m_pMainWnd .....



User avatar
Silviu Ardelean
Senior
Senior
Posts: 1175
Joined: 12 Jul 2007, 09:22
Judet: Timiş
Location: Timisoara
Contact:

Re: Cum accesez m_wndStatusBar din CDocument ?

Post by Silviu Ardelean » 16 Feb 2009, 22:09

Din moment ce un atribut este privat, nu poti avea acces la el in nici un mod... decat prin intermediul unor metode publice genul SetX(), GetX().
In alta ordine de idei, din cate stiu, un astfel de atribut CStatusBar m_wndStatusBar; e protected si poate fi accesat direct din clase derivate.

Totusi, de ce vrei sa accesezi acest atribut privat din clasa Document?

User avatar
Marius Bancila
Fondator
Fondator
Posts: 2344
Joined: 11 Jul 2007, 11:45
Judet: Timiş
Location: Timisoara
Contact:

Re: Cum accesez m_wndStatusBar din CDocument ?

Post by Marius Bancila » 16 Feb 2009, 23:45

mesajflaviu wrote:Buna . As vrea sa va intreb ceva : Cum as putea accesa variabila membru privata a clasei CMainFrame m_wndStatusBar din clasa CMyDoc ( derivata din CDocument ) intr-o aplicatie MDI ? Fiind variabila membru privata nu o pot accesa obisnuit prin pointerul m_pMainWnd .....
Pai iti faci o metoda GetStatusBar() care returneaza un pointer/referinta la acel obiect.
Marius Bancila
Fondator Codexpert, Microsoft MVP VC++
Site personal | Blog

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

Re: Cum accesez m_wndStatusBar din CDocument ?

Post by Viorel » 17 Feb 2009, 09:57

Pentru a accesa bara de stare în scopul setării textui, foloseşte funcţia SetMessageText. Un pointer spre fereastra principală poate fi obţinut şi cu GetParentFrame.

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

Re: Cum accesez m_wndStatusBar din CDocument ?

Post by Andreas » 17 Feb 2009, 18:43

Problema ta are o rezolvare asemanatoare cu ce am prezentat in:[MFC] Cum schimb date cu un dialog modal?

adica

in cpp-ul mainframe-ului declari o variabila globala :

Code: Select all

extern CMainFrame* pAppMainFrame=NULL;
careia ii atribui pointerul this in constructor:

Code: Select all

CMainFrame::CMainFrame()
{
	// TODO: add member initialization code here
	pAppMainFrame=this;
}
in cpp-ul clasei document declari aceiasi variabila globala fara valoare(este una si aceiasi cu cea de mai sus):

Code: Select all

extern CMainFrame* pAppMainFrame;
fara sa uiti header-ul corespunzator clasei mainframe.

Si de aici totul este evident. Sa zicem ca vrem sa accesam status bar-ul in handler-ul OnNewDocument:

Code: Select all

BOOL CMDITestDoc::OnNewDocument()
{
	if (!CDocument::OnNewDocument())
		return FALSE;

	// TODO: add reinitialization code here
	// (SDI documents will reuse this document)
	CStatusBarCtrl& statusBarWnd=pAppMainFrame->m_wndStatusBar.GetStatusBarCtrl();//asa poti accesa status barul ca pe o fereastra
	statusBarWnd.SetBkColor(RGB(255,0,0));

	return TRUE;
}
Succes!

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

Re: Cum accesez m_wndStatusBar din CDocument ?

Post by Andreas » 17 Feb 2009, 18:47

Am uitat ceva: am facut m_wndStatusBar "public" in clasa main frame.
Altfel, si asa se recomanda, cum s-a mai scris, trebuie sa iti definesti metodele de acces la wndStatusBar ca data privata.

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

Re: Cum accesez m_wndStatusBar din CDocument ?

Post by mesajflaviu » 18 Feb 2009, 17:10

Totusi, de ce vrei sa accesezi acest atribut privat din clasa Document?
As vrea sa afisez ceva in aceasta bara de stare in momentul deschiderii unui document ( de tip text de exemplu )

Am incercat prima solutie , mi-am definit o metoda a clasei CMainFrame prin care sa am acces la m_wndStatusBar :

Code: Select all

CStatusBar* CMainFrame::GetStatusBar()
{
	return &m_wndStatusBar;
}
iar cand incerc s-o apelez din CMyDoc imi zice ca aceasta metoda nu face parte din clasa CWnd ....('GetStatusBar' : is not a member of 'CWnd') , de ce ?

User avatar
crystyce
Junior
Junior
Posts: 38
Joined: 26 Jul 2007, 22:24
Location: Bucuresti
Contact:

Re: Cum accesez m_wndStatusBar din CDocument ?

Post by crystyce » 18 Feb 2009, 18:04

Trebuie sa faci asa :

Code: Select all

((CMainFrame*)AfxGetMainWnd())->GetStatusBar();

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

Re: Cum accesez m_wndStatusBar din CDocument ?

Post by mesajflaviu » 20 Feb 2009, 10:54

Multumesc pentru raspunsuri , am inteles ce am gresit .... ( sau asa cred eu :biggrin: )

User avatar
cristianamarie
Membru++
Membru++
Posts: 480
Joined: 12 Mar 2009, 18:47
Judet: Iaşi
Location: Iasi

Re: Cum accesez m_wndStatusBar din CDocument ?

Post by cristianamarie » 12 Mar 2009, 19:00

Daca CMainFrame al tau e derivat din CFrameWnd:
CFrameWnd::GetMessageBar
Call this member function to get a pointer to the status bar.
(In cazul MDI, CMDIFrameWnd e si el derivat tot din CFrameWnd).

CDocument::GetNextView --> CView; CView::GetParentFrame --> si ai frame-ul.
Mai pe larg, pentru relatiile dintre ele: "Relationships Among MFC Objects".

Gaining Access to Other Objects in Your Application
From object How to access other objects
Document
  • Use GetFirstViewPosition and GetNextView to access the document's view list.
    Call GetDocTemplate to get the document template.

View
  • Call GetDocument to get the document.
    Call GetParentFrame to get the frame window.

Document frame window
  • Call GetActiveView to get the current view.
    Call GetActiveDocument to get the document attached to the current view.

MDI frame window
  • Call MDIGetActive to get the currently active CMDIChildWnd.


Nuclear launch detected

User avatar
Silviu Ardelean
Senior
Senior
Posts: 1175
Joined: 12 Jul 2007, 09:22
Judet: Timiş
Location: Timisoara
Contact:

Re: Cum accesez m_wndStatusBar din CDocument ?

Post by Silviu Ardelean » 13 Mar 2009, 00:01

Desi cred ca e cam tarziu pentru mesajflaviu, o referinta mai completa si precisa la cele spuse de cristianamarie se gaseste la: http://www.codeguru.com/forum/showthread.php?t=281430

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

Re: Cum accesez m_wndStatusBar din CDocument ?

Post by mesajflaviu » 13 Mar 2009, 10:01

Silviu Ardelean wrote:Desi cred ca e cam tarziu pentru mesajflaviu, o referinta mai completa si precisa la cele spuse de cristianamarie se gaseste la: http://www.codeguru.com/forum/showthread.php?t=281430
Nu e niciodata tarziu sa invat lucruri noi , acum am o imagine mai clara a problemei .

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

Re: Cum accesez m_wndStatusBar din CDocument ?

Post by Andreas » 13 Mar 2009, 11:40

cristianamarie wrote:

Daca CMainFrame al tau e derivat din CFrameWnd:
CFrameWnd::GetMessageBar
Call this member function to get a pointer to the status bar.
(In cazul MDI, CMDIFrameWnd e si el derivat tot din CFrameWnd).

CDocument::GetNextView --> CView; CView::GetParentFrame --> si ai frame-ul.
Mai pe larg, pentru relatiile dintre ele: "Relationships Among MFC Objects".
Ce spui tu nu merge! E mai bine sa testam inainte sa postam, atunci cand ne sta la indemana. Cand timpul sau complexitatea problemei nu ne permite, sunt bine venite orice sugestie. Dar aici nu era cazul.
Cum se poate verifica si in link-ul dat de Silviu, CView::GetParentFrame duce la frame-ul ferestrei copil.
Ca sa mearga trebuie folosit CView::GetParentOwner. Ceva de genul

Code: Select all

POSITION first=this->GetFirstViewPosition();
CView* pView=this->GetNextView(first);
CWnd* pMainWnd=pView->GetParentOwner();	
CStatusBar* pStatusBar=((CMainFrame*)pMainWnd->GetStatusBar();
CStatusBarCtrl& statusBarWnd=pStatusBar->GetStatusBarCtrl();
statusBarWnd.SetBkColor(RGB(255,0,0));
dar ai trei linii de cod in plus. Cred ca solutia data de crystyce este cea mai buna, si arata clar cum un pointer la clasa de baza se poate converti("cast") la pointerul oricarei clase derivate.

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

Re: Cum accesez m_wndStatusBar din CDocument ?

Post by mesajflaviu » 12 May 2009, 08:54

Ok , am facut o metoda clasei CMainFrame , publica :

Code: Select all

void CMainFrame::SetStatusBarMessage(CString sMessage)
{
	if(sMessage.IsEmpty())
		return;
	
	m_wndStatusBar.SetPaneText(0,sMessage);
}
pe care o accesez de oriunde din aplicatie pentru a afisa ceva in StatusBar ...
pana aici totul bine . La serializare , in clasa MyDoc , la salvarea
documentului , criptez textul editat , iar aici apelez metoda
SetStatusBarMessage din CMainFrame :

Code: Select all


CMainFrame* pMainFrame = (CMainFrame*)AfxGetMainWnd();
if(pMainFrame == NULL) return;

	if (ar.IsStoring())
	{
		// TODO: add storing code here
		if(criptarea s-a efectuat cu succes)
			pMainFrame->SetStatusBarMessage("Criptare reusita !!");
		else
			pMainFrame->SetStatusBarMessage("Atentie ! Criptare esuata !");
	}
	else
	{
		// TODO: add loading code here

		if(decriptarea s-a efectuat cu succes)
			pMainFrame->SetStatusBarMessage("Decriptare reusita !!");
		else
			pMainFrame->SetStatusBarMessage("Atentie ! Decriptare esuata !!");
	}
Problema e ca la decriptare nu imi afiseaza mesajul in StatusBar, ci un mesaj dat de
framework : 'Ready' .... de ce ?

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

Re: Cum accesez m_wndStatusBar din CDocument ?

Post by Ovidiu Cucu » 12 May 2009, 09:50

mesajflaviu wrote: 'Ready' .... de ce ?
Pentru ca framwork-ul SDI/MDI foloseste primul pane al statusbar-ului ca sa afiseze ceva informatii in primul rand despre meniul selectat la un moment dat.
Daca te uiti la stringurile din resurse, vei vedea stringuri cu acelasi ID ca si unele item-uri din menu, de exemplu "Create a new document\nNew". Partea din stanga lui \n se afiseaza in statusbar atunci cand se selecteaza meniul "New". Partea din dreapta o foloseste pentru tooltip-uri la toolbar.
Atunci cand nu am nici un meniu selectat scrie in statusbar un mesaj de "idle" avand ID-ul AFX_IDS_IDLEMESSAGE (vezi in <afxres.h>).
Ai putea carpi problema suprascriind functia virtuala CMainFrame::GetMessageString:

Code: Select all

void CMainFrame::GetMessageString(UINT nID, CString& rMessage) const
{
   if(AFX_IDS_IDLEMESSAGE != nID) // do not display "Ready"!
   {
      CFrameWnd::GetMessageString(nID, rMessage);
   }
}
Ca veni vorba. Un pic mai elegant decat sa-ti implementezi in clasa frame-ului o metoda publica pentru pus textul in statusbar, ar fi sa-i trimiti mesajul WM_SETMESSAGESTRING (acesta este un mesaj MFC-specific, definit in <afxpriv.h>
Exemplu

Code: Select all

#include <afxpriv.h>
// ...
   AfxGetMainWnd()->SendMessage(WM_SETMESSAGESTRING, 0, (LPARAM)_T("Ala bala portocala"));
Si un sfat. Lasa primul pane (0) pentru framework si scrie in urmatorul (in cazul asta da,... ar merge o metoda in CMainFrame).

Post Reply