When you open internet explorer or mozilla, a new task in the task bar pops out.
When you right click this taskbar item it saids
Restore, move, size, minimize, maximize, close.
Now i have an application that does not use size, minimize,maximize or close.
Can someone give me a quick lead or heads up in order to disable them?
Thanks in advance
-Kevin
You can use the SetWindowLong function (http://msdn.microsoft.com/en-us/library/ms633591(VS.85).aspx).
[DllImport("user32.dll", SetLastError = true)]
private static extern int GetWindowLong(IntPtr hWnd, int nIndex);
[DllImport("user32.dll")]
private static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
int GwlStyle = -16; // GWL_STYLE
int WsSysMenu = 0x80000; // WS_POPUP
var hwnd = new WindowInteropHelper(this).Handle;
SetWindowLong(hwnd, GwlStyle, GetWindowLong(hwnd, GwlStyle) & ~WsSysMenu);
Check the above link for more information about what the values of GwlStyle and WsSysMenu indicate. This will style the window to be a popup window. However, this also removes the close, maximize, and minimize buttons from the top-right.
Related
I want to Hide/Disable Minimize and Maximize button on WPF window.
I have tried using WinAPI
I added following class in my code base
internal static class WindowExtensions
{
// from winuser.h
private const int GWL_STYLE = -16,
WS_MAXIMIZEBOX = 0x10000,
WS_MINIMIZEBOX = 0x20000;
[DllImport("user32.dll")]
extern private static int GetWindowLong(IntPtr hwnd, int index);
[DllImport("user32.dll")]
extern private static int SetWindowLong(IntPtr hwnd, int index, int value);
internal static void HideMinimizeAndMaximizeButtons(this Window window)
{
IntPtr hwnd = new System.Windows.Interop.WindowInteropHelper(window).Handle;
var currentStyle = GetWindowLong(hwnd, GWL_STYLE);
SetWindowLong(hwnd, GWL_STYLE, (int)(currentStyle & -65537 & -131073));
}
}
then I tried to call the HideMinimizeAndMaximizeButtons method on SourceInitialised method of that window.
This is the only solution I found on Internet.
Can anyone Suggest any other workaround?
One possible workaround is to hide the entire title bar with
<Window
WindowStyle="None"
and create the "program closing button" with a custom button if you need it
I've disabled the system menu buttons in the past on many windows using GetWindowLong (or GetWindowLongPtr if 64-bit) and SetWindowLong (or SetWindowLongPtr) with great success. I have a Citrix session that launches internet explorer and I cannot get these items to be removed from the title bar. I know the method that I am using is working because I can do what I want to do when a normal, non-Citrix, internet explorer is open. I successfully get the window handle for the Citrix IE session as I can focus it, set it to topmost, etc. It just does not want to work with Get/SetWindowLong and is obviously something to do with Citrix. Ignore the attribute parameter - I will eventually be passing in what WS_ will be used to manipulate the window, but I just want to keep it simple until I get this working (if it is even possible).
[DllImport("user32.dll")]
internal extern static long SetWindowLong(int hwnd, int index, long value);
[DllImport("user32.dll")]
internal extern static long GetWindowLong(int hwnd, int index);
public static void SetWindowAttribute(int hwnd, int attribute)
{
IntPtr hwndPtr = new IntPtr(hwnd);
const int GWL_STYLE = -16;
const long WS_MINIMIZEBOX = 0x00020000L;
const long WS_MAXIMIZEBOX = 0x00010000L;
long value = GetWindowLong(hwnd, GWL_STYLE);
Trace.TraceInformation("GetWindowLong value {0}", value.ToString());
long ret = SetWindowLong(hwnd, GWL_STYLE, (value & ~WS_MINIMIZEBOX & ~WS_MAXIMIZEBOX));
Trace.TraceInformation("SetWindowLong reg {0}", ret.ToString());
}
If the code above is for 32-bit, then on the SetWindowLong declaration the value parameter type should be int, not long. There is a possibility this may cause some inconsistent behavior.
For reference, here are the 32-bit signatures as defined internally in System.Windows.Forms:
[DllImport("user32.dll", CharSet = CharSet.Auto, EntryPoint = "SetWindowLong")]
public static extern IntPtr SetWindowLongPtr32(HandleRef hWnd, int nIndex, HandleRef dwNewLong);
[DllImport("user32.dll", CharSet = CharSet.Auto, EntryPoint = "GetWindowLong")]
public static extern IntPtr GetWindowLong32(HandleRef hWnd, int nIndex);
Also, using Spy++, you can verify what styles are on the IE window before and after you modify the style.
what I want to do is to extend the MainMenu of the Windows Mobile Winforms to have a second menu level. If you tip short on the menu button it will do the event action but if you press it longer a second menu level should pop up. The MainMenu is very deficient in its managed functions so I had to find another way. I archived this by deriving MainMenu and add some SubClassing.
public delegate IntPtr Win32WndProc(IntPtr hWnd, int msg, int wParam, int lParam);
[DllImport("coredll.dll", EntryPoint = "FindWindow", SetLastError = true)]
public static extern IntPtr FindWindow(string lpClassName, IntPtr lpWindowName);
[DllImport("coredll.dll")]
public static extern bool EnableWindow(IntPtr hWnd, bool bEnable);
[DllImport("coredll")]
public static extern IntPtr SetWindowLong(IntPtr hWnd, int nIndex, Win32WndProc newProc);
int GWL_WNDPROC = (-4);
int GW_CHILD = 5;
IntPtr _oldToolbarProc;
IntPtr _oldMenuWorkerProc
void Hookup()
{
//find the window to hook
var hWndHooked = FindWindow("HHTaskbar", IntPtr.Zero);
if (hWndHooked == IntPtr.Zero)
return;
//enable the taskbar, not realy necessary
EnableWindow(hWndHooked, true);
//find the menu_worker window
var menuWorkerWnd = FindWindow("menu_worker", IntPtr.Zero);
if (menuWorkerWnd == IntPtr.Zero)
return;
var toolbarWnd = GetWindow(menuWorkerWnd, GW_CHILD);
if (toolbarWnd == IntPtr.Zero)
return;
Win32WndProc newMenuWorker = MenuWorkerProc;
_oldMenuWorkerProc = SetWindowLong(menuWorkerWnd, GWL_WNDPROC, newMenuWorker);
Win32WndProc newToolbar = ToolbarProc;
_oldToolbarProc = SetWindowLong(newToolbarWnd, GWL_WNDPROC, newToolbar);
}
The toolbar subclassing measures the time between WM_LBUTTONDOWN and WM_LBUTTONUP
and depending on the time leaped between these events a context Menu is invoked.
If the context menu is invoked the menu_worker subclassing must suppress the WM_COMMAND of the pressed button.
This works fine for a single window. But if I use it on a second form they will recongize both the same toolbar and menuworker and application crashes.
What I tried is to hook and unhook in the onFocus /onLostFocus events of the parent form.
But sadly onFocus is called before the right window is visible and it also gets the wrong window handle :(
What I did now (I know a very bad hack) is to start a time in the onFocus event and wait for 1000ms and hook it up then. This results in a 50:50 change to hook the right window..
Isn't there a better solution for subclassing the right window?
i am trying to grab the selected text from the open form on a users machine. Currently i have tried using GetFocus which is defined as
'[DllImport("user32.dll")]
static extern int GetFocus();'
In the api it says - Retrieves the handle to the window that has the keyboard focus, if the window is attached to the calling thread's message queue. Which explains why my app can grab the selected text from a window thats part of my app, but not one thats external, like a pdf for example.
What alternative win32 method is available for me to use that would fit this purpose?
Thanks.
edit: this is the attempt at the moment
[DllImport("user32.dll")]
static extern int GetFocus();
[DllImport("user32.dll")]
static extern bool AttachThreadInput(uint idAttach, uint idAttachTo, bool fAttach);
[DllImport("kernel32.dll")]
static extern uint GetCurrentThreadId();
[DllImport("user32.dll")]
static extern uint GetWindowThreadProcessId(int hWnd, int ProcessId);
[DllImport("user32.dll")]
static extern int GetForegroundWindow();
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
static extern int SendMessage(int hWnd, int Msg, int wParam, StringBuilder lParam);
// second overload of SendMessage
[DllImport("user32.dll")]
private static extern int SendMessage(IntPtr hWnd, uint Msg, out int wParam, out int lParam);
const int WM_SETTEXT = 12;
const int WM_GETTEXT = 13;
private static string PerformCopy()
{
try
{
//Wait 5 seconds to give us a chance to give focus to some edit window,
//notepad for example
System.Threading.Thread.Sleep(1000);
StringBuilder builder = new StringBuilder(500);
int foregroundWindowHandle = GetForegroundWindow();
uint remoteThreadId = GetWindowThreadProcessId(foregroundWindowHandle, 0);
uint currentThreadId = GetCurrentThreadId();
//AttachTrheadInput is needed so we can get the handle of a focused window in another app
AttachThreadInput(remoteThreadId, currentThreadId, true);
//Get the handle of a focused window
int focused = GetFocus();
//Now detach since we got the focused handle
AttachThreadInput(remoteThreadId, currentThreadId, false);
//Get the text from the active window into the stringbuilder
SendMessage(focused, WM_GETTEXT, builder.Capacity, builder);
return builder.ToString();
}
catch (System.Exception oException)
{
throw oException;
}
}
Check GetForegroundWindow.
I don't think you have much chance of succeeding with your current approach. I'm pretty sure there's no single general purpose API for getting hold of the current selection. I believe this because each application can implement text selection in its own way.
As an alternative solution you should consider using a clipboard listener. Listen for changes to the clipboard contents and whenever text is added you can suck it out of the clipboard and put it in your app's window.
I think this is a job for UI Automation (the API screen readers use). Here's a post that get's the selected text in C#.
I'm interested in working on a plugin for Keepass, the open-source password manager. Right now, Keepass currently detects what password to copy/paste for you based off of the window title. This prevents Keepass from detecting the current password you need for apps that don't actively update their window title based on the current site (Chrome for instance).
How can I walk through another processes window elements (buttons, labels, textbox) similar to how Spy++ works? When you run Spy++ you can hover over other programs windows and get all kinds of information about various properties concerning various controls (labels, textboxes, etc). Ideally, I'd like my Keepass plugin to enhance the current window detection by walking through the active window's elements in an effort to find a matching account to copy/paste the password.
How can I walk other processes window elements and be able to retrieve label and textbox values using C#?
I've being answering similar questions like this here: How can I detect if a thread has windows handles?. Like it states, the main idea is to enumerate through process windows and their child windows using EnumWindows and EnumChildWindows API calls to get window handles and then call GetWindowText or SendDlgItemMessage with WM_GETTEXT to get window text. I've modified code to make an example which should be doing what you need (sorry it's a bit long :). It iterates through processes and their windows and dumps window text into console.
static void Main(string[] args)
{
foreach (Process procesInfo in Process.GetProcesses())
{
Console.WriteLine("process {0} {1:x}", procesInfo.ProcessName, procesInfo.Id);
foreach (ProcessThread threadInfo in procesInfo.Threads)
{
// uncomment to dump thread handles
//Console.WriteLine("\tthread {0:x}", threadInfo.Id);
IntPtr[] windows = GetWindowHandlesForThread(threadInfo.Id);
if (windows != null && windows.Length > 0)
foreach (IntPtr hWnd in windows)
Console.WriteLine("\twindow {0:x} text:{1} caption:{2}",
hWnd.ToInt32(), GetText(hWnd), GetEditText(hWnd));
}
}
Console.ReadLine();
}
private static IntPtr[] GetWindowHandlesForThread(int threadHandle)
{
_results.Clear();
EnumWindows(WindowEnum, threadHandle);
return _results.ToArray();
}
// enum windows
private delegate int EnumWindowsProc(IntPtr hwnd, int lParam);
[DllImport("user32.Dll")]
private static extern int EnumWindows(EnumWindowsProc x, int y);
[DllImport("user32")]
private static extern bool EnumChildWindows(IntPtr window, EnumWindowsProc callback, int lParam);
[DllImport("user32.dll")]
public static extern int GetWindowThreadProcessId(IntPtr handle, out int processId);
private static List<IntPtr> _results = new List<IntPtr>();
private static int WindowEnum(IntPtr hWnd, int lParam)
{
int processID = 0;
int threadID = GetWindowThreadProcessId(hWnd, out processID);
if (threadID == lParam)
{
_results.Add(hWnd);
EnumChildWindows(hWnd, WindowEnum, threadID);
}
return 1;
}
// get window text
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern int GetWindowTextLength(IntPtr hWnd);
private static string GetText(IntPtr hWnd)
{
int length = GetWindowTextLength(hWnd);
StringBuilder sb = new StringBuilder(length + 1);
GetWindowText(hWnd, sb, sb.Capacity);
return sb.ToString();
}
// get richedit text
public const int GWL_ID = -12;
public const int WM_GETTEXT = 0x000D;
[DllImport("User32.dll")]
public static extern int GetWindowLong(IntPtr hWnd, int index);
[DllImport("User32.dll")]
public static extern IntPtr SendDlgItemMessage(IntPtr hWnd, int IDDlgItem, int uMsg, int nMaxCount, StringBuilder lpString);
[DllImport("User32.dll")]
public static extern IntPtr GetParent(IntPtr hWnd);
private static StringBuilder GetEditText(IntPtr hWnd)
{
Int32 dwID = GetWindowLong(hWnd, GWL_ID);
IntPtr hWndParent = GetParent(hWnd);
StringBuilder title = new StringBuilder(128);
SendDlgItemMessage(hWndParent, dwID, WM_GETTEXT, 128, title);
return title;
}
hope this helps, regards
Have a look at this article here which contains information about the Managed Spy and why the author wrote the tool.
You can use EnumWindows to find every top-level Chrome window and then call EnumChildWindows recursively (see Jeroen Wiert Pluimers' comment) to get every child of the main window. Alternatively, once you have the main Chrome window, you can use GetWindow to manually navigate the tree since you probably know what you're looking for (3rd child's children collection or something similar).
Once you find your window, you can use SendMessage with a WM_GETTEXT parameter to read the window's label.
You can use HWndSpy. Source code is here.
For the functionality of pointing to a window. You need to SetCapture() so that you get mouse messages that are outside of your window. Then use WindowFromPoint() to convert a mouse position to a Window. You will need to convert the moust position from client coordinates to window coordinates first.
If you try an call SetCapture() anywhere but on a mouse click message, you will probably be ignored. This is the reason that Spy++ makes you click on an Icon and drag and drop it on the window you want to point to.