I am trying to get the rich edit class to send the main window a message saying text has been typed. To do this I used the EN_KEYEVENTS and sent it to the rich edit control. However I am not getting the messages. Anyone have any ideas??
case WM_NOTIFY:
// MSGFILTER * lpMsgFilter = (MSGFILTER *)lParam;
switch(LOWORD(lParam))
{
case EN_MSGFILTER:
MessageBox(hwnd,"oh yeah",
"Error",MB_OK|MB_ICONEXCLAMATION);
break;
case ENM_KEYEVENTS:
MessageBox(hwnd,"oh yeah8",
"Error",MB_OK|MB_ICONEXCLAMATION);
break;
}
break;
rxbagain
July 28th, 2003, 10:03 PM
Use HIWORD(lParam) in your WM_NOTIFY message handler. The LOWORD(lParam) contains the controlID for the richedit.
Hope it will help you
Yves M
July 29th, 2003, 10:38 AM
First of all, it doesn't send you ENM_KEYEVENTS, but it will send you WM_KEYDOWN / UP etc.
And your WM_NOTIFY handling is not correct. It should be:
case WM_NOTIFY:
{
MSGFILTER * lpMsgFilter = (MSGFILTER *)lParam;
switch (lpMsgFilter->msg) { // Assuming that you only have one control and don't need to verify the event's source.
case WM_KEYDOWN:
MessageBox(0, "Key Down", "Info", MB_OK);
break;
}
}
Yves M
July 29th, 2003, 10:40 AM
Originally posted by rxbagain
Use HIWORD(lParam) in your WM_NOTIFY message handler. The LOWORD(lParam) contains the controlID for the richedit.
Hope it will help you
I don't know where you get this from, but that's wrong.
MSDN
lResult = SendMessage( // returns LRESULT in lResult
(HWND) hWndControl, // handle to destination control
(UINT) WM_NOTIFY, // message ID
(WPARAM) wParam, // = (WPARAM) (int) idCtrl;
(LPARAM) lParam // = (LPARAM) (LPNMHDR) pnmh; );
idCtrl
Identifier of the common control sending the message. This identifier is not guaranteed to be unique. An application should use the hwndFrom or idFrom member of the NMHDR structure (passed as the lParam parameter) to identify the control.
pnmh
Pointer to an NMHDR structure that contains the notification code and additional information. For some notification messages, this parameter points to a larger structure that has the NMHDR structure as its first member.
geoffba
July 29th, 2003, 11:25 AM
Thank you for the help guys. I tried what you guys were saying and it works correctly now. However I seem to be getting the signal three times for every character. Am I still doing something wrong.
case WM_NOTIFY:
switch (((LPNMHDR) lParam)->code)
{
case EN_MSGFILTER:
{
LPTOOLTIPTEXT lptttext; //tooltip structure
lptttext = (LPTOOLTIPTEXT) lParam; //fill the structure with values
lptttext->hinst = ghInst;
switch(lptttext->hdr.idFrom)
{
case 153:
TakeUser('4');
break;
//MessageBox(hwnd,"oh yeah",
// "Error",MB_OK|MB_ICONEXCLAMATION);
}
}
break;
}
break;
geoffba
July 29th, 2003, 11:36 AM
Yves M, I used your WM_NOTIFY switch case code and now I am only getting one message from the richedit control. This is going to work just fine. Just as a further question how would I modify the code to ensure that I am only looking at the rich edit control?
Yves M
July 29th, 2003, 11:51 AM
Just put an if (lpMsgFilter->idFrom == RichEditID) around the switch(lpMsgFilter->msg) block. Judging from your example, you would replace RichEditID by 153.
However I seem to be getting the signal three times for every character
You are not distinguishing which message is at the origin of the WM_NOTIFY call. My guess is that you recieve a WM_KEYDOWN, WM_KEYUP, WM_CHAR sequence.
geoffba
July 29th, 2003, 11:55 AM
Yves M,
Thanks alot, that works great, now though in my program I need to turn on read only in the rich edit control. So I did this and then I want to get the keys pressed by the user. I cannot get them from the rich edit control cause I put on READONLY. How would i go about this?
Yves M
July 29th, 2003, 12:16 PM
You can just set to be not read only, and return 1 in EN_MSGFILTER, like this:
case WM_NOTIFY:
{
MSGFILTER * lpMsgFilter = (MSGFILTER *)lParam;
if (lpMsgFilter->idFrom == 153) {
switch (lpMsgFilter->msg) {
case WM_KEYDOWN:
MessageBox(0, "Key Down", "Info", MB_OK);
break;
}
return 1;
}
}
This tells the Richedit that it should ignore the message.
MSDN
EN_MSGFILTER:
Return Value
- If the control should process the event, the message returns a zero value.
- If the control should ignore the event, the message returns a nonzero value.
geoffba
July 29th, 2003, 12:37 PM
Yves M,
Ok I understand how it works, with the return value and I am now using this instead of the readonly function. However I do not understand how to get the key that the user pressed?
Yves M
July 29th, 2003, 02:03 PM
Just process the forwarded WM_KEYDOWN normally.
e.g.
switch (lpMsgFilter->msg) {
case WM_KEYDOWN:
if (lpMsgFilter->wParam == VK_F1) {
// Show help screen
}
break;
}
geoffba
July 29th, 2003, 03:04 PM
Yves M.
That worked great. The interface now accepts input from the user and sends it out the terminal port. Now I have to work on the different 'special' characters and such. But I will go off and attempt it. Thank you for helping me get through this.
-geoff baker
Yves M
July 29th, 2003, 03:15 PM
You are welcome and good luck ;)
geoffba
July 29th, 2003, 04:14 PM
When I press the numeric keys or anything, the value returned is not an ascii value. Instead it seems to be a windows value. or something. How do I get around that.
geoffba
July 29th, 2003, 04:50 PM
When you retrieve the data from a richedit the window in the application shows the actual key pressed on the keyboard, but the value returned by the control is something else entirely.
Such as keypad 1 returns lower case 'a'
Process Characters:
case WM_NOTIFY:
{
MSGFILTER * lpMsgFilter = (MSGFILTER *)lParam;
LPTOOLTIPTEXT lpttext;
lpttext = (LPTOOLTIPTEXT) lParam;
lpttext->hinst = ghInst;
if (lpttext->hdr.idFrom == 153)
{
switch (lpMsgFilter->msg) { // Assuming that you only have one control and don't need to verify the event's source.
case WM_KEYDOWN:
{
if(Connected==1)
{
unsigned char data=lpMsgFilter->wParam;
SerialPort_Access.SendChar(data);
}
else
{
MessageBox(hwnd,"***Error***\nConnect to Serial Port First",
"Error",MB_OK|MB_ICONEXCLAMATION);
}
}
break;
}
return 0;
}
}
break;
Yves M
July 30th, 2003, 05:11 AM
If you want to get character values, you should handle WM_CHAR instead of WM_KEYDOWN.
geoffba
July 31st, 2003, 12:39 PM
Yves M.
That no worked. I can now get the entire terminal application to operate in the way intended minus a couple of bugs but I will work on that in time. Thank you for your help and time. I was worried that I would need to convert between the data coming in and the data sent to the rich edit but listening to the character message works great. Thanks a lot.
-geoff
Ali Imran
August 18th, 2005, 10:17 AM
As far I learnt from this forum, there is another simpel way to do this. After which your dialog/window procedure will be able to receive EN_CHANGE same as of simple edit controls.
Send following message to richtext control right after its creation at point 'CreateWindowEx'