API и FreeBasic. (Цвета контролов, часть вторая)

В этой статье будет описан способ изменения цвета контролов: Static, Edit , Button , ListBox , ScrollBar, Up-Down, ComboBox. Все вышеперечисленные контролы меняют цвет по одному принципу. В процедуре окна родителя отлавливаются сообщения:

WM_CTLCOLORSTATIC - для Static , Button (checkbox,radiobutton,groupbox)
WM_CTLCOLOREDIT - для Edit , ComboBox(заголовок), Up-Down
WM_CTLCOLORLISTBOX - для ListBox , ComboBox(список)
WM_CTLCOLORSCROLLBAR - для ScrollBar

При отлове этого сообщения, в параметре оконной функции Wparam будет указатель на контекст изображения (HDC), в параметре Lparam будет хендл контрола.

После того, как получен контекст изображения, его можно задействовать в функциях:

SetBkColor - цвет фона
SetTextColor - цвет текста

Обе функции имеют 2 параметра (контекст изображения, новый цвет контрола)

Однако для того,  чтобы система могла перекрасить контрол, ей нужно возвратить кисть фона контрола. Создать такую кисть можно с помощью функции CreateSolidBrush , в единственном параметре которой передать цвет фона контрола. По большому счету, цвет фона в параметре CreateSolidBrush может совпадать с цветом фона, указанный в функции SetBkColor, но можно указать цвет фона окна родителя контрола. Если вы передадите другой цвет, то конечно ничего страшного не будет, но эффект покраски контрола вам не понравится :) Важно понимать, что функция CreateSolidBrush пожирает память при каждом ее вызове, поэтому если контрол на протяжении всей работы программы будет скажем красным цветом , кисть лучше создать один раз в сообщении WM_CREATE, а потом просто возвращать ее в сообщении WM_CTLCOLORSTATIC , WM_CTLCOLOREDIT и пр. Если же контрол часто меняет цвет, то перед созданием новой кисти, старую следует удалить с помощью функции DeleteObject.  

Вообще способы создания кистей не ограничиваются функцией CreateSolidBrush. Есть другие функции . Например  CreatePatternBrush способна создать кисть из рисунка и в результате фон контрола будет залит фоном рисунка 

И пример:

#INCLUDE "windows.bi"
Dim msg As MSG
Dim As WNDCLASSEX wc
Dim As String NameClass="MyClass"
Dim As HINSTANCE Hinst=GetModuleHandle(0)

Function wndproc(hwnd As HWND, msg As Uinteger,_
    wparam As WPARAM, lparam As LPARAM) As Integer

    Static hBrush As HBRUSH ' указатель на кисть
    Select Case msg
        Case WM_CREATE
            CreateWindowEx(0,"Static","Цветная надпись",WS_VISIBLE Or WS_CHILD,10,10,120,20,hwnd,Cast(HMENU,1),0,0)
            hBrush = CreateSolidBrush(&hFF0000) ' создаем кисть синего цвета
        Case WM_CTLCOLORSTATIC
            Dim hdc As HDC ' указатель на контекст изображения
            hdc = Cast(HDC,WPARAM) ' получаем контект из WPARAM
            SetBkColor(hdc,&hFF0000) ' красим фон синим цветом
            SetTextColor(hdc,&hFFFFFF) ' красим текст белым цветом
            Return Cint(hBrush) ' возвращаем кисть
        Case WM_DESTROY
            DeleteObject(hBrush) ' удаляем кисть
            PostQuitMessage(0)
    End Select
    Return DefWindowProc(hwnd,msg,wparam,lparam)
End Function

With wc
    .cbSize=SizeOf(WNDCLASSEX)
    .style=CS_HREDRAW Or CS_VREDRAW
    .lpfnWndProc=@wndproc
    .hInstance=Hinst
    .hIcon=LoadIcon(0,IDI_QUESTION)
    .hCursor=LoadCursor(0,IDC_ARROW)
    .hbrBackground=Cast(HBRUSH,COLOR_WINDOW)
    .lpszClassName=StrPtr(NameClass)
    .hIconSm=.hIcon
End With

If RegisterClassEx(@wc)=0 Then
    Print "Register error, press any key"
    Sleep
    End
Endif

CreateWindowEx(0,NameClass,"Главное окно",_
WS_VISIBLE Or WS_OVERLAPPEDWINDOW,100,100,160,100,0,0,Hinst,0)

While GetMessage(@msg,0,0,0)
    TranslateMessage(@msg)
    DispatchMessage(@msg)
Wend

colorstatic.png 

содержание | назад | вперед