How to disable Windows lockscreen shortcut - c#

I want to disable Windows lock screen shortcut, because I want to remap it to some other function, but I don't want to disable actual computer locking mechanism.
I know that I can disable lockscreen altogether, this is not what I'm after.
I used this example: https://github.com/kverpoorten/BabyKeyboardBash
I changed the global keyboard hook to ignore all events if it detects that Left Win key is down. If LWin is down, I send a dummy key event.
All the LWin + KEY shortcuts are ignored, except Windows lockscreen shortcut. It seems that Windows catches that event before my app does.
Here is what is changed: https://github.com/kverpoorten/BabyKeyboardBash/blob/master/Keyboard.cs (line 198)
private IntPtr HookCallback( int nCode, IntPtr wParam, ref KBDLLHOOKSTRUCT lParam)
{
if ((NativeMethods.GetKeyState(VK_LWIN) & 0x8000) != 0)
{
Console.WriteLine("LWin down!");
return (System.IntPtr)1;
}
}
Currently I'm only testing if I can even catch the lockscreen shortcut. Everything so for suggests it is not possible.
Thanks!

Related

How to get hidden windows handle of the windows that show hidden system tray icons

I am trying to write application in C# that catch the handle of the hidden windows that appear when pressing the button ("Show hidden icons").
When we don't show all the notification area we have hidden system tray icons.
When we press on the button ("Show hidden icons") that show them we have a new window that all the icons inside it:
The hidden windows marked with green circle
How can I catch the handle of this hidden window ?
When I used Spy++ I couldn't find this window because the windows dissapears when I click any other key on the keyboard.
So I found the handle of the button and used the logging option:
In the logging results I only saw windows handles of the regular system tray tool bar:
So how can I catch the handle of the hidden window (the one I marked with green in the begging of my question, first pictuare).
References (links I found but didn't help me):
How to capture Notification icons properties using Microsoft Spy++
Get information about hidden tray icons in windows7
I succeed !
I succeed to catch it with Spy++:
Code solution:
static IntPtr GetHiddenSystemTrayHandle()
{
IntPtr hWndTray = User32.FindWindow("NotifyIconOverflowWindow", null);
if (hWndTray != IntPtr.Zero)
{
if (hWndTray != IntPtr.Zero)
{
// Windows caption "Overflow Notification Area"
hWndTray = User32.FindWindowEx(hWndTray, IntPtr.Zero, "ToolbarWindow32", null);
return hWndTray;
}
}
return IntPtr.Zero;
}

WPF Window Handle for Message Loop Only

I am writing a WPF application that will put an icon in the system tray and, as an exercise, I want to do this without depending on System.Windows.Forms and using its NotifyIcon or NativeWindow classes.
This is fairly easy - Shell_NotifyIcon isn't hard to call from C# - and, indeed, I have succeeded in my task.
As part of this effort, I have had to create a window handle for the sole purpose of receiving messages from the system-tray. I create the native window as follows:
// Create a 'Native' window
_hwndSource = new HwndSource(0, 0, 0, 0, 0, 0, 0, null, parentHandle);
_hwndSource.AddHook(WndProc);
The message loop is hooked in AddHook() and messages are processed in a function that looks like this:
private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
// Handle windows messages in this...
}
And, finally, when it comes time to destroy the thing, I close the window by posting it a WM_CLOSE message and disposing the HwndSource.
if (null != _hwndSource)
{
UnsafeNativeMethods.PostMessage(_hwndSource.Handle, WindowMessage.WM_CLOSE, 0, 0);
_hwndSource.Dispose();
_hwndSource = null;
}
My question is this: the first three parameters to the constructor of HwndSource are the class style, style and extended style of the native Win32 window, respectively. For a non-visible window that will only be used as a target for window-messages, what should they be?
My defaults of zero, zero and ... er.. zero do work but I have used Spy++ to examine what Windows.Forms.NotifyIcon does and it seems that the NativeWindow it creates have the following:
Class Style: <zero>
Styles: WS_CAPTION, WS_CLIPSIBLINGS,
WS_OVERLAPPED
Extended Styles: WS_EX_LEFT, WS_EX_LTRREADING,
WS_EX_RIGHTSCROLLBAR, WS_EX_WINDOWEDGE
Are any of those important for a non-visible window? (I think not.)
Windows style flags date from 1986, back when Windows v1.0 was released. There have been lots of appcompat hacks in the past 29 years and 10 major versions, Windows silently overrides style flags when the app specifies wonky ones. Nothing terribly wonky about this however, note that the value of the WS_OVERLAPPED style flag is 0. Which asks for a plain window, you automatically get the appropriate style flags for such a window.
Your HwndSource window has the exact same style flags, maybe you haven't found the correct one back in Spy++. So you don't have a problem. And no, they don't matter when the window never becomes visible.
Note a bug in your code, the WM_CLOSE message you post is never actually processed since you destroy the window right after calling PostMessage(). Just delete it, there is no point in asking the window nicely, it isn't going to object. You do however have to call Shell_NotifyIcon() with NIM_DELETE to delete the tray icon. Failure to do so leaves a "ghost" icon that only disappears when you move the mouse over it.
And do note that NotifyIcon is not as trivial as you assume it is, it has a non-obvious bug workaround that you are likely to overlook. You'll notice when the context menu refuses to close.

Send keyboard input to a specific child control

Ok, ill try to keep this quick and to the point.
In C# Winforms, I have a GUI window which displays a datagridview and a textbox. Basically what I want to do is, when either the Up Arrow key or Down arrow key is pressed, to send this input straight to the datagridview in order to move up and down through the list. If any other key is pressed, I want to send this input to my textbox.
I've tried over-writing the ProcessCmdKey method and setting focus based on the keyData keycode, but what happens is the first key press will only set the control focus, then, the 2nd key press will actually work on the focused control. I'd like the input to work immediately without that one key delay.
Extra details:
The GUI class is a generic class.
Hope this makes sense! I will edit if more details are needed
Thank you!
This is tricky to do, DataGridView is difficult to tinker with. It has the ProcessUpKey() and ProcessDownKey() methods but they are protected. You'd have to override the class and add public methods so you can call them. What you tried to do failed because by the time you got the keyboard message, it is already committed to the window that has the focus.
A bit of sly hackorama that will work without making big changes to your existing form is just posting the keyboard message back, but this time with the DataGridView as the target window. Paste this snippet into your form class:
protected override bool ProcessCmdKey(ref Message msg, Keys keyData) {
if (msg.HWnd != dataGridView1.Handle && (keyData == Keys.Up || keyData == Keys.Down)) {
PostMessage(dataGridView1.Handle, msg.Msg, msg.WParam, msg.LParam);
return true;
}
return base.ProcessCmdKey(ref msg, keyData);
}
[System.Runtime.InteropServices.DllImport("user32.dll")]
private static extern IntPtr PostMessage(IntPtr hWnd, int msg, IntPtr wp, IntPtr lp);

Intercept mouse click from other program

I’m trying to intercept mouse clicks from another program. I’m making a plugin for the program, that overlays a transparent form on the program and displays additional information. When I click on the transparent part of the form I can click on things in the main program. I don’t want this to happen (at least not every time - there are some parts where you are allowed to click and some parts where you aren’t but this isn’t the problem).
The way I’m doing this now is by using WH_MOUSE_LL, this is working fine and I can keep the mouse click from getting to the program by returning a non zero value (http://msdn.microsoft.com/en-gb/library/windows/desktop/ms644988(v=vs.85).aspx).
The problem is, this makes my main program lag, I don’t need to get notifications for all mouse movements, I only want to get a notification if the user actually clicked something. Is there any way I can limit the WH_MOUSE_LL so it only fires on mouse clicks? (The lag isn’t because of calculations in the MouseHookProc method - it’s currently doing nothing except for calling: CallNextHookEx(hHook, nCode, wParam, lParam).)
I’ve tried to fix this by using a global hook (http://www.codeproject.com/Articles/18638/Using-Window-Messages-to-Implement-Global-System-H) that hooks the WM_MOUSEACTIVATE message. The idea was to only hook up the WH_MOUSE_LL when I received a WM_MOUSEACTIVATE notification. Unfortunately WH_MOUSE_LL click notification gets sent before WM_MOUSEACTIVATE so this doesn't work.
EDIT:
#Nanda here’s the proc code:
public int MouseHookProc(int nCode, IntPtr wParam, IntPtr lParam)
{
return WindowUtility.CallNextHookEx(hHook, nCode, wParam, lParam);
}
As you can see I’m not doing very much with it atm, but it already lags...
#Cody Gray I’ve made a very small test for the Form handling the messages:
public class Form1 : Form
{
private TrackBar m_Trackbar;
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
public Form1()
{
m_Trackbar = new System.Windows.Forms.TrackBar();
m_Trackbar.LargeChange = 1;
m_Trackbar.Location = new System.Drawing.Point(5, 10);
m_Trackbar.Maximum = 100;
m_Trackbar.Size = new System.Drawing.Size(280, 40);
m_Trackbar.Value = 100;
this.Controls.Add(m_Trackbar);
m_Trackbar.Scroll += new System.EventHandler(this.m_TrackbarScroll);
}
private void m_TrackbarScroll(object sender, System.EventArgs e)
{
this.Opacity = ((Convert.ToDouble(m_Trackbar.Value)) / 100);
}
protected override void WndProc(ref Message m)
{
switch (m.Msg)
{
case 0x201: //WM_LBUTTONDOWN
Console.WriteLine("MouseButton Down!");
//I could copy the Message over to the MainProgram with this right?
//SendMessage(MainProgramHwnd, m.Msg, m.WParam, m.LParam);
//This will also only work on an opacity higher than 0.
break;
}
base.WndProc(ref m);
}
}
When you said: “return that it's transparent and let it be routed to the window underneath it?” Can I do this by using SendMessage and basically copying the message I receive in my WndProc method?
To make things more complicated I’m also using this form http://www.codeproject.com/Articles/1822/Per-Pixel-Alpha-Blend-in-C. To my understanding this enables me to draw bitmaps on the form who are Anti Aliasing against the background. With this form there seems to be no way to set the opacity, as it’s just transparent all the time. Is there a better way to draw bitmaps on a Form?
You may want to look into Easyhook (http://easyhook.codeplex.com/) which will allow you to hook Windows API calls from a single process rather than for all processes.

Ignore Keyboard Input

I have an application that displays a keyboard and tests whether the keys have been pressed or not. The issue I'm having is that when certain keys are pressed like the arrow buttons/tab, the keyboard graphic loses focus and it starts accessing menu items/etc. I tried registering to the preview mouse down event in the MainWindow and setting e.handled = true. But this does not work all the time. It would also be nice if there was a way to disable the windows button as well.
I think you would need to get into the operating system code for your solution. The OS treats some keys different from normal, so you may not be able to peak at a key's value or even that it has been pressed before it takes control away from your application.
I saw this kind of thing back when I was writing machine code BIOS routines for CP/M. Windows is much more involved than that. I quit writing code to control hardware when I started to use Windows 3.1.
I used this class:
http://gist.github.com/471698
I replaced line 99 with this code:
return EnableKeyboard ? InterceptKeys.CallNextHookEx(hookId, nCode, wParam, lParam) : (IntPtr) 1;
Where EnableKeyboard is set by the user.

Categories