 |
|
|
 |
|
 |
Hi
I wanted to know if you could tell me of a sureshot way of how to resize the form because when you use image maps you loose a lot of the functionality of the standard windows form.
I want to be able to resize the form with the mouse by dragging on its boarders also a button to resize the form to the maximum window size and then minimize it.
If you can tell me all of this I'd be glad.
|
|
|
|
 |
|
 |
I had tested code like this one (VB 2005/2008) but the GetPixel technique is very slow .. Do you have any recommendations for this ?!
Thanks in advance.
|
|
|
|
 |
|
 |
After I've rolled the bitmaps into a resource file, the program is running faster. Don't know if the former is the cause of the latter. I haven't done any other changes, though.
- Nick
|
|
|
|
 |
|
 |
cannot be found in class 'BitmapRegionTest.Form1'.
when I insert a bitmat other ... it not run and i see message a bout it
help me .
|
|
|
|
 |
|
 |
I have a same problem. I`m using VS 2005. Picture is placed in bin\debug. Anyone can help?
|
|
|
|
 |
|
 |
In no way at all am I trying to put what you did down, but isn't this what XAML and WPF were designed for? So we could get the graphics controls we want without using bitmaps, but vector art? It's a great article, I just think that XAML does away with programatic graphics controls. This would be great for an App that requirements say that it must run on a platform not supported by 3.0.
|
|
|
|
 |
|
 |
First, This article was written in 2004
Second, Not everyone has the time or desire to drop what they're doing and learn wpf and xaml.
This article is exactly what I was looking for.
|
|
|
|
 |
|
 |
using unsafe code is fastest but... For those who prefer managed code. private static GraphicsPath CalculateControlGraphicsPath(Bitmap bitmap) { GraphicsUnit unit = GraphicsUnit.Pixel; RectangleF boundsF = bitmap.GetBounds(ref unit); Rectangle bounds = new Rectangle((int)boundsF.Left, (int)boundsF.Top, (int)boundsF.Width, (int)boundsF.Height); Color transparencyKey = bitmap.GetPixel(0, 0); int key = ((transparencyKey.A << 24) | (transparencyKey.R << 16) | (transparencyKey.G << 8) | (transparencyKey.B << 0)); BitmapData bmpData = bitmap.LockBits(bounds, ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); // Get the address of the first line. IntPtr dataPtr = bmpData.Scan0; // Declare an array to hold the bytes of the bitmap. // This code is specific to a bitmap with 32 bits per pixels. int yMax = (int)boundsF.Height; int xMax = (int)boundsF.Width; int stride = bmpData.Stride / 4; int words = xMax * yMax; int[] rgbValues = new int[words]; // Copy the RGB values into the array. System.Runtime.InteropServices.Marshal.Copy(dataPtr, rgbValues, 0, words); // Unlock the bits. bitmap.UnlockBits(bmpData); GraphicsPath path = new GraphicsPath(); for (int j = 0; j < yMax; j++) for (int i = 0; i < xMax; i++) { if (rgbValues[(stride * j) + i] == key) continue; int x0 = i; while ((i < xMax) && (rgbValues[(stride * j) + i] != key)) i++; path.AddRectangle(new Rectangle(x0, j, i - x0, 1)); } return path; }
|
|
|
|
 |
|
 |
Another (small) optimization is to move the (stride * j) calc out of the inner loop - multiplies, while not being as expensive as divides, still cost...
for (int j = 0; j < yMax; j++)
{
strideXj = (stride * j);
for (int i = 0; i < xMax; i++)
{
if (rgbValues[strideXj + i] == key)
continue;
int x0 = i;
while ((i < xMax) && (rgbValues[strideXj + i] != key))
i++;
path.AddRectangle(new Rectangle(x0, j, i - x0, 1));
}
}
|
|
|
|
 |
|
 |
apologies for the second post, but on second thought, you could get rid of that multiply altogether by the initializing strideXj before both of the 'for' loops
int strideXj = 0;
and then at the bottom of the inner loop, add the following:
strideXj += stride;
|
|
|
|
 |
|
|
 |
|
 |
Hello! I want to know if a mouse button is held down when it enters on a certain control. Can anybody please help me?
|
|
|
|
 |
|
 |
Since the form now doesn't have a title bar, we need to make it such that the user is able to left click anywhere in the form and drag it. The solution used for the MFC version is to handle WM_LBUTTONDOWN and doing a PostMessage(WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM(point.x,point.y)) to fool windows into thinking that we clicked on the caption.
Not good - better way is to handle the WM_NCHITTEST message and return HTCAPTION!
|
|
|
|
 |
|
 |
Add this to the form...
protected override void WndProc(ref Message m)
{
// Let the base class have first crack
base.WndProc(ref m);
int WM_NCHITTEST = 0x84; // winuser.h
if(m.Msg != WM_NCHITTEST) return;
// If the user clicked on the client
// ask the OS to treat it as a click on the caption
int HTCLIENT = 1;
int HTCAPTION = 2;
if (m.Result.ToInt32() == HTCLIENT)
{
m.Result = (IntPtr) HTCAPTION;
}
}
|
|
|
|
 |
|
 |
it's Very nice work ..., Exciting,
just i have some little points ,
1) it dosent work perfict in VS2005 ,
like the "Hi, I'm pop "bubble it flash then disable part ..
while the action on your demo set it visable until next click,
2) while draging over the form .., the mouse moves from it's orgenal place on the form where i started to drag ..,
lets say i want to mouse down on the Middle of the form then drag righ and left ... then see the mouse and the form .. i see the mouse on the far right on the screen and the form in the far left
3)while lettle drag .. the processor usage increase very fast,
4) while drage it always flicker the screen , it seems it re drow all the screen again ...,
welcome for any comments , Questions
|
|
|
|
 |
|
 |
But I think that you make some things a little more difficult then they are.
And the mouse movment routine is not the best... This is a small example how I would do it.
//Definition
private Point m_diff;
private void Form1_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
{
//Check if left button is pressed
if ((MouseButtons & MouseButtons.Left) == MouseButtons.Left)
{
if (toBlock)
{
this.Location = new Point(MousePosition.X - m_diff.X, MousePosition.Y - m_diff.Y);
toBlock = false;
}
else
toBlock = true;
}
}
private void Form1_MouseDown(object sender, MouseEventArgs e)
{
// Set how far from the top, left corner the mouse was pressed
m_diff.X = e.X;
m_diff.Y = e.Y;
}
|
|
|
|
 |
|
 |
This application of region was very useful for me.
The Windows 2000 issue also appeared: there is an offset between the picture and the mask, due to a different size of the form borders in XP vs 2000.
The solution brought by jirong zhou didn't work for me, as the program crashed under W2000 just by adding Region.Translate
So I prefer to calculate the mask including the translation and apply it without the Translate method:
1. add these lines of code at the beginning of the CalculateControlGraphicsPath method:
// Gets variables about the Windows version
int OSOffsetY=0;
int OSOffsetX=0;
OperatingSystem os = Environment.OSVersion;
Version vs = os.Version;
string platform = os.Platform.ToString();
int majorVer = vs.Major;
int minorVer = vs.Minor;
// If Windows 2000 is currently running, then
if((platform=="Win32NT")&&(majorVer==5)&&(minorVer==0))
{
OSOffsetY=SystemInformation.CaptionHeight+3;
OSOffsetX=SystemInformation.FrameBorderSize.Width-1;
}
2. replace the original graphicsPath.AddRectangle(...) by:
graphicsPath.AddRectangle(new Rectangle(colOpaquePixel+OSOffsetX,row+OSOffsetY,colNext-colOpaquePixel,1));
I runned it under XP, W2000 SP4 station and W2000 server and it works fine.
JM BOUZARD
Health Care Software Developer
|
|
|
|
 |
|
 |
THANKS ALOT THIS REALY SOLVE MY ISSUE
Mubi
|
|
|
|
 |
|
 |
Hi.
After I added your code, the bitmap is still shifting on Win2k, XP is alright.
And it messed up the bitmap.
The code affects both FORM and BUTTON, right?
I don't know what is wrong.
|
|
|
|
 |
|
 |
I really liked the idea but it was a little slow when you resize a form and the function had to re-do the form region. I was wonder why you did not use scanlines to do this, and I had never used scanlines in C#. It is a little different to what I was used to in C++ but it gets the job done.
I thought this might help someone, This site has helped me alot...
If any one finds a better (faster) way of doing this please let me know.
//==========================================================================
private static GraphicsPath QuickCalculateGraphicsPath(Bitmap bitmap, Color TransparentColor)
{
GraphicsPath graphicsPath = new GraphicsPath();
int StartRegionArea = -1;
Color PixelColor = Color.Empty;
BitmapData bData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
IntPtr ScanL = bData.Scan0;
int YOffset = bData.Stride - bitmap.Width * 3;
unsafe
{
byte* p = (byte*)(void*)ScanL;
for (int y = 0; y <= bitmap.Height-1; y++)
{
for (int x = 0; x <= bitmap.Width-1; x++)
{
int B = (int)p[0];
int G = (int)p[1];
int R = (int)p[2];
PixelColor = Color.FromArgb(R, G, B);
if (PixelColor == TransparentColor && StartRegionArea != -1)
{
graphicsPath.AddRectangle(new Rectangle(StartRegionArea, y, (x - 1) - StartRegionArea, 1));
StartRegionArea = -1;
}
if (PixelColor != TransparentColor && StartRegionArea == -1)
{
StartRegionArea = x;
}
p += 3;
}
if (StartRegionArea != -1)
{
graphicsPath.AddRectangle(new Rectangle(StartRegionArea, y, bitmap.Width - StartRegionArea, 1));
StartRegionArea = -1;
}
p += YOffset;
}
}
bitmap.UnlockBits(bData);
return graphicsPath;
}
//==========================================================================
|
|
|
|
 |
|
 |
Want optimization??? Try this!!
u had:
for (int y = 0; y <= bitmap.Height-1; y++)
{
...
}
replace with:
int width = bitmap.Width;
int height = bitmap.Height;
unsafe
{
...
for (int y = 0; y <= height-1; y++)
{
...
}
...
}
Your code took 10 sec to process my image. Now it's done in real time!!
Also, if the bitmap is only B&W (most common use), you can optimize the code, in the color comparison.
|
|
|
|
 |
|
 |
whoa, it really speeds up a lot, this tweak is worth a try, thanks
|
|
|
|
 |
|
 |
nice one, but a little error in:
replace:
if (PixelColor == TransparentColor && StartRegionArea != -1)
{
graphicsPath.AddRectangle(new Rectangle(StartRegionArea, y, (x - 1) - StartRegionArea, 1));
StartRegionArea = -1;
}
with that one:
if (PixelColor == TransparentColor && StartRegionArea != -1)
{
graphicsPath.AddRectangle(new Rectangle(StartRegionArea, y, x - StartRegionArea, 1));
StartRegionArea = -1;
}
got it? no? (have a look at (x - 1) - StartRegionArea... the (x - 1) removes too much from region color heh
So, now it works perfectly... Bye
FreewareFire is in the House!
|
|
|
|
 |
|
 |
There is a subtle bug in here - the Form looks fine until it is dragged (or anything that triggers a redraw)!
The problem is that the "see-through" parts of the Form are actually being built as part of the Forms' region so they are in effect persisted (leaving a corrupt graphic - visible when the Form is redrawn).
To fix it, change the line:
PixelColor = Color.FromArgb(R, G, B);
to
PixelColor = Color.FromArgb(0, R, G, B);
If this isn't done, then the subsequent comparisons against the TransparentColour will never be correct and so the GraphicsPath is always going to be the same!
To save further confusion, I will stand on the shoulders of the predecessing giants and re-post the GraphicsPath function, complete with unsafe modifications:
private static GraphicsPath CalculateControlGraphicsPath(Bitmap bitmap)
{
Color TransparentColour = bitmap.GetPixel(0, 0);
GraphicsPath graphicsPath = new GraphicsPath();
int StartRegionArea = -1;
Color PixelColor = Color.Empty;
BitmapData bData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
IntPtr ScanL = bData.Scan0;
int YOffset = bData.Stride - bitmap.Width * 3;
int lBitmapHeight = bitmap.Height;
int lBitmapWidth = bitmap.Width;
unsafe
{
byte* p = (byte*)(void*)ScanL;
for (int y = 0; y <= lBitmapHeight-1; y++)
{
for (int x = 0; x <= lBitmapWidth-1; x++)
{
int B = (int)p[0];
int G = (int)p[1];
int R = (int)p[2];
PixelColor = Color.FromArgb(0, R, G, B);
if (PixelColor == TransparentColour && StartRegionArea != -1)
{
graphicsPath.AddRectangle(new Rectangle(StartRegionArea, y, x - StartRegionArea, 1));
StartRegionArea = -1;
}
if (PixelColor != TransparentColour && StartRegionArea == -1)
{
StartRegionArea = x;
}
p += 3;
}
if (StartRegionArea != -1)
{
graphicsPath.AddRectangle(new Rectangle(StartRegionArea, y, lBitmapWidth - StartRegionArea, 1));
StartRegionArea = -1;
}
p += YOffset;
}
}
bitmap.UnlockBits(bData);
return graphicsPath;
}
Hope this helps
Gee
|
|
|
|
 |