Normally, my C# app shows the full window contents dynamically resizing while the form itself is resizing.
I clearly remember some apps doing this very nice effect where rather than doing this, it would just show a ghostly border during resize and THEN redraw the window.
How do I get this lovely effect in my forms? I can't find any thing on Google that appears to pertain to this.
PInvoke SystemParametersInfo to change it, but it changes for all windows.
Here is a references for all commands: MSDN SystemParametersInfo
[System.Runtime.InteropServices.DllImport("user32.dll")]
private static extern int SystemParametersInfo(int uAction, int uParam, int lpvParam, int fuWinIni);
[STAThread]
static void Main() {
int SPI_SETDRAGFULLWINDOWS = 0x0025;
SystemParametersInfo(SPI_SETDRAGFULLWINDOWS,0,0,2);
Application.Run(new Form());
}
Related
I have an application WPF. My main Windows as :
<Setter Property="WindowStyle" Value="None"/>
When I set :
Window.GetWindow(this).WindowState = System.Windows.WindowState.Maximized
The window goes in full screen. It's ok on my secondary screen, but it hide taskbar on my primary screen. I have try o use SystemParameters.MaximizedPrimaryScreenHeight but it makes trouble on the secondary. And in WPF I don't know how to detect the actual screen.
Someone has a solution ?
I am pretty sure that there is no native WPF function to get the monitor resolution, but if you are using multiple screens these functions might catch your interest.
With the help of Dominik K I finally find this post How do I know what monitor a WPF window is in and use the solution with :
internal static class NativeMethods
{
public const Int32 MONITOR_DEFAULTTOPRIMERTY = 0x00000001;
public const Int32 MONITOR_DEFAULTTONEAREST = 0x00000002;
[System.Runtime.InteropServices.DllImport("user32.dll")]
public static extern IntPtr MonitorFromWindow(IntPtr handle, Int32 flags);
}
It's work without using Forms functions
I require the ability to get the height of the on screen keyboard for Windows 8.1, "TabTip.exe." So far I've managed to open and close it at will, but now I also need to get it's height so I can compensate for it in my app. I have TextBox controls near the very bottom of the Window that get covered up by the keyboard.
All attempts to utilize the Win API call "GetWindowRect" have failed.
Code placed just inside the beginning of the class definition:
private const string OnScreenKeyboardName = "TabTip";
DllImport("user32.dll")]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool GetWindowRect(HandleRef hWnd, ref RECT lpRect);
[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
}
code placed inside one of the event handlers in the Window:
RECT rct = new RECT();
if (Process.GetProcessesByName(OnScreenKeyboardName).Length > 0)
{
Process[] Processes = Process.GetProcessesByName(OnScreenKeyboardName);
foreach (Process pOnScreenKeyboard in Processes)
{
if (!GetWindowRect(new HandleRef(this, pOnScreenKeyboard.Handle), ref rct))
{
MessageBox.Show("ERROR");
return;
}
MessageBox.Show(rct.ToString());
}
}
Consistent with most examples, I had originally been using a call to "FindWindow" to get the handle for the TabTip.exe Window. That seemed to work great for a while, but it stopped working all of a sudden within the last few days, and so I switched to "Process.FindByName..."
My test case involves placing the code (second part) above into the Window's "MouseMove" event handler. Then I make sure the on screen keyboard is showing, and then I move the mouse. This causes the event to fire and then it always shows the "ERROR" MessageBox, which indicates that "GetWindowRect" returns false (or has some kind of error?
I've spent a lot of time on Google searches, p/invoke, etc. This is frustrating because there seem to be very few examples of how to properly do this. And it seems there is some new thing called a HandleRef (am I using that properly? - there are basically no examples for that either!!!)
I really need to get this working. Can someone please tell me where I'm going wrong? Thanks!
You are passing the process handle (pOnScreenKeyboard.Handle) to GetWindowRect where GetWindowRect expects a window handle (HWND). Finding the process isn't sufficient - a process can create many windows, so you need to find the onscreen keyboard's window handle. You can try using pOnScreenKeyboard.MainWindowHandle, but from this post, you might find that it's null. You said you had a previous solution using FindWindow. I would go back to that and figure out why it stopped working.
Is it possible to do the following with WinForms/C#?
Dynamically detect window size and position of a running program (for example Notepad.exe)?
Snap WinForm to specific position within Notepad.exe?
Minimize and maximize WinForm window with other process (so when Notepad is minimize, so is WinForm window)?
See for example (black shape would be WinForm window):
Essentially I need to create a toolbar for a program, and the toolbar should "snap" to that program in the same place regardless of position or size of window.
First find the handle of the notepad window:
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
Just pass null for the first parameter and the caption ("Notepad"?) of the window as the second parameter.
An alternative would be to enumerate all windows and select the best match based on the caption:
using System.Runtime.InteropServices;
public delegate bool CallBackPtr(int hwnd, int lParam);
private CallBackPtr callBackPtr;
public class EnumReport
{
[DllImport("user32.dll")]
private static extern int EnumWindows(CallBackPtr callPtr, int lPar);
public static bool Report(int hwnd, int lParam)
{
Console.WriteLine("Window handle is "+hwnd);
return true;
}
}
static void Main()
{
// note in other situations, it is important to keep
// callBackPtr as a member variable so it doesnt GC while you're calling EnumWindows
callBackPtr = new CallBackPtr(EnumReport.Report);
EnumReport.EnumWindows(callBackPtr, 0);
}
Then attach a WndProc to it:
HwndSource src = HwndSource.FromHwnd(windowHandle);
src.AddHook(new HwndSourceHook(WndProc));
In the WndProc respond to the resizing and moving of the window.
I am not sure about setting the toolbar as a child of the notepad window; that might have unexpected effects when Notepad tries to manage it and order its z-depth.
At the same time I doubt this to be a good thing; the user will be able to type 'below' the overlay and lose his cursor/text.
Find Notepad's window (FindWindow).
Create your window without borders.
Set your window as a child of Notepad's window (SetParent).
Your window will be anchored to the top left corner of Notepad's window. Minimizing will be handled automatically, but you'll need to resize your window when Notepad's window is resized (or maximized). You may also want to move Notepad's edit control.
WinForms can be used, but you'll need some interop calls.
I have to warn that this is not a very good idea. Your controls may conflict with controls inside host process's window, host process may rearrange controls the way you don't like, draw over your controls. In general, be ready to fight with numerous issues without a good clean solution, and to accept that there may be glitches when resizing etc.
See also:
Attach form window to another window in C#.
I am currently developing an iTunes plug-in and I need to have my WPF plug-in to stick beside the iTunes window when dragged, resized, etc. The goal is to have iTunes sticked to my wpf app side by side.
I am looking for a way to track the movement (resizing, moving) of another window (in my case iTunes). The iTunes COM for Windows SDK offers events on maximize and minimize, unfortunately there are no events for resizing and moving the window.
I have tried the win32 setParent function without no succes. I don't think it's the appropriate solution for my problem. I have searched thoroughly through out the web but didn't find nothing.
I think the WINDOWPOS structure is what you're looking for. Other window structures may come in handy.
Some google searching turned up another example, that doesn't use WINDOWPOS:
1, Invoke API FindWindow() to retrieve the window handle (Uuse SPY++
to get the two parameters ClassName & WindowName);
2, Invoke API
GetWindowRect() to retrieve the size & postion of the specified
window.
Code Snippet
[DllImport("user32.dll")]
private static extern IntPtr FindWindow(string className, string windowName);
[DllImport("user32.dll")]
private static extern int GetWindowRect(IntPtr hwnd, out Rectangle rect);
private void button2_Click(object sender, EventArgs e)
{
string className = "yourClassName";
string windowName = "yourWindowName";
Rectangle rect;
IntPtr hwnd = FindWindow(className, windowName);
GetWindowRect(hwnd, out rect);
}
I am trying to write a simple application to activate my screensaver when the mouse in at the top right corner of the screen. I have found an answer to controlling the screensaver from C# however I am having trouble working out how to do a "hot corner" type check for the mouse position. This is the only part I am stuck with, any help would be appreciated.
This Activates the screensaver
[DllImport("user32.dll", EntryPoint = "GetDesktopWindow")]
private static extern IntPtr GetDesktopWindow();
[DllImport("user32.dll")]
private static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, int wParam, int lParam);
private const int SC_SCREENSAVE = 0xF140;
private const int WM_SYSCOMMAND = 0x0112;
public static void SetScreenSaverRunning()
{
SendMessage(GetDesktopWindow(), WM_SYSCOMMAND, SC_SCREENSAVE, 0);
}
You could use the System.Windows.Form.Screen class to get the current resolution (take a look at this answer). Then use Cursor.Position.Property to determine where the cursor is currently located (i.e. is it within the boundaries of some predefined rectangle that should activate it).
I have made the exact same thing, only it loads in the top left. What I did was just make the form size 1px by 1px with no border, and just activate the screensaver when the mouse stays over the form for a second. Doing it this way requires that you find all ways to keep the form on top of everything.
Another option would be mouse hooking and just watching for (0,0) mouse position, or for the top right - (0, screen.width)
You could also try ScrHots from Lucian Wischik. It's freeware and does exactly what you need, and also has hot-corners for "never activate the screensaver" capability. All four corners can be programmed to do either function. I've used this one for years, and it works great.
http://www.wischik.com/scr/savers.html (ScrHots3, under the "Utilities" section)
Hope this helps someone.