Jump to content
Sign in to follow this  
binhnx

If condition check in a interruptible function. Is it safe?

Recommended Posts

Let start with some examples:

1. (As seen in another topic: '?do=embed' frameborder='0' data-embedContent>> ).

Script copied from that topic

Interrupt function can be any hotkey/event/adlib/callback.

If-check inside interrupted function/script 

; HotKeySet, or any function that can cause script interrupt
HotKeySet("{Delete}", "RemoveSelectedControl")

;...
Dim $InfoAboutControls[4096]
Global $HandleForCurrentControl
;...


While 1
    $msg = GuiGetMsg()
  ;....
    
  ;---Code to process moving a control (drag-n-drop)---
    ; If check in MAIN LOOP (interruptible function).
    If $HandleForCurrentControl > 0 Then;Make sure we have a valid control handle
  ; ***** oops user pressed Delete key and we get pre-empted
  ; ***** user removed the selected control.
  ; ***** Returning from the RemoveSelectedControl function and resuming here:
        GuiCtrlSetPos($InfoAboutControls[$HandleForCurrentControl], $newLeftPosition, $newTopPosition)
    EndIf
WEnd

Func RemoveSelectedControl()
    $HandleForCurrentControl = -1
EndFunc

2. If-check inside interrupt function

Hotkey only.

Flag is set right after if check.

It's possible or not this function print twice or more?

HotKeySet("{Delete}", "_TestHotkey")

Func _TestHotkey()
  Static $bFlag = True
  If ($bFlag) Then 
     ; ***** Right here, user pressed Delete key
     ; ***** bFlag is currently not set
     ; ***** And the script will execute this function twice or more times, instead of just once
     $bFlag = False
     ConsoleWrite("This should be printed only ONCE")
  EndIf
EndFunc

3. Same as 2, but with global flag

The question is: can I rely on if-checking with a flag, to ensure that my script doesn't do any strange things, as describe in the above examples?

Edited by binhnx

99 little bugs in the code

99 little bugs!

Take one down, patch it around

117 little bugs in the code!

Share this post


Link to post
Share on other sites

Not a specific script. That is only a general problem, and I ask for a general answer.

Indeed, 3 above examples is details as much as it should. Any line added to that is for nothing but make the topic unfocused.

To provide more details, 

  • Details about example 1 can be read in the original topic linked.
  • For example 2 and 3: As you see, my script only allow _TestHotkey() function to execute exactly once. But since AutoIt script can be interrupted and reentrant, it's probably that function be executed twice or more, if user presses "Delete" key right after the if-check line is executed. So, I need an assurance that AutoIt "had some mechanism" to play with it, like a Critical Section as describe at the linked topic.

99 little bugs in the code

99 little bugs!

Take one down, patch it around

117 little bugs in the code!

Share this post


Link to post
Share on other sites

There is almost no possibility of that function running twice if you clear the hotkey/adlib function used to call it as the very first line of the function.

HotKeySet("{Delete}", "_TestHotkey")

Func _TestHotkey()
  HotKeySet("{Delete}")
  Static $bFlag = True
  If ($bFlag) Then 
     ; ***** Right here, user pressed Delete key
     ; ***** bFlag is currently not set
     ; ***** And the script will execute this function twice or more times, instead of just once
     $bFlag = False
     ConsoleWrite("This should be printed only ONCE")
  EndIf
EndFunc

If you wanted the HotKey to be active again, you'd need to set it again somewhere else in the script. AdlibUnRegister would work the same way.


If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Share this post


Link to post
Share on other sites

Or:

$bFlag = True
HotKeySet("{Delete}", "_TestHotkey")

Func _TestHotkey()
  If $bFlag Then 
     ; ***** Right here, user pressed Delete key
     ; ***** bFlag is currently not set
     ; ***** And the script will execute this function twice or more times, instead of just once
     $bFlag = False
     ConsoleWrite("This should be printed only ONCE")
  EndIf
EndFunc

While True
WEnd
Edited by jdelaney

IEbyXPATH-Grab IE DOM objects by XPATH IEscriptRecord-Makings of an IE script recorder ExcelFromXML-Create Excel docs without excel installed GetAllWindowControls-Output all control data on a given window.

Share this post


Link to post
Share on other sites

@BrewmanNH: yeah, in your case, if Delete is pressed right at the function begining, before the HotKeySet line, so what will happen?

In general, it also very very low probability, but i need to an exactly zero. 

Indeed, with Hotkey, if a line is the smallest element in AutoIt, so interrupt a line never can occur, so another trick will be better:

Func _TestHotKey()
 Static $nCounter = 0
 $nCounter += 1
 If ($nCounter = 1) Then
  ;Do everything you want
 EndIf
 $nCounter -= 1
EndFunc

It guarantee that the function execute exactly once (at the same time). But this method cannot be used with event or adlib since all that is queued, not interruped & reentrant.

@jdelaney: It's exactly my example 3. It's still unsafe at all, unless a dev state that it's safe!

A side note: The set flag statement is right after the check statement. I wonder AutoIt has some guard around it, or it's still simply a race-condition problem.

Edited by binhnx

99 little bugs in the code

99 little bugs!

Take one down, patch it around

117 little bugs in the code!

Share this post


Link to post
Share on other sites

There's probably a .000000000000000000000000001% chance that someone could hit the same key twice in the time it takes to get to that line. There's no such thing as exactly zero in computers, you are NEVER going to achieve that, especially in an interpreted language.


If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Share this post


Link to post
Share on other sites

@BrewmanNH.

No, as seen in the linked topic: '?do=embed' frameborder='0' data-embedContent>>

If a Critical Section (or any other guards) is implemented, it should be exactly zero!

The linked topic is provide a little information so I do not know it is implemented or not, so I open this topic to ask.

A side note: Computing is all about zero and one, isn't it?


99 little bugs in the code

99 little bugs!

Take one down, patch it around

117 little bugs in the code!

Share this post


Link to post
Share on other sites

We're talking about timing, not numbers. Also, if you had read the first response to that nearly 10 year old thread, the answer given is exactly what I proposed.


If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Share this post


Link to post
Share on other sites

Yeah, just kidding :)

I've read, and notice that, but after search along the forum, no other topic describe that problem, so I haven't know about its state yet.

In computing, many method is implemented to ensure that everything is done right. In a general programming language, also count interpreted language, such as Python or PHP also implemented that, using a lock before the check and the problem solved.

Is AutoIt (internally) did that?

Edit: Maybe I mis-understood what the Overlord said? Did he said that the guard function is totally imlemented? Or totally ignored? Or he said that the guard function is implemented around the disable Hotkey/Adlib/OnEvent function? 

Edited by binhnx

99 little bugs in the code

99 little bugs!

Take one down, patch it around

117 little bugs in the code!

Share this post


Link to post
Share on other sites

There is no guard function, you'd have to program that yourself, and it's all about disabling the hotkey or adlib as soon as you enter the function. Either by calling another function to clear it, or by implementing it inside the function being called. You're worrying over less than nothing in this thread, the function won't be called twice because you can't press the hotkey that fast, it's as close to zero time as is possible on a computer and using an interpreted language. If you need something quicker than almost instantaneous, you need to use another language.


If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Share this post


Link to post
Share on other sites

Thank you for your patience, but it seems not much logic since the OP of the linked topic can disable Adlib/Hotkey/OnEvent right before check statement and re-enable it after go out of work section, without using CriticalSection guard, but still ensure script works right.

And, with the behavior of AutoIt when processing Event/HotKey/Adlib, using CriticalSection inside a script is a bad idea, because it:

  • Have no effect when using inside Event/Adlib function, since these kind result in a queued function call, so next EnterCriticalSection always called after last LeaveCriticalSection is called => no effect at all
  • Resulted in dead-lock when using with Hotkey, think about Hotkey is pressed right after called to EnterCriticalSection, and it resulted in wait for a not-released CriticalSection, also, to release it, the function should be returned from the later Hotkey function, but it's stuck since the later one is stuck in EnterCriticalSection call. Using multipleCriticalSection (using local variable so we have one with each called function) is out of concept because it cannot guarantee anything if we use it like that.
  • Use inside a normal function/mail script: has not much logic, since a normal disable function will solve the problem.

Furthermore, writing using a different language is not an option. You may think I mad, it's OK. Maybe I somewhat like AutoIt and I want to write in AutoIt than using a different language.

But this time, the reason makes me stick with AutoIt is I'm writing a program that use AutoIt as underlying rendering program (Yes, a form designer, AutoIt lacks a good designer. First, I need a native renderer, instead of using another language to do it, as Koda used Delphi. This will provide a better experiencement to user, since the designer form is exactly visually identified with the result form. Second, The FormBuilder Beta found in the forum - which is written entirely in AutoIt - is elegance, but too much crashable bug. So I decided to write a new one)

Edited by binhnx

99 little bugs in the code

99 little bugs!

Take one down, patch it around

117 little bugs in the code!

Share this post


Link to post
Share on other sites

 

And, with the behavior of AutoIt when processing Event/HotKey/Adlib, using CriticalSection inside a script is a bad idea, because it:

How do you know that? Have you ever run into a problem with using what I posted? Not some theoretical "what-if" scenario, I mean real world examples of where a hotkey can be pressed quicker than it takes to disable it in the function that's called by it. Have you ever encountered a deadlock condition from using a hotkey in the way I demonstrated? My guess would be no to all questions, because the probability of it happening is extremely small.

If you think you can show a way to do it, please post a script that demonstrates it.


If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Share this post


Link to post
Share on other sites

Have you ever seen any real-world-100%-will-occur-race-condition?

The answer is 'absolutely NO', because this is very very rare to occur, but every one can ensure that, at a random (not-so) beautiful day, your application will crash stupidly because a stupid bug. It's not acceptable with a programmer, but may be acceptable with a scripter/ automater. 

It's not speed problem. It's timing problem.

It's not about how many small. It's YES or NO


99 little bugs in the code

99 little bugs!

Take one down, patch it around

117 little bugs in the code!

Share this post


Link to post
Share on other sites

Maybe I asked at wrong forum region.

Anyone may have a look at 

and give me some advice? Thank you very much!


99 little bugs in the code

99 little bugs!

Take one down, patch it around

117 little bugs in the code!

Share this post


Link to post
Share on other sites

I think, I posted in the wrong thread. all I need is a answer by a developer, who can easily say that yes or no. I'm tired of explaining anything about my question.

Should I delete the thread and re-post?

Edited by binhnx

99 little bugs in the code

99 little bugs!

Take one down, patch it around

117 little bugs in the code!

Share this post


Link to post
Share on other sites

Not if you want a long and healthy stay on the forum :)

If people are still asking for clarification, maybe you should take that as a clue that you're not explaining yourself very well.


"Profanity is the last vestige of the feeble mind. For the man who cannot express himself forcibly through intellect must do so through shock and awe" - Spencer W. Kimball

How to get your question answered on this forum!

Share this post


Link to post
Share on other sites

So, honestly, may you spend some time to read my post and give me some point, what do I need to answer, to get the answer for me?

Edited by binhnx

99 little bugs in the code

99 little bugs!

Take one down, patch it around

117 little bugs in the code!

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By Bhooshan
      I need to mute an ongoing call on Microsoft teams without activating the window. Teams allows us to mute using shortcut key Ctrl+Shift+m but only when the window is active.
      # Used set option as ongoing call can be with any person which leads to change in Title Name.
      AutoItSetOption ( "WinTitleMatchMode", 2 ) 
      # I am not clear with the control ID which will be good to use here and also the key combination of ^M       
      ControlSend ( "Microsoft Teams", "", "[CLASS:Intermediate D3D Window; INSTANCE:1]", "{ctrl down}")
       
      Can anyone help...!!! 
       

    • By MrCreatoR
      This UDF allows to set an events handler for Mouse device.
       
      The beginning...
      I searched for a way to disable the Mouse Primary click, and be able to call some function when the click event is received...
      Big thanks to amel27 for this one, i only organized the whole stuff to UDF style.
       
      Example:
      #include <GUIConstantsEx.au3> #include "MouseOnEvent.au3" HotKeySet("{ESC}", "_Quit") _Example_Intro() _Example_Limit_Window() Func _Example_Intro() MsgBox(64, "Attention!", "Let's set event function for mouse wheel *scrolling* up and down", 5) ;Set event function for mouse wheel *scrolling* up/down and primary button *down* action (call our function when the events recieved) _MouseSetOnEvent($MOUSE_WHEELSCROLLDOWN_EVENT, "_MouseWheel_Events") _MouseSetOnEvent($MOUSE_WHEELSCROLLUP_EVENT, "_MouseWheel_Events") _MouseSetOnEvent($MOUSE_PRIMARYDOWN_EVENT, "_MousePrimaryDown_Event") Sleep(3000) ;UnSet the events _MouseSetOnEvent($MOUSE_WHEELSCROLLDOWN_EVENT) _MouseSetOnEvent($MOUSE_WHEELSCROLLUP_EVENT) _MouseSetOnEvent($MOUSE_PRIMARYDOWN_EVENT) ToolTip("") MsgBox(64, "Attention!", "Now let's disable Secondary mouse button up action, and call our event function.", 5) _MouseSetOnEvent($MOUSE_SECONDARYUP_EVENT, "_MouseSecondaryUp_Event", 0, 1) Sleep(5000) _MouseSetOnEvent($MOUSE_SECONDARYUP_EVENT) ToolTip("") EndFunc Func _Example_Limit_Window() Local $hGUI = GUICreate("MouseOnEvent UDF Example - Restrict events on specific window") GUICtrlCreateLabel("Try to click on that specific GUI window", 40, 40, 300, 30) GUICtrlSetFont(-1, 12, 800) GUICtrlCreateLabel("Press <ESC> to exit", 10, 10) GUISetState() _MouseSetOnEvent($MOUSE_PRIMARYDOWN_EVENT, "_MousePrimaryDown_Event", $hGUI) ;A little(?) bugie when you mix different events :( ;_MouseSetOnEvent($MOUSE_SECONDARYUP_EVENT, "_MouseSecondaryUp_Event", $hGUI) While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop Case $GUI_EVENT_PRIMARYDOWN MsgBox(0, "", "Should not be shown ;)") EndSwitch WEnd _MouseSetOnEvent($MOUSE_PRIMARYDOWN_EVENT) ;_MouseSetOnEvent($MOUSE_SECONDARYUP_EVENT) EndFunc Func _MouseWheel_Events($iEvent) Switch $iEvent Case $MOUSE_WHEELSCROLLDOWN_EVENT ToolTip("Wheel Mouse Button (scrolling) DOWN Blocked") Case $MOUSE_WHEELSCROLLUP_EVENT ToolTip("Wheel Mouse Button (scrolling) UP Blocked") EndSwitch Return $MOE_BLOCKDEFPROC ;Block EndFunc Func _MousePrimaryDown_Event() ToolTip("Primary Mouse Button Down Blocked") Return $MOE_BLOCKDEFPROC ;Block EndFunc Func _MouseSecondaryUp_Event() ToolTip("Secondary Mouse Button Up Blocked") EndFunc Func _Quit() Exit EndFunc  
      Available Events Constants:
       
      ------------------------------------------
      CHANGELOG:
      Download:
      Attached:     MouseOnEvent_2.4.zip
      Old version:
      MouseOnEvent.zip - v2.3
      MouseOnEvent_2.1.zip
      MouseOnEvent_2.0.zip
      MouseOnEvent_UDF_1.9.zip
      MouseSetOnEvent_UDF_1.8.zip
      MouseSetOnEvent_UDF_1.7.zip
      MouseSetOnEvent_UDF_1.6.zip
      MouseSetOnEvent_UDF_1.5.zip
      MouseSetOnEvent_UDF_1.4.zip
      MouseSetOnEvent_UDF_1.3.zip
      Previous downloads: 146 + 200 + 804
      MouseOnEvent.zip
      MouseOnEvent.zip
    • By Blois
      Hi Guis,
       
      I need to create keyboard shortcut to navigate the tabs and activate them, but I could not use the code below:
      #include <TabConstants.au3> #include <WindowsConstants.au3> #include <GuiTab.au3> #include <GUIConstantsEx.au3> HotKeySet("^{TAB}", "_TabRight") HotKeySet("^+{TAB}", "_TabLeft") $gui = GUICreate("test",450, 300) $Tab1 = GUICtrlCreateTab(20, 24, 425, 201) $TabSheet1 = GUICtrlCreateTabItem("Tabsheet 1") $lbContagemGrupos2 = GUICtrlCreateLabel("aaaa", 50, 50) GUICtrlSetColor(-1, 0x0000FF) GUICtrlCreateTabItem("") $TabSheet2 = GUICtrlCreateTabItem(" ") $TabSheet3 = GUICtrlCreateTabItem(" ") GUISetState() While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop EndSwitch WEnd Func _TabRight() $CurPos = _GUICtrlTab_GetCurSel($Tab1) _GUICtrlTab_SetCurSel($Tab1, $CurPos + 1) $tab = "$TabSheet" & $CurPos GUICtrlSetState($TabSheet1 + $CurPos, $GUI_SHOW) Return EndFunc Func _TabLeft() $CurPos = _GUICtrlTab_GetCurSel($Tab1) _GUICtrlTab_SetCurSel($Tab1, $CurPos - 1) $tab = "$TabSheet" & $CurPos GUICtrlSetState($TabSheet1 + $CurPos, $GUI_SHOW) Return EndFunc Exit  
      can you help me?
    • By guner7
      Hi everyone,
      I would like to share a simple snippet where I use for my hotkey script.
      I was searching for a solution whereby pressing a same key, I could have different outcome according to the way the key is being pressed.
      1) Double tap/press fast (like double click the mouse) - outcome A
      2) Long press or HOLD for awhile (2-4 sec) - outcome B
      #Include <Timers.au3> Global $interval_timer, $counter HotKeySet("{F10}", "_terminate") While 1 Sleep(10) WEnd Func _terminate() Local $itv_timer $itv_timer = _Timer_Diff($interval_timer) $interval_timer = _Timer_Init() ;ConsoleWrite($itv_timer & @CRLF) ;to review the timer difference so I can decide the range to capture double tap sequence If $itv_timer > 100 And $itv_timer < 250 Then $counter = 0 $interval_timer = _Timer_Init() MsgBox("","","double tap detected") Elseif $counter >= 25 Then $counter = 0 $interval_timer = _Timer_Init() MsgBox("","","long press detected") ElseIf $itv_timer < 50 Then $counter = $counter + 1 ConsoleWrite($counter & @CRLF) Else $counter = 0 EndIf EndFunc The trick here is to collect and use the frequency of the hotkey is called, and the time difference between each time the hotkey is being called.
      My coding style is not efficient and can be such a mess most of the time, any suggestion or better coding are welcome.
      I hope you find this one helpful.
    • By nacerbaaziz
      Detect if the focus item is a button or check box
      Hello everyone.
      My dears I have a problem
      When I try to use
      ControlGetFocus function
      it  doesn't recognize the check  boxes.
      The result is that the selector is a button
      Although the specified is a check box
      but I want a way to identify the check boxes.
      Because I want to make a tool that helps screen readers users
      I hope you have the solution.
      Thank you in advance.
       
×
×
  • Create New...