Sign in to follow this  
Followers 0
nullschritt

Keeping one window inside a second window

5 posts in this topic

#1 ·  Posted (edited)

Hello all, I have two windows my script creates but I would like to always keep the second window inside the first. I am able to bring it back down if it goes too far up, and back right if it goes too far left, but I'm stumpped on how to bring it up if its too far down and left if it's too far right, I've spent the better part of a half an hour trying different calculations but I just can't seem to get it to position itself back to the right place, and if the child window goes in the bottom left corner it glitched back and fourth between the bottom and left side of the gui.

I know there has to be an easier way to do it, I've seen it in the past. Anyways here's my (faulty) code.

#include <File.au3>
#include <Constants.au3>
#include <WindowsConstants.au3>
;~ #include "_GUIResourcePic.au3"
#include <GDIPlus.au3>
#include <GuiConstantsEx.au3>
#include <GDIPlus.au3>

Global $sFile, $label1

_GDIPlus_Startup()

; Make GUI
Global $hGuix = GUICreate("Secure Instant Messenger - Login - BETA", 720, 405)
Global $iCtrlID = GUICtrlCreatePic("", 0, 0, 720, 405, -1, $GUI_WS_EX_PARENTDRAG)
GUICtrlSetState(-1, $GUI_DISABLE)
;~ _GUICtrlPic_SetImage($iCtrlID, "", True)
GUISetState()

$mainpos = WinGetPos("Secure Instant Messenger - Login - BETA")
 DisplayImage(@ScriptDir&"\loginform.png", $mainpos[0]+30, $mainpos[1]+ 270)

Global $iPlay = 1

;~ $Label1 = GUICtrlCreateLabel("Version 0.1.0.0", 152, 64, 139, 19)
;~ GUICtrlSetBkColor(-1, $GUI_BKCOLOR_TRANSPARENT)

; Loop till end
While 1
    Switch GUIGetMsg()
        Case -3
            Exit
    EndSwitch
    if WinExists(@ScriptDir&"\loginform.png") Then
    $mainpos = WinGetPos("Secure Instant Messenger - Login - BETA")
    $loginpos = WinGetPos(@ScriptDir&"\loginform.png")
    if $loginpos[0] < $mainpos[0] Then
        WinMove(@ScriptDir&"\loginform.png", "", $mainpos[0]+5, $loginpos[1])
    EndIf
    if $loginpos[1] < $mainpos[1] Then
        WinMove(@ScriptDir&"\loginform.png", "", $loginpos[0], $mainpos[1]+40)
    EndIf
    if $loginpos[0]+$loginpos[2] > $mainpos[2]+$mainpos[0] Then
        WinMove(@ScriptDir&"\loginform.png", "", $loginpos[0]-$loginpos[3]+50, $loginpos[0]+$loginpos[2])
    EndIf
    if $loginpos[1]+$loginpos[3] > $mainpos[3]+$mainpos[1] Then
        WinMove(@ScriptDir&"\loginform.png", "",($mainpos[3]+$mainpos[1])-(($mainpos[3]+$mainpos[1])-$loginpos[0]), ($mainpos[2]+$mainpos[0])-$loginpos[1] )
    EndIf
    EndIf
WEnd

Func DisplayImage($sFile, $iPosX = -1, $iPosY = -1, $iAlpha = 0xFF, $bTopmost = True)
    Local Const $hBmp_Background = _GDIPlus_BitmapCreateFromFile($sFile) ;load the image
    If @error Then Return SetError(1, 0, 0) ;image cannot be loaded
    Local Const $iW = _GDIPlus_ImageGetWidth($hBmp_Background), $iH = _GDIPlus_ImageGetHeight($hBmp_Background) ;get the dimension of the background image
    Local Const $hGUI = GUICreate($sfile, $iW, $iH, $iPosX, $iPosY, $WS_POPUP, BitOR($WS_EX_LAYERED, $WS_EX_TOPMOST * $bTopmost, $WS_EX_TOOLWINDOW),$hguix) ;create GUI with appropriate styles and extented style (borderless transparent GUI)
    GUICtrlCreateLabel("", 0, 0, $iW, $iH, Default, $GUI_WS_EX_PARENTDRAG) ;create a hidden label for GUI dragging
    GUISetState(@SW_SHOW, $hGUI) ;show GUI

    Local Const $hBitmap = _GDIPlus_BitmapCreateFromScan0($iW, $iH) ;define an empty bitmap where all the gfx stuff will copied to
    Local Const $hGfx = _GDIPlus_ImageGetGraphicsContext($hBitmap) ;get the context to the bitmap to be able to copy / draw to the bitmap
    _GDIPlus_GraphicsDrawImageRect($hGfx, $hBmp_Background, 0, 0, $iW, $iH) ;draw background image to the empty bitmap

    ;display GDI+ with transparency on desktop
    Local Const $hHBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap) ;convert GDI+ image to GDI to display it on the screen using GDI functions
    Local Const $hScrDC = _WinAPI_GetDC($hGUI) ;get the device context (dc) handle of the GUI
    Local Const $hMemDC = _WinAPI_CreateCompatibleDC($hScrDC) ;create a compatible dc handle
    Local Const $hOld = _WinAPI_SelectObject($hMemDC, $hHBitmap) ;selects the GDI bitmap object into the specified device context
    Local Const $tSize = DllStructCreate($tagSIZE) ;create a $tagSIZE struct (x = width, y = height)
    DllStructSetData($tSize, "X", $iW) ;set data for width
    DllStructSetData($tSize, "Y", $iH) ;set data for height
    Local $tSource = DllStructCreate($tagPOINT) ;create a $tagPOINT struct (x = x position, y = y position)
    Local $tBlend = DllStructCreate($tagBLENDFUNCTION) ;create $tagBLENDFUNCTION struct -> see help file for more info
    DllStructSetData($tBlend, "Alpha", $iAlpha) ;set the alpha channel of the GUI -> 255 = opaque, 0 = transparent
    DllStructSetData($tBlend, "Format", 1) ;set the format to 1 -> bitmap has alpha channels
    DllCall("user32.dll", "bool", "UpdateLayeredWindow", "hwnd", $hGUI, "handle", $hScrDC, "ptr", 0, "struct*", $tSize, "handle", $hMemDC, "struct*", $tSource, "dword", 0, "struct*", $tBlend, "dword", $ULW_ALPHA) ;display bitmap on screen

    ;release resources otherwise memory will filled up (memory leak)
    _GDIPlus_GraphicsDispose($hGfx)
    _GDIPlus_BitmapDispose($hBitmap)
    Local $aResource[7] = [$hGUI, $hScrDC, $hHBitmap, $hMemDC, $tBlend, $tSize, $tSource] ;return the handle to release it later
    Return $aResource
EndFunc   ;==>DisplayImage

; This function releases the resources of a specific image and closes it
Func ReleaseResources(ByRef $aResource)
    If Not IsArray($aResource) Then Return SetError(1, 0, 0)
    If UBound($aResource) <> 7 Then Return SetError(2, 0, 0)
    _WinAPI_ReleaseDC($aResource[0], $aResource[1])
    _WinAPI_DeleteDC($aResource[3])
    _WinAPI_DeleteObject($aResource[2])
    GUIDelete($aResource[0])
EndFunc   ;==>ReleaseResources

; To fade in an image leave $bIn at default (True); to fade out specify False.
; There are also options to set the ending transparency level (0 transparent, 255 opaque), speed and delay.
; If you change the speed or delay be sure to specify $bIn and $iTrans, otherwise you'll wonder why the fade-in or out isn't what you hoped for.
; The default values are specified in the function below.
Func _Fader($res1, $bIn = True, $iTrans = 255, $speed = 3, $delay = 10  )
    If Not IsArray($res1) Then Return SetError(1, 0, 0)
    If UBound($res1) <> 7 Then Return SetError(2, 0, 0)
    Switch $bIn
        Case True
            For $a = 0 To $iTrans Step $speed
                DllStructSetData($res1[4], "Alpha", $a)
                DllCall("user32.dll", "bool", "UpdateLayeredWindow", "hwnd", $res1[0], "handle", $res1[1], "ptr", 0, "struct*", $res1[5], "handle", $res1[3], "struct*", $res1[6], "dword", 0, "struct*", $res1[4], "dword", $ULW_ALPHA) ;display bitmap on screen
                Sleep($delay)
            Next
        Case Else
            For $a = $iTrans To 0 Step -$speed
                DllStructSetData($res1[4], "Alpha", $a)
                DllCall("user32.dll", "bool", "UpdateLayeredWindow", "hwnd", $res1[0], "handle", $res1[1], "ptr", 0, "struct*", $res1[5], "handle", $res1[3], "struct*", $res1[6], "dword", 0, "struct*", $res1[4], "dword", $ULW_ALPHA) ;display bitmap on screen
                Sleep($delay)
            Next
    EndSwitch
EndFunc   ;==>_FadeIn

required image is attached

post-70883-0-34115400-1426458960_thumb.p

Edited by nullschritt

Share this post


Link to post
Share on other sites



Okay I've written this to get it to stay in the same place, but it doesnt move to the proper location until after the window moves. Is there a way to move it with the window(without spawning a second process) or to stop the script from pausing during window movement?

#include <File.au3>
#include <Constants.au3>
#include <WindowsConstants.au3>
;~ #include "_GUIResourcePic.au3"
#include <GDIPlus.au3>
#include <GuiConstantsEx.au3>
#include <GDIPlus.au3>
#include <winapi.au3>

Global $sFile, $label1

_GDIPlus_Startup()

; Make GUI
Global $hGuix = GUICreate("Secure Instant Messenger - Login - BETA", 720, 405)
Global $iCtrlID = GUICtrlCreatePic("", 0, 0, 720, 405, -1, $GUI_WS_EX_PARENTDRAG)
GUICtrlSetState(-1, $GUI_DISABLE)
;~ _GUICtrlPic_SetImage($iCtrlID, @ScriptDir&"\background.gif", True)
GUISetState()

$mainpos = WinGetPos("Secure Instant Messenger - Login - BETA")
$login = DisplayImage(@ScriptDir&"\loginform.png", $mainpos[0]+30, $mainpos[1]+ 270)
Global $iPlay = 1

;~ $Label1 = GUICtrlCreateLabel("Version 0.1.0.0", 152, 64, 139, 19)
;~ GUICtrlSetBkColor(-1, $GUI_BKCOLOR_TRANSPARENT)

; Loop till end
While 1
    Switch GUIGetMsg()
        Case -3
            Exit
    EndSwitch
    $mainpos = WinGetPos("Secure Instant Messenger - Login - BETA")
    WinMove(@ScriptDir&"\loginform.png", "", $mainpos[0]+30, $mainpos[1]+ 270)

WEnd

Func DisplayImage($sFile, $iPosX = -1, $iPosY = -1, $iAlpha = 0xFF, $bTopmost = True)
    Local Const $hBmp_Background = _GDIPlus_BitmapCreateFromFile($sFile) ;load the image
    If @error Then Return SetError(1, 0, 0) ;image cannot be loaded
    Local Const $iW = _GDIPlus_ImageGetWidth($hBmp_Background), $iH = _GDIPlus_ImageGetHeight($hBmp_Background) ;get the dimension of the background image
    Local Const $hGUI = GUICreate($sfile, $iW, $iH, $iPosX, $iPosY, $WS_POPUP, BitOR($WS_EX_LAYERED, $WS_EX_TOPMOST * $bTopmost, $WS_EX_TOOLWINDOW),$hguix) ;create GUI with appropriate styles and extented style (borderless transparent GUI)
    GUICtrlCreateLabel("", 0, 0, $iW, $iH, Default, $GUI_WS_EX_PARENTDRAG) ;create a hidden label for GUI dragging
    GUISetState(@SW_SHOW, $hGUI) ;show GUI

    Local Const $hBitmap = _GDIPlus_BitmapCreateFromScan0($iW, $iH) ;define an empty bitmap where all the gfx stuff will copied to
    Local Const $hGfx = _GDIPlus_ImageGetGraphicsContext($hBitmap) ;get the context to the bitmap to be able to copy / draw to the bitmap
    _GDIPlus_GraphicsDrawImageRect($hGfx, $hBmp_Background, 0, 0, $iW, $iH) ;draw background image to the empty bitmap

    ;display GDI+ with transparency on desktop
    Local Const $hHBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap) ;convert GDI+ image to GDI to display it on the screen using GDI functions
    Local Const $hScrDC = _WinAPI_GetDC($hGUI) ;get the device context (dc) handle of the GUI
    Local Const $hMemDC = _WinAPI_CreateCompatibleDC($hScrDC) ;create a compatible dc handle
    Local Const $hOld = _WinAPI_SelectObject($hMemDC, $hHBitmap) ;selects the GDI bitmap object into the specified device context
    Local Const $tSize = DllStructCreate($tagSIZE) ;create a $tagSIZE struct (x = width, y = height)
    DllStructSetData($tSize, "X", $iW) ;set data for width
    DllStructSetData($tSize, "Y", $iH) ;set data for height
    Local $tSource = DllStructCreate($tagPOINT) ;create a $tagPOINT struct (x = x position, y = y position)
    Local $tBlend = DllStructCreate($tagBLENDFUNCTION) ;create $tagBLENDFUNCTION struct -> see help file for more info
    DllStructSetData($tBlend, "Alpha", $iAlpha) ;set the alpha channel of the GUI -> 255 = opaque, 0 = transparent
    DllStructSetData($tBlend, "Format", 1) ;set the format to 1 -> bitmap has alpha channels
    DllCall("user32.dll", "bool", "UpdateLayeredWindow", "hwnd", $hGUI, "handle", $hScrDC, "ptr", 0, "struct*", $tSize, "handle", $hMemDC, "struct*", $tSource, "dword", 0, "struct*", $tBlend, "dword", $ULW_ALPHA) ;display bitmap on screen

    ;release resources otherwise memory will filled up (memory leak)
    _GDIPlus_GraphicsDispose($hGfx)
    _GDIPlus_BitmapDispose($hBitmap)
    Local $aResource[7] = [$hGUI, $hScrDC, $hHBitmap, $hMemDC, $tBlend, $tSize, $tSource] ;return the handle to release it later
    Return $aResource
EndFunc   ;==>DisplayImage

; This function releases the resources of a specific image and closes it
Func ReleaseResources(ByRef $aResource)
    If Not IsArray($aResource) Then Return SetError(1, 0, 0)
    If UBound($aResource) <> 7 Then Return SetError(2, 0, 0)
    _WinAPI_ReleaseDC($aResource[0], $aResource[1])
    _WinAPI_DeleteDC($aResource[3])
    _WinAPI_DeleteObject($aResource[2])
    GUIDelete($aResource[0])
EndFunc   ;==>ReleaseResources

; To fade in an image leave $bIn at default (True); to fade out specify False.
; There are also options to set the ending transparency level (0 transparent, 255 opaque), speed and delay.
; If you change the speed or delay be sure to specify $bIn and $iTrans, otherwise you'll wonder why the fade-in or out isn't what you hoped for.
; The default values are specified in the function below.
Func _Fader($res1, $bIn = True, $iTrans = 255, $speed = 3, $delay = 10  )
    If Not IsArray($res1) Then Return SetError(1, 0, 0)
    If UBound($res1) <> 7 Then Return SetError(2, 0, 0)
    Switch $bIn
        Case True
            For $a = 0 To $iTrans Step $speed
                DllStructSetData($res1[4], "Alpha", $a)
                DllCall("user32.dll", "bool", "UpdateLayeredWindow", "hwnd", $res1[0], "handle", $res1[1], "ptr", 0, "struct*", $res1[5], "handle", $res1[3], "struct*", $res1[6], "dword", 0, "struct*", $res1[4], "dword", $ULW_ALPHA) ;display bitmap on screen
                Sleep($delay)
            Next
        Case Else
            For $a = $iTrans To 0 Step -$speed
                DllStructSetData($res1[4], "Alpha", $a)
                DllCall("user32.dll", "bool", "UpdateLayeredWindow", "hwnd", $res1[0], "handle", $res1[1], "ptr", 0, "struct*", $res1[5], "handle", $res1[3], "struct*", $res1[6], "dword", 0, "struct*", $res1[4], "dword", $ULW_ALPHA) ;display bitmap on screen
                Sleep($delay)
            Next
    EndSwitch
EndFunc   ;==>_FadeIn

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

I was able to acheive my desired effect with the below code, but it requires a second process be spawned.

#include <File.au3>
#include <Constants.au3>
#include <WindowsConstants.au3>
;~ #include "_GUIResourcePic.au3"
#include <GDIPlus.au3>
#include <GuiConstantsEx.au3>
#include <GDIPlus.au3>
#include <winapi.au3>

Global $sFile, $label1

if not @Compiled then Exit ;need to be compiled

_GDIPlus_Startup()

if $cmdlineraw="/loginmovewith" Then
while WinExists("Secure Instant Messenger - Login - BETA")
    $mainpos = WinGetPos("Secure Instant Messenger - Login - BETA")
    if @error Then Exit
    WinMove(@ScriptDir&"\loginform.png", "", $mainpos[0]+30, $mainpos[1]+ 270)
    sleep(5)
WEnd
Exit
EndIf

; Make GUI
Global $hGuix = GUICreate("Secure Instant Messenger - Login - BETA", 720, 405)
Global $iCtrlID = GUICtrlCreatePic("", 0, 0, 720, 405, -1, $GUI_WS_EX_PARENTDRAG)
GUICtrlSetState(-1, $GUI_DISABLE)
;~ _GUICtrlPic_SetImage($iCtrlID, @ScriptDir&"\background.gif", True)
GUISetState()

$mainpos = WinGetPos("Secure Instant Messenger - Login - BETA")
$login = DisplayImage(@ScriptDir&"\loginform.png", $mainpos[0]+30, $mainpos[1]+ 270)
Global $iPlay = 1

if @Compiled Then
ShellExecute(@ScriptFullPath, "/loginmovewith")
EndIf
;~ $Label1 = GUICtrlCreateLabel("Version 0.1.0.0", 152, 64, 139, 19)
;~ GUICtrlSetBkColor(-1, $GUI_BKCOLOR_TRANSPARENT)

; Loop till end
While 1
    Switch GUIGetMsg()
        Case -3
            Exit
    EndSwitch
WEnd

Func DisplayImage($sFile, $iPosX = -1, $iPosY = -1, $iAlpha = 0xFF, $bTopmost = True)
    Local Const $hBmp_Background = _GDIPlus_BitmapCreateFromFile($sFile) ;load the image
    If @error Then Return SetError(1, 0, 0) ;image cannot be loaded
    Local Const $iW = _GDIPlus_ImageGetWidth($hBmp_Background), $iH = _GDIPlus_ImageGetHeight($hBmp_Background) ;get the dimension of the background image
    Local Const $hGUI = GUICreate($sfile, $iW, $iH, $iPosX, $iPosY, $WS_POPUP, BitOR($WS_EX_LAYERED, $WS_EX_TOPMOST * $bTopmost, $WS_EX_TOOLWINDOW),$hguix) ;create GUI with appropriate styles and extented style (borderless transparent GUI)
    GUICtrlCreateLabel("", 0, 0, $iW, $iH, Default, $GUI_WS_EX_PARENTDRAG) ;create a hidden label for GUI dragging
    GUISetState(@SW_SHOW, $hGUI) ;show GUI

    Local Const $hBitmap = _GDIPlus_BitmapCreateFromScan0($iW, $iH) ;define an empty bitmap where all the gfx stuff will copied to
    Local Const $hGfx = _GDIPlus_ImageGetGraphicsContext($hBitmap) ;get the context to the bitmap to be able to copy / draw to the bitmap
    _GDIPlus_GraphicsDrawImageRect($hGfx, $hBmp_Background, 0, 0, $iW, $iH) ;draw background image to the empty bitmap

    ;display GDI+ with transparency on desktop
    Local Const $hHBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap) ;convert GDI+ image to GDI to display it on the screen using GDI functions
    Local Const $hScrDC = _WinAPI_GetDC($hGUI) ;get the device context (dc) handle of the GUI
    Local Const $hMemDC = _WinAPI_CreateCompatibleDC($hScrDC) ;create a compatible dc handle
    Local Const $hOld = _WinAPI_SelectObject($hMemDC, $hHBitmap) ;selects the GDI bitmap object into the specified device context
    Local Const $tSize = DllStructCreate($tagSIZE) ;create a $tagSIZE struct (x = width, y = height)
    DllStructSetData($tSize, "X", $iW) ;set data for width
    DllStructSetData($tSize, "Y", $iH) ;set data for height
    Local $tSource = DllStructCreate($tagPOINT) ;create a $tagPOINT struct (x = x position, y = y position)
    Local $tBlend = DllStructCreate($tagBLENDFUNCTION) ;create $tagBLENDFUNCTION struct -> see help file for more info
    DllStructSetData($tBlend, "Alpha", $iAlpha) ;set the alpha channel of the GUI -> 255 = opaque, 0 = transparent
    DllStructSetData($tBlend, "Format", 1) ;set the format to 1 -> bitmap has alpha channels
    DllCall("user32.dll", "bool", "UpdateLayeredWindow", "hwnd", $hGUI, "handle", $hScrDC, "ptr", 0, "struct*", $tSize, "handle", $hMemDC, "struct*", $tSource, "dword", 0, "struct*", $tBlend, "dword", $ULW_ALPHA) ;display bitmap on screen

    ;release resources otherwise memory will filled up (memory leak)
    _GDIPlus_GraphicsDispose($hGfx)
    _GDIPlus_BitmapDispose($hBitmap)
    Local $aResource[7] = [$hGUI, $hScrDC, $hHBitmap, $hMemDC, $tBlend, $tSize, $tSource] ;return the handle to release it later
    Return $aResource
EndFunc   ;==>DisplayImage

; This function releases the resources of a specific image and closes it
Func ReleaseResources(ByRef $aResource)
    If Not IsArray($aResource) Then Return SetError(1, 0, 0)
    If UBound($aResource) <> 7 Then Return SetError(2, 0, 0)
    _WinAPI_ReleaseDC($aResource[0], $aResource[1])
    _WinAPI_DeleteDC($aResource[3])
    _WinAPI_DeleteObject($aResource[2])
    GUIDelete($aResource[0])
EndFunc   ;==>ReleaseResources

; To fade in an image leave $bIn at default (True); to fade out specify False.
; There are also options to set the ending transparency level (0 transparent, 255 opaque), speed and delay.
; If you change the speed or delay be sure to specify $bIn and $iTrans, otherwise you'll wonder why the fade-in or out isn't what you hoped for.
; The default values are specified in the function below.
Func _Fader($res1, $bIn = True, $iTrans = 255, $speed = 3, $delay = 10  )
    If Not IsArray($res1) Then Return SetError(1, 0, 0)
    If UBound($res1) <> 7 Then Return SetError(2, 0, 0)
    Switch $bIn
        Case True
            For $a = 0 To $iTrans Step $speed
                DllStructSetData($res1[4], "Alpha", $a)
                DllCall("user32.dll", "bool", "UpdateLayeredWindow", "hwnd", $res1[0], "handle", $res1[1], "ptr", 0, "struct*", $res1[5], "handle", $res1[3], "struct*", $res1[6], "dword", 0, "struct*", $res1[4], "dword", $ULW_ALPHA) ;display bitmap on screen
                Sleep($delay)
            Next
        Case Else
            For $a = $iTrans To 0 Step -$speed
                DllStructSetData($res1[4], "Alpha", $a)
                DllCall("user32.dll", "bool", "UpdateLayeredWindow", "hwnd", $res1[0], "handle", $res1[1], "ptr", 0, "struct*", $res1[5], "handle", $res1[3], "struct*", $res1[6], "dword", 0, "struct*", $res1[4], "dword", $ULW_ALPHA) ;display bitmap on screen
                Sleep($delay)
            Next
    EndSwitch
EndFunc   ;==>_FadeIn
Edited by nullschritt

Share this post


Link to post
Share on other sites

Okay Now I've managed to do it by registering an event that updates the positions

Share this post


Link to post
Share on other sites

Hi nullschritt. I was not able to get your code to work. Only a big gray window appeared. I'd like to learn from what you were able to accomplish. Thank you.

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  
Followers 0