Jump to content

help with masking gui don't know how to delete


 Share

Recommended Posts

Hi, I am very confused. :D The code below if I understand it correctly masks a gui by creating a region on it that i can AddMask() other controls on it. I don't know how it completely works but I know it allows me to create a child gui on a parent and have that child be completely transparent while the controls on it are still visible. What I don't understand is how to "unmask" it. I want to update controls in the mask on the transparent child but i can't because the old controls will still show because of the mask. I need help with this and would like to know how it works as well. Is there any ClearMask() function or something that will "delete the old masks", so i can then update the controls in it, then "re-create" the mask. Would appreciate help very much.

Credits to martin, the original author of this code.

#include <GuiConstants.au3>
#include <windowsconstants.au3>

$Main_GUI = GUICreate("Main")
$Btn_Exit = GUICtrlCreateButton("E&xit", 10, 10, 90, 20)
$DeleteChild = GUICtrlCreateButton("Delete Child Window", 50, 250, 70, 70)
$menu = GUICtrlCreateContextMenu()
GUICtrlCreateMenuItem("Exit", $menu)
GUISetState(@SW_SHOW, $Main_GUI)
$childwin = GUICreate("Child", 200, 100, 10, 50, $WS_POPUP )
GUISetBkColor(0xfffaf0, $childwin)
$Btn_Test = GUICtrlCreateButton("Test", 10, 10, 90, 20)
$picture = GUICtrlCreatePic(@ScriptDir & "\merlin.gif", 15, 40, 50, 50)
GUISetState(@SW_SHOW, $childwin)
DllCall("user32.dll", "int", "SetParent", "hwnd", WinGetHandle($childwin), "hwnd", WinGetHandle($Main_GUI))



While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE, $Btn_Exit
            Exit
        Case $Btn_Test
            MsgBox(0, "Test", "Hit Button on Child Window")
            $masterMask = CreateMasterMask();
            AddMask($masterMask,$childwin,$Btn_Test);add button to mask
            AddMask($masterMask,$childwin,$picture);add button to mask
            FitMask($masterMask,$childwin);apply the mask to the window
        Case $DeleteChild
            GUIDelete($childwin)
    EndSwitch
WEnd

Func CreateMasterMask()
    return DllCall("gdi32.dll", "long", "CreateRectRgn", "long", 0, "long", 0, "long", 0, "long", 0)
EndFunc

Func FitMask($aMask,$hWnd)
    DllCall("user32.dll", "long", "SetWindowRgn", "hwnd", $hWnd, "long", $aMask[0], "int", 1)
endfunc

Func AddMask(ByRef $MM, $hWnd, $ID)
    $pp = ControlGetPos($hWnd,'',$ID)
    Local $Mask1 = DllCall("gdi32.dll", "long", "CreateRectRgn", "long", $pp[0], "long", $pp[1], "long", $pp[0] + $pp[2], "long",$pp[1] + $pp[3])
    DllCall("gdi32.dll", "long", "CombineRgn", "long", $MM[0], "long", $Mask1[0], "long", $MM[0],"int",2)
EndFunc
Edited by Hypertrophy
Link to comment
Share on other sites

Mask is a bad way to describe what is happening. From my understanding, these dllcalls reform the window shape. In reality, I believe the window is still there, it is just there only behind the controls. So all the functions do is make the window a different shape (the shape of the controls).

The CreateMasterMask function is making a mask to add controls to. It is the mask that will eventually be resized.

The add mask function is getting the position of the control and the "CreateRectRgn" part is reforming the window to the size and position of that control. The "CombineRgn" part is adding the control to the mask so that the previous control isn't lost.

The "FitMask" function is what finally applies the mask to the window.

If you don't know what a dllcall does, google it and normally the very first thing that comes up is msdn. That will tell you the parameters and return values of the dllcall.

Here is the code that you want:

#include <GuiConstants.au3>
#include <windowsconstants.au3>

$Main_GUI = GUICreate("Main")
$Btn_Exit = GUICtrlCreateButton("E&xit", 10, 10, 90, 20)
$DeleteChild = GUICtrlCreateButton("Delete Child Window", 50, 250, 70, 70)
$menu = GUICtrlCreateContextMenu()
GUICtrlCreateMenuItem("Exit", $menu)
GUISetState(@SW_SHOW, $Main_GUI)
$childwin = GUICreate("Child", 200, 100, 10, 50, $WS_POPUP)
GUISetBkColor(0xfffaf0, $childwin)
$Btn_Test = GUICtrlCreateButton("Test", 10, 10, 90, 20)
$picture = GUICtrlCreatePic(@ScriptDir & "\merlin.gif", 15, 40, 50, 50)
GUISetState(@SW_SHOW, $childwin)
DllCall("user32.dll", "int", "SetParent", "hwnd", WinGetHandle($childwin), "hwnd", WinGetHandle($Main_GUI))



While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE, $Btn_Exit
            Exit
        Case $Btn_Test
            MsgBox(0, "Test", "Hit Button on Child Window")
            $masterMask = CreateMasterMask(0, 0, 0, 0);
            AddMask($masterMask, $childwin, $Btn_Test);add button to mask
            AddMask($masterMask, $childwin, $picture);add button to mask
            FitMask($masterMask, $childwin);apply the mask to the window
        Case $DeleteChild
            $Pos = WinGetPos($childwin)
            $masterMask = CreateMasterMask(0, 0, $Pos[2], $Pos[3]);
;~             AddMask($masterMask, $childwin, $Btn_Test);add button to mask
;~             AddMask($masterMask, $childwin, $picture);add button to mask
            FitMask($masterMask, $childwin);apply the mask to the window
    EndSwitch
WEnd

Func CreateMasterMask($X, $Y, $Width, $Height)
    ;http://msdn.microsoft.com/en-us/library/ms908184.aspx
    ;this is the region that you want the window to be
    ;coordinates must be relative to the window they will be applied to
    Return DllCall("gdi32.dll", "long", "CreateRectRgn", "long", $X, "long", $Y, "long", $Width, "long", $Height)
EndFunc   ;==>CreateMasterMask

Func FitMask($aMask, $hWnd)
    ;this sets the window to the region created
    DllCall("user32.dll", "long", "SetWindowRgn", "hwnd", $hWnd, "long", $aMask[0], "int", 1)
EndFunc   ;==>FitMask

Func AddMask(ByRef $MM, $hWnd, $ID)
    ;this gets the position of the control
    $pp = ControlGetPos($hWnd, '', $ID)
    ;this creates a region exactly the size of the control and in the same position
    Local $Mask1 = DllCall("gdi32.dll", "long", "CreateRectRgn", "long", $pp[0], "long", $pp[1], "long", $pp[0] + $pp[2], "long", $pp[1] + $pp[3])
    ;this combines $Mask1 with the final mask; the final mask is a combination of all the other masks
    DllCall("gdi32.dll", "long", "CombineRgn", "long", $MM[0], "long", $Mask1[0], "long", $MM[0], "int", 2)
EndFunc   ;==>AddMask
Edited by dantay9
Link to comment
Share on other sites

@ dantay9

I don't see where you unmask.

@ hypertrophy. I think you just need a function like this

Func uNMask ($hWnd)
    Local $cp = WinGetPos($hWnd)
    Local $rgn = _WinAPI_CreateRectRgn (0, 0, $cp[2], $cp[3])
    _WinAPI_SetWindowRgn ($hWnd, $rgn)
EndFunc   ;==>uNMask

It's all in the help, look up _WInAPI_SetWindowRgn. My code is not the best to follow, I would recommend using the _WinAPI calls as in the help.

EDIT:corrected function and removed unused parameter.

Edited by martin
Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.
Link to comment
Share on other sites

dantay: Thank you for explaining everything so well to me.

martin: Thank you! That's what I've been after. New to DllCalls so it's good to have a guru helping me out :D

God Bless All.

NP. To find out about these API's you only need to google the function name followed by function eg "SetWindowRgn function" and follow the link to msdn. (SetWindowRgn)

Note the I corrected the UnMask function.

Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.
Link to comment
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
 Share

  • Recently Browsing   0 members

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