i'm using c# .net 4.5;
my question is how could i get the cmd location.
for example to get my own form location i use this.Location and i'm getting the x and the y.
how could i do it for an application which is running but has nothing to do with my own app? i know it's possible because windows 8 use something like that. :)
thanks for helping...
Your question at first glance seems you want the location of the application exe and not the position of the window. If you want the position of the window you need to use API.
[StructLayout(LayoutKind.Sequential)]
public struct Rect
{
public int left;
public int top;
public int right;
public int bottom;
}
[DllImport("user32.dll")]
public static extern IntPtr GetWindowRect(IntPtr hWnd, ref Rect rect
And then use it like so:
var proc = Process.GetProcessesByName(proccessName)[0];
Rect rect = new Rect();
GetWindowRect(proc.MainWindowHandle, ref rect);
Hope it helps
For more information look at MSDN and pInvoke
Related
So, I have been asked to figure out a way to make a program containing sensitive data more secure since we have staff that go afk and put potentially put data at risk.
I have loaded up Visual Studio for C# and found a nice way to get process of the fore mentioned application. Then grab the main window and attach a panel of my very own. This panel will basically now be used like a blind covering the application when its not in use.
Now, I have a program running in system tray waiting for the sensitive data to come on screen and my little panel hijacks the entire window and now nothing can be seen.
My problem now is how ever, that whilst my panel is attacked the main window of the application i am trying to lock out seems to just crash. I am guessing that is because my panel and the application belong to different processes.
Anyway I could do with some advise here.
Here is my panels class.
class LockingPanel : System.Windows.Forms.Panel
{
private IntPtr prn;
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
public void SetParent(IntPtr parent)
{
prn = parent;
SetParent(this.Handle, prn);
}
public IntPtr GetParent() {
return prn;
}
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool GetWindowRect(IntPtr hWnd, ref RECT Rect);
[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
public int Left; // x position of upper-left corner
public int Top; // y position of upper-left corner
public int Right; // x position of lower-right corner
public int Bottom; // y position of lower-right corner
}
public void FillParent()
{
RECT rtc = new RECT();
GetWindowRect(prn, ref rtc);
this.Location = new System.Drawing.Point(0, 0);
this.Size = new System.Drawing.Size(rtc.Right, rtc.Bottom);
}
Anybody got a better idea on how I can go about this, or at least make it so that my panel inst going to crash the application.
I want to get Screenshots of a possible hidden Window of another application that is using drawing via direct3d or opengl. I tryed a lot of ways to receive this windows content but only got black or transparent pictures. The closest i got was by using a DWM sample here
http://bartdesmet.net/blogs/bart/archive/2006/10/05/4495.aspx
this paints the window onto my c# form but i cant get the pixelcolors. If ill do a form.drawtobitmap the pixels drawn by dwm are missing.
So is their any way to use DWM to recive the capture into a image
or to get the image drawn onto my form?
To answer your question:
You can use GetPixel() Win32 function. But it's overkill in this situation.
Pinvoke GetPixel
MSDN GetPixel
The right way, is to get the device context and bit blit the content.
EDIT:
I've thrown together some code, by using PrintWindow. Seems to work quite well, even with media players. Note that GetWindowRect returns invalid rectangle for minimized Windows. But it's a decent start.
[StructLayout(LayoutKind.Sequential)]
public struct Rect
{
internal Rect(int left, int top, int right, int bottom)
{
Left = left;
Top = top;
Right = right;
Bottom = bottom;
}
public int Left;
public int Top;
public int Right;
public int Bottom;
}
[DllImport("user32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool PrintWindow(IntPtr hwnd, IntPtr hDC, uint nFlags);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetWindowRect(IntPtr hwnd, out Rect lpRect);
public void DumpWindow(IntPtr hwndSource, string filename)
{
Rect rc;
GetWindowRect(hwndSource, out rc);
var bmp = new Bitmap(rc.Right - rc.Left, rc.Bottom - rc.Top, PixelFormat.Format32bppArgb);
using (Graphics gBmp = Graphics.FromImage(bmp))
{
IntPtr hdcBmp = gBmp.GetHdc();
PrintWindow(hwndSource, hdcBmp, 0);
gBmp.ReleaseHdc(hdcBmp);
}
bmp.Save(filename);
}
Edit2:
And if you add a second button to DWM demo form, insert this:
private void button1_Click(object sender, EventArgs e)
{
var w = (Window)lstWindows.SelectedItem;
DumpWindow(w.Handle, "test.bmp");
Process.Start("test.bmp");
}
It still shows an empty image?
Having worked out how to obtain the mouse click position anywhere along the monitor boundaries using low level hooks I receive an X Y coordinate that will contain a value typically between x: -1680 to +1920 and y: 0 to 1200 in my pcs case. Easy enough!
Now the problem is that I now want to calculate the mouse position relative to a given window that I have so I use GetForegroundWindow() and GetWindowRect(HandleRef hWnd, out RECT lpRect) to obtain my active window coordinates.
Where I am stuck is I require the current active desktop (By active I mean which monitor the click occurred on) to calculate the coordinates of my mouse click relative to a window.
Unfortunately I have not been able to find an API call like GetActiveMonitor() or similar so hopefully someone can point me in the right direction?
[DllImport("user32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool GetWindowRect(IntPtr hWnd, ref RECT lpRect);
[StructLayout(LayoutKind.Sequential)]
private struct RECT
{
public int Left;
public int Top;
public int Right;
public int Bottom;
}
Call it as:
RECT rct = new RECT();
GetWindowRect(hWnd, ref rct);
after get your mouse position like this
int mouserelativepositionX = mousePosition.X - rct.Left;
int mouserelativepositionY = mousePosition.Y - rct.Top;
My guess is that you can know where your mouse is by using an if:
if(mousePosition.X > -1680 && mousePosition.X < 0)
//We are in monitor 1;
else
//Monitor 2;
Problem
When you search for such question using google you get a lot of hits but all solutions assume you have at least one window.
But my question is just like I phrased it -- not assumptions at all. I can have a window, but I could have zero windows (because I didn't even show one or I just closed the last one). So in short the solution cannot rely on any widget or window -- the only thing is known, is there is a desktop (and app running, but it does not have any windows).
So the question is -- how to get the mouse position?
Background
I would like to show windows centered to mouse position. There is no such mode in WPF (there are only center to owner, or center to screen) so I have to do it manually. The missing piece is mouse position.
Edits
Thank you all, so now I have the first part of the solution -- raw position. Now there is a problem how to convert the data for WPF. I found such topic:
WPF Pixels to desktop pixels
but again, it assumes having some window.
Then I googled more and I found solution:
http://jerryclin.wordpress.com/2007/11/13/creating-non-rectangular-windows-with-interop/
the code includes class for scaling up/down coordinates relying only on info about desktop. So joining those two pieces, I finally get the solution :-). Thanks again.
Getting the Screen Coordinates:
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool GetCursorPos(out POINT lpPoint);
[StructLayout(LayoutKind.Sequential)]
public struct POINT
{
public int X;
public int Y;
public POINT(int x, int y)
{
this.X = x;
this.Y = y;
}
}
private void WritePoint(object sender, RoutedEventArgs e)
{
POINT p;
if (GetCursorPos(out p))
{
System.Console.WriteLine(Convert.ToString(p.X) + ";" + Convert.ToString(p.Y));
}
}
Converting Pixels to WPF Units:
[DllImport("User32.dll")]
static extern IntPtr GetDC(IntPtr hwnd);
[DllImport("gdi32.dll")]
static extern int GetDeviceCaps(IntPtr hdc, int nIndex);
[DllImport("user32.dll")]
static extern bool ReleaseDC(IntPtr hWnd, IntPtr hDC);
private Point ConvertPixelsToUnits(int x, int y)
{
// get the system DPI
IntPtr dDC = GetDC(IntPtr.Zero); // Get desktop DC
int dpi = GetDeviceCaps(dDC, 88);
bool rv = ReleaseDC(IntPtr.Zero, dDC);
// WPF's physical unit size is calculated by taking the
// "Device-Independant Unit Size" (always 1/96)
// and scaling it by the system DPI
double physicalUnitSize = (1d / 96d) * (double)dpi;
Point wpfUnits = new Point(physicalUnitSize * (double)x,
physicalUnitSize * (double)y);
return wpfUnits;
}
Putting both together:
private void WriteMouseCoordinatesInWPFUnits()
{
POINT p;
if (GetCursorPos(out p))
{
Point wpfPoint = ConvertPixelsToUnits(p.X, p.Y);
System.Console.WriteLine(Convert.ToString(wpfPoint.X) + ";" + Convert.ToString(wpfPoint.Y));
}
}
Two options:
Use System.Windows.Forms.Control.MousePosition, or p/invoke
[DllImport("user32.dll", CharSet=CharSet.Auto, ExactSpelling=true)]
public static extern bool GetCursorPos([In, Out] NativeMethods.POINT pt);
The first option already does the p/invoke for you. I'm not entirely sure it requires you have some UI splashed up, but I don't think so. Yes, its winforms and not wpf, but it really doesn't have anything to do with where its located at.
If you want to skip any dependencies on system.windows.forms.dll then check out more information about the second on pinvoke.net.
I stumbled over that thread while looking for a solution for the same problem. In the meantime, I found PointToScreen, which does not require any P/Invoke. The method is available on any Visual starting .NET 3.0 (and thus UIElement, Control, etc.) and an implementation would look like this:
protected void OnMouseLeave(object Sender, MouseEventArgs e) {
var relativePosition = e.GetPosition(this);
var screenPosition = this.PointToScreen(relativePosition);
}
Is it possible to reserve a screen area near an edge of the screen for your app in Windows 7? It would behave similar to the Windows taskbar (i.e. maximized windows would not overlap with it).
I'm writing a taskbar app with proper support for multiple monitors. The primary purpose is to show a taskbar on each screen containing only the apps on that screen. None of the existing solutions (Ulltramon, DisplayFusion) I know of work for Win 7, and none are open source.
C# code would be nice, but any hints are appreciated as well.
I feel silly answering my own question, but thanks to Michael's hint, I found an appropriate C# code sample.
using System;
using System.Runtime.InteropServices;
public class WorkArea
{
[System.Runtime.InteropServices.DllImport("user32.dll", EntryPoint="SystemParametersInfoA")]
private static extern Int32 SystemParametersInfo(Int32 uAction, Int32 uParam, IntPtr lpvParam, Int32 fuWinIni);
private const Int32 SPI_SETWORKAREA = 47;
public WorkArea(Int32 Left,Int32 Right,Int32 Top,Int32 Bottom)
{
_WorkArea.Left = Left;
_WorkArea.Top = Top;
_WorkArea.Bottom = Bottom;
_WorkArea.Right = Right;
}
public struct RECT
{
public Int32 Left;
public Int32 Right;
public Int32 Top;
public Int32 Bottom;
}
private RECT _WorkArea;
public void SetWorkingArea()
{
IntPtr ptr = IntPtr.Zero;
ptr = Marshal.AllocHGlobal(Marshal.SizeOf(_WorkArea));
Marshal.StructureToPtr(_WorkArea,ptr,false);
int i = SystemParametersInfo(SPI_SETWORKAREA,0,ptr,0);
}
}
I'm unsure of how to do this directly in C#, but in native code you can call SystemParametersInfo with SPI_SETWORKAREA. This is how apps like the taskbar, sidebar, and so on can prevent maximized windows from overlapping them.
http://msdn.microsoft.com/en-us/library/ms724947.aspx is the documentation for SystemParametersInfo.
http://social.msdn.microsoft.com/forums/en-US/winforms/thread/9fe831e5-ccfb-4e8d-a129-68c301c83acb/ shows P/Invoke signatures for this method.