I'm creating a program to manage a local network but Im having a little problem.
When the form starts, it starts hidden.
I used this code to hide it:
Protected Overrides Sub SetVisibleCore(ByVal value As Boolean)
If Not Me.IsHandleCreated Then
Me.CreateHandle()
value = False
End If
MyBase.SetVisibleCore(value)
End Sub
What I want exactly is to show the form when I click ALT+X for example.
Use a Global Hotkey. That way you don't have to worry about your Application having focus. A good example for VB.Net is here:
http://www.kirsbo.com/How_to_add_global_hotkeys_to_applications_in_VB.NET
To summarise. Define a HotKey class:
Public Class Hotkey
#Region "Declarations - WinAPI, Hotkey constant and Modifier Enum"
''' <summary>
''' Declaration of winAPI function wrappers. The winAPI functions are used to register / unregister a hotkey
''' </summary>
Public Declare Function RegisterHotKey Lib "user32" _
(ByVal hwnd As IntPtr, ByVal id As Integer, ByVal fsModifiers As Integer, ByVal vk As Integer) As Integer
Public Declare Function UnregisterHotKey Lib "user32" (ByVal hwnd As IntPtr, ByVal id As Integer) As Integer
Public Const WM_HOTKEY As Integer = &H312
Enum KeyModifier
None = 0
Alt = &H1
Control = &H2
Shift = &H4
Winkey = &H8
End Enum 'This enum is just to make it easier to call the registerHotKey function: The modifier integer codes are replaced by a friendly "Alt","Shift" etc.
#End Region
#Region "Hotkey registration, unregistration and handling"
Public Shared Sub registerHotkey(ByRef sourceForm As Form, ByVal triggerKey As String, ByVal modifier As KeyModifier)
RegisterHotKey(sourceForm.Handle, 1, modifier, Asc(triggerKey.ToUpper))
End Sub
Public Shared Sub unregisterHotkeys(ByRef sourceForm As Form)
UnregisterHotKey(sourceForm.Handle, 1) 'Remember to call unregisterHotkeys() when closing your application.
End Sub
Public Shared Sub handleHotKeyEvent(ByVal hotkeyID As IntPtr)
MsgBox("The hotkey was pressed")
End Sub
#End Region
End Class
Then add the following Sub to your main form:
'System wide hotkey event handling
Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
If m.Msg = Hotkey.WM_HOTKEY Then
Hotkey.handleHotKeyEvent(m.WParam)
End If
MyBase.WndProc(m)
End Sub
Then register a HotKey in the startup code for your form:
Hotkey.RegisterHotKey(Me, "X", Hotkey.KeyModifier.Alt)
The first parameter is the form, the second is the key to be handled and the third is the modifier key. Once this Hotkey is registered it will trigger code in HotKey.handleHotKeyEvent.
You can then use some sort of Callback to trigger a method in the calling form itself if you so desire.
Related
I want to copy the highlighted text from outside of winform using vb.net.
For example, if the user highlights a text in a browser or in notepad it should be copied into a textbox in a winform.
Any help would be great!
Thanks in advance.
Ok!
Thanks to this link I got my answer.
My Logic is First of all the user will highlight a value, not specific to browser but anywhere.
then the user will press the Hotkey, In my case it's F8. Then Code will trigger the copy command and then retrieve the Clipboard value and will assign it to a textbox text.
Here is the Full Code along with Helping Class.
Hotkey.vb
Public Class Hotkey
#Region "Declarations - WinAPI, Hotkey constant and Modifier Enum"
''' <summary>
''' Declaration of winAPI function wrappers. The winAPI functions are used to register / unregister a hotkey
''' </summary>
Private Declare Function RegisterHotKey Lib "user32" _
(ByVal hwnd As IntPtr, ByVal id As Integer, ByVal fsModifiers As Integer, ByVal vk As Integer) As Integer
Private Declare Function UnregisterHotKey Lib "user32" (ByVal hwnd As IntPtr, ByVal id As Integer) As Integer
Public Const WM_HOTKEY As Integer = &H312
Enum KeyModifier
None = 0
Alt = &H1
Control = &H2
Shift = &H4
Winkey = &H8
End Enum 'This enum is just to make it easier to call the registerHotKey function: The modifier integer codes are replaced by a friendly "Alt","Shift" etc.
#End Region
#Region "Hotkey registration, unregistration and handling"
Public Shared Sub registerHotkey(ByRef sourceForm As Form, ByVal triggerKey As String, ByVal modifier As KeyModifier)
RegisterHotKey(sourceForm.Handle, 1, modifier, &H77)
End Sub
Public Shared Sub unregisterHotkeys(ByRef sourceForm As Form)
UnregisterHotKey(sourceForm.Handle, 1) 'Remember to call unregisterHotkeys() when closing your application.
End Sub
Public Shared Sub handleHotKeyEvent(ByVal hotkeyID As IntPtr)
SendKeys.Send("^(c)") 'for Ctrl-C[/CODE]
End Sub
#End Region
End Class
This Section will Trigger the Hotkey Code and do the rest of logic
Main Form
'This Program will wait for a key to press in our case it will wait for the F8 key to be press
'Then it will copy the highlighted text (Outside and Inside of the form) and will concatinate the text with a webaddress'
Imports Name_Of_Your_Project.Hotkey
Public Class Form1
'This Chunk of code will register the F8 key as a main key for the Program'
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Hotkey.registerHotkey(Me, "f8", Hotkey.KeyModifier.None)
End Sub
'This sub will trigger the Hotkey Sub Code in the Hotkey.vb Class'
Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
If m.Msg = Hotkey.WM_HOTKEY Then
Hotkey.handleHotKeyEvent(m.WParam)
'After pressing the F8 key It will copy the highlighted data from anywhere and store it to the clipboard'
If Clipboard.ContainsText Then
Try
Textbox1.text = My.Computer.Clipboard.GetData(DataFormats.Text).ToString
Catch ex As Exception
MessageBox.Show("Error in Program" + ex.ToString())
End Try
End If
End If
MyBase.WndProc(m)
End Sub
'System wide hotkey event handling
End Class
I'm trying to use RegisterHotkey without adding a Form class.
Right now I have an "Empty Project(.NET Framework) Visual Basic" with two classes in it, as follows.
Imports System.Windows.Forms
Public Class AppCore
Inherits ApplicationContext
Public myHotkeys As New clsHotkey
Shared Sub main()
Console.WriteLine("starting " & Now)
Dim myAppCore As AppCore
myAppCore = New AppCore
System.Windows.Forms.Application.Run(myAppCore)
End Sub
Public Const MOD_CONTROL As Integer = &H11
Public Const MOD_SHIFT As Integer = &H10
Public Const MOD_ALT As Integer = &H1
Public Const WM_HOTKEY As Integer = &H312
Public Declare Function RegisterHotKey Lib "user32.dll" Alias "RegisterHotKey" (ByVal hwnd As IntPtr, ByVal id As Integer, ByVal fsModifiers As Integer, ByVal vk As Integer) As Integer
Public Declare Function UnregisterHotKey Lib "user32.dll" Alias "UnregisterHotKey" (ByVal hwnd As IntPtr, ByVal id As Integer) As Integer
Sub New()
RegisterHotKey(myHotkeys.Handle, 100, 0, Keys.F6)
RegisterHotKey(myHotkeys.Handle, 200, MOD_ALT, Keys.F7)
End Sub
End Class
Imports System.Windows.Forms
Public Class clsHotkey
Inherits NativeWindow
Public Const WM_HOTKEY As Integer = &H312
Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
MyBase.WndProc(m)
Beep()
If m.Msg = WM_HOTKEY Then
Select Case CType(m.WParam, Integer)
Case 100
Console.WriteLine("ID 100")
Case 200
Console.WriteLine("ID 200")
End Select
End If
End Sub
End Class
Now this will compile without errors and run.
In the WndProc of clsHotKey, I put a Beep(), but this never gets called.
The original example I used to build this used the DefWndProc on a Form Class, however the NativeWindow's DefWndProc is not overrideable according to the IDE.
I have tried rebooting the computer, in case the hooks for the hotkeys were just not releasing, but that isn't it.
I am at a loss what is wrong here. Are there any ways to watch the windows event distribution system, maybe find out where the message ends and why it does not trigger WndProc ?
Thanks !
RegisterHotKey(myHotkeys.Handle, 100, 0, Keys.F6)
It is debuggable, you can see that myHotkeys.Handle is zero. Not so sure how that went wrong, using Beep() to debug the code is a hint. Not necessary, you can simply use a breakpoint.
You might have gotten used to the Form.Handle property, when you use that one then it automatically also creates the window to ensure the Handle is valid. But that is not what NativeWindow does, you have to ask. Fix:
Sub New()
myHotkeys.CreateHandle(New CreateParams())
RegisterHotKey(myHotkeys.Handle, 100, 0, Keys.F6)
...
End Sub
Works fine now.
Is there any way to make a cursor look something like the blinking, square cursor used in console applications, say, inside of a text box instead of the regular vertical line? Example:
https://gyazo.com/db9f5661d493c32e48434eed2fa45252
You can control the caret (cursor) using the Win API Caret Functions.
A simple custom WinForm TextBox can be given a blinking caret like this:
Public Class MyTB : Inherits TextBox
<DllImport("user32.dll", SetLastError:=True)> _
Private Shared Function CreateCaret(ByVal hWnd As IntPtr, ByVal hBitmap As IntPtr, ByVal nWidth As Integer, ByVal nHeight As Integer) As Boolean
End Function
<DllImport("user32.dll")>
Private Shared Function DestroyCaret() As Boolean
End Function
<DllImport("user32.dll")>
Private Shared Function SetCaretBlinkTime(ByVal uMSeconds As UInt32) As Boolean
End Function
<DllImport("user32.dll")> _
Private Shared Function ShowCaret(ByVal hWnd As IntPtr) As Boolean
End Function
Protected Overrides Sub OnGotFocus(e As EventArgs)
MyBase.OnGotFocus(e)
MyTB.CreateCaret(Me.Handle, Nothing, 5, Me.Font.Height)
MyTB.SetCaretBlinkTime(500UI)
MyTB.ShowCaret(Me.Handle)
End Sub
Protected Overrides Sub OnLostFocus(e As EventArgs)
MyBase.OnLostFocus(e)
MyTB.DestroyCaret()
End Sub
End Class
I'm making an app for the company I work for and I was wondering how to customise the window's context menu like PuTTY's (aka, it has "New Session..." etc.). I've looked all over Google and can't find the answer I'm looking for.
make a new module and add Imports System.Runtime.InteropServices on top
then declare this
<Flags()> _
Public Enum MenuFlags As Integer
MF_BYPOSITION = 1024
MF_REMOVE = 4096
MF_SEPARATOR = 2048
MF_STRING = 0
End Enum
<DllImport("user32.dll", CallingConvention:=CallingConvention.Cdecl)> _
Public Function GetSystemMenu(ByVal hWnd As IntPtr, Optional ByVal bRevert As Boolean = False) As IntPtr
End Function
<DllImport("user32.dll", CharSet:=CharSet.Auto)> _
Public Function AppendMenu(ByVal hMenu As IntPtr, ByVal uFlags As MenuFlags, ByVal uIDNewItem As Int32, ByVal lpNewItem As String) As Boolean
End Function
then on your form load handler add this code
Dim sysmenu As IntPtr = GetSystemMenu(Me.Handle)
AppendMenu(sysmenu, MenuFlags.MF_STRING, &H1FFF, "Hello")
then, in order to be able to capture the user click on your new menu item, you have to implement this function which will capture all messages, just add it to your form code
Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
If m.Msg = WM_SYSCOMMAND Then
If m.WParam.ToInt32 = &H1FFF Then
' your menu item is clicked, call a function here
End If
End If
MyBase.WndProc(m)
End Sub
I asked a question earlier about keyhooks in vb.net.
My current issue is such:
I have created a program which should perform a certain action whenever a certain group of keys is pressed at the same time. The program must be able to run in the background, or in the system tray or something. Essentially, this should work like the KeyDown event on a form, except the form in this case is everything.
I'm not certain if there is a way to do this directly from within the .net API, but if there is I certainly have not found it.
That doesn't require a keyboard hook, you'll want to register a hot key. Much easier to implement and much less demanding of system resources. Here's an example, it restores the form to the foreground if it was minimized. Note that you can register more than one key:
Imports System.Runtime.InteropServices
Imports System.ComponentModel
Public Class Form1
Private Const cHotKeyId As Integer = 0
Protected Overrides Sub OnLoad(ByVal e As System.EventArgs)
'--- Register Ctrl + Shift + U as a hot key
If Not RegisterHotKey(Me.Handle, cHotKeyId, MOD_CONTROL + MOD_SHIFT, Keys.U) Then
Throw New Win32Exception()
End If
MyBase.OnLoad(e)
End Sub
Protected Overrides Sub OnFormClosing(ByVal e As System.Windows.Forms.FormClosingEventArgs)
UnregisterHotKey(Me.Handle, cHotKeyId)
MyBase.OnFormClosing(e)
End Sub
Protected Overrides Sub WndProc(ByRef m As Message)
Console.WriteLine(m.ToString())
If (m.Msg = WM_HOTKEY AndAlso m.WParam = CType(cHotKeyId, IntPtr)) Then
Me.Visible = True
If Me.WindowState = FormWindowState.Minimized Then Me.WindowState = FormWindowState.Normal
SetForegroundWindow(Me.Handle)
End If
MyBase.WndProc(m)
End Sub
'--- P/Invoke declarations
Private Const WM_HOTKEY As Integer = &H312
Private Const MOD_ALT As Integer = &H1
Private Const MOD_CONTROL As Integer = &H2
Private Const MOD_SHIFT As Integer = &H4
Private Declare Function RegisterHotKey Lib "user32.dll" (ByVal hWnd As IntPtr, ByVal id As Integer, ByVal fsModifier As Integer, ByVal vk As Integer) As Boolean
Private Declare Function UnregisterHotKey Lib "user32.dll" (ByVal hWnd As IntPtr, ByVal id As Integer) As Boolean
Private Declare Function SetForegroundWindow Lib "user32.dll" (ByVal hWnd As IntPtr) As Boolean
End Class