|
LynnSong wrote:
It seems that GDI+ hasn't packaged the windows API all around,
GDI+ is not a GDI wrapper, it is a whole new implementation.
LynnSong wrote:
It seems that GDI+ donnot have a XOR operation to use, can I call GDI's XOR op?
GDI+ does not have one. You can call GDI's version by doing
hdc=Graphics.GetHDC();
Graphics.ReleaseHDC();
LynnSong wrote:
I want to realize a eraser tool, it could set pixels on the bitmap buffer to transparent.
Do you mean actually transparent, or do you want to make the area erased revert back to the original bitmap?
If you mean actually transparent, you will have to modify the Alpha channel of the bitmap.
If you mean revert to the original, then you can keep a copy of the original version of the bitmap and copy pixels from the original to the new version wherever the eraser is used.
But for either of these, you cannot really depend on the GDI+ brush class. You will have to modify the pixels by your own code.
If you want to just erase to the background color, just use a brush of the same color as the background (you likely knew this already ).
"Do unto others as you would have them do unto you." - Jesus
"An eye for an eye only makes the whole world blind." - Mahatma Gandhi
|
|
|
|
|
Actually there are two way of eraser I want to use,
One implement of eraser is used in a tool called selector, it select a rectangle or ellipse region of the view to give a clip region of the drawing. The user could drag out a rectagle or ellipse frame from a point, so I should 'erase' the former rectagle/ellipse repeatly. This could be worked out using XOR command .There is a example in 'C# Windows Programming', but the auther just said there is no XOR operation in GDI+, he use background color to 'erase' the former rectangle. But he didn't give a method using XOR.
the other implement of eraser is a true rubber for drawing. I have mentioned it in last reply. I want to make the points on bitmap operated by eraser to be totally transparent. Could it be done by Bitmap.SetPixel() method? or I should use the BitBlt to set the pixel to be transparent?
|
|
|
|
|
LynnSong wrote:
So after MouseUp state, the whole 'free line' has a quite ugly look, while what I want is a free line with sigle alpha value so it will has a clear and correct look.
One thing you can do is to not draw on the layer bitmap until you get a mouseup event, so what you would do is have a collection of points representing each part of the mousemove event, in your OnPaint method you draw the layers behind and including the current layer, then you draw your lines with alpha blending (using the DrawLines method), then draw the layers on top of the current layer.
Once you get the MouseUp event then you can draw your lines onto the bitmap for that layer.
LynnSong wrote:
I want to realize a eraser tool, it could set pixels on the bitmap buffer to transparent.
This is a bit more difficult to handle because you need to allow all colors, but yet one particular color needs to be made transparent. Perhaps someone else can offer a suggestion for how you would go about that.
The eraser tool is basically going to do a FillRectangle with the color that represents the transparent color used in the SolidBrush.
James
"It is self repeating, of unknown pattern"
Data - Star Trek: The Next Generation
|
|
|
|
|
James T. Johnson wrote:
One thing you can do is to not draw on the layer bitmap until you get a mouseup event, so what you would do is have a collection of points representing each part of the mousemove event, in your OnPaint method you draw the layers behind and including the current layer, then you draw your lines with alpha blending (using the DrawLines method), then draw the layers on top of the current layer.
This would make it look nice, but I wouldn't use a program that did it this way, because I like to see the line I'm drawing. I'm writing a paint app that allows for transparent lines. I'm going to "re-invent the wheel" and do the line-drawing myself. This way, I can have a hash-table that tells me which pixels have already been modified, so that they aren't re-drawn-on. This eliminates the problems of varying levels of transparency that make the line look wierd.
"Do unto others as you would have them do unto you." - Jesus
"An eye for an eye only makes the whole world blind." - Mahatma Gandhi
|
|
|
|
|
jdunlap wrote:
This would make it look nice, but I wouldn't use a program that did it this way, because I like to see the line I'm drawing.
You would still see the line because it is getting drawn, but it is being drawn straight to the screen rather than modifying that layer's bitmap. Once you get the MouseUp event then you modify that layer's bitmap.
James
"It is self repeating, of unknown pattern"
Data - Star Trek: The Next Generation
|
|
|
|
|
I see. If you don't want to do the whole implementation yourself, that would be the way to go. Although you would still see the messy line until you lift your mouse.
"Do unto others as you would have them do unto you." - Jesus
"An eye for an eye only makes the whole world blind." - Mahatma Gandhi
|
|
|
|
|
But draw on screen first in every Mousedown-mouseMove-mouseUp bout cannot satisfy the multi-layer effect,
that is draw on low layer will be covered partly by upper layer's strokes. I am now implementin that by update the buffer bitmap every OnMouseMove calls.
|
|
|
|
|
LynnSong wrote:
I am now implementin that by update the buffer bitmap every onmousemove calls.
How I would set it up requires that you maintain a Bitmap for each layer of the image.
Then you also need a collection of Point (or PointF) which represents the location of the mouse each time MouseMove is called.
Maybe some (psuedo) code will explain it better?
The code is uncompiled and thus untested but the premise is there.
private BitmapCollection layers;
private int currentLayer;
private Size size;
private PointCollection points;
private Pen currentPen;
OnMouseDown(MouseEventArgs e)
{
if( 0 != (e.Button & MouseButtons.Left) )
{
points.Clear();
points.Add( new Point(e.X, e.Y) );
Rectangle rectToInvalidate = new Rectangle(
e.X - (int) currentPen.Width, e.Y - (int) currentPen.Width,
((int) currentPen.Width) * 2, ((int) currentPen.Width) * 2
);
Invalidate( rectToInvalidate );
}
}
OnMouseMove( MouseEventArgs e )
{
if( 0 != (e.Button & MouseButtons.Left) )
{
Point newPoint = new Point(e.X, e.Y);
points.Add( newPoint );
Rectangle rectToInvalidate = RectFromTwoPoints(
newPoint, points[points.Count - 2], (int) currentPen.Width);
Invalidate( rectToInvalidate );
}
}
OnMouseUp( MouseEventArgs e )
{
if( 0 != (e.Button & MouseButtons.Left) )
{
using(Graphics g = Graphics.FromBitmap( layers[currentLayer] );
{
Point [] pointsArray = points.ToArray(typeof(Point[]));
g.DrawLines( currentPen, pointsArray );
points.Clear();
}
}
}
OnPaint( PaintEventArgs e )
{
for(int = 0; i < layers.Count; i++ )
{
if( i == currentLayer && points.Count > 0 )
{
Point [] pointsArray = points.ToArray(typeof(Point[]));
g.DrawLines( currentPen, pointsArray );
}
}
}
Rectangle RectFromTwoPoints( Point p1, Point p2, int penWidth )
{
int left, top, right, bottom;
if( p1.X < p2.X )
{
left = p1.X;
right = p2.X;
}
else if( p1.X > p2.X )
{
left = p2.X;
right = p1.X;
}
else
{
left = right = p1.X;
}
if( p1.Y < p2.Y )
{
top = p1.Y;
bottom = p2.Y;
}
else if( p1.Y > p2.Y )
{
top = p2.Y;
bottom = p1.Y;
}
else
{
top = bottom = p1.Y;
}
top -= penWidth;
left -= penWidth;
right += penWidth;
bottom += penWidth;
return Rectangle.FromLTRB( left, top, right, bottom );
} Sheesh, I do all that and I see that MSDN has a similar example, only one 'layer' but it shows you how you can draw the lines using a GraphicsPath object. You can find the example in the help topic for the Control.MouseDown event (it is probably copied for the other Mouse events too).
James
"It is self repeating, of unknown pattern"
Data - Star Trek: The Next Generation
|
|
|
|
|
I have several assemblies that have been registered for COM Interop but have not been installed into the GAC. There are all installed side-by-side in my application directory. One of the assemblies is a Windows Service exe. Things have been working fine but occasionally the service fails to start. I was wondering if this was due to the long startup time caused by the JIT compliation. I have now tried using Ngen to pre-compile all the assemblies. I see that they now appear in the GAC and have a cache type of ZAP? My question is - can I tell programmically if I'm using the native images I've just created? If not, can I verify that application is using the native images? How does the runtime find the native images? Especially the service which is configured to point at the original exe?
|
|
|
|
|
solidstore wrote:
I was wondering if this was due to the long startup time caused by the JIT compliation
May be.
solidstore wrote:
have now tried using Ngen to pre-compile all the assemblies
You have pre-jitted one or more assemblies so the resulting images are stored in the GAC for future reference. Without pre-jit, assemblies are jitted on-the-fly in memory.
solidstore wrote:
My question is - can I tell programmically if I'm using the native images I've just created?
This question sounds weird. You are always using native images, whether they are from the GAC, or from in-memory jitted images.
What's more interesting to the issue is what is the relationship between an assembly in a private folder referrenced by a main assembly, with the same assembly stored in the GAC : in other words, which assembly is used ? The answer is it has a lot to do with versioning rules and strong names.
My recommendation is to read Jeffrey Richter's "Applied .NET framework programming" book. It's all there.
|
|
|
|
|
Hi,
I was wondering if it is possible to program a low level network application in .net. I mean I want to choose the network interface that handles the packets sent from my app, I want to get every IP packet that passes thru my computer, and so on...
Can anyone give me any pointers?
Thanks a lot,
Andrei Matei
andreimatei@home.ro
|
|
|
|
|
I'm pretty sure there was an article posted on CodeProject doing something similar to what you want. Bascially the code resembled a packet sniffer applied on a particular interface. The article is here http://www.codeproject.com/csharp/networkmonitor.asp?target=network%7Cpacket[^]
There are actually a few articles here on CodeProject. Do an article search on network packet.
Hope this helps.
Andy
He who knows and knows that he knows, is wise; follow him
He who knows and knows not that he knows, is asleep; wake him
He who knows not, and knows that he knows not, is simple; teach him
He whoe knows not and knows not that he knows not, is a fool; kick him
|
|
|
|
|
Hi all,
I create a worker thread to do some stuff, when that thread completes I would like to make a call from that thread to main thread to tell it to take a new course of action.
In a windows forms environment you can call:
this.Invoke
but what if your developing an assembly or console app , is there an equivalent. I've tried using delegates etc but when you look at the
Threading.Thread.CurrentThread.Name property your still 'in' the worker thread.
Anyone know about this.
TIA.
|
|
|
|
|
Are you trying to make sure that after something happens in your worker thread that a method is executed within the context of the main thread, or are you just trying to signal the main thread from your worker thread.
Probably the easiest way would be to pass a waithandle to your worker thread and get your main thread to wait on the handle (or check it regularly) for the handle to be signaled and then go from there. But if thats the case then you might as well recode the worker thread as an asynchronous method call.
The above may not be to your liking Looking at the Mono project, the way they have implemented System.Windows.Forms.Control.Invoke() is place the delegate passed ot Invoke() in a queue. This queue is then checked in the windows message loop (which executes in the same thread as the control was created in), and any delegates in the queue are then called.
So you could create a synchronized queue, get your worker thread to place a delegate in this queue, and then either get your main thread to periodically check this queue or signal a waithandle, and then get the main thread to execute the delegates in the queue.
|
|
|
|
|
Hi Andy,
I was looking to actually call a method on the main thread in the same way as Control.Invoke() 'marshals' the call to the main thread in a windows form.
Your suggestions of passing a waithandle to the worker thread or using an asynchronous method call sound good and I will certainly look into them ( especially the async call, that hadn't occured to me at all )
Your description of how Mono works is very interesting and I imagine that microsoft do it in a similar way or at least thats how it appears to work. But it does seem to be a bit tricky for my feable brain and right now I need a quick and dirty solution.
Thank you very much for help, it was very useful to me.
|
|
|
|
|
I am having the same problem.
I am calling the FileWatcher component in the .NET framework from a server (middleware) class. If I place this on a form, I'm set, I just hand the FileWatcher class a reference to my form. The file watcher class then calls the form's Invoke method.
However I don't have a form, so am forced to implement the ISynchronizeInvoke interface myself.
Your suggestion to go look at the mono project seems like a good start. Can you tell me where to find this project?
My solution so far is to implement ISnychronizeInvoke and to create an delegate instance that will be executed when the callback is executed.
1. I register a call back.
2. The call back is executed. The sender is the operating system.
3. I then execute a delegate that I instantiated on the "target" thread.
David Minor
Applications Programmer
NC State Archives
|
|
|
|
|
|
Will my C# .Net programs work on other opperating system? Like OSX?
/\ |_ E X E GG
|
|
|
|
|
Visual Studio .NET only creates Windows apps, but there is a cross-platform, open-source version of .NET called Mono. You can use SharpDevelop[^] which can create Mono apps. SharpDevelop currently does not have many of the features of VS .NET, but it is being steadily improved, and it is FREE. You cannot currently run SharpDevelop on any OS but Windows, but I believe next version (0.95) will allow you to do this. You cannot build windows forms apps that are cross-platform yet, because System.Windows.Forms cannot be ported to other platforms.
"Do unto others as you would have them do unto you." - Jesus
"An eye for an eye only makes the whole world blind." - Mahatma Gandhi
|
|
|
|
|
As long as theres a clr on that operating system it will work. Take that with a pinch of salt though cos who knows what features etc will be supported on that version of the clr.
Mircosoft have made one called rotor that runs on
'Windows XP, the FreeBSD operating system, and Mac OS X 10.2'
here[^]
Also someones doing it for linux, mono.
mono[^]
Which looks cool.
I have no experience with either of these implementations but I'll bet your in for some headaches trying to get your code to run on them as they seem to still be in development.
Hope this helps.
|
|
|
|
|
I am creating a "Visual Studio .NET" deployment project to install some component assemblies.
I would like that the setup program make the assemblies appear in the Visual Studio .NET "Customize Toolbox" dialog box.
|
|
|
|
|
In your deployment project for you "developer" version, create a new registry key under HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\AssemblyFolders. Use a unique string for the key name. The Default value should point to the directory where your assembly is located.
You'll need two copies of your assembly, one in the GAC, and one in a normal directory.
Hope that helps.
Burt Harris
|
|
|
|
|
I've been using Visual Studio 7.0 to develop a C# application for a while. Today, I downloaded and installed the .NET 1.1 framework and SDK. But I can't figure out how to get Visual Studio to start using the new version of the SDK. If I rebuild my project and run, it's still using .NET 1.0... you can see this in the output:
'DefaultDomain': Loaded 'c:\winnt\microsoft.net\framework\v1.0.3705\mscorlib.dll', ...
...
How do I get Visual Studio to start using the new version?
Part of my problem may be that I didn't install Visual Studio in its default location. I put Visual Studio in one place, but I installed the new SDK in the default place (i.e., Program Files).
I hope that I don't have to buy another copy of Visual Studio just to use the new SDK
|
|
|
|
|
I hope that I don't have to buy another copy of Visual Studio just to use the new SDK
I know you may not want to but you can upgrade to VS 2003 just for a "cost-of-materials" price, i.e., about $30.
However, there should be a way to do what you want but I've no idea how!
Kevin
|
|
|
|
|
Not if you're an academic
|
|
|
|
|