AHK if/else of output from Custom Message Box Function - if-statement

I've been trying to create a script that displays message boxes conditioned on the output from another customized message box with more than 3 options.
The custom functions are taken form this thread http://www.autohotkey.com/board/topic/29570-function-custom-msgbox-custom-buttons/page-2
I've tried both the CMsgbox and the MsgBoxV2 functions, running into the same problem. The Message "IT WORKED!" testing with if(condition) will always appear regardless of whether pressing any of the Sym|&Go|&C options, and the message "worked" will never appear regardless of actually pressing C, In other words no specificity or sensitivity regarding variable testing.
!o::
var := MsgBoxV2("Question11","Hi, what's up??","Sym|Go|C","24")
Msgbox 4,, You Pressed %var%
if (%var% = C)
{
Msgbox 4,, IT WORKED!
}
IfEqual, %var%,C
{
Msgbox 4,, worked
}
return
!e::
var := CMsgbox( "s", "d", "*&Sym|&Go|&C","",1 )
Msgbox 4,, You Pressed %var%
if (%var% = C)
{
Msgbox 4,, IT WORKED!
}
IfEqual, %var%,C
{
Msgbox 4,, worked
}
return
I don't know if this is because I've misunderstood the if/Else testing in ahk, or if the output from these custom functions cannot be tested, or both.
One solution would be to figure out what type of variable %var% is, but I've not been able to find a way to figure that out either.
Thanks for reading and hope you guys can help.
here are the custom message functions for testing.
MsgBoxV2(Title="",Text="",Buttons="",IconPath="",Timeout="",Font="",Schriftart="Arial",Colors="||",WindowStyles="",GuiNr = "")
{
Static Stat2,Stat1
Col1:="0xFFFFFF" ,Col2:="0x000000",Col3:="0x000000", Color1:="", Color2:="", Color3:=""
Loop, Parse, Colors,`|
Color%A_Index% := (A_Loopfield = "") ? Col%A_Index% : A_Loopfield
Loop 3
Color%A_Index% := (Color%A_Index% = "") ? Col%A_Index% : Color%A_Index%
if instr(WindowStyles,"+altsubmit")
{
AltSub := "1"
Stringreplace,WindowStyles,WindowStyles,`+altsubmit
}
Gui, Color, %Color1%,%Color1%
Gui, Font, s9
Gui, Font, %Font%, %Schriftart%
X := 20 ,Y := 20
ifexist, %IconPath%
{
Gui, Add, Picture, x20 y20 w32 h32, %IconPath%
X := 70 ,Y := 30
} else
if IconPath is integer
{
Gui, Add, Picture, x20 y20 icon%IconPath% w32 h32, %A_WinDir%\system32\shell32.dll
X := 70 ,Y := 30
}
Gui, Add, Text, x%X% y%Y% c%Color2% vStat2, %Text%
GuicontrolGet, Stat2, Pos
X2 = 10
Y2 := (Stat2Y + Stat2H < 52) ? 82 : Stat2Y + Stat2H + 30
HMax = 0
Gui, Add, Text, vStat1 +border -background
Loop, Parse, Buttons,|,`|
{
Gui, Add, Button, x%X2% w100 Y%Y2% gExButton , %A_Loopfield%
ButT%A_Index% := A_Loopfield
Guicontrolget, Button%A_Index%,Pos
if (HMax < Button%A_Index%H)
HMax := Button%A_Index%H
ABut := A_Index
X2 += 110
}
Loop %ABut%
Guicontrol, Move, Button%A_Index%,h%HMax%
Gui, %WindowStyles%
Gui, Show, Autosize Center,%Title%
Guicontrol, Move, Stat1, % "X-1 Y" Y2 - 10 " W" 1400 " h" 41 + HMax
Guicontrol, -Background +hidden, Stat1
Guicontrol, show, Stat1
Gui, +LastFound
WinGet, G_id
if Timeout !=
if Timeout is integer
settimer, Timeout, %Timeout%
Winwait, ahk_id %G_id%
retval = 0
while winexist("ahk_id " G_id)
sleep 100
if !AltSub
return ButT%retval%
else
return retval
Timeout:
if Timeout =
return
GuiClose:
Gui, destroy
return
ExButton:
MouseGetPos,,,, Control
Stringreplace,retval,Control,Button
Gui, destroy
return
}
;-------------------------------------------------------------------------------
; Custom Msgbox
; Filename: cmsgbox.ahk
; Author : Danny Ben Shitrit (aka Icarus)
;-------------------------------------------------------------------------------
; Copy this script or include it in your script (without the tester on top).
;
; Usage:
; Answer := CMsgBox( title, text, buttons, icon="", owner=0 )
; Where:
; title = The title of the message box.
; text = The text to display.
; buttons = Pipe-separated list of buttons. Putting an asterisk in front of
; a button will make it the default.
; icon = If blank, we will use an info icon.
; If a number, we will take this icon from Shell32.dll
; If a letter ("I", "E" or "Q") we will use some predefined icons
; from Shell32.dll (Info, Error or Question).
; owner = If 0, this will be a standalone dialog. If you want this dialog
; to be owned by another GUI, place its number here.
;
;-------------------------------------------------------------------------------
CMsgBox( title, text, buttons, icon="", owner=0 ) {
Global _CMsg_Result
GuiID := 9 ; If you change, also change the subroutines below
StringSplit Button, buttons, |
If( owner <> 0 ) {
Gui %owner%:+Disabled
Gui %GuiID%:+Owner%owner%
}
Gui %GuiID%:+Toolwindow +AlwaysOnTop
MyIcon := ( icon = "I" ) or ( icon = "" ) ? 222 : icon = "Q" ? 24 : icon = "E" ? 110 : icon
Gui %GuiID%:Add, Picture, Icon%MyIcon% , Shell32.dll
Gui %GuiID%:Add, Text, x+12 yp w180 r8 section , %text%
Loop %Button0%
Gui %GuiID%:Add, Button, % ( A_Index=1 ? "x+12 ys " : "xp y+3 " ) . ( InStr( Button%A_Index%, "*" ) ? "Default " : " " ) . "w100 gCMsgButton", % RegExReplace( Button%A_Index%, "\*" )
Gui %GuiID%:Show,,%title%
Loop
If( _CMsg_Result )
Break
If( owner <> 0 )
Gui %owner%:-Disabled
Gui %GuiID%:Destroy
Result := _CMsg_Result
_CMsg_Result := ""
Return Result
}
9GuiEscape:
9GuiClose:
_CMsg_Result := "Close"
Return
CMsgButton:
StringReplace _CMsg_Result, A_GuiControl, &,, All
Return

The answer lies in syntax of your code. I highly suggest that you read the Tutorial in the Docs fully! It's really well written.
What immediately popped out to me is that your Variables in your If Expressions are surrounded by percents, which is wrong.
Here is a link to the section in the Tutorial that you need to read in order to fix your code.
Try this:
!o::
var := MsgBoxV2("Question11","Hi, what's up??","Sym|Go|C","24")
Msgbox 4,, You Pressed %var%
if (var = "C")
{
Msgbox 4,, IT WORKED!
}
!e::
var := CMsgbox( "s", "d", "*&Sym|&Go|&C","",1 )
Msgbox 4,, You Pressed %var%
If (var = "C")
{
Msgbox 4,, worked
}
return
The IfEqual command is pretty much deprecated and while it's still included in the latest releases, it's basically bad form to use since the If expression much easier to read. Also plain text excluding numbers in an expression should be surrounded by quotes. Hope this helps.

Related

How can I run an AutoHotkey script on C++ code?

I am developing an open source desktop application in C++, and I need to run this AutoHotkey script inside C++ code, how can I make it?
Acc_Caret := Acc_ObjectFromWindow(WinExist("A"), OBJID_CARET := 0xFFFFFFF8)
Caret_Location := Acc_Location(Acc_Caret)
x = %A_CaretX%
y = %A_CaretY%
WinGetPos, Xc, Yc,,, A
msgbox, Act at %Xc%`,%Yc%
msgbox % Caret_Location.x "`n" Caret_Location.y
msgbox % x "`n" y
return
Acc_Init()
{
Static h
If Not h
h:=DllCall("LoadLibrary","Str","oleacc","Ptr")
}
Acc_ObjectFromWindow(hWnd, idObject = -4)
{
Acc_Init()
If DllCall("oleacc\AccessibleObjectFromWindow", "Ptr", hWnd, "UInt", idObject&=0xFFFFFFFF, "Ptr", -VarSetCapacity(IID,16)+NumPut(idObject==0xFFFFFFF0?0x46000000000000C0:0x719B3800AA000C81,NumPut(idObject==0xFFFFFFF0?0x0000000000020400:0x11CF3C3D618736E0,IID,"Int64"),"Int64"), "Ptr*", pacc)=0
Return ComObjEnwrap(9,pacc,1)
}
Acc_Location(Acc, ChildId=0, byref Position="") { ; adapted from Sean's code
try Acc.accLocation(ComObj(0x4003,&x:=0), ComObj(0x4003,&y:=0), ComObj(0x4003,&w:=0), ComObj(0x4003,&h:=0), ChildId)
catch
return
Position := "x" NumGet(x,0,"int") " y" NumGet(y,0,"int") " w" NumGet(w,0,"int") " h" NumGet(h,0,"int")
return {x:NumGet(x,0,"int"), y:NumGet(y,0,"int"), w:NumGet(w,0,"int"), h:NumGet(h,0,"int")}
}
(msgbox are there just to debug)
Looks like using the dll should work see https://www.autohotkey.com/boards/viewtopic.php?t=34779&p=160687 Perhaps you could see how this Ruby/Ahk integration worked.

IRC String comparison is always true

I'm trying to simply compare a line in a text file to today's date.
The line I want help with always seems to evaluate true for my code.
Any examples?
My code:
set %lines $lines(test.txt)
set %date $adate
while (%i <= %lines)
set %read $read(test.txt, n, %i)
if( %date isin %read ){ ; <-- Line in question
do things
}
}
You have a few errors.
Your while loop is missing an open bracket. (And closing at the end)
while (%i <= %lines) {
You must have a space between () { } and the rest of the lines
if<space>(
)<space> {
if ( %date isin %read ) {
I took the liberty of suggesting another version.
Code:
var %filename = test.txt
var %lines = $lines(%filename)
var %currentDate = $adate
var %i = 1
while (%i <= %lines) {
var %line = $read(%filename, n, %i)
if (%currentDate isin %line) {
# do things
# Should uncomment the break in case you want to stop after a match
#break
}
inc %i
}
I am sorry if I didn't understand, but what is the reason for a complex script just to check if there is a date format in a line of a text file?
There is no reason to set a variable %read to store the line of the loop in question, when you can do an IF condition after the loop:
var %x = 1
while (%x <= $lines(test.txt)) {
if ($adate isin $read(test.txt,n,%x)) {
;do things
}
inc %x
}

Multiple concurrency in golang

I'm trying to port a simple synchronous bit of PHP to Go, but am having a hard time getting my head around how concurrency works with regards to channels. The PHP script makes a request to get a list of media library sections, then makes requests to get the items within each of these sections. If the section is a list of TV Shows, it then makes a request for each show to get all the seasons and then another to get the episodes within each season.
I've trying writing in pidgeon-go what I expected to work, but I'm not having any luck. I've tried various channel guides online, but normally end up with deadlock warnings. Currently this example warns about item := <-ch used as value and doesn't look like it's waiting on the goroutines to return. Does anyone have any ideas what I can do?
package main
import (
"fmt"
"time"
)
// Get all items for all sections
func main() {
ch := make(chan string)
sections := getSections()
for _, section := range sections {
go getItemsInSection(section, ch)
}
items := make([]string, 0)
for item := <- ch {
items = append(items, item)
}
fmt.Println(items)
}
// Return a list of the various library sections
func getSections() []string {
return []string{"HD Movies", "Movies", "TV Shows"}
}
// Get items within the given section, note that some items may spawn sub-items
func getItemsInSection(name string, ch chan string) {
time.Sleep(1 * time.Second)
switch name {
case "HD Movies":
ch <- "Avatar"
ch <- "Avengers"
case "Movies":
ch <- "Aliens"
ch <- "Abyss"
case "TV Shows":
go getSubItemsForItem("24", ch)
go getSubItemsForItem("Breaking Bad", ch)
}
}
// Get sub-items for a given parent
func getSubItemsForItem(name string, ch chan string) {
time.Sleep(1 * time.Second)
ch <- name + ": S01E01"
ch <- name + ": S01E02"
}
First, that code doesn't compile because for item := <- ch should be for item := range ch
Now the problem is you either have to close the channel or run your loop forever inside a goroutine.
go func() {
for {
item, ok := <-ch
if !ok {
break
}
fmt.Println(item)
items = append(items, item)
}
}()
time.Sleep(time.Second)
fmt.Println(items)
playground

AS3 and HTML5 - parse string into array using regex

I've been looking and playing with RegEx for a while now and am trying to find this solution that I can apply to both AS3 and to HTML5.
I've got a custom user entry section, 256 chars that they can customize.
What I would like is for them to use my predefined table of codes 00 - 99 and they can insert them into the box to automatically generate a response that can go through a few hundred examples.
Here is a simple example:
Please call: 04
And ask for help for product ID:
03
I'd be able to take this and say, okay i got the following into an array:
[Please call: ]
[04]
[/n]
[And ask for help for product ID: ]
[/n]
[03]
and possibly apply a flag to say whether this is a database entry or not
[Please call: ][false]
[04][true]
[/n][false]
[And ask for help for product ID: ][false]
[/n][false]
[03][true]
this would be something that my program could read. Where I know that for the ## matches, to find a database entry and insert, though for anything else, use the strings.
I have been playing around on
http://gskinner.com/RegExr/
to try and brute force an answer to no avail so far.
Any help would be greatly appreciated.
The best I've come up with so far for matches is the following. Though this is my first time playing with the regex functions and would need to find out how to push these entries into my ordered array.
\d\d
\D+
And would need some way to combine them to pull an array... or I'll be stuck with a crappy loop:
//AS3 example
database_line_item:int = 127;
previous_value_was_int:boolean = false;
_display_text:string = "";
for(var i:int = 0; i < string.length; i++){
if(string.charAt(i) is int){
if(previous_value_was_in){
previous_value_was_int = true;
}else{
_display_text += getDatabaseValue(string.charAt(i-1)+string.charAt(i), database_line_item);
previous_value_was_int = false;
}
}else{
//Hopefully this handles carriage returns, if not, will have to add that in.
_display_text += string.charAt(i);
}
}
// >>>>>>>>> HTML5 Example <<<<<<<<<<<<<
...
and I would cycle through the database_line_item, though for maybe 400 line items, this will be a taxing, to go through that string. Splitting it into smaller arrays would be easier to handle.
Here is the magic reg : /([^0-9\n\r]+)|(\d+)|(\r\n?|\n)/gi
Exemple output :
[Please call: ][false]
[4][true]
[/n][false]
[And ask for help for product ID:][false]
[/n][false]
[3][true]
Exemple code that do the job and put the data into an array :
package
{
import flash.display.Sprite;
public class TestReg extends Sprite
{
public function TestReg()
{
super();
var data : Array = parse("Please call: 04\n"+
"And ask for help for product ID:\n"+
"03");
// Output
for(var i : uint = 0; i < data.length; i += 2)
trace("[" + data[ i ] + "][" + data[ i + 1 ] + "]");
}
private var _search : RegExp = /([^0-9\n\r]+)|(\d+)|(\r\n?|\n)/gi;
public function parse(str : String) : Array
{
var result : Array = [];
var data : Array = str.match( _search );
for each(var item : * in data)
{
// Replace new line by /n
if(item.charAt( 0 ) == "\n" || item.charAt( 0 ) == "\r")
item = "/n";
// Convert to int if is a number
if( ! isNaN( parseFloat( item.charAt( 0 ) ) ) )
item = parseInt( item );
result.push( item );
result.push( !( item is String ));
}
return result;
}
}
}

SendInput without a binding keyword

I am trying to send input to VMWare Player when I switch to it. This is so that do not have press Ctrl-g and make the VMWare grab my input. The following is the script I came up with, but it does not do anything. What is it that missed?
#IfWinActive ahk_class VMPlayerFrame
{
SendInput, {Ctrl down}g{Ctrl up}
} return
You can use #IfWinActive to change hotkeys or hotstrings, but not to create scripts.
You need to detect the window change, and act on that.
#SingleInstance
#installKeybdHook
#Persistent
Gui +LastFound
hWnd := WinExist()
DllCall( "RegisterShellHookWindow", UInt,Hwnd )
MsgNum := DllCall( "RegisterWindowMessage", Str,"SHELLHOOK" )
OnMessage( MsgNum, "ShellMessage" )
Return
ShellMessage( wParam )
{
If (wParam = 4 or wParam = 32772) ; Without VMware Player running: wParam = 4, with VMware Player running: wParam = 32772
{
IfWinActive ahk_class VMPlayerFrame
{
SendInput, {Ctrl down}g{Ctrl up}
}
}
}
Return
; Hotkey {Win}+g launches Chrome
#g::Run "C:\Users\%A_Username%\AppData\Local\Google\Chrome\Application\chrome.exe"
; Hotkeys {Ctrl}+Nr gives you fractures
^2::
Send, ½
TrayTip, For 2 Squared,press Ctrl + Shift 2,1,1
Return
^3::
Send, ¾
TrayTip, For 3 Cubed,press Ctrl + Shift 3,1,1
Return
^4::Send, ¼
; HotKeys {Shift}+{Ctrl}+Nr gives you the power
+^0::Send, °
+^1::Send, ¹
+^2::Send, ² ; Shift Control 2#
+^3::Send, ³ ; Shift Control 3#
; Hotstrings mvge, mvgd or mvgf will give you my salutations in various languages.
:*:mvge::Regards,{Enter}{Enter}Robert Ilbrink
:*:mvgd::Mit freundlichen Grüßen,{Enter}{Enter}Robert Ilbrink
:*:mvgf::Salutions,{Enter}{Enter}Robert Ilbrink