Constant update of the form's data - c#

This is basically a simple question.
I want to update the label dynamically when I press the capslock and numlock keys while the main form is open in the WinForm application on the .net platform. How can I do this?

You have to listen for keypress callbacks like that
private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
{
if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN)
{
Keys k = (Keys)Marshal.ReadInt32(lParam);
if (k == Keys.Capital)
{
label1.Text = "Heureka";
}
}
return CallNextHookEx(_hookID, nCode, wParam, lParam);
}

Related

How to prevent fullscreen/halfscreen on Windows

I am developing a single-window app on Windows with Unity.
I allow a user to resize the window but the aspect ratio must be kept.
I want to prevent fullscreen and halfscreen, because they break the aspect ratio.
I've found the following operations make an app fullscreen or halfscreen.
fullscreen:
clicking a maximize button on the title bar
dragging the window to top of screen
pressing Alt + Enter key
pressing Windows + Up-Arrow key
halfscreen:
dragging the window to left/right of screen
pressing Windows + Left/Right -Arrow key
I want to disable all of them.
This can disable a maximize button on the title bar.
HandleRef hWnd = new HandleRef(null, GetActiveWindow());
long style = GetWindowLong(hWnd, GWL_STYLE);
style &= ~WS_MAXIMIZEBOX;
SetWindowLong(hWnd, GWL_STYLE, style);
And this can disable Windows + Up-Arrow key.
private static IntPtr WndProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam)
{
switch (msg)
{
case WM_SYSCOMMAND:
if (wParam.ToInt32() == SC_MAXIMIZE) {
return IntPtr.Zero;
}
break;
}
return CallWindowProc(oldWndProcPtr, hWnd, msg, wParam, lParam);
}
But the other operations still work.
How can I disable the other operations?
private static IntPtr WndProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam)
{
switch (msg)
{
case WM_SYSCOMMAND:
if (wParam.ToInt32() == SC_MAXIMIZE) {
return IntPtr.Zero;
}
break;
// BY PASS *** Alt + Enter ***
case WM_KEYDOWN:
case WM_SYSKEYDOWN:
if (wParam == VK_RETURN)
if ((HIWORD(lParam) & KF_ALTDOWN))
return 0;
break;
}
return CallWindowProc(oldWndProcPtr, hWnd, msg, wParam, lParam);
}

C# Capture Keyboard Keys when focuse in a game

I coded a program to capture keys from any application.Now it works when I'm in any window an other applications, but when I'm in a game like dirt3 even run window form mode , when I press keys it just doesn't do it, I have to alt+tab and than press the keys and it'll work. Is there any way to make it so the key capture priority of the program is absolute, aka more important than will be capture even if I am in game?
Thanks
private static LowLevelKeyboardProc _proc = HookCallback;
private static IntPtr _hookID = IntPtr.Zero;
private static IntPtr SetHook(LowLevelKeyboardProc proc)
{
using (Process curProcess = Process.GetCurrentProcess())
using (ProcessModule curModule = curProcess.MainModule)
{
return SetWindowsHookEx(WH_KEYBOARD_LL, proc,
GetModuleHandle(curModule.ModuleName), 0);
}
}
protected static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
{
if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN)
{
int vkCode = Marshal.ReadInt32(lParam);
commandStr += ((Keys)vkCode);
if (commandStr.ToLower().Contains("ooff"))
{// do it work
}
}
return CallNextHookEx(_hookID, nCode, wParam, lParam);
}

postmessage to a process

I have a problem with posting a message to a process. When I send a key like A it is working great, but when I am sending a "special character" like Enter or F3 it is not working.
Here is my code :
[DllImport("user32.dll")]
private static extern IntPtr PostMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
public IntPtr SendKeystroke(IntPtr hWnd, Keys k)
{
return PostMessage(hWnd, 0x100, (IntPtr)k, (IntPtr)0);
}
And here is executing a method :
Process p = Process.GetProcessesByName("name")[0];
SendKeystroke(p.Handle, Keys.A);
SendKeystroke(p.Handle, Keys.Enter);

Subclass a native application from C#

I want to handle mouse click in a native MFC application from a C# application.
To do so I'm trying to subclass the native application. I don't get any errors, but the wndproc are newer invoked.
private const int GwlWndProc = -4;
private delegate int Win32WndProc(IntPtr hWnd, int msg, int wParam, int lParam);
[DllImport("user32")]
private static extern IntPtr SetWindowLong(IntPtr hWnd, int nIndex, Win32WndProc newProc);
Win32WndProc _newWndProc = MyWndProc;
SetLastError(0);
IntPtr oldWndProc = SetWindowLong(hWnd, GwlWndProc, _newWndProc);
if (oldWndProc == IntPtr.Zero)
{
int errorCode = Marshal.GetLastWin32Error();
if (errorCode != 0)
throw new Win32Exception(errorCode);
}
private int MyWndProc(IntPtr hWnd, int msg, int wParam, int lParam)
{
Debug.WriteLine("MyWndProc " + (WindowsMessage)msg);
if (msg == (int) WindowsMessage.LeftButtonDown)
{
MessageBox.Show("Clicked");
return 0;
}
else return CallWindowProc(_subclasses[hWnd], hWnd, msg, wParam, lParam);
}
Edit:
To get the hWnd I use GetForegroundWindow()
What I try to do is is to prevent the application to get the mouse click
I think you need to use hooking because SetWindowLong does not work across different processes: have a look here http://www.codeproject.com/Articles/5264/Cross-Process-Subclassing

Hooking into Windows message loop in WPF window adds white border on the inside

I am trying to create a WPF window with WindowStyle="None" (for custom buttons and no title) that cannot be resized. Setting ResizeMode to NoResize removes the aero border, which I want to keep.
I could set the min/max size properties and be done with it, except that:
The resize cursors are still visible, and
The window is displayed in response to a user action and fits to its contents. It displays an image, so the size changes.
So, I have a simple scheme that gets me 99% of the way there:
public class BorderedWindowNoResize : Window
{
[DllImport( "DwmApi.dll" )]
public static extern int DwmExtendFrameIntoClientArea(
IntPtr hwnd,
ref MARGINS pMarInset );
[DllImport( "user32.dll", CharSet = CharSet.Auto )]
public static extern IntPtr DefWindowProc(
IntPtr hWnd,
int msg,
IntPtr wParam,
IntPtr lParam );
public BorderedWindowNoResize()
{
Loaded += BorderedWindowNoResize_Loaded;
}
private void BorderedWindowNoResize_Loaded( object sender, RoutedEventArgs e )
{
IntPtr mainWindowPtr = new WindowInteropHelper( this ).Handle;
HwndSource mainWindowSrc = HwndSource.FromHwnd( mainWindowPtr );
mainWindowSrc.AddHook( WndProc );
}
private IntPtr WndProc( IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled )
{
var htLocation = DefWindowProc( hwnd, msg, wParam, lParam ).ToInt32();
if( msg == (uint)WM.NCHITTEST )
{
handled = true;
switch( htLocation )
{
case (int)HitTestResult.HTBOTTOM:
case (int)HitTestResult.HTBOTTOMLEFT:
case (int)HitTestResult.HTBOTTOMRIGHT:
case (int)HitTestResult.HTLEFT:
case (int)HitTestResult.HTRIGHT:
case (int)HitTestResult.HTTOP:
case (int)HitTestResult.HTTOPLEFT:
case (int)HitTestResult.HTTOPRIGHT:
htLocation = (int)HitTestResult.HTBORDER;
break;
}
}
return new IntPtr( htLocation );
}
}
Basically;
Override the window procedure.
Call the default window procedure.
If the message it is WM_NCHITTEST, check for the border results.
If it is a border, return the regular HTBORDER.
This works as far as allowing me to keep the aero window border and hiding the resize cursor(s), but it adds a ~5 pixel white border to the inside of my window.
In fact, even if I return the default windows procedure result at the top of WndPrc and do nothing else the border is still there. I need a different background color on my window, so this won't work for me.
Any ideas? Thanks in advance as always.
When you add your hook, you should only handle the messages you need to, and ignore the others. I believe you are handling certain messages twice, since you call DefWindowProc, but never set the handled parameter to true.
So in your case, you'd use:
private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) {
if (msg == (uint)WM.NCHITTEST) {
handled = true;
var htLocation = DefWindowProc(hwnd, msg, wParam, lParam).ToInt32();
switch (htLocation) {
case (int)HitTestResult.HTBOTTOM:
case (int)HitTestResult.HTBOTTOMLEFT:
case (int)HitTestResult.HTBOTTOMRIGHT:
case (int)HitTestResult.HTLEFT:
case (int)HitTestResult.HTRIGHT:
case (int)HitTestResult.HTTOP:
case (int)HitTestResult.HTTOPLEFT:
case (int)HitTestResult.HTTOPRIGHT:
htLocation = (int)HitTestResult.HTBORDER;
break;
}
return new IntPtr(htLocation);
}
return IntPtr.Zero;
}
Also, I'd probably add the hook in an OnSourceInitialized override, like so:
protected override void OnSourceInitialized(EventArgs e) {
base.OnSourceInitialized(e);
IntPtr mainWindowPtr = new WindowInteropHelper(this).Handle;
HwndSource mainWindowSrc = HwndSource.FromHwnd(mainWindowPtr);
mainWindowSrc.AddHook(WndProc);
}
You can try from anywhere in a WPF App
ComponentDispatcher.ThreadFilterMessage += new ThreadMessageEventHandler(ComponentDispatcherThreadFilterMessage);
and:
// ******************************************************************
private static void ComponentDispatcherThreadFilterMessage(ref MSG msg, ref bool handled)
{
if (!handled)
{
if (msg.message == WmHotKey)
{
HotKey hotKey;
if (_dictHotKeyToCalBackProc.TryGetValue((int)msg.wParam, out hotKey))
{
if (hotKey.Action != null)
{
hotKey.Action.Invoke(hotKey);
}
handled = true;
}
}
}
}

Categories

Resources