Change line color on edit control...

Hey guys, i'm fairly new to c++, and to make matters worse i'm a labview-guy ;), so i'm having a hard time creating my GUI, and i was hoping one of you experts could help me out :), here's my problem...
i'm trying to make a small chat program, using a disabled edit control as my chat-window, now every time the user types a message and hits enter, or presses the send button, i append the text to my chat-window, BUT if failing to send the message, i wont it to be displayed in red text, i've searched the internet for hours, and i now know how to set the color in the WM_CTLCOLORSTATIC case using SetTextColor(), but i just can't figure out how to change the color of a single line of text? here's my code...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
#include <windows.h>
#include <winsock2.h>
#include <stdio.h>
#include <stdlib.h>
#include <tchar.h>

#define IDC_BUTTON      2000
#define IDC_EDIT        2001
#define IDC_STATIC_EDIT 2002

SOCKET sClient;

void postMessage(HWND hStaticEdit, HWND hEdit);

LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);

char szClassName[ ] = "Mit første chat program";

int WINAPI WinMain (HINSTANCE hThisInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR lpszArgument,
                     int nCmdShow)
{
    HWND hwnd;     
    MSG messages;        
    WNDCLASSEX wincl;        

    wincl.hInstance = hThisInstance;
    wincl.lpszClassName = szClassName;
    wincl.lpfnWndProc = WindowProcedure;
    wincl.style = CS_DBLCLKS;
    wincl.cbSize = sizeof (WNDCLASSEX);

    wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
    wincl.lpszMenuName = NULL;            
    wincl.cbClsExtra = 0;
    wincl.cbWndExtra = 0;
    wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;

    if (!RegisterClassEx (&wincl))
        return 0;

    hwnd = CreateWindowEx (
           0,                
           szClassName,
           "Mit første chat program!",
           WS_SYSMENU|WS_MINIMIZEBOX,
           CW_USEDEFAULT,
           CW_USEDEFAULT,
           311,
           159,
           HWND_DESKTOP,
           NULL,        
           hThisInstance,
           NULL          
           );

    ShowWindow (hwnd, nCmdShow);

    WSADATA t_wsa;
    WORD wVers;
    int iError;
    wVers = MAKEWORD(2, 2);
    iError = WSAStartup(wVers, &t_wsa);
    if(iError != NO_ERROR || iError == 1){
        MessageBox(
            NULL,
            (LPCTSTR)"Error at WSAStartup()",
            (LPCTSTR)"Client::Error",
            MB_OK|MB_ICONERROR
        );
        WSACleanup();
        return 0;
    }
 
    if(LOBYTE(t_wsa.wVersion) != 2 || HIBYTE(t_wsa.wVersion) != 2)
        MessageBox(
            NULL,
            (LPCTSTR)"Error at WSAStartup()",
            (LPCTSTR)"Client::Error",
            MB_OK|MB_ICONERROR
        );
        WSACleanup();
        return 0;
    }
    sClient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if(sClient == INVALID_SOCKET || iError == 1){
        MessageBox(
            NULL,
            (LPCTSTR)"Invalid Socket!",
            (LPCTSTR)"Client::Error",
            MB_OK|MB_ICONERROR
        );
        WSACleanup();
        return 0;
    }
    SOCKADDR_IN sinClient;
    memset(&sinClient, 0, sizeof(sinClient));
    char cIP[50];
    strcpy(cIP, "127.0.0.1");
    sinClient.sin_family = AF_INET;
    sinClient.sin_addr.s_addr = inet_addr(cIP);
    sinClient.sin_port = htons(100);
    if(connect(sClient, (LPSOCKADDR)&sinClient, sizeof(sinClient)) == SOCKET_ERROR){
        MessageBox(
            NULL,
            (LPCTSTR)"Could not connect to the server!",
            (LPCTSTR)"Client::Error",
            MB_OK|MB_ICONERROR
        );
        WSACleanup();
        return 0;
    }
    while (GetMessage (&messages, NULL, 0, 0))
    {
        TranslateMessage(&messages);
        DispatchMessage(&messages);
    }

    WSACleanup();
    return messages.wParam;
}

LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
        case WM_CREATE:
        {
            CreateWindowEx(
                WS_EX_CLIENTEDGE,
                "edit","",WS_CHILD|WS_VISIBLE|ES_MULTILINE|ES_AUTOHSCROLL,
                10, 100, 200, 20,
                hwnd, (HMENU)IDC_EDIT,
                NULL, 0
                );
            CreateWindowEx(
                WS_EX_CLIENTEDGE,
                "button","Send",WS_CHILD|WS_VISIBLE,
                215, 100, 80, 20,
                hwnd, (HMENU)IDC_BUTTON,
                NULL, 0
                );
            CreateWindowEx(
                WS_EX_CLIENTEDGE,
                "edit","",WS_CHILD|WS_VISIBLE|ES_MULTILINE|WS_VSCROLL|ES_READONLY,
                10, 10, 285, 85,
                hwnd, (HMENU)IDC_STATIC_EDIT,
                NULL, 0
                );
        }
            break;
        case WM_COMMAND:
            switch(LOWORD(wParam)){
                case IDC_BUTTON:
                {
                    postMessage(GetDlgItem(hwnd,IDC_STATIC_EDIT),GetDlgItem(hwnd,IDC_EDIT));
                    break;
                }
                case IDC_EDIT:
                    switch(HIWORD(wParam)){
                        case EN_MAXTEXT:
                            postMessage(GetDlgItem(hwnd,IDC_STATIC_EDIT),GetDlgItem(hwnd,IDC_EDIT));
                            break;
                    }
                    break;
            }
            break;
        case WM_DESTROY:
            PostQuitMessage (0);
            break;
        default:
            return DefWindowProc (hwnd, message, wParam, lParam);
    }
    return 0;
}

void postMessage(HWND hStaticEdit, HWND hEdit){
    TCHAR szBuffer[256];
    TCHAR *prBuffer = szBuffer;
    GetWindowText(hEdit,szBuffer,256);
    if(strlen(szBuffer)!=0){
        SetWindowText(hEdit,"");
        int ndx = GetWindowTextLength(hStaticEdit);
        SendMessage(hStaticEdit,EM_SETSEL,(WPARAM)ndx,(LPARAM)ndx);
        SendMessage(hStaticEdit,EM_REPLACESEL,0,(LPARAM)(LPCTSTR)szBuffer);
        SendMessage(hStaticEdit,EM_REPLACESEL,strlen(szBuffer),(LPARAM)(LPCTSTR)"\n");
        int iRet;
        char buffer[200];
        strcpy(buffer, "Hey server, I just connected!\0");
        iRet = send(sClient, buffer, strlen(buffer), 0);
        if(iRet == SOCKET_ERROR){            
            
            
			//TODO: Change text color to red!...
			
			

            MessageBox(
                NULL,
                (LPCTSTR)"Could not send data!",
                (LPCTSTR)"Client::Error",
                MB_OK|MB_ICONERROR
            );
            WSACleanup();
        }
    }
}
Last edited on
at first glance i would recommend using a rich edit control. Google Richedit in win32 and it should help you out.
or try http://msdn.microsoft.com/en-us/library/windows/desktop/hh298375(v=vs.85).aspx

Assuming you get it working try something like
1
2
3
4
5
6
7
SendMessage(hEdit, EM_SETSEL, start_pos, end_pos); //select text for coloring
CHARFORMAT cf;
memset( &cf, 0, sizeof cf );
cf.cbSize = sizeof cf;
cf.dwMask = CFM_COLOR;
cf.crTextColor = RGB(255,0,0);// <----- the color of the text
SendMessage( hEdit , EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM) &cf);


start_pos is the start of your line (or the length of the text before you enter the line) and end_pos if the end of the current line (or the length of the text after you enter the text)

try it
Thanks nano, just knowing what it's called helps a lot, now first step for me would be to try and create a richedit control, my problem there is, that the example given on the link you posted dosen't seem to work...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
HWND CreateRichEdit(HWND hwndOwner,        // Dialog box handle.
                    int x, int y,          // Location.
                    int width, int height, // Dimensions.
                    HINSTANCE hinst)       // Application or DLL instance.
{
    LoadLibrary(TEXT("Msftedit.dll"));
    
    HWND hwndEdit= CreateWindowEx(0, MSFTEDIT_CLASS, TEXT("Type here"),
        ES_MULTILINE | WS_VISIBLE | WS_CHILD | WS_BORDER | WS_TABSTOP, 
        x, y, width, height, 
        hwndOwner, NULL, hinst, NULL);
        
    return hwndEdit;
}


...it says that MSFTEDIT_CLASS wasn't declared, now i've tryed several versions of richedit, but i just cant get it to work, i dont know if it has anything to do with the LoadLibrary() function? i dont have much experience linking librarys, since you dont do that in labview...
any thoughts?...
If i understand the text in the link you might have a previous version of the Richedit control, try RICHEDIT_CLASS
Last edited on
msfedit.dll requires windows xp sp1 or higher, so try to define WINVER with an appropiate value first.
Hey guys as i mentioned i've allready tryed previous versions, and besides i'm running windows 7, so i cant really see what more i can try? :S
but is there any way i can manually search for one of the richedit librarys and link it, instead of using LoadLibrary()?...
It isn't LoadLibrary that defines MSFTEDIT_CLASS/RICHEDIT_CLASS or not.
Search around for the actual definition of it ( in this case it's L"RICHEDIT50W" for unicode)
Remember this (from msdn) :
To use visual styles with these controls, an application must include a manifest and must call the InitCommonControls function at the beginning of the program.


I don't know what visual styles is referred to as, but if you have strange gfx things try adding such manifest and call InitCommonControls.
AAAAAAHG !!!! OFCOURSE sorry guys ! i simply needed to #include <richedit.h> !!! hmm, now i just cant get it to show, but i'm sure that just takes a bit of practise and research, i'll get back to you once i have a visible control :)...

hey EssGeEich, english isn't my native, but i enterpreted "visual styles" as borders, colors etc. ?...
Last edited on
Well english isn't my native either, but I find strange that for such kind of "visual styles" you need to initialize another component? Because you can draw borders, coloured text and such without extra work, so I'd guess it is something extra? Anyways checking MSDN i found InitCommonControls is outdated and you should use InitCommonControlsEx. What it does is making sure the right Controls (Edit boxes, static controls, etc...) are initialized in the proper way, even if I never needed to call it.
Topic archived. No new replies allowed.