• Advertisement
Sign in to follow this  

MFC : 2 dialogs : PLEASE help me!

This topic is 4737 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello, I really need help on this problem : I'm trying to make a database program : On my main window I can already view/edit/add/change my records, but now I'm trying to create a second Dialog box on which I can also access my records. I already created a new Dialog resource and derived this one from the class CRecordView. But how can I open that dialog box in my program via a button? In a tutorial I read that I need to use the following code : CMyWnd *MyWnd = new CMyWnd() ; myWnd->CreateEx(WS_EX_TOPMOST, strWndClass, "venster naam", WS_OVERLAPPED|WS_CAPTION|WS_THICKFRAME, CRect(100, 100, 200, 200), NULL, 0) ; MyWnd->ShowWindow(SW_SHOWNORMAL) ; MyWnd->UpdateWindow() ; But I'm still left with some questions : 1) CMyWnd, which class is this? Is this the class of my new dialog box? 2) strWndClass, which string is this? according to msdn, I need to get this string via the function AfxRegisterWndClass(), but how do I do this? Thanx in advance for any1 that can help me out here!

Share this post


Link to post
Share on other sites
Advertisement
Guest Anonymous Poster
it really depends on what you want. do you want a modal dialog (takes control of app until dismissed) or modeless (sits happily in another window alongside main app).

also CRecordView is a view not a dialog. so just create a normal dialog class (derived from CDialog) and add a list control (or whatever) to display your records. let's call this dialog class CRecordListyThingDlg...

so for modal (the easy one)
in your button handler code for the main window

void CWhatever::OnClickedShowListyThing()
{
CRecordListyThingDlg dlg;

// this line displays the dialog and will wait here until you close it
if (dlg.DoModal() == IDOK)
{
// user has finished with dialog, do something useful
}
}



or modeless (slightly harder)
need more code, first in main window class declaration

// Whatever.h

class CWhatever
{
// constructors/methods and so on

private:
CRecordListyThingDlg *m_pListyThingDlg;
};



and in the implementation

//Whatever.cpp

BOOL CWhatever::OnInitDialog()
{
// initialisation stuff

// create the dialog but don't show it
m_pDlg = new CRecordListyThingDlg(this);
m_pDlg->Create(IDD_LISTY_DLG, this);
}

void CWhatever::OnClickedShowListyThing()
{
m_pDlg->ShowWindow(SW_SHOW);
m_pDlg->BringWindowToTop();
}

// make sure to clean up
void CWhatever::~CWhatever()
{
delete m_pDlg;
}



hope that helps


Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Use QT [grin]

http://www.trolltech.com/products/qt/index.html

Share this post


Link to post
Share on other sites
Quote:
Original post by Anonymous Poster
Use QT [grin]

http://www.trolltech.com/products/qt/index.html


wow that's helpful... the OP should abandon all the work he's done and switch to a new GUI. good idea!

Share this post


Link to post
Share on other sites
well, my problem is, if I make a normal CDialog based dialog, I can't access my database anymore on that second dialog!
So if you know how I can access my database again in that second Dialog, I would be easier for me.

Share this post


Link to post
Share on other sites
Quote:
Original post by da_cobra
well, my problem is, if I make a normal CDialog based dialog, I can't access my database anymore on that second dialog!
So if you know how I can access my database again in that second Dialog, I would be easier for me.


The way I got around this problem is by having a global variable defined for the base dialog. Then you can access the data anywhere you want to. To do this, you will need to do a few things. I'll try to explain for now, but if you need code segments, I can put something together later, it's late now.

What you want to do is make an 'extern yourdialog *variable' in the .h file. In the new second dialog class, you will want to include that .h file, so you now have access to that variable. This is how you can access all the data. However, you will need to assign the pointer to the class in your main dialogs, init function, where it says to "Add additional initialization code". You can simply do variable = this; and be done. That's about it.

One thing to keep in mind is that the data you are accessing should be public - that is if you do not want to make a lot of Get/Set functions...

- Drew

Share this post


Link to post
Share on other sites
Quote:
Original post by Drew_Benton
Quote:
Original post by da_cobra
well, my problem is, if I make a normal CDialog based dialog, I can't access my database anymore on that second dialog!
So if you know how I can access my database again in that second Dialog, I would be easier for me.


The way I got around this problem is by having a global variable defined for the base dialog. Then you can access the data anywhere you want to. that is if you do not want to make a lot of Get/Set functions...


No offense, but IMO, that is not the best way to do it. Simply pass a reference or a pointer to your DB object when creating the new dialog. As for making everything public, I won't go into that, but there are any number of references which will tell you why this isn't the best idea.

To access the DB from your new dialog do this

// NewDialog.h

class CNewDialog : public CDialog
{
CNewDialog(const CYourDBClass& db)
// dialog stuff

private:
// make it const if you only want to display data
const CYourDBClass& m_db;
}

// NewDialog.cpp

CNewDialog::CNewDialog(const CYourDBClass& db)
: m_db(db)
{

}



m_db now refers to your db object without having to resort to a global and all the potential bugs that entails.



Share this post


Link to post
Share on other sites
ok, thx for the help, I'll try that last solution first tonight and I will keep you guys updated on if it works or not

Share this post


Link to post
Share on other sites
ok, so this is what I tried now :

- created a new project : single document, database view with file support and then I chose my datasource and table
- all the other stuff I kept default

So now I had 1 dialog, I placed an edit control on it and set the variable to m_pSet->m_Bouwjaar
I ran it and voila database is working.

Now to get that second dialog working :

First : Insert->Resource->Dialog
Then I changed the ID to IDD_DIALOG2
Right mouse button->ClassWizard
Now I get the question to add a new class for my new dialog :
So : new class -> class name : CDialog2
Base class : CDialog
Dialog ID : IDD_DIALOG2
OK and OK again

So now I have my second Dialog

Now I placed a new button on the main dialog and named it "Open Dialog2"
Double clicked on it : New member function : "OnButtonOpenDialog2", OK

Now, entering the following code :


CDialog2 dlg2 ;
HRESULT hresult = dlg2.DoModal() ;






and offcourse adding #include "Dialog2.h" on top of my 2DialogsView.cpp (main dialog, source file)

compile + run = everything OK, Pressing the button shows my second Dialog
Also in my editbox on my main dialog I get the value of the first record.

But now to get my database working on my second dialog!
So this is what I did :

first of all I added this line as a public member in my class CDialog2 :

CDialog2(const CMy2DialogsSet& db) ; // CMy2DialogSet is the database, right?

secondly I added the next line also in the private section of my class :

const CMy2DialogsSet& m_db;

and then in my CDialog2.cpp

CDialog2::CDialog2(const CMy2DialogsSet& db)
: m_db(db)
{

}

Now first changing
CDialog2 dlg2 ;

to

CDialog2 dlg2(*m_pSet) ;

Compiling now : 8 errors

I forgot to include the header file, so I #include "CMy2DialogsSet.h" on top of the CDialog2.h

compiling : 1 error :
error C2758: 'm_db' : must be initialized in constructor base/member initializer list
And pointed to my original constructor.

uhhhhh, what the hell?

Still doesn't work :(

I also tried setting an editbox on my second Dialog and tried to assign the variable m_db->m_Bouwjaar to it but I get the error : "invalid symbol "m_db->m_Bouwjaar" specified" :(

I hope you take the time to read this and I also hope that you can help me!

thanx in advance

[Edited by - da_cobra on March 2, 2005 12:54:29 PM]

Share this post


Link to post
Share on other sites
ok that's a pretty simple error. a reference must be initialised on creation, i.e.

int x =0;
int y = 1;
int& xRef = x; // xRef now refers to x
int& yRef; // ERROR!! can't create reference without initialisation


so, if I understand you correctly, in your dialog class you now have 2 constructors


//dialog2.h
class CDialog2 : public CDialog
{
CDialog2(void);
CDialog2(const CMy2DialogsSet& db);
};

// dialog2.cpp
CDialog2::CDialog2(void)
// eek, no reference initialisation
{
//arrgh, compiler not happy...
}

CDialog2::CDialog2(const CMy2DialogsSet& db)
: m_db(db) // all cool reference is initialised
{
}


my advice is to delete your default constructor, as it's not necessary. this will prevent you from creating CDialog2 objects in a bad state (with no m_db).

I suggest you read up on references.
If you you plan to continue developing in C++ you will see them frequently. Good luck.

Share this post


Link to post
Share on other sites
thanx for the info :D
If I'm correct I tried to delete that first constructor yesterday, but I still got some errors, but since I'm at work right now I can't say what the errors were.
So I'll post again tonight!

Share this post


Link to post
Share on other sites
ok, I tried deleting the first original constructor and my code compiled fine, but then when I ran my application and pressed the button to display my second Dialog I've got a "debug assertion failed" error :(

Program : 2Dialogs.exe
file : dlgcore.cpp
line : 497

aarrgggg, I really need to solve this problem, pls help me...

This is the code within dlgcore.cpp


int CDialog::DoModal()
{
// can be constructed with a resource template or InitModalIndirect
ASSERT(m_lpszTemplateName != NULL || m_hDialogTemplate != NULL ||
m_lpDialogTemplate != NULL);

// load resource as necessary
LPCDLGTEMPLATE lpDialogTemplate = m_lpDialogTemplate;
HGLOBAL hDialogTemplate = m_hDialogTemplate;
HINSTANCE hInst = AfxGetResourceHandle();
if (m_lpszTemplateName != NULL)
{
hInst = AfxFindResourceHandle(m_lpszTemplateName, RT_DIALOG);
HRSRC hResource = ::FindResource(hInst, m_lpszTemplateName, RT_DIALOG);
hDialogTemplate = LoadResource(hInst, hResource);
}




and the error is on the first ASSERT() line

Share this post


Link to post
Share on other sites
there is something new that I found out today :

In the ClassWizard, on the last tab (Class Info), I can enter a Foreign Class : "CMy2DialogsSet" (= my recordset, right?)

If I do this I can choose my record members when I declare a variable for an edit box!

but if I compile, I get an "assert error" again :'(

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement