|
yes it changes on the mouse down to true. but the mouse up event never fires because the loop has not finished. but it will change in the mouse up event. if the value never changed then I would have to set it to const or read only. A static variable will change. private means this variable is not accessible from another class. when the form is initialized the variable is set to false. When the mouseDown event is fired then the variable is set to true. This is working. the problem lies in the loop. Because it is in the loop the MouseUp event never executes.
|
|
|
|
|
Zap-Man wrote: IsKeyDown = true;
while (IsKeyDown) {
Winamp.Winamp.VolumeDown();
}
This loop will never terminate so your event handler button1_MouseDown will never notify the framework that it is complete. This blocks your application from doing anything else, so you need to separate the functions somehow.
BTW it helps if you put <pre></pre> tags around your code snippet so it is easier to read.
|
|
|
|
|
Hi,
this is all wrong.
1. event handlers get executed on the main thread (aka GUI thread), hence MouseUp cannot do anything as long as MouseDown is active.
2. Your while loop will never exit.
3. Your while loop has no delay, so at what rate will VolumeDown be called?
4. Using Thread.Sleep would not be a good approach as that blocks the GUI; using a timer (a Windows.Forms.Timer) is the perfect solution: start the timer on MouseDown, stop it on MouseUp (or better yet have the Tick handler check Control.MouseButtons).
Zap-Man wrote: I don't want to use a timer
why? because you don't understand them? because you don't like a clean and natural solution?
Luc Pattyn
I only read code that is properly indented, and rendered in a non-proportional font; hint: use PRE tags in forum messages
Local announcement (Antwerp region): Lange Wapper? Neen!
|
|
|
|
|
Look I am not looking for Critics. If you cant help then don't bother posting. I understand timers perfectly. My app has a timer which runs a massive about of code. I understand what the program is doing. I am looking for a way around it.
|
|
|
|
|
This response is uncalled for, Luc's comments are valid.
only two letters away from being an asset
|
|
|
|
|
private AutoResetEvent autoEvent = null;
private void OnMouseDown(object sender, MouseEventArgs e)
{
autoEvent = new AutoResetEvent(false);
ThreadPool.QueueUserWorkItem(VolumeDown);
}
private void OnMouseUp(object sender, MouseEventArgs e)
{
autoEvent.Set();
}
private void VolumeDown(object state)
{
bool lowerVolume = true;
do
{
BeginInvoke(new MethodInvoker(delegate() { Winamp.Winamp.VolumeDown(); }), null);
if(autoEvent.WaitOne(100))
lowerVolume = false;
}
while(lowerVolume);
}
only two letters away from being an asset
|
|
|
|
|
Thank you Mark This is excatly what Im looking for. Congrats to you!!!
|
|
|
|
|
You're welcome
only two letters away from being an asset
|
|
|
|
|
First, the reason your original idea doesn't work is that the event handlers are all on the same thread. The mouseup handler cannot run until mousedown returns, and mousedown doesn't return until mouseup has run, so you're basically deadlocking yourself with only one thread!
Depending on what you do in those handlers you may be able to do it in another thread instead. But if you want to do anything to the GUI itself, you aren't allowed to do so on any thread but the "gui thread", which is the same thread that is raising the events.
So you have to use another hook... to marshal the call back to the UI thread again!
Here's an example of how to do this. To run it, create a new windows forms application and replace Form1.cs with:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
namespace WindowsFormsApplication2
{
public partial class Form1 : Form
{
long n;
MouseButtons buttons;
Label label1;
public Form1()
{
label1 = new Label();
label1.Text = "here";
Controls.Add(label1);
label1.MouseUp += new MouseEventHandler(label1_MouseUp);
label1.MouseDown += new MouseEventHandler(label1_MouseDown);
}
void label1_MouseDown(object sender, MouseEventArgs e)
{
buttons = e.Button;
new Thread(run).Start();
}
void label1_MouseUp(object sender, MouseEventArgs e)
{
buttons = MouseButtons.None;
}
void run()
{
var upd = new Action(update);
while (buttons != MouseButtons.None) label1.Invoke(upd);
}
void update()
{
n = (buttons == MouseButtons.Left ? --n : ++n);
label1.Text = n.ToString();
}
}
}
|
|
|
|
|
Hey guys.
So, my owner drawn TabControl, inheriting from the TabControl in System.Windows.Forms, doesn't want to give me a transparent background. (Or I simply don't know how) It's also giving me these weird gaps, and somehow it's not filling out all the space in my Panel parent.
Here's a screenshot: http://tinypic.com/r/1tou9h/4
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Design;
using System.IO;
using System.Linq;
using System.Runtime;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;
using Storm;
using Storm.Docking;
using Storm.Docking.Controls;
using Storm.Docking.Visual;
using Storm.Docking.Visual.Drawing;
using Storm.Docking.Visual.Glyphs;
using Storm.Docking.Win32;
namespace Storm.Docking.Visual
{
#region TabMouseEventArgs
public class TabMouseEventArgs
: EventArgs
{
#region Fields
private TabPage _tabPage = null;
#endregion
#region Properties
[Browsable(false)]
[Description("Gets or sets the TabPage associated with the TabMouseEventArgs.")]
public TabPage TabPage
{
get { return _tabPage; }
set { _tabPage = value; }
}
#endregion
public TabMouseEventArgs()
{
}
public TabMouseEventArgs(TabPage page)
{
this.TabPage = page;
}
}
#endregion
public class DockTab
: TabControl
{
#region Fields
private int _hoverIndex = -1;
private StringFormat _stringFormat = null;
private DockRenderer _renderer = null;
private DockPanel _dockPanel = null;
private DockPane _dockPane = null;
#region Events
public event TabMouseEventHandler TabMouseEnter;
public event TabMouseEventHandler TabMouseLeave;
#endregion
#region Delegates
public delegate void TabMouseEventHandler(object sender, TabMouseEventArgs e);
#endregion
#endregion
#region Properties
[Browsable(false)]
[Description("Gets or sets the DockRenderer of the DockTab.")]
public DockRenderer Renderer
{
get { return _renderer; }
set
{
_renderer = value;
this.Invalidate();
}
}
[Browsable(false)]
[Description("Gets the index of the tab the user is currently hovering over with the mouse.")]
public int HoverIndex
{
get { return _hoverIndex; }
}
[Browsable(false)]
[Description("Gets the StringFormat used to draw the TabPages' text.")]
public StringFormat StringFormat
{
get { return _stringFormat; }
}
[Browsable(true)]
[Description("Gets or sets the parent DockPanel.")]
public DockPanel DockPanel
{
get { return _dockPanel; }
set
{
_dockPanel = value;
_dockPanel.Controls.Add(this);
this.Parent = _dockPanel;
if (_dockPanel.DockPane != null)
_dockPane = _dockPanel.DockPane;
}
}
[Browsable(false)]
[Description("Gets the parent DockPane.")]
public DockPane DockPane
{
get { return _dockPane; }
}
#endregion
#region Methods
#region Internal
internal void InvokePaintAll(Control c, PaintEventArgs e)
{
this.InvokePaint(c, e);
this.InvokePaintBackground(c, e);
}
#endregion
#region Protected
protected override void OnPaint(PaintEventArgs e)
{
this.Renderer.TabPaintBackground(this, e.Graphics);
for (int i = 0; i < this.TabCount; i++)
{
this.Renderer.TabDrawTab(this, e.Graphics,
this.TabPages[i], i);
}
base.OnPaint(e);
}
protected override void OnPaintBackground(PaintEventArgs pevent)
{
this.Renderer.TabPaintBackground(this,
pevent.Graphics);
}
protected override void OnMouseMove(MouseEventArgs e)
{
bool foundItem = false;
int index = -1;
foreach (TabPage page in this.TabPages)
{
index++;
if (this.GetTabRect(index).Contains
(e.Location) == true)
{
_hoverIndex = index;
this.Invalidate();
foundItem = true;
if (this.TabMouseEnter != null)
{
TabMouseEventArgs tabArgs = new TabMouseEventArgs();
tabArgs.TabPage = page;
this.TabMouseEnter(this, tabArgs);
}
}
else if (foundItem == false)
{
_hoverIndex = -1;
this.Invalidate();
if (this.TabMouseLeave != null)
{
TabMouseEventArgs tabArgs = new TabMouseEventArgs();
tabArgs.TabPage = page;
this.TabMouseLeave(this, tabArgs);
}
}
}
base.OnMouseMove(e);
}
protected override void OnMouseLeave(EventArgs e)
{
_hoverIndex = -1;
this.Invalidate();
if (this.TabMouseLeave != null)
{
TabMouseEventArgs tabArgs = new TabMouseEventArgs();
tabArgs.TabPage = null;
this.TabMouseLeave(this, tabArgs);
}
base.OnMouseLeave(e);
}
#endregion
#endregion
public DockTab()
{
_renderer = new DockRenderer();
this.SetStyle(ControlStyles.UserPaint, true);
this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
this.SetStyle(ControlStyles.ResizeRedraw, true);
this.SetStyle(ControlStyles.SupportsTransparentBackColor, true);
this.Dock = DockStyle.Fill;
this.BackColor = this.Renderer.DockColorTable.TabBodyBackColor;
this.Font = this.Renderer.DockColorTable.PaneFont;
this.Alignment = TabAlignment.Bottom;
_stringFormat = new StringFormat();
_stringFormat.Alignment = StringAlignment.Center;
_stringFormat.LineAlignment = StringAlignment.Center;
}
}
}
using System;
using System.Collections;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Design;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Storm;
using Storm.Docking;
using Storm.Docking.Controls;
using Storm.Docking.Visual;
using Storm.Docking.Visual.Drawing;
using Storm.Docking.Visual.Glyphs;
using Storm.Docking.Win32;
namespace Storm.Docking.Visual.Drawing
{
public class DockRenderer
{
#region Fields
private DockColorTable _colorTable = null;
#endregion
#region Properties
public virtual DockColorTable DockColorTable
{
get { return _colorTable; }
set { _colorTable = value; }
}
#endregion
#region Methods
#region Public
#region DockCaption
public virtual void CaptionDrawBar(DockCaption c, Graphics g)
{
Color startColor = DockColorTable.CaptionNormalColorStart;
Color endColor = DockColorTable.CaptionNormalColorEnd;
Color textColor = DockColorTable.CaptionNormalTextForeColor;
if (c.Focused == true)
{
startColor = DockColorTable.CaptionFocusColorStart;
endColor = DockColorTable.CaptionFocusColorEnd;
textColor = DockColorTable.CaptionFocusTextForeColor;
}
LinearGradientBrush brush = new LinearGradientBrush
(c.Bounds.Location, new Point(c.Bounds.
Location.X, c.Bounds.Location.Y +
c.Size.Height), startColor, endColor);
float diameter = DockColorTable.CaptionRadius * 2.0F;
SizeF sizeF = new SizeF(diameter, diameter);
GraphicsPath path = new GraphicsPath();
RectangleF arc = new RectangleF(new PointF
(c.Location.X, c.Location.Y), sizeF);
path.AddArc(arc, 180, 90);
arc.X = c.Bounds.Right - diameter;
path.AddArc(arc, 270, 90);
path.AddRectangle(new Rectangle(new Point((int)path.
PathPoints[0].X, (int)path.PathPoints[0].Y),
c.Size));
path.CloseFigure();
g.FillPath(brush, path);
g.DrawPath(BrushStack.GetPen(DockColorTable
.CaptionBorderColor), path);
PointF textPoint = new PointF(c.Location.X + 1,
c.Location.Y + (c.Size.Height / 2)
- (c.Font.GetHeight() / 2));
g.DrawString(c.CaptionText, c.Font,
BrushStack.GetBrush(textColor), textPoint);
}
#endregion
#region DockTab
public virtual void TabPaintBackground(DockTab t, Graphics g)
{
t.ClientRectangle.Offset(t.Location);
PaintEventArgs e = new PaintEventArgs(g, t.ClientRectangle);
GraphicsState state = g.Save();
g.SmoothingMode = SmoothingMode.AntiAlias;
try
{
g.TranslateTransform((float)-t.Location.X,
(float)-t.Location.Y);
t.InvokePaintAll(t.Parent, e);
}
finally
{
g.Restore(state);
t.ClientRectangle.Offset(-t.Location.X, -t.Location.Y);
}
}
public virtual void TabDrawTab(DockTab t, Graphics g, TabPage tabPage, int index)
{
Rectangle recBounds = t.GetTabRect(index);
RectangleF tabTextArea = (RectangleF)t.GetTabRect(index);
RectangleF tabArea = tabTextArea;
Color tabColorStart = DockColorTable.TabNormalBackColorStart;
Color tabColorEnd = DockColorTable.TabNormalBackColorEnd;
Color tabBorderColor = DockColorTable.TabNormalBorderColor;
Color textColor = DockColorTable.TabNormalForeColor;
bool selected = t.SelectedIndex == index;
bool hovering = t.HoverIndex == index && selected == false;
if (selected == true)
{
tabColorStart = DockColorTable.TabFocusBackColorStart;
tabColorEnd = DockColorTable.TabFocusBackColorEnd;
tabBorderColor = DockColorTable.TabFocusBorderColor;
textColor = DockColorTable.TabFocusForeColor;
}
if (hovering == true)
{
tabColorStart = DockColorTable.TabHoverBackColorStart;
tabColorEnd = DockColorTable.TabHoverBackColorEnd;
tabBorderColor = DockColorTable.TabHoverBorderColor;
textColor = DockColorTable.TabHoverForeColor;
}
Rectangle rect = new Rectangle(new Point((int)tabArea.X,
(int)tabArea.Y), new Size((int)tabArea.Size.Width - 1,
(int)tabArea.Size.Height - 4));
LinearGradientBrush brush = new LinearGradientBrush
(rect, tabColorStart, tabColorEnd, 90f);
g.FillRoundedRectangle(brush, rect, (int)DockColorTable.
TabRadius, RectangleEdgeFilter.BottomLeft |
RectangleEdgeFilter.BottomRight);
g.DrawRoundedRectangle(BrushStack.GetPen(tabBorderColor),
rect, (int)DockColorTable.TabRadius,
RectangleEdgeFilter.BottomLeft | RectangleEdgeFilter.
BottomRight);
if ((tabPage.ImageIndex >= 0) && (t.ImageList != null) &&
(t.ImageList.Images[tabPage.ImageIndex] != null))
{
int leftMargin = 8;
int rightMargin = 2;
Image image = t.ImageList.Images[tabPage.ImageIndex];
Rectangle imageBounds = new Rectangle(recBounds.X +
leftMargin, recBounds.Y + 1,
image.Width, image.Height);
float adjust = (float)(leftMargin + image.Width +
rightMargin);
imageBounds.Y += (recBounds.Height - image.Height) / 2;
tabArea.X += adjust;
tabArea.Width -= adjust;
g.DrawImage(image, imageBounds);
}
Brush textBrush = BrushStack.GetBrush(textColor);
g.DrawString(tabPage.Text, t.Font, textBrush,
tabTextArea, t.StringFormat);
}
#endregion
#region Glyph
public virtual void GlyphDrawHover(Glyph glyph, Graphics g)
{
Color penColor = DockColorTable.GlyphNormalBorderColor;
Color fillColorStart = DockColorTable.GlyphNormalFillColorStart;
Color fillColorEnd = DockColorTable.GlyphNormalFillColorEnd;
int radius = 2;
if (glyph.DockCaption.Focused == true)
{
penColor = DockColorTable.GlyphHoverBorderColor;
fillColorStart = DockColorTable.GlyphHoverFillColorStart;
fillColorEnd = DockColorTable.GlyphHoverFillColorEnd;
}
LinearGradientBrush brush = new LinearGradientBrush(glyph.GlyphRect,
fillColorStart, fillColorEnd, LinearGradientMode.Vertical);
g.SmoothingMode = SmoothingMode.HighQuality;
g.FillRoundedRectangle(brush, glyph.GlyphRect, radius);
Rectangle borderRect = glyph.GlyphRect;
borderRect.Width--;
borderRect.Height--;
g.DrawRoundedRectangle(BrushStack.GetPen(penColor),
borderRect, radius);
}
public virtual void GlyphDrawPressed(Glyph glyph, Graphics g)
{
Color penColor = DockColorTable.GlyphPressedBorderColor;
Color fillColorStart = DockColorTable.GlyphPressedFillColorStart;
Color fillColorEnd = DockColorTable.GlyphPressedFillColorEnd;
int radius = 2;
LinearGradientBrush brush = new LinearGradientBrush(glyph.GlyphRect,
fillColorStart, fillColorEnd, LinearGradientMode.Vertical);
g.SmoothingMode = SmoothingMode.HighQuality;
g.FillRoundedRectangle(brush, glyph.GlyphRect, radius);
Rectangle borderRect = glyph.GlyphRect;
borderRect.Width--;
borderRect.Height--;
g.DrawRoundedRectangle(BrushStack.GetPen(penColor),
borderRect, radius);
}
#endregion
#endregion
#endregion
public DockRenderer()
{
_colorTable = new DockColorTable();
}
}
}
|
|
|
|
|
|
Bumping does you no good around here.
The reason your question is getting voted down is because of the massive code snippets you posted. Most people simply are not going to look through all of that.
I don't see where your code is doing its own transparency or what you expect to see through the background of your control. If you're using Control.Transparent in your code, all you're really doing is telling the control to take on the background properties of the control that contains your control. You will not see the contents of parent containers or other windows and controls through the "transparency".
|
|
|
|
|
Consider the following...
byte[] theArray = new byte[2];
byte[] TheArray
{
get { return theArray; }
}
byte a = TheArray[0];
TheArray[1] = 255;
Can anyone explain what happens? I would assume a function call to get would be executed for each = TheArray[i]; Correct? What about TheArray[1] = 255; ? If there is no set method it should still work, right? If not, I know it would if it were a method that returned an array. TheArray()[1] = 255; I guess my question is, does the C# compiler optimize this code so function calls are not performed when accessing the array through property and method invocations?
How would the set property method work with the indexer? Is that possible? What is the point in it if it were not. Allowing properties that handle arrays seems illogical, especially in the set method and in that you can index it like in the code sample, but.. and @!$#% .
modified on Friday, October 16, 2009 11:24 PM
|
|
|
|
|
Hi,
the statement a = TheArray[0]; contains three operations:
1. getting an array (TheArray)
2. getting an element (TheArray[0])
3. assigning a value (to a)
the statement TheArray[1]=255; contains three operations:
1. evaluating an expression (255)
2. getting an array (TheArray)
3. setting an element (TheArray[1])
So in both cases it is the array getter that is used, that is why it works.
An array setter property would be used to assign a new array, as in TheArray=new byte[] {1,2,3,4};
If you want a property that works on a specific array element, then:
- the type should be byte, not byte[], as only one element will be operated upon
- the index must be known somehow (by being fixed, or as a parameter); when a parameter is required it no longer is a property, it becomes a method as in byte GetArrayElementAt(int index) or SetArratElementAt(int index, byte val)
There is a way to use an indexer, however that is not a general solution, as it doesn't have an identifier (it uses "this" to refer to the class), see here[^]; so for an int indexer, you can only do it once on a class (however, you can do another indexer with say a string index).
Luc Pattyn
I only read code that is properly indented, and rendered in a non-proportional font; hint: use PRE tags in forum messages
Local announcement (Antwerp region): Lange Wapper? Neen!
modified on Friday, October 16, 2009 11:55 PM
|
|
|
|
|
And this is why the Design Guidelines for Class Library Developers advice against using array type properties. Normally encapsulation will require that you clone the array before "giving it" to anyone, and since this can be expensive (if the array is large) it is important to signify the fact to the user of the class by providing a method and not a property.
byte[] bytes;
public byte[] GetBytes()
{
return (byte[])bytes.Clone();
}
|
|
|
|
|
Hi,
I am developing a Windows service in C#. I have couple of question on that.
1. Is it possible to set a Start up parameter during installation of the service? I know that I can pass a parameter while calling ServiceController.Start() method. But the service start type is Autometic and I want the service to run everytime with the same parameter.
2. Is it possible to uninstall the service from within. Say if I meet certain criteria in the service work flow, I want to uninstall the service. Is it possible?
Thanks.
|
|
|
|
|
Aryan S wrote: 1. Is it possible to set a Start up parameter during installation of the service? I know that I can pass a parameter while calling ServiceController.Start() method. But the service start type is Autometic and I want the service to run everytime with the same parameter.
Store the parameters in the Registry or in a config file somewhere.
Aryan S wrote: 2. Is it possible to uninstall the service from within. Say if I meet certain criteria in the service work flow, I want to uninstall the service. Is it possible?
I've never heard of a service uninstalling itself. Doesn't mean it's not possible though.
|
|
|
|
|
1) Store it somewhere -- I use a database
2) I doubt it; you can't uninstall a running Service
... but maybe you could Start a Process that will stop and uninstall the Service.
|
|
|
|
|
Hi,
My application has a heavy form (meaning with lots of images etc.) and after I minimize it and then maximize it the form flickers for 2-3 seconds. I've tried to set DoubleBuffered property of my form to true and tried all kinds of SetStyle combinations but nothing helped. Is there anyone out there who has any idea how I can solve this problem or workaround it?
Thanks in advance.
|
|
|
|
|
Hi,
please tell us more.
1. what are the Controls on the Form? how many? UserControls? nested UserControls?
2. what is showing the images? are they overlapping?
3. trying some transparency stuff?
4. what code is in the Resize handler? any Controls docked, or anchored on both ends so they stretch?
Luc Pattyn
I only read code that is properly indented, and rendered in a non-proportional font; hint: use PRE tags in forum messages
Local announcement (Antwerp region): Lange Wapper? Neen!
|
|
|
|
|
Hi,
My form contains 2-3 panels, over 7 pictureboxes, lots of labels and groupboxes, one progressbar and one button. There are no overlapping images but some images have transparent backgrounds. There is no code in resize handler and my form is not resizeable. Form's FormBorderStyle is set to none.
|
|
|
|
|
OK,
so you don't have list stuff (ListBox, ListView, TreeView, DataGridView), that is good.
here are things that help in reducing flicker:
- keep the GUI simple (keep the number of Controls below say 50)
- make sure you have high-performance code in the paint handlers, if any (don't create too many objects,
Pens, Fonts, ...; and if you have those, don't forget to Dispose the ones you created)
- use the Graphics from PaintEventArgs, don't use CreateGraphics
- all the above should result in fast painting
- apply double-buffering, which almost completely hides the painting work
These work against you:
- PictureBoxes (PB is a stupid Control, I prefer to paint images myself, in a Paint handler)
- IIRC: transparancy in general, objects (e.g. Labels) on top of something transparant in particular
this normally helps:
- make the Form double-buffered by inserting this in its constructor:
SetStyle(System.Windows.Forms.ControlStyles.DoubleBuffer,true);
SetStyle(System.Windows.Forms.ControlStyles.AllPaintingInWmPaint,true);
SetStyle(System.Windows.Forms.ControlStyles.UserPaint,true);
(if such code is outside constructor it also needs a Control.UpdateStyles)
- avoid huge images, even when shown in small size (heavy rescale = CPU cycles); maybe calculate the right sized image once and keep it around.
- load the image from disk once (outside all Paint handlers) and keep it as an object.
Luc Pattyn
I only read code that is properly indented, and rendered in a non-proportional font; hint: use PRE tags in forum messages
Local announcement (Antwerp region): Lange Wapper? Neen!
modified on Saturday, October 17, 2009 8:16 AM
|
|
|
|
|
Thank you for your advices. They really helped me and the form. It doesn't have to struggle anymore.
|
|
|
|
|
you're welcome.
Luc Pattyn
I only read code that is properly indented, and rendered in a non-proportional font; hint: use PRE tags in forum messages
Local announcement (Antwerp region): Lange Wapper? Neen!
|
|
|
|
|
Luc Pattyn wrote: if you have those, don't forget to Dispose the ones you created
Hi, What if my app has values need to be passed? does this.Dispose() going to erase them?
Sun
|
|
|
|
|