Page 1 of 1

Accesare variabila membru in DialogBar

Posted: 19 Jan 2011, 18:33
by mesajflaviu
Intr-o aplicatie SDI am un dialog bar , si pentru ca vreau sa pun pe acest dialog bar altfel de controale decat butoane simple ( un edit box de exemplu ) am derivat o clasa CBarDlg , derivata din CDialogBar la care am atasat un membru variabila de tip CEdit , m_Edit , pentru a controla edit box-ul din dialog bar . Toate bune pana aici , numai ca in momentul cand accesez aceasta variabila membru din afara clasei CBarDlg , eroare ( wincore.cpp , line 3055 )

Code: Select all

class CBarDlg : public CDialogBar
{
// Construction
public:
	void DoSomething();
	CBarDlg(CWnd* pParent = NULL);   // standard constructor

// Dialog Data
	//{{AFX_DATA(CBarDlg)
	enum { IDD = IDD_DIALOG_BAR };
	CEdit	m_Edit;
	//}}AFX_DATA
...
}

Code: Select all

void CBarDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogBar::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CBarDlg)
	DDX_Control(pDX, IDC_EDIT1, m_Edit);
	//}}AFX_DATA_MAP
}

Code: Select all

void CBarDlg::DoSomething()
{
	m_Edit.SetSel(0,-1);
}
iar cand apelez metoda CBarDlg::DoSomething() din CDialogBarTestView , eroare :

Code: Select all

void CDialogBarTestView::OnHelpTest() 
{
	// TODO: Add your command handler code here

	CBarDlg dlg;
	dlg.DoSomething();
}
intrebarea este , cum se pot accesa aceste variabile membru ale dialogbar-ului ?

Am atasat si o mica aplicatie de test ...

Re: Accesare variabila membru in DialogBar

Posted: 19 Jan 2011, 23:43
by Viorel
După m_wndDlgBar.Create executată cu succes adaugă m_wndDlgBar.UpdateData(FALSE).

În interiorul funcţiei OnHelpTest accesează bara existentă:

Code: Select all

CMainFrame * f = STATIC_DOWNCAST(CMainFrame, AfxGetMainWnd());
f->m_wndDlgBar.DoSomething();
(Adaugă #include şi fă accesibil membrul m_wndDlgBar, sau creează DoSomething la nivel de CMainFrame).

Re: Accesare variabila membru in DialogBar

Posted: 20 Jan 2011, 19:13
by mesajflaviu
Viorel , m-ai salvat , imi trebuia un control intr-un dialog bar intr-un mic proiect si timpul era critic . Multumesc !

Re: Accesare variabila membru in DialogBar

Posted: 21 Jan 2011, 13:30
by Ovidiu Cucu
Sunt doar curios.
Priectelul pe care l-ai atasat + fixul lui Viorel, chiar functioneaza?

Re: Accesare variabila membru in DialogBar

Posted: 21 Jan 2011, 13:56
by mesajflaviu
Cu mici modificari , da . O sa atasez mai tarziu un nou proiect , cu modificarea facuta ... Ciudata rezolvare , nu inteleg de ce pointer-ul spre CMainFrame trebuie "aranjat" ca STATIC_DOWNCAST :?:

Re: Accesare variabila membru in DialogBar

Posted: 22 Jan 2011, 11:06
by Ovidiu Cucu
STATIC_DOWNCAST face o verificare "MFC classic-style" folosind CObject::IsKindOf. In plus vede daca nu cumva pointerul ala-i NULL.
E OK asa cum l-a folosit Viorel, nu aia era problema.
Buba e ca m_Edit din CBarDlg nu are atasata o fereastra (un control) deci vei primi acelasi assert ca si mai inainte.

Desi suna asemanator, CDialogBar NU este derivat din CDialog si nu are acea minunata functie virtuala numita OnInitDialog care se apeleaza din codul pe care-l pune wizard-ul si care are grija printre altele de initializat controalele.
Deci, ar trebui sa mapezi manual un handler pentru WM_INITDIALOG, ceva de genul:

Code: Select all

// BarDlg.h
class CBarDlg : public CDialogBar
{
//...
   afx_msg LRESULT OnInitDialog(WPARAM wParam, LPARAM lParam);
   DECLARE_MESSAGE_MAP()
};

Code: Select all

// BarDlg.cpp
// ...
   ON_MESSAGE(WM_INITDIALOG, OnInitDialog)
END_MESSAGE_MAP()

LRESULT CBarDlg::OnInitDialog(WPARAM wParam, LPARAM lParam)
{
   HandleInitDialog(wParam, lParam);
   UpdateData(FALSE);

   return 1;
}
Sper ca astea erau acele "mici modificari" la care te refereai". :)

Si doua mici observatii:
  • In general, nu-i nevoie de derivat din CDialogBar decat daca vrei sa faci cine stie ce chestii super custom.
  • Treaba unui view e sa afiseze ceva, nu sa aiba grija de barele de control; de ele se ocupa frame-ul.

Re: Accesare variabila membru in DialogBar

Posted: 22 Jan 2011, 16:18
by mesajflaviu
Desi suna asemanator, CDialogBar NU este derivat din CDialog si nu are acea minunata functie virtuala numita OnInitDialog care se apeleaza din codul pe care-l pune wizard-ul si care are grija printre altele de initializat controalele
Surpriza asta am avut-o si eu cand am incercat sa mapez OnInitDialog(...) pentru CBarDlg , dar am gasit aici rezolvarea : http://support.microsoft.com/kb/185672
Sper ca astea erau acele "mici modificari" la care te refereai".
Asa e , asta e modificarea la care ma refeream , si pe care am incercat-o de prima data , dar chiar si asa , cand incercam sa accesez controlul pe dialogbar aveam eroare .

Dar dupa solutia lui Viorel , merge si fara maparea OnInitDialog , doar apelarea metodei UpdateData(FALSE) , dupa crearea dialogbar-ului , ca in aplicatia test atasata ...

Re: Accesare variabila membru in DialogBar

Posted: 23 Jan 2011, 19:22
by cristianamarie
Poate nu inteleg eu ceva, ce e cu STATIC_DOWNCAST si restul?

Code: Select all

void CDialogBarTestView::OnHelpTest()
{
   // TODO: Add your command handler code here

   CBarDlg dlg;
   dlg.DoSomething();
}
Nu vad nici un DoModal sau Create (::DialogBox sau ::CreateDialogIndirect) sau altceva care sa treaca prin crearea controlului; editul ala e cit de poate de necreat.
Sau imi scapa mie ceva? (nu m-am uitat in surse).

Re: Accesare variabila membru in DialogBar

Posted: 23 Jan 2011, 22:02
by mesajflaviu
cristianamarie wrote:Poate nu inteleg eu ceva, ce e cu STATIC_DOWNCAST si restul?

Code: Select all

void CDialogBarTestView::OnHelpTest()
{
   // TODO: Add your command handler code here

   CBarDlg dlg;
   dlg.DoSomething();
}
Nu vad nici un DoModal sau Create (::DialogBox sau ::CreateDialogIndirect) sau altceva care sa treaca prin crearea controlului; editul ala e cit de poate de necreat.
Sau imi scapa mie ceva? (nu m-am uitat in surse).
DialogBar-ul este membru al CMainFrame-ului , si se creeaza in modul urmator :

Code: Select all

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
		return -1;

	if(! m_wndDlgBar.Create(this, IDD_DIALOG_BAR, TBSTYLE_FLAT | WS_CHILD | WS_VISIBLE | CBRS_TOP | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC, IDD_DIALOG_BAR))
	{
		TRACE0(_T("Failed to create the dialog bar\n"));
		return -1;
	}
	return 0;
}
apoi , m_wndDlgBar se ocupa si cu creearea editbox-ului ...

Re: Accesare variabila membru in DialogBar

Posted: 24 Jan 2011, 07:06
by cristianamarie

Code: Select all

  CBarDlg dlg;
  dlg.DoSomething();
Eu de variabila dlg vorbesc.

Re: Accesare variabila membru in DialogBar

Posted: 24 Jan 2011, 10:41
by mesajflaviu
Asa incercam sa ajung la dialogbar fara a mai trece prin CMainFrame ...

Code: Select all

//    CMainFrame.h
    CBarDlg m_wndDlgBar;
sa inteleg ca instanta mea

Code: Select all

CBarDlg dlg;
nu avea controlul ( editbox-ul ) creat ?

Re: Accesare variabila membru in DialogBar

Posted: 24 Jan 2011, 11:11
by Ovidiu Cucu
mesajflaviu wrote:Asa incercam sa ajung la dialogbar fara a mai trece prin CMainFrame ...

Code: Select all

//    CMainFrame.h
    CBarDlg m_wndDlgBar;
sa inteleg ca instanta mea

Code: Select all

CBarDlg dlg;
nu avea controlul ( editbox-ul ) creat ?
Nu. Nici macar nu avea creata fereastra proprie, daramite copilasii. ;)

In MFC, un obiect dintr-o clasa derivata din CWnd se creaza in doua etape:
  1. constructor - se instantiaza un obiect C++; in acest moment nu are atasata nici o fereastra iar orice incercare de a trimite un mesaj sau de a apela o functie WinAPI care implica acea fereastra va da kix. In modul DEBUG, MFC-ul arata un ASSERT pentru ca m_hWnd este NULL.
  2. o functie "create" - (poate fi CWnd::Create, CDialog::DoModal etc); in acest moment se creaza fereastra (cu ::CreateWindowEx) iar handle-ul ei este atast la acel obiect (m_hWnd se initializeaza cu HWND-ul ferestrei). Mai departe, avem fereastra si (almost) everything is OK.

Re: Accesare variabila membru in DialogBar

Posted: 24 Jan 2011, 18:04
by mesajflaviu
Intradevar , incercand sa obtin pointer la dialogbar in modul urmator :

Code: Select all

	CMainFrame* pFrame = (CMainFrame*)AfxGetMainWnd();
	pFrame->m_wndDlgBar.DoSomething();    // m_wndDlgBar este membru public
nu mai este nevoie de a folosi macro-ul STATIC_DOWNCAST , dar trebuie sa apelez

Code: Select all

UpdateData(FALSE);
imediat dupa crearea dialogbar-ului ...

Re: Accesare variabila membru in DialogBar

Posted: 25 Jan 2011, 09:23
by mesajflaviu
Se pare ca la inceput nu am obtinut corect pointerul la dialogbar , dar cu ocazia asta am invatat cateva lucruri ! Multumesc tuturor !