|
Hello!
How can I write shell extensions with C#? (more specifically: context menu items in explorer)
I'm looking for a nice tutorial like Michael Dunn's excellent article for MFC/C++[^], but using C#. I want to do some real shell programming, not just registry hacks[^]...
Thanks in advance and best regards
|
|
|
|
|
It depends which parts of the shell you want to extend, icon handlers and overlays are fairly simple while context menu extensions are rather more tricky. It all requires a reasonable amount of com and win32api interop and some fairly defensive programming to prevent errors reaching and crashing the shell if they occur. Some things like property sheets really aren't possible in fully managed code though that may change when the 2.0 CLR is released.
|
|
|
|
|
I use a panel draw images using graphics.DrawImage(image,x,y,imagewidth,imageheight). This method is called in a foreach loop so that i can fill the panel with different images.Each time panel is refreshed the entire loop executed so that more flickering on the panel.Is there any way to paint a region of a control?
please help!
|
|
|
|
|
For a simpler fix consider using double buffering. In the contorl ctor or somewhere else add this:
SetStyle(ControlStyles.DoubleBuffer, true);
A few other options there that you can mess with.
Alex Korchemniy
|
|
|
|
|
i 've used it, but itdoesn't make any big difference
thanx for ur reply
|
|
|
|
|
Although I'm not exactly sure what you are tyring to do... you can try using your own buffer by using an Image .
Alex Korchemniy
|
|
|
|
|
In case, you are using Invalidate method to refresh the Panel, then instead of using plain Invalidate method, use the following overload of this method, which will refresh a particular rectangular area only:
public void Invalidate(Rectangle rc);
Or, if possible, try to use some bool or other appropriate variable (defined outside the loop but used inside the loop) to somehow check as to in which circumstances and in what rectangular area, the Panel should be refreshed.
If you give details of the method or the manner in which you are refreshing the Panel, it may be possible to give some specific suggestion.
|
|
|
|
|
private void Panel_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
{
Graphics g = e.Graphics;
if(myImageArray.Count > 0)
{
foreach (ImageClass myObject in myImageArray)
{
g.DrawImage((Bitmap)myObject.Image,myObject.TopX,myObject.TopY);
}
}
}
this is the code I used in Paint event of Panel
where "ImageClass" contain a bitmap object and its co codinates on the Panel.
"myImageArray" is an ArrayList of type "ImageClass".Each time I click on the panel,a constructor is created with image and Panel's (x,y) co ordinates and its added to myImageArray.
then refresh the Panel.
|
|
|
|
|
You'll want to use the Control's Invalidate(Rectangle rc) method (see MSDN[^])
panel.Invalidate(new Rectangle(0, 0, 100, 100));
Then when you paint the panel you only paint an image if its bounding rectangle intersects with the clip rectangle
protected override void OnPaint(PaintEventArgs e)<br />
{<br />
Rectange imageRect = new Rectangle(imageX, imageY, imageWidth, imageHeight);<br />
<br />
if (imageRect.IntersectsWith(e.ClipRectangle))<br />
{<br />
e.Graphics.DrawImage(image, imageRect);<br />
}<br />
}
"I think I speak on behalf of everyone here when I say huh?" - Buffy
|
|
|
|
|
I want that control (Label, TextBox) with property Enabled = false don't change it ForeColor to grey.
For example I have a UserControl with TextBox or Label on it. I can change TextBox property BackColor very easy:
private void UserControl1_EnabledChanged(object sender, System.EventArgs e)<br />
{<br />
if(this.Enabled)<br />
{<br />
}<br />
else<br />
{<br />
this.TextBox1.BackColor = System.Drawing.Color.White;<br />
}<br />
}
But I can't change TextBox(Label) property ForeColor!
private void UserControl1_EnabledChanged(object sender, System.EventArgs e)<br />
{<br />
if(this.Enabled)<br />
{<br />
this.BackColor = System.Drawing.Color.White;<br />
}<br />
else<br />
{<br />
this.textBox1.BackColor = System.Drawing.Color.White;<br />
this.textBox1.ForeColor = System.Drawing.Color.Black;<br />
<br />
this.Label1.ForeColor = System.Drawing.Color.Black;<br />
}<br />
}
This code can't do this!
If I make MyLabel by inheritance of Label and overide OnEnabledChanged(...), this will not help too:
protected override void OnEnabledChanged(EventArgs e)<br />
{<br />
}
If I put MyLabel on UserControl1 and then change Enable property of UserControl1 to false, the ForeColor property of MyLabel will not change!
But when I deactivate form with this control and then activate it, text of MyLabel will be grey.
Please, help!
|
|
|
|
|
In my humble opinion it is not wise to change the way disabled controls appear to the user. It can confuse people.
If you look into the Label implementation you will see that the disabled appearance of is hardcoded in. You cannot do anything about how a disabled Label looks.
However, if you really need to change something... create your own label implementation.
Alex Korchemniy
|
|
|
|
|
Some people have problems with monocrome LCD screens, where the text in textBoxes are almost invisible when they have Enabled set to false.
So actually it would be nice to be able to change that color...
Just a point of view.
I'm in the high-fidelity first class traveling set.
And I think I need a Lear jet.
|
|
|
|
|
where i can download the msdn in spanish
|
|
|
|
|
|
Hello everyone,
I have a question on garbage collection that you guys will probably be able to answer in a snap. Here goes...
If I do this...
<br />
public void DoSomethingHere()<br />
{<br />
MyCustomClass mcc = new MyCustomClass();<br />
mcc.PerformFunction();<br />
<br />
mcc = new MyCustomClass();<br />
mcc.PerformAnotherFunction();<br />
}<br />
As you'll see above, mcc has performed a new twice. I'm just curious as to what happens to the memory from the first "new". Will the garbage collector know about it and clean it up later on, or is this considered a memory leak which will just sit in limbo?
Thanks,
~Brad
|
|
|
|
|
The garbage collector will pick it up - anything non-static that nobody has a reference to will be picked up.
|
|
|
|
|
Thank you.
|
|
|
|
|
GC will handle it because the first object will no longer be referenced. However be careful with objects that have resources that need to be released.
This makes a big mess:
Bitmap b = new Bitmap(100, 100);<br />
for(int i = 0 ; i < 1000; i++)<br />
{<br />
b = new Bitmap(100, 100);<br />
}
This is correct:
Bitmap b = new Bitmap(100, 100);<br />
for(int i = 0 ; i < 1000; i++)<br />
{<br />
b.Dispose();<br />
b = new Bitmap(100, 100);<br />
}
Alex Korchemniy
|
|
|
|
|
|
how to fit the height of more than one labels at same time in a main form if the labels textlines increes their height while the form width its changing plz helpme with this issue
|
|
|
|
|
If I understand you correctly... you are trying to achieve flow layout.
If all you have on the form is a few labels it would be better to do custom drawing code. For each string you draw you do MeasureString . Using the SizeF that is returned you can calculate where to draw the next string.
Alex Korchemniy
|
|
|
|
|
hi alex thanks by the form isuue but this one i dont understand so much can u explainme better
the labels are putted on runtime not on desingtime and their dock property are setit to top
|
|
|
|
|
Do away with labels completely. I'm assuming that you have no other controls in the way to worry about. Instead handle the Paint event for the form. Inside the paint event "draw" the strings that you have. For each string you draw you keep a record of the location. You can also add padding if necessary. Also make sure that everything is redrawed when resize occurs.
Off the top of my head and not tested:
Graphics g = e.Graphics;<br />
int currentY = 0;<br />
foreach(string s in myStringArray)<br />
{<br />
SizeF sz = g.MeasureString(s, this.Font, this.Width);<br />
g.DrawString(s, this.Font, Brushes.Black, new Rectangle(0, currentY, (int)sz.Width, (int)sz.Height));<br />
currentY += (int)sz.Height;<br />
currentY += 10;
}
Alex Korchemniy
|
|
|
|
|
How to minimize a main form while the closing event with out dispose or close the form;
|
|
|
|
|
Handle the Closing event. In the event set the Visible to false. To prevent the Form from closing in the CancelEventArgs that you get with the event handler set Cancel to true.
See: MSDN docs[^]
Alex Korchemniy
|
|
|
|