Is there any means to make it so that a WinForms Window will not be switched to the active window if you click on a button? I am trying to make a program that will assist with entering long strings of text for you and such when you click on a button. However, if you click on one of these buttons it will switch to my program and it won't type the text properly.
Edit:
I was able to somewhat do this by doing the following. However, there is a problem since it won't activate the window if I click on the Titlebar. So I guess what I am looking for is something that will still let me process the button click but not activate the window.
const int WS_EX_NOACTIVATE = 0x08000000;
protected override CreateParams CreateParams
{
get
{
CreateParams ret = base.CreateParams;
ret.ExStyle |= WS_EX_NOACTIVATE;
return ret;
}
}
From http://blogs.msdn.com/b/jfoscoding/archive/2005/09/29/475564.aspx:
private const int WM_MOUSEACTIVATE = 0x0021, MA_NOACTIVATE = 0x0003;
protected override void WndProc(ref Message m) {
if (m.Msg == WM_MOUSEACTIVATE) {
m.Result = (IntPtr)MA_NOACTIVATE;
return;
}
base.WndProc(ref m);
}
Related
I am developing a Windows Forms application in C# in which I have a form which must start in a maximized state and not allow users to restore or resize it. I have already configured the form to start in maximized mode, disable the restore and maximize button and locked the borders of the form but when the title bar is double clicked, the form restores to a smaller size which is unexpected. The following are the properties I set to achieve the required behaviour:
FormBorderStyle = FixedSingle
MaximizeBox = False
WindowState = Maximized
Can someone please help me solve this problem and explain me the solution?
Thanks in advance.
You have to remember that your form starts with some default size values and double click is just toggling between 2 states.
Within your normal state the form will retrieve it's last ( in your case default ) size which you can override :
Width = Screen.PrimaryScreen.Bounds.Width;
Height = Screen.PrimaryScreen.Bounds.Height;
Another thing is that your application has something called start position which ( from what I remember ) defaults to the center of the screen and you can change it using :
Form.StartPosition = new Point(0, 0); // top-left corner
Now all you have to do in your applicaiton is to check for the toggle between window states. Easiest way would be to use WndProc and wait for messages listed in this msdn page :
protected override void WndProc(ref Message m)
{
const int WM_SYSCOMMAND = 0x0112;
const int SC_MAXIMIZE = 0xF030;
const int SC_RESTORE = 0xF120;
if (m.Msg == WM_SYSCOMMAND)
{
switch((int)m.WParam)
{
case SC_RESTORE:
// your window was restored ( double clicked on the command bar )
// set it's window state back to maximize or do whatever
break;
case SC_MAXIMIZE:
// your window was maximized .. no actions needed, just for debugging purpose
break;
}
}
base.WndProc(ref m);
}
This can be accomplished by catching the event and overriding it:
private void Form_Load(object sender, EventArgs e)
{
this.FormBorderStyle = FormBorderStyle.FixedSingle;
this.WindowState = FormWindowState.Maximized;
this.MaximizeBox = false;
this.MinimumSize = Screen.GetWorkingArea(this.Location).Size;
}
private const int WM_NCLBUTTONDBLCLK = 0x00A3;
//double click on a title bar
protected override void WndProc(ref Message m)
{
if (m.Msg == WM_NCLBUTTONDBLCLK)
{
m.Result = IntPtr.Zero;
return;
}
base.WndProc(ref m);
}
So here's what I'm trying to achieve. I have a simple chat winforms application that I want to be put on top of other applications that are fullscreen, I don't want it to take focus but I'd like it to accept the user input in the text box. I've achieved the first part so far and my chat app stays on top of other apps without taking its focus. Here's what I've used:
const int WS_EX_NOACTIVATE = 0x8000000;
protected override CreateParams CreateParams
{
get
{
CreateParams ret = base.CreateParams;
ret.ExStyle |= WS_EX_NOACTIVATE;
return ret;
}
}
public Form1()
{
InitializeComponent();
TopMost = true;
}
Now the problem is that I can't write anything into the textbox. All buttons work fine, I can click them and they trigger events, but the textbox doesn't take any input.
Override this parameters inf your Form class and erase TopMost = true; from your code. This will work and will gain focus when trying to edit textbox.
protected override bool ShowWithoutActivation
{
get { return true; }
}
private const int WS_EX_TOPMOST = 0x00000008;
protected override CreateParams CreateParams
{
get
{
CreateParams createParams = base.CreateParams;
createParams.ExStyle |= WS_EX_TOPMOST;
return createParams;
}
}
Found it here: Look at second answer
I was wondering how to hide the titlebar of a form but keep the original border, like e.g Dropbox does:
Thanks in advance!
Set FormBorderStyle to FormBorderStyle.Sizable or FormBorderStyle.SizableToolWindow and set Text to an empty string, and ControlBox to false
Note that FixedToolWindow won't work, it will remove the border. If you don't want it to be sizable, use SizableToolWindow and add this to the form's codebehind (adding both languages since you don't specify and tagged the question with both):
In vb.net:
Protected Overrides Sub WndProc(ByRef message As Message)
If message.Msg = &H84 Then ' WM_NCHITTEST
message.Result = CType(1, IntPtr)
Return
End If
MyBase.WndProc(message)
End Sub
In C#:
protected override void WndProc(ref Message message)
{
if (message.Msg == 0x0084) // WM_NCHITTEST
message.Result = (IntPtr)1;
else base.WndProc(ref message);
}
Here is a simple way:
this.ControlBox = false;
this.Text = string.Empty;
If the Form is designed to be a pop-up dialog, you might want to add the following line:
this.ShowInTaskBar = false;
That keeps the Form from appearing in the taskbar.
// 3rd option (C#)
protected override CreateParams CreateParams
{
get
{
int WS_DLGFRAME = 0x400000;
CreateParams result = base.CreateParams;
result.Style &= ~WS_DLGFRAME;
return result;
}
}
I created my own on screen keyboard with special features.
I'm using override methods ShowWithoutActivation and CreateParams for preventing my Form getting focus (according to this stackoverflow question).
protected override bool ShowWithoutActivation
{
get { return true; }
}
protected override CreateParams CreateParams
{
get
{
CreateParams param = base.CreateParams;
param.ExStyle |= 0x08000000;
return param;
}
}
But after a few Hide() and Show() my Form is again focusable.
To fix it I need to restart application, but it is of course poor solution.
Is it possible to do without restart?
Showing Form after being hidden without giving it focus not help. My application can just be focused again.
I'm noticed that in most cases it happens randomly, but in one of them always: if I show my application after right mouse click on NotifyIcon in tray and choose item from ContextMenuStrip. OnClick I simply call show function.
Do you need to click the window? When not, try this one:
protected override void WndProc(ref Message message)
{
switch (message.Msg)
{
case 0x84: // WM_NCHITTEST
message.Result = (IntPtr)(-1); // HTTRANSPARENT;
return;
}
base.WndProc(ref message);
return;
}
I have a simple windows form with no border and several label controls (nothing that needs to be clicked). I needed to be able to allow the user to move the form by clicking anywhere on it, so I found this question, and used the following code found there.
private const int WM_NCHITTEST = 0x84;
private const int HTCLIENT = 0x1;
private const int HTCAPTION = 0x2;
protected override void WndProc(ref Message m)
{
switch (m.Msg) {
case WM_NCHITTEST:
base.WndProc(ref m);
if ((int)m.Result == HTCLIENT) {
m.Result = (IntPtr)HTCAPTION;
return;
} else {
return;
}
break;
}
base.WndProc(ref m);
}
This works well...to a point. If I click anywhere on the form itself (the background), WM_NCHITTEST is HTCLIENT, so I can move my form as expected. However, if I click on a label control itself, the message is something different, and I can't tell what it is.
I found this article about the various possible values for WM_NCHITTEST but none of them seem to be what I need.
I realize I could disable all my label controls and that would allow me to click "on" them as if it was the form itself, but I'm wondering if there's a better/different way to do this.
Thanks for the help!
You are overriding the WndProc for the form, but when the cursor is over a label the WM_NCHITTEST message is sent to the label.
You could create your own label control derived from Label and override its WndProc. This should always return HTTRANSPARENT in response to WM_NCHITTEST. Something like:
private const int HTTRANSPARENT = -1;
protected override void WndProc(ref Message m)
{
switch (m.Msg)
{
case WM_NCHITTEST:
m.Result = (IntPtr)HTTRANSPARENT;
return;
}
base.WndProc(ref m);
}
Also note that there's a small bug in your WndProc. If the message is WM_NCHITTEST but the region isn't HTCLIENT then you call the base class twice.