|
my application requires me to load tons of images dynamically based on a path set at run time. right now I have something that looks like this.
private Image mybtn;
public Image MyBtn{
get{return = mybtn;}
set{mybtn = value;}
}
public static void SetButtonImage(string imgPath){
MyBtn = new Bitmap(imgPath);
}
the problem is that the images are slow. Slow loading, slow reloading a hover image. I have found that if I use a pictureBox instead its faster but not fast enough.
The question is, is there a was to load these in like a temp resouce file that will enable every thing to run faster. Im looking into using DirectX and load them as sprites but not sure if its really going to help much. Please Let me know what you all think.
Mike
|
|
|
|
|
Right now, are you loading the images from resources inside your EXE, or are these discrete files on disk?
Nevermind, I failed to read carefully enough!
|
|
|
|
|
Zap-Man wrote: my application requires me to load tons of images dynamically
First question is why? Do you really need all the images at once? Can you load them on demand?
only two letters away from being an asset
|
|
|
|
|
The system goes through a file and sets all parameters at that point. The graphics are read off several different files. at the time when starting the project. I thought that loading the Images into a Image variable would be faster than loading them into a string aka path. That way it would not have to go get the file then convert it over to an Image at the time of display.
right now I have panels working as screens. when one screen is displayed the others remain at size(0,0). The panels are preset at when loading the program and all the controls that belong to the panel, where the images are sitting and what size. so when a new srceen is shown all it has to do is resize the panel to the correct size from 0,0. I understand that windows has to repaint all these when displayed but im just trying to speed it up. The whole program runs on images.
|
|
|
|
|
This senerio has your app using a lot more memory and thus contributing to reducing the overall performance of the machine, not making it faster.
I would consider loading the images on demand. Even if all of your panels are used during each session they are not all displayed at the same time. You could prefetch the next set of images when displaying a panel to reduce the load time.
I wouldn't load all the panels and set them to 0,0 either. Regardless of the display size they are still using resources that may not be necessary. Use User Controls and dynamically add or remove them if nothing else.
Finally, if your entire app runs on images, I'd consider a different environment, like WPF or an out of browser Silverlight app, or a different design to not be so reliant on images.
only two letters away from being an asset
|
|
|
|
|
ok this is the information I need. Again Mark I say thanks. Have you used WPF? would all my code be transferable, meaning Im I going to have to learn a new language or does it render C#. Im looking at a few sites that give information on WPF but before I decide to transfer to it or something like it I need to know how fast I can implemt the application over. my app is finished and sold yesterday. I cant spend tons of time changing it over right now. maybe in a couple of months but not sure.
The bad thing is if I kept up on things maybe I could have suggested WPF but instead I just did what I was told and never gave it a second thought.
|
|
|
|
|
Zap-Man wrote: Im I going to have to learn a new language or does it render C#.
The code is C# yes but the layout is XMAL.
Zap-Man wrote: how fast I can implemt the application over.
Can't answer that question, it's up to how fast you can pickup the skills and what code you do have. If the app was structured with independent layers and loosely coupled then it should be a matter of changing the presentation, nothing else.
only two letters away from being an asset
|
|
|
|
|
ok I answered many of my questions. I downloaded a sample project that they had and yes they used tons of C#. a could other files that I could not open like vail. Im still searching for a download the link to blend isn't working so im still searching. lol Thanks again for all your help Mark.
|
|
|
|
|
Your're welcome.
Please remember to vote on the answers, good or bad, so it will help others who may have similar problems find a sufficient answer also
only two letters away from being an asset
|
|
|
|
|
ok I have given up on the wpf. I spent all day yesterday trying to install a trial version an kept reciving errors. And none of the links to install it actually work. So far im not impressed by it. I think I'll just stick to c# vs for now. probably will just be inserting some DirectX into the code to render my images as sprites. This should free up a little stress on the cpu.
It sounds like there are alot of others out there using wpf but I think theres more that just got tired of all the crap and errors that I went through.
|
|
|
|
|
How do I convert a ushort * to an IntPtr ?
Or any primitive pointer to an IntPtr ? int* , uint* , etc..
Background:
The ushort* holds the start address to a buffer from a PInvoke call:
[DllImport( "DCamLIB.dll" )]
private unsafe static extern bool DcamCapture( ushort* imageBuffer, Int32 bufferSize );
I need to then pass this location on complete with buffer size to a C# method that takes a IntPtr .
Thanks in advance,
Jason
|
|
|
|
|
This is what you would do:
[DllImport( "DCamLIB.dll" )]private unsafe static extern bool DcamCapture( IntPtr imageBuffer, Int32 bufferSize );
IntPtr ShortVariable = Marshal.AllocHGlobal(4);
DcamCapture( ShortVariable, bufferSize );
Int16 Result = Marshal.ReadInt16( ShortVariable );
Hope this helps!
EDIT: I may not have gotten your scenario correct, but the concepts are the same. You declare the external function with IntPtr's, and pass IntPtr's. And you use the Marshal class to allocate and read from or write to unmanaged memory.
modified on Tuesday, October 20, 2009 7:07 PM
|
|
|
|
|
Hi,
I know two ways to do this without explicit marshaling, and in such a way that the data never gets copied. The example holds a native function that sums the elements of a managed array; however it would be equally valid for the native code to write into the array (within its bounds of course).
1.
for a once-of pointer, that is not used asynchronously in the native world later on, this suffices (it does need the "allow unsafe code" switch):
unsafe public int ArrayFixed() {
int dim=1000;
int[] numbers=new int[dim];
...
int sum;
fixed (int* pNumbers=&numbers[0]) {
sum=SumArray(pNumbers, dim);
}
return sum;
}
[DllImport("native.dll")]
unsafe public static extern int SumArray(int* pNumbers, int count);
2.
The general approach (which I prefer) is this:
public int ArrayHandle() {
int dim=10000;
int[] numbers=new int[dim];
...
GCHandle handle=GCHandle.Alloc(numbers, GCHandleType.Pinned);
int sum=SumArray(handle.AddrOfPinnedObject(), dim);
handle.Free();
return sum;
}
[DllImport("nativeC.dll")]
public static extern int SumArray(IntPtr pNumbers, int count);
Here you should free the handle when the pointer is no longer in use natively.
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? 59.24% waren verstandig genoeg om NEEN te stemmen; bye bye viaduct.
modified on Tuesday, October 20, 2009 8:05 PM
|
|
|
|
|
Richard and Luc,
I will give the GCHandle approach a try tomorrow.
I updated the code and it of course compiles correctly but, the actual physical device this API talks to is at work and I just got home.
Hopefully I'll have good news tomorrow.
TYVM,
Jason
|
|
|
|
|
It worked just fine. I can now remove the unsafe switch from the project.
Thanks so much!
Jason
|
|
|
|
|
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? 59.24% waren verstandig genoeg om NEEN te stemmen; bye bye viaduct.
|
|
|
|
|
I am sort of stumpped.
I have a
List<string> EmailsTO
List<string> EmailsCC
I want to be able to pass the lists into a form. Modify those lists in the form. Then return the new lists back to the Parrent form, followed by closing of the child form I am simulating as a popup.
I can not figure out how to get the list<string> ... into the form and back out.
Can someone help point me in the right direction?
Here is some of what I have come up with....
using (frmpopupEmailRecipient popupVerifyEmailRecipients = new frmpopupEmailRecipient(ref EmailTo, ref EmailCC))
{
popupVerifyEmailRecipients.ShowDialog(this);
}
|
|
|
|
|
What I still can not figure out is passing a ref into the form is great for 1 way population if information. But What I need is to be able to receive a list back to the parrent replacing the list the parrent currently has with the modified list of the child.
I keep thinking I need to set up a List<string> Property on the child form. But I can not find any examples on how to set up a list<string> Property.
Please Help.
|
|
|
|
|
Don't pass controls around. Pass the data around. Use delegates to pass changes back to the main form.
Christian Graus
Driven to the arms of OSX by Vista.
Read my blog to find out how I've worked around bugs in Microsoft tools and frameworks.
|
|
|
|
|
|
JollyMansArt wrote: but I am not understanding an example where I can pass List between parrent and child forms...
DON'T pass a list control between your forms. Pass the list itself ( I don't know if that's what you mean by list ). Pass it into the form, then if the form is modal, you can just access it back out with a property. If the form is modeless, a delegate is needed to tell the main form when data was changed inside the other form ( assuming this is possible )
Christian Graus
Driven to the arms of OSX by Vista.
Read my blog to find out how I've worked around bugs in Microsoft tools and frameworks.
|
|
|
|
|
I am not passing a control I am passing a List<string> ABC Object which is sort of like string[].tolist<string>()
I agree with what your saying and I just thought of that to. Now I just have to remember how to do that. I have avoided interform communication methods in the past. Now it is time to figure out how to do it again. Your right though..
Encapsulating the new form in a using statement in a previous project did allow me to communicate with it from the parrent form. I just forget how to do that. I will research. Unless you have a sample. I am close in my code example i think.
|
|
|
|
|
Hi,
I assume this is about System.Net.Mail.MailMessage, which has three properties (To, Cc, Bcc) of type MailAddressCollection.
you can pass such lists just like any other object, and it does not need a ref keyword; and the receiving method can enumerate, add, remove, and perform all operations that the list supports. The one thing you cannot do is replace the list by a different list (that is the only operation that would require you to use the ref keyword).
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? 59.24% waren verstandig genoeg om NEEN te stemmen; bye bye viaduct.
|
|
|
|
|
Partial assumption is correct.....
This is the mailmessage as to what it will go to. That part of the application I have working. I am tweaking the (to,cc,bc) before I pass the parameter to the procedure handling the list. To allow for the ability for a popup window with 2 checkbox list boxes. To allow the end user to override or add to the list of email addresses the will be used to send the autogenerated email. It was a requirement being asked in the last second.
So I need to pass the 2 list variables into the popup form, allow the form to add/delete items from the list variable for the (to,cc,bc) email addresses. Then finally pass the new list objects back to the parent, replacing the parents list variables from the list variables received from the child.
|
|
|
|
|
Here is some of the code behind what I am doing before:
private void SendEmail(string AlertType, string Subject, string MessageBody)
{
string[] MailTo;
string[] MailCC;
string MailFrom = "it@peerassistllc.com";
List<string> EmailToAddress = EmailTo(AlertType);
List<string> EmailCCAddress = EmailCC(AlertType);
if (EmailToAddress.Count > 0)
{
MailTo = EmailToAddress.ToArray<string>();
MailCC = EmailCCAddress.ToArray<string>();
}
else
{
MailTo = EmailCCAddress.ToArray<string>();
EmailCCAddress.Clear();
MailCC = EmailCCAddress.ToArray<string>();
}
string smtpHOST = txtSMTPServer.Text;
int smtpPORT = Convert.ToInt32(txtsmtpPortNumber.Text);
string smtpNETAuthUser = txtsmtpServerAuthencationUserName.Text;
string smtpNETAuthPassword = txtsmtpServerAuthencationPassword.Text;
int i = 0;
string LogMessage = "Mail From: " + MailFrom;
if (MailTo.Length > 0)
{
LogMessage += " Mail To: ";
for (i = 0; i < MailTo.Length; i++)
{
LogMessage += MailTo[i] + "; ";
}
}
if (MailCC.Count<string>() > 0)
{
LogMessage += " Mail CC: ";
for (i = 0; i < MailCC.Length; i++)
{
LogMessage += MailCC[i] + "; ";
}
}
LogMessage += " SMTP Host Server: " + txtSMTPServer.Text;
LogMessage += " SMTP Server Port: " + txtsmtpPortNumber.Text;
LogMessage += " SMTP Server UserName Authencation: " + txtsmtpServerAuthencationUserName.Text;
LogMessage += " Message Subject: " + Subject;
StandardProcedures.SQL_Log(WhatIsMyConnectionString, AlertType, LogMessage, true);
StandardProcedures.SQL_Log(WhatIsMyConnectionString, AlertType, MessageBody, true);
if (MailTo.Count<string>() == 0 & MailCC.Count<string>() == 0)
{ return; }
ConfirmEmailReceipents(ref MailTo, ref MailCC);
StandardProcedures.NET_AuthenticatedMailSend(MailFrom, MailTo, MailCC, Subject, MessageBody, smtpHOST, smtpPORT, smtpNETAuthUser, smtpNETAuthPassword);
}
modified on Tuesday, October 20, 2009 8:25 PM
|
|
|
|