Restore maximzed state on secondary monitor - c#

I have a problem about restore state of window when I maximized it on secondary monitor.
I maximized window on the not primary screen and then close.
When reopen window, it also maximized, but it is maximized on primary screen.
I want is maximized on the not primary screen (the screen display window when close).
Please help me if you know.
Note: if state of window is normal, window will be restored correct screen.
My code as below:
if (ShellState == WindowState.Maximized)
{
ShellState = WindowState.Normal;
LeftPosition = Screen.AllScreens[selectedScreen].WorkingArea.Left;
TopPosition = Screen.AllScreens[selectedScreen].WorkingArea.Top;
ShellHeight = Screen.AllScreens[selectedScreen].WorkingArea.Height;
ShellWidth = Screen.AllScreens[selectedScreen].WorkingArea.Width;
ShellState = WindowState.Maximized;
}

We had many problems on multi-screen systems using the standard WPF tools for storing and restoring the window state and size, as long as the screen assignment.
We endet with creating a custom behavior that uses the native WinAPI functions.
Here is the (simplified) source code of our behavior. You can use it in your application instead of the WPF tools.
You have to change the way the window placement will be stored. This can be a dependency property providing a container, a static Properties.Settings reference or something else. In the code below, a static ApplicationSettings reference is used as an example.
class WindowPlacementPersistenceBehavior : Behavior<Window>
{
protected override void OnAttached()
{
base.OnAttached();
this.AssociatedObject.SourceInitialized += this.AssociatedObject_SourceInitialized;
this.AssociatedObject.Closing += this.AssociatedObject_Closing;
}
protected override void OnDetaching()
{
this.AssociatedObject.SourceInitialized -= this.AssociatedObject_SourceInitialized;
this.AssociatedObject.Closing -= this.AssociatedObject_Closing;
base.OnDetaching();
}
private void AssociatedObject_Closing(object sender, CancelEventArgs e)
{
WINDOWPLACEMENT wp;
NativeMethods.GetWindowPlacement(new WindowInteropHelper(this.AssociatedObject).Handle, out wp);
// Here you can store the window placement
ApplicationSettings.WindowPlacement = wp.ToString();
}
private void AssociatedObject_SourceInitialized(object sender, EventArgs e)
{
// Here you can load the window placement
WINDOWPLACEMENT wp = WINDOWPLACEMENT.Parse(ApplicationSettings.WindowPlacement);
if (wp.ShowCmd == NativeMethods.SW_SHOWMINIMIZED)
{
// Don't start in the minimized state
wp.ShowCmd = NativeMethods.SW_SHOWNORMAL;
}
try
{
NativeMethods.SetWindowPlacement(new WindowInteropHelper(this.AssociatedObject).Handle, ref wp);
}
catch
{
}
}
[Serializable]
[StructLayout(LayoutKind.Sequential)]
private struct RECT
{
public int Left;
public int Top;
public int Right;
public int Bottom;
public static RECT Parse(string input)
{
RECT result;
string[] items = input.Split(';');
result.Left = int.Parse(items[0]);
result.Top = int.Parse(items[1]);
result.Right = int.Parse(items[2]);
result.Bottom = int.Parse(items[3]);
return result;
}
public override string ToString()
{
return this.Left + ";" + this.Top + ";" + this.Right + ";" + this.Bottom;
}
}
[Serializable]
[StructLayout(LayoutKind.Sequential)]
private struct POINT
{
public int X;
public int Y;
public static POINT Parse(string input)
{
POINT result;
string[] items = input.Split(';');
result.X = int.Parse(items[0]);
result.Y = int.Parse(items[1]);
return result;
}
public override string ToString()
{
return this.X + ";" + this.Y;
}
}
[Serializable]
[StructLayout(LayoutKind.Sequential)]
private struct WINDOWPLACEMENT
{
public int Length;
public int Flags;
public int ShowCmd;
public POINT MinPosition;
public POINT MaxPosition;
public RECT NormalPosition;
public static WINDOWPLACEMENT Parse(string input)
{
WINDOWPLACEMENT result = default(WINDOWPLACEMENT);
result.Length = Marshal.SizeOf(typeof(WINDOWPLACEMENT));
try
{
string[] items = input.Split('/');
result.Flags = int.Parse(items[0]);
result.ShowCmd = int.Parse(items[1]);
result.MinPosition = POINT.Parse(items[2]);
result.MaxPosition = POINT.Parse(items[3]);
result.NormalPosition = RECT.Parse(items[4]);
}
catch
{
}
return result;
}
public override string ToString()
{
return this.Flags + "/" + this.ShowCmd + "/" + this.MinPosition.ToString() + "/" + this.MaxPosition.ToString() + "/" + this.NormalPosition.ToString();
}
}
private static class NativeMethods
{
public const int SW_SHOWNORMAL = 1;
public const int SW_SHOWMINIMIZED = 2;
[DllImport("user32.dll")]
public static extern bool SetWindowPlacement(IntPtr hWnd, [In] ref WINDOWPLACEMENT lpwndpl);
[DllImport("user32.dll")]
public static extern bool GetWindowPlacement(IntPtr hWnd, [Out] out WINDOWPLACEMENT lpwndpl);
}
}
To use this behavior, just add it to your window in XAML:
<Window
xmlns:v="clr-namespace:YourNameSpace"
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity">
<i:Interaction.Behaviors>
<v:WindowPlacementPersistenceBehavior />
</i:Interaction.Behaviors>
</Window>

Related

How do I convert stdole.stdPicture to a .net image in C#?

Im building an Add-In for Outlook where I copy all exchange users from the global address list to the local contacts.
The problem is I want transfer the picture of the exchange user too, but exchUser.GetPicture() returns a stdole.stdPicture and I have not yet found a working solution to download or convert it into an image/jpg/...
Here the code to get the exchange User from the global address list:
private void EnumerateGAL()
{
Outlook.AddressList gal = Application.Session.GetGlobalAddressList();
if (gal != null)
{
for (int i = 1; i <= gal.AddressEntries.Count - 1; i++)
{
Outlook.AddressEntry addrEntry = gal.AddressEntries[i];
Outlook.ExchangeUser exchUser = addrEntry.GetExchangeUser();
if (addrEntry.AddressEntryUserType == Outlook.OlAddressEntryUserType.olExchangeUserAddressEntry
&& exchUser.CompanyName == "")
{
CreateContact(exchUser);
//exchUser.GetPicture() returns stdole.stdPicture
}
}
}
return;
}
The closest solution I found, was a conversion of stdole.IPictureDisp which returns a bitmap but IPuctureDisp and stdPicture isn´t the same as I read somewhere.
public static System.Drawing.Image ConvertPicture(stdole.IPictureDisp image)
{
int type = image.Type;
if (type == 1)
{
IntPtr hPal = (IntPtr)image.hPal;
return Image.FromHbitmap((IntPtr)image.Handle, hPal);
}
return null;
}
In the end I need to download the picture because I can only upload a picture to a contact with a path.
So, is there a way to download a stdPicture or convert it to be able to download it?
There are four main ways to get the job done.
The "traditional" approach is to use the GetIPictureDispFromPicture and GetPictureFromIPicture methods in the System.Windows.Forms.AxHost class. These are both protected members of the class, so you can't use them externally. For this reason, it is common to subclass the AxHost class and expose public methods that internally call the base class protected methods. This approach allows you to convert in both directions:
internal class AxHostConverter : AxHost
{
private AxHostConverter() : base("") { }
static public stdole.IPictureDisp ImageToPictureDisp(Image image)
{
return (stdole.IPictureDisp)GetIPictureDispFromPicture(image);
}
static public Image PictureDispToImage(stdole.IPictureDisp pictureDisp)
{
return GetPictureFromIPicture(pictureDisp);
}
}
Your second option is to use OleLoadPicture or OleCreatePictureIndirect. There's an old support article on the topic here. OleLoadPicture creates a new picture object and initializes it from the contents of a stream.
internal class OleCreateConverter
{
[DllImport("oleaut32.dll", EntryPoint = "OleCreatePictureIndirect",
CharSet = CharSet.Ansi, ExactSpelling = true, PreserveSig = true)]
private static extern int OleCreatePictureIndirect(
[In] PictDescBitmap pictdesc, ref Guid iid, bool fOwn,
[MarshalAs(UnmanagedType.Interface)] out object ppVoid);
const short _PictureTypeBitmap = 1;
[StructLayout(LayoutKind.Sequential)]
internal class PictDescBitmap
{
internal int cbSizeOfStruct = Marshal.SizeOf(typeof(PictDescBitmap));
internal int pictureType = _PictureTypeBitmap;
internal IntPtr hBitmap = IntPtr.Zero;
internal IntPtr hPalette = IntPtr.Zero;
internal int unused = 0;
internal PictDescBitmap(Bitmap bitmap)
{
this.hBitmap = bitmap.GetHbitmap();
}
}
public static stdole.IPictureDisp ImageToPictureDisp(Image image)
{
if (image == null || !(image is Bitmap))
{
return null;
}
PictDescBitmap pictDescBitmap = new PictDescBitmap((Bitmap)image);
object ppVoid = null;
Guid iPictureDispGuid = typeof(stdole.IPictureDisp).GUID;
OleCreatePictureIndirect(pictDescBitmap, ref iPictureDispGuid, true, out ppVoid);
stdole.IPictureDisp picture = (stdole.IPictureDisp)ppVoid;
return picture;
}
public static Image PictureDispToImage(stdole.IPictureDisp pictureDisp)
{
Image image = null;
if (pictureDisp != null && pictureDisp.Type == _PictureTypeBitmap)
{
IntPtr paletteHandle = new IntPtr(pictureDisp.hPal);
IntPtr bitmapHandle = new IntPtr(pictureDisp.Handle);
image = Image.FromHbitmap(bitmapHandle, paletteHandle);
}
return image;
}
}
Your third option is to use the VB6 compatibility library, documented here. To use this, you'll need to add a reference to Microsoft.VisualBasic.Compatibility.dll, which is listed on the .NET tab of the Add References dialog (it resides in the GAC). Then, you can use the ImageToIPictureDisp and IPictureDispToImage methods in the Support class. This is obviously by far the simplest approach, although it does pull in the VB6 compatibility DLL. Internally, the VB6 compatibility code looks a lot like the second option above – using OleCreatePictureIndirect.
using Microsoft.VisualBasic.Compatibility.VB6;
internal class VB6CompatibilityConverter
{
public static stdole.IPictureDisp ImageToPictureDisp(Image image)
{
return (stdole.IPictureDisp)Support.ImageToIPictureDisp(image);
}
public static Image PictureDispToImage(stdole.IPictureDisp pictureDisp)
{
return Support.IPictureDispToImage(pictureDisp);
}
}
Finally, you can implement IPictureDisp and IPicture yourself. This is fine if you just want to convert from an Image to an IPictureDisp, but doesn't help you converting in the other direction. The implementation below relies on the Image actually being a derived Bitmap type, because we call Bitmap.GetHbitmap internally. If you want to keep the support to the generic Image type, you'll have to do a lot more work to p/invoke to a bunch of undocumented GDI methods instead
internal class PictureDispConverter
{
public static stdole.IPictureDisp BitmapToPictureDisp(Bitmap bitmap)
{
return new PictureDispImpl(bitmap);
}
public static Image PictureDispToBitmap(stdole.IPictureDisp pictureDisp)
{
// TODO
return null;
}
}
internal class PictureDispImpl : stdole.IPictureDisp, stdole.IPicture
{
#region Init
[DllImport("gdi32.dll")]
static extern void DeleteObject(IntPtr handle);
private Bitmap _image;
private IntPtr _handle;
public PictureDispImpl(Bitmap image)
{
_image = image;
}
~PictureDispImpl()
{
if (_handle != IntPtr.Zero)
{
DeleteObject(_handle);
}
}
#endregion
#region IPictureDisp Members
public int Width
{
get { return _image.Width; }
}
public int Height
{
get { return _image.Height; }
}
public short Type
{
get { return 1; }
}
public int Handle
{
get
{
if (_handle == IntPtr.Zero)
{
_handle = _image.GetHbitmap();
}
return _handle.ToInt32();
}
}
public int hPal
{
get { return 0; }
set { }
}
public void Render(
int hdc, int x, int y, int cx, int cy, int xSrc, int ySrc, int cxSrc, int cySrc, IntPtr prcWBounds)
{
Graphics graphics = Graphics.FromHdc(new IntPtr(hdc));
graphics.DrawImage(
_image, new Rectangle(x, y, cx, cy), xSrc, ySrc, cxSrc, cySrc, GraphicsUnit.Pixel);
}
#endregion
#region IPicture Members
public int Attributes
{
get { return 0; }
}
public int CurDC
{
get { return 0; }
}
public bool KeepOriginalFormat
{
get { return false; }
set { }
}
public void PictureChanged()
{
}
public void SaveAsFile(IntPtr pstm, bool fSaveMemCopy, out int pcbSize)
{
pcbSize = 0;
}
public void SelectPicture(int hdcIn, out int phdcOut, out int phbmpOut)
{
phdcOut = 0;
phbmpOut = 0;
}
public void SetHdc(int hdc)
{
}
#endregion
}

Xamarin Binding Libriary 'Overlay': member names cannot be the same as their enclosing type

I'm need rename field "Overlay", but not remove.
I'm try make link native jar lib to xamarin dll.
I`m create new Binding Libriary project and include jar file inside.
But when i'm try build solution, system output window get error
'Overlay': member names cannot be the same as their enclosing type.
I'm try configurate MetaData file in the following way.
<metadata>
<remove-node path="/api/package[#name='Com.Cdcom.Naviapps.Progorod']/class[#name='Overlay']/method[#name='Overlay']" />
</metadata>
or
<remove-node path="/api/package[#name='Com.Cdcom.Naviapps.Progorod']/class[#name='Overlay']" />
or i'm try change EnumMethods
<enum-method-mappings>
<mapping jni-class="/api/package[#name='com.cdcom.naviapps.progorod']/class[#name='Overlay']">
<method jni-name="Overlay" parameter="return" clr-enum-type="Android.OS.Overlay" />
</mapping>
</enum-method-mappings>
but i'm get other error
"generator.exe" exited with code -532462766.
You can see the class from first error below
// Metadata.xml XPath class reference: path="/api/package[#name='com.cdcom.naviapps.progorod']/class[#name='Overlay']"
[global::Android.Runtime.Register ("com/cdcom/naviapps/progorod/Overlay", DoNotGenerateAcw=true)]
public partial class Overlay : global::Java.Lang.Object {
//region "Event implementation for Com.Cdcom.Naviapps.Progorod.Overlay.IOnOverlayListener"
public event EventHandler<global::Com.Cdcom.Naviapps.Progorod.Overlay.OverlayEventArgs> Overlay {
add {
global::Java.Interop.EventHelper.AddEventHandler<global::Com.Cdcom.Naviapps.Progorod.Overlay.IOnOverlayListener, global::Com.Cdcom.Naviapps.Progorod.Overlay.IOnOverlayListenerImplementor>(
ref weak_implementor___SetOnOverlayListener,
__CreateIOnOverlayListenerImplementor,
__v => OnOverlayListener = __v,
__h => __h.Handler += value);
}
remove {
global::Java.Interop.EventHelper.RemoveEventHandler<global::Com.Cdcom.Naviapps.Progorod.Overlay.IOnOverlayListener, global::Com.Cdcom.Naviapps.Progorod.Overlay.IOnOverlayListenerImplementor>(
ref weak_implementor___SetOnOverlayListener,
global::Com.Cdcom.Naviapps.Progorod.Overlay.IOnOverlayListenerImplementor.__IsEmpty,
__v => OnOverlayListener = null,
__h => __h.Handler -= value);
}
}
//endregion
}
Original java code
public class Overlay
{
public List<OverlayItem> getItems()
{
return this.mOverlayItems;
}
public OnOverlayListener getOnOverlayListener()
{
return this.mOverlayListener;
}
public void populate()
{
double[] latlon = new double[this.mOverlayItems.size() * 2];
int d = 0;
for (OverlayItem oi : this.mOverlayItems)
{
latlon[(d++)] = oi.getGeoPoint().getLatitude();
latlon[(d++)] = oi.getGeoPoint().getLongitude();
}
Native.populateOverlay(this.mId, latlon);
}
public void setBitmap(Bitmap bitmap, float xOffset, float yOffset, boolean isPlain, int sizeInMeters)
{
int width = 0;
int height = 0;
int[] pixels = null;
if (bitmap != null)
{
width = bitmap.getWidth();
height = bitmap.getHeight();
pixels = new int[width * height];
bitmap.getPixels(pixels, 0, width, 0, 0, width, height);
}
Native.setOverlayBitmap(this.mId, width, height, pixels, xOffset, yOffset, isPlain, sizeInMeters);
}
public void setOnOverlayListener(OnOverlayListener listener)
{
this.mOverlayListener = listener;
}
public static int SPECIAL_OVERLAY_START_ROUTE = -1;
public static int SPECIAL_OVERLAY_FINISH_ROUTE = -2;
public static int SPECIAL_OVERLAY_ROUTE_SPRITE = -3;
public static int SPECIAL_OVERLAY_GEOBLOG_SPRITE = -4;
private static int SPECIAL_OVERLAYS_COUNT = 4;
public static Overlay specialOverlay(int id)
{
if (mSpecialOverlays[(id + SPECIAL_OVERLAYS_COUNT)] == null)
{
mSpecialOverlays[(id + SPECIAL_OVERLAYS_COUNT)] = new Overlay();
mSpecialOverlays[(id + SPECIAL_OVERLAYS_COUNT)].mId = id;
}
return mSpecialOverlays[(id + SPECIAL_OVERLAYS_COUNT)];
}
protected int getId()
{
return this.mId;
}
protected int mId = mNextId++;
private static int mNextId = 1;
private List<OverlayItem> mOverlayItems = new ArrayList();
private OnOverlayListener mOverlayListener;
private static Overlay[] mSpecialOverlays = new Overlay[SPECIAL_OVERLAYS_COUNT];
public static abstract interface OnOverlayListener
{
public abstract void onOverlayEvent(Overlay paramOverlay, OverlayItem paramOverlayItem);
}
}

Registar User Defined Hot Key

My Solution
[DllImport("user32.dll")]
public static extern bool RegisterHotKey(IntPtr hWnd, int id, uint fsModifiers, int vk);
[DllImport("user32.dll")]
public static extern bool UnregisterHotKey(IntPtr hWnd, int id);
public enum KeyModifiers : uint { None = 0, Alt = 1, Control = 2, Shift = 4, Windows = 8, }
Actions<int, string> Directories = new Dictionary<int, string>();
const string MessageTitle = "Opps, Somthing Happened!";
const MessageBoxButtons msgButtons = MessageBoxButtons.OK;
const MessageBoxIcon msgIcon = MessageBoxIcon.Information;
private void btnCreateShortcut_Click(object sender, EventArgs e)
{
if (cboModifier.SelectedIndex > 0)
{
uint key = (uint)Enum.Parse(typeof(KeyModifiers), cboModifier.SelectedItem.ToString());
if (txtShortcutKey.Text != "")
CreateHotKey(key, txtShortcutKey.Text.ToString());
else
MessageBox.Show("Please enter a Hot key to use", MessageTitle, msgButtons, msgIcon);
}
else
MessageBox.Show("Please Select a Base Key", MessageTitle, msgButtons, msgIcon);
}
private void btnDestroyShortcuts_Click(object sender, EventArgs e)
{
destroyShortcuts();
}
private void quickActions_FormClosing(object sender, FormClosingEventArgs e)
{
destroyShortcuts();
}
protected override void WndProc(ref Message msg)
{
switch (msg.Msg)
{
case 0x0312:
if (Actions.ContainsKey((int)msg.WParam))
// Preform Action
break;
}
base.WndProc(ref msg);
}
public void destroyShortcuts()
{
foreach (KeyValuePair<int, string> pair in Actions)
UnregisterHotKey(this.Handle, pair.Key);
lstActiveKeys.Items.Clear();
Actions.Clear();
}
public void CreateHotKey(uint modifier, string key)
{
int keyID = (Actions.Count + 1) * 100;
Actions.Add(keyID, txtAction.Text.ToString());
lstActiveKeys.Items.Add(modifier + "+" + key[0] + " - " + txtAction.Text.ToString());
RegisterHotKey(this.Handle, keyID, modifier, (int)((char)key[0]));
}
I would like to know how to make it so that my users could define their own hot keys given the options for select a control key and a letter.
All of the code I found showed how to define one single hot key, but one users could have 3 and another could have 5 and they may not be the same keys.
What I would like, is given a control key and a alphanumeric key I can create a Windows Hot Key.
I also need to be able to destroy the registered keys when the application is closed.
PS: These needs to be system-wide not just within the application. Thanks #scott-chapman for pointing that out
This is a link to a VS2010 project that does just that. I wrote it last year. File is hosted on SkyDrive.
http://sdrv.ms/Wc2R5H
Here is the solution I developed this is a C# method that appears to be working rather nicely.
[DllImport("user32.dll")]
public static extern bool RegisterHotKey(IntPtr hWnd, int id, uint fsModifiers, int vk);
[DllImport("user32.dll")]
public static extern bool UnregisterHotKey(IntPtr hWnd, int id);
public enum KeyModifiers : uint { None = 0, Alt = 1, Control = 2, Shift = 4, Windows = 8, }
Actions<int, string> Directories = new Dictionary<int, string>();
const string MessageTitle = "Opps, Somthing Happened!";
const MessageBoxButtons msgButtons = MessageBoxButtons.OK;
const MessageBoxIcon msgIcon = MessageBoxIcon.Information;
private void btnCreateShortcut_Click(object sender, EventArgs e)
{
if (cboModifier.SelectedIndex > 0)
{
uint key = (uint)Enum.Parse(typeof(KeyModifiers), cboModifier.SelectedItem.ToString());
if (txtShortcutKey.Text != "")
CreateHotKey(key, txtShortcutKey.Text.ToString());
else
MessageBox.Show("Please enter a Hot key to use", MessageTitle, msgButtons, msgIcon);
}
else
MessageBox.Show("Please Select a Base Key", MessageTitle, msgButtons, msgIcon);
}
private void btnDestroyShortcuts_Click(object sender, EventArgs e)
{
destroyShortcuts();
}
private void quickActions_FormClosing(object sender, FormClosingEventArgs e)
{
destroyShortcuts();
}
protected override void WndProc(ref Message msg)
{
switch (msg.Msg)
{
case 0x0312:
if (Actions.ContainsKey((int)msg.WParam))
// Preform Action
break;
}
base.WndProc(ref msg);
}
public void destroyShortcuts()
{
foreach (KeyValuePair<int, string> pair in Actions)
UnregisterHotKey(this.Handle, pair.Key);
lstActiveKeys.Items.Clear();
Actions.Clear();
}
public void CreateHotKey(uint modifier, string key)
{
int keyID = (Actions.Count + 1) * 100;
Actions.Add(keyID, txtAction.Text.ToString());
lstActiveKeys.Items.Add(modifier + "+" + key[0] + " - " + txtAction.Text.ToString());
RegisterHotKey(this.Handle, keyID, modifier, (int)((char)key[0]));
}

Implementing a drag over window option

Note:
Using Windows Forms
preferably C# .NET
Question:
Best method for implementing a drag-over-window tool, similar (or identical) to that featured in process explorer, to obtain the process ID corresponding to the selected Window
I think the easiest way is to put a control on your form that acts as a starting point; you press a mouse button there, and then you move it over the screen while the button is pressed, and pick up the process ID of whatever you are pointing at. I my example I have used a panel (called _aim).
First we set up the mouse events:
private void Panel_MouseDown(object sender, MouseEventArgs e)
{
// make all mouse events being raised in the _aim panel
// regardless of whether the mouse is within the control's
// bounds or not
_aim.Capture = true;
}
private void Panel_MouseMove(object sender, MouseEventArgs e)
{
if (_aim.Capture)
{
// get the process id only if we have mouse capture
uint processId = GetProcessIdFromPoint(
_aim.PointToScreen(e.Location)).ToString();
// do something with processId (store it for remembering the
// last processId seen, to be used as MouseUp for instance)
}
}
private void Panel_MouseUp(object sender, MouseEventArgs e)
{
if (_aim.Capture)
{
// release capture if we have it
_aim.Capture = false;
// perhaps do something more (fetch info about last seen
// process id, if we stored it during MouseMove, for instance)
}
}
The GetProcessIdFromPoint method looks like this:
private uint GetProcessIdFromPoint(Point point)
{
uint procId;
WinApi.GetWindowThreadProcessId(WinApi.WindowFromPoint(point), out procId);
return procId;
}
And finally the windows API things (from pinvoke.net):
public static class WinApi
{
[StructLayout(LayoutKind.Sequential)]
public struct POINT
{
public int X;
public int Y;
public POINT(int x, int y)
{
this.X = x;
this.Y = y;
}
public static implicit operator System.Drawing.Point(POINT p)
{
return new System.Drawing.Point(p.X, p.Y);
}
public static implicit operator POINT(System.Drawing.Point p)
{
return new POINT(p.X, p.Y);
}
}
[DllImport("user32.dll")]
public static extern IntPtr WindowFromPoint(POINT Point);
[DllImport("user32.dll", SetLastError = true)]
public static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
}

How do i capture the Print Screen key?

I my program I need to capture when the Print Screen key is pressed down but it is not working (however it works with other keys).
I guess this has something to do with windows hijacking my authority and since im still new at this I'd love to know how I can get around this issue.
Here's my current code:
namespace Boom_Screenshot_
{
/// <summary>
/// Interaction logic for Window1.xaml
/// </summary>
public partial class Window1 : Window
{
//SETTINGS
Key TRIGGER_KEY = Key.PrintScreen;
public Window1()
{
InitializeComponent();
}
private void Window_KeyDown(object sender, KeyEventArgs e)
{
if (e.Key == TRIGGER_KEY)
{
MessageBox.Show("'PrintScreen' was pressed.");
}
}
}
}
I have an answer for you that I found here (I don't speak Chinese so don't ask me what it says :). You have to set a hook. He provides a wrapper class. I repeat some code here without the Chinese characters. RegisterHotKey.cs ...
using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace TestKeydown
{
public class RegisterHotKeyClass
{
private IntPtr m_WindowHandle = IntPtr.Zero;
private MODKEY m_ModKey = MODKEY.MOD_CONTROL;
private Keys m_Keys = Keys.A;
private int m_WParam = 10000;
private bool Star = false;
private HotKeyWndProc m_HotKeyWnd = new HotKeyWndProc();
public IntPtr WindowHandle
{
get { return m_WindowHandle; }
set { if (Star)return; m_WindowHandle = value; }
}
public MODKEY ModKey
{
get { return m_ModKey; }
set { if (Star)return; m_ModKey = value; }
}
public Keys Keys
{
get { return m_Keys; }
set { if (Star)return; m_Keys = value; }
}
public int WParam
{
get { return m_WParam; }
set { if (Star)return; m_WParam = value; }
}
public void StarHotKey()
{
if (m_WindowHandle != IntPtr.Zero)
{
if (!RegisterHotKey(m_WindowHandle, m_WParam, m_ModKey, m_Keys))
{
throw new Exception("");
}
try
{
m_HotKeyWnd.m_HotKeyPass = new HotKeyPass(KeyPass);
m_HotKeyWnd.m_WParam = m_WParam;
m_HotKeyWnd.AssignHandle(m_WindowHandle);
Star = true;
}
catch
{
StopHotKey();
}
}
}
private void KeyPass()
{
if (HotKey != null) HotKey();
}
public void StopHotKey()
{
if (Star)
{
if (!UnregisterHotKey(m_WindowHandle, m_WParam))
{
throw new Exception("");
}
Star = false;
m_HotKeyWnd.ReleaseHandle();
}
}
public delegate void HotKeyPass();
public event HotKeyPass HotKey;
private class HotKeyWndProc : NativeWindow
{
public int m_WParam = 10000;
public HotKeyPass m_HotKeyPass;
protected override void WndProc(ref Message m)
{
if (m.Msg == 0x0312 && m.WParam.ToInt32() == m_WParam)
{
if (m_HotKeyPass != null) m_HotKeyPass.Invoke();
}
base.WndProc(ref m);
}
}
public enum MODKEY
{
MOD_ALT = 0x0001,
MOD_CONTROL = 0x0002,
MOD_SHIFT = 0x0004,
MOD_WIN = 0x0008,
}
[DllImport("user32.dll")]
public static extern bool RegisterHotKey(IntPtr wnd, int id, MODKEY mode, Keys vk);
[DllImport("user32.dll")]
public static extern bool UnregisterHotKey(IntPtr wnd, int id);
}
}
Calling code in a Form ...
private RegisterHotKeyClass _RegisKey = new RegisterHotKeyClass();
void _Regis_HotKey()
{
MessageBox.Show("ok");
}
private void Form1_Load(object sender, EventArgs e)
{
_RegisKey.Keys = Keys.PrintScreen;
_RegisKey.ModKey = 0;
_RegisKey.WindowHandle = this.Handle;
_RegisKey.HotKey += new RegisterHotKeyClass.HotKeyPass(_Regis_HotKey);
_RegisKey.StarHotKey();
}
Below is my pure WPF solution.
We can achieve this in xaml by using NavigationCommands (Namespace: System.Window.Input) class which provides a standard set of navigation commands (e.g. NextPage, PreviousPage, Refresh, Search etc.)
Implementation Approach:
So we can call any custom code to execute on application refresh using NavigationCommands.Refresh as
<UserControl.CommandBindings>
<CommandBinding Command='NavigationCommands.Refresh'
Executed="ApplicationRefresh_Executed">
</CommandBinding>
</UserControl.CommandBindings>
Now in code behind class of UserControl we can define method as
private void ApplicationRefresh_Executed(object sender, ExecutedRoutedEventArgs e)
{
// Implementation goes here.
}

Categories