Click to See Complete Forum and Search --> : is text coloring or highlighting possible in a normal edit control


vironic
February 20th, 2007, 11:21 PM
I have a standard edit control. I'd like to set it up so that the user can select text and change the color of the selected text. Kind of like syntax highlighting but only done once for the text the user selects. Is this possible in a standard edit control?

I realize that a rich edit control is the obvious choice, but there are some aspects of the rich edit control I don't like. Anyway, is coloring or highlighting of selected text possible in a normal edit control?

MikeAThon
February 21st, 2007, 10:33 AM
No. With a standard edit control, all text must have the same appearance (which can be anything) against the same background color (which again can be anything).

Use a rich edit control.

Mike

ovidiucucu
February 21st, 2007, 11:01 AM
I'm just curious. Please, tell me which aspects of the rich edit control you don't like! And why?

vironic
February 21st, 2007, 05:00 PM
ovidiucucu

There are a few issues about rich edit controls that I need solved


I don't like the fact that I am unable to intercept pasting into the Rich edit control by hjacking the WM_PASTE message like I would using a normal edit control. This is necessary for what I'm doing because I need to have whatever is being pasted into the rich edit control in a specific format and to strip out characters that are invalid.

A WM_PASTE message is never generated when I Ctrl V or paste something into a rich edit control (someone tested this for me in another forum and I verfied it myself using my debugger, for some reason, regardless of whether or not the rich edit is subclassed, a WM_PASTE message is never generated). I found a work around by detecting when Ctrl V is pushed then getting the plain text data from the clipboard and editing that the way I want it, then posting that data to the edit control while avoiding a double paste of the data I dont want by calling SendMessage(hwnd, WM_UNDO, 0, 0);. It's a bad way to do it I know, but it's the only way I have found to accomplish this. It's annoying to do it this way because if I WAS pasting highlighted text, the formating would be lost. This also triggers some undo/redo buffer problems because I'm calling an undo everytime something is pasted.

Another issue I have with rich edit control is the lack of intercepting invalid keystrokes. I need my edit control to ignore the return key. In a normal edit control I would simply do this....

case WM_CHAR:
if( wParam == 0x000D )
return 0;
break;

Problem solved. In a rich edit control I can't do this. In a rich edit control the only way I've found to eliminate this behavior is doing this..

case WM_CHAR:
if( wParam == 0x000D )
SendMessage(hwnd, WM_UNDO, 0, 0);
break;

Again, it isn't ideal because everytime I hit the return key accidentally, undo is triggered. Ideally I need an edit control that will allow highlighting and have the undo/redo buffers of a rich edit control but with the simplicity of a standard edit control. Unless I can get rid of some of these behaviors or come up with a better solution I think I may have to stick with a normal edit control. I hope I'm not overlooking an obvious fix to my rich edit control problems, this is possible since I just started learning Win32 API last month.

MikeAThon
February 21st, 2007, 08:12 PM
It might be helpful to read a bit more about how to use edit/rich edit controls. You should particularly read about the notifications that the controls send to the parent (i.e., the EN_xxx notifications). For example, the EN_MSGFILTER notification (see http://msdn.microsoft.com/library/en-us/shellcc/platform/commctls/richedit/richeditcontrols/richeditcontrolreference/richeditnotificationmessages/en_msgfilter.asp ) is sent by a rich edit to its parent whenever there is a keyboard or mouse event, and lets you modify the message or prevent it from being processed.

As for the return key, maybe all you need is to set the ES_WANTRETURN style??

Mike

ovidiucucu
February 21st, 2007, 08:20 PM
First to clarify: as already said here, there is not possible to make syntax highlighting with a "normal" common edit control. Also, as you already said, obviously, you have to switch to rich edit control for doing that.

Second, indeed, the rich edit behaves different, i.e. does not receive the WM_PASTE message like the edit (and combobox) control does.

However, you can "filter" the keyboard (and mouse) messages.
For that you have to do the following:

Send EM_SETEVENTMASK to rich edit control, passing ENM_KEYEVENTS in LPARAM. Further, the control will send to its parent the EN_MSGFILTER notifications for keyboard events.
Handle EN_MSGFILTER notification (sent with WM_NOTIFY message) in the parent's procedure. For the corresponding messages which you don't want to be further processed by rich edit control you have to return a non-zero value.

Here is a simple example which "traps" 'Ctrl+V' keystrokes.
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <windowsx.h>
#include <RICHEDIT.H>
#include "resource.h"

BOOL CALLBACK DialogProc(HWND, UINT, WPARAM, LPARAM);
BOOL OnInitDialog(HWND, HWND, LPARAM);
void OnClose(HWND);
int OnNotifyMsgFilter(MSGFILTER*);
int HandleRichEditKeyDown(TCHAR);

int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
LoadLibraryA("RICHED32.DLL");
DialogBox(hInstance, MAKEINTRESOURCE(IDD_MAIN), NULL, DialogProc);
return 0;
}

BOOL CALLBACK DialogProc(HWND hWndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
BOOL bRet = FALSE;
switch(uMsg)
{
HANDLE_MSG(hWndDlg, WM_INITDIALOG, OnInitDialog);
HANDLE_MSG(hWndDlg, WM_CLOSE, OnClose);
case WM_NOTIFY:
{
switch(((LPNMHDR)lParam)->code)
{
case EN_MSGFILTER:
bRet = OnNotifyMsgFilter((MSGFILTER*)lParam);
break;
}
}
break;
}
return bRet;
}
BOOL OnInitDialog(HWND hWndDlg, HWND hwndFocus, LPARAM lParam)
{
HWND hWndRichEdit = GetDlgItem(hWndDlg, IDC_RICHEDIT);
SendMessage(hWndRichEdit, EM_SETEVENTMASK, 0, ENM_KEYEVENTS);
return TRUE;
}

void OnClose(HWND hWndDlg)
{
EndDialog(hWndDlg, IDCANCEL);
}

int OnNotifyMsgFilter(MSGFILTER* pMsgFilter)
{
BOOL nRet = 0;
switch(pMsgFilter->msg)
{
case WM_KEYDOWN:
nRet = HandleRichEditKeyDown(pMsgFilter->wParam);
break;
}
return nRet;
}

int HandleRichEditKeyDown(TCHAR KeyCode)
{
int nRet = 0;
switch(KeyCode)
{
case 'V': // 'V' key-down
if(0x1000 & GetKeyState(VK_CONTROL)) // 'Ctrl' is pressed
{
nRet = 1; // prevent default 'paste'
}
break;
}
return nRet;
}

ovidiucucu
February 21st, 2007, 08:32 PM
A note:
There is a little mistake in the code above which I couldn't find yet. A similar code written with MFC worked with no problem:
BOOL CMyDialog::OnInitDialog()
{
// ...
m_richedit.SetEventMask(ENM_KEYEVENTS);
return TRUE;
}
void CMyDialog::OnMsgFilterRichedit(NMHDR* pNMHDR, LRESULT* pResult)
{
*pResult = 0;
MSGFILTER *pMsgFilter = (MSGFILTER*)pNMHDR;

if((pMsgFilter->msg == WM_KEYDOWN))
{
if(_T('V') == pMsgFilter->wParam)
{
if(0x1000 & GetKeyState(VK_CONTROL))
{
TRACE0(_T("PASTE"));
*pResult = 1;
}
}
}
}
If somebody can find what's going wrong, please do not hesitate to point it.

TheCPUWizard
February 21st, 2007, 09:38 PM
While I agree a Reich Edit control is the way to go...


With a standard edit control, all text must have the same appearance (which can be anything) against the same background color (which again can be anything).


Is *NOT* strictly true. You can subclass a standard text box control, implement OwnerDraw and do anything you want :eek: :D :D

vironic
February 21st, 2007, 09:49 PM
Thanks for the input MikeAThon and ovidiucucu. Your posts were very helpful. I'll use your suggestions on my rich edit control and see if I can set things the way I want them :)

MikeAThon
February 21st, 2007, 10:00 PM
... You can subclass a standard text box control, implement OwnerDraw and do anything you want :eek: :D :D
Point conceded :)

ovidiucucu
February 22nd, 2007, 02:16 AM
Is *NOT* strictly true. You can subclass a standard text box control, implement OwnerDraw and do anything you want :eek: :D :D
Point conceded :)
Actually, yes, everything is possible including change the sex.
However, most of people prefer keeping the initial one,... anyhow to not cut&paste too much from Mother Nature's gifts. :D ;)

Ali Imran
February 22nd, 2007, 05:40 PM
Actually, yes, everything is possible including change the sex.

:) lol, ya


Here is great material form another MVP
http://catch22.net/tuts/

Please see series under heading "Design and Implementation of a Win32 Text Editor". Such thing is for those who really wish to implement fully custom edit control.