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;
Изменение цвета текста в Edit'е
Решить данную проблему пробовал как с использованием диалоговой панели "Цвет", так и с использованием диалогового окна "Шрифт":
Код:
Диалог "Шрифт" изменяет шрифт текста. Цвет текста остаётся без изменений (чёрным). Даже явное задание цвета ни к чему не приведёт:
Код:
CF.rgbColors:=RGB(255, 0, 0);
Также пробовал решить проблему так:
Код:
SetTextColor(hParentDC, CF.rgbColors);
...
SetTextColor(hParentDC, CC.rgbResult);
...
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;
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)
должна предшествовать обработке сообщений; в противном случае цвет фона не изменяется.
Код:
WM_CTLCOLOREDIT:
if (lParam == hEdit) {
SetTextColor ((HDC) wParam, RGB (255, 0, 0));
break;
}
break;
if (lParam == hEdit) {
SetTextColor ((HDC) wParam, RGB (255, 0, 0));
break;
}
break;
Все работает и без DefWindowProc... :)
А что же делать с цветом фона? Почему глючит прорисовка окна?
Если вы используете Delphi, зачем вам вообще мучиться с API Windows в данном случае, когда всё это элементарно решается изменением значения соответствующих свойств элемента управления?
А кто сказал, что я использую среду разработки Delphi? Может я использую Virtual Pascal или Pascal for Windows... Ну так никто не поделится своими соображениями по поводу цвета фона Edit'a?
Код:
result:=longint(CreateSolidBrush(CC.rgbResult));
должна бы работать, только, во-первых, я что-то не понял, что такое у тебя "СС" и, следовательно, что находится в "rgbResult", во-вторых, для чего написано вот это вот
Код:
SetBkColor(HDC(wParam), CC.rgbResult);
и в-третьих, как у тебя вообще в оконной функции передаётся управление на конструкцию "case of", если вначале имеется безусловных выход посредством этого
Код:
result:=DefWindowProc(wnd, msg, wParam, lParam);
Цитата: ShadyMan
и в-третьих, как у тебя вообще в оконной функции передаётся управление на конструкцию "case of", если вначале имеется безусловных выход посредством этого
Код:
result:=DefWindowProc(wnd, msg, wParam, lParam);
Присвоение псевдопеременной Result не является выходом, в отличие от оператора return в Си-подобных языках.
Код:
result:=longint(CreateSolidBrush(CC.rgbResult))
то цвет фона останется без изменения белым, так как мы не изменили цвет фона под символами. Для изменения цвета фона под символами используется функция SetBkColor. В этом случае всё работает стабильно, но, во-первых, Edit постепенно окрашивается в выбранный цвет по мере заполнения Edit’a текстом; во-вторых, при прокрутке текста перерисовка Edit’a сопровождается неприятным мерцанием. (Работает при отсутствии строки result:=longint(CreateSolidBrush(CC.rgbResult)))Использование функции
Код:
SetBkMode(HDC(wParam), TRANSPARENT)
При использовании кода
Код:
WM_CTLCOLOREDIT: begin
if lParam=Edit then begin
SetTextColor(HDC(wParam), ColorText);
SetBkColor(HDC(wParam), ColorBkGrd);
end;
result:=longint(CreateSolidBrush(ColorBkGrd));
end;
if lParam=Edit then begin
SetTextColor(HDC(wParam), ColorText);
SetBkColor(HDC(wParam), ColorBkGrd);
end;
result:=longint(CreateSolidBrush(ColorBkGrd));
end;
происходит сбой во всей системе. Я даже не могу сфоткать экран, чтобы продемонстрировать всю сложность ситуации из-за нехватки памяти, которая возникает в процессе работы приложения...
здесь есть такие, напрмер ALEdit и SXSkinComponents.
Можно попытаться разобраться в работе чужих компонентов, к которым можно применять скины. Вот
Цитата: SergPas
При использовании кода
Код:
WM_CTLCOLOREDIT:
А слабо подсмотреть, как сделано в VCL?
Цитата:
Код:
result:=longint(CreateSolidBrush(ColorBkGrd));
И сколько раз эта кисть создаётся? При каждом вызове функции. Здесь никакой памяти не хватит. Нужно создать кисть только один раз и использовать её.
Проверил на практике, как это всё работает. Действительно, SetBkColor необходима. Но если кисть создаётся 1 раз, никаких сбоев нет: всё красиво перепрорисовывается без побочных эффектов.