Что нового

Проблема с Tab'ом

  • Автор темы qsort
  • Дата начала

madmasles

Модератор
Глобальный модератор
Сообщения
7 790
Репутация
2 319
qsort
Странно, у меня следующий код нормально отрабатывает с видеопамятью 128 Мб:
Код:
#include <GUIConstantsEx.au3>

GUICreate('My GUI Tab', 250, 150)
$tab = GUICtrlCreateTab(10, 10, 200, 100)
$tab0 = GUICtrlCreateTabItem('tab0')
$nLabel = GUICtrlCreateLabel(StringFormat('%06d', 0) & '-0', 50, 40, 110, 18)
GUICtrlSetBkColor(-1, 0x00FFFF)
GUICtrlSetFont(-1, 12, 600)
$nButton = GUICtrlCreateButton('Go', 20, 70, 50, 20)
$tab1 = GUICtrlCreateTabItem('tab1')
$tab2 = GUICtrlCreateTabItem('tab2')
GUICtrlCreateTabItem('')
GUISetState()

While 1
	$nMsg = GUIGetMsg()
	Switch $nMsg
		Case $GUI_EVENT_CLOSE
			Exit
		Case $nButton
			GUICtrlSetState($nButton, $GUI_DISABLE)
			For $i = 1 To 1000
				GUICtrlSetData($nLabel, StringFormat('%06d', Random(1000, 999999, 1)) & '-' & $i)
				Sleep(20)
			Next
			GUICtrlSetState($nButton, $GUI_ENABLE)
	EndSwitch
WEnd
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8 472
Репутация
2 401
Обычно это делается так:

Код:
_GUICtrlSetDataEx($nLabel, "Some data")

Func _GUICtrlSetDataEx($nCtrlID, $vData)
	If GUICtrlRead($nCtrlID) <> $vData Then
		Return GUICtrlSetData($nCtrlID, $vData)
	EndIf
	
	Return 0
EndFunc
 

madmasles

Модератор
Глобальный модератор
Сообщения
7 790
Репутация
2 319
OffTopic:
CreatoR [?]
Обычно это делается так:
В моем варианте, если использовать Вашу функцию, она вряд ли когда-нибудь вернет 0. :smile:
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8 472
Репутация
2 401
madmasles [?]
В моем варианте, если использовать Вашу функцию, она вряд ли когда-нибудь вернет 0
Ну тогда и проблемы нет (хотя Random может повторяться ;) ).
В нашем же случае проблема в слишком быстром обновлений элемента теми же данными, я с этим уже сталкивался.
Проблема также может быть в стилях окна ($WS_CLIPCHILDREN например).
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5 379
Репутация
2 711
Никакой "каши" в label'ах быть не должно. Более того, от скорости обновления ничего не зависит, т.к. все общение в Windows с любыми элементами происходит на уровне сообщений, которые в принципе не могут одновременно выполняться для одного и того же элемента. Просто формируется очередь... Если все же возникает "каша", значит не происходит обновления Tab'а (WM_ERASEBKGND), а это свидетельствует об ошибках в самом коде. Трудно что-то сказать, не видя его (кода).

А вообще, я уже неоднократно на нашем форуме говорил, что в подобных задачах лучше использовать WM_COPYDATA для коммуникации процессов. Вот еще один простой пример:

Main.au3 (основная программа с многострадальными Tab'ами)

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

Global Const $RECEIVER_NAME = '[email protected]#10'

$hReceiver = GUICreate($RECEIVER_NAME)

$hForm = GUICreate('MyGUI', 400, 400)
GUICtrlCreateTab(10, 10, 380, 380)
GUICtrlCreateTabItem('Tab1')
GUICtrlCreateLabel('Label1:', 30, 50, 45, 14)
GUICtrlSetFont(-1, 8.5, 800, 0, 'MS Shell Dlg')
$Label1 = GUICtrlCreateLabel('', 76, 50, 60, 14)
GUICtrlCreateLabel('Label2:', 30, 75, 45, 14)
GUICtrlSetFont(-1, 8.5, 800, 0, 'MS Shell Dlg')
$Label2 = GUICtrlCreateLabel('', 76, 75, 60, 14)
GUICtrlCreateTabItem('Tab2')
GUICtrlCreateTabItem('Tab3')
GUICtrlCreateTabItem('')
$Dummy = GUICtrlCreateDummy()

GUIRegisterMsg($WM_COPYDATA, 'WM_COPYDATA')

GUISetState()

While 1
	Switch GUIGetMsg()
		Case $GUI_EVENT_CLOSE
			Exit
		Case $Dummy
			$Data = GUICtrlRead($Dummy)
			Switch BitShift($Data, 16)
				Case 1
					GUICtrlSetData($Label1, BitAND($Data, 0xFFFF))
				Case 2
					GUICtrlSetData($Label2, BitAND($Data, 0xFFFF))
				Case Else

			EndSwitch
	EndSwitch
WEnd

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

	Switch $hWnd
		Case $hReceiver
			GUICtrlSendToDummy($Dummy, DllStructGetData(DllStructCreate('ulong_ptr;dword;ptr', $lParam), 1))
			Return 1
	EndSwitch
	Return 0
EndFunc   ;==>WM_COPYDATA


Label1.au3 (программа для изменения значений в Label1)

Код:
#Include <WindowsConstants.au3>

Global Const $RECEIVER_NAME = '[email protected]#10'

While 1
	_SendMsg(WinGetHandle($RECEIVER_NAME), 1, Random(0, 0xFFFF, 1))
	Sleep(20)
WEnd

Func _SendMsg($hWnd, $iIndex, $iValue)

	Local $tCOPYDATA = DllStructCreate('ulong_ptr;dword;ptr')
	Local $Ret

	DllStructSetData($tCOPYDATA, 1, BitOR(BitShift(BitAND($iIndex, 0xFFFF), -16), BitAND($iValue, 0xFFFF)))
	DllStructSetData($tCOPYDATA, 2, 0)
	DllStructSetData($tCOPYDATA, 3, 0)
	$Ret = DllCall('user32.dll', 'lresult', 'SendMessage', 'hwnd', $hWnd, 'uint', $WM_COPYDATA, 'ptr', 0, 'ptr', DllStructGetPtr($tCOPYDATA))
	If (@error) Or (Not $Ret[0]) Then
		Return 0
	EndIf
	Return 1
EndFunc   ;==>_SendMsg


Label2.au3 (программа для изменения значений в Label2)

Код:
#Include <WindowsConstants.au3>

Global Const $RECEIVER_NAME = '[email protected]#10'

While 1
	_SendMsg(WinGetHandle($RECEIVER_NAME), 2, Random(0, 0xFFFF, 1))
	Sleep(200)
WEnd

Func _SendMsg($hWnd, $iIndex, $iValue)

	Local $tCOPYDATA = DllStructCreate('ulong_ptr;dword;ptr')
	Local $Ret

	DllStructSetData($tCOPYDATA, 1, BitOR(BitShift(BitAND($iIndex, 0xFFFF), -16), BitAND($iValue, 0xFFFF)))
	DllStructSetData($tCOPYDATA, 2, 0)
	DllStructSetData($tCOPYDATA, 3, 0)
	$Ret = DllCall('user32.dll', 'lresult', 'SendMessage', 'hwnd', $hWnd, 'uint', $WM_COPYDATA, 'ptr', 0, 'ptr', DllStructGetPtr($tCOPYDATA))
	If (@error) Or (Not $Ret[0]) Then
		Return 0
	EndIf
	Return 1
EndFunc   ;==>_SendMsg


и т.д. Разница лишь в следующих строчках:

Код:
_SendMsg(WinGetHandle($RECEIVER_NAME), 1, Random(0, 0xFFFF, 1))
Sleep(20)


Запускаем все три скрипта в любой последовательности и радуемся жизни.

:smile:

P.S

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