0

I'm trying to subclass an edit box in a dialog in VS C++ 2022. I want to intercept any key presses in a particular edit box to do further processing.

Here's my code. The 4th line confuses me because I expected GetDlgItem() to return an HWND, not a CWnd, but this is the only way I could get it to work without an error there. The error I do get is on the SetWindowLongPtrA() function call, 3rd parameter.

The error:

argument of type "void (CDialogControlAndStatus::*)() is incompatable with parameter type "LONG_PTR"

And error:

'&': illegal operation on bound member function expression

If I leave off the "&" in front of param #3, I get the same first error plus I get error:

non-standard syntax; use '&' to create a pointer to member

It seems I'm damned if I do or I don't!

void CDialogControlAndStatus::Edit1ProcInst()
{
  HWND DlgHndl = m_hWnd;               // get handle of this dialog
  CWnd *Edit1CWnd = GetDlgItem(IDC_EDIT1); // get the CWnd to the edit box
  HWND Edit1Handl = *Edit1CWnd;            // get the HWND to the edit box
  m_LongPtrEdit1 =
    SetWindowLongPtrA(Edit1Handl, GWLP_WNDPROC, &Edit1Proc); //subclass edit box window
}

void CDialogControlAndStatus::Edit1Proc()
{
    // TODO: Add your implementation code here.
}

1 Answer 1

4

There are two errors in the code:

  1. The 3rd parameter of SetWindowLongPtrW is of type LONG_PTR (a type alias for long or __int64). There is no implicit conversion from a pointer type. An explicit cast is required.
  2. Edit1Proc is a class member. The address of a class member is spelled as &CDialogControlAndStatus::Edit1Proc.

Once you address those issues, the code will compile. It's still wrong and will crash at run-time or otherwise behave erratically. The window procedure has a predefined signature and a (non-static) class member's signature doesn't match.

Only a free function, a static class member, or some closures can be made to match the required signature. If you require access to the class instance from the callback, you'll have to arrange for that through some other channel.

Since you're using MFC the easiest solution is to make use of the framework. Binding a custom C++ class to a GUI control is a two-step process:

  1. Derive a custom class from one of the MFC-provided control wrappers (e.g., CEdit for a standard EDIT control) and make an instance a class member of the dialog class.
  2. Add a DDX_Control call to the DoDataExchange() implementation of the dialog class.

With that in place all window messages designated for the control are passed through the custom control implementation. You can modify the message map to control which messages are handled by which callback.

Sign up to request clarification or add additional context in comments.

Your Answer

Draft saved
Draft discarded

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.