I want MsgBox() on mouse click, but prevent natural behaviour of mouse click. That means if I click any links here on Stack Overflow my active page must remain the same.
#include <MsgBoxConstants.au3>
#Include <Misc.au3>
While 1
If _IsPressed(01) Then ShowAlert() ; 01 is for left mouse button
Sleep (100)
WEnd
Func ShowAlert()
MsgBox($MB_SYSTEMMODAL, "", "Test")
EndFunc
This should do the trick:
#include <Constants.au3>
#include <WinAPI.au3>
#include <WindowsConstants.au3>
Global Const $HC_ACTION = 0
Global $hStub_MouseProc = DllCallbackRegister("_MouseProc", "long", "int;wparam;lparam")
Global $hmod = _WinAPI_GetModuleHandle(0)
Global $hHook = _WinAPI_SetWindowsHookEx($WH_MOUSE_LL, DllCallbackGetPtr($hStub_MouseProc), $hmod)
HotKeySet('^+!e', '_ende') ; CTRL+SHIFT+ALT+E to exit.
OnAutoItExitRegister('ExitFunc')
While 1
Sleep(100)
WEnd
Func _ende()
Exit
EndFunc ;==>_ende
Func _MouseProc($nCode, $wParam, $lParam)
If $nCode < 0 Then
Return _WinAPI_CallNextHookEx($hHook, $nCode, $wParam, $lParam)
EndIf
If $nCode = $HC_ACTION Then
Switch $wParam
Case 0x0201
ConsoleWrite('No Click!' & #CRLF)
Return -1
;~ Case $WM_MBUTTONUP
;~ Return _mouse_event($MOUSEEVENTF_RIGHTUP) ; Returns -1; mouse click will be ignored.
EndSwitch
EndIf
Return _WinAPI_CallNextHookEx($hHook, $nCode, $wParam, $lParam)
EndFunc ;==>_MouseProc
Func ExitFunc()
_WinAPI_UnhookWindowsHookEx($hHook)
DllCallbackFree($hStub_MouseProc)
EndFunc ;==>ExitFunc
Func _mouse_event($dwFlags)
DllCall("user32", 'long', 'mouse_event', 'long', $dwFlags, 'long', 0, 'long', 0, 'long', 0, 'long', 0)
Return -1
EndFunc ;==>_mouse_event
… prevent it's natural behaviour in the same time …
As per MouseOnEvent UDF:
This UDF allows to set an events handler for Mouse device.
Example (using ConsoleWrite() as MsgBox() requires the blocked mouse-click in order to be closed):
#include "MouseOnEvent.au3"
Global Const $g_sKeyQuit = '{esc}'
Global Const $g_iDelay = 10
Global Const $g_bBlockInput = True
Global $g_bStateQuit = False
Main()
Func Main()
HotKeySet($g_sKeyQuit, 'Quit')
_MouseSetOnEvent($MOUSE_PRIMARYDOWN_EVENT, '_MousePrimaryDown_Event')
_MouseSetOnEvent($MOUSE_PRIMARYDBLCLK_EVENT, '_MousePrimaryDblclk_Event')
While Not $g_bStateQuit
Sleep($g_iDelay)
WEnd
Exit
EndFunc
Func Quit()
$g_bStateQuit = True
EndFunc
Func _MousePrimaryDown_Event()
ConsoleWrite('Detected $MOUSE_PRIMARYDOWN_EVENT' & #CRLF)
Return $g_bBlockInput ? $MOE_BLOCKDEFPROC : $MOE_RUNDEFPROC
EndFunc
Func _MousePrimaryDblclk_Event()
ConsoleWrite('Detected $MOUSE_PRIMARYDBLCLK_EVENT' & #CRLF)
Return $g_bBlockInput ? $MOE_BLOCKDEFPROC : $MOE_RUNDEFPROC
EndFunc
The UDF allows events to be registered to a specific window as well. It can either block or pass events after detection and includes example on how to restrict functionality to part(s) of a screen.
Related
I want to bind some variable textcontent to an specific key (example on key p)
For example:
First press on p: "hannes1"
second press on p: "hannes2"
third press on p: "hannes3"
And so on. Thanks for any help.
It isn't clear from your question if you want a fixed string hannes with a counter or "the next string from a list", so I added both options (available via p and P
; Global $aVars[3] = ["hannes1", "hannes2", "hannes3"]
HotKeySet("p", "_SendVarArray")
HotKeySet("P", "_sendvarCount")
While True
Sleep(25)
WEnd
Func _SendVarArray() ; write strings from an array; rotating
Local $aVars[3] = ["One", "Two", "Three"] ; define EITHER here as Local OR in main program as Global
Local Static $x = UBound($aVars) - 1 ; initial value for next line to be changed as start value '0'
$x = Mod($x + 1, UBound($aVars))
Send($aVars[$x])
EndFunc ;==>_SendVarArray
Func _SendVarCount()
Local Static $x = 0 ; 'Static' to remember value with next execution
$x += 1
Send("hannes" & $x)
EndFunc ;==>_SendVarCount
NOTE: an ordinary letter is a bad choice for a hotkey, because if a string you send() contains that letter, it will activate the hotkey function too (I kept it anyway, leaving it to you to find a better key(combination)).
The advantage of HotKeySet() is that your program can do other things while waiting for the hotkey being pressed.
Try this: Change the ConsoleWrite to Send if you want to send the keys to any application.
#include <Misc.au3>
#include <MsgBoxConstants.au3>
Local $hDLL = DllOpen("user32.dll")
Local $counter = 0
While 1
If _IsPressed("50", $hDLL) Then
; Wait until key is released.
While _IsPressed("50", $hDLL)
Sleep(25)
WEnd
ConsoleWrite("Hannes" & $counter & #CRLF)
$counter +=1
ElseIf _IsPressed("1B", $hDLL) Then
MsgBox($MB_SYSTEMMODAL, "_IsPressed", "The Esc Key was pressed, therefore we will close the application.")
ExitLoop
EndIf
Sleep(25)
WEnd
DllClose($hDLL)
I have an endless cycle going on. How do I stop the program to output the answer? The meaning of my program: reads all characters (including enter) and outputs the sum of only numbers.
fun main() {
fun StrToSum(str: String): Long {
var sum : Long = 0
var next = ""
for (symbol in str + " ") {
if (symbol == '-') {
if ((next != "-") && (next != "")) {
sum += next!!.toLong()
}
next = symbol.toString()
} else if (symbol.isDigit()) {
next += symbol
} else if (next != "") {
if (next != "-") {
sum += next!!.toLong()
}
next = ""
}
}
return sum
}
var string: String = ""
while (1<2) { //How stop it ?
var str = readLine()!!.toString()
string += " " + str
}
println (StrToSum(string)) //answer
}
maybe there is some kind of keyboard shortcut ? I work for IntelliJ from Jetbrains
You can terminate the currently running program, but that will kill it - it won't be able to output the answer. You need to code that handling as part of your design, so you enable the user to finish and print your result.
The usual way people do this is to have some kind of cancel input, like entering an x or something:
// while (true) is a typical way to create an infinite loop
while (true) {
var str = readLine()!!.toString()
// look for the cancel token, break out of the loop if you see it
if (str.lowercase() == "x") break
string += " " + str
}
If you don't want to do that (remember you can make the cancel token anything, like the word "cancel" if you like, and put a prompt on the screen telling the user to type it to finish) then you'd have to do something like detecting other keycodes like Ctrl+Z or whatever - and I'm not sure how you'd do that from a basic command-line program reading from standard input. Maybe someone knows some tricks you could use! It's not something I've ever had to do, so I can't help you there
edit If you're happy to just look for control characters like ^D in the lines of standard input, you could do this kind of thing
if (str.firstOrNull().code == 4) break // char value for ^D
But that still requires the user to press Enter after the Ctrl+D, so the line including that character can be sent from the terminal to standard input. That's just how it works, outside of the solutions in the discussion I linked which involve OS-level interaction or building a GUI so you have access to the raw keypresses.
I want to implement yes | head -n 1 in Rust, properly
connecting pipes and checking exit statuses: i.e., I want to be able to
determine that yes exits due to SIGPIPE and that head completes
normally. The pipe functionality is easy (Rust Playground):
use std::process;
fn a() -> std::io::Result<()> {
let child_1 = process::Command::new("yes")
.arg("abracadabra")
.stdout(process::Stdio::piped())
.spawn()?;
let pipe: process::ChildStdout = child_1.stdout.unwrap();
let child_2 = process::Command::new("head")
.args(&["-n", "1"])
.stdin(pipe)
.stdout(process::Stdio::piped())
.spawn()?;
let output = child_2.wait_with_output()?;
let result = String::from_utf8_lossy(&output.stdout);
assert_eq!(result, "abracadabra\n");
println!("Good from 'a'.");
Ok(())
}
But while we can wait on child_2 at any point, the declaration of
pipe moves child_1, and so it’s not clear how to wait on child_1.
If we were to simply add child_1.wait()? before the assert_eq!, we’d
hit a compile-time error:
error[E0382]: borrow of moved value: `child_1`
--> src/main.rs:15:5
|
8 | let pipe: process::ChildStdout = child_1.stdout.unwrap();
| -------------- value moved here
...
15 | child_1.wait()?;
| ^^^^^^^ value borrowed here after partial move
|
= note: move occurs because `child_1.stdout` has type `std::option::Option<std::process::ChildStdout>`, which does not implement the `Copy` trait
We can manage to wait with unsafe and platform-specific
functionality (Rust Playground):
use std::process;
fn b() -> std::io::Result<()> {
let mut child_1 = process::Command::new("yes")
.arg("abracadabra")
.stdout(process::Stdio::piped())
.spawn()?;
use std::os::unix::io::{AsRawFd, FromRawFd};
let pipe: process::Stdio =
unsafe { FromRawFd::from_raw_fd(child_1.stdout.as_ref().unwrap().as_raw_fd()) };
let mut child_2 = process::Command::new("head")
.args(&["-n", "1"])
.stdin(pipe)
.stdout(process::Stdio::piped())
.spawn()?;
println!("child_1 exited with: {:?}", child_1.wait().unwrap());
println!("child_2 exited with: {:?}", child_2.wait().unwrap());
let mut result_bytes: Vec<u8> = Vec::new();
std::io::Read::read_to_end(child_2.stdout.as_mut().unwrap(), &mut result_bytes)?;
let result = String::from_utf8_lossy(&result_bytes);
assert_eq!(result, "abracadabra\n");
println!("Good from 'b'.");
Ok(())
}
This prints:
child_1 exited with: ExitStatus(ExitStatus(13))
child_2 exited with: ExitStatus(ExitStatus(0))
Good from 'b'.
This is good enough for the purposes of this question, but surely there
must be a safe and portable way to do this.
For comparison, here is how I would approach the task in C (without
bothering to capture child_2’s output):
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#define FAILIF(e, msg) do { if (e) { perror(msg); return 1; } } while (0)
void describe_child(const char *name, int status) {
if (WIFEXITED(status)) {
fprintf(stderr, "%s exited %d\n", name, WEXITSTATUS(status));
} else if (WIFSIGNALED(status)) {
fprintf(stderr, "%s signalled %d\n", name, WTERMSIG(status));
} else {
fprintf(stderr, "%s fate unknown\n", name);
}
}
int main(int argc, char **argv) {
int pipefd[2];
FAILIF(pipe(pipefd), "pipe");
pid_t pid_1 = fork();
FAILIF(pid_1 < 0, "child_1: fork");
if (!pid_1) {
FAILIF(dup2(pipefd[1], 1) == -1, "child_1: dup2");
FAILIF(close(pipefd[0]), "child_1: close pipefd");
execlp("yes", "yes", "abracadabra", NULL);
FAILIF(1, "child_1: execlp");
}
pid_t pid_2 = fork();
FAILIF(pid_2 < 0, "child_2: fork");
if (!pid_2) {
FAILIF(dup2(pipefd[0], 0) == -1, "child_2: dup2");
FAILIF(close(pipefd[1]), "child_2: close pipefd");
execlp("head", "head", "-1", NULL);
FAILIF(1, "child_2: execlp");
}
FAILIF(close(pipefd[0]), "close pipefd[0]");
FAILIF(close(pipefd[1]), "close pipefd[1]");
int status_1;
int status_2;
FAILIF(waitpid(pid_1, &status_1, 0) == -1, "waitpid(child_1)");
FAILIF(waitpid(pid_2, &status_2, 0) == -1, "waitpid(child_2)");
describe_child("child_1", status_1);
describe_child("child_2", status_2);
return 0;
}
Save to test.c and run with make test && ./test:
abracadabra
child_1 signalled 13
child_2 exited 0
Use Option::take:
let pipe = child_1.stdout.take().unwrap();
let child_2 = process::Command::new("head")
.args(&["-n", "1"])
.stdin(pipe)
.stdout(process::Stdio::piped())
.spawn()?;
let output = child_2.wait_with_output()?;
child_1.wait()?;
See also:
How do I move out of a struct field that is an Option?
Unable to pipe to or from spawned child process more than once
How do I read the output of a child process without blocking in Rust?
Reading and writing to a long-running std::process::Child
Cannot move out of borrowed content when unwrapping
I have this code that allows the user to load an input file (option 1), display the contents of the input file (option2) and they have the option to exit (option 3). Is there any way that I can skip the first line of the input file from being couted?
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <string>
using namespace std;
int main ()
{ char selection = ' ';
char fileName[25];
ifstream file;
string line;
cout<< "Choose an action"<<endl;
string myMenu[3]={" 1 - Load An Exam ", " 2 - Display Exam ", " 3 - Quit " };
for (int i=0; i<3; i++)
{ cout<<myMenu[i]<<endl;}
cin>>selection;
switch(selection)
{
case '1':
cout<<"Please enter the file name"<<endl;
cin>>fileName,25;
file.open(fileName);
if (file.fail())
{cout<<"Unable to open file"<<endl;
cout<<"Please enter the file name"<<endl;
cin>>fileName,25;
file.open(fileName); }
break;
case '2':
if (file.good())
{
while (getline(file, line))
{cout<<line<<"\n";}
file.close();
}
else cout<<"Unable to open file";
break;
case '3':
cout<<"Thank you!"<<endl;
break;
}
Just continue inside the while loop. This will re-trigger the getLine function, which will move the pointer forward 1 line.
while (getline(file, line))
{
if ( skipLineCondition ) { continue; }
cout<<line<<"\n";
}
Also, please try to post better formatted code. We are here to help, but you should focus more effort into making it easy for everyone to help you.
I want to pause an AutoIt script containing a While loop and some functions. But I am only able to close the script on HotKeySet(). How can I pause it?
The script checks for changes on a part of screen (x,y coordinates are set in a config file) and takes screenshots after playing an alert sound. It doesn't stop the While loop when pushing the pause button. But closing the program works. Here is my code:
Global $Paused, $counter = 0
HotKeySet("{1}", "TogglePause")
HotKeySet("{2}", "Terminate")
HotKeySet("{3}", "ShowMessage")
Init()
Start()
While 1
$counter +=1
ToolTip('Script is "Running"',0,0, $counter, 1)
Sleep(700)
Switch TrayGetMsg()
Case $resume
Start()
DisableAlert()
Case $exit
ExitLoop
Exit
EndSwitch
WEnd
//some of the functions
Func Start()
$ready = 0
$count = 0
$lastScreenshotNum = 0
TrayItemSetState($resume, $TRAY_DISABLE)
TraySetIcon("on.ico")
TakeScreenshot()
AdlibRegister(TakeScreenshot,2000)
EndFunc
Func Stop()
AdlibUnRegister(TakeScreenshot)
TraySetIcon("off.ico")
TrayItemSetState($resume, $TRAY_ENABLE)
EndFunc
Func TogglePause()
Stop()
$Paused = NOT $Paused
While $Paused
sleep(100)
ToolTip('Script is "Paused"',0,0, $counter, 1)
WEnd
ToolTip("")
EndFunc
Func Terminate()
Exit 0
EndFunc
Func ShowMessage()
MsgBox(4096,"","This is a message.")
EndFunc
Func EnableAlert()
SendMail()
Alert()
AdlibRegister(Alert,5000)
EndFunc
Func DisableAlert()
AdlibUnRegister(Alert)
EndFunc
Func Alert()
SoundPlay("alert.mp3")
EndFunc
I want to pause an Autoit script, containing a while1 loop and some functions. But I am only able to close the the script on HotKeySet. So how can i pause it?
"Pause" While -loops by running their instructions conditional to (key-toggled) states (untested, no error checking):
Global Const $g_sKeyQuit = 'q'
Global Const $g_sKeyPause = 'p'
Global Const $g_iDelay = 500
Global $g_bStateQuit = False
Global $g_bStatePause = False
Main()
Func Main()
HotKeySet($g_sKeyQuit, 'SwitchStateQuit')
HotKeySet($g_sKeyPause, 'SwitchStatePause')
While Not $g_bStateQuit
If Not $g_bStatePause Then YourCode()
Sleep($g_iDelay)
WEnd
Exit
EndFunc
Func YourCode()
Local Static $iCount = 0
$iCount += 1
ConsoleWrite($iCount & #LF)
EndFunc
Func SwitchStateQuit()
$g_bStateQuit = True
EndFunc
Func SwitchStatePause()
_SwitchVar($g_sKeyPause)
EndFunc
Func _SwitchVar(ByRef $bSwitch)
$bSwitch = Not $bSwitch
EndFunc
P pauses.
Q exits.
Change content of YourCode() as required.
Visual explanation (illustrating While -loop in Main()):
Loops and AdlibRegister() are different ways to accomplish the same (choose either one).
Use TimerDiff() if accurately timed repetition is required because simply adding Sleep() introduces time-drifts (disregards execution time, which is true for AdlibRegister() as well). As per documentation:
Note that other running processes often affect the timing accuracy and so pauses are likely to last for slightly longer than requested.