MsgBox() for V1

Post your working scripts, libraries and tools for AHK v1.1 and older
User avatar
SKAN
Posts: 1551
Joined: 29 Sep 2013, 16:58

MsgBox() for V1

08 Nov 2020, 13:40

A wrapper function that mimics V2 MsgBox()
 
The function
 

Code: Select all

MsgBox( Text:="", Title:="", Options:=0 ) {  ; v0.63 by SKAN on D3AS/D3AS @ tiny.cc/msgbox
Local                                        ;    MsgBox() requires AutoHotkey 1.1.33.02 +

  UT := 0, Opts := (A_Space . Options)
  Loop, Parse, % Trim(Options), %A_Space%
  Switch (A_LoopField)
  {
      Default:                                    UT := (UT | Format("{:d}", A_LoopField))
      Case          "O",   "OK"                                 :  UT := (UT &~ 0xF) | 0x0
      Case 0x1,     "OC",  "O/C",   "OKCancel"                  :  UT := (UT &~ 0xF) | 0x1
      Case 0x2,     "ARI", "A/R/I", "AbortRetryIgnore"          :  UT := (UT &~ 0xF) | 0x2
      Case 0x3,     "YNC", "Y/N/C", "YesNoCancel"               :  UT := (UT &~ 0xF) | 0x3
      Case 0x4,     "YN",  "Y/N",   "YesNo"                     :  UT := (UT &~ 0xF) | 0x4
      Case 0x5,     "RC",  "R/C",   "RetryCancel"               :  UT := (UT &~ 0xF) | 0x5
      Case 0x6,     "CTC", "C/T/C", "CancelTryAgainContinue"    :  UT := (UT &~ 0xF) | 0x6
      Case 0x00010, "Iconx"                             :  UT := (UT &~    0x60) |    0x10
      Case 0x00020, "Icon?"                             :  UT := (UT &~    0x50) |    0x20
      Case 0x00030, "Icon!"                             :  UT := (UT &~    0x40) |    0x30
      Case 0x00040, "Iconi"                             :  UT := (UT &~    0x30) |    0x40
      Case 0x00100, "Default2"                          :  UT := (UT &~   0x200) |   0x100
      Case 0x00200, "Default3"                          :  UT := (UT &~   0x100) |   0x200
      Case 0x00300, "Default4"                          :  UT := (UT &~   0x000) |   0x300
      Case 0x01000, "+Sys",  "+SystemModal"             :  UT := (UT &~ 0x42000) | 0x01000
      Case 0x02000, "+Task", "+TaskModal"               :  UT := (UT &~ 0x41000) | 0x02000
      Case 0x40000, "+Top",  "+Topmost", "+AlwaysOnTop" :  UT := (UT &~ 0x03000) | 0x40000
  }

  Hwnd := ( (f := InStr(Opts, " Owner",, 0)) ? Format("{:d}", SubStr(Opts, f+6)) : 0 )
  DetectHiddenWindows, % ("On", DHW := A_DetectHiddenWindows)
  SetWinDelay, % (0, SWD := A_WinDelay)
  SplashImage, 8:, x0 y0 w0 h0 B Hide,,, OwnDialogTest
  WinWait, OwnDialogTest ahk_class AutoHotkey2,, 10
  hOwner := DllCall("GetWindow", "Ptr",WinExist(), "Int",4 ,"Ptr")          ; GW_OWNER = 4
  SplashImage, 8:Off
  Hwnd := (hOwner!=A_ScriptHwnd) ? hOwner : WinExist("ahk_id" . Hwnd)
  SetWinDelay, %SWD%
  DetectHiddenWindows, %DHW%

  Res := DllCall("User32.dll\MessageBoxTimeout", "Ptr",Hwnd
     ,"Str",Text  ? Text  : "Press OK to continue."
     ,"Str",Title ? Title : A_ScriptName,   "Int",UT,   "Short",0
     ,"Int",( (f:=InStr(Opts, " T",, 0)) ? Format("{:d}", SubStr(Opts, f+2)) : 0) * 1000 )

Return { 1:"OK", 2:"Cancel", 3:"Abort", 4:"Retry", 5:"Ignore", 6:"Yes", 7:"No"
     , 10:"TryAgain", 11:"Continue", 32000:"Timeout" }[Res]
}
My Scripts and Functions: V1  V2
hasantr
Posts: 933
Joined: 05 Apr 2016, 14:18
Location: İstanbul

Re: MsgBox() for V1

08 Nov 2020, 14:20

This is great. It will be necessary to rework a few old studies. :) Thank you.
User avatar
SKAN
Posts: 1551
Joined: 29 Sep 2013, 16:58

Re: MsgBox() for V1

08 Nov 2020, 23:58

@hasantr :thumbup: :)

Note: Lines 29 to 36 can be removed if support for +OwnDialogs isn't needed.
User avatar
watagan
Posts: 80
Joined: 03 Nov 2020, 05:17

Re: MsgBox() for V1

10 Nov 2020, 19:53

Thanks again SKAN :)
Wouldn't it be great if message boxes had an option to show centered on owner GUI?
Oh well, you can't ask much from Windows.
User avatar
boiler
Posts: 16962
Joined: 21 Dec 2014, 02:44

Re: MsgBox() for V1

10 Nov 2020, 20:18

watagan wrote:
10 Nov 2020, 19:53
Wouldn't it be great if message boxes had an option to show centered on owner GUI?
Oh well, you can't ask much from Windows.
No, but you can ask a lot from AHK:

Code: Select all

Gui, +HwndGuiHwnd
Gui, Show, x50 y50 w300 h200, My GUI
MsgBox("This is my MsgBox", "My MsgBox",, GuiHwnd)
ExitApp
Return

MsgBox( Text:="", Title:="", Options:=0, CenterOver:=0 ) {  ; v0.63 by SKAN on D3AS/D3AS @ tiny.cc/msgbox
Local                                        ;    MsgBox() requires AutoHotkey 1.1.33.02 +

  UT := 0, Opts := (A_Space . Options)
  Loop, Parse, % Trim(Options), %A_Space%
  Switch (A_LoopField)
  {
      Default:                                    UT := (UT | Format("{:d}", A_LoopField))
      Case          "O",   "OK"                                 :  UT := (UT &~ 0xF) | 0x0
      Case 0x1,     "OC",  "O/C",   "OKCancel"                  :  UT := (UT &~ 0xF) | 0x1
      Case 0x2,     "ARI", "A/R/I", "AbortRetryIgnore"          :  UT := (UT &~ 0xF) | 0x2
      Case 0x3,     "YNC", "Y/N/C", "YesNoCancel"               :  UT := (UT &~ 0xF) | 0x3
      Case 0x4,     "YN",  "Y/N",   "YesNo"                     :  UT := (UT &~ 0xF) | 0x4
      Case 0x5,     "RC",  "R/C",   "RetryCancel"               :  UT := (UT &~ 0xF) | 0x5
      Case 0x6,     "CTC", "C/T/C", "CancelTryAgainContinue"    :  UT := (UT &~ 0xF) | 0x6
      Case 0x00010, "Iconx"                             :  UT := (UT &~    0x60) |    0x10
      Case 0x00020, "Icon?"                             :  UT := (UT &~    0x50) |    0x20
      Case 0x00030, "Icon!"                             :  UT := (UT &~    0x40) |    0x30
      Case 0x00040, "Iconi"                             :  UT := (UT &~    0x30) |    0x40
      Case 0x00100, "Default2"                          :  UT := (UT &~   0x200) |   0x100
      Case 0x00200, "Default3"                          :  UT := (UT &~   0x100) |   0x200
      Case 0x00300, "Default4"                          :  UT := (UT &~   0x000) |   0x300
      Case 0x01000, "+Sys",  "+SystemModal"             :  UT := (UT &~ 0x42000) | 0x01000
      Case 0x02000, "+Task", "+TaskModal"               :  UT := (UT &~ 0x41000) | 0x02000
      Case 0x40000, "+Top",  "+Topmost", "+AlwaysOnTop" :  UT := (UT &~ 0x03000) | 0x40000
  }

  Hwnd := ( (f := InStr(Opts, " Owner",, 0)) ? Format("{:d}", SubStr(Opts, f+6)) : 0 )
  DetectHiddenWindows, % ("On", DHW := A_DetectHiddenWindows)
  SetWinDelay, % (0, SWD := A_WinDelay)
  SplashImage, 8:, x0 y0 w0 h0 B Hide,,, OwnDialogTest
  WinWait, OwnDialogTest ahk_class AutoHotkey2,, 10
  hOwner := DllCall("GetWindow", "Ptr",WinExist(), "Int",4 ,"Ptr")          ; GW_OWNER = 4
  SplashImage, 8:Off
  Hwnd := (hOwner!=A_ScriptHwnd) ? hOwner : WinExist("ahk_id" . Hwnd)
  SetWinDelay, %SWD%
  DetectHiddenWindows, %DHW%

  if CenterOver
    SetTimer, MoveMsgBox, -50
  Res := DllCall("User32.dll\MessageBoxTimeout", "Ptr",Hwnd
     ,"Str",Text  ? Text  : "Press OK to continue."
     ,"Str",Title ? Title : A_ScriptName,   "Int",UT,   "Short",0
     ,"Int",( (f:=InStr(Opts, " T",, 0)) ? Format("{:d}", SubStr(Opts, f+2)) : 0) * 1000 )

Return { 1:"OK", 2:"Cancel", 3:"Abort", 4:"Retry", 5:"Ignore", 6:"Yes", 7:"No"
     , 10:"TryAgain", 11:"Continue", 32000:"Timeout" }[Res]

  MoveMsgBox:
    WinGetPos, WinX, WinY, WinW, WinH, ahk_id %CenterOver%
	WinGetPos,,, MsgW, MsgH, A
	WinMove, A,, WinX + (WinW - MsgW) / 2, WinY + (WinH - MsgH) / 2
  Return
}
User avatar
watagan
Posts: 80
Joined: 03 Nov 2020, 05:17

Re: MsgBox() for V1

10 Nov 2020, 20:46

@boiler

OwnDialog in both SKAN's function and your example didn't work. After studying the function and with some modification I got it working by passing GUI ID as an extra param.
Regarding centering message box, WinMove is just a workaround and bound to fail at some point. A preprogrammed message box would be ideal. Wishful thinking.
User avatar
boiler
Posts: 16962
Joined: 21 Dec 2014, 02:44

Re: MsgBox() for V1

10 Nov 2020, 20:58

watagan wrote:
10 Nov 2020, 20:46
Regarding centering message box, WinMove is just a workaround and bound to fail at some point.
Why is it bound to fail?
User avatar
watagan
Posts: 80
Joined: 03 Nov 2020, 05:17

Re: MsgBox() for V1

10 Nov 2020, 21:06

@boiler
Because it's a workaround.
Getting active (A) window info is a desperate solution. It reminds me of AHK basic days.
Think of a situation where another window suddenly pops up at the exact moment.
You want to try and always work with handles.
Also, waiting for it to appear then moving it is not elegant.
User avatar
boiler
Posts: 16962
Joined: 21 Dec 2014, 02:44

Re: MsgBox() for V1

10 Nov 2020, 21:25

You don’t have to use the active window. You can identify it using the title, window class, and process. I agree it’s not elegant to move it after it appears. Just offering an approach.
User avatar
SKAN
Posts: 1551
Joined: 29 Sep 2013, 16:58

Re: MsgBox() for V1

10 Nov 2020, 23:31

watagan wrote:
10 Nov 2020, 20:46
OwnDialog in both SKAN's function and your example didn't work. After studying the function and with some modification I got it working by passing GUI ID as an extra param.
Can you post a snippet? The following works fine for me:

Code: Select all

#NoEnv
#Warn
#SingleInstance, Force

Gui +OwnDialogs
Gui, Show, x100 y100 w400 h200
MsgBox("You can't close the GUI`nunless this Message is dismissed")
Return

GuiClose:
 ExitApp
User avatar
watagan
Posts: 80
Joined: 03 Nov 2020, 05:17

Re: MsgBox() for V1

11 Nov 2020, 00:27

This wouldn't work. Seems like you got an issue if GUI has a name.

Code: Select all

Gui, SKAN: Show, x100 y100 w400 h200
User avatar
SKAN
Posts: 1551
Joined: 29 Sep 2013, 16:58

Re: MsgBox() for V1

11 Nov 2020, 01:03

watagan wrote:
11 Nov 2020, 00:27
This wouldn't work. Seems like you got an issue if GUI has a name.

Code: Select all

Gui, SKAN: Show, x100 y100 w400 h200
The following works :!:
 

Code: Select all

#NoEnv
#Warn
#SingleInstance, Force

Gui, SKAN: +OwnDialogs
Gui, SKAN: Show, x100 y100 w400 h200
MsgBox("You can't close the GUI`nunless this Message is dismissed")
Return

SKANGuiClose:
 ExitApp
burque505
Posts: 1736
Joined: 22 Jan 2017, 19:37

Re: MsgBox() for V1

11 Nov 2020, 12:44

@SKAN, thanks as always for another great contribution. Working fine for me on Win7 SP1 64-bit.
Regards,
burque505
User avatar
SKAN
Posts: 1551
Joined: 29 Sep 2013, 16:58

Re: MsgBox() for V1

11 Nov 2020, 23:38

burque505 wrote:
11 Nov 2020, 12:44
@SKAN, thanks as always for another great contribution. Working fine for me on Win7 SP1 64-bit.
Regards,
burque505
:thumbup: :)

I miss Win7 badly. Unable to install it in my newly assembled AMD Ryzen HTPC :(
User avatar
rommmcek
Posts: 1475
Joined: 15 Aug 2014, 15:18

Re: MsgBox() for V1

12 Nov 2020, 17:27

watagan wrote:
10 Nov 2020, 19:53
Wouldn't it be great if message boxes had an option to show centered on owner GUI?
Here is elaborated example for Ahk native MsgBox (based on boiler's code):
Spoiler
and the one for SKAN's MsgBox():

Code: Select all

#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
; #Warn  ; Enable warnings to assist with detecting common errors.
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.

SetBatchLines -1
global hwnd, GuiHwnd, wasActive

HookProcAdr:= RegisterCallback( "HookProc", "F" )
hWinEventHook:= SetWinEventHook( 0x8002, 0x8002, 0, HookProcAdr, 0, 0, 0) ; 0x8002 show events 

OnExit, HandleExit

Gui, +HwndGuiHwnd
Gui, Add, Button, +Default gBtn, MsgBox
Gui, Show, x50 y50 w300 h200, My GUI
Return

Btn:
    MsgBox("This is my MsgBox", "My MsgBox")
Return

GuiClose:
GuiEscape:
HandleExit:
    UnhookWinEvent()
    ExitApp

MsgBox( Text:="", Title:="", Options:=0 ) {  ; v0.63 by SKAN on D3AS/D3AS @ tiny.cc/msgbox
Local                                        ;    MsgBox() requires AutoHotkey 1.1.33.02 +

  UT := 0, Opts := (A_Space . Options)
  Loop, Parse, % Trim(Options), %A_Space%
  Switch (A_LoopField)
  {
      Default:                                    UT := (UT | Format("{:d}", A_LoopField))
      Case          "O",   "OK"                                 :  UT := (UT &~ 0xF) | 0x0
      Case 0x1,     "OC",  "O/C",   "OKCancel"                  :  UT := (UT &~ 0xF) | 0x1
      Case 0x2,     "ARI", "A/R/I", "AbortRetryIgnore"          :  UT := (UT &~ 0xF) | 0x2
      Case 0x3,     "YNC", "Y/N/C", "YesNoCancel"               :  UT := (UT &~ 0xF) | 0x3
      Case 0x4,     "YN",  "Y/N",   "YesNo"                     :  UT := (UT &~ 0xF) | 0x4
      Case 0x5,     "RC",  "R/C",   "RetryCancel"               :  UT := (UT &~ 0xF) | 0x5
      Case 0x6,     "CTC", "C/T/C", "CancelTryAgainContinue"    :  UT := (UT &~ 0xF) | 0x6
      Case 0x00010, "Iconx"                             :  UT := (UT &~    0x60) |    0x10
      Case 0x00020, "Icon?"                             :  UT := (UT &~    0x50) |    0x20
      Case 0x00030, "Icon!"                             :  UT := (UT &~    0x40) |    0x30
      Case 0x00040, "Iconi"                             :  UT := (UT &~    0x30) |    0x40
      Case 0x00100, "Default2"                          :  UT := (UT &~   0x200) |   0x100
      Case 0x00200, "Default3"                          :  UT := (UT &~   0x100) |   0x200
      Case 0x00300, "Default4"                          :  UT := (UT &~   0x000) |   0x300
      Case 0x01000, "+Sys",  "+SystemModal"             :  UT := (UT &~ 0x42000) | 0x01000
      Case 0x02000, "+Task", "+TaskModal"               :  UT := (UT &~ 0x41000) | 0x02000
      Case 0x40000, "+Top",  "+Topmost", "+AlwaysOnTop" :  UT := (UT &~ 0x03000) | 0x40000
  }

  Hwnd := ( (f := InStr(Opts, " Owner",, 0)) ? Format("{:d}", SubStr(Opts, f+6)) : 0 )
  DetectHiddenWindows, % ("On", DHW := A_DetectHiddenWindows)
  SetWinDelay, % (0, SWD := A_WinDelay)
  SplashImage, 8:, x0 y0 w0 h0 B Hide,,, OwnDialogTest
  WinWait, OwnDialogTest ahk_class AutoHotkey2,, 10
  hOwner := DllCall("GetWindow", "Ptr",WinExist(), "Int",4 ,"Ptr")          ; GW_OWNER = 4
  SplashImage, 8:Off
  Hwnd := (hOwner!=A_ScriptHwnd) ? hOwner : WinExist("ahk_id" . Hwnd)
  SetWinDelay, %SWD%
  DetectHiddenWindows, %DHW%

  Res := DllCall("User32.dll\MessageBoxTimeout", "Ptr",Hwnd
     ,"Str",Text  ? Text  : "Press OK to continue."
     ,"Str",Title ? Title : A_ScriptName,   "Int",UT,   "Short",0
     ,"Int",( (f:=InStr(Opts, " T",, 0)) ? Format("{:d}", SubStr(Opts, f+2)) : 0) * 1000 )

Return { 1:"OK", 2:"Cancel", 3:"Abort", 4:"Retry", 5:"Ignore", 6:"Yes", 7:"No"
     , 10:"TryAgain", 11:"Continue", 32000:"Timeout" }[Res]
}

HookProc( hWinEventHook, Event, hWnd, idObject, idChild, dwEventThread, dwmsEventTime ) {
    WinGetClass, class, ahk_id %hWnd%
    If (class = "#32770")	{
        WinGetPos, WinX, WinY, WinW, WinH, ahk_id %GuiHwnd%
        DetectHiddenWindows, % ("On", DHW:= A_DetectHiddenWindows), wasActive:= 1
        WinGetPos,,, MsgW, MsgH, My MsgBox ahk_class #32770
        WinMove, My MsgBox,, WinX + (WinW - MsgW) / 2, WinY + (WinH - MsgH) / 2
        DetectHiddenWindows, % DHW
    } 
}

SetWinEventHook(eventMin, eventMax, hmodWinEventProc, lpfnWinEventProc, idProcess, idThread, dwFlags) {
	DllCall("CoInitialize", Uint, 0)
	return DllCall("SetWinEventHook", UInt,eventMin, UInt,eventMax, Ptr,hmodWinEventProc, Ptr,lpfnWinEventProc
                                    , UInt,idProcess, UInt,idThread, UInt,dwFlags, Ptr)
}

UnhookWinEvent() {
	Global
    DllCall( "UnhookWinEvent", Ptr, hWinEventHook )
    if wasActive ; Don't copy me I'm not sure if it's ok!
        DllCall("GlobalUnlock", "Ptr",&HookProcAdr )
      , DllCall("GlobalFree", "Ptr",&HookProcAdr ) ; free up allocated memory for RegisterCallback
    VarSetCapacity(HookProcAdr, 0) ; free up variable ???
}
This one is probably not memory tight (I just don't like to wait seconds to exit).

@SKAN: I copy-pasted one your lines where you in turn used my "Extended parameters", if I'm not wrong.
User avatar
SKAN
Posts: 1551
Joined: 29 Sep 2013, 16:58

Re: MsgBox() for V1

12 Nov 2020, 18:11

rommmcek wrote: @SKAN: I copy-pasted one your lines where you in turn used my "Extended parameters", if I'm not wrong.
Not really. Sean was using it a decade ago.
I recently started using it, of course before you. :P
IIUC, this feature is available from AutoHotkey v1.0.46 - November 29, 2006 when "multiple variable declaration on same line" feature was introduced.
User avatar
rommmcek
Posts: 1475
Joined: 15 Aug 2014, 15:18

Re: MsgBox() for V1

12 Nov 2020, 19:26

Thanks for the clarification, so you published it exactly one month before me (Line ~108). But it's pretty rare, I wonder why!
User avatar
SKAN
Posts: 1551
Joined: 29 Sep 2013, 16:58

Re: MsgBox() for V1

12 Nov 2020, 20:03

rommmcek wrote:
12 Nov 2020, 19:26
it's pretty rare, I wonder why!
Actually, it didn't appeal to me when Sean used to do it like
DllCall(...) ? DllCall(...), DllCall(...DllCall(...)), DllCall(...) : DllCall(...), DllCall(...)
that too without any enclosing parenthesis.

I was using this feature only with Return statement of a function and then stopped that too as it wasn't working properly in AHK V2.
User avatar
rommmcek
Posts: 1475
Joined: 15 Aug 2014, 15:18

Re: MsgBox() for V1

12 Nov 2020, 20:36

Ahk v2.0 considers the last concatenated parameter as the "native" one and this works in all "expressions". I tested the return right now and returned value is as expected, however all preceding "parameters" are not evaluated (are ignored indeed, but only for return AFAIK).

Return to “Scripts and Functions (v1)”

Who is online

Users browsing this forum: No registered users and 126 guests