I want to minimize a window using C#
Ex : I have opened this path E:\ using
process.start(E:\)
And I want to minimize this path on a certain event.
How can I make that possible?
The following sample Console Application code will minimize all shell explorer views that are opened on E:\ :
class Program
{
static void Main(string[] args)
{
// add a reference to "Microsoft Shell Controls and Automation" COM component
// also add a 'using Shell32;'
Shell shell = new Shell();
dynamic windows = shell.Windows(); // this is a ShellWindows object
foreach (dynamic window in windows)
{
// window is an WebBrowser object
Uri uri = new Uri((string)window.LocationURL);
if (uri.LocalPath == #"E:\")
{
IntPtr hwnd = (IntPtr)window.HWND; // WebBrowser is also an IWebBrowser2 object
MinimizeWindow(hwnd);
}
}
}
static void MinimizeWindow(IntPtr handle)
{
const int SW_MINIMIZE = 6;
ShowWindow(handle, SW_MINIMIZE);
}
[DllImport("user32.dll")]
private static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
}
It's using the Shell Objects for Scripting. Note the usage of the dynamic keyword that's mandatory here because there is no cool typelib, and therefore no intellisense either.
Shell32.Shell objShell = new Shell32.Shell();
objShell.MinimizeAll();
this will help you to minimize all the window Not only Folders all(something like windows + M!!!
Your question is not very clear. If you are using a TreeView control see
MSDN Treeview class. You can then: Expand or Collapse items at will.
You can use the configuration file or a Variable
This is a possible solution and only minimizes the window u opened:
private int explorerWindowNumber;
public const int WM_SYSCOMMAND = 0x0112;
public const int SC_MINIMIZE = 0xF020;
[DllImport("user32.dll", SetLastError = true)]
public static extern int GetForegroundWindow();
[DllImport("user32.dll")]
public static extern int SendMessage(int hWnd, uint Msg, int wParam, int lParam);
public void button1_Click(object sender, EventArgs e)
{
//Start my window
StartMyExplorer();
}
private void StartMyExplorer()
{
Process.Start("D:\\");
Thread.Sleep(1000);
//Get the window id (int)
explorerWindowNumber = GetForegroundWindow();
}
private void button2_Click(object sender, EventArgs e)
{
//Minimize the window i created
SendMessage(explorerWindowNumber, WM_SYSCOMMAND, SC_MINIMIZE, 0);
}
Related
I am trying to set a new parent window (host window) for the another window (client window) that belongs to other process. Also, the is a requirement to duplicate main menu of the client window so that the host window should have the same working main menu as the calient window has.
I managed to set the client window menu to the host window, but the host menu does not work. It is possible to navigate through menu, but is does not work (f.e. it not possible to open/create new file).
The question is if it possible to do this at all and if it is, what did I miss?
There is a code snippet:
public partial class Form1 : Form
{
[DllImport("user32.dll", SetLastError = true)]
private static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
[DllImport("user32.dll")]
private static extern IntPtr GetMenu(IntPtr hWnd);
[DllImport("user32.dll")]
private static extern bool SetMenu(IntPtr hWnd, IntPtr hMenu);
private Process notepadProcess;
public Form1()
{
InitializeComponent();
}
private void Form1_Shown(object sender, EventArgs e)
{
ProcessStart();
Thread.Sleep(100);
EmbedNotepadWindow();
}
private void ProcessStart()
{
notepadProcess = new Process();
notepadProcess.StartInfo.FileName = "notepad.exe";
notepadProcess.Start();
}
private void EmbedNotepadWindow()
{
SetParent(notepadProcess.MainWindowHandle, panel1.Handle);
var menuHandle = GetMenu(notepadProcess.MainWindowHandle);
SetMenu(this.Handle, menuHandle);
}
}
Copy main menu from Client to Host window
I would like to know the word under the mouse cursor in Powerpoint so that it can be used for a screen reader. Accessibility solutions are acceptable if it can distinguish between different words (vs a block).
This is actually really hard, if you do not know what you are doing. There is a easy way and a hard way to do this. Easy way would be to use Microsoft UI automation framework (that includes Powerpoint automation). Alternative frameworks can also be used.
Hard way wold be to directly use win api.
For example: To get window title currently under the mouse.
public static class dllRef
{
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool GetCursorPos(out Point lpPoint);
[DllImport("user32.dll")]
private static extern IntPtr WindowFromPoint(Point point);
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern int RegisterWindowMessage(string lpString);
[DllImport("user32.dll", EntryPoint = "SendMessage", CharSet = CharSet.Auto)]
public static extern bool SendMessage(IntPtr hWnd, uint Msg, int wParam, StringBuilder lParam);
[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr SendMessage(int hWnd, int Msg, int wparam, int lparam);
public const int WM_USER = 0x400;
public const int WM_COPYDATA = 0x4A;
public const int WM_GETTEXT = 0x000D;
public const int WM_GETTEXTLENGTH = 0x000E;
public static void RegisterControlforMessages()
{
RegisterWindowMessage("WM_GETTEXT");
}
public static string GetText()
{
StringBuilder title = new StringBuilder();
Point p = dllRef.getMousePosition();
var lhwnd = dllRef.WindowFromPoint(p);
var lTextlen = dllRef.SendMessage((int)lhwnd, dllRef.WM_GETTEXTLENGTH, 0, 0).ToInt32();
if (lTextlen > 0)
{
title = new StringBuilder(lTextlen + 1);
SendMessage(lhwnd, WM_GETTEXT, title.Capacity, title);
}
return title.ToString();
}
public static Point getMousePosition()
{
Point p = new Point();
GetCursorPos(out p);
return p;
}
}
and
private void Form1_Load(object sender, EventArgs e)
{
Timer t = new Timer();
t.Interval = 25;
t.Tick += new EventHandler(Timer_Tick);
t.Start();
}
public void Timer_Tick(object sender, EventArgs eArgs)
{
this.label1.Text = dllRef.GetText();
}
In addition you can use Microsoft Spy++
to find if information you are looking for is exposed. Other then that I can really recommend you use automation framework that is layer built on top of this. Google has more then enough examples on this (as well as how to build sophisticated keyloggers).
The same solutions as Margus came to mind. Either UI Automation or PowerPoint interop. Luckily UI Automation works.
The below works in my test putting the mouse over a PowerPoint 2013 text box. Let me know if you think something is missing.
using System.Windows.Automation;
using UIAutomationClient;
String TextUnderCursor()
{
System.Windows.Point point = new System.Windows.Point(Cursor.Position.X, Cursor.Position.Y);
AutomationElement element = AutomationElement.FromPoint(point);
object patternObj;
if (element.TryGetCurrentPattern(TextPattern.Pattern, out patternObj))
{
var textPattern = (TextPattern)patternObj;
return textPattern.DocumentRange.GetText(-1).TrimEnd('\r'); // often there is an extra '\r' hanging off the end.)
} else
{
return "no text found";
}
}
Update Sample http://download.veodin.com/misc/PowerPoint_Screen_Reader.zip
Focus Visual Studio, put the mouse over the PowerPoint then use F5 to run the code
I was wondering if it is possible to remove the ability to close OTHER windows using C#?
I know that you can override your windows' close() method, but is that also possible for other processes? And what about changing the window style of another process to fixed___ so it cannot be resized?
So far I have gotten the main window handle of the application and I have removed all buttons and menus, but I still need to figure out how to make it uncloseable and unresizeable.
Here's what I've got:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace ThirdTest
{
class Program
{
#region Constants
//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);
[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);
//assorted constants needed
public static uint MF_BYPOSITION = 0x400;
public static uint MF_REMOVE = 0x1000;
public static int GWL_STYLE = -16;
public static int WS_CHILD = 0x40000000; //child window
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 static int WS_SYSMENU = 0x00080000; //window menu
#endregion
public static void WindowsReStyle()
{
Process[] Procs = Process.GetProcesses();
foreach (Process proc in Procs)
{
Console.WriteLine("Found process: " + proc.ProcessName.ToString());
if (proc.ProcessName.StartsWith("notepad"))
{
IntPtr pFoundWindow = proc.MainWindowHandle;
int style = GetWindowLong(pFoundWindow, GWL_STYLE);
//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);
SetWindowLong(pFoundWindow, GWL_STYLE, (style & ~WS_SYSMENU));
SetWindowLong(pFoundWindow, GWL_STYLE, (style & ~WS_CAPTION));
}
}
}
static void Main(string[] args)
{
WindowsReStyle();
}
}
}
Any ideas? (:
As I've put in the comments, here are some more details on the issue:
I need two applications to be side-by-side on the monitor.
None of them can be closeable or resizeable. One is a browser, the other is an application called "Z-tree".
I have already fixed the issue with Z-tree as it, by default, runs with no closebutton and no resizing and you can specify the size and position of it in the command line.
Here's another idea, create a winforms project and set the window so it cannot be resized. Then embed a single WebBrowser control in the form and navigate to your page in the form load:
private void Form1_Load(object sender, EventArgs e)
{
//catch form closing event to prevent form being closed using alt-f4
FormClosing += Form1_FormClosing;
//remove close button from toolbar and remove window border to prevent
//moving and resizing
this.ControlBox = false;
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
//set position to half of the screen
this.Left = Screen.PrimaryScreen.Bounds.Width / 2;
this.Top = 0;
this.Width = Screen.PrimaryScreen.Bounds.Width / 2;
this.Height = Screen.PrimaryScreen.Bounds.Height;
//mark the window as a top level window, reducing users ability to alt-tab away
TopMost = true;
webBrowser1.Navigate("www.google.com");
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
//prevent form being closed
e.Cancel = true;
}
//the only way to close the form
void DoExit()
{
//remove the closing handler first or it won't close
FormClosing -= Form1_FormClosing;
Close();
}
you can force internet explorer into an "unexitable" fullscreen mode if you start it with:
iexplore -k www.google.com
This is how shops and stuff get it to run so no-one can close it. Of course you can close it through task manager, but it just makes it difficult for most users to close it.
(CTRL-W will close it <--- secret key!)
http://support.microsoft.com/kb/154780
I need to be able to list all active applications on a windows machine.
I had been using this code...
Process[] procs = Process.GetProcesses(".");
foreach (Process proc in procs)
{
if (proc.MainWindowTitle.Length > 0)
{
toolStripComboBox_StartSharingProcessWindow.Items.Add(proc.MainWindowTitle);
}
}
until I realized that this doesn't list cases like WORD or ACROREAD when multiple files are opened each in their own window. In that situation, only the topmost window is listed using the above technique. I assume that's because there's only one process even though two (or more) files are opened. So, I guess my question is: How do I list all windows rather than their underlying process?
pinvoke using EnumWindows in user32.dll. something like this would do what you want.
public delegate bool WindowEnumCallback(int hwnd, int lparam);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool EnumWindows(WindowEnumCallback lpEnumFunc, int lParam);
[DllImport("user32.dll")]
public static extern void GetWindowText(int h, StringBuilder s, int nMaxCount);
[DllImport("user32.dll")]
public static extern bool IsWindowVisible(int h);
private List<string> Windows = new List<string>();
private bool AddWnd(int hwnd, int lparam)
{
if (IsWindowVisible(hwnd))
{
StringBuilder sb = new StringBuilder(255);
GetWindowText(hwnd, sb, sb.Capacity);
Windows.Add(sb.ToString());
}
return true
}
private void Form1_Load(object sender, EventArgs e)
{
EnumWindows(new WindowEnumCallback(this.AddWnd), 0);
}
I have made a similar method, but it also filter on window style ToolWindow and hidden windows store applications that circument the hidden flag by being cloaked.
public static class WindowFilter
{
public static bool NormalWindow(IWindow window)
{
if (IsHiddenWindowStoreApp(window, window.ClassName)) return false;
return !window.Styles.IsToolWindow && window.IsVisible;
}
private static bool IsHiddenWindowStoreApp(IWindow window, string className)
=> (className == "ApplicationFrameWindow" || className == "Windows.UI.Core.CoreWindow") && window.IsCloaked;
}
The above example is part of a project of github, were you can see the rest of the code.
https://github.com/mortenbrudvik/WindowExplorer
Looking for hints, tips and search terms for changing the text on a win32 window from C#.
More specifically, I'm trying to change the text on the print dialog from "Print" to "OK", as I am using the dialog to create a print ticket and not do any printing.
How can I find the dialog's window handle? Once I've got it, how would I go about finding the button in the child windows of the form? Once I've found that, how would I change the text on the button? And how can I do all this before the dialog is shown?
There's a similar question here, but it points to a CodeProject article that is waaay more complex than needed and is taking me a bit longer to parse through than I'd like to spend on this. TIA.
You should use Spy++ to take a look at the dialog. The class name is important and the control ID of the button. If it is a native Windows dialog then the class name should be "#32770". In which case you'll have a lot of use for my post in this thread. Here is another in C#. You change the button text by P/Invoking SetWindowText() on the button handle.
using System;
using System.Text;
using System.Drawing;
using System.Windows.Forms;
using System.Runtime.InteropServices;
class SetDialogButton : IDisposable {
private Timer mTimer = new Timer();
private int mCtlId;
private string mText;
public SetDialogButton(int ctlId, string txt) {
mCtlId = ctlId;
mText = txt;
mTimer.Interval = 50;
mTimer.Enabled = true;
mTimer.Tick += (o, e) => findDialog();
}
private void findDialog() {
// Enumerate windows to find the message box
EnumThreadWndProc callback = new EnumThreadWndProc(checkWindow);
if (!EnumThreadWindows(GetCurrentThreadId(), callback, IntPtr.Zero)) mTimer.Enabled = false;
}
private bool checkWindow(IntPtr hWnd, IntPtr lp) {
// Checks if <hWnd> is a dialog
StringBuilder sb = new StringBuilder(260);
GetClassName(hWnd, sb, sb.Capacity);
if (sb.ToString() != "#32770") return true;
// Got it, get the STATIC control that displays the text
IntPtr hCtl = GetDlgItem(hWnd, mCtlId);
SetWindowText(hCtl, mText);
// Done
return true;
}
public void Dispose() {
mTimer.Enabled = false;
}
// P/Invoke declarations
private const int WM_SETFONT = 0x30;
private const int WM_GETFONT = 0x31;
private delegate bool EnumThreadWndProc(IntPtr hWnd, IntPtr lp);
[DllImport("user32.dll")]
private static extern bool EnumThreadWindows(int tid, EnumThreadWndProc callback, IntPtr lp);
[DllImport("kernel32.dll")]
private static extern int GetCurrentThreadId();
[DllImport("user32.dll")]
private static extern int GetClassName(IntPtr hWnd, StringBuilder buffer, int buflen);
[DllImport("user32.dll")]
private static extern IntPtr GetDlgItem(IntPtr hWnd, int item);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
private static extern bool SetWindowText(IntPtr hWnd, string txt);
}
Usage:
using (new SetDialogButton(1, "Okay")) {
printDialog1.ShowDialog();
}