;Скрипт отображает сообщение в правом нижнем углу экрана
;Формат запуска message_clear.exe cmd#-#sec#-#message
;cmd - команда add - добавить сообщение; upd - обновить предыдущее сообщение; off - выход из скрипта
;sec - количество секунд до выхода из скрипта
;message - само сообщение
;Между параметрами знаки #-# обязательны
;Щелчек по окну сообщения ПКМ = выход из крипта
#include <EditConstants.au3>
#include <StaticConstants.au3>
#include <GUIConstantsEx.au3>
#include <ListBoxConstants.au3>
#include <WindowsConstants.au3>
#include <WinAPI.au3>
#include <Array.au3>
#include <Timers.au3>
#include <Misc.au3>
#NoTrayIcon
Local $Text="", $Text_new="", $Text_buf="",$Text_Last="", $sCMD, $iSEC, $sTXT
Local $i, $y, $height, $width, $Size, $Pos, $Clip="", $iLabel, $TimeOFF=0, $TimeOut=0
Local $aParam, $iTimerID, $Timer1
if _Singleton("message67538",1) = 0 Then;Если окно с заголовком Х уже запущено
$hGUI = WinGetHandle ("message67538");Получаем ID этого окна
WinActivate($hGUI);Активируем окно
_AU3COM_SendData($CmdLineRaw, $hGUI);отправляем текст
Exit
EndIf
Global $hGUI = GUICreate("message67538", 0, 0, -1, -1, $WS_POPUP, $WS_EX_TOPMOST, $WS_EX_TOOLWINDOW);$WS_EX_TOOLWINDOW=нет иконки в панели задач $WS_EX_TOPMOST=поверх всех окон
WinSetTrans($hGUI, "", 200);Устанавливает прозрачность окна.
$iLabel = GUICtrlCreateLabel('', 0, 0)
GUICtrlSetBkColor(-1,0x005200)
GUICtrlSetFont(-1, 10, 650, 0);Размер шрифта
GUICtrlSetColor( -1, 0x00DE00);Цвет шрифта
GUICtrlSetLimit(-1, 200) ; ограничить прокрутку по горизонтали
_WinStickToRightCorner($hGUI)
GUISetState()
GUIRegisterMsg($WM_NCHITTEST, "WM_NCHITTEST");Сообщение выполняется при скольжении курсора мыши в окне
GUIRegisterMsg($WM_COPYDATA, "_GUIRegisterMsgProc");Интеракция между скриптами
if $CmdLineRaw=="" Then
Exit
EndIf
$aParam= StringSplit($CmdLineRaw, "#-#", 1);
if $aParam[0] <> 3 Then
Exit
EndIf
$sCMD="first";$CmdLine[1]
$iSEC=$aParam[2]
$sTXT=$aParam[3]
While 1
Switch GUIGetMsg()
Case $GUI_EVENT_PRIMARYDOWN ;закроет окно по нажатию ЛКМ
;MsgBox(0, "Событие GUI", "Вы нажали CLOSE! Завершаем...")
_Exit()
EndSwitch
Select
Case $Text_new <> $sTXT
$Text_new=$sTXT
Switch $sCMD
Case "first";Добавление первой строки в окно
if $sTXT=="off" Then
Exit
EndIf
$Text = @hour & ":" & @min & ":" & @sec & ">" & $sTXT
Case "add";Добавление новой строки в окно
$Text_Last=$Text
$Text = $Text & @CRLF & @hour & ":" & @min & ":" & @sec & ">" & $sTXT
Case "upd";Обработка команды обновления предыдущей строки upd#-#3#-#ae-ae-off
$Text = $Text_Last & @CRLF & @hour & ":" & @min & ":" & @sec & ">" & $sTXT
Case "off";Обработка команды выхода из приложения off#-#3#-#
Sleep ($iSEC*1000)
_Exit()
Case Else
$Text = $Text & @CRLF & @hour & ":" & @min & ":" & @sec & ">" & "Не понятная команда: " & $sCMD
EndSwitch
$Text_buf = $Text
$Size = _GetTabbedStringSizeEx(-1, $Text_buf, 1)
If Not @Error Then
GUICtrlSetPos($iLabel, 0, 0, $Size[0], $Size[1])
GUICtrlSetData(-1, $Text)
EndIf
WinMove ($hGUI, '', Default, Default , $Size[0], $Size[1])
_WinStickToRightCorner($hGUI);_Sleep($TimeOFF)
Case Else
$Pos = 1
EndSelect
WEnd
Func _GUIRegisterMsgProc($hWnd, $MsgID, $WParam, $LParam)
If $MsgID = $WM_COPYDATA Then
Local $vs_Msg = _AU3COM_RecvData($LParam)
Local $sMSGRECVD = DllStructGetData($vs_Msg, 1)
$aParam= StringSplit($sMSGRECVD, "#-#", 1);
if $aParam[0] <> 3 Then
Return -1
EndIf
$sCMD=$aParam[1];$CmdLine[1]
$iSEC=$aParam[2]
$sTXT=$aParam[3]
EndIf
EndFunc
Func _AU3COM_RecvData($iCOM_LParam)
; $COM_LParam = Poiter to a COPYDATA Struct
Local $STRUCTDEF_AU3MESSAGE = "char var1[256];int"
Local $StructDef_COPYDATA = "dword var1;dword var2;ptr var3"
Local $vs_cds = DllStructCreate($StructDef_COPYDATA, $iCOM_LParam)
; Member No. 3 of COPYDATA Struct (PVOID lpData;) = Pointer to Costum Struct
Local $vs_msg = DllStructCreate($STRUCTDEF_AU3MESSAGE, DllStructGetData($vs_cds, 3))
Return $vs_msg
EndFunc
Func _AU3COM_SendData($sInfoToSend, $hRecvWinHandle)
Local $StructDef_COPYDATA = "dword var1;dword var2;ptr var3"
Local $sCDString = DllStructCreate("char var1[256];char var2[256]") ;the array to hold the string we are sending
DllStructSetData($sCDString, 1, $sInfoToSend)
Local $pCDString = DllStructGetPtr($sCDString) ;the pointer to the string
Local $vs_cds = DllStructCreate($StructDef_COPYDATA);create the message struct
DllStructSetData($vs_cds, "var1", 0) ;0 here indicates to the receiving program that we are sending a string
DllStructSetData($vs_cds, "var2", String(StringLen($sInfoToSend) + 1));tell the receiver the length of the string
DllStructSetData($vs_cds, "var3", $pCDString) ;the pointer to the string
Local $pStruct = DllStructGetPtr($vs_cds)
DllCall("User32.dll", "int", "SendMessage", "hwnd", $hRecvWinHandle, "int", $WM_COPYDATA, "int", 0, "ptr", $pStruct)
$vs_cds = 0 ;free the struct
$sCDString = 0 ;free the struct
Return 1
EndFunc
Func _Exit()
For $i = 200 to 0 Step -5;buf#-#on#-#0#-#ae-ae
WinSetTrans($hGUI, "", $i)
Sleep (80)
Next
Exit
EndFunc
Func WM_NCHITTEST($hWnd, $iMsg, $iwParam, $ilParam);Сообщение выполняется при скольжении курсора мыши в окне
If $hWnd <> $hGUI Then Return $GUI_RUNDEFMSG
Local $iRet = _WinAPI_DefWindowProc($hWnd, $iMsg, $iwParam, $ilParam)
Switch $iRet
Case 10 To 18;Запрет изменения границ окна
Return 1
EndSwitch
Return $iRet
EndFunc
Func _WinStickToRightCorner($hWin);Позиционирует окно в правом нижнем углу
Local $aWin_Pos = WinGetPos($hWin)
Local $aClient_Size = WinGetClientSize($hWin)
Local $iBorder_Width = ($aWin_Pos[2] - $aClient_Size[0])
Local $iCaption_Height = ($aWin_Pos[3] - $aClient_Size[1])
Local Const $SPI_GETWORKAREA = 48
Local $stRECT = DllStructCreate("long;long;long;long")
Local $SPIRet = DllCall("User32.dll", "int", "SystemParametersInfo", _
"uint", $SPI_GETWORKAREA, "uint", 0, "ptr", DllStructGetPtr($stRECT), "uint", 0)
If @error Or $SPIRet[0] = 0 Then Return SetError(1, 0, 0)
Local $sRightArea = DllStructGetData($stRECT, 3)
Local $sBottomArea = DllStructGetData($stRECT, 4)
Local $iTop = (@DesktopHeight-(@DesktopHeight-$sBottomArea)-$aClient_Size[1]) - $iCaption_Height
Local $iLeft = (@DesktopWidth-$aClient_Size[0]) - $iBorder_Width
If $sRightArea < @DesktopWidth Then $iLeft -= (@DesktopWidth - $sRightArea)
WinMove($hWin, "", $iLeft, $iTop)
EndFunc
Func _GetTabbedStringSizeEx($CtrlID, ByRef $sString, $fAlignment = False);Эта функция возвращает размеры абсолютно любой строки (необязательно содержащей @TAB или @CRLF)
Local $W = 0, $H, $tTM, $pTM, $hDC = 0, $hSv = 0, $aTemp, $aSize, $aData, $aTabs, $aText, $sText = '', $Error, $Tab, $Ret
Local $tTM = DllStructCreate('long;long;long;long;long;long;long;long;long;long;long;wchar;wchar;wchar;wchar;byte;byte;byte;byte;byte')
;~ Local $tTM = DllStructCreate($tagTEXTMETRIC)
Local $pTM = DllStructGetPtr($tTM)
Local $tData = DllStructCreate('long;long')
Local $pData = DllStructGetPtr($tData)
Local $aResult[2] = [0, 0]
If Not IsHWnd($CtrlID) Then
$CtrlID = GUICtrlGetHandle($CtrlID)
If Not $CtrlID Then
Return SetError(1, 0, 0)
EndIf
EndIf
Do
$Error = 1
$Ret = DllCall('user32.dll', 'ptr', 'GetDC', 'hwnd', $CtrlID)
If (@Error) Or (Not $Ret[0]) Then
ExitLoop
EndIf
$hDC = $Ret[0]
$Ret = DllCall('user32.dll', 'ptr', 'SendMessageW', 'hwnd', $CtrlID, 'uint', 0x0031, 'wparam', 0, 'lparam', 0)
If (@Error) Or (Not $Ret[0]) Then
ExitLoop
EndIf
$Ret = DllCall('gdi32.dll', 'ptr', 'SelectObject', 'hwnd', $hDC, 'ptr', $Ret[0])
If (@Error) Or (Not $Ret[0]) Then
ExitLoop
EndIf
$hSv = $Ret[0]
$Ret = DllCall('gdi32.dll', 'int', 'GetTextMetricsW', 'hwnd', $hDC, 'ptr', $pTM)
If (@Error) Or (Not $Ret[0]) Then
ExitLoop
EndIf
$Tab = 8 * DllStructGetData($tTM, 6)
If Not $Tab Then
ExitLoop
EndIf
$aData = StringSplit(StringReplace($sString, @CRLF, @CR), @CR, 2)
$H = UBound($aData)
If ($H > 1) And ($fAlignment) Then
For $i = 0 To $H - 1
$aTemp = StringSplit($aData[$i], @TAB)
If $W < $aTemp[0] Then
$W = $aTemp[0]
EndIf
Next
Dim $aText[$H][$W]
Dim $aSize[$H][$W]
For $i = 0 To $H - 1
$aTemp = StringSplit($aData[$i], @TAB)
For $j = 0 To $W - 1
Select
Case $aTemp[0] < $j + 1
$aText[$i][$j] = 0
$aSize[$i][$j] = -1
Case $aTemp[0] = $j + 1
$aText[$i][$j] = $aTemp[$j + 1]
$aSize[$i][$j] = -1
Case Else
$aText[$i][$j] = $aTemp[$j + 1]
$Ret = DllCall('gdi32.dll', 'int', 'GetTextExtentPoint32W', 'hwnd', $hDC, 'wstr', $aTemp[$j + 1], 'int', StringLen($aTemp[$j + 1]), 'ptr', $pData)
If (Not @Error) And ($Ret[0]) Then
$aSize[$i][$j] = DllStructGetData($tData, 1)
Else
$aSize[$i][$j] = 0
EndIf
EndSelect
Next
Next
Dim $aTabs[$W]
For $j = 0 To $W - 1
$aTabs[$j] = 1
For $i = 0 To $H - 1
If $aSize[$i][$j] <> -1 Then
If $aSize[$i][$j] < $Tab Then
$aSize[$i][$j] = 1
Else
$aSize[$i][$j] = Floor($aSize[$i][$j] / $Tab) + 1
If $aTabs[$j] < $aSize[$i][$j] Then
$aTabs[$j] = $aSize[$i][$j]
EndIf
EndIf
EndIf
Next
Next
Dim $aData[$H]
For $i = 0 To $H - 1
$aData[$i] = ''
For $j = 0 To $W - 1
If IsString($aText[$i][$j]) Then
$aData[$i] &= $aText[$i][$j]
If $aSize[$i][$j] <> -1 Then
$aSize[$i][$j] = $aTabs[$j] - $aSize[$i][$j]
EndIf
For $k = 1 To $aSize[$i][$j] + 1
$aData[$i] &= @TAB
Next
Else
ExitLoop
EndIf
Next
$sText &= $aData[$i] & @CRLF
Next
EndIf
$Error = 1
DllStructSetData($tData, 1, $Tab)
For $i = 0 To $H - 1
$Ret = DllCall('user32.dll', 'dword', 'GetTabbedTextExtentW', 'hwnd', $hDC, 'wstr', $aData[$i], 'int', StringLen($aData[$i]), 'int', 1, 'ptr', $pData)
If (Not @Error) And ($Ret[0]) Then
$aResult[1] += BitShift($Ret[0], 16)
$Ret = BitAND($Ret[0], 0xFFFF)
If $aResult[0] < $Ret Then
$aResult[0] = $Ret
EndIf
Else
ExitLoop 2
EndIf
Next
$Error = 0
Until 1
If $hSv Then
DllCall('gdi32.dll', 'ptr', 'SelectObject', 'hwnd', $hDC, 'ptr', $hSv)
EndIf
If $hDC Then
DllCall('user32.dll', 'int', 'ReleaseDC', 'hwnd', $CtrlID, 'hwnd', $hDC)
EndIf
If $Error Then
Return SetError(1, 0, 0)
EndIf
If $fAlignment Then
$sString = StringTrimRight($sText, 2)
EndIf
Return $aResult
EndFunc ;==>_GetTabbedStringSizeEx
|