Что нового

Добавление текста на кнопки с рисунком

avtoIT

Новичок
Сообщения
94
Репутация
0
В этой теме http://autoit-script.ru/index.php?topic=21707.0, Yashied предложил вариант решения этой проблемы, но я не смог разобраться.

Yashied сказал(а):
Почему? Берите текст из .ini и рисуйте его на пустой кнопке с помощью GDI или GDI+. Затем обновляйте изображения кнопок.



У меня было что-то наподобие этого:
Код:
_GDIPlus_Startup ()
$hGraphic = _GDIPlus_GraphicsCreateFromHWND($Form1)
_GDIPlus_GraphicsDrawString($hGraphic, "Hello world", 140, 110)


но текст нигде не показывается, или нужно в $hGraphic складывать дескриптор кнопки?
 

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
avtoIT
что есть на данный момент?
можно увидеть весь код? иначе это будет долго
 
Автор
A

avtoIT

Новичок
Сообщения
94
Репутация
0
Код:
#include <ButtonConstants.au3>
#include <ComboConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#Include <Skin.au3>
#include <StaticConstants.au3>
#include <GDIPlus.au3>
#include <WinAPIMisc.au3>

Global $Form1, $Button1, $Skin = True

$Form1 = GUICreate("Form1", 300, 180, -1, -1, $WS_BORDER + $WS_POPUP, 0);, $WS_EX_CONTROLPARENT)
GUICtrlCreatePic (@ScriptDir & '\bck.bmp.png', 0, 0, 300, 180)
GUICtrlSetState(-1, $GUI_DISABLE)
$Button1 = _Skin_AddButton(90, 90, 120, 42, '1.png', '2.png', '3.png', '3.png', '3.png', 1)

$Combo1 = GUICtrlCreateCombo('English', 80, 55, 140, 25, $CBS_DROPDOWNLIST + $WS_VSCROLL)
GUICtrlSetData (-1, 'Русский')
GUICtrlSetFont(-1, 10, 400, 0, 'Arial')
;_Skin_EnableFocus(1)
GUIRegisterMsg($WM_COMMAND, 'WM_COMMAND')
GUIRegisterMsg($WM_NCHITTEST, 'WM_NCHITTEST')
GUISetState(@SW_SHOW)

While 1
	If $Skin Then
		_Skin_Helper($Form1)
	EndIf
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit
        Case $Button1
            ;SoundPlay ("zvyuk.wav")
            ;_WinAPI_PlaySound ("zvvv.wav", $SND_ASYNC + $SND_NOWAIT)
            MsgBox (0, 0, GUICtrlRead($Combo1))
    EndSwitch
WEnd

Func WM_COMMAND($hWnd, $iMsg, $wParam, $lParam)

	Local $Msg = BitShift($wParam, 16)

	Switch $hWnd
		Case $Form1
			Switch BitAND($wParam, 0xFFFF)
				Case $Combo1
					Switch $Msg
						Case $CBN_CLOSEUP
							$Skin = 1
						Case $CBN_DROPDOWN
							$Skin = 0
						Case Else

					EndSwitch
			EndSwitch
	EndSwitch
	Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_COMMAND

Func WM_NCHITTEST($hWnd, $iMsg, $wParam, $lParam)
    Switch $hWnd
        Case $Form1
            If $skData[0][3] > 0 Then
                Return $GUI_RUNDEFMSG
            EndIf
            Local $Info = GUIGetCursorInfo($Form1)
            If Not @Error Then
                Switch $Info[4]
                    Case $Button1
                        ; Nothing
                    Case Else
						Return $HTCAPTION
                EndSwitch
            EndIf
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NCHITTEST


Yashied сказал(а):
avtoIT сказал(а):
Текст на кнопку нужен был в основном для того, чтобы поддерживать разные языки, получается, что нельзя будет использовать простой .ini файл с фразами?
Почему? Берите текст из .ini и рисуйте его на пустой кнопке с помощью GDI или GDI+. Затем обновляйте изображения кнопок.

Я просто не понимаю, как на кнопке из Skin.au3 нарисовать строку=(
 
A

Alofa

Гость
avtoIT сказал(а):
... Я просто не понимаю, как на кнопке из Skin.au3 нарисовать строку=(
К примеру так:
Код:
#include <ButtonConstants.au3>
#include <ComboConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#Include <Skin.au3>
#include <StaticConstants.au3>
#include <GDIPlus.au3>
#include <WinAPIMisc.au3>

Global $Form1, $Button1, $Skin = True

$Form1 = GUICreate("Form1", 300, 180, -1, -1, $WS_BORDER + $WS_POPUP, 0);, $WS_EX_CONTROLPARENT)
GUICtrlCreatePic (@ScriptDir & '\bck.bmp.png', 0, 0, 300, 180)
GUICtrlSetState(-1, $GUI_DISABLE)
$Button1 = _Skin_AddButton(90, 90, 120, 42, '1.png', '2.png', '3.png', '3.png', '3.png', 1)


$Combo1 = GUICtrlCreateCombo('English', 80, 55, 140, 25, $CBS_DROPDOWNLIST + $WS_VSCROLL)
GUICtrlSetData (-1, 'Русский')
GUICtrlSetFont(-1, 10, 400, 0, 'Arial')
;_Skin_EnableFocus(1)
GUIRegisterMsg($WM_COMMAND, 'WM_COMMAND')
GUIRegisterMsg($WM_NCHITTEST, 'WM_NCHITTEST')
GUISetState(@SW_SHOW)

_GDIPlus_Startup()
_DrawText('Мой текст')

While 1
    If $Skin Then
        _Skin_Helper($Form1)
    EndIf
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit
        Case $Button1
            ;SoundPlay ("zvyuk.wav")
            ;_WinAPI_PlaySound ("zvvv.wav", $SND_ASYNC + $SND_NOWAIT)
            MsgBox (0, 0, GUICtrlRead($Combo1))
    EndSwitch
WEnd


Func _DrawText($sString)
	; Пример взят из http://autoit-script.ru/autoit3_docs/libfunctions/_gdiplus_graphicsdrawstringex.htm

	$hGraphic = _GDIPlus_GraphicsCreateFromHWND($Form1)
	$hBrush = _GDIPlus_BrushCreateSolid(0xFF00007F)
	$hFormat = _GDIPlus_StringFormatCreate()
	$hFamily = _GDIPlus_FontFamilyCreate("Arial")
	$hFont = _GDIPlus_FontCreate($hFamily, 12, 2)
	$tLayout = _GDIPlus_RectFCreate(100, 100, 0, 0)
	$aInfo = _GDIPlus_GraphicsMeasureString($hGraphic, $sString, $hFont, $tLayout, $hFormat)
	_GDIPlus_GraphicsDrawStringEx($hGraphic, $sString, $hFont, $aInfo[0], $hFormat, $hBrush)
	
	_GDIPlus_FontDispose($hFont) ;			-|
	_GDIPlus_FontFamilyDispose($hFamily) ;	 | Блок освобождает объекты и закрывает GDI+
	_GDIPlus_StringFormatDispose($hFormat) ; | - его можно задействовать в конце работы скрипта,
	_GDIPlus_BrushDispose($hBrush) ;		 | когда отображения текста уже не требуется.
	_GDIPlus_GraphicsDispose($hGraphic) ;	 |
	_GDIPlus_Shutdown() ;					-|
EndFunc
 
Автор
A

avtoIT

Новичок
Сообщения
94
Репутация
0
Уже продвижение, но при первом же наведении на кнопку, текст исчезает (проваливается под нее) :scratch:
 
A

Alofa

Гость
А на что вам в скрипте:
Код:
Func WM_COMMAND($hWnd, $iMsg, $wParam, $lParam)
; ...
EndFunc 
; И
Func WM_NCHITTEST($hWnd, $iMsg, $wParam, $lParam)
; ...
EndFunc
 
Автор
A

avtoIT

Новичок
Сообщения
94
Репутация
0
Это писал Yashied, без них нельзя заблокировать кнопку во время выборов вариантов в комболисте (кликая по варианту из комбо, одновременно кликаешь и по кнопке), а другая команда для перетаскивания окна за клиентскую часть (если ставить стандартный стиль, то кнопка срабатывает только при двойном клике)
 

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
любое обновление элемента нужно сопровождать прорисовкой текста. то есть повторять
функцию
Код:
_DrawText($sString)

навели на кнопку, кнопка обновилась и перерисовываем текст
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Код:
#include <APIConstants.au3>
#include <GUIConstants.au3>
#include <GUIComboBox.au3>
#include <GDIPlus.au3>
#include <WinAPIEx.au3>

#include "Skin.au3"

_GDIPlus_Startup()

Global $hPng[3] = [_GDIPlus_BitmapCreateFromFile('1.png'), _GDIPlus_BitmapCreateFromFile('2.png'), _GDIPlus_BitmapCreateFromFile('3.png')]
Global $Form1, $Button1, $Combo1, $nMsg, $Skin = True

$Form1 = GUICreate('Form1', 300, 180, -1, -1, BitOR($WS_BORDER, $WS_POPUP))
GUICtrlCreatePic('bck.bmp.png', 0, 0, 300, 180)
GUICtrlSetState(-1, $GUI_DISABLE)
$Combo1 = GUICtrlCreateCombo('English', 80, 55, 140, 25, BitOR($CBS_DROPDOWNLIST, $WS_VSCROLL))
GUICtrlSetData(-1, 'Русский')
GUICtrlSetFont(-1, 9.8, $FW_NORMAL, $GUI_FONTNORMAL, 'Arial')
$Button1 = _Skin_AddButtonEx(90, 90, 120, 42, $hPng[0], $hPng[1], $hPng[2], '', $hPng[2], 1)
GUIRegisterMsg($WM_COMMAND, 'WM_COMMAND')
GUIRegisterMsg($WM_NCHITTEST, 'WM_NCHITTEST')
_Update()
GUISetState()

While 1
	If $Skin Then
		_Skin_Helper($Form1)
	EndIf
	$nMsg = GUIGetMsg()
	Switch $nMsg
		Case $GUI_EVENT_CLOSE
			Exit
		Case $Combo1
			_Update()
		Case $Button1

	EndSwitch
WEnd

Func _Update()

	Local $hBitmap[3], $hGraphic, $hFamily, $hFont, $hFormat, $hBrush, $tLayout, $aData, $Text

	Switch _GUICtrlComboBox_GetCurSel($Combo1)
		Case 0 ; English
			$Text = 'Button'
		Case 1 ; Русский
			$Text = 'Кнопка'
		Case Else
			$Text = ''
	EndSwitch
	$hGraphic = _GDIPlus_ImageGetGraphicsContext($hPng[0])
	$hFamily = _GDIPlus_FontFamilyCreate('Segoe UI')
	$hFont = _GDIPlus_FontCreate($hFamily, 14, 0, 2)
	$tLayout = _GDIPlus_RectFCreate(5, 5, 110, 31)
	$hFormat = _GDIPlus_StringFormatCreate()
	$aData = _GDIPlus_GraphicsMeasureString($hGraphic, $Text, $hFont, $tLayout, $hFormat)
	_GDIPlus_GraphicsDispose($hGraphic)
	DllStructSetData($aData[0], 1, 5 + (110 - DllStructGetData($aData[0], 3)) / 2)
	DllStructSetData($aData[0], 2, 5 + (31 - DllStructGetData($aData[0], 4)) / 2)
	$hBrush = _GDIPlus_BrushCreateSolid(0xFF000000)
	For $i = 0 To 2
		$hBitmap[$i] = _GDIPlus_ImageClone($hPng[$i])
		$hGraphic = _GDIPlus_ImageGetGraphicsContext($hBitmap[$i])
		_GDIPlus_GraphicsSetTextRenderingHint($hGraphic, 5)
		_GDIPlus_GraphicsDrawStringEx($hGraphic, $Text, $hFont, $aData[0], $hFormat, $hBrush)
		_GDIPlus_GraphicsDispose($hGraphic)
	Next
	_Skin_SetButtonEx($Button1, $hBitmap[0], $hBitmap[1], $hBitmap[2], 0, $hBitmap[2], 1, 1)
	_GDIPlus_StringFormatDispose($hFormat)
	_GDIPlus_FontFamilyDispose($hFamily)
	_GDIPlus_FontDispose($hFont)
	_GDIPlus_BrushDispose($hBrush)
EndFunc   ;==>_Update

Func _GDIPlus_ImageClone($hImage)
    Local $aResult = DllCall($__g_hGDIPDll, "int", "GdipCloneImage", "handle", $hImage, "handle*", 0)
    If @error Then Return SetError(@error, @extended, 0)
    If $aResult[0] Then Return SetError(10, $aResult[0], 0)
    Return $aResult[2]
EndFunc   ;==>_GDIPlus_ImageClone

Func WM_COMMAND($hWnd, $iMsg, $wParam, $lParam)

	Local $Msg = BitShift($wParam, 16)

	Switch $hWnd
		Case $Form1
			Switch BitAND($wParam, 0xFFFF)
				Case $Combo1
					Switch $Msg
						Case $CBN_CLOSEUP
							$Skin = 1
						Case $CBN_DROPDOWN
							$Skin = 0
						Case Else

					EndSwitch
			EndSwitch
	EndSwitch
	Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_COMMAND

Func WM_NCHITTEST($hWnd, $iMsg, $wParam, $lParam)
	Switch $hWnd
		Case $Form1
			If $skData[0][3] > 0 Then
				Return $GUI_RUNDEFMSG
			EndIf
			Local $Info = GUIGetCursorInfo($Form1)
			If Not @error Then
				Switch $Info[4]
					Case $Button1
						; Nothing
					Case Else
						Return $HTCAPTION
				EndSwitch
			EndIf
	EndSwitch
	Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NCHITTEST
 
A

Alofa

Гость
OffTopic:
Yashied
Эх, не выдержала душа поэта :smile:
 
Автор
A

avtoIT

Новичок
Сообщения
94
Репутация
0
Alofa, joiner, Yashied, большое спасибо, надеюсь, что более по этой теме от меня постов вы не увидите:smile:
 
Автор
A

avtoIT

Новичок
Сообщения
94
Репутация
0
Хм... Интересно, попробовал изменить текст кнопки с "Вперед" на "Далее" и у меня вылазит ошибка (Прекращена работа программы...)
Не подскажите из-за чего это может случаться?
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
avtoIT, вы уже не первый день на форуме. Хотите получить квалифицированный ответ, выкладывайте пример, демонстрирующий данную ошибку. В следующий раз я буду подобные посты удалять.
 
Автор
A

avtoIT

Новичок
Сообщения
94
Репутация
0
Код:
#include <APIConstants.au3>
#include <GUIConstants.au3>
#include <GDIPlus.au3>
#include <WinAPIEx.au3>

#include "Skin.au3"



_GDIPlus_Startup()

Global $hPng[3] = [_GDIPlus_BitmapCreateFromFile('butc1.png'), _GDIPlus_BitmapCreateFromFile('butc2.png'), _GDIPlus_BitmapCreateFromFile('butc3.png')]
Global $Form1, $Button1, $nMsg, $Skin = True

$Form1 = GUICreate('Form1', 350, 200, -1, -1, BitOR($WS_BORDER, $WS_POPUP))
GUICtrlCreatePic('bck.bmp', 0, 0, 350, 200)
GUICtrlSetState(-1, $GUI_DISABLE)

$Button1 = _Skin_AddButtonEx(234, 162, 120, 42, $hPng[0], $hPng[1], $hPng[2], '', $hPng[2], 1)

GUIRegisterMsg($WM_NCHITTEST, 'WM_NCHITTEST')
_Update($Button1, 'Далее')
GUISetState()

While 1
    If $Skin Then
        _Skin_Helper($Form1)
    EndIf
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit
        Case $Button1

    EndSwitch
WEnd

Func _Update($buttonthatwillbetexted, $textthatwillbeonbuttontexted)

    Local $hBitmap[3], $hGraphic, $hFamily, $hFont, $hFormat, $hBrush, $tLayout, $aData




    $hGraphic = _GDIPlus_ImageGetGraphicsContext($hPng[0])
    $hFamily = _GDIPlus_FontFamilyCreate('Segoe UI')
    $hFont = _GDIPlus_FontCreate($hFamily, 14, 0, 2)
    $tLayout = _GDIPlus_RectFCreate(5, 5, 110, 31)
    $hFormat = _GDIPlus_StringFormatCreate()
    $aData = _GDIPlus_GraphicsMeasureString($hGraphic, $textthatwillbeonbuttontexted, $hFont, $tLayout, $hFormat)
    _GDIPlus_GraphicsDispose($hGraphic)
    DllStructSetData($aData[0], 1, 5 + (110 - DllStructGetData($aData[0], 3)) / 2)
    DllStructSetData($aData[0], 2, 5 + (31 - DllStructGetData($aData[0], 4)) / 2)
    $hBrush = _GDIPlus_BrushCreateSolid(0xFF000000)
    For $i = 0 To 2
        $hBitmap[$i] = _GDIPlus_ImageClone($hPng[$i])
        $hGraphic = _GDIPlus_ImageGetGraphicsContext($hBitmap[$i])
        _GDIPlus_GraphicsSetTextRenderingHint($hGraphic, 5)
        _GDIPlus_GraphicsDrawStringEx($hGraphic, $textthatwillbeonbuttontexted, $hFont, $aData[0], $hFormat, $hBrush)
        _GDIPlus_GraphicsDispose($hGraphic)
    Next
    _Skin_SetButtonEx($buttonthatwillbetexted, $hBitmap[0], $hBitmap[1], $hBitmap[2], 0, $hBitmap[2], 1, 1)
    _GDIPlus_StringFormatDispose($hFormat)
    _GDIPlus_FontFamilyDispose($hFamily)
    _GDIPlus_FontDispose($hFont)
    _GDIPlus_BrushDispose($hBrush)
EndFunc   ;==>_Update

Func _GDIPlus_ImageClone($hImage)
    Local $aResult = DllCall($__g_hGDIPDll, "int", "GdipCloneImage", "handle", $hImage, "handle*", 0)
    If @error Then Return SetError(@error, @extended, 0)
    If $aResult[0] Then Return SetError(10, $aResult[0], 0)
    Return $aResult[2]
EndFunc   ;==>_GDIPlus_ImageClone



Func WM_NCHITTEST($hWnd, $iMsg, $wParam, $lParam)
    Switch $hWnd
        Case $Form1
            If $skData[0][3] > 0 Then
                Return $GUI_RUNDEFMSG
            EndIf
            Local $Info = GUIGetCursorInfo($Form1)
            If Not @error Then
                Switch $Info[4]
                    Case $Button1
                        ; Nothing
                    Case Else
                        Return $HTCAPTION
                EndSwitch
            EndIf
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NCHITTEST


P.s. прошу прощения за супер-классные имена переменных
 
A

Alofa

Гость
avtoIT сказал(а):
Хм... Интересно, попробовал изменить текст кнопки ...
... или изменили названия рисунков?
Пример вполне рабочий.


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

avtoIT сказал(а):
... прошу прощения за супер-классные имена переменных
Не надо просить прощения - почитайте ка это:
Рекомендации по написанию скриптов (от CreatoR)

Типы данных сказал(а):
В AutoIt существует только один тип данных - Variant , поэтому для удобства написания скриптов рекомендуется использовать следующие имена переменных:

Первый набор символов после знака доллара ($) должен определять тип данных. Следующий список определяет префиксы и типы данных используемые с ними:
  • $a<символ> - (Array) Массив данных - последующий символ взятый из списка ниже, определяет тип данных в массиве
  • $b - (Binary data) Двоичные данные
  • $h - (File or window handle) Дескриптор файла, окна, и т.д.
  • $i - (Integer) Целое число
  • $f - (Boolean) Логический тип, может принимать значения True или False
  • $n - (Floating point number) Число с плавающей точкой
  • $s - (String) Строка
  • $v - (Variant) Вариант, неопределённый тип данных, базовый тип для AutoIt
  • $t - (Struct) Структура в стиле C/C++, для использования в DllCall, в сообщениях WM_*, при обработке данных и т.п.
  • $p - (Pointer) Указатель на структуру или на её элемент
Остальное имя переменной следует начинать с заглавной буквы, и оно должно отражать функциональность (свойства) переменной. Имена вроде “$iC” не приемлемы.
"$aiWeekDayNames" или "$iCounter" намного предпочтительнее.

Переведено с «User Defined Functions Standards».

P.S
От себя...
Такая манера написания скриптов уже стала почти стандартом среди AutoIt-кодеров, оно придаёт коду более читабельный и приятный вид.
 
Автор
A

avtoIT

Новичок
Сообщения
94
Репутация
0
Спасибо, за названия переменных :IL_AutoIt_1:

У меня конкретно этот пример не работает (все файлы присутствуют) (с которыми другими словами вместо жалее все хорошо)
Или это опять глюка Scite и откомпилив все заработает?
 
A

Alofa

Гость
Что пишет в консоли? Предоставьте ошибку.
 
Автор
A

avtoIT

Новичок
Сообщения
94
Репутация
0
Код:
--> Press Ctrl+Alt+Break to Restart or Ctrl+Break to Stop
!>08:42:38 AutoIt3.exe ended.rc:-1073741819
+>08:42:38 AutoIt3Wrapper Finished.
>Exit code: 3221225477    Time: 6.016
Если в коде заменить Далее на Вперед, то все работает:smile:
 
Автор
A

avtoIT

Новичок
Сообщения
94
Репутация
0
Хм... в общем, повозившись с кодом получилось следующее
Код:
$Button1 = _Skin_AddButtonEx(90, 90, 120, 42, $hPng[0], $hPng[1], $hPng[2], '', '', 1) ;работает
$Button1 = _Skin_AddButtonEx(90, 90, 120, 42, $hPng[0], $hPng[1], $hPng[2], '', $hPng[2], 1) ;не работает

:scratch:
Под не работает подразумевается Прекращение работы скрипта.
 
Верх