|
Hi,
1.
AFAIK all Controls can be double-buffered, and that is the best way to improve the situation
2.
some improvement can be achieved by NOT updating the control when all the parameters remain the same,
i.e. compare the current ForeColor, BackColor and Text, with the new ones, and only update when there is a difference.
Luc Pattyn [Forum Guidelines] [My Articles]
DISCLAIMER: this message may have been modified by others; it may no longer reflect what I intended, and may contain bad advice; use at your own risk and with extreme care.
|
|
|
|
|
No, not all controls can be double buffered. As I tried to enable double buffering on that label,
compiling error C3767 "Candidate Function Not Accessible" appears.
I just can assign doublebuffering to the whole control (it's a control library project), but that has
sadly no effect on the flickering.
I also have tried your second hint, the comparison has also no effect and the fact is, that I have to update,
because in every loop there's number incremented, which I want to display.
So at least the text of the label MUST be changed.
Nevertheless, thank you! Maybe you come up with a further issue..
|
|
|
|
|
cherrymotion wrote: No, not all controls can be double buffered
I haven't encountered a situation yet where I was in need to double-buffer something that did not offer to do so.
cherrymotion wrote: Maybe you come up with a further issue
If the only purpose is to show some progress is (or isn't) being made, I often reverse the initiative: adding a Windows.Forms.Timer that periodically (say every 333msec) checks the situation and reports progress, independent of the work that is going on.
BTW: that timer ticks on the GUI thread, so its handler can update any Control.
PS: for it to work at all, the work itself needs to be handled by another thread (maybe in a BackgroundWorker)
Luc Pattyn [Forum Guidelines] [My Articles]
DISCLAIMER: this message may have been modified by others; it may no longer reflect what I intended, and may contain bad advice; use at your own risk and with extreme care.
|
|
|
|
|
Hi,
I started the backgroundworker doing his work, and from the DoWork-Event, I called
timer->start();
but somehow the timer starts never.
In the timer_Tick event I always update my label, I got you right?!
But as I said, the Tick() event is never reached, altough I started the timer.
Do I have to do something else with the backgroundworker? An own thread?
|
|
|
|
|
A Forms.Timer is like a Control, you should only touch it from the main thread, hence outside your worker threads. It needs an Interval value, a Tick handler, and a Start(). It is best to make the timer object a class member of your Form (or other Control).
Luc Pattyn [Forum Guidelines] [My Articles]
DISCLAIMER: this message may have been modified by others; it may no longer reflect what I intended, and may contain bad advice; use at your own risk and with extreme care.
|
|
|
|
|
Hello,
Problem is - User can input any number, program need to take decision based on inputs.
Let suppose input is stored in variable n;
based on value of n some function will be called.
program logic can be -
if(n > 1 && n < 10 )
callfun1();
if(n > 11 && n < 20 )
callfun2();
if(n > 25 && n < 30 )
callfun3();
if(n > 33 && n < 38 )
callfun4();
if(n > 1 && n < 10 )
callfun5();
.
.
.
and so on
if(n > minlimit && n < maxlimit )
callfunX();
Is there any easy way to avoid if else chain to do similar work.
Or is there any way to change the limits in if condition at some central place something using #define.
Please provide your inputs/help to help me finding other ways to optimize programming.
Thank
Vikas
vicky
|
|
|
|
|
Hello.
In .NET you could do something like:
Define an array of minlimits and maxlimits, define a class C to hold your methods, methods that are named in the line of M1, M2 and then use invokemember to call them like this:
For(int i = 0;i<bound;i++)
{
if((minlimits[i]<n)&and(maxlimits[i]>n)
C.GetType().InvokeMember("M"+i.tostring(), .....)
}
In C++ i think you can do this with an array of pointers to functions, but i quit C++ a long time ago and i don't know for sure. Also, the .NET solution is not tested, but looks good:P
modified on Thursday, June 11, 2009 10:10 AM
|
|
|
|
|
vikasvds wrote: Please provide your inputs/help to help me finding other ways to optimize programming.
Software Design Patterns[^]
|
|
|
|
|
Hello!
You could store the intervals in a sorted container together
with the function delegates to call for the specific interval.
You could now use a binary search to find the appropriate
intervals.
However, it gets more difficult when the intervals overlap
and there has to be a certain order. When there are
repeated intervals as above, you could use multicast delegates,
calling callfun1() and callfun5() after each other.
Alex
|
|
|
|
|
Thanks for all of your responses.
I have got the answer.
Thanks
Vikas
vicky
|
|
|
|
|
Please any one know how to run an external application in c++ Windows Forms
|
|
|
|
|
You can use either ShellExecute() or CreateProcess().
Advantage of CreateProcess() function is your program can wait till another application you have launched is not finished/terminated.
Thanks
Vikas
vicky
|
|
|
|
|
Hi,
read up on the Process class. Simple stuff can be handled in a Process.Start() statement; more complexe requirements need details stored in a ProcessStartInfo objects first.
Luc Pattyn [Forum Guidelines] [My Articles]
The quality and detail of your question reflects on the effectiveness of the help you are likely to get.
Show formatted code inside PRE tags, and give clear symptoms when describing a problem.
|
|
|
|
|
Could someone provide me with code examples of:
- A C++/CLI program with a function that takes a string as an argument, writes it into every entry of an array of length 5, and returns that array to the caller.
- A C# program which invokes the above program.
I've spent a good portion of the day poking at C# and C++/CLI trying to get them to talk to each other and a simply am getting no where.
I'm certain, given the above example, I can extrapolate what I'll need to complete my task. My problem, is most of the stuff I've found via google searches either just shows off C++/CLI syntax (and does not shows how to access it via another .NET language), or uses what I've learned are "old" interoperability conventions.
Any assistance would be greatly appreciated.
|
|
|
|
|
Sound like homework question. But here you go..
Shadowsoal wrote: A C++/CLI program with a function that takes a string as an argument, writes it into every entry of an array of length 5, and returns that array to the caller.
typedef array<System::String^> StringArray;
public ref class Foo
{
public:
StringArray^ GetStringArray(System::String^ str)
{
StringArray^ a = gcnew StringArray(5);
for(int i = 0; i < 5; i++)
{
a[i] = str;
}
return a;
}
};
int main(StringArray^ args)
{
Foo^ foo = gcnew Foo();
StringArray^ a = foo->GetStringArray("Test");
for each(String^ str in a)
{
Console::WriteLine(str);
}
return 0;
}
Shadowsoal wrote: A C# program which invokes the above program.
In your C# project, add reference to the assembly you got from the above code. You will get access to class Foo .
|
|
|
|
|
Certainly not a homework question. Initially I was just going to ask for the C++/CLI to write helloworld, but I figured I'd ensure I figured out how to pass around arrays and the like.
I've got a library written in C that i need to make C# compliant for a client, and from what I've seen the way to do that is to write a wrapper around the C library in C++/CLI.
Regardless of that, thank you for the response. I'm not developing this specifically in Visual Studio though, I was just compiling with cl and csc. Which is why I was wondering if someone could explain how to explicitly link the two. There's lots on the internet about C++/CLI, what I'm having trouble with is convincing a C# program to play nice with something like the above code.
Thanks again!
|
|
|
|
|
Shadowsoal wrote: Certainly not a homework question
My mistake
Shadowsoal wrote: I'm not developing this specifically in Visual Studio though, I was just compiling with cl and csc. Which is why I was wondering if someone could explain how to explicitly link the two.
I am not getting where you are stuck.
Use cl with /clr command switch to compile C++/CLI program. Make a DLL from it which can be run on common language runtime. See the compiler switches here[^].
Once you generated the DLL, use csc to compile the C# application. There is no linker needed for C# programs. Specify the DLL as reference to the compiler. I guess /reference is the compiler switch used for that. See /lib[^] as well for specifying the directories where to look for assembly.
|
|
|
|
|
Yeah, that's exactly what I was doing before. I suppose I just had something wrong in the C++/CLI file.
Thanks again!
|
|
|
|
|
Shadowsoal wrote: I suppose I just had something wrong in the C++/CLI file.
Does it compile? Are you able to view the produced DLL via reflector[^]?
|
|
|
|
|
Haha, it's midnight in my neck of the woods, and I don't have any of my code on my home machine. Despite that, I'm fairly confident I'll be able to resolve my issues given what you've said. My biggest problem was every Google query resulted in different people answering similar, but non-identical, questions all in different manners. From what I've read, Microsoft's .NET interoperability standards have changed quite a bit over the years, so I'm fairly certain I was probably mixing some old stuff and new stuff that just didn't jive. That combined with the fact that all of the explicit tutorials involved going step by step through visual studio, which is not a tool I'm using.
My deepest thanks, you've been extremely helpful!
|
|
|
|
|
Okay, here is your code, very slightly changed
using namespace System;
typedef array<String^> StringArray;
public ref class Foo
{
public:
StringArray^ GetStringArray(String^ str)
{
StringArray^ a = gcnew StringArray(5);
for(int i = 0; i < 5; i++)
{
a[i] = str;
}
return a;
}
};
int main(StringArray^ args)
{
Foo^ foo = gcnew Foo();
StringArray^ a = foo->GetStringArray("Test");
for each(String^ str in a)
{
Console::WriteLine(str);
}
return 0;
}
This is my C# program:
public class CSTest
{
public static void Main()
{
System.Console.WriteLine("Hello World!");
Foo myFoo = new Foo();
string[] myArr = myFoo.GetStringArray("Pineapple");
}
}
And this is what happens:
$ cl CLIWrapper.cpp /clr /LD /FeCLIWrapper.dll -nologo
cl CLIWrapper.cpp /clr /LD /FeCLIWrapper.dll -nologo
CLIWrapper.cpp
$ csc CSTest.cs /r:CLIWrapper.dll -nologo
csc CSTest.cs /r:CLIWrapper.dll -nologo
$ CSTest
CSTest
Unhandled Exception: System.IO.FileNotFoundException: The specified module could not be found. (Exception from HRESULT: 0x8007007E)
at CSTest.Main()
This is what was happening yesterday, the C++/CLI program compiles into a DLL which I can see (with a program like reflector) has my functions in it. The C# file compiles just fine, but the moment I try to run the C# program, a windows error report window pops up, and when I close it the above error message appears.
Anyone have any ideas?
|
|
|
|
|
Shadowsoal wrote: Unhandled Exception: System.IO.FileNotFoundException: The specified module could not be found. (Exception from HRESULT: 0x8007007E)
at CSTest.Main()
To understand the problem you should read the /clr[^] switches and it's use. You are using /clr option which will allow both native and managed assemblies. To achieve this side by side assemblies, it has to create a separate manifest file which will have all details about the assemblies used. Regardless of the .dll extension, a manifest file is just a XML file and you can open it in any supported editor to view the contents.
If you goto the C++/CLI program's directory, you will see two files CLIWrapper.dll and CLIWrapper.dll.manifest . The second one contains manifest information and it tells that side by side assemblies are used. Application requires msvcm80.dll when compiled using /clr or /clr:pure thus you can't avoid manifest files when using these compiler switches. This manifest information is not embedded into the executable you are producing and it is the reason for error. When compiling from VS, it does this internally.
When you use csc CSTest.cs /r:CLIWrapper.dll to compile your C# application, it will compile but the manifest information for C++/CLI library is not included. You have to include this after the compilation. mt.exe[^] is the exe which can do this. Once the compilation finishes run the following command
mt -manifest CLIWrapper.dll.manifest -outputresource:CSTest.exe This will set the manifest. Now run the exe and it should work fine.
If clr:/safe is used then manifest files are not required. Your code should work without doing any extra work.
Hope that helps
|
|
|
|
|
It compiles and it runs! Thank you very much navaneeth. My simple test programs compile and run just fine now that I'm using /clr:safe instead of just /clr. Now all I need to do is write a handful of wrapper functions around my old library, and things should be golden.
I'm sure I'll be back here in the relatively near future if I find myself hitting my head against a wall again. You've been a tremendous help, a gentleman and a scholar.
|
|
|
|
|
Shadowsoal wrote: My simple test programs compile and run just fine now that I'm using /clr:safe instead of just /clr. Now all I need to do is write a handful of wrapper functions around my old library
clr:/safe can't compile the application when native classes are involved. It is OK if you have only managed classes. Since you have native classes, go with /clr or /clr:pure .
|
|
|
|
|
After having worked with a handful of other things related to this project, I return to the C++/CLI looking to finish things off, but alas, I run into an issue once again. Hopefully it can be easily resolved.
|
|
|
|