Advertisement

MFC & Dialog Question

Started by September 25, 2000 09:19 PM
7 comments, last by Shannon Barber 24 years, 3 months ago
First, please no flak about using MFC, I just have a simple question: I made a simple MFC dialog based app, I got a picture object on the screen and use it for my directx rendering, I got some progress bars and a list box & an edit box for chatting (thats the plan any away). The problem is, everytime I hit enter or esc the dialog closes, just like its designed too How can I prevent this? I tried over taking the winproc and ignoring wm_close msg''s unless I was good and ready to close. Alt-F4, and selecting close from the menu bar don''t close my app. But enter and esc still do Is there some simple setting somewhere I can set to alter this behavior?
- The trade-off between price and quality does not exist in Japan. Rather, the idea that high quality brings on cost reduction is widely accepted.-- Tajima & Matsubara
Two thoughts.
Here''s the first: are you using a modal dialog box? The code that M$ VC++ 6.0 generates uses the function DoModal() (creating a modal dialog box) as a default when you create a dialog based program, so I assume so. The thing with modal dialog boxes is, when one is open, it automatically has the focus, and no other windows can be accessed until the box is dismissed (that''s what makes it modal ) That sounds sort of like the problem you''re having. If you used the member function Create() rather than DoModal() you could make a mode-less dialog box and maybe get away from that behavior.

Here''s the second thought:
I know less about this, but it should be possible to override the default message handlers that come pre-packaged with the CDialog class. This would require mucking around with the VC++ generated code though.

Wait, just had a third thought while in process of writing this.
A little while ago I was working on getting a desktop window application up and running with dialog support, so I created a dialog-based project, then added in my own WinMain() and WinProc() for my window. Problem was, Whenever I hit OK or Cancel on the dialog the whole damn program closed. arrgh, sound familiar? Here''s a snippet from my WinProc() :
case WM_COMMAND:		switch(LOWORD(wparam))		{		case ID_FILE_NEW:			{			DoNewMapDialog = TRUE;						}break;						case ID_FILE_EXIT:			{			PostQuitMessage(0);			return(0);			}break;														default: break;			}  

With this WinProc(), my program closed every time I closed my dialog. Oddly enough, the solution came about as one of those things where you''re just dickering with the code and something useful comes out. Specifically I inserted a return(0) statement in the bottom of case ID_FILE_NEW, and presto it worked. Don''t know why (or even what the heck it was returning to, not Windows surely since the program isn''t exiting) but it did.
Well, three thoughts for the price of two; hope somewhere in there was something useful.
Advertisement
The box closes because that is the default behavior for the "ok" (enter) and "cancel" (esc) messages. You can fix this by overriding the virtual member functions:

void MyDialog::OnOK()
{
}

void MyDialog::OnCancel()
{
}

As usual the documentation on this is piss-poor!
Be sure to call a return and do not call the base functionality from within the OnOK and OnCancel functions. In order to properly insert these functions, right click on the button in question and use the class wizard so it propogates correctly.

You can always delete those buttons, you know. It won''t do any harm. Or change their ID''s to something other than IDOK and IDCANCEL.

-fel
~ The opinions stated by this individual are the opinions of this individual and not the opinions of her company, any organization she might be part of, her parrot, or anyone else. ~
I had this same problem recently. You probably have a default button or action (double-clicking a listbox entry?) that the user would assume would be triggered with "return". Make that your default button, and remove the OK button and OnOK methods completely.

I tried overriding OnCancel, but then found that I couldn''t close the window at all--hitting the system X box in the upper-right corner calls OnCancel, which I''d overridden to do nothing. I eventually left the esc-quits-program functionality in. Does anybody know a way around this?
Felisandra: You don''t want to just rename (or remove) the buttons, because the default "on return" and "on escape / on close box" are also associated with IDOK and IDCANCEL. I experienced a lot of headaches when I first realized this!

Stoffel: I had the same problem. The way I worked around it was to keep OnCancel as the default (so that the box would close) and trap the ESC key with PreTranslateMessage() (I suppose OnKeyDown would work also):

    BOOL CMyDlg:<img src="tongue.gif" width=15 height=15 align=middle>reTranslateMessage(MSG* pMsg) {  if(pMsg->msg==WM_KEYDOWN) {    char code = LOBYTE(pMsg->wParam);    if(code==VK_ESCAPE) {      return TRUE; // ignore this    }  }  return CDialog:<img src="tongue.gif" width=15 height=15 align=middle>reTranslateMessage(pMsg)}    


This seems rather hacky, but it does get the job done in my experience. PreTranslateMessage() in general has proven to be quite useful, since you get a crack at the message map before windoze screws you over!


Advertisement
Ack. Auto-smiley screwed up the post!

Well, obviously the html should just be "P". Sorry about that.
I''ll have to double check when I get home, but I''m really pretty sure that the X in the upper right is associated with WM_CLOSE which maps to OnClose(). Granted this goes through the IDCANCEL if you override it, but actually deleting the button from the resource should do no harm, and shouldn''t require any extra code. My pure-MFC-custom-control game Peg, for instance, has no OK or Cancel buttons, and it closes just fine if you hit the X.

-fel
~ The opinions stated by this individual are the opinions of this individual and not the opinions of her company, any organization she might be part of, her parrot, or anyone else. ~
I deleted those two buttons immedietly, OnOK and OnCancel are not in the wanna-be-a-wizard class list.

I even tried trapping IDOK & IDCANEL in OnCommand

I added my own msg map and overrode OnOK and OnCancel, it works (or rather, no longer works ) as I want it too.

    	//{{AFX_MSG(CInfinitumDlg)	virtual BOOL OnInitDialog();	afx_msg void OnSysCommand(UINT nID, LPARAM lParam);	afx_msg void OnPaint();	afx_msg HCURSOR OnQueryDragIcon();	afx_msg void OnFileExit();	afx_msg void OnFileConnect();	afx_msg void OnMove(int x, int y);	afx_msg void OnSize(UINT nType, int cx, int cy);	afx_msg void OnTimer(UINT nIDEvent);	afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);	afx_msg void OnHelpAbout();	afx_msg void OnUpdateEditMsg();	afx_msg void OnClose();	afx_msg void OnOK();     //added these two myself	afx_msg void OnCancel(); //...	//}}AFX_MSG	DECLARE_MESSAGE_MAP()...//elsewherevoid CInfinitumDlg::OnOK(){//it closes as designed with the next line uncommented	//CDialog::OnOK();}void CInfinitumDlg::OnCancel(){}    


Thanks!
- The trade-off between price and quality does not exist in Japan. Rather, the idea that high quality brings on cost reduction is widely accepted.-- Tajima & Matsubara

This topic is closed to new replies.

Advertisement