Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Изменение цвета текста в Edit'е

397
19 августа 2007 года
SergPas
527 / / 03.02.2007
Как можно изменить цвет текста в Edit'е?
Решить данную проблему пробовал как с использованием диалоговой панели "Цвет", так и с использованием диалогового окна "Шрифт":
Код:
Var lf:LOGFONT;
     hParentDC:HDC;
     Font:HFONT;
     CF:TCHOOSEFONT;
     acrCustClr:array[0..15] of COLORREF;
     ...
function WndProc(wnd:HWND; msg, wParam, lPapram:longint):longint; stdcall;
begin
result:=DefWindowProc(wnd, msg, wParam, lParam);
case msg of
WM_CREATE: begin
           hParentDC:=GetDC(Edit);
           lf.lfHeight:= -MulDiv( 10, GetDeviceCaps(hParentDC,LOGPIXELSY), 72);
           lf.lfWidth:= 0;
           lf.lfEscapement:= 0;
           lf.lfOrientation:=0;
           lf.lfWeight:= FW_NORMAL;
           lf.lfItalic:= 0;
           lf.lfUnderline:= 0;
           lf.lfStrikeOut:= 0;
           lf.lfCharSet:= ANSI_CHARSET;
           lf.lfOutPrecision:= OUT_TT_PRECIS;
           lf.lfClipPrecision:= CLIP_DEFAULT_PRECIS;
           lf.lfQuality:= DEFAULT_QUALITY;
           lf.lfPitchAndFamily:= DEFAULT_PITCH or FF_DONTCARE;
           lf.lfFaceName:='Arial';
           Font:=CreateFontIndirect(lf);
           Edit:=CreateWindowEx(0,'Edit','',WS_CHILD or WS_VISIBLE or ES_MULTILINE or
                                ES_AUTOVSCROLL or WS_VSCROLL, 0, 0, 0, 0, wnd,
                                HMENU(20), hInstance, nil);
           SendMessage(Edit, WM_SETFONT, integer(Font),MakelParam(0,1));
           SetFocus(Edit);

           //Инициализация диалога "Цвет"
           FillChar(CC, SizeOf(TCHOOSECOLOR),0);
           CC.lStructSize:=SizeOf(TCHOOSECOLOR);
           CC.hWndOwner:=wnd;
           CC.hInstance:=hInstance;
           CC.lpCustColors:=@acrCustClr;
           CC.Flags:=CC_FULLOPEN;

           //Инициализация диалога "Шрифт"
           FillChar(CF, SizeOf(TCHOOSEFONT),0);
           CF.lStructSize:=SizeOf(TCHOOSEFONT);
           CF.hWndOwner:=Wnd;
           CF.lpLogFont:=@lf;
           CF.Flags:=CF_SCREENFONTS or CF_EFFECTS;
           CF.hDC:=hParentDC;
           end;
WM_COMMAND: case wParam of
                      118: begin //Использование диалога "Цвет"
                             ChooseColor(CC);
                             CF.rgbColors:=CC.rgbResult;
                             Font:=CreateFontIndirect(CF.lpLogFont^);
                             PrevFont:=SelectObject(hParentDC, Font);
                       SendMessage(Edit, WM_SETFONT, Font, MakelParam(0, 1));
                             SetFocus(Edit);
                             end;
                      119: begin //Использование диалога "Шрифт"
                             ChooseFont(CF);
                             Font:=CreateFontIndirect(CF.lpLogFont^);
                             PrevFont:=SelectObject(hParentDC, Font);
       SendMessage(Edit, WM_SETFONT, integer(PrevFont),MakelParam(0,1));
                             SetFocus(Edit);
                             end;
                      end;
end;
end;

Диалог "Шрифт" изменяет шрифт текста. Цвет текста остаётся без изменений (чёрным). Даже явное задание цвета ни к чему не приведёт:
 
Код:
CF.rgbColors:=RGB(255, 0, 0);

Также пробовал решить проблему так:
 
Код:
SetTextColor(hParentDC, CF.rgbColors);
...
SetTextColor(hParentDC, CC.rgbResult);

Возникают проблемы и при изменении цвета фона Edit'a.
Цвет фона изменяю так:
Код:
function WndProc(wnd:HWND; msg, wParam, lParam:longint):longint; stdcall;
Begin
result:=DefWindowProc(wnd, msg, wParam, lParam);
case msg of
WM_COMMAND: case wParam of
                      ...
                      117: begin
                             ChooseColor(CC);
                         SendMessage(Edit, WM_CTLCOLOREDIT, hParentDC, Edit);
                             SetFocus(Edit);
                             end;
                        end;
WM_CTLCOLOREDIT: begin
                             SetBkColor(HDC(wParam), CC.rgbResult);
                             result:=longint(CreateSolidBrush(CC.rgbResult));
                             end;
end;
End;

В этом случае цвет фона Edit'а изменяется, но возникают серьёзные проблемы с прорисовкой всего окна в случае многострочного редактора текста. При этом также следует учесть, что строка
 
Код:
result:=DefWindowProc(wnd, msg, wParam, lParam)

должна предшествовать обработке сообщений; в противном случае цвет фона не изменяется.
22K
19 августа 2007 года
Pastor
43 / / 16.05.2007
 
Код:
WM_CTLCOLOREDIT:
if (lParam == hEdit) {
    SetTextColor ((HDC) wParam, RGB (255, 0, 0));
    break;
}
break;

Все работает и без DefWindowProc... :)
397
19 августа 2007 года
SergPas
527 / / 03.02.2007
А что же делать с цветом фона? Почему глючит прорисовка окна?
3.3K
19 августа 2007 года
ShadyMan
191 / / 15.07.2006
Если вы используете Delphi, зачем вам вообще мучиться с API Windows в данном случае, когда всё это элементарно решается изменением значения соответствующих свойств элемента управления?
397
22 августа 2007 года
SergPas
527 / / 03.02.2007
А кто сказал, что я использую среду разработки Delphi? Может я использую Virtual Pascal или Pascal for Windows... Ну так никто не поделится своими соображениями по поводу цвета фона Edit'a?
3.3K
22 августа 2007 года
ShadyMan
191 / / 15.07.2006
Я, конечно, не знаю, что такое "Virtual Pascal или Pascal for Windows", но если там есть какие-то свои средства, то их и надо использовать. Если ты ограничиваешься чистым API, то вот эта строка
 
Код:
result:=longint(CreateSolidBrush(CC.rgbResult));

должна бы работать, только, во-первых, я что-то не понял, что такое у тебя "СС" и, следовательно, что находится в "rgbResult", во-вторых, для чего написано вот это вот
 
Код:
SetBkColor(HDC(wParam), CC.rgbResult);

и в-третьих, как у тебя вообще в оконной функции передаётся управление на конструкцию "case of", если вначале имеется безусловных выход посредством этого
 
Код:
result:=DefWindowProc(wnd, msg, wParam, lParam);
10
22 августа 2007 года
Freeman
3.2K / / 06.03.2004
Цитата: ShadyMan
и в-третьих, как у тебя вообще в оконной функции передаётся управление на конструкцию "case of", если вначале имеется безусловных выход посредством этого
 
Код:
result:=DefWindowProc(wnd, msg, wParam, lParam);


Присвоение псевдопеременной Result не является выходом, в отличие от оператора return в Си-подобных языках.

397
22 августа 2007 года
SergPas
527 / / 03.02.2007
CC- это структура CHOOSECOLOR диалогового окна «Цвет». Поле rgbResult содержит выбранный пользователем цвет. Попробую более детально описать процесс закраски Edit’a. Если использовать для закраски только строку
 
Код:
result:=longint(CreateSolidBrush(CC.rgbResult))

то цвет фона останется без изменения белым, так как мы не изменили цвет фона под символами. Для изменения цвета фона под символами используется функция SetBkColor. В этом случае всё работает стабильно, но, во-первых, Edit постепенно окрашивается в выбранный цвет по мере заполнения Edit’a текстом; во-вторых, при прокрутке текста перерисовка Edit’a сопровождается неприятным мерцанием. (Работает при отсутствии строки result:=longint(CreateSolidBrush(CC.rgbResult)))Использование функции
 
Код:
SetBkMode(HDC(wParam), TRANSPARENT)
в данном случае недопустимо, так как при прокрутке текста происходит наложение текста, то есть перерисовка Edit’a не осуществляется.
При использовании кода
 
Код:
WM_CTLCOLOREDIT: begin
                             if lParam=Edit then begin
                             SetTextColor(HDC(wParam), ColorText);
                             SetBkColor(HDC(wParam), ColorBkGrd);
                             end;
                             result:=longint(CreateSolidBrush(ColorBkGrd));
                             end;

происходит сбой во всей системе. Я даже не могу сфоткать экран, чтобы продемонстрировать всю сложность ситуации из-за нехватки памяти, которая возникает в процессе работы приложения...
16K
22 августа 2007 года
Zbyszek
118 / / 08.08.2007
Можно попытаться разобраться в работе чужих компонентов, к которым можно применять скины. Вот здесь есть такие, напрмер ALEdit и SXSkinComponents.
10
22 августа 2007 года
Freeman
3.2K / / 06.03.2004
Цитата: SergPas

При использовании кода
 
Код:
WM_CTLCOLOREDIT:


А слабо подсмотреть, как сделано в VCL?

5.3K
22 августа 2007 года
Somebody
185 / / 24.12.2006
Цитата:
 
Код:
result:=longint(CreateSolidBrush(ColorBkGrd));


И сколько раз эта кисть создаётся? При каждом вызове функции. Здесь никакой памяти не хватит. Нужно создать кисть только один раз и использовать её.

3.3K
22 августа 2007 года
ShadyMan
191 / / 15.07.2006
Проверил на практике, как это всё работает. Действительно, SetBkColor необходима. Но если кисть создаётся 1 раз, никаких сбоев нет: всё красиво перепрорисовывается без побочных эффектов.
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог