[win32] Change text color

Pages: 12
Aug 26, 2011 at 2:22am
Hi,

how can I change color of part of the text? I'm making chat application and I wanna make Moderator's name blue, I would like to use RGB so if u have any command for that or something it would be great :) (I don't wanna make whole text blue, just name)

Best Regards, SEnergy!
Aug 26, 2011 at 2:48am
Aug 26, 2011 at 3:08am
well, I'm looking for something for win32 API, I'm making gui application :P
Aug 26, 2011 at 4:32am
If you are the one drawing the text yourself then DrawText() (or any other GDI text-drawing functions) will draw the text using the fore color set in the device context.
Aug 26, 2011 at 10:48am
no, I'm using SetDlgItemText() function
Aug 26, 2011 at 2:59pm
You can't do what you want with stock dialog forms. You'll have to create your own dialog window and override the window procedure and handle the WM_PAINT yourself.
Aug 26, 2011 at 5:20pm
If you swap your Edit control to a Rich Edit you can control the color using RTF markup.

1
2
3
4
5
6
7
8
	std::string strRTF = _T("{\\rtf1\\ansi\\ansicpg0\\deff0");
	strRTF += _T("{\\colortbl;\\red0\\green0\\blue0;\\red255\\green0\\blue0;}");
	strRTF += _T("This line is the default color\\line");
	strRTF += _T("\\cf2 ");
	strRTF += _T("This line is red\\line");
	strRTF += _T("\\cf1 ");
	strRTF += _T("This line is the default color");
	strRTF += _T("}");


Where "\\cf2 " = use 2nd entry in color table

But I don't think you can use SetDlgItemText to set this kind of text. I use EM_SETTEXTEX, after using EM_SETTEXTMODE to set the correct mode (TM_RICHTEXT) and EM_SETTARGETDEVICE to set the device (hdc = NULL, line width = 0)
Last edited on Aug 26, 2011 at 5:38pm
Aug 26, 2011 at 6:02pm
what...? O_o can u explain it betteR? :P

how can I create rich edit using resedit? + how does it affect my program? can I use same commands like with edit control?
Last edited on Aug 26, 2011 at 6:27pm
Aug 26, 2011 at 6:20pm
how can I create rich edit using resedit?

Hopefully resedit allows you to insert it just like a normal Edit control

If not, you have to replace the line in the rc file which looks a bit like

EDITTEXT IDC_EDIT_ANSWER,13,214,301,29,ES_MULTILINE | ES_READONLY

with

CONTROL "",IDC_EDIT_ANSWER,"RichEdit20A",ES_MULTILINE | ES_READONLY,13,214,301,29


how does it affect my program? can I use same commands like with edit control?

Most of the standard Edit control's functionality is supported by Rich Edit. But some events have to be enabled using EM_SETEVENTMASK, though this might not be an issue if you just want to display colored text.

Then check out:

About Rich Edit Controls
http://msdn.microsoft.com/en-us/library/bb787873%28v=VS.85%29.aspx
(esp.Using..)

The overall string is made up of a header which defines the encoding (ansi) and codepage (0), and then defines a color table. This one contains just two colors.
 
{\rtf1\ansi\ansicpg0\deff0{\colortbl;\red0\green0\blue0;\red255\green0\blue0;}


then it defines 3 lines. \cf1, cf2 are switching the color of the text (the number is the 1-based index into the color table); \line is the RTF line break command, used instead of \n or \r\n
1
2
3
This line is the default color\line
\cf2 This line is red\line
\cf1 This line is the default color

and close the rtf doc (like C++, braces are used to define scopes)

}

This Wikipedia entry gives some examples

http://en.wikipedia.org/wiki/Rich_Text_Format

Andy

P.S. One catch is that you must call LoadLibrary on the required version of the rich edit control dll (see MSDN for details)
Last edited on Aug 27, 2011 at 1:31pm
Aug 28, 2011 at 5:03pm
well, I have troubles with LoadLibrary:

1
2
3
4
5
#include <Windows.h>
#include "resource.h"
#include <string>

LoadLibrary("Riched20.dll");


1
2
3
4
5
main.cpp(5): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
main.cpp(5): error C2365: 'LoadLibraryA' : redefinition; previous definition was 'function'
winbase.h(7160) : see declaration of 'LoadLibraryA'
main.cpp(5): error C2440: 'initializing' : cannot convert from 'const char [13]' to 'int'
There is no context in which this conversion is possible
Last edited on Aug 28, 2011 at 5:04pm
Aug 28, 2011 at 5:12pm
LoadLibrary cannot be called at global scope. Move it inside the WinMain, somewhere near the top.

You might also get the return value and use _ASSERTE to check it's valid

1
2
3
4
5
6
7
8
9
10
11
INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, INT nShowCmd)
{
	UNREFERENCED_PARAMETER(hPrevInstance);
	UNREFERENCED_PARAMETER(lpCmdLine);

	g_hInst = hInstance; // Store instance handle in our global variable

	HMODULE hmodRichEdit = LoadLibrary("Riched20.dll");
	_ASSERTE(NULL != hmodRichEdit);

	...

Last edited on Aug 28, 2011 at 5:12pm
Aug 28, 2011 at 6:01pm
okay, it's working, but,
#1 how can I make it to automatically, if I send long message, it will "break" it and then put it in next line? (In output), I'll send u a picture to explain it better :P

http://filebeam.com/4230545b2f947878f7336a1baf0ec5a6.jpg

I was searching in edit control "modes" too, but I didn't found anything, only autoh/v/scroll or something like this, but it don't works

#2 is there any way to make that thing on right side so if there will be a lot of messages users can browse through them up and down? screen again :D

http://filebeam.com/6f63d8b56175a1023866af7a9cd93107.jpg

cuz when I write a lot of messages, it will write them there, but you can't see them (and I wanna make it automatically scroll down when new message is sended)
Aug 28, 2011 at 6:13pm
#1 Make sure you are not using ES_AUTOHSCROLL -- when auto hscroll is off, and it's multi-line, it should wrap

#2 You need WS_VSCROLL and ES_AUTOVSCROLL -- the former will cause a vertical scrollbar to appear when needed; the auto vscroll shouldl scroll the window to display the new text when added.

Andy

(P.S. the above all need to be added/removed from the .rc file)
Aug 28, 2011 at 6:25pm
ehh, it's working, again :D thanks, I have almost everything, I just have problems with writing multiline text in rich edit, and with that colors, this is what I have:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
void AppendText(HWND hMain, char buffer[256], int size)
{
	char messages[4096];
	GetDlgItemText(hMain, IDC_OUTPUT1, messages, sizeof(messages)/sizeof(messages[0]));
	GetDlgItemText(hMain, IDC_MESSAGE1, buffer, size);
	std::string wholeMessage;
	wholeMessage += "{\\rtf1\\ansi\\ansicpg0\\deff0";
	wholeMessage += "{\\colortbl;\\red0\\green0\\blue0;\\red255\\green0\\blue0;}";
	wholeMessage += messages;
	if(Level == 10)
		wholeMessage += "\\cf2 ";
	wholeMessage += Username;
	wholeMessage += "\\cf1 ";
	wholeMessage += ": ";
	wholeMessage += buffer;
	wholeMessage += "\r\n";
	wholeMessage += "\\line";
	wholeMessage += "}";
	SetDlgItemText(hMain, IDC_OUTPUT1, wholeMessage.c_str());
}


this is how it looks like:

http://filebeam.com/3422fc94d8a0652edda2aa210fd215d8.jpg

as u can see, it will write it to one line, I tried both, \r\n and \\line, but nothing is working, why? O_O + my name is not red in first message, this happens when I send second message
Last edited on Aug 28, 2011 at 6:27pm
Aug 28, 2011 at 7:01pm
I have not manipulated text like that.

If I had to guess, the text you're getting back from your call to GetDlgItemText has lost its RTF markup. So when you rebuild the string, only the new text has any markup.

To test this, trying writing the contents of messages to a file or the debugger

OutputDebugString(messages);

or even

1
2
3
	char debugOutput[1024] = "";
	sprintf("message = %s\n", messages);
	OutputDebugString(debugOutput);


I would be inserting the new text, not getting all the text back and then setting back the updated text.
Last edited on Aug 29, 2011 at 12:55pm
Aug 28, 2011 at 7:31pm
what do u mean with that u haven't manipulated text like that? :P

I used fstream for that, and sended 3 messages

1
2
3
{\rtf1\ansi\ansicpg0\deff0{\colortbl;\red0\green0\blue0;\red255\green0\blue0;}\cf2 SEnergy\cf1 : first\line}
{\rtf1\ansi\ansicpg0\deff0{\colortbl;\red0\green0\blue0;\red255\green0\blue0;}SEnergy: first\cf2 SEnergy\cf1 : second\line}
{\rtf1\ansi\ansicpg0\deff0{\colortbl;\red0\green0\blue0;\red255\green0\blue0;}SEnergy: firstSEnergy: second\cf2 SEnergy\cf1 : third\line}
Aug 28, 2011 at 10:23pm
what do u mean with that u haven't manipulated text like that? :P

I haven't retrieved a long string from an edit control, altered it, and set it back. I just insert the extra text.

Anyway, from the three lines you posted, it's clear that the formatting is being lost.

Try...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
void AppendText(HWND hMain, char buffer[256], int size)
{
	GetDlgItemText(hMain, IDC_MESSAGE1, buffer, size);
	std::string wholeMessage;
	wholeMessage += "{\\rtf1\\ansi\\ansicpg0\\deff0";
	wholeMessage += "{\\colortbl;\\red0\\green0\\blue0;\\red255\\green0\\blue0;}";
	if(Level == 10)
		wholeMessage += "\\cf2 ";
	wholeMessage += Username;
	wholeMessage += "\\cf1 ";
	wholeMessage += ": ";
	wholeMessage += buffer;
	wholeMessage += "\r\n";
	wholeMessage += "\\line";
	wholeMessage += "}";
	HWND hwndOutput = GetDlgItem(hMain, IDC_OUTPUT1);
	int textLen = SendMessage(hwndOutput, WM_GETTEXTLENGTH, 0, 0);
	_ASSERTE(0 <= textLen);
	SendMessage(hwndOutput, EM_SETSEL, textLen, textLen);
	SendMessage(hwndOutput, EM_REPLACESEL, TRUE, (LPARAM)wholeMessage.c_str());
}
Aug 28, 2011 at 11:12pm
it's working well, thanks, I just need to explain that last 4 lines :P (17-20)

edit: I just noticed that if I write something and rich edit will be full, that scoll bar on the right will appear, but it won't automatically scroll down, how to fix that? I need to scoll it down manually
Last edited on Aug 29, 2011 at 12:40am
Aug 29, 2011 at 6:56am
The last 4 lines are appending text by:
- getting the length of the existing text
- setting the current selection to a zero length range at the end of the string
- replacing the selected text with the new text

The assert is prob totally neurotic

This is the standard way to do append text. See following for more info:

How To Programatically Append Text to an Edit Control
http://support.microsoft.com/kb/109550
Last edited on Aug 29, 2011 at 12:56pm
Aug 29, 2011 at 11:19am
aha, thanks! :P and what about that scroll bar? how can I make it scroll down automatically?
Pages: 12