limbe
asked on
Can CDocument work with CDialog?
IN a SDI, my document data actually is something like record-based data, I've to prompt user to enter a few information typically in Edit Control in a model/modeless dialog, when user press OK button, the data should be save onto a file. I want to take advantages of all functionalities provided by the application framework such as New, Open, Save and Save as menu options which are handled by CWinApp and CDocument.
My question are:
1. how to achieve that with a CDialog but not a CView? Is it possible? or any solution and suggestion?
2. When user select 'New' option from File menu item, can I override OnFileNew() to call a CDialog?
3. When user select 'Open' option from File menu item, once I got the selected file name, how to load the content of the file and pass it or show it in a CDialog derived class?
4. What if when user choose 'Save' option from File menu item?
Please help. Thanks.
My question are:
1. how to achieve that with a CDialog but not a CView? Is it possible? or any solution and suggestion?
2. When user select 'New' option from File menu item, can I override OnFileNew() to call a CDialog?
3. When user select 'Open' option from File menu item, once I got the selected file name, how to load the content of the file and pass it or show it in a CDialog derived class?
4. What if when user choose 'Save' option from File menu item?
Please help. Thanks.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
In other words, I want to create additional dialog (modal or modeless) based on CFormView, if 'New' from File menu is selected, the dialog will be shown. How?
Since it is SDI and there is already a CView, forget CFormView. Use a modal or modeless dialog box. You can override CWinApp::OnFileNew, CWinApp::OnFileOpen, CDocument::OnFileClose , CDocument::OnSaveDocument, etc. You may pass the document pointer (CDocument *) to the dialog box so that it is able to access the data.
ASKER
may be I have to do this way, ok, one more question, how to pass the document pointer to a dialog box?
ASKER
the reason I want to use CFormView is because a view can be associated to a CDocument and I need to do all serialize stuff later.
class CMyDlg : public CDialog
{
public:
CMyDlg(CMyDocument *pDoc, CWnd* pParent = NULL);
CMyDocument *m_pDoc;
....
};
CMyDlg::CMyDlg(CMyDocument *pDoc, CWnd* pParent /*=NULL*/)
: CDialog(CMyDlg::IDD, pParent)
{
m_pDoc = pDoc;
}
CMyDlg dlg(pView->GetDocument(), pParent);
dlg.DoModal();
{
public:
CMyDlg(CMyDocument *pDoc, CWnd* pParent = NULL);
CMyDocument *m_pDoc;
....
};
CMyDlg::CMyDlg(CMyDocument
: CDialog(CMyDlg::IDD, pParent)
{
m_pDoc = pDoc;
}
CMyDlg dlg(pView->GetDocument(), pParent);
dlg.DoModal();
ASKER
Thanks for your prompt reply. will try and let you know.
ASKER
If I override CWinApp::OnFileNew, when the application start, it show the dialog first everytime. I don't want that, I want it only be shown if the user select 'New' from File menu. actually the Application framework call CWinApp::OnFileNew indirectly through ProcessSellCommand() when an application start and CWinApp::OnFileNew call CDocument::OnNewDocument() . Thus, call my dialog in OnNewDocument() also cause the same result.
Seems like this method is not comply with MFC's Doc/View architecture.
What is you suggestion??
Seems like this method is not comply with MFC's Doc/View architecture.
What is you suggestion??
ASKER
If I override CWinApp::OnFileNew, when the application start, it show the dialog first everytime. I don't want that, I want it only be shown if the user select 'New' from File menu. actually the Application framework call CWinApp::OnFileNew indirectly through ProcessSellCommand() when an application start and CWinApp::OnFileNew call CDocument::OnNewDocument() . Thus, call my dialog in OnNewDocument() also cause the same result.
Seems like this method is not comply with MFC's Doc/View architecture.
What is you suggestion??
Seems like this method is not comply with MFC's Doc/View architecture.
What is you suggestion??
Handle the ID_FILE_NEW command in the CView.
BEGIN_MESSAGE_MAP(CMyView, CView)
ON_COMMAND(ID_FILE_NEW, OnFileNew)
END_MESSAGE_MAP()
BEGIN_MESSAGE_MAP(CMyView,
ON_COMMAND(ID_FILE_NEW, OnFileNew)
END_MESSAGE_MAP()
ASKER
I handle it in CMainFrame because I've 3 CView, if the CView is not active the menu options is disable. Thanks.
Sorry, I still have some questions to ask as I carry on the development, but you're definitely deserve a higest grade for your answer.
Sorry, I still have some questions to ask as I carry on the development, but you're definitely deserve a higest grade for your answer.
ASKER
Why my modeless dialog always on top of my mainframe window?
What do you mean? If the parent window of the dialog box is the main window, it is always on top of it. Try using NULL as the parent window.
ASKER
I means it's always blocking the parent window, when I click the parent window, the modeless dialog still in front of the parent window although it's inactivate. The default value of 'pParent' in CDialog constructor is NULL.
MFC internally assigns the main window (AfxGetMainWnd) as the dialog box's parent window if you specify NULL because creating a dialog box without an owner is not recommended. Why do you want that behavior? It seems difficult to use for the user. The user might forget there is a window behind the main window.
ASKER
I want that because my CDialog acts as a data entry screen, if the user want to save the data, it has to either click the toolbar button at the Frame window or select the "Save/Save as..." from menu, so it's quite often user may need to access frame window, somemore the CDialog size is quite big, it's blocking most of the frame window. Is it possible to create a modeless dialog without owner?
If it's too tedious, forget about it.
If it's too tedious, forget about it.
>Is it possible to create a modeless dialog without owner?
Yes, it is possible. Take a look at the MFC source code Dlgcore.cpp. You need to duplicate the code of CDialog::Create and do not use
if (pParentWnd == NULL)
pParentWnd = AfxGetMainWnd();
Yes, it is possible. Take a look at the MFC source code Dlgcore.cpp. You need to duplicate the code of CDialog::Create and do not use
if (pParentWnd == NULL)
pParentWnd = AfxGetMainWnd();
ASKER
How to trigger an keyboard event from a modeless CDailog? I guess all WM_CHAR, WM_KEYDOWN and WM_KEYUP have been eaten by the controls on the dialog.
Set focus to the window you want to send keyboard messages to and call keybd_event.
ASKER
not really get what you mean.
You mean set focus to the dialog as below??
void CMainFrame::OnFileNewPage( )
{
CPageDlg *dlg=new CPageDlg;
dlg->Create(IDD_PAGE);
dlg->SetFocus();
}
Then from the CDialog map WM_CHAR.
void CPageDlg::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
{
TRACE("On Char %c\n",nChar);
CDialog::OnChar(nChar, nRepCnt, nFlags);
}
But it doesn't work.
You mean set focus to the dialog as below??
void CMainFrame::OnFileNewPage(
{
CPageDlg *dlg=new CPageDlg;
dlg->Create(IDD_PAGE);
dlg->SetFocus();
}
Then from the CDialog map WM_CHAR.
void CPageDlg::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
{
TRACE("On Char %c\n",nChar);
CDialog::OnChar(nChar, nRepCnt, nFlags);
}
But it doesn't work.
You missed out calling keybd_event. Why don't you just call dlg->OnChar directly?
ASKER
Sorry, I don't understand what do you mean. I don't know how to use keybd_event(), when and where to put it? And how to call dlg->OnChar() directly? How do I know which are the parameters to pass to when calling dlg->OnChar().
I've referred to on-line help but just can't get it. Sorry for my stupidity.
I've referred to on-line help but just can't get it. Sorry for my stupidity.
Whenever you want to simulate a key press, call keybd_event. It will send keyboard messages to the focus window.
The parameters of OnChar depend on which key you want.
What exactly do you want to do? There might be a more reliable way.
The parameters of OnChar depend on which key you want.
What exactly do you want to do? There might be a more reliable way.
ASKER
I think you are misunderstanding of my question. Actually I need to capture the WM_CHAR in my modeless dialog, so I map an OnChar message entry in my dialog message map, however, the OnChar() message handler will never get called because of the ::IsDialogMessage() have been processed all the messages to a dialog box, in other word, only the controls in the dialog box can receive the WM_CHAR message. Infact, I knew this habit long ago, even in VB and VFP, a WM_CHAR cannot be trigger from a Form(dialog) by default, but I'm so new to VC++ user interface design.
Anyway thanks. I've got the solution from KB Q117563.
Anyway thanks. I've got the solution from KB Q117563.
Yeah, I misunderstood your question because you said "trigger" instead of "capture".
ASKER
This is you point. you deserve it. Thanks.
ASKER
Let me describe what is my understanding as below, please show me and correct me if I'm wrong.
1. Create a view class derived from CFormView.
2. User dialog resource editor to design the content of a the dialog.
3. Set dialog perperties to Border=none, window=child, visible=false and save.
4. Map a handler for ID_FILE_NEW menu item, create the CFormView object and the how to show it???
Please help, and show me the steps or concept of doing that, I'm realy in my rush. Please don't ask me to refer to on-line help, I really have no extra time to spend.
Thanks.