|
You need to recurse through anything which can contain other controls.
public void ChangeColors(ControlsCollection parent)
{
foreach(var c in parent)
{
if(c is Label)
{
c.ForeColor = Color.Aqua;
}
else if(c is Button)
{
c.ForeColor = Color.Yellow;
}
else if(c.HasChildren)
{
ChangeColors(c.Controls);
}
}
}
Call it with ChangeColors(Form1.ActiveForm.Controls);
|
|
|
|
|
Something like this should work:
private void IterateOverAllControls(Control control)
{
foreach (Control childControl in control.Controls)
{
IterateOverAllControls(childControl);
}
if (c is Label)
{
((Label)c).ForeColor = Color.Aqua;
}
else if (c is Button)
{
((Button)c).BackColor = Color.Yellow;
}
}
|
|
|
|
|
c should be control
Other than that, pretty much same solution I came up with. Great minds, rodney, great minds!
|
|
|
|
|
J4amieC wrote: c should be control
Well spotted. At this point, I was looking at his implementation and hooking in part of his logic.
|
|
|
|
|
Hey Gurus,
I'm putting my Comm Port stuff together with my graphing stuff.
Is there any compelling reason for me to either of these possibilities ?...
[A] Require the same size packet for each data exchange
[B] Purposely avoid any such requirement
The environment and context of this is a small device controlled by a user GUI on a PC
|
|
|
|
|
There is no real rule - it depends on what you are talking to and how much data you are talking about. If most of your communications is "Are you alive?" "Yes" then fixing a packet size at 2KB is a heck of a silly idea. But if you want to transfer a 640x480 screen regularly instead, then a large fixed packet may be a good idea as it can help avoid memory fragmentation in the small device.
Horses and courses, I'm afraid!
If you get an email telling you that you can catch Swine Flu from tinned pork then just delete it. It's Spam.
|
|
|
|
|
What I have is
-- About five little 10 and 20 byte packets and responses (Hello, ready, start, stop, what's the error ? and so on)
-- Packets of 16384 bytes each, with individual variations, sent over and over again; I think they hit me at one second intervals. I have to separate them into individual channels, then plot them on a graph, hopefully before the next package of data arrives.
-- Amidst all this, there is a super-tiny chance that I may need to handle a small packet.
I have control of the small box on the other side of the UART, at least for now; i.e., I wrote the comm routines in the box and I can change it if I want.
i.e., I could make it send individual 64 Byte packs if that would make sense in the multi-threading thing; but I just don't know ahead of time if large or small will work better.
|
|
|
|
|
I hope you have a fast UART! You're going to need at least 164K baud just to transfer the 16Kb packets in one second, let alone process them!
I would not use a fixed packet size - too much overhead. If at all possible, I would want to reduce the amount of data flying around - if you are using a UART you are probably RS232 or RS485, and the reliability drops as a function of both distance and transmission speed. The more data you throw at high speed (for the medium) the more chance of data errors/ retries. (If you are using USB then the TX speed can be pretty huge before it becomes a problem)
I would probably start looking at two threads - one to handle the raw data comms and extract the data blocks, then queue them up for the display thread. That way, the UI can continue in it's own merry way while blocks are stacking up for it.
If you get an email telling you that you can catch Swine Flu from tinned pork then just delete it. It's Spam.
|
|
|
|
|
OriginalGriff wrote: I hope you have a fast UART! ....at least 164K... Yes, BlueTooth and USB, 900Kbps, if everybody's telling the truth, and all tests indicate they are.
There are 20 channels of data for me to display, so my scheme and design from square one has been twenty threads for graphs, and one thread for the UART, with a Central Dispatch routine overseeing the operation and coordinating the operation; most probably via semaphores. e.g.,
public static byte ChannelState09;
Then the dispatcher gives channel 9 the command to go and graph, and channel 1 responds by telling the dispatcher that he is busy, then he finishes and so notifies the dispatcher, who will give him his next task when data has arrived.
That's the "eternal loop without an exit" model.
The other model in my head is to just start the individual thread and wait for it to finish. At this moment, I'm not completely certain that one way or the other would work better. If anyone reading has personal experience in this, I welcome the feedback.
|
|
|
|
|
Related question.
Which scheme is better ? Or, what nonobvious costs and nonobvious benefits might be present in either of these schemes ?
-A- Each thread stays active and continually loops in a "semaphore watch" waiting for a specific byte to change from "DoNothing" to "GraphYourNextPoint"
-B- Each Thread is spawned individually, does its task on the spot, and exits.
Maybe the question is: will I spend more processor time in actually spawning the different threads and terminating them over and over again ? Or will I spend more time in a bunch of threads that are continually polling their status flags (aka semaphore bytes) while waiting for real action ?
|
|
|
|
|
Probably what I would do is have the UI thread do the graphing, and a single other thread to handle the comms. If you set the comms up in a BackgroundWorker[^] it's pretty simple to do because it has the ProgressChanged event, which the UI can subscribe to. It gets a progress event, the handler gets the data (with a lock to make sure it's thread safe) and does the graphing. That way, nobody has to wait (except the background thread which is waiting for physical data anyway).
If you get an email telling you that you can catch Swine Flu from tinned pork then just delete it. It's Spam.
|
|
|
|
|
Excellent find, thank you.
That is truly daunting material to master at first glance.
I see 9 properties, 22 Methods, and then 4 events for good measure.
I think that's 792 possible combinations.
I will be searching for example code, and welcome any suggested links.
|
|
|
|
|
It's not as complex as it looks - if you look at the example on the same page, you will find that you need about two properties, two method, and two events if you ignore the cancellation stuff (which you can since this is unlikely to be a thread that needs cancellation)
If you get an email telling you that you can catch Swine Flu from tinned pork then just delete it. It's Spam.
|
|
|
|
|
OriginalGriff wrote: unlikely to be a thread that needs cancellation Ack, my bad.
This thread will need to be canceled and restarted at the user's whim. The external box can start and stop, and it has a special "Alert" button just to send a little notice to the PC GUI.
That, plus, there will be disk files that save the data and observations, and blah blah blah.
|
|
|
|
|
Why? If you start and stop it, it won't get the message from the device...
If you get an email telling you that you can catch Swine Flu from tinned pork then just delete it. It's Spam.
|
|
|
|
|
Oh, that kind of "cancel". Got it. cool
|
|
|
|
|
Just looked for info on the BackgroundWorker class.
Found This[^]
First thing in the description was
"...The Silverlight BackgroundWorker class provides..." I stopped immediately. Sorry for the feeble braincells here; just want to make sure that I don't have to require special software on the users machine.
I took a quick look at this[^] page and I see mostly stuff about internet and web browsers.
Was my view of the forest obliterated by a tree ?
|
|
|
|
|
The link I pointed you at is the standard .NET BackgroundWorker - it doesn't need Silverlight (or anything extra that isn't already needed to run c#) A quick look says it it pretty much the same class anyway - all the events and properties are the same.
MS do reuse names - look at the number of Timer classes you could play with if you wanted to!
If you get an email telling you that you can catch Swine Flu from tinned pork then just delete it. It's Spam.
|
|
|
|
|
Hi
I've got a Delphi32 DLL that I have to call from C# and have a .h, .hpp, and .bas header file.
Would it make most sense to use the .hpp file to create a Class that will wrap the DLL? Seems so to me.
Unfortunately, I don't do C++
It sort of makes sense, but not completely. Mostly, I know void * should be IntPtr, and char * should be string. But that's about it.
For instance,
const char bapiDll[] = "BAPI32.DLL";
HINSTANCE hLib;
enum TParamType { literal, reference, list } ParamType;
void * pRPC;
should turn into
const string bapiDll = "BAPI32.DLL";
uint HINSTANCE, hLib;
enum TParamType { literal, reference, list } ;
IntPtr pRPC;
Yes? No?
But what do I do with the prototypes and what follows inside the actual guts of the thing? like
void RPCBPropGet ( char * s, char * t);
which obviously has something to do with
void TRPCBroker::RPCBPropGet ( char * s, char * t)
{
iRPCBPropGet(pRPC, s, t);
}
and
TRPCBroker::TRPCBroker()
{
hLib = LoadLibrary(bapiDll);
if((unsigned)hLib<=HINSTANCE_ERROR)
{
char bfr[40];
wsprintf(bfr, "Failure loading library: %s", bapiDll);
MessageBox(NULL, bfr, toolSet, MB_OK|MB_APPLMODAL);
UnLoad = true;
}
. . .
iRPCBPropGet = (void (__stdcall*)(void *, char *, char *)) GetProcAddress(hLib, "RpcbPropGet");
. . .
UnLoad = false;
pRPC = iRPCBCreate();
};
Any good references out there that'll cover this without me having to spend days reading through everything I don't want to know? Or anyone incredibly bored with no life who wants to hold my hand through all 139 lines of it (including empty and comment lines :p )?
|
|
|
|
|
Luc (Pattyn) had a nice article on 'P/Invoke' that Ive found useful .. http://www.perceler.com/articles1.php?art=pinvoke1[^]
Im sure there used to be some automated tools out there that would assist in converting function prototypes (c++) into their C# .NET equivalent, but cant find them right now
I had a similar issue, needing to use PGP SDK (Commercial) from C# - I ended up with essentially 3 layers :-
a) Interop Layer
b) C++ DLL exposing/combining lower level PGP SDK functions into higher functions - for example, the encrypt_file procedure uses key management functions, encrypt functions from the SDK
c) the PGP SDK DLL
It all depends on what functionality you need to expose from your DLL how you 'wrap it'
There's another approach, but I havnt used it which is c++/CLI
|
|
|
|
|
Luc's looks promising. Thanks.
I think I tried one of the automated online converters once...and it came up with line after line of "ya gotta do this part by hand".
|
|
|
|
|
Have a look at x86 calling conventions[^]
I assume that header file is for C++ Builder, and the delphi dll will use what the article calls 'Borland fastcall' which is different from 'Microsoft fastcall' - so you're probably going to need to wrap the functions and expose them using the __stdcall calling convention.
GenJerDan wrote: everything I don't want to know?
Not the most promising attitude for a developer - and calling conventions is something I would think you need to understand.
Best regards
Espen Harlinn
|
|
|
|
|
I've never had to deal directly with DLLs, or at least not to try to use one that wasn't friendly with the rest of the program....and I started I started in 1992 or so.
Push comes to shove, I don't even have have to do this now. I've got Delphi sitting here, too.
I just think it might be a good idea if I didn't have to keep running a virtual machine to write these things. (Delphi 5 won't install on 64bit Windows.)(Yes, I said Delphi 5)
The __stdcall is already there in the header, so I assume the DLL was written to work with it.
|
|
|
|
|
GenJerDan wrote: I've got Delphi sitting here, too
Delphi has always been one of my favourite development tools, I've been using it since version 1 - but, seriously, Delphi 5, that makes me nostalgic.
GenJerDan wrote: I started in 1992
I believe I was working on a C++ IDE for IBM and OS/2 at that time.
GenJerDan wrote: __stdcall is already there in the header
I assumed the code above was from the header file, and I only saw __stdcall in one place.
Go for Delphi XE3[^], assuming you haven't done any magic related to getting notified on object destruction, which was something many Delphi developers did, porting the code should be pretty easy.
Good luck
|
|
|
|
|
Read up on Marshalling and unmanaged code. Normally C# can handle unmanaged code pretty well.
Although it might take some fiddling (searching) .
[EDIT]
Take in account that older code still takes ASCII strings or worse (1 byte vs 2 bytes) and even C# integers can be C++ longs, ...
[/EDIT]
|
|
|
|
|