Jump to content

Recommended Posts

Posted (edited)

question about _WinAPI_CreateWindowEx
good morning
welcome autoit team
please i need your help
i've searched a lot about how to use the _WinAPI_CreateWindowEx
finally i found an example
but i found some problem i hope you can help me
firstly, i want to set the controls focussable with the keyboard input
i already used the ws_tabStop but it did not work with me.

secondly, i want to set some access keys linked with the window
such as control+o enable the open button and control+f4 exit the app
note: i need a local access keys and not a global hotkeys
such as GUISetAccelerators

finaly, before i will put the code here i must clarify a few things.
1. you will ask me why you don't use the GUICreate function
here i'll tell you that it as dialog and It is a little heavy in motion with screen readers.
the screen readers for blind has some function that work with dialogs and others work with full windows style
2. you will ask me why you didn't search the net for that?
i will tell you that all examples that i found in the internet with pdfs and Picture books.
i found some examples in microsoft but it with cpp.

ok here is the code
i hope you can help me to do what i want
thank you in advance
 

; Small AutoIt Application that uses Windows API
; Written by Yuraj
#NoTrayIcon
#include <_RegisterClassEx.au3>
#include <WinAPI.au3>

#include <WindowsConstants.au3>
#include <ButtonConstants.au3>
#include <EditConstants.au3>
#include <FontConstants.au3>

AutoItSetOption("MustDeclareVars", 1)

; Window definitions
Const $WinWidth = 370
Const $WinHeight = 350
Const $WinXPos = (@DesktopWidth / 2) - ($WinWidth / 2)
Const $WinYPos = (@DesktopHeight / 2) - ($WinHeight / 2)
Const $WinTitle = "Win32 Application - Text reader"
Const $WinClass = "mainapp"
Const $WinIcon = _WinAPI_LoadIcon(_WinAPI_GetModuleHandle("shell32.dll"), 13)
; Windows handles
Global $hwnd, $edit1, $btn1, $btn2
; Fonts
Global $fnt1

; Register class, Create the window
Local $retVal = __WinAPI_RegisterClassEx($WinClass, "WindowCallback", $WinIcon, 0, _WinAPI_GetSysColor($COLOR_BTNFACE), BitOR($CS_DEFAULTSTYLE, $CS_DROPSHADOW)) ;
If $retVal == 0 Then ; If registerclass fails
MsgBox(16, "Error", "Error while registering window class!")
Exit
EndIf

; Create windows/controls
$hwnd = _WinAPI_CreateWindowEx($WS_EX_STATICEDGE, $WinClass, $WinTitle, BitOR($WS_OVERLAPPED,$WS_SYSMENU, $WS_MINIMIZEBOX, $WS_GROUP, $WS_DLGFRAME), $WinXPos, $WinYPos, $WinWidth, $WinHeight, 0)
$btn1 = _WinAPI_CreateWindowEx(0, "button", "Open file ...", BitOR($WS_VISIBLE, $WS_CHILD, $WS_TABSTOP, $WS_CLIPCHILDREN), 25, 270, 100, 30,$hwnd)
$btn2 = _WinAPI_CreateWindowEx(0, "Button", "Exit", BitOR($WS_VISIBLE, $WS_CHILD, $WS_TABSTOP, $WS_CLIPCHILDREN), 235, 270, 100, 30, $hwnd)
$edit1 = _WinAPI_CreateWindowEx(0, "edit", "text", BitOR($WS_VISIBLE, $WS_CHILD, $WS_VSCROLL, $ES_AUTOVSCROLL, $es_readOnly, $WS_TABSTOP), 5, 5, $WinWidth - 15, $WinHeight - 100, $hwnd)

; Set controls identifiers
_WinAPI_SetWindowLong($btn1,$GWL_ID,150)
_WinAPI_SetWindowLong($btn2,$GWL_ID,160)

; Set (controls) fonts
$fnt1 = _CreateFont("MS Sans Serif", 15)
_WinAPI_SetFont($btn1, $fnt1)
_WinAPI_SetFont($btn2, $fnt1)
_WinAPI_SetFont($edit1, $fnt1)

; Set focus to edit
_WinAPI_SetFocus($edit1)

; Show window
_WinAPI_ShowWindow($hwnd)
_WinAPI_UpdateWindow($hwnd)

; Main loop that keep application opened
While 1
Sleep(100)
WEnd

;=================================================================;
; WINDOW CALLBACK ...
;=================================================================;

Func WindowCallback($_hwnd, $iMsg, $wParam, $lParam)
Local $iNC, $iID
Switch $iMsg
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Case $WM_CLOSE
; Show message on closing
If MsgBox(48 + 4, $WinTitle, "Do you want really exit?", 0, $hwnd) <> 6 Then Return 0
; Call destructor and then exit main thread
FinalizeApp()
Exit
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Case $WM_COMMAND
$iNC = _WinAPI_HiWord($wParam)
$iID = _WinAPI_LoWord($lParam)

Switch $iNC
Case $BN_CLICKED ; When is control clicked
Switch _WinAPI_GetDlgCtrlID($iID)
Case _WinAPI_GetDlgCtrlID($btn1)
BtnOpenFileClick()
Case _WinAPI_GetDlgCtrlID($btn2)
BtnExitClick()
EndSwitch
EndSwitch
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
EndSwitch

Return _WinAPI_DefWindowProc($_hwnd, $iMsg, $wParam, $lParam)
EndFunc   ;==>WindowCallback

Func FinalizeApp()
_WinAPI_DeleteObject($fnt1)
_WinAPI_DestroyWindow($hwnd)
__WinAPI_UnregisterClass($WinClass)
EndFunc   ;==>FinalizeApp

Func _CreateFont($fontName, $height = 16, $style = $FW_NORMAL, $italic = False, $underline = False, $strikeout = False)
Local $hFont = _WinAPI_CreateFont($height, 0, 0, 0, $style, $italic, $underline, $strikeout, $DEFAULT_CHARSET, _
$OUT_DEFAULT_PRECIS, $CLIP_DEFAULT_PRECIS, $DEFAULT_QUALITY, $DEFAULT_PITCH, $fontName)
Return $hFont
EndFunc   ;==>_CreateFont

;=================================================================;
; WINDOW EVENTS
;=================================================================;

Func BtnOpenFileClick()
Local $ret = _WinAPI_GetOpenFileName("", "Text files (*.txt)|All files (*.*)", ".", "", "", 1, 0, 0, $hwnd)
If ($ret[0] > 0) Then
Local $path = $ret[1] & "\" & $ret[2]

Local $file = _WinAPI_CreateFile($path, 2, 2)
Local $buf = DllStructCreate("byte[" & _WinAPI_GetFileSizeEx($file) & "]")
Local $i = 0

_WinAPI_ReadFile($file, DllStructGetPtr($buf), _WinAPI_GetFileSizeEx($file), $i)

; Close file handle
_WinAPI_CloseHandle($file)
_WinAPI_SetWindowText($edit1, BinaryToString(DllStructGetData($buf, 1)))
EndIf
EndFunc   ;==>BtnOpenFileClick

Func BtnExitClick()
FinalizeApp()
Exit
EndFunc   ;==>BtnExitClick

 

_RegisterClassEx.au3

Edited by nacerbaaziz
uploaded the _RegisterClassEx.au3

Share this post


Link to post
Share on other sites

Unless someone tells me wrong, I do not believe you can do it. It is possible in other languages, but not in AutoIt.  You would need to implement a loop with win32 APIs GetMessage, TranslateMessage, DispatchMessage (look MSDN for explaination).  Problem is that it will interfere with AutoIt internals and it will not work properly.  In the example you found, you are able steel the WindowProc and it will work correctly.  That is as far as you can go.

But, you could simulate the {TAB} key using _IsPressed or with a hook in the fields that you want to tab in (this later solution may also cause interference as it adds another level of callback).  Good luck with it.  If you find a solution, please report back here.  It would be very nice to see it.

ps.  I would highly recommend you using AutoIt GUI as I cannot see a true real reason why not.

Share this post


Link to post
Share on other sites
On 4/12/2020 at 1:03 PM, Nine said:

Unless someone tells me wrong, I do not believe you can do it. It is possible in other languages, but not in AutoIt.  You would need to implement a loop with win32 APIs GetMessage, TranslateMessage, DispatchMessage (look MSDN for explaination).  Problem is that it will interfere with AutoIt internals and it will not work properly.  In the example you found, you are able steel the WindowProc and it will work correctly.  That is as far as you can go.

But, you could simulate the {TAB} key using _IsPressed or with a hook in the fields that you want to tab in (this later solution may also cause interference as it adds another level of callback).  Good luck with it.  If you find a solution, please report back here.  It would be very nice to see it.

ps.  I would highly recommend you using AutoIt GUI as I cannot see a true real reason why not.

you mean that i must stop searching in autoit and try to use the GUI with an other language? i hope that the autoit team can give us the ability to do that in autoit because it is a buetifull programing language

Share this post


Link to post
Share on other sites

I'm absolutely sure that Nine is wrong on this one. This can be implemented in AutoIt code. Of course, you cannot use any of the internal functions in the GUI Management section of the help file. But you can use all the UDF code based on Windows API functions in the GUI Reference section. You can generally use all code based on Windows API functions.

Read this Microsoft documentation on using accelerator keys and implement CreateAcceleratorTableW as a _WinAPI_ function.

If you need advanced functionality that is normally coded through GUIRegisterMsg() then use GUIRegisterMsg20() instead.

Share this post


Link to post
Share on other sites

Examples here. About the questions in the first post. First of all, I want to state that it is possible to code what you want in AutoIt. However, you should not start with such a low level example as shown in your code box. It's too cumbersome and time consuming.

My example 0 is an almost direct copy of the example of _WinAPI_RegisterClassEx() in the help file, which also uses _WinAPI_CreateWindowEx() to create a GUI window. I have placed the code in a function so you can use local variables.

Example 1 shows how to code a message loop to handle keyboard accelerators.

In example 2, a listview control is created in the window with _GUICtrlListView_Create(). Do not use _WinAPI_CreateWindowEx() to create controls. Use the functions in the GUI Reference section of the help file. Then the Tab key probably works immediately.

Example 3 is a more advanced example for implementing subclassing. You probably won't need that.

Share this post


Link to post
Share on other sites

Sorry to say but your approach has not solved OP problem.  You still cannot provide a script where one could navigate from one control to another with the TAB key.  What you have done reflects pretty much the wall I was facing...Thanks for the effort though.

Share this post


Link to post
Share on other sites

According to the documentation for WS_TABSTOP, the IsDialogMessage() function must be included in the message loop to identify a keystroke as a dialog box key. Example here.

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

  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By nacerbaaziz
      hello autoit team
      please i need your help today
      am trying to make the list of features in list view and control it
      am using the dism command line to read output
      i've made the code
      but i found some problems
      what i need is the list of features in 2d array
      $array[$n][0]= name $array[$i][1] = state
      when i tested the code
      it give me some results that i don't need to it e.g
      ------ ------  | --------
      or
      name       | state
      i need just the list of features and there state
      please help me to do that
      here is my example
      #RequireAdmin #NoTrayIcon #include <AutoItConstants.au3> Wow64EnableWow64FsRedirection(false) _Windows_Get_Features() func _Windows_Get_Features() local $a_FeaturesArray[1][2] $a_FeaturesArray[0][0] local $i_Dism_Run = Run("DISM /online /english /get-features /format:table", "", @sw_hide, BitOR($STDERR_CHILD, $STDOUT_CHILD)) local $s_OutputDism = "", $a_OutPutDism While 1 $s_OutputDism = StdoutRead($i_Dism_Run) If @error Then exitLoop if ($s_OutputDism = "") or (StringRegExp($s_OutputDism, "^((\-){1,})?(?:\s)\|?(?:\s)((\-){1,})$", 0) = 1) then ContinueLoop if (StringRegExp($s_OutputDism, "((([\s\d\-\+\_\,]{1})\|([\s\d\-\+\_\,]{1})){1,})", 0) = 1) then $a_OutPutDism = StringSplit($s_OutputDism, @lf) for $i = 1 to $a_OutPutDism[0] if msgBox(1, $i, $a_OutPutDism[$i]) = 1 then exitLoop next endIf Wend endFunc func Wow64EnableWow64FsRedirection($b_Enabled) local $h_OpenFS = DLLOpen("kernel32.dll") local $Return = DllCall($h_OpenFS, "boolean", "Wow64EnableWow64FsRedirection", "boolean", $b_Enabled) if @error then DLLClose($h_OpenFS) Return SetError(@error, @extended, -1) else DLLClose($h_OpenFS) Return $Return[0] endIf endFunc  
    • By kingjacob90
      Hi
      So I am trying to click the green button, this button is not always in the same place. So fare I am trying to click it by finding the color but there is also something else with the same color on the screen (circled in yellow) that is causing issues. Is there a way to use the Title and Class of the window (can't be just the window as there are more than one with the same name).
      How does AutoIt Info get this information?

    • By nacerbaaziz
      screen curtain on autoit windows 8 +
      hello autoit forum please i've a question
      on windows 8 and more the micro soft added the Magnification options
      this future can help the blind by turn the screen black to To relax the eyes.
      i searched allot in autoit but i couldn't find any way to do it
      and after then i found an python addon can do that, it's an addon open source to screen reader NVDA
      i hope you can help me to convert it to an autoit script
      note i couldn't do that because I'm very fresh man in dealing with dll files
      inadition to am 0 on python
      please if any one can help me.
      this is the NVDA Python Addon it very small, i need just one future that turn the screen black
      thx in advance
       
      screenCurtain.rarr
       
    • By Saravanan2213
      Hi everyone,
      i just need your help. i have script for cleaning browsing history and other unwanted file but the problem is i don't want to see the GUI i have attached below. It should not show anything on the screen. is it possible to do it in autoit. thanks in advance.
       
      So for i have tried flag
      Run("rundll32.exe InetCpl.cpl,ClearMyTracksByProcess 255", "", @SW_HIDE)
      @SW_DISABLE
       
      Looking forward your help.........

    • By Kelvin44
      WiFi Disconnects Automatically Windows 10 / 8 / 7 Laptop. This video guide very help to me
×
×
  • Create New...