Click here to Skip to main content
15,887,027 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi,

is there a chance to disable the messaging system for a particular window dynamically during runtime? Looking at my application, I have got a CEdit control (lets say Edit1) and a handler routine which will be called on EN_CHANGE notification.

The message handler now invokes SetWindowTextW (or SetDlgItemTextW [both tried]) which issues WM_SETTEXT message to other CEdit controls (lets say Edit2). This is part of the functionality and has to be implemented as mentioned.

The EN_CHANGE message handler for the Edit2 is the same as in the clause above due to objective oriented design. SetWindowTextW/SetDlgItemTextW is called which invokes the (same) message handler for Edit1 and so on and so on .... stack overflow.

Thats why my question to disable the message handling for an CEdit control before calling SetWindowTextW/SetDlgItemTextW and enabling the message handling afterwards. This would achieve that only the Text of the CEdit control will be set, but not issuing another WM_SETTEXT message.

Thanks for your help in advance.

koni
Posted

I did not completely understood your question.But upto my understanding you are doing this.

VB
ON_EN_CHANGE(IDC_EDIT1, &CTestCEdit1Dlg::OnEnChangeEdit1)
ON_EN_CHANGE(IDC_EDIT2, &CTestCEdit1Dlg::OnEnChangeEdit2)

in OnEnChangeEdit1 you are changing the text of EDIT2 and in OnEnChangeEdit2 you are changing the text of EDIT1.if it is then,
Declare a Bool variable m_bool and initialise it to true in dialog constructor.after
C#
void CTestCEdit1Dlg::OnEnChangeEdit1()
{
    // TODO:  If this is a RICHEDIT control, the control will not
    // send this notification unless you override the CDialog::OnInitDialog()
    // function and call CRichEditCtrl().SetEventMask()
    // with the ENM_CHANGE flag ORed into the mask.
    if(m_bool == TRUE)
    {
        m_bool = FALSE;
        m_Edit2.SetWindowTextW(_T("Hi2"));
    }
     else
    {
        m_bool = TRUE;
    }
    // TODO:  Add your control notification handler code here
}


and

C#
void CTestCEdit1Dlg::OnEnChangeEdit2()
{
    // TODO:  If this is a RICHEDIT control, the control will not
    // send this notification unless you override the CDialog::OnInitDialog()
    // function and call CRichEditCtrl().SetEventMask()
    // with the ENM_CHANGE flag ORed into the mask.
    if(m_bool == TRUE)
    {
        m_bool = FALSE;
        m_Edit1.SetWindowTextW(_T("Hi1"));
    }
    else
    {
        m_bool = TRUE;
    }
    // TODO:  Add your control notification handler code here
}
}
 
Share this answer
 
Comments
derkoni87 21-Jun-11 10:17am    
"The EN_CHANGE message handler for the Edit2 is the same as in the clause above due to objective oriented design."
Consequential:
ON_EN_CHANGE(IDC_EDIT1, &CTestCEdit1Dlg::OnEnChangeEdit)
ON_EN_CHANGE(IDC_EDIT2, &CTestCEdit1Dlg::OnEnChangeEdit)

Depending on the user input, the message handler may update the text of other CEdit controls via SetWindowTextW or SetDlgItemTextW. In this case, the methods SetWindowTextW/SetDlgItemTextW release WM_SETTEXT which invokes once more CTestCEdit1Dlg::OnEnChangeEdit which updates once more ALL CEdit controls text which is then resulting in stack overflow. The WM_SETTEXT message must not be released.

Hope to plain the topic a bit :)
if you handle all edit changes in same OnEnChangeEdit handler,then how you are knowing which edit box is updated.Anyways if you provide the code inside
OnEnChangeEdit handler then it will be somewhat easy to understood the problem.
derkoni87 22-Jun-11 2:26am    
It's object oriented. The main window gets the EN_CHANGE notification (also providing IDC of the CEdit control), then the main window looks at a table and calculates the tableIndex. Something like this:

if (table[tableIndex] == IDC)
{
m_MyObjects[tableIndex].DoSomeThing()
}

m_MyObjects is a class instance which holds the CEdit (and its whole internal state). Anyway, when calling MyObject::DoSomeThing() and updating another CEdit control (via SetDlgItemText/SetWindowTextW) of another MyObject instance, then (depending on user input) an infinite recursion of (finally) DoSomeThing() will occur.
Well, one quick way of doing this is to just derive your classes from the same base but don't include the SetWindowText() to the secondary CEdit in one.

With a derivation sort of like this (where CEdit is whatever common base you want):
class CEditSetTxt : public CEdit
class CEditFinal  : public CEdit
 
Share this answer
 
Comments
derkoni87 21-Jun-11 9:51am    
Well, as I understood your solution you dont want to implement SetWindowText of the CEdit derived class (CEditFinal). But this wont work as SetWindowTextW is not declared as virtual method in CWnd base class of CEdit.

Or are you pointing at a solution which refuses a WM_SETTEXT message in the message handler of CEditFinal class?
Albert Holguin 21-Jun-11 10:00am    
Where are you calling SetWindowText() from? Just exclude that from one of the CEdit derived classes... unless I'm misunderstanding what you're doing...
overwrite PreTranslateMessage and handle the messages your way.

Tip: best is to call the default PreTranslateMessage at the end
 
Share this answer
 
Comments
derkoni87 21-Jun-11 10:55am    
I tried out your solution and wrote a class which is derived from CEdit. The following code (btw. whats the tag to highlight sourcecode):

void LockEnChange(BOOL value = TRUE)
{
m_LockEnChange = value;
}

BOOL PreTranslateMessage(MSG* pMsg)
{
BOOL returnValue = TRUE;

switch (pMsg->message)
{
case WM_SETTEXT:
{
if (m_LockEnChange == FALSE)
{
returnValue = CEdit::PreTranslateMessage(pMsg);
}
break;
}
default:
{
returnValue = CEdit::PreTranslateMessage(pMsg);
break;
}
}

return returnValue;
}

(with BOOLEAN m_LockEnChange variable declared respectively)

But there is no WM_SETTEXT message when stepping over SetWindowTextW. As I understood, SetWindowTextW uses SendMessageW to invoke the message handler in direct way? So there has to be an WM_SETTEXT event during that time?!
KarstenK 22-Jun-11 2:42am    
why arent your function i a class scope of your derived class?
derkoni87 22-Jun-11 3:03am    
They are. I have just quickly implemented these functions in the header file of the derived class, so you dont see the function's scope.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900