I tried to use mouse_event() function, but it seems that it works asynchronously.
Below is my code (the problem is in Main method).
I set mouse position and simulate click, but my code returns the previous window (in the last line) even before click simulation happen.
How to overcome this asynchrony without suspending thread for 100 milliseconds?
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Threading;
namespace MouseSimulatingTesting
{
class Program
{
static void Main(string[] args)
{
Thread.Sleep(3000); //just for testing - to have time to have an ability to switch to another window
//remember current foreground window
IntPtr previousForegroundWindow = GetForegroundWindow();
IntPtr browserWindowHandle = GetBrowserWindow();
//set browser window to foreground to make a click in it
ForceActivateWindow(browserWindowHandle);
//make a click
SetCursorPos(150, 20);
mouse_event(LEFT_DOWN, 0, 0, 0, 0);
mouse_event(LEFT_UP, 0, 0, 0, 0);
//Thread.Sleep(100); //if I uncomment this line then everything works perfectly
//return previous foreground window to top
ForceActivateWindow(browserWindowHandle);
}
const int LEFT_DOWN = 0x00000002;
const int LEFT_UP = 0x00000004;
[DllImport("user32.dll")]
private static extern void mouse_event(int dwFlags, int dx, int dy, int dwData, int dwExtraInfo);
[DllImport("user32.dll", EntryPoint = "SetCursorPos")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetCursorPos(int X, int Y);
[DllImport("user32.dll")]
public static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll", SetLastError = true)]
public static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
[DllImport("kernel32.dll")]
public static extern uint GetCurrentThreadId();
[DllImport("user32.dll")]
public static extern bool AttachThreadInput(uint idAttach, uint idAttachTo, bool fAttach);
[DllImport("user32.dll", SetLastError = true)]
public static extern bool BringWindowToTop(IntPtr hWnd);
[DllImport("user32.dll")]
public static extern bool ShowWindow(IntPtr hWnd, uint nCmdShow);
[DllImport("user32.dll")]
public static extern int SetForegroundWindow(IntPtr hWnd);
static public void ForceActivateWindow(IntPtr windowHandle)
{
uint processID;
uint foregroundThreadID = GetWindowThreadProcessId(GetForegroundWindow(), out processID);
uint mainThreadId = GetCurrentThreadId();
const uint SW_SHOW = 5;
if (foregroundThreadID != mainThreadId)
{
AttachThreadInput(foregroundThreadID, mainThreadId, true);
BringWindowToTop(windowHandle);
ShowWindow(windowHandle, SW_SHOW);
SetForegroundWindow(windowHandle);
AttachThreadInput(foregroundThreadID, mainThreadId, false);
}
else
{
BringWindowToTop(windowHandle);
ShowWindow(windowHandle, SW_SHOW);
SetForegroundWindow(windowHandle);
}
}
static IntPtr GetBrowserWindow()
{
var browserProcesses = Process.GetProcessesByName("opera");
if (browserProcesses.Length == 0)
throw new Exception("Browser is not opened");
return browserProcesses[0].MainWindowHandle;
}
}
}
Related
I have list of open Applications. To get this list i have used following code
internal static class NativeMethods
{
public static readonly Int32 GWL_STYLE = -16;
public static readonly UInt64 WS_VISIBLE = 0x10000000L;
public static readonly UInt64 WS_BORDER = 0x00800000L;
public static readonly UInt64 DESIRED_WS = WS_BORDER | WS_VISIBLE;
public delegate Boolean EnumWindowsCallback(IntPtr hwnd, Int32 lParam);
public static List<WindowWrapper> GetAllWindows()
{
List<WindowWrapper> windows = new List<WindowWrapper>();
StringBuilder buffer = new StringBuilder(100);
EnumWindows(delegate(IntPtr hwnd, Int32 lParam)
{
if ((GetWindowLongA(hwnd, GWL_STYLE) & DESIRED_WS) == DESIRED_WS)
{
GetWindowText(hwnd, buffer, buffer.Capacity);
WindowWrapper wnd = new WindowWrapper();
wnd.handle = hwnd;
wnd.title = buffer.ToString();
windows.Add(wnd);
}
return true;
}, 0);
return windows;
}
[DllImport("user32.dll")]
static extern Int32 EnumWindows(EnumWindowsCallback lpEnumFunc, Int32 lParam);
[DllImport("user32.dll")]
public static extern void GetWindowText(IntPtr hWnd, StringBuilder lpString, Int32 nMaxCount);
[DllImport("user32.dll")]
static extern UInt64 GetWindowLongA(IntPtr hWnd, Int32 nIndex);
}
public class WindowWrapper : IWin32Window
{
internal IntPtr handle;
internal String title;
public IntPtr Handle
{
get { return handle; }
}
public String Title
{
get { return title; }
}
}
to call this i used following code
foreach (var wnd in NativeMethods.GetAllWindows())
{
string caption = wnd.title;
string handle = wnd.Handle
// Add this caption and handle to list
}
Now, User will select any of the opened window from the list and my task is to read caption of the selected window, get handle of process and maximize/minimize or close window. How can I do this.
You can use findwindowbycaption to get the handle then maximize or minimize with showwindow
private const int SW_MAXIMIZE = 3;
private const int SW_MINIMIZE = 6;
// more here: http://www.pinvoke.net/default.aspx/user32.showwindow
[DllImport("user32.dll", EntryPoint = "FindWindow")]
public static extern IntPtr FindWindowByCaption(IntPtr ZeroOnly, string lpWindowName);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
Then in your code you use this:
IntPtr hwnd = FindWindowByCaption(IntPtr.Zero, "The window title");
ShowWindow(hwnd, SW_MAXIMIZE);
Although it seems you already have the window handle by using EnumWindows in that case you would only need:
ShowWindow(windows[i].handle, SW_MAXIMIZE);
i is the index of the window.
to close the window you will use:
[DllImport("user32.dll", CharSet = CharSet.Unicode, SetLastError=true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool DestroyWindow(IntPtr hwnd);
in the code:
DestroyWindow(hwnd) //or DestroyWindow(windows[i].handle)
this is the unmanaged version of system.windows.forms.form.close()
or you can use:
Process [] proc Process.GetProcessesByName("process name");
proc[0].Kill();
or you can use:
static uint WM_CLOSE = 0x0010;
[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("user32.dll", SetLastError = true)]
static extern bool PostMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
in code:
PostMessage(hWnd, WM_CLOSE, IntPtr.Zero, IntPtr.Zero);
You may use native method ShowWindow with SW_MAXIMIZE, SW_MINIMIZE for ncmdShow
Take a look at http://msdn.microsoft.com/en-us/library/windows/desktop/ms633548(v=vs.85).aspx
private const int SW_MAXIMIZE = 3;
private const int SW_MINIMIZE = 6;
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool ShowWindow(IntPtr hWnd, ShowWindowCommands nCmdShow);
// in your code
ShowWindow(wnd.Handle, SW_MAXIMIZE);
you can use ShowWindowAsync
private const int SW_SHOWNORMAL = 1;
private const int SW_SHOWMINIMIZED = 2;
private const int SW_SHOWMAXIMIZED = 3;
[DllImport("user32.dll")]
private static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);
ShowWindowAsync(wnd.Handle, SW_SHOWMINIMIZED );
and it's better and to use
var openWindows = Process.GetProcesses().Where(process=> String.IsNullOrEmpty(process.MainWindowTitle)==false);
to get opened windows
I have test MainWindowTitle in Porcess and it helps to search on window given it's caption.
var handles = Process.GetProcesses().Where(x => x.MainWindowTitle == "Untitled - Notepad").Select(y=>y.Handle).ToList();
I want to create a program, which could make screenshot of scrolling window. As opposed to making screenshots, scrolling another app is difficult for me. Basing on a few scripts from web, I’ve written that:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.Threading;
namespace scroller
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern int GetScrollPos(IntPtr hWnd, int nBar);
[DllImport("user32.dll")]
static extern int SetScrollPos(IntPtr hWnd, int nBar, int nPos, bool bRedraw);
[DllImport("user32.dll")]
static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
[DllImport("user32.dll")]
static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
[DllImport("user32.dll", SetLastError = true)]
private static extern bool MoveWindow(IntPtr hwnd, int x, int y, int cx, int cy, bool repaint);
[DllImport("user32.dll")]
static extern IntPtr SetActiveWindow(IntPtr hWnd);
[DllImport("user32.dll", SetLastError = true)]
static extern void SwitchToThisWindow(IntPtr hWnd, bool fAltTab);
[DllImport("user32.dll", SetLastError = true)]
private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
[DllImport("User32.Dll", EntryPoint = "PostMessageA")]
static extern bool PostMessage(IntPtr hWnd, uint msg, int wParam, int lParam);
[DllImport("user32.dll")]
private static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll")]
static extern int GetWindowText(IntPtr hWnd, StringBuilder text, int count);
internal delegate int WindowEnumProc(IntPtr hwnd, IntPtr lparam);
[DllImport("user32.dll")]
internal static extern bool EnumChildWindows(IntPtr hwnd, WindowEnumProc func, IntPtr lParam);
private void Form1_Load(object sender, EventArgs e)
{
List<IntPtr> result = new List<IntPtr>();
Thread.Sleep(5000);
IntPtr ParenthWnd = GetForegroundWindow();
if (!ParenthWnd.Equals(IntPtr.Zero))
{
StringBuilder myStringBuilder = new StringBuilder(256);
GetWindowText(ParenthWnd, myStringBuilder, 256);
this.Text = myStringBuilder.ToString();
IntPtr prevChild = IntPtr.Zero;
IntPtr currChild = IntPtr.Zero;
while (true)
{
currChild = FindWindowEx(ParenthWnd, prevChild, null, null);
if (currChild == IntPtr.Zero) break;
result.Add(currChild);
prevChild = currChild;
}
}
for(int i=0 ;i<=result.Count-1;i++){
IntPtr myHandle = result[i];
SetActiveWindow(ParenthWnd);
SwitchToThisWindow(myHandle, true);
SetScrollPos(myHandle, 0x1, 0, true);
PostMessage(myHandle, 0x115, 4 + 0x10000 * 0,0);
}
}
}
}
This waits 5 seconds, and moves scrollbars of all windows to top. It works e.g. with notepad, but not with web browsers, ms word and many others. What am I doing wrong?
I am using the below code to remove the Title Bar of an application, which is working perfectly for notepad. Now i want to remove the Menu Bar also. How to achieve it ?
//Finds a window by class name
[DllImport("USER32.DLL")]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
//Sets a window to be a child window of another window
[DllImport("USER32.DLL")]
public static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
//Sets window attributes
[DllImport("USER32.DLL")]
public static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
//Gets window attributes
[DllImport("USER32.DLL")]
public static extern int GetWindowLong(IntPtr hWnd, int nIndex);
[DllImport("user32.dll", EntryPoint = "FindWindow", SetLastError = true)]
static extern IntPtr FindWindowByCaption(IntPtr ZeroOnly, string lpWindowName);
//assorted constants needed
public static int GWL_STYLE = -16;
public static int WS_BORDER = 0x00800000; //window with border
public static int WS_DLGFRAME = 0x00400000; //window with double border but no title
public static int WS_CAPTION = WS_BORDER | WS_DLGFRAME; //window with a title bar
public void WindowsReStyle()
{
Process[] Procs = Process.GetProcesses();
foreach (Process proc in Procs)
{
if (proc.ProcessName.StartsWith("notepad"))
{
IntPtr pFoundWindow = proc.MainWindowHandle;
int style = GetWindowLong(pFoundWindow, GWL_STYLE);
SetWindowLong(pFoundWindow, GWL_STYLE, (style & ~WS_CAPTION));
}
}
}
You can't hide them, you will need to remove them using the API instead, YMMV on the result of doing this;
[DllImport("USER32.DLL")]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll", EntryPoint = "FindWindow", SetLastError = true)]
static extern IntPtr FindWindowByCaption(IntPtr ZeroOnly, string lpWindowName);
[DllImport("user32.dll")]
static extern IntPtr GetMenu(IntPtr hWnd);
[DllImport("user32.dll")]
static extern int GetMenuItemCount(IntPtr hMenu);
[DllImport("user32.dll")]
static extern bool DrawMenuBar(IntPtr hWnd);
[DllImport("user32.dll")]
static extern bool RemoveMenu(IntPtr hMenu, uint uPosition, uint uFlags);
public static uint MF_BYPOSITION = 0x400;
public static uint MF_REMOVE = 0x1000;
public static void WindowsReStyle() {
Process[] Procs = Process.GetProcesses();
foreach (Process proc in Procs) {
if (proc.ProcessName.StartsWith("notepad")) {
//get menu
IntPtr HMENU = GetMenu(proc.MainWindowHandle);
//get item count
int count = GetMenuItemCount(HMENU);
//loop & remove
for (int i = 0; i < count; i++)
RemoveMenu(HMENU, 0, (MF_BYPOSITION | MF_REMOVE));
//force a redraw
DrawMenuBar(proc.MainWindowHandle);
}
}
}
How to hide Start button while openning camera using CameraCaptureDialog in windows mobile
Do you just want to hide the Start button, or the whole taskbar?
You can hide and show the complete taskbar by using this code:
[DllImport("coredll", EntryPoint = "FindWindow")]
public static extern IntPtr FindWindow(
[In] string lpClassName,
[In] string lpWindowName);
[DllImport("coredll", EntryPoint = "ShowWindow")]
public static extern bool ShowWindow(
[In] IntPtr hWnd,
[In] int nCmdShow);
[DllImport("coredll", EntryPoint = "EnableWindow")]
public static extern bool EnableWindow(
[In] IntPtr hWnd,
[In] bool bEnable);
public const int SW_HIDE = 0x0000;
public const int SW_SHOW = 0x0001;
public static void HideTaskBar()
{
IntPtr hWnd = FindWindow("HHTaskBar", null);
EnableWindow(hWnd, false);
ShowWindow(hWnd, Win32.SW_HIDE);
}
public static void ShowTaskBar()
{
IntPtr hWnd = FindWindow("HHTaskBar", null);
EnableWindow(hWnd, true);
ShowWindow(hWnd, Win32.SW_SHOW);
}
I want to bring another application into the foreground, however, I only have a partial name of the window. Back in the day, I'd hook into the EnumWindows API and look for what I needed.
Is there a way to do this better in C#? An example would be great.
This should do the job:
[DllImport("user32.dll", EntryPoint="SystemParametersInfo")]
public static extern bool SystemParametersInfo(uint uiAction, uint uiParam, uint pvParam, uint fWinIni);
[DllImport("user32.dll", EntryPoint="SetForegroundWindow")]
public static extern bool SetForegroundWindow(IntPtr hWnd);
[DllImport("User32.dll", EntryPoint="ShowWindowAsync")]
private static extern bool ShowWindowAsync(IntPtr hWnd, int cmdShow);
private const int WS_SHOWNORMAL = 1;
private const int SW_SHOWMAXIMIZED = 3;
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool GetWindowPlacement(IntPtr hWnd, ref WINDOWPLACEMENT lpwndpl);
private struct WINDOWPLACEMENT
{
public int length;
public int flags;
public int showCmd;
public System.Drawing.Point ptMinPosition;
public System.Drawing.Point ptMaxPosition;
public System.Drawing.Rectangle rcNormalPosition;
}
Process[] processes = Process.GetProcesses();
foreach(Process p in processes){
if(p.MainWindowTitle.Contains("nice_title")){
WINDOWPLACEMENT wp = new WINDOWPLACEMENT();
placement.length = Marshal.SizeOf(placement);
GetWindowPlacement(p.MainWindowHandle, ref placement);
int proposedPlacement = wp.showCmd;
if (wp.showCmd == SW_SHOWMINIMIZED)
proposedPlacement = SW_SHOWMAXIMIZED;
SystemParametersInfo( (uint) 0x2001, 0, 0, 0x0002 | 0x0001);
ShowWindowAsync(p.MainWindowHandle, proposedPlacement);
SetForegroundWindow(p.MainWindowHandle);
SystemParametersInfo( (uint) 0x2001, 200000, 200000, 0x0002 | 0x0001);
}
}