Что нового

Пример перевода на русский язык элементов чужого окна.

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
AutoIt: 3.3.6.1
Версия: 1.0

Категория: Окна и диалоги.

Описание: К примеру у нас есть программа с английским интерфейсом и мы хотим поменять интерфейс на русский. Чтобы не появлялись такие темы, или, если нет возможности связаться с автором программы по поводу исходного кода, или автор не хочет предоставлять свой код, предлагаю перевести элементы окна "на лету" следующим образом.
1. Скомпилируем следующий код в test.exe.
Код:
Код:
#include <ComboConstants.au3>
#include <GUIConstantsEx.au3>

Break(0)
GUICreate('Test', 280, 100)
GUICtrlCreateLabel('Hello', 100, 5, 50, 20)
$Combo = GUICtrlCreateCombo('', 10, 30, 80, 20, BitOR($CBS_DROPDOWN,$CBS_AUTOHSCROLL))
GUICtrlSetData(-1, 'one|two|three|four|five', 'three')
GUICtrlCreateButton('Button', 110, 30, 80, 25)
GUICtrlCreateCheckbox('Help', 210, 30, 60, 20)
GUISetState()

While 1
	$nMsg = GUIGetMsg()
	Switch $nMsg
		Case $GUI_EVENT_CLOSE
			Exit
	EndSwitch
WEnd
Этот test.exe мы будем использовать в качестве примера сторонней программы с английским интерфейсом.
2. При помощи AutoIt v3 Window Info найдем все элементы окна и их текст, который мы хотим перевести.
3. Переводим весь нужный нам текст на русский язык (способов это сделать много).
4. Пишем код для перевода. Как пример, код для перевода test.exe.
Код:
Код:
#include <GUIComboBox.au3>

Opt('WinWaitDelay', 10)

$sTitle = 'Тест'
$sStaticText = 'Привет'
$sButtonText = 'Кнопка'
$sCheckboxText = 'Помощь'
Dim $aComboText[5] = ['один', 'два', 'три', 'четыре', 'пять']

Run(@ScriptDir & '\test.exe')
$hWin = WinWait('Test', '', 3)
If Not $hWin Then
	MsgBox(16, 'Error', 'Error')
	Exit
EndIf
WinSetTitle($hWin, '', $sTitle)
ControlSetText($hWin, '', '[CLASS:Static; INSTANCE:1]', $sStaticText)
ControlSetText($hWin, '', '[CLASS:Button; INSTANCE:1]', $sButtonText)
ControlSetText($hWin, '', '[CLASS:Button; INSTANCE:2]', $sCheckboxText)
$hCombo = ControlGetHandle($hWin, '', '[CLASS:ComboBox; INSTANCE:1]')
If $hCombo Then
	$iIndex = _GUICtrlComboBox_GetCurSel($hCombo)
	For $i = 0 To 4
		_GUICtrlComboBox_DeleteString($hCombo, 0)
		_GUICtrlComboBox_AddString($hCombo, $aComboText[$i])
	Next
	_GUICtrlComboBox_SetCurSel($hCombo, $iIndex)
EndIf
Теперь test.exe мы запускаем с помощью этого кода (оба файла должны лежать в одной папке). Все элементы окна переведены на русский язык.
5. Допустим, что в элементе ComboBox нельзя менять текст, т.к. программа, например, его считывает и, если текст изменен, то работать не будет. Тогда мы немного изменяем код
Код:
Код:
#include <Array.au3>

Opt('MouseCoordMode', 2)
Opt('WinWaitDelay', 10)

$sTitle = 'Тест'
$sStaticText = 'Привет'
$sButtonText = 'Кнопка'
$sCheckboxText = 'Помощь'
$sComboText = ''
Dim $aComboText[5][2] = [['один', 'one'],['два', 'two'],['три', 'three'], _
		['четыре', 'four'],['пять', 'five']]
For $i = 0 To 4
	If $i <> 4 Then
		$sComboText &= $aComboText[$i][0] & @LF
	Else
		$sComboText &= $aComboText[$i][0]
	EndIf
Next
$fYes = True

Run(@ScriptDir & '\test.exe')
$hWin = WinWait('Test', '', 3)
If Not $hWin Then
	MsgBox(16, 'Error', 'Error')
	Exit
EndIf
WinSetTitle($hWin, '', $sTitle)
ControlSetText($hWin, '', '[CLASS:Static; INSTANCE:1]', $sStaticText)
ControlSetText($hWin, '', '[CLASS:Button; INSTANCE:1]', $sButtonText)
ControlSetText($hWin, '', '[CLASS:Button; INSTANCE:2]', $sCheckboxText)

While 1
	$aPosWindow = WinGetClientSize($hWin)
	$aPosMouse = MouseGetPos()
	$aPosCombo = ControlGetPos($hWin, '', '[CLASS:ComboBox; INSTANCE:1]')
	If IsArray($aPosWindow) And IsArray($aPosMouse) And IsArray($aPosCombo) Then
		Switch $aPosMouse[1]
			Case $aPosCombo[1] To $aPosCombo[1] + $aPosCombo[3]
				Switch $aPosMouse[0]
					Case $aPosCombo[0] To $aPosCombo[0] + $aPosCombo[2]
						If $fYes Then
							$sEnText = ControlGetText($hWin, '', '[CLASS:ComboBox; INSTANCE:1]')
							$iIndex = _ArraySearch($aComboText, $sEnText, 0, 0, 0, 0, 1, 1)
							If $iIndex <> -1 Then
								$sRusText = $aComboText[$iIndex][0]
							Else
								$sRusText = 'Не смог определить'
							EndIf
							ToolTip($sEnText & ' - ' & $sRusText & @LF & '-----' & @LF & $sComboText)
							$fYes = False
						EndIf
					Case Else
						ToolTip('')
						$fYes = True
				EndSwitch
			Case Else
				ToolTip('')
				$fYes = True
		EndSwitch
	EndIf
	Sleep(50)
	If Not WinExists($hWin) Then Exit
WEnd
Теперь, при наведении курсора на элемент ComboBox будет появляться подсказка с переводом.
Таким же образом можно перевести практически любые элементы окна.

Источник: Пример перевода на русский язык элементов чужого окна.
Автор(ы): madmasles
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,673
Репутация
2,486
Идея конечно неплохая, но имхо, очень муторно так каждый раз писать скрипт-переводчик.

P.S
Для многих программ я использую Restorator, конкретно для test.exe оно конечно не подходит.
 
Автор
madmasles

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
CreatoR [?]
очень муторно так каждый раз писать скрипт-переводчик
Мне проше написать скрипт-переводчик, чем выучить английский язык. ;D
А если серьезно, то не надо все переводить, можно какие-то элементы определенные перевести. И еще, ИМХО, честнее написать переводчик, чем пытаться декомпилировать чужую программу.
 
Автор
madmasles

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
Еще пример с элементом ListView. AutoIt v3 Window Info определяет его как SysListView32.
Код для компиляции 1_test.exe:
Код:
#include <GUIConstantsEx.au3>

Break(0)
GUICreate('Test', 200, 100)
$nListview = GUICtrlCreateListView('First            |Second            ', 10, 10, 180, 80)
GUICtrlCreateListViewItem('one|two', $nListview)
GUICtrlCreateListViewItem('three|four', $nListview)
GUISetState()

While 1
	$nMsg = GUIGetMsg()
	Switch $nMsg
		Case $GUI_EVENT_CLOSE
			Exit
	EndSwitch
WEnd
Полный перевод:
Код:
#include <GuiListView.au3>

Opt('WinWaitDelay', 10)

$sTitle = 'Тест'
Dim $aColumn[2] = ['Первая', 'Вторая']
Dim $aListView[2][2] = [['один', 'два'],['три', 'четыре']]
Run(@ScriptDir & '\1_test.exe')
$hWin = WinWait('Test', '', 3)
If Not $hWin Then
	MsgBox(16, 'Error', 'Error')
	Exit
EndIf
WinSetTitle($hWin, '', $sTitle)
$hListView = ControlGetHandle($hWin, '', '[CLASS:SysListView32; INSTANCE:1]')
If $hListView Then
	For $i = 0 To 1
		_GUICtrlListView_SetColumn($hListView, $i, $aColumn[$i])
	Next
	For $i = 0 To 1
		For $j = 0 To 1
			_GUICtrlListView_SetItemText($hListView, $i, $aListView[$i][$j], $j)
		Next
	Next
EndIf
Перевод-подсказка:
Код:
#include <Array.au3>
#include <GuiListView.au3>

Opt('MouseCoordMode', 2)
Opt('WinWaitDelay', 10)

$sTitle = 'Тест'

$sListViewSelectText = ''
$sListViewText = ''
$sColumnText = 'Первая|Вторая'
Dim $aListView[2][2] = [['один|два', 'one'],['три|четыре', 'three']]
For $i = 0 To 1
	If $i <> 1 Then
		$sListViewText &= $aListView[$i][0] & @LF
	Else
		$sListViewText &= $aListView[$i][0]
	EndIf
Next
$sListViewText = $sColumnText & @LF & '-----' & @LF & $sListViewText
Run(@ScriptDir & '\1_test.exe')
$hWin = WinWait('Test', '', 3)
If Not $hWin Then
	MsgBox(16, 'Error', 'Error')
	Exit
EndIf
WinSetTitle($hWin, '', $sTitle)
$hListView = ControlGetHandle($hWin, '', '[CLASS:SysListView32; INSTANCE:1]')
$iColumns = _GUICtrlListView_GetColumnCount($hListView)
While 1

	$aPosWindow = WinGetClientSize($hWin)
	$aPosMouse = MouseGetPos()
	$aPosListView = ControlGetPos($hWin, '', $hListView)
	If IsArray($aPosWindow) And IsArray($aPosMouse) And IsArray($aPosListView) Then
		Switch $aPosMouse[1]
			Case $aPosListView[1] To $aPosListView[1] + $aPosListView[3]
				Switch $aPosMouse[0]
					Case $aPosListView[0] To $aPosListView[0] + $aPosListView[2]
						$sListViewSelectText = ''
						$iCount = _GUICtrlListView_GetItemCount($hListView)
						For $i = 0 To $iCount - 1
							If _GUICtrlListView_GetItemSelected($hListView, $i) Then
								$sListViewSelectText = _GUICtrlListView_GetItemText($hListView, $i)
							EndIf
						Next
						If $sListViewSelectText Then
							$iIndex = _ArraySearch($aListView, $sListViewSelectText, 0, 0, 0, 0, 1, 1)
							If $iIndex = -1 Then
								$sRusTextSelect = 'Не смог определить'
							Else
								$sRusTextSelect = $aListView[$iIndex][0]
							EndIf
							ToolTip($sRusTextSelect & @LF & '=====' & @LF & $sListViewText)
						Else
							ToolTip('=====' & @LF & $sListViewText)
						EndIf
					Case Else
						ToolTip('')
				EndSwitch
			Case Else
				ToolTip('')
		EndSwitch
	EndIf
	Sleep(50)
	If Not WinExists($hWin) Then Exit
WEnd
 
Верх