Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

MsgBox Function


  • Please log in to reply
No replies to this topic
sjcaldwell
  • Members
  • 4 posts
  • Last active: Dec 17 2011 03:06 PM
  • Joined: 23 Sep 2011
Hi. I'm new to AutoHotKey. Really didn't care for the native MsgBox so I wrote a function that calls the DLL. It can also be used with RunWait and parameters. Also if you use 0xa0 as the flag, you won't hear a beep but the side affect is you also don't get the icons. It uses the windows MessageBox function. I've only tested with Win XP.

Again new to this so let me know if you see room for improvement.

/*
Title: MsgBox.ahk
Description: MsgBox function implemented as a dll call as opposed to AHK command
Written by: Steven J. Caldwell
Last Update: 23-Sep-2011
Other Notes: Added MB_QUIETMASK for nobeep however that overrides the ICON flags when used
Found this little trick in AutoIT forum based on behaviour of Microsoft WinAPI MessageBox which this
function uses and calls as a DLL
*/

MB_OK := 0x0
MB_OKCANCEL := 0x1
MB_ABORTRETRYIGNORE := 0x2
MB_YESNOCANCEL := 0x3
MB_YESNO := 0x4
MB_RETRYCANCEL := 0x5

MB_ICONHAND := 0x10
MB_ICONQUESTION := 0x20
MB_ICONEXCLAMATION := 0x30
MB_ICONASTERISK := 0x40


MB_ICONINFORMATION := MB_ICONASTERISK
MB_ICONSTOP := MB_ICONHAND

; Default Buttons
MB_DEFBUTTON1 := 0x0
MB_DEFBUTTON2 := 0x100
MB_DEFBUTTON3 := 0x200

; Modal

MB_APPLMODAL := 0x0
MB_SYSTEMMODAL := 0x1000
MB_TASKMODAL := 0x2000

MB_NOFOCUS := 0x8000
MB_SETFOREGROUND := 0x10000
MB_DEFAULT_DESKTOP_ONLY := 0x20000

MB_TYPEMASK := 0xF
MB_ICONMASK := 0xF0
MB_DEFMASK := 0xF00
MB_MODEMASK := 0x3000
MB_MISCMASK := 0xC000
MB_QUIETMASK := 0xA0 ; I added this one

; Return valudes
; From http://msdn.microsoft.com/en-us/library/ms645505%28VS.85%29.aspx

MB_RET_ABORT := 3 ; Abort
MB_RET_CANCEL := 2 ; Cancel
MB_CONTINUE := 11 ; Continue [v1.0.44.08+] 
MB_IGNORE := 5 ; Ignore
MB_NO := 7 ; No
MB_OK := 1 ; OK
MB_RETRY := 4 ; Retry 
MB_TRY_AGAIN := 11 ; TryAgain [v1.0.44.08+]
MB_YES := 6 ; Yes
MB_TIMEOUT := 12
; Timeout (that is, the word "timeout" is present if the MsgBox timed out)

; Set up an Array for returns
MB_RETVAL%MB_OK% :=  "OK"
MB_RETVAL%MB_RET_CANCEL% := "Cancel"
MB_RETVAL%MB_RET_ABORT% := "Abort"
MB_RETVAL%MB_RETRY% := "Retry"
MB_RETVAL%MB_IGNORE% := "Ignore"
MB_RETVAL%MB_YES% := "Yes"
MB_RETVAL%MB_NO% := "No"
MB_RETVAL%MB_CONTINUE% := "TryAgain"
MB_RETVAL%MB_TIMEOUT% := "Timeout"
/* ; For testing
Loop 12 ; Debug
{
mesg := MB_RETVAL%A_Index% . "`n"
msgwindow(mesg,"AHK_Messages","MessageBox Test Loop")
} 
*/

hwnd := 0 ; owning window id

; Definitions End - Code starts

; Command Line Options go here Modify as necessary
; Uncomment this section if you will be using arguments

; MsgBox, A_ScriptName = %A_ScriptName%
CallingScriptName := A_ScriptName 
MsgBoxScriptName := "MsgBox.ahk" ; Change this to the file name given to this file or it won't work
if  (CallingScriptName == MsgBoxScriptName) ; if it is in the include file we will assume it is a function it will be different than this file name
{
RunCommand := TRUE
}
; ExitApp
if 0 < 4  
{
	if  (RunCommand) ; If as an #include flie don't balk 
	{
	MsgBox 0,Usage,Usage is:`n`nMsgBox FLAG TITLE TEXT TIMEOUT`n`nSet TIMOUT to 0 for no timeout`n`nOr`n`nsimply #include MsgBox.ahk and do it as a function call`n`nMsgbox(FLAG,TITLE,TEXT,TIMEOUT)
	; MsgBox 0,Info, Currently run as %1% %2% %3% %4%
	ExitApp
	}
}
else
{ ; This is run with the AHK "Run or RunWait" Command or from a command line
; MsgBox 0,Info, Currently run as %1% %2% %3% %4%
a = %1% 
b = %2%
c = %3%
d = %4%
MsgBox(a,b,c,d)
}

;Start Code below this line


MsgBox(_mbflag,_mbtitle,_mbtext,_mbtimeout)
{
global ; if I don't do this the subroutine does not regocnize the variables

if (_mbtimeout > 0)
{
	_mbtimeout *= -1000
	SetTimer, _mbtimeoutlabel , %_mbtimeout% 
	; MsgBox, , Timeout set
}
WhichButton := DllCall("MessageBox", "int", hwnd, "str", _mbtext, "str", _mbtitle, "int", _mbflag)


WinWaitClose %_mbtitle%,%_mbtext% ; Don't continue until the mesage box has closed
if (mb_timeoutflag == 1)
{
if (RunCommand)
	{
	ExitApp , %MB_TIMEOUT%
	}
else
	{
	return MB_RETVAL%MB_TIMEOUT%
	}
}
else ; if (mb_timeoutflag == 1)
{
if (RunCommand)
	{
	ExitApp, %WhichButton%
	}
else
	{
	return MB_RETVAL%WhichButton%
	}
} ; if (mb_timeoutflag == 1)

; return "Timeout"
_mbtimeoutlabel: ; This needs to be unique in all applications
WinWaitActive %_mbtitle%,%_mbtext%,,2
if ErrorLevel
{
    MsgBox, WinWait timed out.
    return
}
WinGet,_mbid ,ID,%_mbtitle%,%_mbtext%
WinActivate, ahk_id %_mbid%
Send {Enter} ; WinKill or WinClose don't work so we have to send the default and the change it later

mb_timeoutflag := 1
return 
}

; Test of code

flag :=   MB_DEFBUTTON1 | MB_ICONHAND | MB_ABORTRETRYIGNORE | MB_QUIETMASK
/*
msgbox flag = %flag% MB_DEFBUTTON1 = %MB_DEFBUTTON1% MB_ICONHAND = %MB_ICONHAND% MB_ABORTRETRYIGNORE = %MB_ABORTRETRYIGNORE%
ExitApp
*/
/*
MsgBoxRetVal := MsgBox(flag,"Test Title", "Test Text",2)
 ;MsgBox , 0, ,MsgBoxRetVal = %MsgBoxRetVal%,2
; MsgBox, 2, Test AHK MsgBox,Test, 2
flag :=   MB_DEFBUTTON1 | MB_ICONINFORMATION | MB_OK 
MsgBox(flag,"Return Value", MsgBoxRetVal,5)
*/
[/code]