I'm having an issue with a richTextBox inside of a windows form.
I have enabled vertical scrolling and everything works fine, except when I use the mouse to drag the scrollbar. When I do this, the scrollbar just stays in place and flickers until I release the drag. The bar scrolls regularly without flickering when I use the scroll wheel on my mouse, or click the up/down arrow keys.
Any ideas as to why this is happening?
In case anyone else ever has this problem, I found a solution here: http://www.angryhacker.com/blog/archive/2010/07/21/how-to-get-rid-of-flicker-on-windows-forms-applications.aspx
Essentially, all that needs to be added to the form.cs file is:
int originalExStyle = -1;
bool enableFormLevelDoubleBuffering = true;
protected override CreateParams CreateParams
{
get
{
if (originalExStyle == -1)
originalExStyle = base.CreateParams.ExStyle;
CreateParams cp = base.CreateParams;
if (enableFormLevelDoubleBuffering)
cp.ExStyle |= 0x02000000; // WS_EX_COMPOSITED
else
cp.ExStyle = originalExStyle;
return cp;
}
}
private void TurnOffFormLevelDoubleBuffering()
{
enableFormLevelDoubleBuffering = false;
this.MaximizeBox = true;
}
private void frmMain_Shown(object sender, EventArgs e)
{
TurnOffFormLevelDoubleBuffering();
}
Related
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've written a user control for that supports transparent background (among other things).
However, I've found a problem that when the background is transparent, and you change the text of the user control, the previous text is still displayed on the screen, under the new text, making it impossible to read.
I've been googling for half a day now, finding all sort of suggestions that didn't work in my case, most of them involving painting the parent control onto a bitmap and draw that bitmap on my control's surface.
However, in my case the parent control is also transparent so I've tried to go up to the form's level like suggested here but i was getting an InvalidArgumentException,
I've tried invalidating the parent control like suggested here but no luck either.
my code is basically this (truncated to the bare minimum):
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.ExStyle |= 0x20;
return cp;
}
}
protected override void OnPaintBackground(PaintEventArgs e)
{
if(this.BackColor != Color.Transparent)
{
base.OnPaintBackground(e);
}
}
I keep learning again and again that simply explaining the problem to someone else often helps you solve it.
So, After combining a few answers from all my searches,
mainly this one about invalidating a specified rectangle of the parent,
and this one about getting the location of the control on the form,
I came up with this:
// Make the Text property browsable again, call Refresh when changed.
[Browsable(true),
DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public override string Text
{
get { return _Text; }
set
{
if(_Text != value)
{
this.Refresh();
_Text = value;
}
}
}
// Override Refresh to invalidate the relevant part of the parent form
public override void Refresh()
{
Form form = this.FindForm();
// only for transparent controls that has text and no background image
if (this.BackColor == Color.Transparent &&
!string.IsNullOrEmpty(this.Text) &&
(this.Gradient.BackColor2==Color.Transparent || !this.Gradient.IsGradient) &&
this.BackgroundImage == null &&
form != null)
{
Point locationOnForm = form.PointToClient(
this.Parent.PointToScreen(this.Location)
);
// Invalidate the rectangle of the form that's behind the current control
form.Invalidate(new Rectangle(locationOnForm, this.Size));
}
base.Invalidate();
}
I will still have to deal with parent controls between the current control and the form, but for now this is good enough for me.
I think we are close on this one.
Firstly, you cannot suppress OnPaintBackground like that and expect the rest of winforms to run as expected, this means nothing gets painted to that region at all, so we have left GDI+ or windows or presumably some other construct to "fill in the blanks". The controls on your form that are opaque may want to call your UserControl to get it's background, so we have to paint something...
So we always call base.OnPaintBackground, but if the background is Transparent, then we need to invalidate the entire surface of the control to be repainted.
public Glass()
{
InitializeComponent();
this.SetStyle(ControlStyles.Opaque, true);
this.SetStyle(ControlStyles.OptimizedDoubleBuffer, false);
}
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.ExStyle |= 0x20;
return cp;
}
}
private bool rePaintState = false;
protected override void OnPaintBackground(PaintEventArgs e)
{
base.OnPaintBackground(e);
if (this.BackColor == Color.Transparent)
{
// we want to invalidate and force it to re-paint but just once
if (rePaintState)
{
rePaintState = false;
}
else
{
rePaintState = true;
this.Invalidate();
}
}
}
This is still not complete, but saved most of the flickering I was experiencing when controls above and below the UserControl had textboxes with values refreshing on a timer.
I know its not a huge help, but WPF is really good for these types of UX issues ^-^
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;
}
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);
}