Что нового

_GUICtrlButton_SetTextColor() - изменение цвета текста для кнопок

Yashied

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

Код:
#Include <GUIButton.au3>
#Include <GUIImageList.au3>
#Include <WinAPI.au3>
#Include <WindowsConstants.au3>

GUICreate('MyGUI', 200, 200)
GUICtrlCreateButton('', 65, 170, 70, 23)
_GUICtrlButton_SetTextColor(-1, 'OK', 0xFF0000)
GUISetState()

Do
Until GUIGetMsg() = -3

Func _GUICtrlButton_SetTextColor($iCtrlID, $sText, $iTextColor)

	Local $hWnd, $hTheme, $hImageList, $hBitmap, $hBack, $hDC, $hMemDC, $hSrcDC, $tRect, $pRect, $Width, $Height, $Prev, $Flags = BitOR($DT_CENTER, $DT_SINGLELINE, $DT_VCENTER)

	$hWnd = GUICtrlGetHandle($iCtrlID)
	If Not $hWnd Then
		Return 0
	EndIf
	$hTheme = DllCall('uxtheme.dll', 'ptr', 'OpenThemeData', 'hwnd', $hWnd, 'wstr', 'BUTTON')
	If (@error) Or (Not $hTheme[0]) Then
		GUICtrlSetColor($iCtrlID, $iTextColor)
		GUICtrlSetData($iCtrlID, $sText)
		Return 1
	EndIf
	$Width = _WinAPI_GetClientWidth($hWnd)
	$Height = _WinAPI_GetClientHeight($hWnd)
	$hImageList = _GUIImageList_Create($Width - 8, $Height - 8, 4, 4)
	$tRect = DllStructCreate('int[4]')
	DllStructSetData($tRect, 1, -4, 1)
	DllStructSetData($tRect, 1, -4, 2)
	DllStructSetData($tRect, 1, $Width - 4, 3)
	DllStructSetData($tRect, 1, $Height - 4, 4)
	$pRect = DllStructGetPtr($tRect)
	$hDC = _WinAPI_GetDC(0)
	$hMemDC = _WinAPI_CreateCompatibleDC($hDC)
	$hSrcDC = _WinAPI_CreateCompatibleDC($hDC)
	$hBitmap = _WinAPI_CreateCompatibleBitmap($hDC, $Width - 8, $Height - 8)
	$hBack = _WinAPI_CreateCompatibleBitmap($hDC, $Width - 8, $Height - 8)
	_WinAPI_ReleaseDC(0, $hDC)
	_WinAPI_SelectObject($hSrcDC, $hBack)
	_WinAPI_SelectObject($hMemDC, _SendMessage($hWnd, $WM_GETFONT))
	_WinAPI_SetTextColor($hMemDC, BitOR(BitAND($iTextColor, 0x00FF00), BitShift(BitAND($iTextColor, 0x0000FF), -16), BitShift(BitAND($iTextColor, 0xFF0000), 16)))
	_WinAPI_SetBkMode($hMemDC, $TRANSPARENT)
	; PBS_NORMAL, PBS_HOT, PBS_PRESSED, PBS_DISABLED, PBS_DEFAULTED
	For $i = 1 To 5
		$Prev = _WinAPI_SelectObject($hMemDC, $hBitmap)
		DllCall('uxtheme.dll', 'int', 'DrawThemeBackground', 'ptr', $hTheme[0], 'hwnd', $hSrcDC, 'int', 1, 'int', $i, 'ptr', $pRect, 'ptr', 0)
		_WinAPI_BitBlt($hMemDC, 0, 0, $Width - 8, $Height - 8, $hSrcDC, 0, 0, $MERGECOPY)
		If $i = 4 Then
			DllCall('uxtheme.dll', 'int', 'DrawThemeText', 'ptr', $hTheme[0], 'hwnd', $hMemDC, 'int', 1, 'int', 4, 'wstr', $sText, 'int', -1, 'dword', $Flags, 'dword', 0, 'ptr', $pRECT)
		Else
			_WinAPI_DrawText($hMemDC, $sText, $tRect, $Flags)
		EndIf
		_WinAPI_SelectObject($hMemDC, $Prev)
		_GUIImageList_Add($hImageList, $hBitmap)
	Next
	; PBS_HOT (Stylus Hot)
	_GUIImageList_SetImageCount($hImageList, 6)
	_GUIImageList_Copy($hImageList, 1, 5)
	_WinAPI_DeleteDC($hMemDC)
	_WinAPI_DeleteDC($hSrcDC)
	_WinAPI_DeleteObject($hBitmap)
	_WinAPI_DeleteObject($hBack)
	DllCall('uxtheme.dll', 'int', 'CloseThemeData', 'ptr', $hTheme[0])
	$Prev = _GUICtrlButton_GetImageList($hWnd)
	If $Prev[0] Then
		_GUIImageList_Destroy($Prev[0])
	EndIf
	GUICtrlSetData($iCtrlID, '')
	If Not _GUICtrlButton_SetImageList($hWnd, $hImageList, 4) Then
		_GUIImageList_Destroy($hImageList)
		Return 0
	EndIf
	Return 1
EndFunc   ;==>_GUICtrlButton_SetTextColor
 
Автор
Yashied

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Re: _GUIButtonSetTextColor() - изменение цвета текста для кнопок

У кого Vista/7, просьба протестировать эту функцию. Я тестировал только на XP.
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
Re: _GUIButtonSetTextColor() - изменение цвета текста для кнопок

Супер.

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

Код:
GUICtrlCreateButton('OK', 65, 170, 70, 23)
_GUICtrlButton_SetTextColor(-1, 0xFF0000)

...

Func _GUICtrlButton_SetTextColor($iCtrlID, $iTextColor)
	Local $sText, $hWnd, $hTheme, $hImageList, $hBitmap, $hObj, $hDC, $hMemDC, $tRect, $pRect, $Data, $Width, $Height, $Prev = -1
	$sText = GUICtrlRead($iCtrlID, 1)
	
	....
EndFunc


Кстати вот такое название подходит больше, т.к соответствует другим функциям для работы с кнопками.
 
Автор
Yashied

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Re: _GUIButtonSetTextColor() - изменение цвета текста для кнопок

После того, как цвет установлен, кнопка должна быть пустой (без текста), в противном случае он будет отображаться поверх кнопки (по крайней мере в XP).

В Vist'е работает?
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
Re: _GUIButtonSetTextColor() - изменение цвета текста для кнопок

Yashied [?]
После того, как цвет установлен, кнопка должна быть пустой (без текста), в противном случае он будет отображаться поверх кнопки
Ну ведь в функции оно так и происходит (кнопка очищается).

В Vist'е работает?
У меня нет Vist'ы под рукой, поэтому проверить не могу :(
 
Автор
Yashied

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Re: _GUIButtonSetTextColor() - изменение цвета текста для кнопок

CreatoR [?]
Ну ведь в функции оно так и происходит (кнопка очищается).

Да, но при следующем вызове... :smile:
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
Re: _GUIButtonSetTextColor() - изменение цвета текста для кнопок

Yashied [?]
Да, но при следующем вызове
Понял... тогда нужно строить функцию _GUICtrlButton_CreateEx :D


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

Или возвращать текст:

Код:
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <GUIButton.au3>
#include <GUIImageList.au3>
#include <WinAPI.au3>

GUICreate('_GUICtrlButton_SetTextColor Example', 350, 200)

$nOK_Button = GUICtrlCreateButton('OK', 25, 170, 70, 23)
$sText = _GUICtrlButton_SetTextColor(-1, 0xFF0000)
_GUICtrlButton_SetTextColor(-1, 0x0000FF, $sText)

$nCancel_Button = GUICtrlCreateButton('Cancel', 110, 170, 70, 23)
_GUICtrlButton_SetTextColor(-1, 0x0000FF)

GUISetState()

While 1
	Switch GUIGetMsg()
		Case $GUI_EVENT_CLOSE, $nOK_Button, $nCancel_Button
			Exit
	EndSwitch
WEnd

Func _GUICtrlButton_SetTextColor($iCtrlID, $iTextColor, $sText = '')
	Local $hWnd, $hTheme, $hImageList, $hBitmap, $hObj, $hDC, $hMemDC, $tRect, $pRect, $Data, $Width, $Height, $Prev = -1
	
	If $sText = '' Then
		$sText = GUICtrlRead($iCtrlID, 1)
	EndIf
	
	$hWnd = GUICtrlGetHandle($iCtrlID)
	
	If Not $hWnd Or StringStripWS($sText, 8) = '' Then
		Return 0
	EndIf
	
	$hTheme = DllCall('uxtheme.dll', 'ptr', 'OpenThemeData', 'hwnd', $hWnd, 'wstr', 'Button')
	
	If @error Or Not $hTheme[0] Then
		GUICtrlSetColor($iCtrlID, $iTextColor)
		GUICtrlSetData($iCtrlID, $sText)
		Return $sText
	EndIf
	
	$hTheme = $hTheme[0]
	$Width = _WinAPI_GetClientWidth($hWnd)
	$Height = _WinAPI_GetClientHeight($hWnd)
	$hImageList = _GUIImageList_Create($Width - 8, $Height - 8, 4, 4)
	$hBitmap = _WinAPI_CreateBitmap($Width - 8, $Height - 8, 1, 32)
	$tRect = DllStructCreate('int[4]')
	DllStructSetData($tRect, 1, -4, 1)
	DllStructSetData($tRect, 1, -4, 2)
	DllStructSetData($tRect, 1, $Width - 4, 3)
	DllStructSetData($tRect, 1, $Height - 4, 4)
	$pRect = DllStructGetPtr($tRect)
	$hDC = _WinAPI_GetDC(0)
	$hMemDC = _WinAPI_CreateCompatibleDC($hDC)
	_WinAPI_ReleaseDC(0, $hDC)
	_WinAPI_SelectObject($hMemDC, _SendMessage($hWnd, $WM_GETFONT))
	_WinAPI_SetTextColor($hMemDC, BitOR(BitAND($iTextColor, 0x00FF00), BitShift(BitAND($iTextColor, 0x0000FF), -16), BitShift(BitAND($iTextColor, 0xFF0000), 16)))
	_WinAPI_SetBkMode($hMemDC, $TRANSPARENT)
	; PBS_NORMAL
	$hObj = _WinAPI_SelectObject($hMemDC, $hBitmap)
	DllCall('uxtheme.dll', 'int', 'DrawThemeBackground', 'ptr', $hTheme, 'hwnd', $hMemDC, 'int', 1, 'int', 1, 'ptr', $pRect, 'ptr', 0)
	_WinAPI_DrawText($hMemDC, $sText, $tRect, BitOR($DT_CENTER, $DT_SINGLELINE, $DT_VCENTER))
	_WinAPI_SelectObject($hMemDC, $hObj)
	_GUIImageList_Add($hImageList, $hBitmap)
	; PBS_HOT
	$hObj = _WinAPI_SelectObject($hMemDC, $hBitmap)
	DllCall('uxtheme.dll', 'int', 'DrawThemeBackground', 'ptr', $hTheme, 'hwnd', $hMemDC, 'int', 1, 'int', 2, 'ptr', $pRect, 'ptr', 0)
	_WinAPI_DrawText($hMemDC, $sText, $tRect, BitOR($DT_CENTER, $DT_SINGLELINE, $DT_VCENTER))
	_WinAPI_SelectObject($hMemDC, $hObj)
	_GUIImageList_Add($hImageList, $hBitmap)
	; PBS_PRESSED
	$hObj = _WinAPI_SelectObject($hMemDC, $hBitmap)
	DllCall('uxtheme.dll', 'int', 'DrawThemeBackground', 'ptr', $hTheme, 'hwnd', $hMemDC, 'int', 1, 'int', 3, 'ptr', $pRect, 'ptr', 0)
	_WinAPI_DrawText($hMemDC, $sText, $tRect, BitOR($DT_CENTER, $DT_SINGLELINE, $DT_VCENTER))
	_WinAPI_SelectObject($hMemDC, $hObj)
	_GUIImageList_Add($hImageList, $hBitmap)
	; PBS_DISABLED
	$hObj = _WinAPI_SelectObject($hMemDC, $hBitmap)
	DllCall('uxtheme.dll', 'int', 'DrawThemeBackground', 'ptr', $hTheme, 'hwnd', $hMemDC, 'int', 1, 'int', 4, 'ptr', $pRect, 'ptr', 0)
	$Data = DllCall('uxtheme.dll', 'int', 'GetThemeColor', 'ptr', $hTheme, 'int', 1, 'int', 4, 'int', 3803, 'dword*', 0)
	
	If (Not @error) And (Not $Data[0]) Then
		$Prev = _WinAPI_SetTextColor($hMemDC, $Data[5])
	EndIf
	
	_WinAPI_DrawText($hMemDC, $sText, $tRect, BitOR($DT_CENTER, $DT_SINGLELINE, $DT_VCENTER))
	
	If $Prev > -1 Then
		_WinAPI_SetTextColor($hMemDC, $Prev)
	EndIf
	
	_WinAPI_SelectObject($hMemDC, $hObj)
	_GUIImageList_Add($hImageList, $hBitmap)
	; PBS_DEFAULTED
	$hObj = _WinAPI_SelectObject($hMemDC, $hBitmap)
	DllCall('uxtheme.dll', 'int', 'DrawThemeBackground', 'ptr', $hTheme, 'hwnd', $hMemDC, 'int', 1, 'int', 5, 'ptr', $pRect, 'ptr', 0)
	_WinAPI_DrawText($hMemDC, $sText, $tRect, BitOR($DT_CENTER, $DT_SINGLELINE, $DT_VCENTER))
	_WinAPI_SelectObject($hMemDC, $hObj)
	_GUIImageList_Add($hImageList, $hBitmap)
	_WinAPI_DeleteDC($hMemDC)
	_WinAPI_DeleteObject($hBitmap)
	DllCall('uxtheme.dll', 'int', 'CloseThemeData', 'ptr', $hTheme)
	$Data = _GUICtrlButton_GetImageList($hWnd)
	
	If $Data[0] Then
		_GUIImageList_Destroy($Data[0])
	EndIf
	
	GUICtrlSetData($iCtrlID, '')
	
	If Not _GUICtrlButton_SetImageList($hWnd, $hImageList, 4) Then
		_GUIImageList_Destroy($hImageList)
		Return 0
	EndIf
	
	Return $sText
EndFunc


:laugh:


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

Кстати, на Vista можно было бы использовать _GUICtrlButton_SetNote, а потом аналогично читать его с кнопки в следующий раз.
 

FlatX007

Tattoo!
Сообщения
197
Репутация
35
Re: _GUIButtonSetTextColor() - изменение цвета текста для кнопок

цвет только белый.
 
Автор
Yashied

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Re: _GUIButtonSetTextColor() - изменение цвета текста для кнопок

CreatoR [?]
...тогда нужно строить функцию _GUICtrlButton_CreateEx

Тут возникают ненужные дополнительные сложности связанные со шрифтом + придется дополнительно писать фунцию изменения цвета для уже существующей кнопки.


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

Эта :Censored: Vista, все никак у людей... Поднял Vist'у, сейчас все исправлю. Кстати, почему-то не могу зайти на форум в IE7...


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

FlatX007 сказал(а):
...цвет только белый.

Поправил, см. первый пост.


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

OffTopic:
"Windows 7 Максимальная" (Это типа Ultimate?)

:rofl:
 
Автор
Yashied

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Немного упростил (уменьшил) код.
 

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4,020
Репутация
626
Автор
Yashied

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
OffTopic:
Просто некоторые слова лучше не переводить... Особенно в этом плане меня "порадовал" в свое время CorelDraw...
 
Верх