Что нового

GUICtrlSetColor() для кнопки

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Кто-нибудь знает простой способ поменять цвет текста на кнопке, но при этом сохранив ее стиль? Вот простой пример.

Код:
GUICreate('MyGUI', 200, 200)
GUICtrlCreateButton('Button', 65, 135, 70, 23)
GUICtrlCreateButton('Button', 65, 165, 70, 23)
GUICtrlSetColor(-1, 0xFF0000)
GUISetState()

Do
Until GUIGetMsg() = -3


Я тут замутил следующее, но думаю должен быть способ попроще.

Код:
#Include <Constants.au3>
#Include <GUIConstantsEx.au3>
#Include <StaticConstants.au3>
#Include <WindowsConstants.au3>
#Include <WinAPI.au3>

Dim $Button[4]

$hForm = GUICreate('MyGUI', 350, 63)

$Button[0] = GUICtrlCreateButton('', 20, 20, 70, 23)
GUICtrlCreateLabel('Button1', 20, 20, 70, 23, BitOR($SS_CENTER, $SS_CENTERIMAGE))
GUICtrlSetBkColor(-1, $GUI_BKCOLOR_TRANSPARENT)
GUICtrlSetColor(-1, 0xFF00FF)

$Button[1] = GUICtrlCreateButton('', 100, 20, 70, 23)
GUICtrlCreateLabel('Button2', 100, 20, 70, 23, BitOR($SS_CENTER, $SS_CENTERIMAGE))
GUICtrlSetBkColor(-1, $GUI_BKCOLOR_TRANSPARENT)
GUICtrlSetColor(-1, 0xFF0000)

$Button[2] = GUICtrlCreateButton('', 180, 20, 70, 23)
GUICtrlCreateLabel('Button1', 180, 20, 70, 23, BitOR($SS_CENTER, $SS_CENTERIMAGE))
GUICtrlSetBkColor(-1, $GUI_BKCOLOR_TRANSPARENT)
GUICtrlSetColor(-1, 0x00FF00)

$Button[3] = GUICtrlCreateButton('', 260, 20, 70, 23)
GUICtrlCreateLabel('Button1', 260, 20, 70, 23, BitOR($SS_CENTER, $SS_CENTERIMAGE))
GUICtrlSetBkColor(-1, $GUI_BKCOLOR_TRANSPARENT)
GUICtrlSetColor(-1, 0x0000FF)

$hDll = DllCallbackRegister('_WinProc', 'ptr', 'hwnd;uint;wparam;lparam')
$pDll = DllCallbackGetPtr($hDll)
For $i = 0 To UBound($Button) - 1
	$hProc = _WinAPI_SetWindowLong(GUICtrlGetHandle($Button[$i]), $GWL_WNDPROC, $pDll)
Next

GUISetState()

While 1
    $Msg = GUIGetMsg()
    Switch $Msg
        Case -3
            ExitLoop
		Case $Button[0], $Button[1], $Button[2], $Button[3]
			MsgBox(0, 'Message', 'Button is pressed.', 0, $hForm)
    EndSwitch
WEnd

For $i = 0 To UBound($Button) - 1
	_WinAPI_SetWindowLong(GUICtrlGetHandle($Button[$i]), $GWL_WNDPROC, $hProc)
Next
DllCallbackFree($hDll)

Func _WinProc($hWnd, $iMsg, $wParam, $lParam)
	Switch $iMsg
		Case $WM_PAINT

			Local $tRECT = DllStructCreate($tagRECT)
			Local $Ret = DllCall('user32.dll', 'int', 'GetUpdateRect', 'hwnd', $hWnd, 'ptr', DllStructGetPtr($tRECT), 'int', 1)

			If $Ret[0] Then
				_WinAPI_InvalidateRect(GUICtrlGetHandle(_WinAPI_GetDlgCtrlID($hWnd) + 1), $tRECT)
			EndIf
	EndSwitch
	Return _WinAPI_CallWindowProc($hProc, $hWnd, $iMsg, $wParam, $lParam)
EndFunc   ;==>_WinProc
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
Yashied [?]
Я тут замутил следующее, но думаю должен быть способ попроще
:laugh: Проще некуда, я думал что даже так оно трудно выполнимо.


Добавлено:
Сообщение автоматически объединено:

Вот так оно будет удобно для использования (на сколько это возможно):

Код:
#Include <Constants.au3>
#Include <GUIConstantsEx.au3>
#Include <StaticConstants.au3>
#Include <WindowsConstants.au3>
#Include <WinAPI.au3>

Global $hLastWndProc
Global $hBtnCtrlWndProc = DllCallbackRegister('__GUICtrlCreateButton_WndProc', 'ptr', 'hwnd;uint;wparam;lparam')
Global $pBtnCtrlWndProc = DllCallbackGetPtr($hBtnCtrlWndProc)

$hForm = GUICreate('Set Button Color - _GUICtrlCreateButtonEx', 370, 65)

$aButton1 = _GUICtrlCreateButtonEx('Button1', 30, 20, 70, 23, BitOR($SS_CENTER, $SS_CENTERIMAGE), -1, 0xFF00FF)
$aButton2 = _GUICtrlCreateButtonEx('Button2', 110, 20, 70, 23, BitOR($SS_CENTER, $SS_CENTERIMAGE), -1, 0xFF0000)
$aButton3 = _GUICtrlCreateButtonEx('Button3', 190, 20, 70, 23, BitOR($SS_CENTER, $SS_CENTERIMAGE), -1, 0x00FF00)
$aButton4 = _GUICtrlCreateButtonEx('Button4', 270, 20, 70, 23, BitOR($SS_CENTER, $SS_CENTERIMAGE), -1, 0x0000FF)

GUISetState()

While 1
    $nMsg = GUIGetMsg()
	
    Switch $nMsg
		Case $GUI_EVENT_CLOSE
			For $i = 1 To 4
				_WinAPI_SetWindowLong(Execute("$aButton" & $i & "[2]"), $GWL_WNDPROC, $hLastWndProc)
			Next
			
			DllCallbackFree($hBtnCtrlWndProc)
			
            Exit
        Case $aButton1[0], $aButton2[0], $aButton3[0], $aButton4[0]
			MsgBox(64, 'Message', GUICtrlRead($nMsg+1, 1) & ' is pressed.', 0, $hForm)
    EndSwitch
WEnd

Func _GUICtrlCreateButtonEx($sText, $iLeft, $iTop, $iWidth = -1, $iHeight = -1, $nStyle = -1, $nExStyle = -1, $nColor = -1)
	Local $anButton[3]
	
	$anButton[0] = GUICtrlCreateButton('', $iLeft, $iTop, $iWidth, $iHeight)
	$anButton[1] = GUICtrlCreateLabel($sText, $iLeft, $iTop, $iWidth, $iHeight, BitOR($SS_CENTER, $SS_CENTERIMAGE))
	$anButton[2] = GUICtrlGetHandle($anButton[0])
	GUICtrlSetBkColor($anButton[1], $GUI_BKCOLOR_TRANSPARENT)
	
	GUICtrlSetColor($anButton[1], $nColor)
	$hLastWndProc = _WinAPI_SetWindowLong($anButton[2], $GWL_WNDPROC, $pBtnCtrlWndProc)
	
	Return $anButton
EndFunc

Func __GUICtrlCreateButton_WndProc($hWnd, $iMsg, $wParam, $lParam)
    Switch $iMsg
        Case $WM_PAINT
            Local $tRECT = DllStructCreate($tagRECT)
            Local $Ret = DllCall('user32.dll', 'int', 'GetUpdateRect', 'hwnd', $hWnd, 'ptr', DllStructGetPtr($tRECT), 'int', 1)
			
            If $Ret[0] Then
                _WinAPI_InvalidateRect(GUICtrlGetHandle(_WinAPI_GetDlgCtrlID($hWnd) + 1), $tRECT)
            EndIf
	EndSwitch
	
    Return _WinAPI_CallWindowProc($hLastWndProc, $hWnd, $iMsg, $wParam, $lParam)
EndFunc
 
Автор
Yashied

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Есть другая идея с использованием uxtheme.dll, позже попробую реализовать...
 
Автор
Yashied

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Вот написал функцию, получилось не совсем "попроще", но более "правильно". Тестировал на Windows XP с разными темами (оффициальными).
 
Верх