Accesare variabila membru in DialogBar

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

Accesare variabila membru in DialogBar

Post by mesajflaviu » 19 Jan 2011, 18:33

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 ...
Attachments
DialogBarTest.rar
(44.77 KiB) Downloaded 284 times



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

Re: Accesare variabila membru in DialogBar

Post by Viorel » 19 Jan 2011, 23:43

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

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

Re: Accesare variabila membru in DialogBar

Post by mesajflaviu » 20 Jan 2011, 19:13

Viorel , m-ai salvat , imi trebuia un control intr-un dialog bar intr-un mic proiect si timpul era critic . Multumesc !

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

Re: Accesare variabila membru in DialogBar

Post by Ovidiu Cucu » 21 Jan 2011, 13:30

Sunt doar curios.
Priectelul pe care l-ai atasat + fixul lui Viorel, chiar functioneaza?

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

Re: Accesare variabila membru in DialogBar

Post by mesajflaviu » 21 Jan 2011, 13:56

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 :?:

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

Re: Accesare variabila membru in DialogBar

Post by Ovidiu Cucu » 22 Jan 2011, 11:06

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.

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

Re: Accesare variabila membru in DialogBar

Post by mesajflaviu » 22 Jan 2011, 16:18

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 ...
Attachments
DialogBarTest.rar
(47.33 KiB) Downloaded 276 times

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

Re: Accesare variabila membru in DialogBar

Post by cristianamarie » 23 Jan 2011, 19:22

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).
Nuclear launch detected

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

Re: Accesare variabila membru in DialogBar

Post by mesajflaviu » 23 Jan 2011, 22:02

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

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

Re: Accesare variabila membru in DialogBar

Post by cristianamarie » 24 Jan 2011, 07:06

Code: Select all

  CBarDlg dlg;
  dlg.DoSomething();
Eu de variabila dlg vorbesc.
Nuclear launch detected

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

Re: Accesare variabila membru in DialogBar

Post by mesajflaviu » 24 Jan 2011, 10:41

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 ?

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

Re: Accesare variabila membru in DialogBar

Post by Ovidiu Cucu » 24 Jan 2011, 11:11

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.

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

Re: Accesare variabila membru in DialogBar

Post by mesajflaviu » 24 Jan 2011, 18:04

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

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

Re: Accesare variabila membru in DialogBar

Post by mesajflaviu » 25 Jan 2011, 09:23

Se pare ca la inceput nu am obtinut corect pointerul la dialogbar , dar cu ocazia asta am invatat cateva lucruri ! Multumesc tuturor !

Post Reply