Index: msgdialog.c
===================================================================
--- msgdialog.c	(revision 6386)
+++ msgdialog.c	(working copy)
@@ -39,6 +39,7 @@
 
 extern HCURSOR hCurSplitNS, hCurSplitWE, hCurHyperlinkHand;
 extern HANDLE hHookWinEvt;
+extern HANDLE hHookWinPopup;
 extern struct CREOleCallback reOleCallback;
 extern HINSTANCE g_hInst;
 
@@ -318,22 +319,6 @@
 	case WM_CHAR:
 		if (GetWindowLong(hwnd, GWL_STYLE) & ES_READONLY)
 			break;
-		//for saved msg queue the keyup/keydowns generate wm_chars themselves
-		if (wParam == '\n' || wParam == '\r') {
-			if (((GetKeyState(VK_CONTROL) & 0x8000) != 0) ^ (0 != DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_SENDONENTER, SRMSGDEFSET_SENDONENTER))) {
-				PostMessage(GetParent(hwnd), WM_COMMAND, IDOK, 0);
-				return 0;
-			}
-			if (DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_SENDONDBLENTER, SRMSGDEFSET_SENDONDBLENTER)) {
-				if (dat->lastEnterTime + ENTERCLICKTIME < GetTickCount())
-					dat->lastEnterTime = GetTickCount();
-				else {
-					SendMessage(hwnd, WM_CHAR, '\b', 0);
-					PostMessage(GetParent(hwnd), WM_COMMAND, IDOK, 0);
-					return 0;
-			}	}
-		}
-		else dat->lastEnterTime = 0;
 
 		if (wParam == 1 && GetKeyState(VK_CONTROL) & 0x8000) {      //ctrl-a
 			SendMessage(hwnd, EM_SETSEL, 0, -1);
@@ -403,6 +388,25 @@
 			SaveKeyboardMessage(dat, msg, wParam, lParam);
 			return 0;
 		}
+		
+		if (wParam == VK_RETURN) {
+			if (((GetKeyState(VK_CONTROL) & 0x8000) != 0) ^ (0 != DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_SENDONENTER, SRMSGDEFSET_SENDONENTER))) {
+				PostMessage(GetParent(hwnd), WM_COMMAND, IDOK, 0);
+				return 0;
+			}
+			if (DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_SENDONDBLENTER, SRMSGDEFSET_SENDONDBLENTER)) {
+				if (dat->lastEnterTime + ENTERCLICKTIME < GetTickCount())
+					dat->lastEnterTime = GetTickCount();
+				else {
+					SendMessage(hwnd, WM_KEYDOWN, VK_BACK, 0);
+					SendMessage(hwnd, WM_KEYUP, VK_BACK, 0);
+					PostMessage(GetParent(hwnd), WM_COMMAND, IDOK, 0);
+					return 0;
+				}
+			}
+		}
+		else
+			dat->lastEnterTime = 0;
 
 		if (wParam == VK_UP && (GetKeyState(VK_CONTROL) & 0x8000) && DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_CTRLSUPPORT, SRMSGDEFSET_CTRLSUPPORT) && !DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_AUTOCLOSE, SRMSGDEFSET_AUTOCLOSE)) {
 			if (pdat->cmdList) {
@@ -446,9 +450,7 @@
 			EnableWindow(GetDlgItem(GetParent(hwnd), IDOK), GetWindowTextLength(GetDlgItem(GetParent(hwnd), IDC_MESSAGE)) != 0);
 			UpdateReadChars(GetParent(hwnd), pdat->hwndStatus);
 		}
-		if (wParam == VK_RETURN)
-			break;
-		//fall through
+		break;
 	case WM_LBUTTONDOWN:
 	case WM_RBUTTONDOWN:
 	case WM_MBUTTONDOWN:
@@ -473,6 +475,45 @@
 			free(dat->keyboardMsgQueue);
 		free(dat);
 		return 0;
+	case WM_CONTEXTMENU: 
+		{
+			MessageWindowPopupData mwpd;
+			mwpd.cbSize = sizeof(mwpd);
+			mwpd.uType = MSG_WINDOWPOPUP_SHOWING;
+			mwpd.uFlags = MSG_WINDOWPOPUP_INPUT;
+			mwpd.hContact = pdat->hContact;
+			mwpd.hwnd = hwnd;
+			mwpd.hMenu = CreatePopupMenu();
+			mwpd.selection = 0;
+
+			if (lParam == 0xFFFFFFFF) {
+				CHARRANGE sel;
+				SendMessage(hwnd, EM_EXGETSEL, 0, (LPARAM) &sel);
+				SendMessage(hwnd, EM_POSFROMCHAR, (WPARAM)&mwpd.pt, (LPARAM) sel.cpMax);
+
+				ClientToScreen(hwnd, &mwpd.pt);
+			}
+			else {
+				mwpd.pt.x = LOWORD(lParam);
+				mwpd.pt.y = HIWORD(lParam);
+			}
+
+			// First notification
+			NotifyEventHooks(hHookWinPopup, 0, (LPARAM)&mwpd);
+
+			// Someone added items?
+			if (GetMenuItemCount(mwpd.hMenu) > 0) {
+				mwpd.selection = TrackPopupMenu(mwpd.hMenu, TPM_RETURNCMD, mwpd.pt.x, mwpd.pt.y, 0, hwnd, NULL);
+			}
+
+			// Second notification
+			mwpd.uType = MSG_WINDOWPOPUP_SELECTED;
+			NotifyEventHooks(hHookWinPopup, 0, (LPARAM)&mwpd);
+			return 0;
+		}
+	case WM_PASTE:
+		SendMessage(hwnd, EM_PASTESPECIAL, CF_TEXT, 0);
+		return 0;
 	}
 	return CallWindowProc(OldMessageEditProc, hwnd, msg, wParam, lParam);
 }
@@ -778,6 +819,7 @@
 			EnableWindow(GetDlgItem(hwndDlg, IDC_AVATAR), FALSE);
 			SendDlgItemMessage(hwndDlg, IDC_LOG, EM_SETOLECALLBACK, 0, (LPARAM) & reOleCallback);
 			SendDlgItemMessage(hwndDlg, IDC_LOG, EM_SETEVENTMASK, 0, ENM_MOUSEEVENTS | ENM_LINK);
+			SendDlgItemMessage(hwndDlg, IDC_MESSAGE, EM_SETEVENTMASK, 0,  ENM_CHANGE);
 			/* duh, how come we didnt use this from the start? */
 			SendDlgItemMessage(hwndDlg, IDC_LOG, EM_AUTOURLDETECT, (WPARAM) TRUE, 0);
 			if (dat->hContact && dat->szProto) {
@@ -1120,6 +1162,7 @@
 			COLORREF colour = DBGetContactSettingDword(NULL, SRMMMOD, SRMSGSET_BKGCOLOUR, SRMSGDEFSET_BKGCOLOUR);
 			dat->hBkgBrush = CreateSolidBrush(colour);
 			SendDlgItemMessage(hwndDlg, IDC_LOG, EM_SETBKGNDCOLOR, 0, colour);
+			SendDlgItemMessage(hwndDlg, IDC_MESSAGE, EM_SETBKGNDCOLOR, 0, colour);
 		}
 		{ // avatar stuff
 			dat->avatarPic = 0;
@@ -1133,12 +1176,17 @@
 		{
 			HFONT hFont;
 			LOGFONT lf;
+			CHARFORMAT cf = {0};
 			hFont = (HFONT) SendDlgItemMessage(hwndDlg, IDC_MESSAGE, WM_GETFONT, 0, 0);
 			if (hFont != NULL && hFont != (HFONT) SendDlgItemMessage(hwndDlg, IDOK, WM_GETFONT, 0, 0))
 				DeleteObject(hFont);
-			LoadMsgDlgFont(MSGFONTID_MESSAGEAREA, &lf, NULL);
+			LoadMsgDlgFont(MSGFONTID_MESSAGEAREA, &lf, &cf.crTextColor);
 			hFont = CreateFontIndirect(&lf);
 			SendDlgItemMessage(hwndDlg, IDC_MESSAGE, WM_SETFONT, (WPARAM) hFont, MAKELPARAM(TRUE, 0));
+
+			cf.cbSize = sizeof(CHARFORMAT);
+			cf.dwMask = CFM_COLOR;
+			SendDlgItemMessage(hwndDlg, IDC_MESSAGE, EM_SETCHARFORMAT, SCF_ALL, (WPARAM) &cf);
 		}
 
         /*
@@ -1528,20 +1576,10 @@
 			SetTimer(hwndDlg, TIMERID_MSGSEND, DBGetContactSettingDword(NULL, SRMMMOD, SRMSGSET_MSGTIMEOUT, SRMSGDEFSET_MSGTIMEOUT), NULL);
 			break;
 		}
-		break;
 
-	case WM_CTLCOLOREDIT:
-		{
-			COLORREF colour;
-			if ((HWND) lParam != GetDlgItem(hwndDlg, IDC_MESSAGE))
+	case WM_MEASUREITEM:
+			if (wParam == 0 || lParam == 0)
 				break;
-			LoadMsgDlgFont(MSGFONTID_MESSAGEAREA, NULL, &colour);
-			SetTextColor((HDC) wParam, colour);
-			SetBkColor((HDC) wParam, DBGetContactSettingDword(NULL, SRMMMOD, SRMSGSET_BKGCOLOUR, SRMSGDEFSET_BKGCOLOUR));
-			return (BOOL) dat->hBkgBrush;
-		}
-
-	case WM_MEASUREITEM:
 		return CallService(MS_CLIST_MENUMEASUREITEM, wParam, lParam);
 
 	case WM_DRAWITEM:
Index: msgs.c
===================================================================
--- msgs.c	(revision 6386)
+++ msgs.c	(working copy)
@@ -28,7 +28,7 @@
 
 HCURSOR hCurSplitNS, hCurSplitWE, hCurHyperlinkHand;
 static HANDLE hEventDbEventAdded, hEventDbSettingChange, hEventContactDeleted;
-HANDLE hHookWinEvt = NULL;
+HANDLE hHookWinEvt = NULL, hHookWinPopup=NULL;
 
 extern HINSTANCE g_hInst;
 
@@ -451,6 +451,7 @@
 	CreateServiceFunction("SRMsg/ReadMessage", ReadMessageCommand);
 	CreateServiceFunction("SRMsg/TypingMessage", TypingMessageCommand);
 	hHookWinEvt=CreateHookableEvent(ME_MSG_WINDOWEVENT);
+	hHookWinPopup=CreateHookableEvent(ME_MSG_WINDOWPOPUP);
 	SkinAddNewSoundEx("RecvMsgActive", Translate("Messages"), Translate("Incoming (Focused Window)"));
 	SkinAddNewSoundEx("RecvMsgInactive", Translate("Messages"), Translate("Incoming (Unfocused Window)"));
 	SkinAddNewSoundEx("AlertMsg", Translate("Messages"), Translate("Incoming (New Session)"));
Index: resource.rc
===================================================================
--- resource.rc	(revision 6386)
+++ resource.rc	(working copy)
@@ -9,6 +9,7 @@
 //
 #include <windows.h>
 #include <winres.h>
+#include "richedit.h"
 #include "../../include/statusmodes.h"
 
 /////////////////////////////////////////////////////////////////////////////
@@ -105,8 +106,17 @@
 CAPTION "Message Session"
 FONT 8, "MS Shell Dlg", 0, 0, 0x1
 BEGIN
-    EDITTEXT        IDC_MESSAGE,1,49,141,13,ES_MULTILINE | ES_AUTOVSCROLL | 
-                    ES_WANTRETURN | WS_VSCROLL,WS_EX_ACCEPTFILES
+#if defined(UNICODE)
+    CONTROL         "",IDC_MESSAGE,"RichEdit20W",ES_MULTILINE | 
+                    ES_AUTOVSCROLL | ES_NOHIDESEL | ES_WANTRETURN | 
+                    WS_VSCROLL | WS_TABSTOP,1,49,141,13,WS_EX_ACCEPTFILES | 
+                    WS_EX_STATICEDGE
+#else
+    CONTROL         "",IDC_MESSAGE,"RichEdit20A",ES_MULTILINE | 
+                    ES_AUTOVSCROLL | ES_NOHIDESEL | ES_WANTRETURN | 
+                    WS_VSCROLL | WS_TABSTOP,1,49,141,13,WS_EX_ACCEPTFILES | 
+                    WS_EX_STATICEDGE
+#endif                    
     DEFPUSHBUTTON   "&Send",IDOK,143,48,39,15
     PUSHBUTTON      "Close",IDCANCEL,129,0,54,15,NOT WS_VISIBLE
     CONTROL         "",IDC_PROTOCOL,"Button",BS_OWNERDRAW,2,5,12,12
@@ -265,6 +275,7 @@
 BEGIN
     "#include <windows.h>\r\n"
     "#include <winres.h>\r\n"
+    "#include ""richedit.h""\r\n"
     "#include ""../../include/statusmodes.h""\r\n"
     "\0"
 END
Index: srmm.c
===================================================================
--- srmm.c	(revision 6386)
+++ srmm.c	(working copy)
@@ -34,7 +34,11 @@
 
 PLUGININFOEX pluginInfo = {
 	sizeof(PLUGININFOEX),
-	"Send/Receive Messages",
+#ifdef _UNICODE
+	"Send/Receive Messages (Unicode) - RichEdit mod",
+#else
+	"Send/Receive Messages - RichEdit mod",
+#endif
 	PLUGIN_MAKE_VERSION(0, 7, 0, 0),
 	"Send and receive instant messages",
 	"Miranda IM Development Team",
@@ -44,9 +48,9 @@
 	UNICODE_AWARE,
 	DEFMOD_SRMESSAGE,            // replace internal version (if any)
 #ifdef _UNICODE
-	{0x657fe89b, 0xd121, 0x40c2, { 0x8a, 0xc9, 0xb9, 0xfa, 0x57, 0x55, 0xb3, 0xc }} //{657FE89B-D121-40c2-8AC9-B9FA5755B30C}
+	{ 0x8219e097, 0xb94c, 0x4109, { 0x90, 0x71, 0xd9, 0xee, 0x3c, 0xf6, 0x60, 0xcb } } // {8219E097-B94C-4109-9071-D9EE3CF660CB}
 #else
-	{0xd53dd778, 0x16d2, 0x49ac, { 0x8f, 0xb3, 0x6f, 0x9a, 0x96, 0x1c, 0x9f, 0xd2 }} //{D53DD778-16D2-49ac-8FB3-6F9A961C9FD2}
+	{ 0x572029ef, 0x2ecb, 0x40d4, { 0x99, 0xee, 0xbb, 0xb0, 0x74, 0x99, 0xbb, 0xe8 } } // {572029EF-2ECB-40d4-99EE-BBB07499BBE8}
 #endif
 };