Что нового

Как вывести секунды бортовых часов виндовс в иконку в трее?

agikon

Знающий
Сообщения
789
Репутация
17
у кого есть желание помогите пожалуйста реализовать данный скрипт.
то есть чтобы в прозрачной иконке, в трее, например красными буквами показывало секунды часов.
ну то есть обычных часов винды, напрмиер на часах 15:37:21
от оно и показывало 21 секунду, ну то есть чтобы отсчитывало в трее с 1 секунды до 60, и так постоянно.
 

WSWR

AutoIT Гуру
Сообщения
941
Репутация
362
agikon, тебе ж по этой, трей-иконочной теме, давали ссылку http://autoit-script.ru/index.php/topic,6030.msg42829.html#msg42829
там приведен базовый пример от Yashied и madmasles вывода текста в иконку(кстати, сам буду им пользоваться :laugh:smile:

Переделать этот пример для вывода секунд недолго:

Код:
#include <FontConstants.au3>
#include <HotKey.au3>
#include <WinAPIEx.au3>

Opt('MustDeclareVars', 1)
Opt('TrayAutoPause', 0)

Global $hAutoIt = WinGetHandle(AutoItWinGetTitle())
Global $Count = 0, $hPrev = 0
HotKeySet('{Esc}', '_Exit')


While 1
Sleep(1000)
_SetAutoItIcon(@SEC, 0xFF0000, 0xD4D0C8)	
WEnd

Func _Exit()
    Exit
EndFunc   ;==>_Exit

Func _SetAutoItIcon($iCount, $iColor = 0x000000, $iBkColor = 0xFFFFFF)
    Local $hDC, $hBitmap, $hMask, $hIcon, $hFont, $tNID, $tRect
    $hDC = _WinAPI_CreateCompatibleDC(0)
    $hBitmap = _WinAPI_CreateSolidBitmap(0, $iBkColor, 16, 16)
    $hMask = _WinAPI_CreateBitmap(16, 16, 1, 1)
    $hFont = _WinAPI_CreateFont(18, 4, 0, 0, $FW_NORMAL, 0, 0, 0, $DEFAULT_CHARSET, $OUT_DEFAULT_PRECIS, $CLIP_DEFAULT_PRECIS, $ANTIALIASED_QUALITY, $DEFAULT_PITCH, 'Tahoma')
    $tRect = _WinAPI_CreateRectEx(1, 0, 15, 16)
    _WinAPI_SelectObject($hDC, $hBitmap)
    _WinAPI_SelectObject($hDC, $hFont)
    _WinAPI_SetTextColor($hDC, $iColor)
    _WinAPI_SetBkColor($hDC, _WinAPI_SwitchColor($iBkColor))
    _WinAPI_DrawText($hDC, $iCount, $tRect, BitOR($DT_CENTER, $DT_SINGLELINE, $DT_VCENTER))
    _WinAPI_DeleteDC($hDC)
    $hIcon = _WinAPI_CreateIconIndirect($hBitmap, $hMask)
    _WinAPI_DeleteObject($hBitmap)
    _WinAPI_DeleteObject($hMask)
    _WinAPI_DeleteObject($hFont)
    $tNID = DllStructCreate($tagNOTIFYICONDATA)
    DllStructSetData($tNID, 'Size', DllStructGetSize($tNID))
    DllStructSetData($tNID, 'hWnd', $hAutoIt)
    DllStructSetData($tNID, 'Flags', $NIF_ICON)
    DllStructSetData($tNID, 'ID', 1)
    DllStructSetData($tNID, 'hIcon', $hIcon)
    _WinAPI_ShellNotifyIcon($NIM_MODIFY, $tNID)
    If $hPrev Then
        _WinAPI_DestroyIcon($hPrev)
    EndIf
    $hPrev = $hIcon
EndFunc   ;==>_SetAutoItIcon
 
Автор
A

agikon

Знающий
Сообщения
789
Репутация
17
ну как же не долго? вот вы чего ж тогда не переделаете раз это недолго? :scratch:
 

Medic84

Омега
Команда форума
Администратор
Сообщения
1,585
Репутация
338
agikon
Вы чего хотите? Вы код пробовали? Код - соответствует ТЗ (ну кроме розрачности)
 
Автор
A

agikon

Знающий
Сообщения
789
Репутация
17
ой
а я ж не знал что WSWR переделал под секунды :-\
да отлично работает. т очто и надо было.

только выложите пожалуйста инклуд HotKey.au3, нигде не могу найти.
 

Medic84

Омега
Команда форума
Администратор
Сообщения
1,585
Репутация
338
Он не нужен в коде этой программы.
 
Автор
A

agikon

Знающий
Сообщения
789
Репутация
17
а какой код имеет прозрачный фон?
 

WSWR

AutoIT Гуру
Сообщения
941
Репутация
362
На счет прозрачности - это для классической темы XP, серый не виден на сером, простейшее решение, а так надо брать цвет тулбара трея, мне лень усложнять. Смотрим цвет трея Au3Info, подставляем в код - получаем "прозрачно".
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,722
agikon сказал(а):
только выложите пожалуйста инклуд HotKey.au3, нигде не могу найти.

А ты пробывал? Вбиваешь в строке поиска по форуму "HotKey.au3" и, как ни странно, получаешь ответ в первой строчке.
 
Автор
A

agikon

Знающий
Сообщения
789
Репутация
17
сори проглючило, забыл я что на формуме можно искать.

WSWR
но это то что вы предлагаете временное решение, а если по-настоящему прозрачно то очень сложно сделать?
 

Zaramot

I ♥ AutoIt
Сообщения
1,160
Репутация
660
OffTopic:
agikon,
А зачем вам секунды ? Или вы хотите в место секунд поставить уровень звука ?
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,722
agikon сказал(а):
...а если по-настоящему прозрачно то очень сложно сделать?

Код:
#Include <APIConstants.au3>
#Include <GDIPlus.au3>
#Include <WinAPIEx.au3>

Opt('TrayMenuMode', 1)

Global Const $hAutoIt = WinGetHandle(AutoItWinGetTitle())
Global $Count = @SEC

$Exit = TrayCreateItem('Exit')

_GDIPlus_Startup()

_Count()
AdlibRegister('_Count', 1000)

Do
Until TrayGetMsg() = $Exit

_GDIPlus_Shutdown()

Func _Count()
	_SetTrayIcon(StringFormat('%02d', $Count), 0xA0C00000)
	$Count += 1
	If $Count > 59 Then
		$Count = 0
	EndIf
EndFunc   ;==>_Count

Func _SetTrayIcon($sSeconds, $iColor = 0xFF000000)

	Static $hPrev = 0

	Local $tNID, $hBitmap[2], $hIcon, $hGraphic, $hImage, $hBrush, $hFormat, $hFamily, $hFont, $pBits, $aData, $tData

	$hImage = _GDIPlus_CreateBitmapFromScan0(16, 16)
	$hGraphic = _GDIPlus_ImageGetGraphicsContext($hImage)
	$hBrush = _GDIPlus_BrushCreateSolid($iColor)
	$hFormat = _GDIPlus_StringFormatCreate()
	$hFamily = _GDIPlus_FontFamilyCreate('Impact')
	$hFont = _GDIPlus_FontCreate($hFamily, 11)
	$aData = _GDIPlus_GraphicsMeasureString($hGraphic, $sSeconds, $hFont, _GDIPlus_RectFCreate(0, 0, 0, 0), $hFormat)
	DllStructSetData($aData[0], 1, -2)
;~	DllStructSetData($aData[0], 1, (16 - DllStructGetData($aData[0], 3)) / 2)
	DllStructSetData($aData[0], 2, (16 - DllStructGetData($aData[0], 4)) / 2)
	_GDIPlus_GraphicsSetTextRenderingHint($hGraphic, 4)
	_GDIPlus_GraphicsDrawStringEx($hGraphic, $sSeconds, $hFont, $aData[0], $hFormat, $hBrush)
	$hBitmap[0] = _WinAPI_CreateBitmap(16, 16, 1, 32)
	$tData = _GDIPlus_BitmapLockBits($hImage, 0, 0, 16, 16, $GDIP_ILMREAD, $GDIP_PXF32ARGB)
	_WinAPI_SetBitmapBits($hBitmap[0], 1024, DllStructGetData($tData, 'Scan0'))
	_GDIPlus_BitmapUnlockBits($hBitmap, $tData)
	_GDIPlus_FontDispose($hFont)
	_GDIPlus_FontFamilyDispose($hFamily)
	_GDIPlus_StringFormatDispose($hFormat)
	_GDIPlus_BrushDispose($hBrush)
	_GDIPlus_GraphicsDispose($hGraphic)
	_GDIPlus_ImageDispose($hImage)
	$hBitmap[1] = _WinAPI_CreateBitmap(16, 16)
	$hIcon = _WinAPI_CreateIconIndirect($hBitmap[0], $hBitmap[1])
	For $i = 0 To 1
		_WinAPI_DeleteObject($hBitmap[$i])
	Next
	$tNID = DllStructCreate($tagNOTIFYICONDATA)
	DllStructSetData($tNID, 'Size', DllStructGetSize($tNID))
	DllStructSetData($tNID, 'hWnd', $hAutoIt)
	DllStructSetData($tNID, 'Flags', $NIF_ICON)
	DllStructSetData($tNID, 'ID', 1)
	DllStructSetData($tNID, 'hIcon', $hIcon)
	_WinAPI_ShellNotifyIcon($NIM_MODIFY, $tNID)
	If $hPrev Then
		_WinAPI_DestroyIcon($hPrev)
	EndIf
	$hPrev = $hIcon
EndFunc   ;==>_SetTrayIcon

Func _GDIPlus_CreateBitmapFromScan0($iWidth, $iHeight, $iStride = 0, $iPixelFormat = 0x0026200A, $pScan0 = 0)

	Local $Ret = DllCall($ghGDIPDll, 'uint', 'GdipCreateBitmapFromScan0', 'int', $iWidth, 'int', $iHeight, 'int', $iStride, 'int', $iPixelFormat, 'ptr', $pScan0, 'ptr*', 0)

	If @error Then
		Return SetError(1, 0, 0)
	Else
		If $Ret[0] Then
			Return SetError(1, $Ret[0], 0)
		EndIf
	EndIf
	Return $Ret[6]
EndFunc   ;==>_GDIPlus_CreateBitmapFromScan0

Func _GDIPlus_GraphicsSetTextRenderingHint($hGraphic, $iTextRenderingHint)

	Local $Ret = DllCall($ghGDIPDll, 'uint', 'GdipSetTextRenderingHint', 'ptr', $hGraphic, 'int', $iTextRenderingHint)

	If @error Then
		Return SetError(1, 0, 0)
	Else
		If $Ret[0] Then
			Return SetError(1, $Ret[0], 0)
		EndIf
	EndIf
	Return 1
EndFunc   ;==>_GDIPlus_GraphicsSetTextRenderingHint
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,321
Yashied,
Как всегда, супер! :thanks:
 
Автор
A

agikon

Знающий
Сообщения
789
Репутация
17
Yashied
скрипт отличный.
но заметил ложку дёгтя в скрипте.
а именно, если на оконке в трее накать правую клавишу(появится окошко) и так подождать пару секунд, то секунды останавивают отсчет. бросаешь и секунды уже отстают на то время на которое было открыто меню.
 

Yashied

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

Opt('TrayMenuMode', 1)

Global Const $hAutoIt = WinGetHandle(AutoItWinGetTitle())
Global $Count = @SEC

$Exit = TrayCreateItem('Exit')

_GDIPlus_Startup()

_Timer_SetTimer(0, 1000, '_Count')
_Count(0, 0, 0, 0)

Do
Until TrayGetMsg() = $Exit

_Timer_KillAllTimers(0)
_GDIPlus_Shutdown()

Func _Count($hWnd, $iMsg, $ID, $iTime)

	#forceref $hWnd, $iMsg, $ID, $iTime

	_SetTrayIcon(StringFormat('%02d', $Count), 0xA0C00000)
	$Count += 1
	If $Count > 59 Then
		$Count = 0
	EndIf
EndFunc   ;==>_Count

Func _SetTrayIcon($sSeconds, $iColor = 0xFF000000)

	Static $hPrev = 0

	Local $tNID, $hBitmap[2], $hIcon, $hGraphic, $hImage, $hBrush, $hFormat, $hFamily, $hFont, $pBits, $aData, $tData

	$hImage = _GDIPlus_CreateBitmapFromScan0(16, 16)
	$hGraphic = _GDIPlus_ImageGetGraphicsContext($hImage)
	$hBrush = _GDIPlus_BrushCreateSolid($iColor)
	$hFormat = _GDIPlus_StringFormatCreate()
	$hFamily = _GDIPlus_FontFamilyCreate('Impact')
	$hFont = _GDIPlus_FontCreate($hFamily, 11)
	$aData = _GDIPlus_GraphicsMeasureString($hGraphic, $sSeconds, $hFont, _GDIPlus_RectFCreate(0, 0, 0, 0), $hFormat)
	DllStructSetData($aData[0], 1, -2)
;~  DllStructSetData($aData[0], 1, (16 - DllStructGetData($aData[0], 3)) / 2)
	DllStructSetData($aData[0], 2, (16 - DllStructGetData($aData[0], 4)) / 2)
	_GDIPlus_GraphicsSetTextRenderingHint($hGraphic, 4)
	_GDIPlus_GraphicsDrawStringEx($hGraphic, $sSeconds, $hFont, $aData[0], $hFormat, $hBrush)
	$hBitmap[0] = _WinAPI_CreateBitmap(16, 16, 1, 32)
	$tData = _GDIPlus_BitmapLockBits($hImage, 0, 0, 16, 16, $GDIP_ILMREAD, $GDIP_PXF32ARGB)
	_WinAPI_SetBitmapBits($hBitmap[0], 1024, DllStructGetData($tData, 'Scan0'))
	_GDIPlus_BitmapUnlockBits($hBitmap, $tData)
	_GDIPlus_FontDispose($hFont)
	_GDIPlus_FontFamilyDispose($hFamily)
	_GDIPlus_StringFormatDispose($hFormat)
	_GDIPlus_BrushDispose($hBrush)
	_GDIPlus_GraphicsDispose($hGraphic)
	_GDIPlus_ImageDispose($hImage)
	$hBitmap[1] = _WinAPI_CreateBitmap(16, 16)
	$hIcon = _WinAPI_CreateIconIndirect($hBitmap[0], $hBitmap[1])
	For $i = 0 To 1
		_WinAPI_DeleteObject($hBitmap[$i])
	Next
	$tNID = DllStructCreate($tagNOTIFYICONDATA)
	DllStructSetData($tNID, 'Size', DllStructGetSize($tNID))
	DllStructSetData($tNID, 'hWnd', $hAutoIt)
	DllStructSetData($tNID, 'Flags', $NIF_ICON)
	DllStructSetData($tNID, 'ID', 1)
	DllStructSetData($tNID, 'hIcon', $hIcon)
	_WinAPI_ShellNotifyIcon($NIM_MODIFY, $tNID)
	If $hPrev Then
		_WinAPI_DestroyIcon($hPrev)
	EndIf
	$hPrev = $hIcon
EndFunc   ;==>_SetTrayIcon

Func _GDIPlus_CreateBitmapFromScan0($iWidth, $iHeight, $iStride = 0, $iPixelFormat = 0x0026200A, $pScan0 = 0)

	Local $Ret = DllCall($ghGDIPDll, 'uint', 'GdipCreateBitmapFromScan0', 'int', $iWidth, 'int', $iHeight, 'int', $iStride, 'int', $iPixelFormat, 'ptr', $pScan0, 'ptr*', 0)

	If @error Then
		Return SetError(1, 0, 0)
	Else
		If $Ret[0] Then
			Return SetError(1, $Ret[0], 0)
		EndIf
	EndIf
	Return $Ret[6]
EndFunc   ;==>_GDIPlus_CreateBitmapFromScan0

Func _GDIPlus_GraphicsSetTextRenderingHint($hGraphic, $iTextRenderingHint)

	Local $Ret = DllCall($ghGDIPDll, 'uint', 'GdipSetTextRenderingHint', 'ptr', $hGraphic, 'int', $iTextRenderingHint)

	If @error Then
		Return SetError(1, 0, 0)
	Else
		If $Ret[0] Then
			Return SetError(1, $Ret[0], 0)
		EndIf
	EndIf
	Return 1
EndFunc   ;==>_GDIPlus_GraphicsSetTextRenderingHint
 
Автор
A

agikon

Знающий
Сообщения
789
Репутация
17
Yashied
теперь вообще идеально. :ok:
спасибо.

но сам код конечно сложный не то слово...

вроде и задача так сказать не такая уж и ресурсоемкая, как бы порсто вывести секунды в прозрачню но сколько работы... :wacko:

я в шоке.
как это можно всё отследить что куда идёт... :wacko:
я вообще не пойму как это реализовывается, но наверно там есть две заливки, одна из которой отвечает за прозрачность, а вторая за цифры, и та что за цифры налаживается на ту что прозрачна. как же это всё запутано... :whistle:
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,722
Предыдущий пример использует GDI, но он не поддерживает прозрачность. Здесь все тоже самое, но только GDI+, который уже полностью поддерживает прозрачность. В целом ничего сложного: создаем пустой битмап, рисуем на нем все, что угодно (в данном случае текст), затем на его основе и пустой маски создаем иконку, которую и помещаем в трей. Сам процесс рисования типичен для WinAPI, только так и делается.
 
Автор
A

agikon

Знающий
Сообщения
789
Репутация
17
для новичка это высшая математика... :whistle:
вот например если как создавать картинки с помощью GDI+ ещё можно как то хоть теоретически понять, но вот откуда берутся и что делают строки на подобии вот этих вызывают шок.
Код:
DllStructSetData($aData[0], 2, (16 - DllStructGetData($aData[0], 4)) / 2)
_WinAPI_SetBitmapBits($hBitmap[0], 1024, DllStructGetData($tData, 'Scan0'))
$hIcon = _WinAPI_CreateIconIndirect($hBitmap[0], $hBitmap[1])
_WinAPI_ShellNotifyIcon($NIM_MODIFY, $tNID)
 
Верх