I want to watermark a textbox, and found several different ways of doing it, but one that I liked uses SendMessage and an external DLL. However, I think I heard somewhere that doing it this way can cause BSOD since it isn't managed. Is this true, or is it just hear-say.
http://vidmar.net/weblog/archive/2008/11/05/watermarked-textbox-in-windows-forms-on-.net.aspx
private const uint ECM_FIRST = 0x1500;
private const uint EM_SETCUEBANNER = ECM_FIRST + 1;
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, uint wParam, [MarshalAs(UnmanagedType.LPWStr)] string lParam);
The short answer is no. It won't cause a BSOD, although it could crash your program.
WinForms is basically built on top of Windows API calls, so when done right, custom API calls should work good as well.
One other thing to keep in mind is that if you do call the Windows API, it may create portability issues, such as when porting to Mono, as those DLLs will most likely not be available.
Related
I am trying to call WaitForSingleObject method from C#, as documented here:
https://msdn.microsoft.com/en-us/library/windows/desktop/ms687032(v=vs.85).aspx
In order to call this function I need to create a Handle, or I need to get a Handle of type IntPtr, how can it be done?
I've tried this function that I found:
http://www.pinvoke.net/default.aspx/kernel32.WaitForSingleObject
[DllImport("coredll.dll", SetLastError = true, CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Auto)]
public static extern IntPtr CreateEvent(HANDLE lpEventAttributes, [In, MarshalAs(UnmanagedType.Bool)] bool bManualReset, [In, MarshalAs(UnmanagedType.Bool)] bool bIntialState, [In, MarshalAs(UnmanagedType.BStr)] string lpName);
Or for instance, when I am getting handle from console:
IntPtr handle = Process.GetCurrentProcess().MainWindowHandle;
It throws a DllNotFoundException.
What's the issue here?
I need it in order to run the process with this function call, and to take a dump form its process, for my ClrMd library learning.
Any help will be appreciated.
Code sample:
static void Main(string[] args)
{
var autoEvent = new AutoResetEvent(false);
//this is where I get the DllNotFoundException
WaitForSingleObject(autoEvent.Handle, WAIT_TIMEOUT );
}
[DllImport("kernel32.dll")]
static extern uint WaitForMultipleObjects(uint nCount, IntPtr[] lpHandles, bool bWaitAll, uint dwMilliseconds);
public const Int32 WAIT_TIMEOUT = 0x102;
I would not go through WinApi to get this from C#: you have EventWaitHandler and other synchronization objects in C#, use them:
WaitHandle wh = new EventWaitHandler();
//do whatever you need
...
WaitHandler.WaitOne(wh); // equivalent to WaitForSingleObject in WinApi
you can use wh.SafeWaitHandle if you really need to interop with WinApi
Also I suspect Process.GetCurrentProcess().MainWindowHandle cannot work in a Console Application, that has not any window at all
I want to call native method (WaitForMultipleObjects) which waits for some handle (don't really mind which one), then I want to see it on thread stack using ClrMd library, from dump file
OK, so what about new ManualResetEvent(false).WaitOne()? This should show up in the dump file. And it's reliable.
Just picking any existing handle is not reliable because it might be signaled or be destroyed at any time. Or, you might change its state by waiting. There is no need, a ManualResetEvent can create you a fresh handle.
My mistake I've posted WaitForMultipleObjects instead of WaitForSingleObject, the main issue was that WaitForSingleObject stayed with DllImport("coredll.dll"...) I don't know where did I found it but I did...
Sorry for the confusion
I am using c#.net to develop a winform application.My winform application is using the below components
1)Win 32 dlls (using System.Runtime.InteropServices)
2)Timers(3 in count) (System.Timers)
3)Excel Interop
The memory of the application is not at all coming down .As timers are running continuosly so i cannot dispose the
So would like to implement dispose patterns .
Is it necessary to dispose the win32 APIs apart from Excel interop.?
If necessary can you please suggest the best way to call and dispose the win32 APIs.
Some of the Win32 APIs Used in application are listed below.
DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern uint RegisterWindowMessage(string lpString);
[DllImport("wininet.dll")]
private extern static bool InternetGetConnectedState(out int netConnection, int val);
[DllImport("Oleacc.dll")]
private static extern int AccessibleObjectFromWindow(IntPtr hwnd, uint dwObjectID, byte[] riid, ref Excel.Window ptr);
[DllImport("WtsApi32.dll")]
private static extern bool WTSRegisterSessionNotification(IntPtr hWnd, [MarshalAs(UnmanagedType.U4)]int dwFlags);
[DllImport("WtsApi32.dll")]
private static extern bool WTSUnRegisterSessionNotification(IntPtr hWnd);
The hWnd parameters in your function calls are all window handles. As a general rule, whenever you have finished using a window handle in the windows API, you need to explicitly release it using the CloseHandle function
I've been using SendMessage to send mouse clicks to a couple of windows. One being a game(everything works perfectly), but the other window, being a 3rd party tool for the game is having trouble with SendMessage. If the window is 'not minimized' everything works fine, don't matter if window is completely covered up by another. But if that same window is minimized then nothing happens, I checked with spy++ and the messages are indeed getting received but not being processed (correct term?). I've tried to solve this last couple days, doing both searches on here and Google alike, many of topics but nothing helped?
//MyImports
[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
And this is how I have it wrapped
public static void LClick(string windowclass, int x, int y)
{
IntPtr WHandle = FindWindow(windowclass, null);
SendMessage(WHandle, (int)WMessages.WM_LBUTTONDOWN, (IntPtr)1, (IntPtr)MakeLParam(x, y));
SendMessage(WHandle, (int)WMessages.WM_LBUTTONUP, (IntPtr)0, (IntPtr)MakeLParam(x, y));
}
I have tried focus, activate. One thing that might be useful info is that the third party program is being loaded as module("Qt5QWindowIcon") of the game.
I tried PostMessage as well, and it does the same thing as SendMessage() same problem when minimized.
This game does allow for macroing and unattended macroing, Hints the third part tool designed to execute the macros (published by the creators) I'm just trying to simulate a mouse click on the program to start the macro.
I would just use SendInput, but the entire purpose of my program is to run in background.
I 've faced same problem .Please change assembly name and project name (Changed name not started with name on that you are throwing/posting windows message)then rebuild it and check it. Now you will able to debug.
I'm trying to develop a WPF C# application that captures mouse clicks even (especially) if it's in background in order to start another task.
On MSDN documentation ( http://msdn.microsoft.com/en-us/library/windows/desktop/ms644990(v=vs.85).aspx ) I can read that WH_MOUSE should have either a global or thread scope.
I instantiate my hook handle this way:
hHook = SetWindowsHookEx(WH_MOUSE,
MouseHookProcedure,
(IntPtr)0,
AppDomain.GetCurrentThreadId());
where MouseHookProcedure is the delegate of my callback function and WH_MOUSE value is 7 (following Winuser.h).
The code works but it can only catch local clicks (I just need WM_LBUTTONDOWN messages), the clicks inside the window. I need to catch clicks also outside the window, and when the window is in background.
I tried hooking to WH_MOUSE_LL (with a value of 14), but it's not working.
For the most part I followed this:
http://support.microsoft.com/kb/318804
with some changes since I am using WPF and not WinForms.
The documentation about Hooks is a bit confusing.
All in all I'd like to know:
Can WH_MOUSE detect mouse messages globally? If yes, what am I doing wrong?
Can I hook from a .NET C# code to a WH_MOUSE_LL? If yes, how?
Thanks in advance.
It's possible with WH_MOUSE_LL and you need it.
In my case I developed a global keyboard maybe this could help you.
I needed to call LoadLibrary in the third parameters.
[DllImport("kernel32", SetLastError = true, CharSet = CharSet.Auto)]
private static extern IntPtr LoadLibrary(string fileName);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr SetWindowsHookEx(int idHook, KeyboardProc lpfn, IntPtr hMod, uint dwThreadId);
void MyFunction(){
[...]
SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardHookProcedure, LoadLibrary("user32.dll"), 0);
}
Technically you should be able to have a global mouse hook implemented in C#. You would then pass zero as the last arguments to SetWindowsHookEx and your hook procedure must reside in a DLL, not an EXE. That's because the DLL will be injected into every process that has windows belonging to the same desktop as the hooking application. For this same reason writing global hooks in .NET is not actually recommended by most because it causes the CLR to be loaded into every desktop process, which can carry substantial overhead.
First off,
I'm trying to send keyboard input to a background application(A window that does'nt have focus or might not even appear visible to the user).
I've verified that the winHandle and constants are correct.
Problem is the background application doesn't seem to get the message, UNLESS,
I set a breakpoint on the PostMessage() line, and press F10(step over) or F5(Continue) when it gets there,
then the keystroke magically gets sent.
What gives?
Relevant code:
[DllImport("User32.Dll", EntryPoint = "PostMessageA", SetLastError = true)]
public static extern bool PostMessage(IntPtr hWnd, uint msg, int wParam, int lParam);
PostMessage(winHandle, (uint)WM_KEYDOWN, 66, 0);
Using Win7 64 and MS Visual studio 2008 pro, Console application. And the above code is on a Thread if that helps.
Using Win7 64
That's somewhat relevant, the declaration is wrong. Works in 32-bit mode, but troublesome in 64-bit mode. The last two arguments are pointers, not ints. 8 bytes, not 4. Fix:
[DllImport("User32.Dll", EntryPoint = "PostMessageA", SetLastError = true)]
public static extern bool PostMessage(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam);
PostMessage(winHandle, (uint)WM_KEYDOWN, (IntPtr)66, IntPtr.Zero);
However, this may not actually solve your problem. In x64 mode, the first 4 arguments of a non-instance method are passed in registers, not the stack. It just so happens that this method has 4 arguments, you won't get the PInvokeStackImbalance MDA warning. And the upper 32-bits of the 64-bit register values are often zero by accident so it doesn't matter whether the P/Invoke marshaller generates a 32-bit or a 64-bit argument value.
Beware that this approach is quite troublesome in practice. You cannot control the state of the keyboard in the target process. You are sending the keystroke for B. That may turn into B, b, Alt+B or Ctrl+B, depending on the state of the modifier keys. Only SendInput() can work reliably. Well, short from the window focus problem.