Perl TK multiple commands on a single button - perltk

I would like to do is to have a button to close my window (button_window), but also call a function (user_info):
my $btn = $main -> Button (-text => 'Start',
-command => sub {$button_window -> destroy},
-command => \&user_info)
-> pack ();
its executing only the last command
thanks in advance

The sub can take any number of calls to other subs.
my $btn = $main->Button(
-text => 'Start',
-command => sub {
user_info();
# do something else...
$button_window->destroy;
},
)->pack();
It's executing only the last command because a hash parameter can have only one '-command' key, so is overwritten.

Related

Multi Clicks With the Same Keyboard Shortcuts to Run a Ahk Script

I want to do Multi Clicks with the same Keyboard Shortcuts to Run a Ahk Script.
I now in Autohotkey Languages, you can write a code that can execute a part of Code, if a certain Keyboard Shortcut combination is pressed.
But i want on my Windows System, to Click a count of the same keystroke combinations to execute a part of Code.
The pros are: you do not have to move your fingers to a other place on that keyboard, Click it again and it will run a other Code. (this will improve my keyboard Movements and i have more options to do keystrokes.)
Example:
Click - Ctrl + (1x)c - to CopyText
DoubleClick - Ctrl + (2x)c - to CopyText + GoogleSearch
multiClick - Ctrl + (5x)c - ?
If you look to this Example Script then you can see what i mean.
(note - Hotkey > [^cc::] or hotkeystring > [:*:^cc::]- this does not work, is there another way to solved this)
; [+ = Shift] [! = Alt] [^ = Ctrl] [# = Win]
#SingleInstance force
;MultiClicks the Same Keyboard Shortcuts to Run a Ahk Script
;Click Ctrl + c to [copy text]
^c::
send ^c
;msgbox script1
return
;DoubleClick Ctrl + (2x)c [copy text] + [do a google search]
^cc::
send ^c
sleep 200
run https://www.google.com/?q=%clipboard%
;msgbox script2
return
;MultiClicks Ctrl + (5x)c to run script5
^ccccc::
;?
;msgbox script5
return
esc::exitapp
^c::
{
count++
SetTimer, actions, 400 ;время за которое нужно нажать комбинацию
}
return
actions:
{
if (count = 1)
{
msgbox CTRL+C
}
else if (count = 2)
{
msgbox CTRL+CС
}
else if (count = 5)
{
msgbox CTRL+CСССС
}
count := 0
}

Powershell GUI, Progress Bar, and Hash Tables

Part of a script that I'm working on takes the specified username, searches active directory for computers named like the username, pings them, and then adds the online machines to an array for use later. I'd like to add a progress bar to the ping portion of the script but I'm running into problems. The form I have to present the progress bar freezes execution of the script if I invoke it prior to the ping loop.
Here is the code for the progress bar (pretty basic):
#Progress Bar
$objFormPBar = New-Object System.Windows.Forms.Form
$objFormPBar.Text = "Loading"
$objFormPBar.Size = New-Object System.Drawing.Size(200,100)
$objFormPBar.StartPosition = "CenterScreen"
$objFormPBar.Topmost = $True
$objFormPBar.Icon = $Icon
$progressBar = New-Object System.Windows.Forms.ProgressBar
$progressBar.Size = New-Object System.Drawing.Size(175,20)
$progressBar.Location = New-Object System.Drawing.Size(5, 20)
$progressBar.Minimum = 0
$progressBar.Maximum = 0
$objFormPBar.Controls.Add($progressBar)
Here is where I'm attempting to display it, this way halts execution of the script (called from inside a click handler function, thus the global variables):
$global:progressBar.Maximum = $computers.count
$global:objFormPBar.Add_Shown({$objFormPBar.Activate()})
[void] $global:objFormPBar.ShowDialog()
Foreach ($computer in $computers) {
$computer = $computer.trim()
If(Test-Connection $computer -Count 1) {
$arrayComputers.add($computer) | Out-Null
}
$global:progressBar.Increment(1)
}
$global:objFormPBar.Close()
Looking into the problem I've discovered that you can run the progress bar in a separate thread and pass variables between the two (See: Marquee Progress Bar freezes in Powershell ). However I have had no luck getting it to work or even to get another thread to launch. How can I get this progress bar and the form along with it to run in another thread?
Why don't you just use the built-in UI for reporting progress in PowerShell? It's a one line call to Write-Progress e.g.:
$computers = 1..10 | % {"server$_"}
$numComputers = $computers.Length
for ($ndx = 0; $ndx -le $numComputers; $ndx++) {
$computer = $computers[$ndx].Trim()
Write-Progress "Testing connection to $computer" -PercentComplete ($ndx/$numComputers * 100)
#if (Test-Connection $computer -Count 1) {
# $arrayComputers.add($computer) | Out-Null
#}
Start-Sleep -Seconds 1
}
BTW the primary problem with your approach above is that the ShowDialog() method call doesn't return until the form is closed. If you want to use ShowDialog(), you have to execute your logic in the context of an event handler inside the form (Load/Activate). The other option is to use Show() but that means you'll have to pump messages in your loop using Application.DoEvents() so the form will have a chance to update itself.

EXCEL VBA: calling an event with onclick property of a button which is being created on the fly

I am creating a excel VBA userform which requires many buttons to be created on the fly (ie as the requirement may be, runtime). I want to assign a subroutine to these buttons so that when they are clicked a subroutine should execute.
this is what I want to do
Set obj4 = usrform.Controls.Add("forms.commandbutton.1")
obj4.Height = 17
obj4.Left = 450
obj4.Top = 75
obj4.Font.Size = 11
obj4.Name = "compare" & (j - i) 'j and i are some variables in the code
obj4.Caption = "Compare!"
obj4.onclick = abcd
public sub abcd()
'some code here
end sub
but this code is not running. I read somewhere that here I cannot call a subroutine but a function. My problem is that I want a subroutine only as I dont intend to get something in return from it. But still for trial purpose I made abcd() a function in the above code and then my code was running but unsuccessfully as it was executing the function abcd without the need of button getting pressed.
Can anyone help me with this? I have searched a lot for this on internet in various forums.
Don't get hung up on subroutine v. function: if you don't set the return value of a function, it's the same as a subroutine.
When you set the onClick property, you give it the name of the function as a string obj4.onclick = "abcd" otherwise it will execute the function and save the return value.

How do I stop ReSharper from placing "x => new" on a new line?

I know this is a fairly small detail, but for some reason it's incredibly annoying to me and I cannot figure out how to correct it (I've looked at the "Line Breaks and Wrapping" options).
Here's how I like this code formatted:
var reps = ctx.Commissions
.GroupBy(x => x.SalesRep)
.Select(x => new
{
x.Key.UserID,
Name = x.Key.FirstName + " " + x.Key.LastName
})
.ToList();
ReSharper, though, likes to format it as
var reps = ctx.Commissions
.GroupBy(x => x.SalesRep)
.Select(
x => new
{
x.Key.UserID,
Name = x.Key.FirstName + " " + x.Key.LastName
})
.ToList();
Any ideas as to how I can stop ReSharper from doing this?
Thank you,
Andrew
It looks like you should disable Prefer wrap after '(' in invocation option in Code Editing -> C# -> Formatting Style -> Line Breaks and Wrapping section.

Executing commands using Button widget in Perl-Tk

#!/usr/local/bin/perl
use Tk;
# Main Window
$mw = new MainWindow;
$label = $mw -> Label(-text=>"Hello World") -> pack();
$button = $mw -> Button(-text => "Quit",
-command => sub { exit }) -> pack();
MainLoop;
In this code when the button $button is pressed it closes the program. Because it executes the exit command. I want to modify the code so that when the user clicks on the button it will flush the iptables rule (iptables -F). How can I do this?
I tried this:
$button = $mw -> Button(-text => "Flush the rules",
-command => system ( iptables -F )) -> pack();
Why isn't this working? Should I have to make a subroutine for it (then writing the iptables -F command there) and then call that subroutine? Can't I directly put the command as I did in above code?
You need to specify a code reference - a callback - which will be executed when the button is pressed, so yes you should place your system call in a sub { }.
What you've written is a call to system() at the point that the Button is defined, so you're specifying the return value from system() as the coderef for the callback - which won't work. The system() function will be called when Button is defined, not when its pressed - which isn't what you want.

Resources