how check connection between PPC to WebService? - c#

How do I check the connection between PPC and a web service on the server? I work on FW3.5 C#

I can't remember offhand if this is available in .Net CF or not:
System.Net.NetworkInformation.NetworkChange.NetworkAvailabilityChanged
Another option is to just attempt to use the web service, and handle exceptions. I usually follow this pattern, is there a reason it doesn't work for your case?
Edit:
Connection Monitor class:
public static class ConnectionMonitor
{
public static event EventHandler IsConnectedChanged;
private static SystemState _connectionState = null,
//_cellState = null,
_gprsState = null;
private static int _connectionCount = 0;
//_cellCount = 0;
private static bool _gprs = false;
private static bool _isConnected = true;
private static string _phoneCarrier = SystemState.PhoneOperatorName;
private const int POWER_FLAGS = 0x00000001; // default
private const string AXIM_WIFI_ADAPTER = "{98C5250D-C29A-4985-AE5F-AFE5367E5006}\\TIACXWLN1";
public static bool IsPhone
{
get { return !string.IsNullOrEmpty(_phoneCarrier); }
}
public static bool IsGPRSConnected
{
get { return _gprs; }
}
public static bool IsConnected
{
get { return _isConnected; }
set
{
if (_isConnected != value)
{
_isConnected = value;
if (IsConnectedChanged != null)
{
IsConnectedChanged(null, EventArgs.Empty);
}
if (!_isConnected && !IsPhone)
{
WifiOn();
}
}
}
}
private static void WifiOn()
{
Win32.CEDEVICE_POWER_STATE state = new Win32.CEDEVICE_POWER_STATE();
if (Win32.GetDevicePower(AXIM_WIFI_ADAPTER, POWER_FLAGS, ref state) == 0)
{
if (state != Win32.CEDEVICE_POWER_STATE.D0)
{
Win32.DevicePowerNotify(AXIM_WIFI_ADAPTER, Win32.CEDEVICE_POWER_STATE.D4, POWER_FLAGS);
Win32.SetDevicePower(AXIM_WIFI_ADAPTER, POWER_FLAGS, Win32.CEDEVICE_POWER_STATE.D0);
}
}
}
public static void Init()
{
if (_connectionState == null)
{
_connectionState = new SystemState(SystemProperty.ConnectionsCount);
_connectionCount = SystemState.ConnectionsCount;
_connectionState.Changed += new ChangeEventHandler(_state_Changed);
}
//if (_cellState == null)
//{
// _cellState = new SystemState(SystemProperty.ConnectionsCellularCount);
// _cellCount = SystemState.ConnectionsCellularCount;
// _cellState.Changed += new ChangeEventHandler(_state_Changed);
//}
if (_gprsState == null)
{
_gprsState = new SystemState(SystemProperty.PhoneGprsCoverage);
_gprs = SystemState.PhoneGprsCoverage;
_gprsState.Changed += new ChangeEventHandler(_state_Changed);
}
IsConnected = _connectionCount > 0 || _gprs;
}
private static void _state_Changed(object sender, ChangeEventArgs args)
{
//_cellCount = SystemState.ConnectionsCellularCount;
_connectionCount = SystemState.ConnectionsCount;
_gprs = SystemState.PhoneGprsCoverage;
IsConnected = _connectionCount > 0 || _gprs;
}
public static void Dispose()
{
if (_connectionState != null)
{
_connectionState.Changed -= new ChangeEventHandler(_state_Changed);
_connectionState.Dispose();
_connectionState = null;
}
//if (_cellState != null)
//{
// _cellState.Changed -= new ChangeEventHandler(_state_Changed);
// _cellState.Dispose();
// _cellState = null;
//}
if (_gprsState != null)
{
_gprsState.Changed -= new ChangeEventHandler(_state_Changed);
_gprsState.Dispose();
_gprsState = null;
}
}
}
My Win32 static class had a lot of calls (unrelated to your needs) in it. Here are all the ones I think you need:
public enum CEDEVICE_POWER_STATE : int
{
PwrDeviceUnspecified = -1,
D0 = 0, // Full On: full power, full functionality
D1 = 1, // Low Power On: fully functional at low power/performance
D2 = 2, // Standby: partially powered with automatic wake
D3 = 3, // Sleep: partially powered with device initiated wake
D4 = 4, // Off: unpowered
PwrDeviceMaximum = 5
}
[DllImport("coredll.dll", SetLastError = true)]
public static extern int DevicePowerNotify(string name, CEDEVICE_POWER_STATE state, int flags);
[DllImport("coredll.dll", SetLastError = true)]
public static extern int SetDevicePower(string name, int flags, CEDEVICE_POWER_STATE state);
[DllImport("coredll.dll", SetLastError = true)]
public static extern int GetDevicePower(string name, int flags, ref CEDEVICE_POWER_STATE state);
If I missed any, look them up on pinvoke.net.

Related

Low level audio player with C# playback stutter - fix?

I am working on a small project (just for fun) that allows me to display the frequencies played back in my current audio buffer.
The plan is:
The thread that is executing the WaveOutPlayer.ThreadProc() method keeps playing and refilling two audio buffers. While the first buffer is playing, the second buffer gets refilled and vice versa. To be sure that one buffer does not start playing before the other one stopped playback, I use the WaitOne() method. After the buffer's audio data has beed played back by the WaveOut device, the buffer's OnCompleted() method is called. This method cancels the waiting.
The playback itself starts, but it is very choppy.
Could anyone tell me why this happens?
The Visual Studio project is located at http://www.pour-toujours.net/lowlevelaudio.zip
(currently, only 16-bit, Stereo, 44,1kHz uncompressed wav is supported.)
Here goes some of my code that seems to be relevant:
using System;
using System.Threading;
using System.Runtime.InteropServices;
using System.Collections;
using System.Linq;
namespace LowLevelAudio
{
internal class WaveOutHelper
{
public static void Try(int err)
{
if (err != WaveNative.MMSYSERR_NOERROR)
throw new Exception(err.ToString());
}
}
public delegate void BufferFillEventHandler(IntPtr data, int size);
public class WaveOutBuffer : IDisposable
{
private AutoResetEvent m_PlayEvent = new AutoResetEvent(false);
private IntPtr m_WaveOut;
private int m_buffersize;
private static byte[] m_samples;
private static double[] m_fftsamples;
private WaveNative.WaveHdr m_Header;
private byte[] m_HeaderData;
private GCHandle m_HeaderHandle;
private GCHandle m_HeaderDataHandle;
private WaveFormat m_waveformat;
private double[] m_fftOccurances;
private double[] m_fftHertzlist;
private bool m_Playing;
public int ID
{
get; set;
}
internal static void WaveOutProc(IntPtr hdrvr, int uMsg, int dwUser, ref WaveNative.WaveHdr wavhdr, int dwParam2)
{
if (uMsg == WaveNative.MM_WOM_DONE)
{
try
{
GCHandle h = (GCHandle)wavhdr.dwUser;
WaveOutBuffer buf = (WaveOutBuffer)h.Target;
buf.OnPlayCompleted();
}
catch(Exception ex)
{
Console.WriteLine("Exception: " + ex.Message);
}
}
}
public WaveOutBuffer(IntPtr waveOutHandle, int size, WaveFormat format)
{
m_WaveOut = waveOutHandle;
m_waveformat = format;
m_HeaderHandle = GCHandle.Alloc(m_Header, GCHandleType.Pinned);
m_Header.dwUser = (IntPtr)GCHandle.Alloc(this);
m_HeaderData = new byte[size];
m_HeaderDataHandle = GCHandle.Alloc(m_HeaderData, GCHandleType.Pinned);
m_Header.lpData = m_HeaderDataHandle.AddrOfPinnedObject();
m_Header.dwBufferLength = size;
m_buffersize = size;
m_samples = new byte[m_buffersize];
WaveOutHelper.Try(WaveNative.waveOutPrepareHeader(m_WaveOut, ref m_Header, Marshal.SizeOf(m_Header)));
}
~WaveOutBuffer()
{
Dispose();
}
public int Size
{
get { return m_Header.dwBufferLength; }
}
public IntPtr Data
{
get { return m_Header.lpData; }
}
public void Dispose()
{
if (m_Header.lpData != IntPtr.Zero)
{
WaveNative.waveOutUnprepareHeader(m_WaveOut, ref m_Header, Marshal.SizeOf(m_Header));
m_HeaderHandle.Free();
m_Header.lpData = IntPtr.Zero;
}
m_PlayEvent.Close();
if (m_HeaderDataHandle.IsAllocated)
m_HeaderDataHandle.Free();
}
public bool Play()
{
lock(this) // works, but has to be fine tuned... (to do)
{
m_PlayEvent.Reset();
m_Playing = WaveNative.waveOutWrite(m_WaveOut, ref m_Header, Marshal.SizeOf(m_Header)) == WaveNative.MMSYSERR_NOERROR;
if (!m_Playing)
throw new Exception("test exception");
return m_Playing;
}
}
public void WaitForMe()
{
Console.WriteLine(this.ID + " WaitFor()");
if (m_Playing)
{
m_Playing = m_PlayEvent.WaitOne();
}
else
{
m_Playing = false;
}
}
public void OnPlayCompleted()
{
Console.WriteLine(this.ID + " OnCompleted()");
m_PlayEvent.Set();
m_Playing = false;
}
}
public class WaveOutPlayer : IDisposable
{
private IntPtr m_WaveOut;
private WaveOutBuffer[] m_bufferlist;
private Thread m_Thread;
private BufferFillEventHandler m_FillProc;
private bool m_Finished;
private byte m_zero;
private int m_buffercount = 0;
private int m_buffersize = 0;
private WaveFormat m_waveformat;
private WaveNative.WaveDelegate m_BufferProc = new WaveNative.WaveDelegate(WaveOutBuffer.WaveOutProc);
public static int DeviceCount
{
get { return WaveNative.waveOutGetNumDevs(); }
}
public WaveOutPlayer(int device, WaveFormat format, int bufferSize, BufferFillEventHandler fillProc)
{
m_zero = format.wBitsPerSample == 8 ? (byte)128 : (byte)0;
m_FillProc = fillProc;
m_buffercount = 2;
m_buffersize = bufferSize;
m_waveformat = format;
WaveOutHelper.Try(WaveNative.waveOutOpen(out m_WaveOut, device, format, m_BufferProc, 0, WaveNative.CALLBACK_FUNCTION));
AllocateBuffers(bufferSize, m_buffercount, format);
m_Thread = new Thread(new ThreadStart(ThreadProc));
m_Thread.Start();
}
~WaveOutPlayer()
{
Dispose();
}
public void Dispose()
{
if (m_Thread != null)
{
try
{
m_Finished = true;
if (m_WaveOut != IntPtr.Zero)
WaveNative.waveOutReset(m_WaveOut);
m_Thread.Join();
m_FillProc = null;
FreeBuffers();
if (m_WaveOut != IntPtr.Zero)
WaveNative.waveOutClose(m_WaveOut);
}
finally
{
m_Thread = null;
m_WaveOut = IntPtr.Zero;
}
}
}
private void ThreadProc()
{
WaveOutBuffer b0 = m_bufferlist[0];
WaveOutBuffer b1 = m_bufferlist[1];
MainForm form = Program.getUI();
bool s = true;
m_FillProc(b0.Data, b0.Size);
while (!m_Finished)
{
if (s)
{
Console.WriteLine("-------------------------");
Console.WriteLine("Playing b0, filling b1");
b0.Play();
m_FillProc(b1.Data, b1.Size);
form.paintEqualizer(b0);
Console.WriteLine("callng waitFor on b0");
b0.WaitForMe();
}
else
{
Console.WriteLine("-------------------------");
Console.WriteLine("Playing b1, filling b0");
b1.Play();
m_FillProc(b0.Data, b0.Size);
form.paintEqualizer(b1);
Console.WriteLine("callng waitFor on b1");
b1.WaitForMe();
}
s = !s;
}
}
private void AllocateBuffers(int bufferSize, int bufferCount, WaveFormat format)
{
FreeBuffers();
m_bufferlist = new WaveOutBuffer[m_buffercount];
if (bufferCount > 0)
{
for (int i = 0; i < m_buffercount; i++)
{
m_bufferlist[i] = new WaveOutBuffer(m_WaveOut, bufferSize, format);
m_bufferlist[i].ID = i;
}
}
}
private void FreeBuffers()
{
if (m_bufferlist != null)
{
foreach (WaveOutBuffer currentBuffer in m_bufferlist)
{
if (currentBuffer != null)
{
currentBuffer.Dispose();
}
}
}
}
}
}

Calls GetScanner but never uses it

So I'm trying to create my own visual studio language plugin for a DSL. My question is, I've implemented LanguageService and override GetScanner. Through debugging I see that it actually returns the IScanner implementation, but it never calls ScanTokenAndProvideInfoAboutIt.
All of this loading happens after opening a file with an extension my language package is tied to, which leads me to believe that it's actually trying to use my plugin for it.
I'm a bit lost here, the process of creating visual studio plugins looks intuitive on the surface, but seems cursed under the covers.
internal class ValLanguageScanner : IScanner
{
private IVsTextBuffer m_buffer;
string m_source;
public ValLanguageScanner(IVsTextBuffer buffer)
{
// Breakpoint gets hit here(to to creation in GetScanner method)
m_buffer = buffer;
}
bool IScanner.ScanTokenAndProvideInfoAboutIt(TokenInfo tokenInfo, ref int state)
{
// Breakpoint never gets hit here
var foundToken = false;
return foundToken;
}
void IScanner.SetSource(string source, int offset)
{
m_source = source.Substring(offset);
}
}
public class ValLanguageService : LanguageService
{
private const string _name = "Val";
private LanguagePreferences m_preferences;
private ValLanguageScanner m_scanner;
public override LanguagePreferences GetLanguagePreferences()
{
if (m_preferences == null)
{
m_preferences = new LanguagePreferences(this.Site,typeof(ValLanguageService).GUID,this.Name);
m_preferences.Init();
}
return m_preferences;
}
public override IScanner GetScanner(IVsTextLines buffer)
{
if (m_scanner == null)
{
m_scanner = new ValLanguageScanner(buffer);
}
return m_scanner;
}
public override AuthoringScope ParseSource(ParseRequest req)
{
return new ValLanguageAuthoringScope();
}
public override string GetFormatFilterList()
{
return "Val(*.val)|*.val";
}
public override string Name
{
get { return _name; }
}
}
[PackageRegistration(UseManagedResourcesOnly = true)]
[ProvideServiceAttribute(typeof(ValLanguageService),
ServiceName = "Val Language Service")]
[ProvideLanguageExtensionAttribute(typeof(ValLanguageService),
".val")]
[ProvideLanguageExtensionAttribute(typeof(ValLanguageService),
".vallist")]
[InstalledProductRegistration("#110", "#112", "1.0")]
public class ValLanguagePackage : Package, IOleComponent
{
private uint m_componentID;
public ValLanguagePackage()
{
Trace.WriteLine(string.Format(CultureInfo.CurrentCulture, "Entering constructor for: {0}", this.ToString()));
}
protected override void Initialize()
{
base.Initialize(); // required
// Proffer the service.
IServiceContainer serviceContainer = this as IServiceContainer;
ValLanguageService langService = new ValLanguageService();
langService.SetSite(this);
serviceContainer.AddService(typeof(ValLanguageService),
langService,
true);
// Register a timer to call our language service during
// idle periods.
IOleComponentManager mgr = GetService(typeof(SOleComponentManager))
as IOleComponentManager;
if (m_componentID == 0 && mgr != null)
{
OLECRINFO[] crinfo = new OLECRINFO[1];
crinfo[0].cbSize = (uint)Marshal.SizeOf(typeof(OLECRINFO));
crinfo[0].grfcrf = (uint)_OLECRF.olecrfNeedIdleTime |
(uint)_OLECRF.olecrfNeedPeriodicIdleTime;
crinfo[0].grfcadvf = (uint)_OLECADVF.olecadvfModal |
(uint)_OLECADVF.olecadvfRedrawOff |
(uint)_OLECADVF.olecadvfWarningsOff;
crinfo[0].uIdleTimeInterval = 1000;
int hr = mgr.FRegisterComponent(this, crinfo, out m_componentID);
}
}
protected override void Dispose(bool disposing)
{
if (m_componentID != 0)
{
Debug.WriteLine("OMG DISPOSING");
IOleComponentManager mgr = GetService(typeof(SOleComponentManager))
as IOleComponentManager;
if (mgr != null)
{
int hr = mgr.FRevokeComponent(m_componentID);
}
m_componentID = 0;
}
Debug.WriteLine("OMG DISPOSING BASE");
base.Dispose(disposing);
Debug.WriteLine("OMG DISPOSED");
}
#region IOleComponent Members
public int FDoIdle(uint grfidlef)
{
bool bPeriodic = (grfidlef & (uint)_OLEIDLEF.oleidlefPeriodic) != 0;
// Use typeof(TestLanguageService) because we need to
// reference the GUID for our language service.
LanguageService service = GetService(typeof(ValLanguageService))
as LanguageService;
if (service != null)
{
service.OnIdle(bPeriodic);
}
return 0;
}
public int FContinueMessageLoop(uint uReason,
IntPtr pvLoopData,
MSG[] pMsgPeeked)
{
return 1;
}
public int FPreTranslateMessage(MSG[] pMsg)
{
return 0;
}
public int FQueryTerminate(int fPromptUser)
{
return 1;
}
public int FReserved1(uint dwReserved,
uint message,
IntPtr wParam,
IntPtr lParam)
{
return 1;
}
public IntPtr HwndGetWindow(uint dwWhich, uint dwReserved)
{
return IntPtr.Zero;
}
public void OnActivationChange(IOleComponent pic,
int fSameComponent,
OLECRINFO[] pcrinfo,
int fHostIsActivating,
OLECHOSTINFO[] pchostinfo,
uint dwReserved)
{
}
public void OnAppActivate(int fActive, uint dwOtherThreadID)
{
}
public void OnEnterState(uint uStateID, int fEnter)
{
}
public void OnLoseActivation()
{
}
public void Terminate()
{
}
#endregion
}

Error on opening MemoryMappedFile in another process, C# compact framework

I have created a MemoryMappedFile using C#.Net Compact Framework on WinCE7.
When I am trying to open the same MemorymappedFile in another process, I am getting a null file handle.
Here is the code I am using.
namespace MMFWriteDemo
{
[Serializable]
public class FileMapIOException : IOException
{
private int m_win32Error;
public int Win32ErrorCode
{
get { return m_win32Error; }
}
public override string Message
{
get
{
if (Win32ErrorCode != 0)
return base.Message + " (" + Win32ErrorCode + ")";
return base.Message;
}
}
public FileMapIOException(int error)
: base()
{
m_win32Error = error;
}
public FileMapIOException(string message)
: base(message)
{
}
public FileMapIOException(string message, Exception innerException)
: base(message, innerException)
{
}
} // class FileMapIOException
public enum MapAccess
{
FileMapCopy = 0x0001,
FileMapWrite = 0x0002,
FileMapRead = 0x0004,
FileMapAllAccess = 0x001f,
}
[Flags]
public enum MapProtection
{
PageNone = 0x00000000,
// protection - mutually exclusive, do not or
PageReadOnly = 0x00000002,
PageReadWrite = 0x00000004,
PageWriteCopy = 0x00000008,
// attributes - or-able with protection
SecImage = 0x01000000,
SecReserve = 0x04000000,
SecCommit = 0x08000000,
SecNoCache = 0x10000000,
}
internal class Win32MapApis
{
[DllImport("coredll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern IntPtr CreateFile(
String lpFileName, int dwDesiredAccess, int dwShareMode,
IntPtr lpSecurityAttributes, int dwCreationDisposition,
int dwFlagsAndAttributes, IntPtr hTemplateFile);
[DllImport("coredll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern IntPtr CreateFileMapping(
IntPtr hFile, IntPtr lpAttributes, int flProtect,
int dwMaximumSizeLow, int dwMaximumSizeHigh,
String lpName);
[DllImport("coredll", SetLastError = true)]
public static extern bool FlushViewOfFile(
IntPtr lpBaseAddress, IntPtr dwNumBytesToFlush);
[DllImport("coredll", SetLastError = true)]
public static extern IntPtr MapViewOfFile(
IntPtr hFileMappingObject, int dwDesiredAccess, int dwFileOffsetHigh,
int dwFileOffsetLow, IntPtr dwNumBytesToMap);
//[DllImport("coredll", SetLastError = true, CharSet = CharSet.Auto)]
//public static extern IntPtr OpenFileMapping(
// int dwDesiredAccess, bool bInheritHandle, String lpName);
public static IntPtr OpenFileMapping(uint dwDesiredAccess, bool bInheritHandle, string lpName)
{
IntPtr t_pHandle = Win32MapApis.CreateFileMapping(new IntPtr(-1), IntPtr.Zero, (int)MapAccess.FileMapRead, 0, 0, lpName);
return t_pHandle;
}
[DllImport("coredll", SetLastError = true)]
public static extern bool UnmapViewOfFile(IntPtr lpBaseAddress);
[DllImport("coredll", SetLastError = true)]
public static extern bool CloseHandle(IntPtr handle);
[DllImport("coredll.dll", SetLastError = true)]
public static extern Int32 GetLastError();
} // class Win32MapApis
public class MemoryMappedFile : MarshalByRefObject, IDisposable
{
//! handle to MemoryMappedFile object
private IntPtr _hMap = IntPtr.Zero;
private MapProtection _protection = MapProtection.PageNone;
private string _fileName = "";
public string FileName { get { return _fileName; } }
private long _maxSize;
private readonly bool _is64bit;
public long MaxSize { get { return _maxSize; } }
#region Constants
private const int GENERIC_READ = unchecked((int)0x80000000);
private const int GENERIC_WRITE = unchecked((int)0x40000000);
private const int OPEN_ALWAYS = 4;
private static readonly IntPtr INVALID_HANDLE_VALUE = new IntPtr(-1);
private static readonly IntPtr NULL_HANDLE = IntPtr.Zero;
#endregion // Constants
#region Properties
public bool IsOpen
{
get { return (_hMap != NULL_HANDLE); }
}
public bool Is64bit
{
get { return _is64bit; }
}
private MemoryMappedFile()
{
_is64bit = IntPtr.Size == 8;
}
~MemoryMappedFile()
{
Dispose(false);
}
#region Create Overloads
public static MemoryMappedFile
Create(MapProtection protection, long maxSize, string name)
{
return Create(null, protection, maxSize, name);
}
public static MemoryMappedFile
Create(MapProtection protection, long maxSize)
{
return Create(null, protection, maxSize, null);
}
public static MemoryMappedFile
Create(string fileName, MapProtection protection)
{
return Create(fileName, protection, 0, null);
}
public static MemoryMappedFile
Create(string fileName, MapProtection protection,
long maxSize)
{
return Create(fileName, protection, maxSize, null);
}
public static MemoryMappedFile
Create(string fileName, MapProtection protection,
long maxSize, String name)
{
MemoryMappedFile map = new MemoryMappedFile();
if (!map.Is64bit && maxSize > uint.MaxValue)
throw new ConstraintException("32bit systems support max size of 4gb.");
// open file first
IntPtr hFile = INVALID_HANDLE_VALUE;
if (!string.IsNullOrEmpty(fileName))
{
if (maxSize == 0)
{
if (!File.Exists(fileName))
{
throw new Exception(string.Format("Winterdom.IO.FileMap.MemoryMappedFile.Create - \"{0}\" does not exist ==> Unable to map entire file", fileName));
}
FileInfo backingFileInfo = new FileInfo(fileName);
maxSize = backingFileInfo.Length;
if (maxSize == 0)
{
throw new Exception(string.Format("Winterdom.IO.FileMap.MemoryMappedFile.Create - \"{0}\" is zero bytes ==> Unable to map entire file", fileName));
}
}
// determine file access needed
// we'll always need generic read access
int desiredAccess = GENERIC_READ;
if ((protection == MapProtection.PageReadWrite) ||
(protection == MapProtection.PageWriteCopy))
{
desiredAccess |= GENERIC_WRITE;
}
// open or create the file
// if it doesn't exist, it gets created
hFile = Win32MapApis.CreateFile(
fileName, desiredAccess, 0,
IntPtr.Zero, OPEN_ALWAYS, 0, IntPtr.Zero
);
if (hFile == INVALID_HANDLE_VALUE)
//throw new FileMapIOException(Marshal.GetHRForLastWin32Error());
throw new FileMapIOException("MMF");
map._fileName = fileName;
}
map._hMap = Win32MapApis.CreateFileMapping(
hFile, IntPtr.Zero, (int)protection,
(int)((maxSize >> 32) & 0xFFFFFFFF),
(int)(maxSize & 0xFFFFFFFF), "unique"
);
// close file handle, we don't need it
if (hFile != INVALID_HANDLE_VALUE) Win32MapApis.CloseHandle(hFile);
if (map._hMap == NULL_HANDLE)
//throw new FileMapIOException(Marshal.GetHRForLastWin32Error());
throw new FileMapIOException("MMF");
map._protection = protection;
map._maxSize = maxSize;
return map;
}
#endregion // Create Overloads
public static MemoryMappedFile Open(MapAccess access, String name)
{
MemoryMappedFile map = new MemoryMappedFile
{
_hMap = Win32MapApis.OpenFileMapping((uint)access, false, name)
};
if (map._hMap == NULL_HANDLE)
throw new FileMapIOException("MMF");
//throw new FileMapIOException(Marshal.GetHRForLastWin32Error());
map._maxSize = -1; // debug unknown
return map;
}
public void Close()
{
Dispose(true);
}
public IntPtr MapView(MapAccess access, long offset, long size)
{
if (!IsOpen)
throw new ObjectDisposedException("Winterdom.IO.FileMap.MemoryMappedFile.MapView - MMF already closed");
// Throws OverflowException if (a) this is a 32-bit platform AND (b) size is out of bounds (ie. int bounds) with respect to this platform
IntPtr mapSize = new IntPtr(size);
IntPtr baseAddress = Win32MapApis.MapViewOfFile(
_hMap, (int)access,
(int)((offset >> 32) & 0xFFFFFFFF),
(int)(offset & 0xFFFFFFFF), mapSize
);
if (baseAddress == IntPtr.Zero)
throw new FileMapIOException("MMF");
//throw new FileMapIOException(Marshal.GetHRForLastWin32Error());
return baseAddress;
}
public MapViewStream MapAsStream()
{
if (!IsOpen)
throw new ObjectDisposedException("Winterdom.IO.FileMap.MemoryMappedFile.MapView - MMF already closed");
// sws should verify against _protection
// Don't know what to do about FILE_MAP_COPY et al
bool isWriteable = (_protection & MapProtection.PageReadWrite) == MapProtection.PageReadWrite;
return new MapViewStream(this, MaxSize, isWriteable);
}
public void UnMapView(IntPtr mapBaseAddr)
{
Win32MapApis.UnmapViewOfFile(mapBaseAddr);
}
public void UnMapView(MapViewStream mappedViewStream)
{
UnMapView(mappedViewStream.ViewBaseAddr);
}
public void Flush(IntPtr viewBaseAddr)
{
// Throws OverflowException if (a) this is a 32-bit platform AND (b) size is out of bounds (ie. int bounds) with respect to this platform
IntPtr flushLength = new IntPtr(MaxSize);
Win32MapApis.FlushViewOfFile(viewBaseAddr, flushLength);
}
public void Flush(MapViewStream mappedViewStream)
{
Flush(mappedViewStream.ViewBaseAddr);
}
#region IDisposable implementation
public void Dispose()
{
Dispose(true);
}
protected virtual void Dispose(bool disposing)
{
if (IsOpen)
Win32MapApis.CloseHandle(_hMap);
_hMap = NULL_HANDLE;
if (disposing)
GC.SuppressFinalize(this);
}
#endregion // IDisposable implementation
} // class MemoryMappedFile
public class MapViewStream : Stream, IDisposable
{
#region Map/View Related Fields
protected MemoryMappedFile _backingFile;
protected MapAccess _access = MapAccess.FileMapWrite;
protected bool _isWriteable;
IntPtr _viewBaseAddr = IntPtr.Zero; // Pointer to the base address of the currently mapped view
protected long _mapSize;
protected long _viewStartIdx = -1;
protected long _viewSize = -1;
long _position; //! our current position in the stream buffer
#region Properties
public IntPtr ViewBaseAddr
{
get { return _viewBaseAddr; }
}
public bool IsViewMapped
{
get { return (_viewStartIdx != -1) && (_viewStartIdx + _viewSize) <= (_mapSize); }
}
#endregion
#endregion // Map/View Related Fields
#region Map / Unmap View
#region Unmap View
protected void UnmapView()
{
if (IsViewMapped)
{
_backingFile.UnMapView(this);
_viewStartIdx = -1;
_viewSize = -1;
}
}
#endregion
#region Map View
protected void MapView(ref long viewStartIdx, ref long viewSize)
{
// Now map the view
_viewBaseAddr = _backingFile.MapView(_access, viewStartIdx, viewSize);
_viewStartIdx = viewStartIdx;
_viewSize = viewSize;
}
#endregion
#endregion
#region Constructors
internal MapViewStream(MemoryMappedFile backingFile, long mapSize, bool isWriteable)
{
if (backingFile == null)
{
throw new Exception("MapViewStream.MapViewStream - backingFile is null");
}
if (!backingFile.IsOpen)
{
throw new Exception("MapViewStream.MapViewStream - backingFile is not open");
}
if ((mapSize < 1) || (mapSize > backingFile.MaxSize))
{
throw new Exception(string.Format("MapViewStream.MapViewStream - mapSize is invalid. mapSize == {0}, backingFile.MaxSize == {1}", mapSize, backingFile.MaxSize));
}
_backingFile = backingFile;
_isWriteable = isWriteable;
_access = isWriteable ? MapAccess.FileMapWrite : MapAccess.FileMapRead;
// Need a backingFile.SupportsAccess function that takes a MapAccess compares it against its stored MapProtection protection and returns bool
_mapSize = mapSize;
_isOpen = true;
// Map the first view
Seek(0, SeekOrigin.Begin);
}
#endregion
#region Stream Properties
public override bool CanRead
{
get { return true; }
}
public override bool CanSeek
{
get { return true; }
}
public override bool CanWrite
{
get { return _isWriteable; }
}
public override long Length
{
get { return _mapSize; }
}
public override long Position
{
get { return _position; }
set { Seek(value, SeekOrigin.Begin); }
}
#endregion // Stream Properties
#region Stream Methods
public override void Flush()
{
if (!IsOpen)
throw new ObjectDisposedException("Winterdom.IO.FileMap.MapViewStream.Flush - Stream is closed");
// flush the view but leave the buffer intact
_backingFile.Flush(this);
}
public override int Read(byte[] buffer, int offset, int count)
{
if (!IsOpen)
throw new ObjectDisposedException("Stream is closed");
if (buffer.Length - offset < count)
throw new ArgumentException("Invalid Offset");
int bytesToRead = (int)Math.Min(Length - _position, count);
Marshal.Copy((IntPtr)(_viewBaseAddr.ToInt64() + _position), buffer, offset, bytesToRead);
_position += bytesToRead;
return bytesToRead;
}
public override void Write(byte[] buffer, int offset, int count)
{
if (!IsOpen)
throw new ObjectDisposedException("Stream is closed");
if (!CanWrite)
throw new FileMapIOException("Stream cannot be written to");
if (buffer.Length - offset < count)
throw new ArgumentException("Invalid Offset");
int bytesToWrite = (int)Math.Min(Length - _position, count);
if (bytesToWrite == 0)
return;
Marshal.Copy(buffer, offset, (IntPtr)(_viewBaseAddr.ToInt64() + _position), bytesToWrite);
_position += bytesToWrite;
}
public override long Seek(long offset, SeekOrigin origin)
{
if (!IsOpen)
throw new ObjectDisposedException("Stream is closed");
long newpos = 0;
switch (origin)
{
case SeekOrigin.Begin: newpos = offset; break;
case SeekOrigin.Current: newpos = Position + offset; break;
case SeekOrigin.End: newpos = Length + offset; break;
}
// sanity check
if (newpos < 0 || newpos > Length)
throw new FileMapIOException("Invalid Seek Offset");
_position = newpos;
if (!IsViewMapped)
{
MapView(ref newpos, ref _mapSize); // use _mapsize here??
}
return newpos;
}
public override void SetLength(long value)
{
// not supported!
throw new NotSupportedException("Winterdom.IO.FileMap.MapViewStream.SetLength - Can't change map size");
}
public override void Close()
{
Dispose(true);
}
#endregion // Stream methods
#region IDisposable Implementation
private bool _isOpen;
public bool IsOpen { get { return _isOpen; } }
public new void Dispose()
{
Dispose(true);
}
protected new virtual void Dispose(bool disposing)
{
if (IsOpen)
{
Flush();
UnmapView();
_isOpen = false;
}
if (disposing)
GC.SuppressFinalize(this);
}
~MapViewStream()
{
Dispose(false);
}
#endregion // IDisposable Implementation
} // class MapViewStream
public class GenericMemoryMappedArray<TValue> : IDisposable, IEnumerable<TValue>
where TValue : struct
{
#region Private fields
private string _path;
private string _fileName;
private string _uniqueName = "mmf-" + "12345Test";//Guid.NewGuid();
private long _fileSize;
private MemoryMappedFile _map;
private int _dataSize;
private bool _deleteFile = true;
private byte[] _buffer;
private IntPtr _memPtr;
private bool _autogrow = true;
private Dictionary<int, MapViewStream> _inUse = new Dictionary<int, MapViewStream>(10);
private Dictionary<int, DateTime> _lastUsedThread = new Dictionary<int, DateTime>();
private readonly object _lockObject = new object();
//private Timer _pooltimer;
private bool _isDisposed;
#endregion
#region Properties
public string UniqueName
{
get { return _uniqueName; }
set { _uniqueName = value; }
}
public long Length
{
get
{
return _fileSize / _dataSize;
}
}
public long Position
{
set
{
int threadId = Thread.CurrentThread.ManagedThreadId;
_lastUsedThread[threadId] = DateTime.UtcNow;
Stream s = GetView(threadId);
s.Position = value * _dataSize;
}
}
public bool AutoGrow
{
get { return _autogrow; }
set { _autogrow = value; }
}
public override string ToString()
{
return string.Format("Length {0}", Length);
}
#endregion
#region Constructor
public GenericMemoryMappedArray(long size, string path)
{
_path = path;
_fileName = Path.Combine(path, _uniqueName + ".bin");
//_fileName = Path.Combine(path, "mmfTest.bin");
// Get the size of TValue
_dataSize = Marshal.SizeOf(typeof(TValue));
// Allocate a global buffer for this instance
_buffer = new byte[_dataSize];
// Allocate a global unmanaged buffer for this instance
_memPtr = Marshal.AllocHGlobal(_dataSize);
SetFileSize(size);
}
#endregion
#region Finalizer
~GenericMemoryMappedArray()
{
Dispose(false);
}
#endregion
#region Private methods
private Stream GetView(int threadId)
{
MapViewStream s;
if (!_inUse.TryGetValue(threadId, out s))
{
// create new view and add to pool
MapViewStream mvs = _map.MapAsStream();
lock (_lockObject)
{
_inUse.Add(threadId, mvs);
}
return mvs;
}
return s;
}
private void SetFileSize(long size)
{
_fileSize = _dataSize * size;
_map = MemoryMappedFile.Create(_fileName, MapProtection.PageReadWrite, _fileSize);
}
#endregion
#region Public methods
public void Write(byte[] buffer)
{
int threadId = Thread.CurrentThread.ManagedThreadId;
_lastUsedThread[threadId] = DateTime.UtcNow;
Stream s = GetView(threadId);
s.Write(buffer, 0, buffer.Length);
}
public void WriteByte(byte b)
{
int threadId = Thread.CurrentThread.ManagedThreadId;
_lastUsedThread[threadId] = DateTime.UtcNow;
Stream s = GetView(threadId);
byte[] buffer = new byte[1] { b };
s.Write(buffer, 0, 1);
}
public int Read()
{
int threadId = Thread.CurrentThread.ManagedThreadId;
_lastUsedThread[threadId] = DateTime.UtcNow;
Stream s = GetView(threadId);
int count = s.Read(_buffer, 0, _buffer.Length);
return count;
}
public byte ReadByte()
{
int threadId = Thread.CurrentThread.ManagedThreadId;
Stream s = GetView(threadId);
return (byte)s.ReadByte();
}
public TValue this[long index]
{
get
{
lock (this)
{
if (index >= Length)
{
throw new ArgumentOutOfRangeException("index", "Tried to access item outside the array boundaries");
}
Position = index;
Read();
TValue value = ConvertToTValue();
return value;
}
}
set
{
lock (this)
{
if (index >= Length)
{
if (_autogrow)
Grow(index, 10);
else
{
throw new ArgumentOutOfRangeException("index", "Tried to access item outside the array");
}
}
Position = index;
ConvertToBytes(value);
Write(_buffer);
}
}
}
private void ConvertToBytes(TValue value)
{
// Could set the last parameter to false if TValue only contains value types
// Safer to leave it to true for all purposes.
Marshal.StructureToPtr(value, _memPtr, true);
Marshal.Copy(_memPtr, _buffer, 0, _dataSize);
}
private TValue ConvertToTValue()
{
Marshal.Copy(_buffer, 0, _memPtr, _dataSize);
object obj = Marshal.PtrToStructure(_memPtr, typeof(TValue));
return (TValue)obj;
}
private void Grow(long size, int percentage)
{
_deleteFile = false;
lock (_lockObject)
{
Dispose(true);
long oldSize = _fileSize;
_fileSize = (long)((float)size * _dataSize * ((100F + percentage) / 100F)); //required filesize
if (_fileSize < (oldSize + _dataSize))
{
_fileSize = oldSize + _dataSize;
}
_map = MemoryMappedFile.Create(_fileName, MapProtection.PageReadWrite, _fileSize);
}
}
#endregion
#region Clone Members
public GenericMemoryMappedArray<TValue> Clone()
{
string copyName = _uniqueName + Guid.NewGuid();
string currentPath = Path.Combine(_path, copyName + ".bin");
File.Copy(_fileName, currentPath);
GenericMemoryMappedArray<TValue> current = new GenericMemoryMappedArray<TValue>(Length, currentPath);
return current;
}
#endregion
#region IDisposable Members
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!_isDisposed && disposing)
{
lock (_lockObject)
{
// Clean up all views
foreach (KeyValuePair<int, MapViewStream> pair in _inUse)
{
pair.Value.Dispose();
pair.Value.Close();
}
_inUse.Clear();
_lastUsedThread.Clear();
}
if (_map != null)
{
_map.Close();
}
}
try
{
if (_deleteFile)
{
Marshal.DestroyStructure(_memPtr, typeof(TValue)); // Clear unmanaged buffer data
Marshal.FreeHGlobal(_memPtr); // Free unmanaged buffer
if (File.Exists(_fileName)) File.Delete(_fileName);
}
}
catch (Exception)
{
// TODO: Handle files which for some reason didn't want to be deleted
throw;
}
_deleteFile = true;
}
#endregion
#region IEnumerable<TValue> Members
public IEnumerator<TValue> GetEnumerator()
{
lock (this)
{
Position = 0;
for (int i = 0; i < Length; i++)
{
Read();
yield return ConvertToTValue();
}
}
}
#endregion
IEnumerator IEnumerable.GetEnumerator()
{
throw new NotImplementedException();
}
}
}
Application for creating the memory mapped file and writing to it, this works OK.
namespace MMFWriteDemo
{
class Program
{
static void Main(string[] args)
{
GenericMemoryMappedArray<byte> mmfTest = new GenericMemoryMappedArray<byte>(1024 * 1024 * 8, #"internal\data");
int i = 0;
byte b = 0;
while (i < 1000)
{
mmfTest.WriteByte(b);
b++;
if (b == 255)
{
b = 0;
}
i++;
}
Console.ReadLine();
}
}
}
This works good, i can see the file created and I can write to it.
Application for opening the memory mapped file and reading from it, it does not work.
namespace MMFReaderDemo
{
class Program
{
static void Main(string[] args)
{
GenericMemoryMappedArray<byte> mmfTest = new GenericMemoryMappedArray<byte>(1024 * 1024 * 8, #"internal\data");
int i = 0;
while (i < 100)
{
Console.WriteLine(mmfTest.ReadByte());
i++;
}
}
}
}
ErrorCode: 0x80000005
Actually I am trying to share the memory mapped file between driver(written in C++) and user app(written in C#).

Form1 is a type but is used as a variable

I am on the last piece of code before I can finally launch my app into alpha, however I'm stuck trying to get a key combination to register globally. I found a class that seems like it will do what I want (found from here):
using System;
using System.Windows.Forms;
using System.ComponentModel;
using System.Xml.Serialization;
using System.Runtime.InteropServices;
namespace Hotkey
{
public class Hotkey : IMessageFilter
{
#region Interop
[DllImport("user32.dll", SetLastError = true)]
private static extern int RegisterHotKey(IntPtr hWnd, int id, uint fsModifiers, Keys vk);
[DllImport("user32.dll", SetLastError=true)]
private static extern int UnregisterHotKey(IntPtr hWnd, int id);
private const uint WM_HOTKEY = 0x312;
private const uint MOD_ALT = 0x1;
private const uint MOD_CONTROL = 0x2;
private const uint MOD_SHIFT = 0x4;
private const uint MOD_WIN = 0x8;
private const uint ERROR_HOTKEY_ALREADY_REGISTERED = 1409;
#endregion
private static int currentID;
private const int maximumID = 0xBFFF;
private Keys keyCode;
private bool shift;
private bool control;
private bool alt;
private bool windows;
[XmlIgnore]
private int id;
[XmlIgnore]
private bool registered;
[XmlIgnore]
private Control windowControl;
public event HandledEventHandler Pressed;
public Hotkey() : this(Keys.None, false, false, false, false)
{
// No work done here!
}
public Hotkey(Keys keyCode, bool shift, bool control, bool alt, bool windows)
{
// Assign properties
this.KeyCode = keyCode;
this.Shift = shift;
this.Control = control;
this.Alt = alt;
this.Windows = windows;
// Register us as a message filter
Application.AddMessageFilter(this);
}
~Hotkey()
{
// Unregister the hotkey if necessary
if (this.Registered)
{ this.Unregister(); }
}
public Hotkey Clone()
{
// Clone the whole object
return new Hotkey(this.keyCode, this.shift, this.control, this.alt, this.windows);
}
public bool GetCanRegister(Control windowControl)
{
// Handle any exceptions: they mean "no, you can't register" :)
try
{
// Attempt to register
if (!this.Register(windowControl))
{ return false; }
// Unregister and say we managed it
this.Unregister();
return true;
}
catch (Win32Exception)
{ return false; }
catch (NotSupportedException)
{ return false; }
}
public bool Register(Control windowControl)
{
// Check that we have not registered
if (this.registered)
{ throw new NotSupportedException("You cannot register a hotkey that is already registered"); }
// We can't register an empty hotkey
if (this.Empty)
{ throw new NotSupportedException("You cannot register an empty hotkey"); }
// Get an ID for the hotkey and increase current ID
this.id = Hotkey.currentID;
Hotkey.currentID = Hotkey.currentID + 1 % Hotkey.maximumID;
// Translate modifier keys into unmanaged version
uint modifiers = (this.Alt ? Hotkey.MOD_ALT : 0) | (this.Control ? Hotkey.MOD_CONTROL : 0) |
(this.Shift ? Hotkey.MOD_SHIFT : 0) | (this.Windows ? Hotkey.MOD_WIN : 0);
// Register the hotkey
if (Hotkey.RegisterHotKey(windowControl.Handle, this.id, modifiers, keyCode) == 0)
{
// Is the error that the hotkey is registered?
if (Marshal.GetLastWin32Error() == ERROR_HOTKEY_ALREADY_REGISTERED)
{ return false; }
else
{ throw new Win32Exception(); }
}
// Save the control reference and register state
this.registered = true;
this.windowControl = windowControl;
// We successfully registered
return true;
}
public void Unregister()
{
// Check that we have registered
if (!this.registered)
{ throw new NotSupportedException("You cannot unregister a hotkey that is not registered"); }
// It's possible that the control itself has died: in that case, no need to unregister!
if (!this.windowControl.IsDisposed)
{
// Clean up after ourselves
if (Hotkey.UnregisterHotKey(this.windowControl.Handle, this.id) == 0)
{ throw new Win32Exception(); }
}
// Clear the control reference and register state
this.registered = false;
this.windowControl = null;
}
private void Reregister()
{
// Only do something if the key is already registered
if (!this.registered)
{ return; }
// Save control reference
Control windowControl = this.windowControl;
// Unregister and then reregister again
this.Unregister();
this.Register(windowControl);
}
public bool PreFilterMessage(ref Message message)
{
// Only process WM_HOTKEY messages
if (message.Msg != Hotkey.WM_HOTKEY)
{ return false; }
// Check that the ID is our key and we are registerd
if (this.registered && (message.WParam.ToInt32() == this.id))
{
// Fire the event and pass on the event if our handlers didn't handle it
return this.OnPressed();
}
else
{ return false; }
}
private bool OnPressed()
{
// Fire the event if we can
HandledEventArgs handledEventArgs = new HandledEventArgs(false);
if (this.Pressed != null)
{ this.Pressed(this, handledEventArgs); }
// Return whether we handled the event or not
return handledEventArgs.Handled;
}
public override string ToString()
{
// We can be empty
if (this.Empty)
{ return "(none)"; }
// Build key name
string keyName = Enum.GetName(typeof(Keys), this.keyCode);;
switch (this.keyCode)
{
case Keys.D0:
case Keys.D1:
case Keys.D2:
case Keys.D3:
case Keys.D4:
case Keys.D5:
case Keys.D6:
case Keys.D7:
case Keys.D8:
case Keys.D9:
// Strip the first character
keyName = keyName.Substring(1);
break;
default:
// Leave everything alone
break;
}
// Build modifiers
string modifiers = "";
if (this.shift)
{ modifiers += "Shift+"; }
if (this.control)
{ modifiers += "Control+"; }
if (this.alt)
{ modifiers += "Alt+"; }
if (this.windows)
{ modifiers += "Windows+"; }
// Return result
return modifiers + keyName;
}
public bool Empty
{
get { return this.keyCode == Keys.None; }
}
public bool Registered
{
get { return this.registered; }
}
public Keys KeyCode
{
get { return this.keyCode; }
set
{
// Save and reregister
this.keyCode = value;
this.Reregister();
}
}
public bool Shift
{
get { return this.shift; }
set
{
// Save and reregister
this.shift = value;
this.Reregister();
}
}
public bool Control
{
get { return this.control; }
set
{
// Save and reregister
this.control = value;
this.Reregister();
}
}
public bool Alt
{
get { return this.alt; }
set
{
// Save and reregister
this.alt = value;
this.Reregister();
}
}
public bool Windows
{
get { return this.windows; }
set
{
// Save and reregister
this.windows = value;
this.Reregister();
}
}
}
}
my understanding of how it should work is like so:
Hotkey hk = new Hotkey();
hk.KeyCode = Keys.1;
hk.Windows = true;
hk.Pressed += delegate { Console.WriteLine("Windows+1 pressed!"); };
hk.Register(myForm);
and my implementation into my form:
Hotkey hk = new Hotkey();
private void Form1_Load(object sender, EventArgs e)
{
hk.KeyCode = Keys.Alt;
hk.Windows = true;
hk.Pressed += hk_Pressed;
hk.Register(Form1);
}
private void hk_Pressed(object sender, EventArgs e)
{
MessageBox.Show("pressed");
}
but I get an error : Form1 is a type but is used as a variable now frankly I am completely lost as to where I am going wrong. I assumed that the name of the form is what needs passed in Register. I am new to C#, so it could be something that I'm doing fundamentally wrong, but I'm at my wits end here any help would be great.
hk.Register(this);
Just do that instead! It's looking for an instance of Form1.
Change hk.Register(myForm); to hk.Register(this);
It's the same thing as your mainForm
Also, I saw that you posted undernearth Michael's answer saying that it still doesn't fire.
You need to remove hk.Windows = true;

Hide mouse cursor after an idle time

I want to hide my mouse cursor after an idle time and it will be showed up when I move the mouse. I tried to use a timer but it didn't work well. Can anybody help me? Please!
If you are using WinForms and will only deploy on Windows machines then it's quite easy to use user32 GetLastInputInfo to handle both mouse and keyboard idling.
public static class User32Interop
{
public static TimeSpan GetLastInput()
{
var plii = new LASTINPUTINFO();
plii.cbSize = (uint)Marshal.SizeOf(plii);
if (GetLastInputInfo(ref plii))
return TimeSpan.FromMilliseconds(Environment.TickCount - plii.dwTime);
else
throw new Win32Exception(Marshal.GetLastWin32Error());
}
[DllImport("user32.dll", SetLastError = true)]
static extern bool GetLastInputInfo(ref LASTINPUTINFO plii);
struct LASTINPUTINFO
{
public uint cbSize;
public uint dwTime;
}
}
And then in your Form
public partial class MyForm : Form
{
Timer activityTimer = new Timer();
TimeSpan activityThreshold = TimeSpan.FromMinutes(2);
bool cursorHidden = false;
public Form1()
{
InitializeComponent();
activityTimer.Tick += activityWorker_Tick;
activityTimer.Interval = 100;
activityTimer.Enabled = true;
}
void activityWorker_Tick(object sender, EventArgs e)
{
bool shouldHide = User32Interop.GetLastInput() > activityThreshold;
if (cursorHidden != shouldHide)
{
if (shouldHide)
Cursor.Hide();
else
Cursor.Show();
cursorHidden = shouldHide;
}
}
}
Here is a contrived example of how to do it. You probably had some missing logic that was overriding the cursor's visibility:
public partial class Form1 : Form
{
public TimeSpan TimeoutToHide { get; private set; }
public DateTime LastMouseMove { get; private set; }
public bool IsHidden { get; private set; }
public Form1()
{
InitializeComponent();
TimeoutToHide = TimeSpan.FromSeconds(5);
this.MouseMove += new MouseEventHandler(Form1_MouseMove);
}
void Form1_MouseMove(object sender, MouseEventArgs e)
{
LastMouseMove = DateTime.Now;
if (IsHidden)
{
Cursor.Show();
IsHidden = false;
}
}
private void timer1_Tick(object sender, EventArgs e)
{
TimeSpan elaped = DateTime.Now - LastMouseMove;
if (elaped >= TimeoutToHide && !IsHidden)
{
Cursor.Hide();
IsHidden = true;
}
}
}
Need to account for Environment.Tickcount being negative:
public static class User32Interop
{
public static TimeSpan GetLastInput()
{
var plii = new LASTINPUTINFO();
plii.cbSize = (uint)Marshal.SizeOf(plii);
if (GetLastInputInfo(ref plii))
{
int idleTime = unchecked(Environment.TickCount - (int)plii.dwTime);
return TimeSpan.FromMilliseconds(idleTime);
}
else
throw new Win32Exception(Marshal.GetLastWin32Error());
}
[DllImport("user32.dll", SetLastError = true)]
static extern bool GetLastInputInfo(ref LASTINPUTINFO plii);
struct LASTINPUTINFO
{
public uint cbSize;
public uint dwTime;
}
}
If you try to hide the cursor from another thread you need to call Invoke(...) on the winform to enter the UI thread. Had cost me some headegg why Cursor.Hide() wasn't working. Also "PInvoke ShowCursor(bool bShow)" has the benefit to return the Show/Hide-Count.
[DllImport("user32.dll")]
static extern int ShowCursor(bool bShow);
private System.Timers.Timer _timerMouseAutoHide;
Point _lastPos = new Point(int.MaxValue);
readonly Stopwatch _stopwatch = new Stopwatch();
private int _cursorVisibilityCount = 0;
private void InitMouseAutoHide()
{
if (_timerMouseAutoHide != null)
return;
_timerMouseAutoHide = new Timer(100){AutoReset = false};
_timerMouseAutoHide.Elapsed += MouseAutoHideHit;
_timerMouseAutoHide.Start();
_stopwatch.Restart();
}
private void MouseAutoHideHit(object pSender, ElapsedEventArgs pE)
{
try
{
if (IsDisposed)
return;
var lCurrentPos = Cursor.Position;
var lCursorHasMoved = _lastPos != lCurrentPos;
_lastPos = lCurrentPos;
if (_cursorVisibilityCount < 0 && lCursorHasMoved)
{
//Cursor is not Visible and Mouse has moved
_cursorVisibilityCount = ShowCursor();
Debug.WriteLine($"Visible {lCurrentPos}, ShowCursor={_cursorVisibilityCount}");
}
else if (_cursorVisibilityCount > -1 && _stopwatch.ElapsedMilliseconds > 3000)
{
//Cursor is Visible and Mouse didn't move fox x ms.
_cursorVisibilityCount = HideCursor();
Debug.WriteLine($"Hidden {lCurrentPos}, ShowCursor={_cursorVisibilityCount}");
}
if (lCursorHasMoved)
_stopwatch.Restart();
}
catch (Exception lEx)
{
GLog.Error(lEx);
}
finally
{
_timerMouseAutoHide?.Start();
}
}
public int ShowCursor()
{
var lCursorVisibilityCount = 0;
Invoke(new Action(() =>
{
do
{
lCursorVisibilityCount = ShowCursor(true);
} while (lCursorVisibilityCount < 0);
}));
return lCursorVisibilityCount;
}
public int HideCursor()
{
var lCursorVisibilityCount = 0;
Invoke(new Action(() =>
{
do
{
lCursorVisibilityCount = ShowCursor(false);
} while (lCursorVisibilityCount > -1);
}));
return lCursorVisibilityCount;
}

Categories

Resources