I have a top level (ie. acts like a window) UserControl (.NET 4.0) which I am using to simulate a custom form. I can easily set the title text and taskbar text like so:
public override string Text
{
get { return base.Text; }
set
{
base.Text = value
TitleText.Text = value;
}
}
Which sets both the title text and taskbar text:
Please note that the bar down the bottom of the image is my actual taskbar; I have installed an alternate shell
The problem I have come across is that I can't seem to set the taskbar icon of this UserControl as it has no overridable Icon property so I can't set the taskbar icon as I would with the text. Please also note that the icon shown in the UserControl is just a PictureBox containing an image.
So, in short I want to be able to do this:
But I can't do this as there is no Icon property for a UserControl:
public override Icon Icon
{
get { return base.Icon; }
set
{
base.Icon = value;
TitleBarIcon.Image = value.ToBitmap();
}
}
How can I change the taskbar icon?
Thanks in advance ;)
I am not sure if I got you right but I think you have to possibilites:
Either set the Icon of the ParentForm.
Or set the ApplicationIcon as described here: http://msdn.microsoft.com/en-us/library/339stzf7.aspx
EDIT:
As you are using a control as TopLevelControl you need to send the WM_SETICON during the creation of the control - as the form does!
Taken from the Form.CreateHandle:
Icon icon = this.Icon;
if (icon != null && this.TaskbarOwner.Handle != IntPtr.Zero)
{
UnsafeNativeMethods.SendMessage(this.TaskbarOwner, 128, 1, icon.Handle);
}
Related
I have a customized button deriving from System.Windows.Forms.Button:
(class MyButton : Button)
This button has an extra property called IsSelected.
public bool IsSelected
{
get
{
return _isSelected;
}
set
{
_isSelected = value;
if (value)
this.Font = new Font(_storedFont.FontFamily, _storedFont.Size - 1); //Decrease font size by 1
else
this.Font = _storedFont; //Set font back to origin
}
}
If IsSelected is set true the font size of the button will be decreased by 1 point to show the user of the application, that this button is in "pressed" state.
If IsSelected is set false the font size of the button will be set back to original size to show the user that this button is now again in "normal" state.
The issue is now that I first need to store the original font size that has been set in the properties window in Visual Studio, before it is changed by IsSelected.
To hold the stored original font size I have property called StoredFont (class level field = _storedFont).
I then tried to store the original font size in a chained constructor in MyButton, but it appears that the constructor is called before Visual Studio has actually set the font that has been defined in the properties window.
Question 1:
Is it correct that the constructor is called before Visual Studio actually sets the font?
Question 2:
Any suggestions to how to save the font that has been set from the properties window when a new instance of MyButton is created?
Note!
I have already considered many other possibilities to show selected state (CheckBox instead of Button, other back color etc.), and this is not my question.
Thanks a lot in advance!
Question 1: Yes otherwise you'll endup with a NullReferenceException...
Question 2: Assuming the first Font assignment is the font you want to store, you could store the font in an override of Font
public override Font Font
{
get
{
return base.Font;
}
set
{
if(_storedFont == null)
_storedFont = Font;
base.Font = value;
}
}
This way you don't have to worry about the order of initialization.
I want to add a StatusStrip to a UserControl and resize this UserControl at runtime. Here is how I add the StatusStrip.
StatusStrip sb = new StatusStrip();
sb.BackColor = System.Drawing.SystemColors.ControlDark;
sb.Dock = DockStyle.Bottom;
sb.GripMargin = new Padding(2);
sb.SizingGrip = true;
sb.GripStyle = ToolStripGripStyle.Visible;
sb.LayoutStyle = ToolStripLayoutStyle.HorizontalStackWithOverflow;
this.Controls.Add(sb);
The StatusStrip is displayed at the bottom of the UserControl. However there is no SizingGrip (little Triangle) in the right bottom corner of the StatusStrip. Why not?
It's not showing up because a UserControl is not a sizable control at runtime. The StatusStrip, nay more specifically the sizing grip, was built to support the Form control.
Here is the code for ShowSizingGrip, a private property used during paint:
private bool ShowSizingGrip
{
get
{
if (this.SizingGrip && base.IsHandleCreated)
{
if (base.DesignMode)
{
return true;
}
HandleRef rootHWnd = WindowsFormsUtils.GetRootHWnd(this);
if (rootHWnd.Handle != IntPtr.Zero)
{
return !UnsafeNativeMethods.IsZoomed(rootHWnd);
}
}
return false;
}
}
at this point I can see two point of interest. First, HandleRef rootHWnd = WindowsFormsUtils.GetRootHWnd(this);, I can't test this class because it's internal, but there's a really good chance it's not going to return a window. However, even if it did, if said window was currently maximized, !UnsafeNativeMethods.IsZoomed(rootHWnd);, the sizing grip wouldn't show either.
My educated guess -- your window is maximized. I make that assumption because it appears Cody Gray was able to make it show up on a UserControl.
I have a library. In the library, I have a button with a Green background color and Text as Go Green.
Now I made a winform project and dragged my Go green button in the form. On running the application, I noticed that the button color is changing to green but text is displayed as button1 (name of the class library).
My library looks like:
public class button : Button
{
public Seats()
{
button.BackColor = Color.Green;
button.Text = "Go Green";
}
}
I discovered that it is happening because InitializeComponent() method is called in the constructor of the form. And in designer.cs,
button.Text = "button1";
is called. How can I avoid that to happen. I want my text to be visible from my class library.
Note: When I manually removed the above code from the designer.cs, everything was working fine.
Easiest way - override button's Text property and make it hidden to designer serialization:
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public override string Text
{
get { return base.Text; }
set { base.Text = value; }
}
Designer will add default button name, but when you build application, your text will be shown.
UPDATE: Another (harder) way - provide to designer default property value for your button. In this case you need reference System.Design.dll which is available only for full version of .net framework (not client profile version).
First: create control designer for your button
public class GoGreenButtonDesigner : System.Windows.Forms.Design.ControlDesigner
{
public override void OnSetComponentDefaults()
{
base.OnSetComponentDefaults();
Control.Text = "Go Green";
}
}
Last: add Designer attribute to your custom button class
[Designer(typeof(GoGreenButtonDesigner))]
public class GoGreenButton : Button
{
//...
}
That's it. Now when you drag button to form, it will have default text "Go Green" without any additional compilations.
I have a few panels with different directshow IVideoWindow handles bound to them so that the videos get shown inside the panels (WindowStyle properties are: Child,ClipSiblings,ClipChildren,Caption) Now I would like to move these panels around but I can only manage to move them when the video content is not filling the entire panel and I'm clicking+holding mouse button on the empty panel space. I can move the video windows around in the panels but of course they only move inside their respective panel space.
Is there a way to bind the video window content directly to the panel , for example the entire panel with content moves freely around when I click+hold the videowindow menu bar?
Thanks in advance.
Forgot to mention,this is in c#.
I use the Video Mixing Renderer 9 and have it tied to a user control. I have set the VMR9 to Windowless mode and then set the video clipping window on the IVMRWindowlessControl9 interface to the handle of my user control. I also set the video to fill the panel completely, using IVMRWindowlessControl9.GetNativeVideoSize, IVMRWindowlessControl9.SetAspectRatioMode, and IVMRWindowlessControl9.SetVideoPosition whenever the panel gets resized. When the form that contains my user control gets moved around, the video follows along. This is all done with C# and DirectShow.NET.
Edited to add sample code:
public partial class VideoPanel : UserControl
{
private VideoMixingRenderer9 _renderer;
private IVMRWindowlessControl9 _windowlessControl;
public VideoMixingRenderer9 Renderer
{
get
{
return _renderer;
}
set
{
_renderer = value;
if (_renderer != null)
{
var filterConfig = _renderer as IVMRFilterConfig9;
if (filterConfig != null)
{
filterConfig.SetRenderingMode(VMR9Mode.Windowless);
_windowlessControl = _renderer as IVMRWindowlessControl9;
if (_windowlessControl != null)
{
_windowlessControl.SetVideoClippingWindow(Handle);
SetSize();
}
}
}
}
}
private void SetSize()
{
var srcRect = new DsRect();
var dstRect = new DsRect(ClientRectangle);
int arWidth, arHeight;
_windowlessControl.GetNativeVideoSize(out srcRect.right, out srcRect.bottom, out arWidth, out arHeight);
_windowlessControl.SetAspectRatioMode(VMR9AspectRatioMode.LetterBox);
_windowlessControl.SetVideoPosition(srcRect, dstRect);
}
}
I solved it finally and I can't believe how silly I was. I left out the
hr = videoWindow.put_MessageDrain(hWin.Handle);
line , of course the videowindow wouldnt "listen" to the panel.
This is a strange thing I'm doing, but how can I set the title of a winform form in the taskbar, but not in its titlebar?
A possible solution (it works fine for me) it's to override the CreateParams property and set the caption to be displayed in the taskbar:
protected override CreateParams CreateParams
{
get
{
new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand();
// Extend the CreateParams property of the Button class.
CreateParams cp = base.CreateParams;
// Update the button Style.
cp.Style &= ~0xC00000; //WS_CAPTION;
cp.Caption = PRODUCT_NAME;
return cp;
}
}
I hope that works for you,
Lisa
Okay, so my temporary work around is this:
At runtime/design-time, Clear the Text Property for the Form (Form1, or whatever form this applies to), and when the Minimize, or Hide() events are triggered, change the Text Property to display a Title. So, when the form is hidden or minimized, you won't be able to see the titlebar anyway, but you will be able to see the caption on the Taskbar! And when the Form is later maximized, or when the Form.WindowState == WindowState.Normal, then clear the Text Property again. :-)
I wonder if this is the approach MS took!?
Edit:
Okay, sweet, I've got some working code of yumminess:
If you're using Visual Studio, go to Design View, select the Form control, open the Properties Pane, click the Events Tab, then double-click the Resize event. The Code View should display. Inside the Resize() code that was just created, type this:
private void Form_Resize( object sender, System.EventArgs e )
{
if( this.WindowState == FormWindowState.Minimized )
this.Text "Some uber-awesome title.";
}
Step 2:
When you want to show/maximize the form again, simply edit the above so it looks like this:
private void Form_Resize( object sender, System.EventArgs e )
{
if( this.WindowState == FormWindowState.Minimized )
this.Text "Some uber-awesome title.";
else if(this.WindowState == FormWindowState.Normal || this.WindowState == FormWindowState.Maximized)
{
this.Text = String.Empty; // Or, you can use: this.Text = "";
}
}
However, this does not completely solve my problem yet. It still doesn't display the Title in the Taskbar when the Form is Visible to the user (because the Text property of the Titlebar is empty.
A workaround could be drawing your own form title bar. That way you won't need to change the actual title that's shown in Taskbar.
This question is about WPF rather than Winforms but it's applicable: Set a taskbar text different from the Window title in wpf