Что нового

Как узнать координаты и размер пустой области панели задач?

Hiki

Новичок
Сообщения
27
Репутация
1
Сделал себе панель поиска в гугле. Поместил ее на панель задач слева от трея по фиксированным координатам, что меня не устраивает, потому что количество значков в трее величина переменная.
Код:
#NoTrayIcon
#include <Misc.au3>
#include <WinAPI.au3>
#include <WindowsConstants.au3>

Global $w=150, $h=20, $x=1200, $y=@DesktopHeight-25																;размеры и позиция

$win=GUICreate('', $w, $h, $x, $y, $WS_POPUP, $WS_EX_TOOLWINDOW)												;окно
$input=GUICtrlCreateInput('', -2, -2, $w+4, $h+4)																;поле ввода
GUISetState()																									;показать

Do
$txt=GUICtrlRead($input)																						;текст для поиска
If $input=_WinAPI_GetDlgCtrlID(ControlGetHandle($win, '', ControlGetFocus($win))) And _IsPressed('0D') Then		;если фокус+enter
ShellExecute('http://google.ru/search?q='&$txt)																	;поиск
GUICtrlSetData($input, '')																						;очистка после enter
EndIf
If WinActive('[CLASS:Shell_TrayWnd]', '')=0 Then WinSetOnTop($win, '', 0)										;под панелью при неактивной панели
If WinActive('[CLASS:Shell_TrayWnd]', '')+WinActive($win, '')>0 Then WinSetOnTop($win, '', 1)					;над панелью при активной панели
Sleep(100)
Until $txt='000'																								;текст для выхода

GUIDelete()
Exit
Нужно координату $x сделать зависимой от ширины трея, плюс еще слева от трея значок языковой панели.
Пробовал ControlGetPos, но выдает только размер панели задач целиком.
Подскажите кто в курсе.
 

Tyr

Новичок
Сообщения
43
Репутация
4
Я не профи в этом языке, но подобные задачи, если не решаются влоб, решаются методами на подобие PixelSearch (да пусть и не супер производительно и не универсально, зато кода мало и просто:
Код:
; Найти чисто красный пиксель в прямоугольнике 0,0-20,300
$coord = PixelSearch(0, 0, 20, 300, 0xFF0000)
If Not @error Then
    MsgBox(0, "X и Y равны:", $coord[0] & "," & $coord[1])
EndIf

; Найти чисто красный пиксель или пиксель с отклонением 10 градаций от чисто красного
$coord = PixelSearch(0, 0, 20, 300, 0xFF0000, 10)
If Not @error Then
    MsgBox(0, "X и Y равны:", $coord[0] & "," & $coord[1])
EndIf
 
Автор
H

Hiki

Новичок
Сообщения
27
Репутация
1
Tyr
Каким образом ваше решение может определить координаты и размеры трея на произвольном мониторе? :scratch:
 

Tyr

Новичок
Сообщения
43
Репутация
4
"...плюс еще слева от трея значок языковой панели." Значок можно по двум(трем) пикселям в заданной области идентифицировать и получив его координаты найти Х... также у меня там надпись Desktop >> ...В Бот темах этого форума примеров много, как кликнуть сбоку от нарисованного текста.... а тебе не кликнуть надо, а только координату получить
 

Tempo

AutoIT Гуру
Сообщения
616
Репутация
205
Пример
Код:
#NoTrayIcon
#include <WinAPI.au3>
#include <WindowsConstants.au3>
#include <GuiConstants.au3>
#include <MsgBoxConstants.au3>
Global $hTaskBar = WinGetHandle("[CLASS:Shell_TrayWnd]"), $hCicero = ControlGetHandle($hTaskBar, Null, "[CLASS:CiceroUIWndFrame; INSTANCE:1]")
Global $sSite = "http://google.ru/search?q=", $sBanner = "Введите запрос"
Global $tPOINT = DllStructCreate($tagPOINT), $iW = 150, $iH = 20, $iX, $iY
Global $hGUI, $iInput, $iEnter, $hInput, $sText

If Not $hTaskBar Or Not $hCicero Then Exit MsgBox($MB_ICONERROR + $MB_TOPMOST, "Ошибка", "Не удалось получить дескриптор Shell_TrayWnd/CiceroUIWndFrame")

_WinAPI_ClientToScreen($hCicero, $tPOINT)
$iX = DllStructGetData($tPOINT, 1) - $iW - 10
$iY = @DesktopHeight - (WinGetPos($hTaskBar)[3] + $iH) / 2

$hGUI = GUICreate(Null, $iW, $iH, $iX, $iY, $WS_POPUP, $WS_EX_TOOLWINDOW)
$iInput = GUICtrlCreateInput(Null, 0, 0, $iW, $iH, $WS_BORDER, 0)
GUICtrlSendMsg(-1, $EM_SETCUEBANNER, True, $sBanner)
$hInput = GUICtrlGetHandle(-1)
$iEnter = GUICtrlCreateDummy()
Global $aKeys[1][2] = [["{ENTER}", $iEnter]]
GUISetAccelerators($aKeys)
GUISetState(@SW_SHOWNOACTIVATE)
AdlibRegister("_UpdatePos", 1000)

While 1
	Switch GUIGetMsg()
		Case $iEnter
			$sText = GUICtrlRead($iInput)
			If _WinAPI_GetFocus() = $hInput And $sText Then
				ShellExecute($sSite & $sText)
				GUICtrlSetData($iInput, Null)
			EndIf
		Case $GUI_EVENT_CLOSE
			ExitLoop
	EndSwitch
	If WinActive($hTaskBar) Then
		WinSetOnTop($hGUI, Null, 1)
	ElseIf Not WinActive($hGUI) Then
		WinSetOnTop($hGUI, Null, 0)
	EndIf
WEnd
GUIDelete($hGUI)

Func _UpdatePos()
	Local $iTmpX, $iTmpY
	DllStructSetData($tPOINT, 1, 0)
	_WinAPI_ClientToScreen($hCicero, $tPOINT)
	$iTmpX = DllStructGetData($tPOINT, 1) - $iW - 10
	$iTmpY = @DesktopHeight - (WinGetPos($hTaskBar)[3] + $iH) / 2
	If $iTmpX <> $iX Or $iTmpY <> $iY Then
		$iX = $iTmpX
		$iY = $iTmpY
		WinMove($hGUI, Null, $iX, $iY)
	EndIf
EndFunc   ;==>_UpdatePos
 

InnI

AutoIT Гуру
Сообщения
4,912
Репутация
1,429
Hiki [?]
Нужно координату $x сделать зависимой от ширины трея, плюс еще слева от трея значок языковой панели.
Код:
$aPos = ControlGetPos("[class:Shell_TrayWnd]", "", "MSTaskListWClass1")
If Not IsArray($aPos) Then Exit

$X = $aPos[0] + $aPos[2]
ConsoleWrite($X & @CRLF)
 
Автор
H

Hiki

Новичок
Сообщения
27
Репутация
1
Всем спасибо за помощь, сделал так:
Код:
#NoTrayIcon
#include <Misc.au3>
#include <WinAPI.au3>
#include <GuiConstants.au3>
#include <WindowsConstants.au3>

Global $cls='[CLASS:Shell_TrayWnd]', $bar=ControlGetPos($cls, '', 'MSTaskListWClass1'), $w=150, $h=20, $x=$bar[0]+$bar[2]-$w, $y=@DesktopHeight-($bar[3]+$h)/2

$win=GUICreate('', $w, $h, $x, $y, $WS_POPUP, $WS_EX_TOOLWINDOW)			;окно
GUICtrlSetDefBkColor(0x000000)												;цвет
GUICtrlSetDefColor(0x00FF00)												;цвет текста
GUISetFont(10, 700, '', 'Courier New')										;шрифт
$input=GUICtrlCreateInput('', -2, -2, $w+4, $h+4)							;поле ввода
GUISetState()
AdlibRegister('upd', 1000)

Do
$txt=GUICtrlRead($input)													;текст для поиска
If _WinAPI_GetFocus()=GUICtrlGetHandle($input) And _IsPressed('0D') Then	;если фокус+enter
	ShellExecute('http://google.ru/search?q='&$txt)							;поиск
	GUICtrlSetData($input, '')												;очистка после enter
EndIf
If WinActive($cls) Then
	WinSetOnTop($win, '', 1)												;над панелью при активной панели
ElseIf Not WinActive($win) Then
	WinSetOnTop($win, '', 0)												;под панелью при неактивной панели
EndIf
Sleep(200)
Until GUIGetMsg()=$GUI_EVENT_CLOSE Or $txt='---'							;выход
GUIDelete()

Func upd()
$bar=ControlGetPos($cls, '', 'MSTaskListWClass1')							;апдейт
If $bar[0]+$bar[2]-$w<>$x Then
	$x=$bar[0]+$bar[2]-$w
	WinMove($win, '', $x, $y)												;сдвиг
EndIf
EndFunc
Теперь работает как надо :ok:
 
Верх