-
May 11th, 2008, 05:45 PM
#1
What to do when OnInitDialog fail
Hi guys,
Sorry for the newbie question...
I dynamiclly allocate memory in OnInitDialog and I check if it failed using try & catch.
My question is what should I do when the it fails??
currently I am using:
Code:
try
{
int *pNum = int;
}
catch (std::bad_alloc&)
{
EndDialog(0);
return FALSE:
}
..
..
..
More code
..
..
..
Is that the right way to do it??
Many thanks
-
May 12th, 2008, 01:57 AM
#2
Re: What to do when OnInitDialog fail
What is this supposed to do ?
-
May 12th, 2008, 06:10 AM
#3
Re: What to do when OnInitDialog fail
You could use EndDialog(...) and return a value that indicates error to the caller.
If you want to terminate the app, ExitProcess(...) or TerminateProcess(GetCurrentProcess(),...) can be used.
Nobody cares how it works as long as it works
-
May 12th, 2008, 12:47 PM
#4
Re: What to do when OnInitDialog fail
OnInitDialog is not the place where you can control if the dialog is to be displayed or not. You do this kind of stuff in constructor, or in other member function. Depending on CTOR or method's return value, you decide whether or not to display the dialog box.
-
April 23rd, 2010, 10:02 AM
#5
Re: What to do when OnInitDialog fail
Problem for me is im adding items to a ListControl from a database, so cannot do this in constructor as listcontrol windows not created yet, seems these are created once OnInitDialog is called, but i can then have a database failure while populating the list in which case need to abort creation of dialog and inform the caller?
How best to acheive this?
Thanks.
-
April 23rd, 2010, 10:11 AM
#6
Re: What to do when OnInitDialog fail
You should show your dialog with something that gives idea the data is loading, and run data-fetching worker thread communicating with your dialog. Then you're able to normally process any incidents with your connection and data as well as notify user about any.
Best regards,
Igor
-
April 23rd, 2010, 10:25 AM
#7
Re: What to do when OnInitDialog fail
Originally Posted by Igor Vartanov
You should show your dialog with something that gives idea the data is loading, and run data-fetching worker thread communicating with your dialog. Then you're able to normally process any incidents with your connection and data as well as notify user about any.
Thats too much solution for me, dont want to introduce threads for something so trivial. Its only a small list, under normal circumstances they would never see the progress message. Even with a worker thread would still have the same problem.
I cannot add items to the listcontrol at least until OnInitDialog is called which is called from. DoModal().
-
April 23rd, 2010, 10:31 AM
#8
Re: What to do when OnInitDialog fail
...and this never means you're not able to fetch the data (especially such a short list) before calling DoModal().
Best regards,
Igor
-
April 23rd, 2010, 10:38 AM
#9
Re: What to do when OnInitDialog fail
Originally Posted by Igor Vartanov
...and this never means you're not able to fetch the data (especially such a short list) before calling DoModal().
Yes i could have done that, but again seems like extra work, more thinking of the general case. potentially in another scenario could be a larger list, which would mean having to create a structure to hold the recordset row items, store these in an array then pass array to dialog and then delete memory when finished.
If there is no way to get round this problem then thats what i would have to do, but finding hard to believe that given something does not goto plan in OnInitDialog that there is not a way to close the dialog down and for it to return IDCANCEL to caller?
-
April 23rd, 2010, 12:32 PM
#10
Re: What to do when OnInitDialog fail
that there is not a way to close the dialog down and for it to return IDCANCEL to caller?
Ain't EndDialog mentioned here? For MFC solution it looks like CDialog::OnCancel.
Best regards,
Igor
-
April 23rd, 2010, 04:00 PM
#11
Re: What to do when OnInitDialog fail
Originally Posted by PRMARJORAM
Problem for me is im adding items to a ListControl from a database, so cannot do this in constructor as listcontrol windows not created yet
Then stop using GUI and window controls to do this work.
You shouldn't go from the database straight to a GUI component. You should store the database information in an internal C++ structure (tree, map, a dynamic array, whatever) on construction of the dialog. Once you are satisfied that the data has been loaded in this structure, then you know your dialog can be displayed and then you load your list box in the OnInitDialog() call. If any exception were to occur, it would be on construction of the dialog before any GUI is shown, and it would be obvious as to how to handle such an error.
Code:
class CMyDialog : public CDialog
{
//...
bool LoadFromDB()
{
// open the DB, and load the information into a vector, map, CMap, CList, std::list, whatever you desire
}
};
// Your OnInitDialog handler just takes the info from the data structure and loads the list constrol
// and here is how you would use this...
CMyDialog MyDialog;
bool isLoaded = MyDialog.LoadFromDB(); // No GUI is shown. The only thing done here is loading the DB into an internal structure
if ( isLoaded )
MyDialog.DoModal();
else
{
// error
}
The big mistake that a lot of programmers make is that they use GUI controls to store their data or code their essential business logic within a GUI component. When it comes time to turn their program into a console app or an app with no GUI, they have to rip out all of that code they've shoved into "button clicks" and list boxes and rework their design. I've seen this with a lot of apps, and it is a horrible approach to have your app rely on a GUI control for storage or essential logic.
Regards,
Paul McKenzie
Last edited by Paul McKenzie; April 24th, 2010 at 01:22 AM.
-
April 26th, 2010, 03:19 AM
#12
Re: What to do when OnInitDialog fail
Originally Posted by Paul McKenzie
Then stop using GUI and window controls to do this work.
You shouldn't go from the database straight to a GUI component. You should store the database information in an internal C++ structure (tree, map, a dynamic array, whatever) on construction of the dialog. Once you are satisfied that the data has been loaded in this structure, then you know your dialog can be displayed and then you load your list box in the OnInitDialog() call. If any exception were to occur, it would be on construction of the dialog before any GUI is shown, and it would be obvious as to how to handle such an error.
Code:
class CMyDialog : public CDialog
{
//...
bool LoadFromDB()
{
// open the DB, and load the information into a vector, map, CMap, CList, std::list, whatever you desire
}
};
// Your OnInitDialog handler just takes the info from the data structure and loads the list constrol
// and here is how you would use this...
CMyDialog MyDialog;
bool isLoaded = MyDialog.LoadFromDB(); // No GUI is shown. The only thing done here is loading the DB into an internal structure
if ( isLoaded )
MyDialog.DoModal();
else
{
// error
}
The big mistake that a lot of programmers make is that they use GUI controls to store their data or code their essential business logic within a GUI component. When it comes time to turn their program into a console app or an app with no GUI, they have to rip out all of that code they've shoved into "button clicks" and list boxes and rework their design. I've seen this with a lot of apps, and it is a horrible approach to have your app rely on a GUI control for storage or essential logic.
Regards,
Paul McKenzie
I totally agree with what your saying and where it matters this is exactly how iv done it, all data access is via DAO interface or ABC.
Its just in this instance it was not really necessary to do so as not shared or used anywhere else and would have been making a meal of things.
But its fine to call OnCancel within OnInitDialog if things dont go to plan.
BOOL CDialogControlDB::OnInitDialog()
{
CDialog::OnInitDialog();
mList.InsertColumn(0, CString("Name"),LVCFMT_LEFT, 120);
if( InitList() == false )
OnCancel();
return TRUE;
}
bool CDialogControlDB::InitList()
{
try{
CRecordsetDBLIST rs(CDBHolder::GetDB());
rs.Open();
while (!rs.IsEOF())
{
mList.InsertItem(0,rs.m_DBName);
rs.MoveNext();
}
rs.Close();
return true;
}catch( CException* e ){
e->ReportError();
return false;
}
}
Thanks, didnt realise it was valid to call OnCancel within OnInitDialog, for those instances within OnInitDialog you need to be quick and direct. But yes it would be better as a DAO, if this data was being used anywhere else then i would have done it that way.
-
April 26th, 2010, 03:34 AM
#13
Re: What to do when OnInitDialog fail
Originally Posted by PRMARJORAM
... Thanks, didnt realise it was valid to call OnCancel within OnInitDialog, ...
Yes, it is valid assuming that:
Code:
void CDialog::OnCancel()
{
EndDialog(IDCANCEL);
}
and according to MSDN:
CDialog::EndDialog
void EndDialog( int nResult );
Parameters
nResult
Contains the value to be returned from the dialog box to the caller of DoModal.
Remarks
Call this member function to terminate a modal dialog box. This member function returns nResult as the return value of DoModal. You must use the EndDialog function to complete processing whenever a modal dialog box is created.
You can call EndDialog at any time, even in OnInitDialog, in which case you should close the dialog box before it is shown or before the input focus is set.
Victor Nijegorodov
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|