Jump to content

How to Add a Control to an Existing 3rd Party Window


Zohar
 Share

Recommended Posts

  • Moderators

Add it as a child.

I believe there was examples with something called anygui years and years ago if it's still around.

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

  • Moderators
1.  Create a GUI that will contain the button
2.  Make sure that the GUI is created with $WS_CHILD in the 6th param
3.  Make sure in the 8th param that you set the handle to the window you want to put the button on
4.  Create your button to the GUI you created in autoit
5.  GUISetState()
 
This is just a guess, but I believe that should work.

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

  • Moderators

If I were going to do this, I'd probably approach it like this:

#include-once
#include <WindowsConstants.au3>
#include <WinAPI.au3>

_Example() ; using desktop window

Func _Example()

    Local Enum $iCtrlID, $iGUIHwnd
    Local $aGUI = _anyGUI_CreateContainer(0, 100, 30, (@DesktopWidth - 100) / 2, (@DesktopHeight - 30) / 2)
    Local $aButton = _anyGUI_CreateButton($aGUI[$iGUIHwnd], "Some Text", 0, 0, 100, 30)
    GUISetState(@SW_SHOW, $aGUI[$iGUIHwnd])
    
    While 1
        Switch GUIGetMsg()
            Case $aButton[$iCtrlID]
                MsgBox(64, "OK", "Time to exit, buh bye!")
                GUIDelete($aGUI[$iGUIHwnd])
                Exit
        EndSwitch
    WEnd
EndFunc

Func _anyGUI_CreateContainer($hParent, $iWidth = Default, $iHeight = Default, $iXPos = Default, _
        $iYPos = Default, $iStyle = $WS_CHILD, $iExStyle = Default, $sGUIText = "_AU3AnyGUIContainer_")

    $iXPos = ($iXPos = Default Or $iXPos = -1) ? Default : $iXPos
    $iYPos = ($iYPos = Default Or $iYPos = -1) ? Default : $iYPos
    $iWidth = ($iWidth = Default Or $iWidth = -1) ? -1 : $iWidth
    $iHeight = ($iHeight = Default Or $iHeight = -1) ? -1 : $iHeight
    $iStyle = ($iStyle = Default Or $iStyle = -1) ? $WS_CHILD : $iStyle
    $iExStyle = ($iExStyle = Default Or $iExStyle = -1) ? -1 : $iExStyle

    Local $aList
    If $sGUIText = "_AU3AnyGUIContainer_" Then
        $aList = WinList($sGUIText)
        $sGUIText &= UBound($aList)
    EndIf

    If Not BitAND($iStyle, $WS_CHILD) Then
        $iStyle = BitOR($iStyle, $WS_CHILD)
    EndIf

    If Not IsHWnd($hParent) Then
        $hParent = (IsArray($hParent)) ? $hParent[1] : WinGetHandle($hParent)
        If Not IsHWnd($hParent) Then ; assume desktop
            $hParent = _WinAPI_GetDesktopWindow()
        EndIf
    EndIf

    Local $hGUI = GUICreate($sGUIText, $iWidth, $iHeight, $iXPos, $iYPos, $iStyle, $iExStyle, $hParent)

    ; return array
    ; [0] = new windows dlgid
    ; [1] = handle from gui within autoit and now within the Container window

    Local $aRet[] = [_WinAPI_GetDlgCtrlID($hGUI), $hGUI]

    Return $aRet
EndFunc

Func _anyGUI_CreateButton($vContainerGUI, $sButtonText, $iXPos, $iYPos, _
        $iWidth = Default, $iHeight = Default, $iStyle = Default, $iExStyle = Default)

    $iWidth = ($iWidth = Default Or $iWidth = -1) ? Default : $iWidth
    $iHeight = ($iHeight = Default Or $iHeight = -1) ? Default : $iHeight
    $iStyle = ($iStyle = Default Or $iStyle = -1) ? Default : $iStyle
    $iExStyle = ($iExStyle = Default Or $iExStyle = -1) ? Default : $iExStyle

    If Not IsHWnd($vContainerGUI) Then
        $vContainerGUI = (IsArray($vContainerGUI)) ? $vContainerGUI[1]: WinGetHandle($vContainerGUI)
        If Not IsHWnd($vContainerGUI) Then
            Return SetError(1, 0, 0)
        EndIf
    EndIf

    Local $iButton = GUICtrlCreateButton($sButtonText, $iXPos, $iYPos, _
        $iWidth, $iHeight, $iStyle, $iExStyle)

    ; return an array
    ; [0] = id
    ; [1] = handle
    Local $aRet[] = [$iButton, GUICtrlGetHandle($iButton)]
    Return $aRet
EndFunc 

I'm unsure if this is how anyGUI worked, but I imagine it was something similar (or at least I hope it was).

Edit:

The control id is not returning from the GUI handle.  Not sure if it's limited to desktop window.

Edited by SmOke_N

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

@Zohar: It's so simple with 1 line of script

_WinAPI_SetParent($hWndButton, $hWndTarget)

A side note: Any attempt to create/attach a control/child gui to another application's window(s) (means cross-process and/or cross-thread) is evil. Don't do something strange or you will crash/hang both your apps and the target apps.

99 little bugs in the code

99 little bugs!

Take one down, patch it around

117 little bugs in the code!

Link to comment
Share on other sites

If you are trying to add a button to another (non AutoIt) program, then you could do something like I did with my Toolbar For Any program, which I use for SciTE etc. It is fairly tricky though, as you need to cater for several things, because it is just a floating toolbar in reality and not added at all. Some of the things to cater for, are minimizing, resizing of window, active state, etc. Then there is the difficulty of engaging with fields in the window (program) the button is tied/linked to. Not forgetting about opening or closing.

Edited by TheSaint

Make sure brain is in gear before opening mouth!
Remember, what is not said, can be just as important as what is said.

Spoiler

What is the Secret Key? Life is like a Donut

If I put effort into communication, I expect you to read properly & fully, or just not comment.
Ignoring those who try to divert conversation with irrelevancies.
If I'm intent on insulting you or being rude, I will be obvious, not ambiguous about it.
I'm only big and bad, to those who have an over-active imagination.

I may have the Artistic Liesense ;) to disagree with you. TheSaint's Toolbox (be advised many downloads are not working due to ISP screwup with my storage)

userbar.png

Link to comment
Share on other sites

If you are trying to add a button to another (non AutoIt) program, then you could do something like I did with my Toolbar For Any program, which I use for SciTE etc. It is fairly tricky though, as you need to cater for several things, because it is just a floating toolbar in reality and not added at all. Some of the things to cater for, are minimizing, resizing of window, active state, etc. Then there is the difficulty of engaging with fields in the window (program) the button is tied/linked to. Not forgetting about opening or closing.

I'm curious if you could just get the html for the page, find the control you wanted to modify and insert your code, save the code and execute it on a new page. I can see where a link that didn't have the prefix of the webpage (ie www.google.com) but linked to an internal page (ie "/pictures/pic.jpg") could make this difficult to automate.

Get Scite to add a popup when you use a 3rd party UDF -> http://www.autoitscript.com/autoit3/scite/docs/SciTE4AutoIt3/user-calltip-manager.html

Link to comment
Share on other sites

@computergroove - you are talking about a html based page, not a program, which is a whole different fish to what is being asked here. Perhaps you should start your own topic, rather than have that discussion here. For me personally though, yes, it is better to modify the original as a replacement if you can. I don't play much with HTML except in a very basic way these days ... epubs excepted.

Make sure brain is in gear before opening mouth!
Remember, what is not said, can be just as important as what is said.

Spoiler

What is the Secret Key? Life is like a Donut

If I put effort into communication, I expect you to read properly & fully, or just not comment.
Ignoring those who try to divert conversation with irrelevancies.
If I'm intent on insulting you or being rude, I will be obvious, not ambiguous about it.
I'm only big and bad, to those who have an over-active imagination.

I may have the Artistic Liesense ;) to disagree with you. TheSaint's Toolbox (be advised many downloads are not working due to ISP screwup with my storage)

userbar.png

Link to comment
Share on other sites

Hi binhbx

@Zohar: It's so simple with 1 line of script

_WinAPI_SetParent($hWndButton, $hWndTarget)

Works terrific!

Thank you for a simple and concise answer.

 

A side note: Any attempt to create/attach a control/child gui to another application's window(s) (means cross-process and/or cross-thread) is evil.

Don't do something strange or you will crash/hang both your apps and the target apps.

Why evil?

Please read on, to understand why not..

 

If you are trying to add a button to another (non AutoIt) program, then you could do something like I did with my Toolbar For Any program, which I use for SciTE etc.

Hi The Saint

That's exactly what I'm aiming for.

I created a Borderless Window (in C#), and I want to "attach" it to my Taskbar,

and later also to regular windows in some empty area they have,

and that way get a Window Specific Toolbar that I created.

I have successfully achieved it now with a simple Window, attaching it to my Taskbar, via binhbx's recommendation for using _WinAPI_SetParent().

 

binhbx:

See? not evil at all.

Also it doesn't crash, because I am not trying to mix my program's code with the original window's code..

I am just attaching an additional GUI, which is handled by the attached program..

 

It is fairly tricky though, as you need to cater for several things, because it is just a floating toolbar in reality and not added at all. Some of the things to cater for, are minimizing, resizing of window, active state, etc. Then there is the difficulty of engaging with fields in the window (program) the button is tied/linked to. Not forgetting about opening or closing.

The advantage of setting the Borderless window as a child of the window that I want to attach to,

is that If the bigger window moves, then the smaller "patch" window moves with it...

That way the problems that The Saint described, do not express.

This is as opposed to just having the smaller window "floating, and needing to follow and update itself according to every UI event of the bigger window.

Edited by Zohar
Link to comment
Share on other sites

Great you found a solution.

No doubt, I should probably revisit my code from years and several versions of AutoIt ago, however my solution still works well enough for me, and new program ideas or more important updates still regularly come along to prevent any serious consideration of rewriting ... same excuse I use for most of my programs started years ago.

If it ain't broke, why fix it?

Especially if you have books, movies, games, chores and life etc knocking on your door.

I can remember back to my childhood and early adulthood and how regularly I was bored ... whatever happened to those days?

Make sure brain is in gear before opening mouth!
Remember, what is not said, can be just as important as what is said.

Spoiler

What is the Secret Key? Life is like a Donut

If I put effort into communication, I expect you to read properly & fully, or just not comment.
Ignoring those who try to divert conversation with irrelevancies.
If I'm intent on insulting you or being rude, I will be obvious, not ambiguous about it.
I'm only big and bad, to those who have an over-active imagination.

I may have the Artistic Liesense ;) to disagree with you. TheSaint's Toolbox (be advised many downloads are not working due to ISP screwup with my storage)

userbar.png

Link to comment
Share on other sites

Yes, in normal case it works. But any problems while handling messages will makes not only your app but also the target app hang or crash, as I mentioned.

MSDN once has a statement that forbidden using SetParent on a different thread/process window, but then removed it. So it's legal, but not considered safe. So you will pay yourself if anything goes wrong (no M$'s support, and I must said that crashing/hanging is often occur than you think. I once got it by simply minimize my AutoIt app, quite strange.

If you want more details, read this.

So if you really want to do it then do it as simple as you can, do not try to add many 'feature' (i.e. theming/styling), if you don't want apps hang but don't know why (not dangerous, yes, since you can fix your script and re-run both apps, but very annoying and in some cases the problems is not easy to figure out to fix).

PS: Why you used C# than asked in AutoIt forum? (if you use C# you can use p/invoke to call SetParent without the need of extra AutoIt app. Merge 3 app together is totally not a good idea :) )

Edited by binhnx

99 little bugs in the code

99 little bugs!

Take one down, patch it around

117 little bugs in the code!

Link to comment
Share on other sites

I can remember back to my childhood and early adulthood and how regularly I was bored ...

whatever happened to those days?

You got married.

 

Yes, in normal case it works. But any problems while handling messages will makes not only your app but also the target app hang or crash, as I mentioned.

MSDN once has a statement that forbidden using SetParent on a different thread/process window, but then removed it. So it's legal, but not considered safe. So you will pay yourself if anything goes wrong (no M$'s support, and I must said that crashing/hanging is often occur than you think. I once got it by simply minimize my AutoIt app, quite strange.

If you want more details, read this.

But you know, I have seen several times programs that attach a small toolbar to regular windows, right on the blue  TitleBar area,

and they add more buttons - to other applications.

And it doesn't stuck, so I think as long as you're not trying to mess to much with what's going on ith the original program, then the problems you mentioned should be avoided.. I will see after playing with it for some time.

 

PS: Why you used C# than asked in AutoIt forum? (if you use C# you can use p/invoke to call SetParent without the need of extra AutoIt app. Merge 3 app together is totally not a good idea :) )

There are things that I use AutoIt for, and things that I use C# for.

When it comes to GUI creation, I never use AutoIt - it is very difficult and cumbersome there. For GUI I use C#.

When I need automation of other programs etc, I use AutoIt.

Soecifically here, the little windiw is created in C#,

but the attaching of it to other windows, is done with AutoIt.

I use ObjCreate() to create an instance of the .NET Form.

Edited by Zohar
Link to comment
Share on other sites

Quite interesting, I haven't try using ObjCreate to create a .NET form before :)

But in my opinion, creating a GUI with AutoIt is not such a pain in the ass, haven't you used some apps like Koda form designer yet?

Anyway, if you care on what you writing, it works, and it's simple and perfect.  My comment is only suggestion and warning, I don't said that you shouldn't use it, I only said that you need to do carefully and simple as much as you can :)

It's easier to write good code than find what's the problem when things go wrong.

Edited by binhnx

99 little bugs in the code

99 little bugs!

Take one down, patch it around

117 little bugs in the code!

Link to comment
Share on other sites

You got married.

So true ... and my life stopped being just my own.

That's an easy answer, marriage, but in truth technology has come on in leaps and bounds.

So much more you can do with your time these days.

As a child, I only had TV (latter years), Radio, Books, Vinyl Records & Cassettes, Board Games, Sport and hanging with friends.

As a young man, Cars, Videos and CD's were added to the mix.

Eventually, Computers, basic Computer Games were added.

Then decent Console Games, DVD's and far better Computer Games.

Now you have personal media devices, blu-rays and more.

If one gets bored now, it's through over-stimulation or perhaps due to being a person in need (poor, etc).

Edited by TheSaint

Make sure brain is in gear before opening mouth!
Remember, what is not said, can be just as important as what is said.

Spoiler

What is the Secret Key? Life is like a Donut

If I put effort into communication, I expect you to read properly & fully, or just not comment.
Ignoring those who try to divert conversation with irrelevancies.
If I'm intent on insulting you or being rude, I will be obvious, not ambiguous about it.
I'm only big and bad, to those who have an over-active imagination.

I may have the Artistic Liesense ;) to disagree with you. TheSaint's Toolbox (be advised many downloads are not working due to ISP screwup with my storage)

userbar.png

Link to comment
Share on other sites

  • 1 year later...

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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...