Show a Form without stealing focus?
Hmmm, isn't simply overriding Form.ShowWithoutActivation enough?
protected override bool ShowWithoutActivation
{
get { return true; }
}
And if you don't want the user to click this notification window either, you can override CreateParams:
protected override CreateParams CreateParams
{
get
{
CreateParams baseParams = base.CreateParams;
const int WS_EX_NOACTIVATE = 0x08000000;
const int WS_EX_TOOLWINDOW = 0x00000080;
baseParams.ExStyle |= ( int )( WS_EX_NOACTIVATE | WS_EX_TOOLWINDOW );
return baseParams;
}
}
How to keep a Form always on top without stealing focus from the active Window?
- Make a standard Form, set its
FormBorderStyle = none
. Make it TopMost (this setting is another topic per se, I'm no going to discuss it here). - Override CreateParams to set the
WS_EX_NOACTIVATE
andWS_EX_TOOLWINDOW
extended styles. This prevents the Form from being activated when mouse events are generated inside its surface (see the docs about these styles). - Add some non-selectable Button Controls to it (the
ButtonNoSel
Control shown below) and set theirTag
property to the Unicode char corresponding to the Emoji image these buttons show. - Add the same Click handler to all the Buttons.
These Buttons, when clicked, simply use SendKeys::Send() (a.k.a. SendInput()
) to send the selected Unicode char to the foreground Window, casting to string the Tag
property value.
This is how it works (setting the Emoji to a Web Page shown by FireFox):
using namespace System;
using namespace System::ComponentModel;
using namespace System::Windows::Forms;
using namespace System::Drawing;
public ref class frmKeyBoard : public System::Windows::Forms::Form
{
public:
frmKeyBoard(void) { InitializeComponent(); }
// [...] Initialization...
protected:
property System::Windows::Forms::CreateParams^ CreateParams {
virtual System::Windows::Forms::CreateParams^ get() override {
auto cp = Form::CreateParams;
cp->ExStyle |= (WS_EX_NOACTIVATE | WS_EX_TOOLWINDOW);
return cp;
}
}
// Event handler for all the Buttons
private:
System::Void buttonNoSelAll_Click(System::Object^ sender, System::EventArgs^ e) {
Control^ ctl = safe_cast<Control^>(sender);
SendKeys::Send(ctl->Tag->ToString());
}
};
Add this simple Custom Control to the Project.
This Control simply uses Control.SetStyle, setting ControlStyles::Selectable = false
to prevent the child Control to become the ActiveControl when interacted with, since it doesn't receive the focus.
using namespace System;
using namespace System::Windows::Forms;
using namespace System::ComponentModel;
namespace CustomControls {
[ToolboxItem(true)]
public ref class ButtonNoSel : public System::Windows::Forms::Button
{
public:
ButtonNoSel(void) {
this->InitializeComponent();
this->SetStyle(ControlStyles::Selectable, false);
}
private:
void InitializeComponent(void) {
this->UseVisualStyleBackColor = true;
}
protected:
~ButtonNoSel() { }
};
}
Note that this Form must run on its own thread.
If you need to show this Form from another one, use Task.Run() to show it as a Dialog Window, calling ShowDialog()
. This will start the Message Loop.
For example, from a Button.Click
handler of another Form (here, named MainForm
).
private:
void ShowKeyboard() {
frmKeyBoard^ fk = gcnew frmKeyBoard();
fk->ShowDialog();
delete fk;
}
private:
System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) {
Task::Run(gcnew Action(this, &MainForm::ShowKeyboard));
}
Show a form without taking focus
If we are talking about wfp, try setting the property ShowActivated="False"
Show a window without setting focus
This article shows how to "Show a Form without stealing focus" by overriding the CreateParams method.
Opening a form in C# without focus
protected override bool ShowWithoutActivation
{
get
{
return true;
}
}
Override this property in your form code and it should do the trick for you.
Show a Form behind everything else, and without stealing focus?
A little bit of PInvoke using SetWindowPos function
public static class HWND {
public static readonly IntPtr
NOTOPMOST = new IntPtr(-2),
BROADCAST = new IntPtr(0xffff),
TOPMOST = new IntPtr(-1),
TOP = new IntPtr(0),
BOTTOM = new IntPtr(1);
}
public static class SWP {
public static readonly int
NOSIZE = 0x0001,
NOMOVE = 0x0002,
NOZORDER = 0x0004,
NOREDRAW = 0x0008,
NOACTIVATE = 0x0010,
DRAWFRAME = 0x0020,
FRAMECHANGED = 0x0020,
SHOWWINDOW = 0x0040,
HIDEWINDOW = 0x0080,
NOCOPYBITS = 0x0100,
NOOWNERZORDER = 0x0200,
NOREPOSITION = 0x0200,
NOSENDCHANGING = 0x0400,
DEFERERASE = 0x2000,
ASYNCWINDOWPOS = 0x4000;
}
[DllImport("user32.dll")]
public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, int uFlags);
private void button1_Click(object sender, EventArgs e) {
RunnerForm frm = new RunnerForm();
SetWindowPos(frm.Handle, HWND.BOTTOM, 0, 0, 0, 0, SWP.SHOWWINDOW | SWP.NOMOVE | SWP.NOOWNERZORDER | SWP.NOSIZE | SWP.NOACTIVATE);
}
How do I prevent the original form from losing focus when I show another form?
Cody Gray answered this, I'm just expanding it by directly pasting the code. Someone with edit rights can copy it over there and delete this for all I care ;)
pinvoke.net's ShowWindow method.:
private const int SW_SHOWNOACTIVATE = 4;
private const int HWND_TOPMOST = -1;
private const uint SWP_NOACTIVATE = 0x0010;
[DllImport("user32.dll", EntryPoint = "SetWindowPos")]
static extern bool SetWindowPos(
int hWnd, // window handle
int hWndInsertAfter, // placement-order handle
int X, // horizontal position
int Y, // vertical position
int cx, // width
int cy, // height
uint uFlags); // window positioning flags
[DllImport("user32.dll")]
static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
static void ShowInactiveTopmost(Form frm)
{
ShowWindow(frm.Handle, SW_SHOWNOACTIVATE);
SetWindowPos(frm.Handle.ToInt32(), HWND_TOPMOST,frm.Left, frm.Top, frm.Width, frm.Height,SWP_NOACTIVATE);
frm.TopMost = false;
}
Related Topics
How to Inject JavaScript in Webbrowser Control
Get the Generated SQL Statement from a SQLcommand Object
How to Access Session Variables from Any Class in ASP.NET
Entering Keys Manually with Entity Framework
How to Bind Wpf Button to a Command in Viewmodelbase
Password Protect a SQLite Db. Is It Possible
Delegate Keyword VS. Lambda Notation
Start a .Net Process as a Different User
How to Detect Installed Version of Ms-Office
Using C# to Check If String Contains a String in String Array
Embedding JavaScript Engine into .Net
Launching an Application (.Exe) from C#
How to Get the Unix Timestamp in C#
Why Is It Bad to Use an Iteration Variable in a Lambda Expression
Binding a Button's Visibility to a Bool Value in Viewmodel
Call Asynchronous Method in Constructor