Link to home
Start Free TrialLog in
Avatar of limbe
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.
ASKER CERTIFIED SOLUTION
Avatar of chensu
chensu
Flag of Canada image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of limbe
limbe

ASKER

Yes you're right, but how to implement it? I'm not creating a new project now. I want a form or a dialog-like window to be shown when user select 'New' or 'Open' from the File item menu.  My application is SDI based, all my main frame client area have been occupied by other CView.

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.
Avatar of limbe

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.
Avatar of limbe

ASKER

may be I have to do this way, ok, one more question, how to pass the document pointer to a dialog box?
Avatar of limbe

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();
Avatar of limbe

ASKER

Thanks for your prompt reply. will try and let you know.
Avatar of limbe

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??
Avatar of limbe

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??
Handle the ID_FILE_NEW command in the CView.

BEGIN_MESSAGE_MAP(CMyView, CView)
    ON_COMMAND(ID_FILE_NEW, OnFileNew)
END_MESSAGE_MAP()
Avatar of limbe

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.
Avatar of limbe

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.
Avatar of limbe

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.
Avatar of limbe

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.
>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();
Avatar of limbe

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.
Avatar of limbe

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 missed out calling keybd_event. Why don't you just call dlg->OnChar directly?
Avatar of limbe

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.
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.
Avatar of limbe

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.
Yeah, I misunderstood your question because you said "trigger" instead of "capture".
Avatar of limbe

ASKER

This is you point. you deserve it. Thanks.