In C#, I write code to detect arrival/removal of device information from Serial Port.
private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
const int WM_DEVICECHANGE = 0x0219;
// System detects a new device
const int DBT_DEVICEARRIVAL = 0x8000;
// The device has been succesfully removed from the system
const int DBT_DEVICEREMOVECOMPLETE = 0x8004;
if (msg == WM_DEVICECHANGE)
{
switch (wParam.ToInt32())
{
case DBT_DEVICEARRIVAL:
MessageBox.Show("New device added");
break;
case DBT_DEVICEREMOVECOMPLETE:
MessageBox.Show("An device has been removed from system");
break;
default:
break;
}
}
return IntPtr.Zero;
}
I searched on Google and I founded this article.
http://www.codeproject.com/Articles/60579/A-USB-Library-to-Detect-USB-Devices
It gives me exactly the code I need to write. But I have to provide to it a PID and VID.
So that, I need to combine my code with above code to make an program that automatically show information about arrival/removal of a device.
My problems is: From the WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled), how to extract the device's VID and PID?.
Related
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);
}
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);
i'm currently trying to get wndproc handling in wpf but without any success..
i need to get the event of window created, window activated and window destroid events.
here's what i tried so far
int uMsgNotify;
public MainWindow()
{
InitializeComponent();
WinApi.SetTaskmanWindow(new WindowInteropHelper(this).Handle);
WinApi.RegisterShellHookWindow(new WindowInteropHelper(this).Handle);
uMsgNotify = WinApi.RegisterWindowMessage("SHELLHOOK");
MainForm.ShowInTaskbar = false;
MainForm.ShowActivated = true;
}
protected override void OnSourceInitialized(EventArgs e)
{
base.OnSourceInitialized(e);
HwndSource source = PresentationSource.FromVisual(this) as HwndSource;
source.AddHook(WndProc);
}
private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
IntPtr handle;
if (msg == uMsgNotify)
{
switch (wParam.ToInt32())
{
case WinApi.HSHELL_WINDOWCREATED:
handle = lParam;
string windowName = GetWindowName(handle);
IntPtr hWnd = WinApi.FindWindow(null, windowName);
add_icon(windowName, handle);// add new task's icon in taskbar
break;
case WinApi.HSHELL_WINDOWACTIVATED:
handle = lParam;
break;
case WinApi.HSHELL_WINDOWDESTROYED:
handle = lParam;
del_icon(handle); //remove icon from taskbar
break;
}
}
return IntPtr.Zero;
}
private static string GetWindowName(IntPtr hWnd)
{
// Allocate correct string length first
int length = WinApi.GetWindowTextLength(hWnd);
StringBuilder sb = new StringBuilder(length + 1);
WinApi.GetWindowText(hWnd, sb, sb.Capacity);
return sb.ToString();
}
code doesn't give any kind of runtime error whatsoever.... but it wont work..
to make more sense i'm developing an alternate shell for windows for my gaming cafe... where it needs to have a kind of taskbar..
any help?
I don't know if you still need it but : If you use ShowInTaskbar = false, it won't be able to catch any message with WndProc.
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
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;
}
}
}
}