I making a program that needs to be able to respond to the key press of Ctrl + ' (that's control + apostrophe) even when the program does not have focus.
The Ctrl + ' will be used to start and stop a timer.
The code would be something like (just some psuedo-code for my example):
On Ctrl + ' KeyPress
If TimerStart = False
Timer.Start()
TimerStart = True
Else
Timer.Stop()
TimerStart = False
End If
I have read that using a keyboard hook is the way to go and this is my preferred method, however I struggle to even understand the tutorials I read and am having trouble with the virtual key codes.
I found a decent tutorial here, but my lack of knowledge makes it hard for me to translate that into what I need.
Any help or an example specific to what I need would be very beneficial for me. This is the last thing I need to code to finish my program and I feel a more specific example, to my needs, would help me to break down and understand this better.
Related
Recently I've decided to code a faster auto clicker, but, while making it, I've run into a bit of a problem with the way I would like to break the loop. The way I have this auto clicker set up, is that it is only to activate when both mouse 5 and mouse 1 are pressed. I have it made to be broken when a button is released, but then the problem is the key release that breaks it is mouse 1. Obviously the easiest fix would to have it be broken by release of mouse 5, but due to both preference and stubbornness, I would rather the loop be broken by releasing mouse 1. In short, I'd like to have the loop continue running while mouse 5 is released, but not while mouse 1 is released. I hope that made sense, sorry if I've worded some things strangely.
Now, being new to AHK, more specifically things like this, I do not exactly know how to accomplish this goal. My code is below, and is a somewhat modified version of the OP of this post's code.
setmousedelay 0
setbatchlines 0
Count = 0
Stop = 0
Return
Xbutton2 & LButton::
ST := A_TickCount
Loop
{
Click
If Not GetKeyState("LButton", "P")
break
}
Return
f1::
ExitApp
I don't believe that ST := A_TickCount is necessarily needed, since I believe it server the purpose of counting the CPS (from the OP), but regardless I've decided to leave it in just in case.
As always, thank you for taking the time to read my post, I appreciate any and all answers/replies. My use of terminology and english are sometimes pretty poor, so if there's something I've left confusing, please feel free to ask me about it.
I am using this script to close all "Alerts" in my notification bar:
tell application "System Events"
tell process "NotificationCenter"
set numwins to (count windows)
repeat with i from numwins to 1 by -1
click button "Close" of window i
end repeat
end tell
end tell
However this doesn't close them all, even when there are no "Alert without Close button".
try catch didn't help. What's wrong?
I tested your script and it seemed to run correctly on my machine, but there is always a potential for problems when you use a repeat loop on a mutating list: in other words, a list that changes as the repeat loop progresses. Each time you close a window Notification Center changes its window list and updates the properties of the remaining windows; the script can simply lose track. I'm a little surprised it doesn't throw errors when this happens, but...
You can try this code and see if it works. rather than referring to windows by index it repeatedly tries to close the last window, ignoring any errors, and keeps on until the window count is zero or it loops 100 times (that last is to prevent an endless loop in case something goes wrong).
tell application "System Events"
tell process "NotificationCenter"
repeat 100 times
try
tell last window
click button "Close"
end tell
end try
if (count of its windows) = 0 then
exit repeat
end if
end repeat
end tell
end tell
EDIT
Per comments, the above doesn't work quite as advertised, so let's switch it over to AppleScriptObjC:
use framework "Foundation"
property NSUserNotificationCenter : class "NSUserNotificationCenter"
NSUserNotificationCenter's defaultUserNotificationCenter's removeAllDeliveredNotifications()
This seems to do the trick on my machine. Of course, NSUserNotificationCenter is deprecated as of 10.14, so this won't work forever — eventually you'll have to shift over to the notification's framework — but it should work for a few more OS versions.
EDIT 2
Per another comment, anyone working on os 10.14 or later (Mojave and Catalina, to date) can do an equivalent AppleScriptObjC routine using the UserNotifications framework, like so:
use framework "UserNotifications"
set notificationCenter to class "UNUserNotificationCenter"'s currentNotificationCenter
notificationCenter's removeAllDeliveredNotifications()
Note that I've used a slightly different syntax (merely calling class "UNUserNotificationCenter" rather than setting up a property). Both work; the property syntax is only preferable when you need to pass the class to handlers.
This is a feature you see in a lot of IRC clients. Basically, if you type a string "Ad" and then hit tab the client will fill in the first matching nick (in the case of an IRC client) mathcing 'Ad' - so let's say it fills in Adam. But, like bash, if you keep hitting tab it should cycle through all the names containing "Ad" as a prefix.
I'm not quite sure how to implement this in the Wndproc for a RichEdit though. Specifically, when a user hits tab I need to get the current 'token', save it, and get all the prefixes and fill in the first. If he hits tab again I need to get the next prefix, and so on, but I need to empty the prefix list once I get a WM_CHAR that's not tab -- I think?
I'm wondering if there's some easier, less hacky way though, or if anybody has seen code that does this?
Thanks.
Useful though Remy's comments are, it seems to me that this question is more about what the logic should be to implement kind-of-bash-style auto-completion than anything else. On that basis, and based on what you posted, which I found slightly confusing, I think it should be something like this (pseudo-code);
int autocomplete_index = 0;
string autocomplete_prefix;
on_tab:
if (autocomplete_prefix == "")
{
autocomplete_prefix = current_contents_of_edit_field ();
autocomplete_index = 0;
}
auto autocomplete_result = get_autocomplete_string (autocomplete_prefix, autocomplete_index++);
if (autocomplete_result != "")
replace_contents_of_edit_field_and_move_caret_to_end (autocomplete_result);
else
beep (); // or cycle round
done;
on_any_other_char:
autocomplete_prefix = "";
If the rich edit control is embedded in a dialog, you also need to ensure that the dialog manager does not speak in and snaffle VK_TAB before you do. That normally doesn't happen for rich edit controls (although it does for regular edit controls - go figure) but if it does you can handle WM_GETDLGCODE appropriately in your WndProc (details on request).
And 'hacky'? Why? I don't think so. Sounds like a good idea to me.
So I wanted to change the keyboard shortcut that's assigned to "Comment Selection" to something that makes sense for me. I don't use many keyboard shortcuts, mainly because I have a hard time remembering all of them.
So, I wanted to change the one that is assigned to "Comment Selection". The default is Ctrl + K, Ctrl + C. I don't like the concept of having to do "2" keystroke combinations to accomplish this. I want to be able to quickly hightlight, enter the keystroke, and then move on, all while leaving one hand on mouse, and one on keyboard.
Too much info...
I changed my keystroke to be Ctrl + Shift + C, but the "event" never fires. It shows up in the options "Edit.CommentSelection" just fine. I overwrote the previous 3 values ("global", "text editor", "data warehouse designer"). I see there are other events that fire when Ctrl + Shift combination is used, so that rules out the possibility of not being able to use the Shift key, which was my original thought.
Any other suggestions on how to get this working for me?
From the discussion above, it seems that the shortcut was already assigned to Edit.CopywithHeaders (which is the default assignment for that shortcut). Removing that assignment will fix your problem.
I need read in an infinite loop some variables and in the case it changes the boolean status it must do something.
I tried to use a Do...Loop but the application crashes.
Is there a way in visual basic 6 to use an infinite loop without stunk?
My code:
Do
asd1 = readValue1
asd2 = readValue2
If asd1 <> asd1ex Then
Text1.Text = "yes"
End If
If asd2 <> asd2ex Then
Text1.Text = "no"
End If
Loop While True
Make a timer and on that timer check the status, instead of the loop.
Solved after comment that explained where the data was coming from (async COM component's property):
working with vb6 IDE on a realtime client-server project. I have to read some variables
and when one of these changes status it sends a socket message to
server. With the sleep it stuck equally
What did not help:
DoEvents and sleep
DoEvents
Sleep 100
might help, will need to refer to the windows function sleep. But VB6 is single thread (well one for UI and one for logic) so you should have a way to get out of the loop. What are you really trying to do? Can you describe at a top level?
Are you working on the VB6 IDE or in VBA code in Office?
For sleep to work declare:-
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
See this too https://stackoverflow.com/a/4540553/1643558
If your showing a form to the user to read value 1 and 2 then you can use a modal form and have a button to click when they are done, and hide the form only when you like the values. No need to have a loop then. Can show an error MsgBox on a modal form too.
See http://www.tek-tips.com/viewthread.cfm?qid=1117372
Maybe remove the sleep and only keep the DoEvents.
You could also make a timer and on that timer check the status, instead of the loop
It looks like you're trying to set up a sort of event handler. In effect, your loop is "listening" for a change to the variable. You don't explain how the variables get changed, and this is important . If whatever is changing the variables can also raise an event, then you're home free--you can get rid of your loop and use the event handler to send the socket message. (This is probably why Deanna asked how the variables change.) This is the preferred way to do what you want, so you should find ways to raise an event if the variables change.