How to endlessly check if key was pressed? - c#

I was making a small program that shows if numlock or capslock was on or off (because my laptop doesn't have those LEDs so I touhgt it would be interesting to make something like this). What I was trying to achieve is that text would change if key was pressed or not. What I have so far is program showing if they was on or off before running the program it self. How to make program react to changes?
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace WindowsFormsApplication3
{
public partial class Form1 : Form
{
[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true, CallingConvention = CallingConvention.Winapi)]
public static extern short GetKeyState(int keyCode);
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
looper();
}
public void looper()
{
cLock_check();
nLock_check();
sLock_check();
}
public void cLock_check()
{
bool CapsLock = (((ushort)GetKeyState(0x14)) & 0xffff) != 0;
if (CapsLock)
lbl_cLock_onOff.Text = "ON";
else
lbl_cLock_onOff.Text = "OFF";
}
public void nLock_check()
{
bool NumLock = (((ushort)GetKeyState(0x90)) & 0xffff) != 0;
if (NumLock)
lbl_nLock_onOff.Text = "ON";
else
lbl_nLock_onOff.Text = "OFF";
}
public void sLock_check()
{
bool ScrollLock = (((ushort)GetKeyState(0x91)) & 0xffff) != 0;
if (ScrollLock)
lbl_sLock_onOff.Text = "ON";
else
lbl_sLock_onOff.Text = "OFF";
}
}
}

You should implement a global keyboard hook, as described in this article. Compare vkCode to VK_NUMLOCK, VK_CAPITAL and VK_SCROLL and call your relevant update function.

Create a timer object, give it a reasonable interval (For most 'responsive' UI issues 300 msec is appropriate), and set the Tick handler to call the looper method:
Timer checkState;
public Form1()
{
InitializeComponent();
checkState = new Timer { Interval = 300};
checkState.Tick += (o,e) => looper();
chechState.Start();
}

Related

How to drag Custom Usercontrol on windows form?

I have a sln file with two projects in it, the first project contains a Custom Usercontrol inherited from Button, the second project has a form and a button on it, when i click the button on the form the Custom Usercontrol which is a button will be added to the form, now i should be able to drag the button on the form wherever i want to on the form after i run it, how to do it.
public partial class buttCustom : Button
{
public buttCustom()
{
InitializeComponent();
}
}
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void toolStripButton1_Click(object sender, EventArgs e)
{
this.Controls.Add(buttControl);
}
}
i should be able to move that green custom button in the image to move anywhere i want using mouse.
I think you can add the code below in your custom User Control class.
[DllImport("user32.DLL", EntryPoint = "ReleaseCapture")]
private extern static void ReleaseCapture();
[DllImport("user32.DLL", EntryPoint = "SendMessage")]
private extern static void SendMessage(System.IntPtr one, int two, int three, int four);
private void CustomCtrl_MouseDown(object sender, MouseEventArgs e)
{
ReleaseCapture();
SendMessage(Handle, 0x112, 0xf012, 0);
}
So the result would be something like:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace MyViewer.CustomControls
{
public partial class CustomCtrl : UserControl
{
public string formTitleText
{
get { return label1.Text; }
set { label1.Text = value; }
}
public CustomCtrl()
{
InitializeComponent();
}
[DllImport("user32.DLL", EntryPoint = "ReleaseCapture")]
private extern static void ReleaseCapture();
[DllImport("user32.DLL", EntryPoint = "SendMessage")]
private extern static void SendMessage(System.IntPtr one, int two, int three, int four);
// Add MouseDown Event
private void CustomCtrl_MouseDown(object sender, MouseEventArgs e)
{
ReleaseCapture();
SendMessage(Handle, 0x112, 0xf012, 0);
}
}
}
Then you can add the custom User Control which can be draggable to your form from the toolbox.
Agula Otgonbaatar has the correct answer, however I use these values
public const int WM_NCLBUTTONDOWN = 0xA1;
public const int HT_CAPTION = 0x2;
I also check for MouseButton.Left in my MouseDown handler, so it would be:
if (e.Button == MouseButtons.Left)
{
ReleaseCapture();
SendMessage(Handle, WM_NCLBUTTONDOWN, HT_CAPTION, 0);
}
This works for me.

Any Hotkey I want to register seems to already be taken

I am trying to register a global hotkey in Visual c# 2012, build target framework .NET3, after using http://www.dreamincode.net/forums/topic/180436-global-hotkeys/ as a tutorial, I got the following (abbreviated) files:
GlobalHotkey.cs
using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace barcodelabel
{
public class GlobalHotkey
{
private int modifier;
private int key;
private IntPtr hWnd;
private int id;
public GlobalHotkey(int modifier, Keys key, Form form)
{
this.modifier = modifier;
this.key = (int)key;
this.hWnd = form.Handle;
id = this.GetHashCode();
}
public bool Register()
{
return RegisterHotKey(hWnd, id, modifier, key);
}
public bool Unregister()
{
return UnregisterHotKey(hWnd, id);
}
public override int GetHashCode()
{
return modifier ^ key ^ hWnd.ToInt32();
}
[DllImport("user32.dll")]
private static extern bool RegisterHotKey(IntPtr hWnd, int id, int fsModifiers, int vk);
[DllImport("user32.dll")]
private static extern bool UnregisterHotKey(IntPtr hWnd, int id);
}
}
GlobalHotkeyConstants.cs
using System;
using System.Collections.Generic;
using System.Text;
namespace barcodelabel
{
class GlobalHotkeyConstants
{
public const int NOMOD = 0x0000;
public const int ALT = 0x0001;
public const int CTRL = 0x0002;
public const int SHIFT = 0x0004;
public const int WIN = 0x0008;
//windows message id for hotkey
public const int WM_HOTKEY_MSG_ID = 0x0312;
}
}
My Form1.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Windows;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using Microsoft.Win32;
namespace barcodelabel
{
public partial class Form1 : Form
{
private GlobalHotkey ghk;
protected override void WndProc(ref Message m)
{
if (m.Msg == GlobalHotkeyConstants.WM_HOTKEY_MSG_ID) {
MessageBox.Show("HOTKEY PRESSED");
}
base.WndProc(ref m);
}
public Form1()
{
InitializeComponent();
this.ghk = new GlobalHotkey(GlobalHotkeyConstants.SHIFT, Keys.F10, this);
}
private void Form1_Load(object sender, EventArgs e)
{
if (!this.ghk.Register())
{
MessageBox.Show("Hotkey could not be registered");
}
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
this.ghk.Unregister();
}
}
No matter what hotkey I want to choose, it can not be registered. I tried using Hotkey Explorer from http://hkcmdr.anymania.com/ to check if the hotkey already was taken, but it only told me it was free.
What can I do to solve this?
I've wrote down your code in my VS and it worked properly. If you want to find the error, don't check a Boolean returned form API only. if it returns False, try using GetLastError API. Then you will have an error code. Refer to MSDN and get the error's description.

How do I capture the Screensaver Event?

I'm trying to capture a Screensaver event, however when I run my application it throws the following exception;
Unable to find an entry point named 'SystemParametersinfo' in DLL 'user32.dll'.
this is my code so far, any and all help would be greatly appreciated =D
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using NLog;
using Topshelf;
using OsWatch;
using Microsoft.Win32;
using System.Runtime.InteropServices;
namespace NotifyIcon
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
SystemEvents.SessionSwitch += SystemEvents_SessionSwitch;
}
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern int SystemParametersinfo(int uAction, int uParam, ref int ipvParam, int fuWinini);
const int SPI_GETSCREENSAVERRUNNING = 114;
static int screenSaverRunning = -1;
int ok = SystemParametersinfo(SPI_GETSCREENSAVERRUNNING, 0, ref screenSaverRunning, 0);
private void ScreenSaver()
{
if (ok == 0)
{
Logger.Trace("SCREENSAVER OFF");
}
if (screenSaverRunning != 0)
{
Logger.Trace("SCREENSAVER ON");
}
}

How to achieve the equivalent of WNetAddConnection2 with a timeout?

The following call to WNetAddConnection2 seems to hang forever. Note that the machine name is intentionally wrong - I'd like this to fail fast rather than block forever. Is there a way to achieve similar functionality but with a timeout?
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Diagnostics;
namespace WindowsFormsApplication2
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
[StructLayout(LayoutKind.Sequential)]
public class NETRESOURCE
{
public int dwScope;
public int dwType;
public int dwDisplayType;
public int dwUsage;
public string LocalName;
public string RemoteName;
public string Comment;
public string Provider;
}
[DllImport("mpr.dll")]
public static extern int WNetAddConnection2(NETRESOURCE netResource, string password, string username, int flags);
private void Form1_Load(object sender, EventArgs e)
{
NETRESOURCE myResource = new NETRESOURCE();
myResource.dwScope = 0;
myResource.dwType = 0; //RESOURCETYPE_ANY
myResource.dwDisplayType = 0;
myResource.LocalName = "";
myResource.RemoteName = #"\\invalid.machine.com";
myResource.dwUsage = 0;
myResource.Comment = "";
myResource.Provider = "";
int returnValue = WNetAddConnection2(myResource, "password", "username", 0); //hangs forever
Debug.Print("Finished connecting");
}
}
}
On earlier versions of Windows it was impossible to terminate a process that was stuck in one of the WNetAddConnection functions. This was fixed in Vista. According to Larry Osterman, the fix is the CancelSynchronousIo function.
The solution to your problem is:
Start a new thread to run WNetAddConnection2
Set a timer or wait in your existing thread.
After the timeout call CancelSynchronousIo specifying the handle of the connection thread.
I can't think of any reason why this would interact badly with .Net, but I haven't actually tried it...

Why can I clickthrough my form?

I am experimenting and trying to figure out DWM and Windows Aero. So far, I think I pretty much have it, all except for some strange reason, when I click the thicker part of my form, my click goes right through it, and I can't figure out how to stop it.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
int en;
public Form1()
{
InitializeComponent();
DwmIsCompositionEnabled(ref en);
if (en > 0 && System.Environment.OSVersion.Version.Major >= 6)
{
en = 0;
MARGINS mg = new MARGINS();
mg.m_Buttom = 0;
mg.m_Left = 0;
mg.m_Right = 0;
mg.m_Top = 25;
DwmExtendFrameIntoClientArea(this.Handle, ref mg);
this.BackColor = Color.Magenta;
this.TransparencyKey = Color.Magenta;
}
}
public struct MARGINS
{
public int m_Left;
public int m_Right;
public int m_Top;
public int m_Buttom;
}
[System.Runtime.InteropServices.DllImport("dwmapi.dll")]
public extern static int DwmExtendFrameIntoClientArea(IntPtr hwnd, ref MARGINS margin);
[System.Runtime.InteropServices.DllImport("dwmapi.dll")]
public extern static int DwmIsCompositionEnabled(ref int en);
}
}
That's because you have
this.BackColor = Color.Magenta;
this.TransparencyKey = Color.Magenta;
Remove line with transparency. This also happens in WindowsForms. I think it's by design, not bug.

Categories

Resources