|
I wrote already some days ago to ask a question: here follows the topic.
"In my application I create some bottons in a form; some of them receive an image to be set as their backgroundImage. When this is done and the mouse hovers on the control I start a timer: I want the program to do something when the -let's say- 5th timer tick occurs, but in the meanwhile I want the image to increase its pixels' alpha value a bit each tick.
How to control the alpha value of an image I load from a file and display it as a backgroundImage on a button?"
KaptinKrunch kindly suggested me a link to have a look to:
http://www.c-sharpcorner.com/UploadFile/mahesh/DrawTransparentImageUsingAB10102005010514AM/DrawTransparentImageUsingAB.aspx
Well, I checked that code, and at some more documentation..and tried that on a small test project, to load a bitmap on a pictureBox, and modify its alpha channel as much as a trackBar in the same form is scrolled, from 0 to 1.
The problem is that: once I have create the Graphics object, loaded with my image, and modified it, I can't reconvert it as a Bitmap object, in such a way to be able to set it as the Image property of the PictureBox of the Form.
Notice this is just a small piece of code to try the thing: actually, in my application, I have to load the bipmap as the BackgroundImage property of a Button, but I don't think this changes a lot..
Thanx for any extra help, sorry for my English..
Here down is listed the code I can't fix:
public partial class Form1 : Form
{
private string sourceFileName;
private string destFileName, proposedDestFile;
private Bitmap image, newImage;
private int modifiedImagesCounter;
ColorMatrix colorMatrix;
ImageAttributes imageAtt;
Graphics g;
public Form1()
{
InitializeComponent();
float[][] matrixItems = {
new float[] {1, 0, 0, 0, 0},
new float[] {0, 1, 0, 0, 0},
new float[] {0, 0, 1, 0, 0},
new float[] {0, 0, 0, 1, 0},
new float[] {0, 0, 0, 0, 1}};
colorMatrix = new ColorMatrix(matrixItems);
imageAtt = new ImageAttributes();
imageAtt.SetColorMatrix(colorMatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);
}
private void loadImageButton_Click(object sender, EventArgs e)
{
openFileDialog.ShowDialog(Parent);
sourceFileName = openFileDialog.FileName;
image = new Bitmap(sourceFileName);
Console.WriteLine("The file to modify is: " + sourceFileName);
//IndexedToARGB_Converter conv = new IndexedToARGB_Converter(sourceFile);
//Bitmap modifiedImage = conv.getNewImage();
pictureBox.Image = image;
}
private void saveImageButton_Click(object sender, EventArgs e)
{
proposedDestFile = DestFileName();
saveFileDialog.FileName = proposedDestFile;
saveFileDialog.ShowDialog(Parent);
destFileName = saveFileDialog.FileName;
Console.WriteLine("The modified file will be saved to: " + destFileName);
newImage.Save(destFileName);
}
private string DestFileName()
{
modifiedImagesCounter++;
StringBuilder strbld = new StringBuilder();
strbld.Append(sourceFileName, 0, sourceFileName.Length - 4);
strbld.Append(modifiedImagesCounter.ToString());
strbld.Append(".GIF");
return strbld.ToString();
}
private void trackBar_Scroll(object sender, EventArgs e)
{
g = pictureBox.CreateGraphics();
//Graphics g = Graphics.FromImage(image);
TrackBar trackBar = (TrackBar)sender;
float f = (float)(trackBar.Maximum - trackBar.Value) / (float)(trackBar.Maximum - trackBar.Minimum);
colorMatrix[3, 3] = f;
int iWidth = image.Width;
int iHeight = image.Height;
Rectangle rect = new Rectangle(pictureBox.Location.X, pictureBox.Location.Y, iWidth, iHeight);
g.DrawImage(
image,
rect, // destination rectangle
0.0f, // source rectangle x
0.0f, // source rectangle y
iWidth, // source rectangle width
iHeight, // source rectangle height
GraphicsUnit.Pixel,
imageAtt);
this.Update();
}
}
|
|
|
|
|
Here is a little method that I think will do what you desire. It requires unsafe code, but will probably be extremely fast:
private static Bitmap ChangeImageAlpha(Bitmap bmp, float newAlpha) {
Bitmap rval = new Bitmap(bmp);
BitmapData bmpData = rval.LockBits(new Rectangle(0, 0, rval.Width, rval
.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
try {
unsafe {
byte* bmpPtr = (byte*)bmpData.Scan0.ToPointer();
byte* last = bmpPtr + (bmp.Height * bmp.Width << 2);
do {
float a = (*bmpPtr) * newAlpha;
*bmpPtr = (byte)Math.Max(Math.Min(a, byte.MaxValue), byte.MinValue);
bmpPtr += 4;
} while (bmpPtr < last);
}
return rval;
} catch {
return null;
} finally {
bmp.UnlockBits(bmpData);
}
} I have not tested this code, so I don't know if it actually works or not. Things to check:
1: The constructor used to create rval actually copies the image data
2: The alpha channel is the first byte in each double-word (if not, change all *bmpPtr to bmpPtr[3])
Hope this helps,
Sounds like somebody's got a case of the Mondays
-Jeff
|
|
|
|
|
I don't know about all of you, but I assume you've experienced the same frustrations as me when it comes to a Solution with multiple projects added to it.
We have 'Project References' as opposed to 'File References' where possible for the following reasons:
1 - We need to be able to enter the referenced assemblies during debugging.
2 - When our .sln builds, we need to make sure we've got the latest and greatest changes from our referenced assemblies.
Before I (or someone on my team) embarks down the road of finding a solution to our problem, I thought I'd ask if anyone else has a solution or ideas on how we might change our Project Refs to File Refs, and not lose the benefit of the two points described above.
It shouldn't be too difficult to build an add-in (or external tool) that would build a .csproj file in debug mode, and copy the .dll and .pdb file into the appropriate location for my solution. This would allow us to step through the code, satisfying point 1 above.
I guess my main struggle is how would I setup a pre-build script (or something) to figure out which file references are actually from projects I've got on my box, and then figure out if it needs to rebuild them, and them build them and copy the dll and pdb file over.
Any thoughts or comments would be great!
Paul Brower
|
|
|
|
|
Paul Brower wrote: how we might change our Project Refs to File Refs, and not lose the benefit of the two points described above.
It's not currently possible.
Paul Brower wrote: I guess my main struggle is how would I setup a pre-build script (or something) to figure out which file references are actually from projects I've got on my box, and then figure out if it needs to rebuild them, and them build them and copy the dll and pdb file over.
That's not generally how file references are used. If you think of the file reference as a complete third-party library, you only pick up a newer version when the consuming code is 100% ready to and it is a deliberate step.
It sounds like you have some references that are "common library" type of things. Even in this case, I would treat them the same way and look at them as if they were third-party libraries.
To do what you want you would need to build an external tool (or add-in).
Scott.
—In just two days, tomorrow will be yesterday.
—Hey, hey, hey. Don't be mean. We don't have to be mean because, remember, no matter where you go, there you are. - Buckaroo Banzai
[ Forum Guidelines] [ Articles] [ Blog]
|
|
|
|
|
Hi,
How can I launch an my application (.exe) after msi installation is complete?
I'm using VS installer, also custom actions. I tried to give Process.Start and run my exe from TARGETDIR in the Commit event of Installer class, but its throwing file cannot be found exception. The file is created before the Commit event, still it throws the error during installation.
I've Googled for the entire day today, and couldn't find a solution for this using Visual Studio 2003. I read that its possible using third party installers, but I cannot use other installer software.
Please somebody help!!
|
|
|
|
|
I would try the following in order until one of them worked:
1. Try hard-coding the path to the default exe location
2. Try doing #1, but do it after the commit stage
3. If neither 1 nor 2 worked, then simply write a console app that instantiates your exe.
If you cannot do this, then post a question here on how to do so If you are successful at step 1, then your problem is your target path. If you are not successful at step 1, but are in step 2, then the installer locks all installation files during the install, and you will need to execute your exe after the commit. If you fail at both 1 & 2, then you are probably attempting to instantiate your application incorrectly. Let us know the results of these tests,
Sounds like somebody's got a case of the Mondays
-Jeff
|
|
|
|
|
Hi Jeff,
Thanks for the help.
I tried something else on my own in the mean time. I added the primary output of my project (.exe) to the Install under Custom Actions. Then in the Commit event override, I called my exe using Process.Start(), target path was taken from savedState IDictionary object.
So now the aplication is launched when the installer reaches its final stage.
Isn't that a work around?
Blumen
|
|
|
|
|
Well-played! I would not have thought of that.
Sounds like somebody's got a case of the Mondays
-Jeff
|
|
|
|
|
Skippums wrote: 1. Try hard-coding the path to the default exe location
<BitchSlap>Hard-coding a path for any reason is a cardnial sin. You should never, Never, NEVER, EVER do this!</BitchSlap> Unless you want to really piss off the person who comes in behind you to maintain your code. Then, you can expect a visit from a very large, intimidating man, wearing an expensive suit with a black leather coat and wielding a silenced pistol. Need I explain what happens next?
|
|
|
|
|
Maybe I wasn't clear on what exactly I was recommending. I was attempting to break down the problem into multiple steps. The progression is as follows...
Step 1: get your executable to run AFTER it is completely installed by hand-
starting a separate application which loads your app via hard-coded paths
Step 2: modify your code from step 1 so that it runs automatically AFTER the commit phase of the installer
Step 3: modify your code from step 2 so that it runs automatically PRIOR to the commit phase of the installer
Step 4: change the path to your executable so that it is NOT hard coded It has been my experience that most questions arise when people try to code the final step as the first step. I was simply trying to illustrate the steps that were skipped so that the person asking the question could step backward through the progression until he had working code that he could then move forward with. Clearly (at least to me) I didn't mean to hard-code the value and leave it. I was offering debugging advice, not coding advice. Hope this clears things up for you.
Sounds like somebody's got a case of the Mondays
-Jeff
|
|
|
|
|
Yes
we can do this with commit event in the Installed class.
with in after commint event write a process object and pass ur exe name with path.
application will be start automatically
i hope this is help 2 u.
Cheers
RRave
MCTS,MCPD
|
|
|
|
|
calling the exe using Process.Start() alone will not run the exe. you have to add the primary output of that exe project to install Custom Action in the deployment project.
|
|
|
|
|
|
Hi Rave,
I appreciate it, but I've tried to run the exe using Process.Start() in Commit event and it didn't work for me without adding the primary output of the project to Install folder in Custom Actions.
Without that the installation would finish as it would normally, but application didn't start.
Regards,
Blumen
|
|
|
|
|
Ok man
can u explian what u r try do?
after installed ur application will want o start automatically is it correct?
thanks
|
|
|
|
|
yep, thats correct.
My project is a Windows application, and the requirement is that it should run once the installation is complete.
So I created a custom installer class, coz I wanted to create a few folders during installation. In the Commit event of my custom installer class (dll), I'm creating these folders. In the deployment project, in Custom Actions, as displayed in the link you have sent me, I'm adding the primary output of my Windows application project to the Commit event (View - Editor - Custom Actions - Commit).
In Installer class, I'm calling the exe that I need to run after installation is complete using the following code:
if(System.IO.File.Exists(@savedState["TargetDir"].ToString() + "MyExe.exe"))
{
ProcessStartInfo psi = new ProcessStartInfo(@savedState["TargetDir"].ToString() + "MyExe.exe");
Process.Start(psi);
}
The only issue is that application starts running once the final screen of installation is displayed to the user.
Regards,
Blumen
|
|
|
|
|
OK blue
now you came to the junction,but u dont where u want to go,?
u take small assumes, like installation will compelete another 0.5 seconds.
so tell to ur process sleep 1 mins after start.because of within the that period ur installation will complete.
thanks.
|
|
|
|
|
Hey Guys
In my app a have a form that has to return a DialogResult, but the snag is that form also has to be an MDI child. but i get an InvalidOperationException when i FrmWhatever.ShowDialog();
is there any way around this?
Thanx
Harvey Saayman - South Africa
Junior Developer
.Net, C#, SQL
think BIG and kick ASS
you.suck = (you.passion != Programming)
|
|
|
|
|
Hmm, why does the form has to be an MDI child???
|
|
|
|
|
cuz my boss want all windows for our app (and there are hundreds!) to be in one singe container (mdi parent)...
Harvey Saayman - South Africa
Junior Developer
.Net, C#, SQL
think BIG and kick ASS
you.suck = (you.passion != Programming)
|
|
|
|
|
Straight off I don't think there's any easy way to achieve that, if I understand what your boss want. How about a MessageBox? Is MessageBox has to be child too? How about Open File dialog, folder browser dialog? The dialog form is no different from an Open File dialog box, IMO.
If your boss really must have that, you may consider hiding Form1 and show Form2, then when user select an action (OK or Cancel or Close), then hide Form2 and Show Form1. But the handling of DialogResult and returned value can be a mess.
So back to my original question, why the dialog form needs to be MDI child?
|
|
|
|
|
lol!
i see your point... what i dont get is why cant a dialog be an mdi child? silly microsoft
Harvey Saayman - South Africa
Junior Developer
.Net, C#, SQL
think BIG and kick ASS
you.suck = (you.passion != Programming)
|
|
|
|
|
The best I can think of is to not have it as a mdiChild but a normal form - use showDialog but pass the MDI Container's child rectangle property to the forms constructor. You can then use the LocationChanged event to disallow movement of the dialog outside of that rectangle.
Passing the ClientRectangle doesn't work, it needs to be
RectangleToClient(ClientRectangle)
or
MdiParent.RectangleToClient(MdiParent.ClientRectangle)
if called from a child.
The X and Y (Top and Left) properties will give negative values so you'll need to subtract them from 0 to get the positive values you need.
This code works in the location changed (I'm sure it could be tidied up/improved but it does the job) where LimitRect is the rectangle passed above.
if (Top < (0 - LimitRect.Top))
{
Top = 0 - LimitRect.Top;
}
if (Left < (0 - LimitRect.Left))
{
Left = 0 - LimitRect.Left;
}
if (Right > LimitRect.Right)
{
Left = (LimitRect.Width - LimitRect.Left) - Width;
}
if (Bottom > LimitRect.Bottom)
{
Top = (LimitRect.Height - LimitRect.Top) - Height;
}
Dave
|
|
|
|
|
thanx man, ill look into it over the weekend !
it just hit 5pm here in south africa so im going home!
thanx again, have a go0d one!
Harvey Saayman - South Africa
Junior Developer
.Net, C#, SQL
think BIG and kick ASS
you.suck = (you.passion != Programming)
|
|
|
|
|
I would create a custom event on the form, and fire it from the forms destructor. Pass the DialogResult is the EventArgs and handle the event from the calling form.
|
|
|
|
|