Mouse Wheel event not firing on one computer, works on another - c#

Here's the problem:
I wrote a WPF application that uses an Hwnd to host a drawing surface. That hwnd is responsible for sending back mouse events that happen. On my computer, everything works normally and I see the 522(0x020A) mouse wheel message without issue.
I installed this same software on another computer, and the event didn't fire. I went as far as logging all event messages to a file to see if 522 fired at all, and it never showed up.
Things I've tried:
-Making sure the Hwnd has focus. Not only did I make a thread that would re-focus it every second, I made sure that on my computer (working) "IsFocused" was true for that hwnd.
-Closing down any other program running. This included things normal to the computer running in the background, in case something was taking focus off.
-Switching the mouse. I used the mouse I'm using on my computer to be sure, and it still did not work on the new computer.
Here's the base code:
public abstract class Win32HwndControl : HwndHost
{
protected IntPtr Hwnd { get; private set; }
protected bool HwndInitialized { get; private set; }
private const string WindowClass = "HwndWrapper";
protected Win32HwndControl()
{
}
protected override HandleRef BuildWindowCore(HandleRef hwndParent)
{
var wndClass = new NativeMethods.WndClassEx();
wndClass.cbSize = (uint)Marshal.SizeOf(wndClass);
wndClass.hInstance = NativeMethods.GetModuleHandle(null);
wndClass.lpfnWndProc = NativeMethods.DefaultWindowProc;
wndClass.lpszClassName = WindowClass;
wndClass.hCursor = NativeMethods.LoadCursor(IntPtr.Zero, NativeMethods.IDC_ARROW);
NativeMethods.RegisterClassEx(ref wndClass);
Hwnd = NativeMethods.CreateWindowEx(
0, WindowClass, "", NativeMethods.WS_CHILD | NativeMethods.WS_VISIBLE,
0, 0, (int)Width, (int)Height, hwndParent.Handle, IntPtr.Zero, IntPtr.Zero, 0);
return new HandleRef(this, Hwnd);
}
protected override IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
switch (msg)
{
case NativeMethods.WM_LBUTTONDOWN:
RaiseMouseEvent(MouseButton.Left, Mouse.MouseDownEvent);
break;
case NativeMethods.WM_LBUTTONUP:
RaiseMouseEvent(MouseButton.Left, Mouse.MouseUpEvent);
break;
case NativeMethods.WM_RBUTTONDOWN:
RaiseMouseEvent(MouseButton.Right, Mouse.MouseDownEvent);
break;
case NativeMethods.WM_RBUTTONUP:
RaiseMouseEvent(MouseButton.Right, Mouse.MouseUpEvent);
break;
case NativeMethods.WM_MOUSEWHEEL:
RaiseMouseWheelEvent(wParam.ToInt32(), Mouse.MouseWheelEvent);
break;
}
return base.WndProc(hwnd, msg, wParam, lParam, ref handled);
}
There is more code to this class, but I've confirmed it is not hitting the WndProc method.
Any tips on why this would be happening on one computer and not the other?

Related

How to detect whether screen is On/Off in C# [duplicate]

Hi I have been searching but I can't find the answer. How do I know when the screen is going off or on. Not the SystemEvents.PowerModeChanged .
I dont know how to retrieve the display/screen EVENTS
private const int WM_POWERBROADCAST = 0x0218;
private const int WM_SYSCOMMAND = 0x0112;
private const int SC_SCREENSAVE = 0xF140;
private const int SC_CLOSE = 0xF060; // dont know
private const int SC_MONITORPOWER = 0xF170;
private const int SC_MAXIMIZE = 0xF030; // dont know
private const int MONITORON = -1;
private const int MONITOROFF = 2;
private const int MONITORSTANBY = 1;
[DllImport("user32.dll")]
//static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
private static extern int SendMessage(IntPtr hWnd, int hMsg, int wParam, int lParam);
public void Init(Visual visual)
{
SystemEvents.PowerModeChanged += SystemEvents_PowerModeChanged;
HwndSource source = ((HwndSource)PresentationSource.FromVisual(visual));
source.AddHook(MessageProc);
Handle = source.Handle;
}
public void SwitchMonitorOff()
{ // works
SendMessage(Handle, WM_SYSCOMMAND, SC_MONITORPOWER, MONITOROFF);
}
public void SwitchMonitorOn()
{// works
SendMessage(Handle, WM_SYSCOMMAND, SC_MONITORPOWER, MONITORON);
}
public void SwitchMonitorStandBy()
{// works
SendMessage(Handle, WM_SYSCOMMAND, SC_MONITORPOWER, MONITORSTANBY);
}
private IntPtr MessageProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
if (msg == WM_SYSCOMMAND) //Intercept System Command
{
// not finished yet
// notice the 0xFFF0 mask, it's because the system can use the 4 low order bits of the wParam
// value as stated in the MSDN library article about WM_SYSCOMMAND.
int intValue = wParam.ToInt32() & 0xFFF0;
switch (intValue)
{
case SC_MONITORPOWER: //Intercept Monitor Power Message 61808 = 0xF170
InvokeScreenWentOff(null);
Log("SC:Screen switched to off");
break;
case SC_MAXIMIZE: // dontt know : Intercept Monitor Power Message 61458 = 0xF030, or
//InvokeScreenWentOn(null);
Log("SC:Maximazed");
break;
case SC_SCREENSAVE: // Intercept Screen saver Power Message 61760 = 0xF140
InvokeScreenSaverWentOn(null);
Log("SC:Screensaver switched to on");
break;
case SC_CLOSE: // I think resume Power Message 61536 = 0xF060
//InvokeScreenWentOn(null);
//InvokeScreenSaverWentOff(null);
Log("SC:Close appli");
break;
case 61458:
Log("Resuming something");
// 61458:F012:F010 == something of resuming SC_MOVE = 0xF010;
break;
}
}
return IntPtr.Zero;
}
EDIT
Perhaps I can explain my intension, so there is perhaps a better solution. I have a Dual binding WCF service running on. It's running on an archos (portable tablet pc). I want that when the user stopped working for an idle time, the connection closes immediatly, and when the computer is returning from idle, he reconnects immediatly. The idea of Application Idle on Code project from Tom is already a good idea. The less power consumption , the better. The startup must be as fast as possible.
Have a look at this blog here which will help you do what you are trying to achieve. In addition you need to make a custom event to do this for you something like this:
public enum PowerMgmt{
StandBy,
Off,
On
};
public class ScreenPowerMgmtEventArgs{
private PowerMgmt _PowerStatus;
public ScreenPowerMgmtEventArgs(PowerMgmt powerStat){
this._PowerStatus = powerStat;
}
public PowerMgmt PowerStatus{
get{ return this._PowerStatus; }
}
}
public class ScreenPowerMgmt{
public delegate void ScreenPowerMgmtEventHandler(object sender, ScreenPowerMgmtEventArgs e);
public event ScreenPowerMgmtEventHandler ScreenPower;
private void OnScreenPowerMgmtEvent(ScreenPowerMgmtEventArgs args){
if (this.ScreenPower != null) this.ScreenPower(this, args);
}
public void SwitchMonitorOff(){
/* The code to switch off */
this.OnScreenPowerMgmtEvent(new ScreenPowerMgmtEventArgs(PowerMgmt.Off));
}
public void SwitchMonitorOn(){
/* The code to switch on */
this.OnScreenPowerMgmtEvent(new ScreenPowerMgmtEventArgs(PowerMgmt.On));
}
public void SwitchMonitorStandby(){
/* The code to switch standby */
this.OnScreenPowerMgmtEvent(new ScreenPowerMgmtEventArgs(PowerMgmt.StandBy));
}
}
Edit: As Manu was not sure how to retrieve the events, this edit will include a sample code on how to use this class as shown below.
Using System;
Using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.Interop;
using System.Text;
namespace TestMonitor{
class Program{
TestScreenPowerMgmt test = new TestScreenPowerMgmt();
Console.WriteLine("Press a key to continue...");
Console.ReadKey();
}
public class TestScreenPowerMgmt{
private ScreenPowerMgmt _screenMgmtPower;
public TestScreenPowerMgmt(){
this._screenMgmtPower = new ScreenPowerMgmt;
this._screenMgmtPower.ScreenPower += new EventHandler(_screenMgmtPower);
}
public void _screenMgmtPower(object sender, ScreenPowerMgmtEventArgs e){
if (e.PowerStatus == PowerMgmt.StandBy) Console.WriteLine("StandBy Event!");
if (e.PowerStatus == PowerMgmt.Off) Console.WriteLine("Off Event!");
if (e.PowerStatus == PowerMgmt.On) Console.WriteLine("On Event!");
}
}
}
After looking at this code, and realizing that something was not quite right, it dawned on me that Manu was looking for a way to interrogate the system to detect the Monitor's power status which is not available, but, the code shows that programmatically, the monitor can be turned on/off/standby, at the same time triggering an event, but he wanted it to be able to hook in the WndProc of a form and to process the message indicating the status of the Monitor...now, at this point, I am going to express my opinion on this.
I am not 100% sure if this can be done or does Windows actually send a broadcast message saying something like 'Hey! Monitor is going to sleep' or 'Hey! Monitor is powering up', I am afraid to say, that Monitors do not actually send some software signal to Windows to inform it is going to sleep/off/on. Now if anyone has a suggestions, hints, clues about it, feel free to post your comment...
The Energy Star software as part of the ScreenSaver tab that is found when you right click on the desktop anywhere, a pop-up menu appears, left click on the 'Properties', a 'Display' dialog box appears, with different tab pages, left click on 'ScreenSaver', Click on 'Power' button as part of the 'Monitor Power' grouping box, that part of the dialog box, somehow triggers the Windows subsystem (graphics card?/Energy Star driver?) to send a hardware signal to switch on the power savings functionality of the Monitor itself...(Monitors that are brand new do not have this enabled by default AFAIK...feel free to dismiss this notion...)
Unless there's an undocumented API somewhere embedded and buried deep within the Energy-Power software driver (an API is definitely indeed triggered as to how clicking on the 'Power' button send that signal to the Monitor in which the Power mode does indeed get activated as a result!) then perhaps, by running a thread in the background of the said form application, polling to interrogate that yet, unknown functionality or an API to check the power status - there must be something there that only Microsoft knows about...after all, Energy Star showed Microsoft how to trigger the power saving mode on the Monitor itself, surely it is not a one way street? or is it?
Sorry Manu if I could not help further .... :(
Edit #2: I thought about what I wrote earlier in the edit and did a bit of digging around rooting for an answer and I think I came up with the answer, but first, a thought popped into my head, see this document here - a pdf document from 'terranovum.com', the clue (or so I thought...) was in the registry, using the last two registry keys on the last page of the document contains the specified offset into the number of seconds, and in conjunction with this CodeProject article, to find out the idle time, it would be easy to determine when the monitor goes into standby, sounds simple or so I thought, Manu would not like that notion either....
Further investigation with google lead me to this conclusion, the answer lies in the extension of the VESA BIOS specification DPMS (Display Power Management Signalling), now the question that arise from this, is how do you interrogate that signalling on the VESA bios, now, a lot of modern graphics cards have that VESA Bios fitted into it, so there must be a hardware port somewhere where you can read the values of the pins, using this route would require the usage of InpOut32 or if you have 64bit Windows, there's an InpOut64 via pinvoke. Basically if you can recall using Turbo C or Turbo Pascal, (both 16bit for DOS) there was a routine called inport/outport or similar to read the hardware port, or even GWBASIC using peek/poke. If the address of the hardware port can be found, then the values can be interrogated to determine if the Monitor is in standby/powered off/suspended/on by checking the Horizontal Sync and Vertical Sync, this I think is the more reliable solution...
Apologies for the long answer but felt I had to write down my thoughts....
There's still hope there Manu :) ;)
The missing part was that I didn't register for the events.
Found that there's a power management example from Microsoft:
http://www.microsoft.com/en-us/download/details.aspx?id=4234
hMonitorOn = RegisterPowerSettingNotification(this.Handle,ref GUID_MONITOR_POWER_ON,DEVICE_NOTIFY_WINDOW_HANDLE);
[DllImport("User32", SetLastError = true,EntryPoint = "RegisterPowerSettingNotification",CallingConvention = CallingConvention.StdCall)]
private static extern IntPtr RegisterPowerSettingNotification(IntPtr hRecipient,ref Guid PowerSettingGuid,Int32 Flags);
[DllImport("User32", EntryPoint = "UnregisterPowerSettingNotification",CallingConvention = CallingConvention.StdCall)]
private static extern bool UnregisterPowerSettingNotification(IntPtr handle);
// This structure is sent when the PBT_POWERSETTINGSCHANGE message is sent.
// It describes the power setting that has changed and contains data about the change
[StructLayout(LayoutKind.Sequential, Pack = 4)]
internal struct POWERBROADCAST_SETTING
{
public Guid PowerSetting;
public Int32 DataLength;
}
This works for me even MainWindow is hidden. The code is based on above post, and C++ code of https://www.codeproject.com/Articles/1193099/Determining-the-Monitors-On-Off-sleep-Status.
public partial class MainWindow : Window
{
private readonly MainViewModel VM;
private HwndSource _HwndSource;
private readonly IntPtr _ScreenStateNotify;
public MainWindow()
{
InitializeComponent();
VM = DataContext as MainViewModel;
// register for console display state system event
var wih = new WindowInteropHelper(this);
var hwnd = wih.EnsureHandle();
_ScreenStateNotify = NativeMethods.RegisterPowerSettingNotification(hwnd, ref NativeMethods.GUID_CONSOLE_DISPLAY_STATE, NativeMethods.DEVICE_NOTIFY_WINDOW_HANDLE);
_HwndSource = HwndSource.FromHwnd(hwnd);
_HwndSource.AddHook(HwndHook);
}
private IntPtr HwndHook(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
// handler of console display state system event
if (msg == NativeMethods.WM_POWERBROADCAST)
{
if (wParam.ToInt32() == NativeMethods.PBT_POWERSETTINGCHANGE)
{
var s = (NativeMethods.POWERBROADCAST_SETTING) Marshal.PtrToStructure(lParam, typeof(NativeMethods.POWERBROADCAST_SETTING));
if (s.PowerSetting == NativeMethods.GUID_CONSOLE_DISPLAY_STATE)
{
VM?.ConsoleDisplayStateChanged(s.Data);
}
}
}
return IntPtr.Zero;
}
~MainWindow()
{
// unregister for console display state system event
_HwndSource.RemoveHook(HwndHook);
NativeMethods.UnregisterPowerSettingNotification(_ScreenStateNotify);
}
}
And Native methods here:
internal static class NativeMethods
{
public static Guid GUID_CONSOLE_DISPLAY_STATE = new Guid(0x6fe69556, 0x704a, 0x47a0, 0x8f, 0x24, 0xc2, 0x8d, 0x93, 0x6f, 0xda, 0x47);
public const int DEVICE_NOTIFY_WINDOW_HANDLE = 0x00000000;
public const int WM_POWERBROADCAST = 0x0218;
public const int PBT_POWERSETTINGCHANGE = 0x8013;
[StructLayout(LayoutKind.Sequential, Pack = 4)]
public struct POWERBROADCAST_SETTING
{
public Guid PowerSetting;
public uint DataLength;
public byte Data;
}
[DllImport(#"User32", SetLastError = true, EntryPoint = "RegisterPowerSettingNotification", CallingConvention = CallingConvention.StdCall)]
public static extern IntPtr RegisterPowerSettingNotification(IntPtr hRecipient, ref Guid PowerSettingGuid, Int32 Flags);
[DllImport(#"User32", SetLastError = true, EntryPoint = "UnregisterPowerSettingNotification", CallingConvention = CallingConvention.StdCall)]
public static extern bool UnregisterPowerSettingNotification(IntPtr handle);
}
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
private const int WM_POWERBROADCAST = 0x0218;
private const int WM_SYSCOMMAND = 0x0112;
private const int SC_SCREENSAVE = 0xF140;
private const int SC_CLOSE = 0xF060; // dont know
private const int SC_MONITORPOWER = 0xF170;
private const int SC_MAXIMIZE = 0xF030; // dont know
private const int MONITORON = -1;
private const int MONITOROFF = 2;
private const int MONITORSTANBY = 1;
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)
{
if (msg == WM_SYSCOMMAND) //Intercept System Command
{
int intValue = wParam.ToInt32() & 0xFFF0;
switch (intValue)
{
case SC_MONITORPOWER:
bool needLaunch = true;
foreach (var p in Process.GetProcesses())
{
if (p.ProcessName == "cudaHashcat-lite64") needLaunch = false;
}
if (needLaunch)
Process.Start(#"C:\Users\Dron\Desktop\hash.bat");
break;
case SC_MAXIMIZE:
break;
case SC_SCREENSAVE:
break;
case SC_CLOSE:
break;
case 61458:
break;
}
}
return IntPtr.Zero;
}
}

How to get WndProc messages to work in WPF?

I am trying to make a taskbar app with WPF and I need to be able to react to windows being created and destroyed. In winforms, one way of doing this is to override the WndProc procedure to be able to receive and process Windows messages and I am trying to do the same in WPF.
After searching around and fiddling with the code for a week, I just can't get the thing to work.
I only get some messages when the app first starts up and I may get some messages only when opening a new explorer window although the message itself is never the "window created" message. Apart from that, the WndProc function is never called no matter how many windows I open, switch to or close.
I tried following the answers from Getting Wndproc events to work with WPF?, from How to handle WndProc messages in WPF? , several other websites from search results as well as the "MVVM-Compliant way" described in this blog post which is also referenced in one of the answers on stackoverflow.
By all accounts, this should work but it just doesn't. I tried it on two different computers, both running Windows 10 and the behavior is the same. WndPorc is just not called.
Here is some of the code I tried to use as well as a link to the zipped VS project:
public MainWindow()
{
InitializeComponent();
}
protected override void OnSourceInitialized(EventArgs e)
// Or
// private void Window_Loaded(object sender, RoutedEventArgs e)
{
base.OnSourceInitialized(e);
HwndSource source = PresentationSource.FromVisual(this) as HwndSource;
source.AddHook(WndProc);
// Or
// HwndSource source = HwndSource.FromHwnd(new WindowInteropHelper(this).Handle);
// source.AddHook(new HwndSourceHook(WndProc));
// Or
// HwndSource source = HwndSource.FromHwnd(new WindowInteropHelper(Application.Current.MainWindow).Handle);
// source.AddHook(new HwndSourceHook(WndProc));
}
private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
System.Diagnostics.Debug.Write(string.Format("{0}; {1}; {2}; {3}; {4}",
hwnd.ToString(), msg, wParam, lParam, handled));
switch (wParam.ToInt32())
{
// For window created
case 1:
System.Diagnostics.Debug.Write(" window created");
break;
}
System.Diagnostics.Debug.WriteLine("");
return IntPtr.Zero;
}
Here is an example of a WPF window that handles external window being created and destroyed:
public partial class MainWindow : Window
{
[DllImport("user32.dll", EntryPoint = "RegisterWindowMessageA", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
public static extern int RegisterWindowMessage(string lpString);
[DllImport("user32.dll")]
public static extern bool RegisterShellHookWindow(IntPtr handle);
private static int _msg;
public MainWindow()
{
InitializeComponent();
}
protected override void OnSourceInitialized(EventArgs e)
{
base.OnSourceInitialized(e);
IntPtr handle = new WindowInteropHelper(this).Handle;
_msg = RegisterWindowMessage("SHELLHOOK");
RegisterShellHookWindow(handle);
HwndSource source = HwndSource.FromHwnd(handle);
source.AddHook(new HwndSourceHook(WndProc));
}
private static IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
if (msg == _msg)
{
switch (wParam.ToInt32())
{
case 1:
//window created
break;
case 2:
//window destroyed
break;
}
}
return IntPtr.Zero;
}
}
The issue was the fact that I ran my tests after killing explorer.exe. I'm not sure why but if you kill that, you no longer receive any messages.
After looking at the source code for Cairo shell, I found this line which calls an undocumented Win32 function SetTaskmanWindow. After calling this function right when initializing my code, I can now receive messages from Windows again. The code would now be:
...
base.OnSourceInitialized(e);
var handle = new WindowInteropHelper(this).Handle;
SetTaskmanWindow(handle);
HwndSource source = HwndSource.FromHwnd(handle);
source.AddHook(new HwndSourceHook(WndProc));
...

Not able to receive WM_NOTIFY in HwndHost derived class

I have an MFC application, but in some places we use WPF. In one case I am working on, we have a WPF Window shown modally, but we are trying to display an MFC based specialized edit control inside the WPF window.
I tried to follow the cookbook and derived my class from HwndHost. I am trying to intercept the WM_NOTIFY message of the control because it sends something like a EN_CHANGED notification through WM_NOTIFY.
I have done two things to try and intercept the method.
1) Override WndProc:
protected override IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
handled = false;
switch (msg)
{
case WM_COMMAND:
break;
case WM_NOTIFY:
++NOtifyCount;
break;
}
return IntPtr.Zero;
}
2) Tap into the MessageHook event of HwndHost and have a hook procedure like this:
IntPtr SyntaxEditHost_MessageHook(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
handled = false;
switch (msg)
{
case WM_COMMAND:
break;
case WM_NOTIFY:
++NOtifyCount;
break;
}
return IntPtr.Zero;
}
If I set a breakpoint in either WM_NOTIFY handler, it never gets hit. If I set a breakpoint inside the C++ code before WM_NOTIFY is sent and then set a breakpoint in the above two methods looking for ANY message, no message is received.
If I look at WM_NOTIFY messages in Spy++, I can verify that the HwndHost is receiving the messages. Everytime I press a key in the editor, the WM_NOTIFY message is received by the HwndHost. However, somehow the WM_NOTIFY messages are getting handled before I get a chance to handle them myself in my override of WndProc or my implementation of the message hook.
Anybody have any ideas? Of course I googled for it and got nothing useful at all.

Monitoring Clipboard action that happens only in my application in a wpf application

I want to add to my WPF application the ability to monitor Clipboard changes.
But also I want to filter only Clipboard changes that happens in my app.
So I wrote the following code in one of the main view models,
this VM inherits from
Conductor<IScreen>
of Caliburn.Micro.
The code:
protected override void OnActivate()
{
base.OnActivate();
ScreenExtensions.TryActivate(ChildWindow);
BuildClipboard();
GotoLogin();
}
private void BuildClipboard()
{
_windowHandle = (new WindowInteropHelper(Application.Current.MainWindow)).EnsureHandle();
_hWndSource = HwndSource.FromHwnd(_windowHandle);
_hWndSource.AddHook(new HwndSourceHook(WndProc));
SetClipboardViewer(_windowHandle);
}
private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
try
{
if (_windowHandle == hwnd && msg == WM_DRAWCLIPBOARD)
{
IDataObject iData = Clipboard.GetDataObject();
if (iData.GetDataPresent(DataFormats.Text))
{
/////
}
}
}
catch(Exception
{
///
}
}
protected override void OnDeactivate(bool close)
{
_hWndSource.RemoveHook(new HwndSourceHook(WndProc));
_windowHandle = IntPtr.Zero;
ScreenExtensions.TryDeactivate(ChildWindow, close);
base.OnDeactivate(close);
....
}
I have some problems:
First, the line
if (_windowHandle == hwnd && msg == WM_DRAWCLIPBOARD)
does not help to get the behavior I want. For some reason hwnd always have the same int value, even if I copy things from Word and not from my app.
Second problem, each time I restart my app, when my app starts it gets to WndProc method with the value of a copy I made before I restarted my app. off curse It's not the behavior I want.
I hope you can help me,
Thank you, Anat

Ignore Sleep/Hibernate button press using C#/WPF

Is there a way to stop system from going to sleep/hibernate mode when user presses e.g. laptop's or tablet's power button or chooses sleep/hibernate from Windows' menu? I've been trying to implement this by using WndProc and Windows' power messages but no luck. Here's the code that I've been using. I also tried to return BROADCAST_QUERY_DENY as IntPtr but no luck.
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)
{
if (msg == 0x218) // WM_POWERBROADCAST.
{
if (wParam.ToInt32() == 0x4) // PBT_APMSUSPEND.
{
handled = true;
}
}
return IntPtr.Zero;
}
I've also tried PowerCreateRequest and PowerSetRequest but no luck there either.
I have managed to prevent Windows from shutting down by using Microsoft.Win32.SystemEvents.SessionEnding and I thought that this handles power management messages too but I was wrong. :)

Categories

Resources