Что нового

Функция _WinAPI_DrawText - непрерывное обновление выводимого текста

QQruza

Новичок
Сообщения
26
Репутация
0
Взял пример из справки, изменил выводимый текст на текущее время. Как сделать, чтобы выводимое время выводилось без наложения? Текущее время взять для примера, там может быть любой счетчик.

Код:
#include <WinAPI.au3>
#include <WindowsConstants.au3>
#include <FontConstants.au3>
#include <Date.au3>

Global $tRECT, $hFont, $hOldFont, $hDC

HotKeySet("{ESC}", "_Exit")

$tRECT = DllStructCreate($tagRect)
DllStructSetData($tRECT, "Left", 5)
DllStructSetData($tRECT, "Top", 5)
DllStructSetData($tRECT, "Right", 250)
DllStructSetData($tRECT, "Bottom", 50)

$hDC = _WinAPI_GetDC(0)
$hFont = _WinAPI_CreateFont(50, 0, 0, 0, 400, False, False, False, $DEFAULT_CHARSET, _
        $OUT_DEFAULT_PRECIS, $CLIP_DEFAULT_PRECIS, $DEFAULT_QUALITY, 0, 'Arial')
$hOldFont = _WinAPI_SelectObject($hDC, $hFont)

_WinAPI_SetTextColor($hDC, 0x0000FF)
_WinAPI_SetBkColor($hDC, 0x000000)
; comment next line to get black background instead of transparent one
_WinAPI_SetBkMode($hDC, $TRANSPARENT)

While 1
	$true_time = _DateTimeFormat( _NowCalc() , 5 )
    _WinAPI_DrawText($hDC, $true_time, $tRECT, $DT_CENTER)
    Sleep(1000)
WEnd

Func _Exit()
    _WinAPI_SelectObject($hDC, $hOldFont)
    _WinAPI_DeleteObject($hFont)
    _WinAPI_ReleaseDC(0, $hDC)
    _WinAPI_InvalidateRect(0, 0)
    $tRECT = 0
    Exit
EndFunc   ;==>_Exit
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
Код:
#include <GUIConstantsEx.au3>
#include <FontConstants.au3>
#include <WindowsConstants.au3>
#include <Date.au3>
#include <WinAPI.au3>

HotKeySet('{ESC}', '_Exit')

$hWnd = GUICreate('', 250, 50, 5, 5, $WS_POPUP, BitOR($WS_EX_TOPMOST, $WS_EX_TOOLWINDOW))
GUISetBkColor(0xFF0000)

$hDC = _WinAPI_GetDC($hWnd)
$hFont = _WinAPI_CreateFont(50, 0, 0, 0, 400, False, False, False, $DEFAULT_CHARSET, $OUT_DEFAULT_PRECIS, $CLIP_DEFAULT_PRECIS, $DEFAULT_QUALITY, 0, 'Arial')
$hOldFont = _WinAPI_SelectObject($hDC, $hFont)
_WinAPI_ReleaseDC($hWnd, $hDC)

_DrawText($hWnd, $hDC, _DateTimeFormat(_NowCalc(), 5))
GUISetState()

While 1
	_DrawText($hWnd, $hDC, _DateTimeFormat(_NowCalc(), 5))
	Sleep(500)
WEnd

Func _Exit()
	_WinAPI_SelectObject($hDC, $hOldFont)
    _WinAPI_DeleteObject($hFont)
	
	Exit
EndFunc

Func _DrawText($hWnd, $hDC, $sText)
	DllCall('gdi32.dll', "int", "BeginPath", "int", $hDC)
	DllCall('gdi32.dll', "int", "TextOut", "int", $hDC, "int", 0, "int", 0, "str", $sText, "int", StringLen($sText))
	DllCall('gdi32.dll', "int", "EndPath", "int", $hDC)
	
	Local $hRgn1 = DllCall('gdi32.dll', "hwnd", "PathToRegion", "int", $hDC)
	Local $tStruct = DllStructCreate("int;int;int;int")
	DllCall('gdi32.dll', "int", "GetRgnBox", "hwnd", $hRgn1[0], "ptr", DllStructGetPtr($tStruct))
	Local $hRgn2 = DllCall('gdi32.dll', "hwnd", "CreateRectRgnIndirect", "ptr", DllStructGetPtr($tStruct))
	
	_WinAPI_CombineRgn($hRgn2[0], $hRgn2[0], $hRgn1[0], $RGN_XOR)
	_WinAPI_DeleteObject($hRgn1[0])
	
	_WinAPI_SetWindowRgn($hWnd, $hRgn2[0])
	_WinAPI_InvalidateRect($hWnd, $hRgn2[0])
EndFunc
 
Автор
Q

QQruza

Новичок
Сообщения
26
Репутация
0
CreatoR, благодарю за ответ. К сожалению не могу разобраться как изменить код под такую задачу - привязка выводимого текста к определенному окну.
И таких окон будет несколько, на которые нужно будет выводить изменяющийся текст.
Для меня уже делали такой скрипт, но в нем та же проблема с обновлением.

Код:
#include <WinAPI.au3>
#include <WindowsConstants.au3>
#include <FontConstants.au3>
#include <Date.au3>

Global $tRECT, $hFont, $hOldFont, $hDC, $hWnd

HotKeySet("{ESC}", "_Exit")

$tRECT = DllStructCreate($tagRect)
DllStructSetData($tRECT, "Left",   500) ; <= Координаты
DllStructSetData($tRECT, "Top",    100) ; <= относительно
DllStructSetData($tRECT, "Right",  900) ; <= левого верхнего
DllStructSetData($tRECT, "Bottom", 200) ; <= угла нужного окна

$hWnd = WinGetHandle("[class:SciTEWindow]") ; <= Нужное окно

While 1
  $hDC = _WinAPI_GetWindowDC($hWnd)
  $hFont = _WinAPI_CreateFont(32, 0, 0, 0, 400, False, False, False, $DEFAULT_CHARSET, _ ; <= Атрибуты
            $OUT_DEFAULT_PRECIS, $CLIP_DEFAULT_PRECIS, $DEFAULT_QUALITY, 0, 'Arial')     ; <= текста
  $hOldFont = _WinAPI_SelectObject($hDC, $hFont)
  _WinAPI_SetTextColor($hDC, 0x0000FF)  ; <= Цвет текста
  _WinAPI_SetBkColor($hDC, 0x000000)    ; <= Цвет фона
  _WinAPI_SetBkMode($hDC, $TRANSPARENT) ; <= Прозрачный фон
  _WinAPI_DrawText($hDC, _DateTimeFormat( _NowCalc() , 5 ), $tRECT, $DT_WORDBREAK) ; <= Сам текст и методы форматирования
  _WinAPI_SelectObject($hDC, $hOldFont)
  _WinAPI_DeleteObject($hFont)
  _WinAPI_ReleaseDC(0, $hDC)
  Sleep(10)
WEnd

Func _Exit()
  _WinAPI_InvalidateRect(0)
  $tRECT = 0
  Exit
EndFunc   ;==>_Exit
 

CreatoR

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

Код:
#include <GUIConstantsEx.au3>
#include <FontConstants.au3>
#include <WindowsConstants.au3>
#include <Date.au3>
#include <WinAPI.au3>

HotKeySet('{ESC}', '_Exit')

$hWnd = GUICreate('', 500, 50, 5, 5, $WS_POPUP, BitOR($WS_EX_TOPMOST, $WS_EX_TOOLWINDOW))
GUISetBkColor(0xFF0000)

$hDC = _WinAPI_GetDC($hWnd)
$hFont = _WinAPI_CreateFont(50, 0, 0, 0, 400, False, False, False, $DEFAULT_CHARSET, $OUT_DEFAULT_PRECIS, $CLIP_DEFAULT_PRECIS, $DEFAULT_QUALITY, 0, 'Arial')
$hOldFont = _WinAPI_SelectObject($hDC, $hFont)

_DrawText($hWnd, $hDC, _DateTimeFormat(_NowCalc(), 5))
GUISetState(@SW_SHOWNOACTIVATE)

$iFlag = 0
$iActive = 0

$hSciTE = WinGetHandle('[CLASS:SciTEWindow]')
$hNotepad = WinGetHandle('[REGEXPCLASS:Notepad.*]')

Dim $ahTargets[2][2] = [[$hSciTE, '%02d:%02d:%02d'], [$hNotepad, '%02d:%02d:%02d, %s.%s.%s']]

While 1
	$iActive = 0
	
	For $i = 0 To UBound($ahTargets)-1
		If WinActive($ahTargets[$i][0]) Then
			$iActive = $i+1
			ExitLoop
		EndIf
	Next
	
	If $iActive Then
		_DrawText($hWnd, $hDC, StringFormat($ahTargets[$iActive-1][1], @HOUR, @MIN, @SEC, @MDAY, @MON, @YEAR))
		GUISetState(@SW_SHOWNOACTIVATE)
		$iFlag = 0
	ElseIf $iFlag = 0 Then
		GUISetState(@SW_HIDE)
		$iFlag = 1
	EndIf
	
    Sleep(50)
WEnd

Func _Exit()
	_WinAPI_ReleaseDC($hWnd, $hDC)
    _WinAPI_SelectObject($hDC, $hOldFont)
    _WinAPI_DeleteObject($hFont)
    
    Exit
EndFunc

Func _DrawText($hWnd, $hDC, $sText)
    DllCall('gdi32.dll', "int", "BeginPath", "int", $hDC)
    DllCall('gdi32.dll', "int", "TextOut", "int", $hDC, "int", 0, "int", 0, "str", $sText, "int", StringLen($sText))
    DllCall('gdi32.dll', "int", "EndPath", "int", $hDC)
    
    Local $hRgn1 = DllCall('gdi32.dll', "hwnd", "PathToRegion", "int", $hDC)
    Local $tStruct = DllStructCreate("int;int;int;int")
    DllCall('gdi32.dll', "int", "GetRgnBox", "hwnd", $hRgn1[0], "ptr", DllStructGetPtr($tStruct))
    Local $hRgn2 = DllCall('gdi32.dll', "hwnd", "CreateRectRgnIndirect", "ptr", DllStructGetPtr($tStruct))
    
    _WinAPI_CombineRgn($hRgn2[0], $hRgn2[0], $hRgn1[0], $RGN_XOR)
    _WinAPI_DeleteObject($hRgn1[0])
    
    _WinAPI_SetWindowRgn($hWnd, $hRgn2[0])
    _WinAPI_InvalidateRect($hWnd, $hRgn2[0])
EndFunc
 
Автор
Q

QQruza

Новичок
Сообщения
26
Репутация
0
привязка выводимого текста к определенному окну
В приведенном примере привязки не получилось, текст в левом верхнем углу экрана, а хотелось бы, чтобы он был в пределах нужного окна и перетаскивался вместе с ним
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
QQruza [?]
хотелось бы, чтобы он был в пределах нужного окна и перетаскивался вместе с ним
Код:
#include <GUIConstantsEx.au3>
#include <FontConstants.au3>
#include <WindowsConstants.au3>
#include <Date.au3>
#include <WinAPI.au3>

HotKeySet('{ESC}', '_Exit')

$hWnd = GUICreate('', 500, 50, 5, 5, $WS_POPUP, BitOR($WS_EX_TOPMOST, $WS_EX_TOOLWINDOW))
GUISetBkColor(0xFF0000)

$hDC = _WinAPI_GetDC($hWnd)
$hFont = _WinAPI_CreateFont(50, 0, 0, 0, 400, False, False, False, $DEFAULT_CHARSET, $OUT_DEFAULT_PRECIS, $CLIP_DEFAULT_PRECIS, $DEFAULT_QUALITY, 0, 'Arial')
$hOldFont = _WinAPI_SelectObject($hDC, $hFont)

$iFlag = 1
$iActive = 0
$hLastParent = 0

$hSciTE = WinGetHandle('[CLASS:SciTEWindow]')
$hNotepad = WinGetHandle('[REGEXPCLASS:Notepad.*]')

Dim $ahTargets[2][2] = [[$hSciTE, '%02d:%02d:%02d'], [$hNotepad, '%02d:%02d:%02d, %s.%s.%s']]

While 1
	$iActive = 0
	
	For $i = 0 To UBound($ahTargets)-1
		If WinActive($ahTargets[$i][0]) Then
			$iActive = $i+1
			ExitLoop
		EndIf
	Next
	
	If $iActive Then
		If $hLastParent <> $ahTargets[$iActive-1][0] Then
			_WinAPI_SetParent($hWnd, $ahTargets[$iActive-1][0])
			$hLastParent = $ahTargets[$iActive-1][0]
		EndIf
		
		_DrawText($hWnd, $hDC, StringFormat($ahTargets[$iActive-1][1], @HOUR, @MIN, @SEC, @MDAY, @MON, @YEAR))
		GUISetState(@SW_SHOWNOACTIVATE)
		$iFlag = 0
	ElseIf $iFlag = 0 Then
		GUISetState(@SW_HIDE)
		$iFlag = 1
	EndIf
	
    Sleep(50)
WEnd

Func _Exit()
	_WinAPI_ReleaseDC($hWnd, $hDC)
    _WinAPI_SelectObject($hDC, $hOldFont)
    _WinAPI_DeleteObject($hFont)
    
    Exit
EndFunc

Func _DrawText($hWnd, $hDC, $sText)
    DllCall('gdi32.dll', "int", "BeginPath", "int", $hDC)
    DllCall('gdi32.dll', "int", "TextOut", "int", $hDC, "int", 0, "int", 0, "str", $sText, "int", StringLen($sText))
    DllCall('gdi32.dll', "int", "EndPath", "int", $hDC)
    
    Local $hRgn1 = DllCall('gdi32.dll', "hwnd", "PathToRegion", "int", $hDC)
    Local $tStruct = DllStructCreate("int;int;int;int")
    DllCall('gdi32.dll', "int", "GetRgnBox", "hwnd", $hRgn1[0], "ptr", DllStructGetPtr($tStruct))
    Local $hRgn2 = DllCall('gdi32.dll', "hwnd", "CreateRectRgnIndirect", "ptr", DllStructGetPtr($tStruct))
    
    _WinAPI_CombineRgn($hRgn2[0], $hRgn2[0], $hRgn1[0], $RGN_XOR)
    _WinAPI_DeleteObject($hRgn1[0])
    
    _WinAPI_SetWindowRgn($hWnd, $hRgn2[0])
    _WinAPI_InvalidateRect($hWnd, $hRgn2[0])
EndFunc
 

InnI

AutoIT Гуру
Сообщения
4,922
Репутация
1,432
QQruza [?]
Для меня уже делали такой скрипт
Этот? ;) http://autoit-script.ru/index.php/topic,11625.msg76132.html#msg76132

Вот ещё вариант. Выводит в активное окно время и раскладку.
Код:
#include <WindowsConstants.au3>
#include <WinAPI.au3>

AdlibRegister("SetInfo", 500)

Global $Width = 140, $Height = 24, $BkColor = 0xA0A0A0, $TxtColor = 0xFF0000

$gui = GUICreate("", $Width, $Height, 10, 10, $WS_POPUP, BitOR($WS_EX_TOPMOST, $WS_EX_LAYERED, $WS_EX_TOOLWINDOW))
GUISetBkColor($BkColor)
$lbl = GUICtrlCreateLabel("", 0, 0, $Width, $Height)
GUICtrlSetFont(-1, 16)
GUICtrlSetColor(-1, $TxtColor)
GUISetState()

_WinAPI_SetLayeredWindowAttributes($gui, $BkColor, 0, $LWA_COLORKEY)

Do
  If WinGetHandle("[active]") <> $gui Then
    $pos = WinGetPos("[active]")
    WinMove($gui, "", $pos[0] + $pos[2] / 2 - $Width / 2, $pos[1] + 4)
  EndIf
Until GUIGetMsg() = -3

Func SetInfo()
  GUICtrlSetData($lbl, @HOUR & ":" & @MIN & ":" & @SEC & " " & _GetKeyboardLayout())
EndFunc

Func _GetKeyboardLayout()
  Local $hWnd = WinGetHandle("[active]")
  Local $aRet = DllCall("user32.dll", "long", "GetWindowThreadProcessId", "hwnd", $hWnd, "ptr", 0)
  $aRet = DllCall("user32.dll", "long", "GetKeyboardLayout", "long", $aRet[0])
  Switch Hex($aRet[0], 4)
    Case 0409
      Return " EN"
    Case 0419
      Return " RU"
    Case Else
      Return ""
  EndSwitch
EndFunc
 
Верх