DoModal in CWnd::PreTranslateMessage( MSG *pMsg )
-
Hello, I need to verify content of my edit control before I let it to loose focus. To do so I wrote my PreTranslateMessage like this:
BOOL CMyFrameWnd::PreTranslateMessage( MSG *pMsg )
{
BOOL bMessageHandled = FALSE;switch( pMsg->message )
{
case WM_LBUTTONDOWN:
{
if( ::GetFocus == MyEditWnd )
{
if( !IsContentOfMyEditWndOK )
{
ShowMessageBox( "You cannot change value");
//ShowMessageBox has got DoModal inside, which pumps messages.
//Unfortunately it causes my *pMsg parameter to be changed.
}
}
break;
}
}
if( !bMessageHandled )
{
bMessageHandled = CFrameWnd::PreTranslateMessage( pMsg ); //I get assertion has failed here, because I am sending pMsg->Hwnd changed with 'ShowMessageBox'
}return bMessageHandled; //I want to show messagebox and let WM_LBUTTONDOWN to be processed, because I do not want to trap focus in my Edit. So I am returning FALSE here. But it has no sence since the pMsg has changed. It is no longer WM_LBUTTONDOWN.
}In order to be able to show modal dialog in PreTranslateMessage and after it forward WM_LBUTTONDOWN I would like to do something like this:
BOOL CMyFrameWnd::PreTranslateMessage( MSG *pMsg )
{
BOOL bMessageHandled = FALSE;
MSG oRememberMsg;switch( pMsg->message )
{
case WM_LBUTTONDOWN:
{
if( ::GetFocus == MyEditWnd )
{
if( !IsContentOfMyEditWndOK )
{
oRememberMsg = *pMsg;
ShowMessageBox( "You cannot change value");
*pMsg = oRememberMsg; //now pMsg is WM_LBUTTONDOWN again
}
}
break;
}
}
if( !bMessageHandled )
{
bMessageHandled = CFrameWnd::PreTranslateMessage( pMsg ); //I am not getting assertion has failed, because pMsg->HWnd is correct now (the same as at the beginning)
}return bMessageHandled; //Now I am forwarding my catch WM_LBUTTONDOWN and my Edit loses focus
}But I am not sure if my code is ok from MFC structural point of view. Can I manipulate with MSG *pMsg parameter as I described above? I tried it and it seems to work, but I don't know... Does it make some side effects? Is something I am missing here? How do you think?
-
Hello, I need to verify content of my edit control before I let it to loose focus. To do so I wrote my PreTranslateMessage like this:
BOOL CMyFrameWnd::PreTranslateMessage( MSG *pMsg )
{
BOOL bMessageHandled = FALSE;switch( pMsg->message )
{
case WM_LBUTTONDOWN:
{
if( ::GetFocus == MyEditWnd )
{
if( !IsContentOfMyEditWndOK )
{
ShowMessageBox( "You cannot change value");
//ShowMessageBox has got DoModal inside, which pumps messages.
//Unfortunately it causes my *pMsg parameter to be changed.
}
}
break;
}
}
if( !bMessageHandled )
{
bMessageHandled = CFrameWnd::PreTranslateMessage( pMsg ); //I get assertion has failed here, because I am sending pMsg->Hwnd changed with 'ShowMessageBox'
}return bMessageHandled; //I want to show messagebox and let WM_LBUTTONDOWN to be processed, because I do not want to trap focus in my Edit. So I am returning FALSE here. But it has no sence since the pMsg has changed. It is no longer WM_LBUTTONDOWN.
}In order to be able to show modal dialog in PreTranslateMessage and after it forward WM_LBUTTONDOWN I would like to do something like this:
BOOL CMyFrameWnd::PreTranslateMessage( MSG *pMsg )
{
BOOL bMessageHandled = FALSE;
MSG oRememberMsg;switch( pMsg->message )
{
case WM_LBUTTONDOWN:
{
if( ::GetFocus == MyEditWnd )
{
if( !IsContentOfMyEditWndOK )
{
oRememberMsg = *pMsg;
ShowMessageBox( "You cannot change value");
*pMsg = oRememberMsg; //now pMsg is WM_LBUTTONDOWN again
}
}
break;
}
}
if( !bMessageHandled )
{
bMessageHandled = CFrameWnd::PreTranslateMessage( pMsg ); //I am not getting assertion has failed, because pMsg->HWnd is correct now (the same as at the beginning)
}return bMessageHandled; //Now I am forwarding my catch WM_LBUTTONDOWN and my Edit loses focus
}But I am not sure if my code is ok from MFC structural point of view. Can I manipulate with MSG *pMsg parameter as I described above? I tried it and it seems to work, but I don't know... Does it make some side effects? Is something I am missing here? How do you think?
-
Couldn't you handle the EN_KILLFOCUS message from the edit control in the parent dialog, check for valid values, and if is isn't OK, call the SetFocus() method for the edit control?
I cannot let to run OnKillFocus if control has no valid value, because OnKillFocus is too late. It is out of my control. Let me show you some example: I have a toolbar also. If somebody presses toolbar button OnCommand is running. Let say it is saving the document. Before saving I have to recalculate it and then save. Recalculating depends on the values in Edit. If Edit is not valid I have wrong calculations. Unfortunately pressing this toolbar buton doesn't cause KillFocus for my Edit. I have to use SetFocus to the edit's parent in order to make KillFocus for my edit to run, before I make recalculation. I don't like this solution. I have many similar problems with validating data in OnKillFocus, so I need to handle all actions before OnKillFocus and before OnLButtonDown, OnCommand, etc of given buton. I do not want to change all possible handlers in my app so I choose PreTranslateMessage. Sometime I return TRUE in PreTranslateMessage for example in order to not let the app for saving document, if user is in serious trouble with his already typed data.
-
Hello, I need to verify content of my edit control before I let it to loose focus. To do so I wrote my PreTranslateMessage like this:
BOOL CMyFrameWnd::PreTranslateMessage( MSG *pMsg )
{
BOOL bMessageHandled = FALSE;switch( pMsg->message )
{
case WM_LBUTTONDOWN:
{
if( ::GetFocus == MyEditWnd )
{
if( !IsContentOfMyEditWndOK )
{
ShowMessageBox( "You cannot change value");
//ShowMessageBox has got DoModal inside, which pumps messages.
//Unfortunately it causes my *pMsg parameter to be changed.
}
}
break;
}
}
if( !bMessageHandled )
{
bMessageHandled = CFrameWnd::PreTranslateMessage( pMsg ); //I get assertion has failed here, because I am sending pMsg->Hwnd changed with 'ShowMessageBox'
}return bMessageHandled; //I want to show messagebox and let WM_LBUTTONDOWN to be processed, because I do not want to trap focus in my Edit. So I am returning FALSE here. But it has no sence since the pMsg has changed. It is no longer WM_LBUTTONDOWN.
}In order to be able to show modal dialog in PreTranslateMessage and after it forward WM_LBUTTONDOWN I would like to do something like this:
BOOL CMyFrameWnd::PreTranslateMessage( MSG *pMsg )
{
BOOL bMessageHandled = FALSE;
MSG oRememberMsg;switch( pMsg->message )
{
case WM_LBUTTONDOWN:
{
if( ::GetFocus == MyEditWnd )
{
if( !IsContentOfMyEditWndOK )
{
oRememberMsg = *pMsg;
ShowMessageBox( "You cannot change value");
*pMsg = oRememberMsg; //now pMsg is WM_LBUTTONDOWN again
}
}
break;
}
}
if( !bMessageHandled )
{
bMessageHandled = CFrameWnd::PreTranslateMessage( pMsg ); //I am not getting assertion has failed, because pMsg->HWnd is correct now (the same as at the beginning)
}return bMessageHandled; //Now I am forwarding my catch WM_LBUTTONDOWN and my Edit loses focus
}But I am not sure if my code is ok from MFC structural point of view. Can I manipulate with MSG *pMsg parameter as I described above? I tried it and it seems to work, but I don't know... Does it make some side effects? Is something I am missing here? How do you think?
-
Unfortunately I cannot use OnChange. It is to early to disturb user. I have to wait untill user finishes typing. EN_CHANGE is sent after each pressed key and I cannot save data from control to internal buffer during typing. I want to do it, if user decides to leave edit control. I have also investigated this MSG *pMsg deeper and it occured that: If I let pumping messages (f.e with modal messagebox), I always have to return TRUE in PreTranslateMessage. Saving first message and forwarding it at the end has no sence, because the whole messaging process is disturbed any way. Here is example of situation, for which my solution with saving *pMSG won't help: WM_LBUTTONDOWN -> WM_LBUTTONUP pair is very sensitive here. If I put messagebox between WM_LBUTTONDOWN and WM_LBUTTONUP in PreTranslateMessage it causes WM_LBUTTONUP to run for mouse point from the [OK] button on the messagebox and not for the original coordinates. So code from CFirstClickedArea::OnLButtonUp() will not be run. So I think, I have to return always TRUE and I have no choice, if I want to use PreTranslateMessage with DoModal.
-
Unfortunately I cannot use OnChange. It is to early to disturb user. I have to wait untill user finishes typing. EN_CHANGE is sent after each pressed key and I cannot save data from control to internal buffer during typing. I want to do it, if user decides to leave edit control. I have also investigated this MSG *pMsg deeper and it occured that: If I let pumping messages (f.e with modal messagebox), I always have to return TRUE in PreTranslateMessage. Saving first message and forwarding it at the end has no sence, because the whole messaging process is disturbed any way. Here is example of situation, for which my solution with saving *pMSG won't help: WM_LBUTTONDOWN -> WM_LBUTTONUP pair is very sensitive here. If I put messagebox between WM_LBUTTONDOWN and WM_LBUTTONUP in PreTranslateMessage it causes WM_LBUTTONUP to run for mouse point from the [OK] button on the messagebox and not for the original coordinates. So code from CFirstClickedArea::OnLButtonUp() will not be run. So I think, I have to return always TRUE and I have no choice, if I want to use PreTranslateMessage with DoModal.
I think you are just making your program far more complicated than necessary. Using either
EN_CHANGE
orEN_UPDATE
means that you can trap illegal content at any point. This will not have any effect on the user's typing unless they enter an incorrect character.Use the best guess
-
I think you are just making your program far more complicated than necessary. Using either
EN_CHANGE
orEN_UPDATE
means that you can trap illegal content at any point. This will not have any effect on the user's typing unless they enter an incorrect character.Use the best guess
This program is already complicated :D Now I am trying to avoid crashes xD I could use EN_CHANGE, if I could prevent just typing. But what about pasting with ctrl + v illegal text? Should I delete it in EN_CHANGE automatically? Other case is, that I have to also read data from editable controls, put it to internal buffer and set "Modified" flag for saving database record later. If data is illegal, I cannot put it to the buffer and set this flag. For simple edits it os ok. But there are also RichEditCtrl controls with OLE and a lot of text. I do not want to copy all text with OLE to the buffer each time EN_CHANGE comes.
-
This program is already complicated :D Now I am trying to avoid crashes xD I could use EN_CHANGE, if I could prevent just typing. But what about pasting with ctrl + v illegal text? Should I delete it in EN_CHANGE automatically? Other case is, that I have to also read data from editable controls, put it to internal buffer and set "Modified" flag for saving database record later. If data is illegal, I cannot put it to the buffer and set this flag. For simple edits it os ok. But there are also RichEditCtrl controls with OLE and a lot of text. I do not want to copy all text with OLE to the buffer each time EN_CHANGE comes.