Что нового

Элементы GUI Как определить наличие фокуса на элементе

pvnn

Осваивающий
Сообщения
305
Репутация
32
Всем привет!
Есть элемент, созданный при помощи Autoit, например Input1, т.е. я знаю ID элемента, его хэндл, а как узнать в фокусе ли элемент? Вроде не сложная задача, но как-то не решается...
В ниже приведенном примере, зная ClassNameNN, я могу определить фокус элемента, но это как-то не универсально, т.к. ClassNameNN может быть любой, в зависимости от последовательности создания элементов на форме.
Можно ли определить наличие фокуса зная только ID элемента/хэндл или как мне программно узнать ClassNameNN элемента?
Код:
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>

HotKeySet("{F1}", "GetFocus")

$Form1 = GUICreate("Form1", 251, 142, 349, 207)
$Input1 = GUICtrlCreateInput("Input1", 8, 16, 121, 21)
$hInput1=GUICtrlGetHandle($Input1)
$Input2 = GUICtrlCreateInput("Input2", 8, 56, 121, 21)
GUISetState(@SW_SHOW)
While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit

    EndSwitch
WEnd

Func GetFocus()
    If ControlGetFocus($Form1)='Edit1' Then
        MsgBox(0,'','$Input1 - в фокусе')
    Else
        MsgBox(0,'','$Input1 - не в фокусе')
    EndIf
EndFunc
 

Oki

Продвинутый
Сообщения
452
Репутация
62
А если так?
Код:
Func GetFocus()
   If ControlGetHandle("", "", ControlGetFocus($Form1)) = $hInput1 Then
      MsgBox(0, "", "in focus")
   Else
      MsgBox(0, "", "not in focus")
   EndIf
EndFunc
 
  • Like
Реакции: pvnn

InnI

AutoIT Гуру
Сообщения
4,922
Репутация
1,432
в зависимости от последовательности создания элементов на форме
Последовательность создания элементов определяете вы сами. В вашем примере Input1 всегда будет Input1, потому что создаётся первым относительно остальных Input.

как мне программно узнать ClassNameNN элемента
 

Oki

Продвинутый
Сообщения
452
Репутация
62
Последовательность создания элементов определяете вы сами. В вашем примере Input1 всегда будет Input1, потому что создаётся первым относительно остальных Input.
Разве автор кода не может использовать мнемонику иного стиля в именовании дескрипторов? Суть же вопроса была в обращении именно по дескриптору.
Не очень понятно, как использовать получение имени класса окна, когда речь об одном конкретном элементе управления. Но это касается лишь побочного вопроса, возникшего у топикстартера, предложившего один из путей решения изначально сформулированного вопроса. Можно ли попросту обойтись функцией ControlGetHandle(), если отбросить побочный вопрос?
 
Последнее редактирование:

Norm

Продвинутый
Сообщения
278
Репутация
74
Я для этого у себя такую функцию сделал:

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

HotKeySet("{F1}", "GetFocus")

$Form1 = GUICreate("Form1", 251, 142, 349, 207)
$Input1 = GUICtrlCreateInput("Input1", 8, 16, 121, 21)
$hInput1=GUICtrlGetHandle($Input1)
$Input2 = GUICtrlCreateInput("Input2", 8, 56, 121, 21)
GUISetState(@SW_SHOW)
While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit

    EndSwitch
WEnd

Func GetFocus()
    Local $aInfo = _ControlGetFocusEx($Form1, 3)
    If $aInfo <> -1 Then
        MsgBox(0, "В фокусе", _
        "ID = "& $aInfo[0] & @CRLF & _
        "Handle = "& $aInfo[1] & @CRLF & _
        "CLASSNN = "& $aInfo[2])
    EndIf
EndFunc

; Возвращает дескриптор, класс и Control-ID элемента имеющего фокус
Func _ControlGetFocusEx($hWnd = 0, _ ; Дескрипток окна
    $iRet = 0) ; Return: 0 => ID элемента; 1 дескриптор элемента; 2 класс элемента; 3 => массив со всей информацией
    If $hWnd = 0 Then
        $hWnd = WinGetHandle("[ACTIVE]")
    EndIf
    If Not $hWnd Then
        Return -1
    EndIf
    Local $aRetArr[3]
    $aRetArr[2] = ControlGetFocus($hWnd) ; Klass
    $aRetArr[1] = ControlGetHandle($hWnd,"",$aRetArr[2]) ; Handle
    $aRetArr[0] = _WinAPI_GetDlgCtrlID($aRetArr[1]) ; GUI-ID
    Switch $iRet
        Case 3
            Return $aRetArr
        Case Else
            Return $aRetArr[$iRet]
    EndSwitch
EndFunc
 

Oki

Продвинутый
Сообщения
452
Репутация
62
Код:
While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit

    EndSwitch
WEnd
Всегда поражает, когда вижу эту конструкцию. Ведь можно не мудрить.
Код:
Do
Until GUIGetMsg() = $GUI_EVENT_CLOSE
Но в целом за готовое решение, конечно, лайк. Не в курсе, годится ли для частной цели основного вопроса топика моё, которое выше? Ведь топикстартеру, похоже, не требуется большего.
 
Последнее редактирование:
Автор
P

pvnn

Осваивающий
Сообщения
305
Репутация
32

Oki, Norm

Спасибо! Для Edit все идеально получилось. но я так понимаю, что с ComboBox подобная конструкция работать не будет.
Потому что GUICtrlGetHandle($Combo1) вернет указатель на ComboBox, а ControlGetHandle("", "", ControlGetFocus($Form1)) указатель на Edit1

Код:
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>

HotKeySet("{F1}", "GetFocus")

$Form1 = GUICreate("Form1", 251, 142, 349, 207)
$Combo1 = GUICtrlCreateCombo("Combo1", 8, 16, 121, 21)
$hCombo1=GUICtrlGetHandle($Combo1)

$Input2 = GUICtrlCreateInput("Input2", 8, 56, 121, 21)
GUISetState(@SW_SHOW)
While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit

    EndSwitch
WEnd

Func GetFocus()
    MsgBox(0,'',ControlGetFocus($Form1)&@CRLF& $hCombo1 &' - '&ControlGetHandle("", "", ControlGetFocus($Form1)))
    If ControlGetHandle("", "", ControlGetFocus($Form1))=$hCombo1 Then
        MsgBox(0,'','$Combo1- в фокусе')
    Else
        MsgBox(0,'','$Combo1 - не в фокусе')
    EndIf
EndFunc

П.С. Я же не выхожу за рамки темы, "Как определить наличие фокуса на элементе" Combo ведь тоже элемент формы. В примере указал только Input, потому что думал, что решение будет работать и для комбо, ведь они оба возвращают ClassNameNN='Edit1'
 
Последнее редактирование:

Norm

Продвинутый
Сообщения
278
Репутация
74
Спасибо InnI за окончательное решения вопроса.
Теперь определяются все элементы.
Код:
#include <WindowsConstants.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WinAPI.au3>

HotKeySet("{F1}", "GetFocus")

Local $iFileMenu, $iFileItem, $hGui
Local $iHelpMenu, $iInfoItem, $iExit, $iRecentFilesMenu
Local $iViewMenu, $iStyleitem, $iBtnOK

$hGui = GUICreate("Элемент меню в GUI", 300, 500)

$iFileMenu = GUICtrlCreateMenu("&Файл")
$iFileItem = GUICtrlCreateMenuItem("Открыть", $iFileMenu)
GUICtrlSetState(-1, $GUI_DEFBUTTON)
$iHelpMenu = GUICtrlCreateMenu(GUICtrlGetHandle($iFileMenu))
GUICtrlCreateMenuItem("Сохранить", $iFileMenu)
GUICtrlSetState(-1, $GUI_DISABLE)
$iInfoItem = GUICtrlCreateMenuItem("Информация", $iHelpMenu)
$iExit = GUICtrlCreateMenuItem("Выход", $iFileMenu)
$iRecentFilesMenu = GUICtrlCreateMenu("Последние файлы", $iFileMenu, 1)
$iStyleitem = GUICtrlCreateMenuItem("Стиль GUI POPUP", $iViewMenu)
GUICtrlCreateMenuItem("", $iViewMenu)
$iRadioitem4 = GUICtrlCreateMenuItem("Радио4", $iViewMenu, -1, 1)

$iBtnOK = GUICtrlCreateButton("", 10, 20, 140, 25)
GUICtrlSetData(-1, "Button = "& GUICtrlGetHandle($iBtnOK))
GUICtrlSetState(-1, $GUI_FOCUS)

$Updown = GUICtrlCreateInput("", 180, 20, 100, 24)
GUICtrlCreateUpdown(-1)
GUICtrlCreateLabel(GUICtrlGetHandle($Updown), 190, 5, 100, 14)

$nCh1 = GUICtrlCreateCheckbox("", 10, 60, 120, 20)
GUICtrlSetData(-1, "ChBx = "& GUICtrlGetHandle($nCh1))

$Combo = GUICtrlCreateCombo("", 150, 60, 100, 23)
$hCombo = GUICtrlGetHandle($Combo)
GUICtrlSetData(-1, $hCombo &"|элемент2|элемент3|элемент4", $hCombo)
$date = GUICtrlCreateDate("1953/04/25", 10, 90, 185, 20)
GUICtrlCreateLabel(GUICtrlGetHandle($date), 200, 92, 185, 20)

$iEdit = GUICtrlCreateEdit("", 10, 120, 200, 40)
GUICtrlSetData(-1, "Edit = "& GUICtrlGetHandle($iEdit))

$Input1 = GUICtrlCreateInput("", 10, 170, 200, 20)
GUICtrlSetData(-1, "Input = "& GUICtrlGetHandle($Input1))

$iRadio1 = GUICtrlCreateRadio("", 10, 200, 130, 20)
GUICtrlSetData(-1, "Radio1 = "& GUICtrlGetHandle($iRadio1))
$iRadio2 = GUICtrlCreateRadio("", 10, 220, 130, 20)
GUICtrlSetData(-1, "Radio1 = "& GUICtrlGetHandle($iRadio2))

$treeview = GUICtrlCreateTreeView(150, 200, 100, 90)
$tree1 = GUICtrlCreateTreeViewItem("Тексты", $treeview)
GUICtrlSetData($tree1, GUICtrlGetHandle($treeview))
GUICtrlCreateTreeViewItem("текст1", $tree1)
GUICtrlCreateTreeViewItem("текст2", $tree1)
GUICtrlCreateTreeViewItem("текст3", $tree1)

$tab = GUICtrlCreateTab(10, 280, 200, 60)
$hInf = GUICtrlGetHandle($tab)
GUICtrlCreateTabItem("Путь")
GUICtrlSetImage(-1, "shell32.dll", -222, 0) ; иконка вкладки
GUICtrlCreateLabel($hInf, 20, 310, 185, 20)
GUICtrlCreateTabItem("Test")
GUICtrlCreateLabel($hInf, 20, 310, 185, 20)
GUICtrlCreateTabItem("")

$ListView = GUICtrlCreateListView("ListView Handle|кол2|кол3  ", 10, 350, 220, 120);,$LVS_SORTDESCENDING)
$hInf = GUICtrlGetHandle($ListView)
GUICtrlSetBkColor(-1, 0xFFFEEE) ; устанавливает цвет фона ListView
GUICtrlCreateListViewItem($hInf &"|кол22|кол23", $ListView)
GUICtrlCreateListViewItem($hInf &"|кол12|кол13", $ListView)

GUISetState()
MsgBox(0,Default,"Установите фокус на элемент и нажмите F1")
Do
Until GUIGetMsg() = $GUI_EVENT_CLOSE

Func GetFocus()
    Local $tInfo, $aInfo = _ControlGetFocusEx($hGui, 3)
   If Not @error Then
        MsgBox(0, GUICtrlGetHandle($aInfo[0]), _
        "ID = "& $aInfo[0] & @CRLF & _
        "Handle = "& $aInfo[1] & @CRLF & _
        "CLASSNN = "& $aInfo[2])
    EndIf

EndFunc

; Возвращает дескриптор, класс и Control-ID элемента имеющего фокус
Func _ControlGetFocusEx($hWnd = 0, _ ; Дескрипток окна
    $iRet = 0) ; Return: 0 => ID элемента; 1 дескриптор элемента; 2 класс элемента; 3 => массив со всей информацие
    If $hWnd = 0 Then
        $hWnd = WinGetHandle("[ACTIVE]")
    EndIf
    If Not $hWnd Then
        Return SetError(-1,0,0)
    EndIf
   Local $aRetArr[4] = [0,0,0], $hAncstr
    $aRetArr[2] = ControlGetFocus($hWnd) ; Klass
    $aRetArr[1] = ControlGetHandle($hWnd,"",$aRetArr[2]) ; Handle
    $hAncstr = _WinAPI_GetAncestor($aRetArr[1]) ; Handle Ancestor
    $aRetArr[0] = _WinAPI_GetDlgCtrlID(($hAncstr <> $hWnd) ? $hAncstr : $aRetArr[1]) ; GUI-ID
    If $aRetArr[1] = $hWnd Then
	  Return SetError(-2,0,0) ; No Focus
    EndIf
    Switch $iRet
        Case 3
            Return $aRetArr
        Case Else
            Return $aRetArr[$iRet]
    EndSwitch
EndFunc
 
Последнее редактирование:
Автор
P

pvnn

Осваивающий
Сообщения
305
Репутация
32
InnI
Спасибо! То что надо.
Тема решена.
 
Верх