Jump to content

Recommended Posts

  • Administrators
Posted (edited)

Dev stuff:

Two new structures you should be familar with:

// The structure used to hold details about an entire window
typedef struct
{
    HWND        hWnd;                            // This window's handle
    int            nCursorID;                        // This window's cursor

    int            nMaxCtrl;                        // Next available control ID (0=none used)
    int            nLastClickedCtrl;
    int            nCtrlWithFocus;                    // Index of the control with focus (-1 = none)

    AString        sHelp;                            // Command to run when F1/Help is pressed
    bool        bVisible;                        // True if the gui is visible
    bool        bFirstShow;                        // True until the gui has been shown for the first time
    short        nW, nH;
    short        nInitW, nInitH;    
    short        nMinW, nMinH;
    int            nBackground;                    // Background colour (or -1 for default)

    GUICONTROL    Ctrl[AUT_GUI_MAXCONTROLS];        // A set of controls

    int            nCurCtrlPosX, nCurCtrlPosY;
    int            nCurCtrlPosW, nCurCtrlPosH;

    bool        bGroupFirstControlCreated;
    bool        bGroupFirstRadioCreated;

    AString        sFont;                            // Empty by default = default font
    int            nFontSize;
    int            nFontWeight;
    int            nFontStyle;

    // Tab stuff (only one control per window allowed)
    HWND        hTab;                            // Tab control handle
    int            nMaxTab;
    int            nCurTab;
    int            nFirstTab;
    bool        bTabCreation;

    // Date and time
    bool        bDateTimeOpen;                    // Is true when the DT drop down is fully opened
    bool        bDateTimeChanged;                // Is true the contents of a DT have changed 

    // Menus
    HMENU        hMenu;
    HMENU        hContextMenu;
    HMENU        hCurMenu;

    // TreeView
    HWND        hCurTV;                            // current treeview
    HTREEITEM    hCurTVItem;                        // current treeviewitem
    int            nSelectedImage;
    int            nNonselectedImage;

} GUIWINDOW;

and

typedef    struct 
{
    BYTE    cType;                                // Control type
    BYTE    cVisState;                            // Visible = 1, Invisible = 0
    BYTE    cTab;                                // Something to do with tabs...

    union 
    {
        HWND        hWnd;                        // If a normal control, the handle (button, edit, etc)
        HMENU        hMenu;                        // If a menu/submenu, the handle
        HTREEITEM    hItem;                        // If a treeview/treeviewitem, the handle
    };

    HWND    hBuddy;                                // Used for buddy controls (updown and treeviews)

    short    nX, nY;                                // X and Y position of control
    short    nW, nH;                                // Width and height
    short    nSizeable;                            // Sizing flag
    
    HFONT    hFont;                                // Handle of the font used (or NULL)
    int        nBackColor;                            // Background colour (or -1)
    int        nTextColor;                            // Text colour (or -1)
    HWND    hTip;                                // Tooltip (or NULL)

} GUICONTROL;

A new GUIWINDOW is created everytime GuiCreate() is used. This in turn creates the array of GUICONTROLS (GUIWINDOW->Ctrl[nnn])

The terminology used in the source goes like this:

nWinIdx = the windows index, GUIWINDOW[0] is the first window

nCtrlIdx = the index of a control WITHIN a window. Same as before numbered from AUT_GUI_FIRSTCONTROL (3) to MAX_CONTROLS. Like nWinIdx this is an internal number used for quickly accessing the array

nGlobalID = The Control ID that is used in AutoIt and by Windows.

The 3 values are related like this:

nGlobalID = (nWinIdx * AUT_GUI_MAXCONTROLS) + nCtrlIdx;

This means that each seperate window has it's own unique pool of GlobalIDs, but it also means that we can easily work out a window/control given a globalID:

nWinIdx = nGlobalID / AUT_GUI_MAXCONTROLS;

nCtrlIdx = nGlobalID - (nWinIdx * AUT_GUI_MAXCONTROLS);

In the source there are these helper functions so you don't have to do this manually:

int WinHWNDtoIndex(HWND hWnd);

int CtrlHWNDtoIndex(int nWinIdx, HWND hWnd);

int CtrlIndextoGlobalID(int nWinIdx, int nCtrlIdx);

bool GlobalIDtoCtrlIndex(int nGlobalID, int &nWinIdx, int &nCtrlIdx);

:ph34r:

Edited by Jon
  • Replies 41
  • Created
  • Last Reply

Top Posters In This Topic

Top Posters In This Topic

  • Administrators
Posted

Had another cool idea. First off we should start using constants instead of number for events. So instead of this

If $msg = -3 Then

we have

If $msg = $GUI_EVENT_CLOSE Then

And now we have the advanced message mode of GuiGetMsg(1) which returns and array like:

$msg[0] = event message / ID

$msg[1] = window handle

$msg[2] = control handle

We can add some other messages that may be useful, like mouse clicks and keypresses - as these events are happening in AutoIt I don't need a hook to get hold of them :ph34r:

Something like:

$msg[0] = mouseclick

$msg[1] = X

$msg[2] = Y

I could even get mouse movements. :(

Posted (edited)

I'm playing with the multiwindows feature.

The idea is very nice.

I made a custom MsgBox some time ago and I tried to make it work, but I failed.

First I have a question before I continue:

What about GUIDelete()? Which window will it delete?

If I want to hide a parent window, I can't swap using GuiSetState().

Only if these things get straighted out, I can make my MsgBoxEx work.

Edited by SlimShady
  • Administrators
Posted (edited)

I'm playing with the multiwindows feature.

The idea is very nice.

I made a custom MsgBox some time ago and I tried to make it work, but I failed.

First I have a question before I continue:

What about GUIDelete()? Which window will it delete?

The Gui keeps track of the "current window". Whenever you use GuiCreate() that new window is set as "current". This doesn't change unless you use GuiSwitch(). So GuiDelete() will delete the current window.

$win1 = GuiCreate(...)
$win2 = GuiCreate(...)
$win3 = GuiCreate(...)

GuiDelete()  ; Deletes win3
GuiSwitch($win1)
GuiDelete()  ; Deletes win1

Also, if you delete a parent window then all of it's children will be deleted. So if your gui has a parent window and 10 children/helper windows you only need to GuiDelete() the parent in order to delete them all. :ph34r:

Edited by Jon
Posted

Not sure what you mean by that.

<{POST_SNAPBACK}>

I meant "how do I hide a window? Because GUISetState(@SW_HIDE) doesn't know which window"

Now I understand. I should use the GuiSwitch() function.

(I didn't know it existed...)

  • Administrators
Posted

Re-added the multi code with Holger's CrtlSetImage that works on treeviews.

Also added a $GUI_EVENT_MOUSEMOVE message that notifies you of the mouse position relative to the client area of the screen (same scheme as the control positioning). See the gui.au3 example. The position updates a maximum of every 50ms but from the example it looks to be very responsive. Capturing mouse clicks is a bit more tricky - as if you are over a control when you click then it doesn't work (you just get the normal control notifcation...). I'll have to think about it.

If there are no major problems found with the multi stuff then I will move it into the usual unstable directory as the only version later on today.

Posted

Hey Jon, can we get a GUIPostMsg() function so that we can post our own messages to go into the message queue? Something of the form:

GUIPostMsg("msg" [, wParam [, lParam]])

GUI's are event driven so its a lot harder to do typical procedural stuff without having some way of specifying an event for it. So I'd like to see some way to post custom events to the script.

Posted

Cool.  How about making the msgbox a child of the main window so that it stays on top?

$MsgBoxEx = GUICreate("Test", 275, 180, -1, -1, BitOR(0x04CF000, 0x00000008), -1, $parent1)

<{POST_SNAPBACK}>

I changed that and I added this for testing:

GUISetState(@SW_MINIMIZE)
         Sleep(1000)

And I'm very pleased with the result. :ph34r:

Posted

Hi Jon,

GuiRead() is not returning the last controlid clicked anymore :">

can you have a look to it

Thanks

  • Administrators
Posted

Hi Jon,

GuiRead() is not returning the last controlid clicked anymore :">

can you have a look to it

Thanks

Oops. But does this mode actually make sense anymore? IIRC it was so you could do things like:

GuiWaitClose

GuiRead(-1)

So you could work out which control was used to close the gui, but that can't happen now... It's easy enough to fix again if you think it should be in :ph34r:

Posted

Oops.  But does this mode actually make sense anymore?  IIRC it was so you could do things like:

GuiWaitClose

GuiRead(-1)

So you could work out which control was used to close the gui, but that can't happen now...  It's easy enough to fix again if you think it should be in :ph34r:

<{POST_SNAPBACK}>

I use it to retrieve which was the last click as

While GuiGetMsg<>-3
...
Wend
$lastclick=GuiRead()
  • Administrators
Posted (edited)

I use it to retrieve which was the last click as

While GuiGetMsg<>-3
...
Wend
$lastclick=GuiRead()

I don't understand.

If msg = -3 (close) then the user has clicked the X button so what should GuiRead return? :ph34r:

Edited by Jon
  • Administrators
Posted (edited)

I don't understand.

If msg = -3 (close) then the user has clicked the X button so what should GuiRead return?   :ph34r:

In some of your examples in the docs you have things like this:

While GuiGetMsg ()>0; to wait a click 
if GuiRead () = $nAdd then GuiCtrlSetData ($nList,"text entry "& $n)   
if GuiRead() = $nClear then GuiCtrlSetData ($nList,"")   
Wend

is this the reason for the GuiRead/Last click thing? I don't think this method should be used as the extra modes I've added to GuiGetMsg make this loop impractical anyway. I feel that the best general purpose newbie/advanced loop is:

While 1
  $msg = GuiGetMsg()
  if $msg = $GUI_EVENT_CLOSE Then ExitLoop

; Select statement or IF statements
  If $msg = $nAdd Then ...
  If $msg = $nClear Then ...
Wend

With the extra options for GuiGetMsg (returning arrays of info) and also with multi windows you need to check not only if GUI_EVENT_CLOSE was received but also which window sent the message. (And it's only 2 lines longer which is not a heavy price to pay for consistency :( )

Edited by Jon

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.
×
×
  • Create New...