jballi
Joined: 01 Oct 2005 Posts: 582 Location: Texas, USA
|
Posted: Sat Jul 07, 2007 3:12 am Post subject: PopupXY v0.3 - Function to calculate X/Y of pop-up window |
|
|
Introduction
They say that necessity is the mother of invention. I needed a way of calculating the X/Y position of a pop-up window so that it would be centered relative to the parent window. I checked the forum and the documentation but couldn't find anything like it so I created a simple function to do it for me.
The Code
| Code: | ;-- v0.3
;-- Save as PopupXY.ahk
;
;*****************
;* *
;* PopupXY *
;* *
;*****************
;
;
; Description
; ===========
; When passed a parent and child window, this function calculates the center
; position for the child window relative to the parent window. If necessary,
; the calculated window positions are adjusted so that the child window will
; fit within the primary monitor work area.
;
;
;
; Parameters
; ==========
;
; Parameter Description
; --------- -----------
; p_Parent For the parent window, this parameter can contain
; either the GUI window number (from 1 to 99) or the
; window title. [Required]
;
; From the AHK documentation...
; The title or partial title of the window (the
; matching behavior is determined by
; SetTitleMatchMode). To use a window class, specify
; ahk_class ExactClassName (shown by Window Spy). To
; use a process identifier (PID), specify ahk_pid
; %VarContainingPID%. To use a window's unique
; ID number, specify ahk_id %VarContainingID%.
;
;
; p_Child For the child (pop-up) window, this parameter can
; contain either the GUI window number (from 1 to 99)
; or the window title. [Required] See the
; p_Parent description for more information.
;
;
; p_ChildX The calculated "X" position for the child window is
; returned in this variable. [Required] This
; parameter must contain a variable name.
;
;
; p_ChildY The calculated "Y" position for the child window is
; returned in this variable. [Required] This
; parameter must contain a variable name.
;
;
;
; Return Codes
; ============
; The function does not return a value but the p_ChildX and p_ChildY variables
; are updated to contain the calculated X/Y values. If the parent or child
; windows cannot be found, these variables are set to 0.
;
;
;
; Calls To Other Functions
; ========================
; (None)
;
;
;-------------------------------------------------------------------------------
PopupXY(p_Parent,p_Child,ByRef p_ChildX,ByRef p_ChildY)
{
;[===============]
;[ Environment ]
;[===============]
l_DetectHiddenWindows:=A_DetectHiddenWindows
DetectHiddenWindows On
SysGet l_MonitorWorkArea,MonitorWorkArea
p_ChildX=0
p_ChildY=0
;[=================]
;[ Parent window ]
;[=================]
;-- If necessary, collect hWnd
if p_Parent is Integer
if p_Parent between 1 and 99
{
gui %p_Parent%:+LastFoundExist
IfWinExist
{
gui %p_Parent%:+LastFound
p_Parent:="ahk_id " . WinExist()
}
}
;-- Collect position/size
WinGetPos l_ParentX,l_ParentY,l_ParentW,l_ParentH,%p_Parent%
;-- Anything found?
if l_ParentX is Space
return
;[================]
;[ Child window ]
;[================]
;-- If necessary, collect hWnd
if p_Child is Integer
if p_Child between 1 and 99
{
gui %p_Child%:+LastFoundExist
IfWinExist
{
gui %p_Child%:+LastFound
p_Child:="ahk_id " . WinExist()
}
}
;-- Collect position/size
WinGetPos,,,l_ChildW,l_ChildH,%p_Child%
;-- Anything found?
if l_ChildW is Space
return
;[=======================]
;[ Calculate child X/Y ]
;[=======================]
p_ChildX:=round(l_ParentX+((l_ParentW-l_ChildW)/2))
p_ChildY:=round(l_ParentY+((l_ParentH-l_ChildH)/2))
;-- Adjust if necessary
if (p_ChildX<l_MonitorWorkAreaLeft)
p_ChildX:=l_MonitorWorkAreaLeft
if (p_ChildY<l_MonitorWorkAreaTop)
p_ChildY:=l_MonitorWorkAreaTop
l_MaximumX:=l_MonitorWorkAreaRight-l_ChildW
if (p_ChildX>l_MaximumX)
p_ChildX:=l_MaximumX
l_MaximumY:=l_MonitorWorkAreaBottom-l_ChildH
if (p_ChildY>l_MaximumY)
p_ChildY:=l_MaximumY
;[=====================]
;[ Reset environment ]
;[=====================]
DetectHiddenWindows %l_DetectHiddenWindows%
;[====================]
;[ Return to sender ]
;[====================]
return
}
|
Example Of Use
Warning: If the Notepad button is clicked, this script will modify the size of the Notepad window. No permanent damage...
| Code: | ;-- Initialize
DetectHiddenWindows On
SysGet MonitorWorkArea,MonitorWorkArea
;-- ParentGUI
gui +Resize -MaximizeBox -MinimizeBox
gui Margin,0,0
gui Add,Text, x0 h90 w400 Center
,`nPopupXY Test`nIf desired, you can move/resize this window before clicking a button.
gui Add,Button,x0 h30 w150 gPopup1,Popup 1
gui Add,Button,x0 h30 w150 gPopup2,Popup 2
gui Add,Button,x0 h30 w150 gPopup3,Popup 3
gui Add,Button,x0 h30 w150 gCalculator,Calculator
gui Add,Button,x0 h30 w150 gNotepad,Notepad
gui Add,Button,x0 h30 w150 gMsgBox,MsgBox
gui Add,Button,x0 h30 w150 gReload,Reload script...
;-- Render, position, and show
gui Show,Hide,ParentGUI ;-- Render but don't show
WinGetPos,,,ParentW,ParentH,ParentGUI
Random PosX,MonitorWorkAreaLeft,% MonitorWorkAreaRight-ParentW
Random PosY,MonitorWorkAreaTop,% MonitorWorkAreaBottom-ParentH
gui Show,x%PosX% y%PosY%
return
Popup1:
gui 1:+Disabled
gui 2:+Owner1
gui 2:-MinimizeBox
gui 2:Add,Edit,r1 w200
gui 2:Show,Hide,Popup1 ;-- Render but don't show
PopupXY(1,2,PosX,PosY)
gui 2:Show,x%PosX% y%PosY% ;-- Show in new position
return
Popup2:
gui 1:+Disabled
gui 3:+Owner1
gui 3:-MinimizeBox
gui 3:Add,Edit,r5 w500
gui 3:Show,Hide,Popup2 ;-- Render but don't show
PopupXY("ParentGUI",3,PosX,PosY)
gui 3:Show,x%PosX% y%PosY% ;-- Show in new position
return
Popup3:
gui 1:+Disabled
gui 4:+Owner1
gui 4:-MinimizeBox
gui 4:Add,Edit,r25 w200
gui 4:Show,Hide,Popup3 ;-- Render but don't show
PopupXY(1,"Popup3",PosX,PosY)
gui 4:Show,x%PosX% y%PosY% ;-- Show in new position
return
Calculator:
;-- Note: Calc doesn't obey the hide command on startup but for other programs
; you should be able to run the program hidden, move it, and then show it in
; the correct location. Although not the best example, see the Notepad code
; below.
;
run calc.exe,,,CalcPID
WinWait ahk_pid %CalcPID%,,2
if ErrorLevel
return
PopupXY(1,"ahk_pid " . CalcPID,PosX,PosY)
WinMove ahk_pid %CalcPID%,,%PosX%,%PosY%
WinWaitClose ahk_pid %CalcPID%
return
Notepad:
run Notepad.exe,,Hide,NotepadPID
WinWait ahk_pid %NotepadPID%,,2
if ErrorLevel
return
WinMove ahk_pid %NotepadPID%,,,,300,150
PopupXY(1,"ahk_pid " . NotepadPID,PosX,PosY)
WinMove ahk_pid %NotepadPID%,,%PosX%,%PosY%
WinShow ahk_pid %NotepadPID%
return
MsgBox:
SetTimer MsgBox2,50
Gui +OwnDialogs ;-- This makes the MsgBox window modal
msgbox This is just a test message...
return
MsgBox2:
;-- Note: This may not the most eloquent way of repositioning a Msgbox window
; but it does work!
;
SetTimer MsgBox2,Off
MsgBox_hWnd:=WinExist("A")
PopupXY(1,"ahk_id " . MsgBox_hWnd,PosX,PosY)
WinMove ahk_id %MsgBox_hWnd%,,%PosX%,%PosY%
return
Reload:
Reload
return
GUIEscape:
GuiClose:
ExitApp
2GUIEscape:
2GUICLose:
3GUIEscape:
3GUIClose:
4GUIEscape:
4GUIClose:
gui 1:-Disabled
gui Destroy
return
#include PopupXY.ahk
|
Final Thoughts
I named the function PopupXY for lack of better name. If you can think of a better name, let me know.
I hope that someone finds this useful.
---------------------------------------------------------------------------
v0.1
First draft.
v0.2
Updated example.
v0.3
p_ParentWinTitle and p_ChildWinTitle parameters renamed to p_Parent and p_Child respectively. These parameters can now contain a GUI window number (1 to 99) as well as a window title, See the documentation for more information.
Updated example.
|
|