CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 12 of 12
  1. #1
    Join Date
    Oct 2011
    Posts
    26

    [RESOLVED] Thread with Delegate works want eventhandling

    I have a program that collects data over a TCP/IP channel.
    I have multiple (sub)forms that create their own tread in the constructor when created (gcnew)
    Example
    Code:
    FYD = gcnew Form_Log_Download(this->progressBar1, Lock, Connection, DatabaseX); 
    FDD = gcnew Form_Dynamic_Download(this->progressBar2, Lock, Connection);
    To show the progress on the main form the first parameter is a pointer to a progressbar which gets updated by the thread (delegate)
    When clicked on the progressbar the subform will show up an show it's own progressbar and aditional info (Log wil show number of log record loaded and Dynamic will show percentage of executed commando's)
    The forms are never closed, only Show and Hide are used.

    The Dynamic Download Thread collects the next data: Voltage, Amperage, Power and temperature then sleeps for 10 seconds and repeats the cycle.

    The thing i want is to set an event when the 4 values are received so the main thread can catch it.
    The main thread can then draw gauges/ show the updated values for the ones the user enabled.
    At the moment i use a dumb timer to update some items on the main form but that is not synchronous.
    I want to connect the pameter (routine) of the timer tick to an event catch. So as soon as the values are updated in the thread the eventcatch can update the screen (or file on disk)

    Is this possible? I have searched around but nothing about events from theads back to the mainform.

  2. #2
    Join Date
    Jun 2010
    Location
    Germany
    Posts
    2,675

    Re: Thread with Delegate works want eventhandling

    So you're already successfully doing the updates of the subforms (which implies that you're not doing any cross-tread GUI manipulations without using Invoke() or BeginInvoke()) and now just want to update (parts of) the main form in quasi-realtime, in particular without polling the data from the subforms in a timer tick handler?

    In this case these three rather less commonly known aspects of .NET event handling may turn out to be useful for you:
    • As the += syntax for adding them already suggests, you can have more than one handler listening to any single event.
    • Complementarily, a single event handler can listen to more than one event, as long as their signatures match. You can tell apart or access the various event sources by using the sender parameter that gets passed to the handler.
    • A handler listening to an event generated by a form or a control hosted on the form does not necessarily need to be a member of that form class. Actually, it doesn't even need to be a member of any form class at all. Just the signatures of the event and the handler need to match.

    However, except for the second point, all of that can't be set up using the IDE. You need to program that yourself, but with the right design that may be surprisingly little effort.
    I was thrown out of college for cheating on the metaphysics exam; I looked into the soul of the boy sitting next to me.

    This is a snakeskin jacket! And for me it's a symbol of my individuality, and my belief... in personal freedom.

  3. #3
    Join Date
    Oct 2011
    Posts
    26

    Re: Thread with Delegate works want eventhandling

    Eri thanks so far,
    an eventhandler on the main form catching multiple events from the child form+thread would be perfect.
    The child form+thread could then fire events for the values already collected (eq four different for Voltage, Amperage, Power and temperature )
    I have seen some examples with the += attachement but so far i still have to do some research.
    As for my current example sending a main form progressbar pointer to the child form+thread can then be removed and replaced by an event making it much more flexible.
    So if i am right i need the following:
    1) in the child form+thread create an event at the moment the value is ready. (in the thread call/set "ParameterX ready" event)
    2) in the main program create a eventhandler/catcher somewhere and set it so it will respond to a "ParameterX ready" event and the call the corresponding update GUI routine.
    Indeed sounds real simple but at the moment i don't have a clue how.
    From you response i got som keywords so i can do some extra searching

    Not being able to do this via the IDE is not a problem at all.

  4. #4
    Join Date
    Jun 2010
    Location
    Germany
    Posts
    2,675

    Re: Thread with Delegate works want eventhandling

    Sure, you may create your own event delegates (for a starting point you may see http://msdn.microsoft.com/en-us/libr...nthandler.aspx, though IIRC you can't simply derive from that delegate, but there's a generic event delegate type available that probably simplifies things), but I never did that myself. Instead I used plain action and function delegates to implement simple callbacks. An example of this can be seen in the code samples from the WCF thread (that still hasn't been marked [RESOLVED], BTW... ), specifically the status report and shutdown request callbacks called from the Server class' heartbeat handler and the service contract method implementations except the last one.

    What I rather meant was attaching to a "foreign" event, yet of a type predefined by the .NET framework, as can be seen in http://www.codeguru.com/forum/showthread.php?t=514703. In that context I was thinking of the TextChanged event of some control for instance. As already suggested, from that handler you can reach the control that sent the event as safe_cast<Control ^>(sender) or the form hosting the control as safe_cast<Form ^>(safe_cast<Control ^>(sender)->Parent), where you may replace the concrete controll class for Control or your concrete form class for Form.

    Eventually, of course, the choice of strategy will depend on your specific requirements and, not to the least, your personal preference.
    I was thrown out of college for cheating on the metaphysics exam; I looked into the soul of the boy sitting next to me.

    This is a snakeskin jacket! And for me it's a symbol of my individuality, and my belief... in personal freedom.

  5. #5
    Join Date
    Oct 2011
    Posts
    26

    Re: Thread with Delegate works want eventhandling

    Continued the last week adding an event to a thread in a seperate form file.
    I think i am almost there but last two days i got stuck.

    Error is the last one i can't get rid off
    Code:
    Error	13	error C2664: 'WFA_1st_testy::Form_Dynamic_Download::PowerEvent::add' : cannot convert parameter 1 from 'WFA_1st_test::Form1::PowerEventDEL ^' to 'WFA_1st_testy::Form_Dynamic_Download::PowerEventDEL ^'	c:\..\..\Form1.h	2816	1	WFA_1st_test
    made an event file:
    PassEventClass.h
    Code:
    #pragma once
    	
    using namespace System;
    	
    public ref class PowerEventArgs: public EventArgs
           {
    
    		private: int _Voltage;
    		private: int _Current;
    		private: int _Power;
    
    		public: property int Voltage
            {
    			int get() {return _Voltage;} 
            }
    		public: property int Current
            {
                int get() { return _Current; }
            }
    		public: property int Power
            {
                int get() { return _Power; }
            }
    
    		public: PowerEventArgs(int Voltage, int Current, int Power)
            {
                _Voltage = Voltage;
                _Current = Current;
                _Power   = Power;
            }
        };
    Next in the subform + thread
    file: "Form_Dynamic_Download.h"
    Code:
    #pragma once
    #include "PassEventClass.h"
    
    namespace WFA_1st_testy {
    
    	using namespace System;
    ..
    ..
    	public ref class Form_Dynamic_Download : public System::Windows::Forms::Form
    	{
    	public:
    		Form_Dynamic_Download(void)
    ..
    ..
    ..
    
    	public: delegate void PowerEventDEL(System::Object^ sender, PowerEventArgs^ e);
    	public: event PowerEventDEL^  PowerEvent;
    
    	}; // END public ref class Form_Dynamic_Download : public System::Windows::Forms::Form
    in the file "Form_Dynamic_Download.cpp"
    at the end of the thread i added
    Code:
    			// Kick Event
    			//if(PowerEvent)// != null)
    			{ 
    				for(int i=1;i<=100;i++)
    			   	{
    					PowerEvent(this, gcnew PowerEventArgs(i, i*2 , i*3));
    					Thread::Sleep(20);
    				}
    			}
    and finally in the main form i added
    Code:
    	// in the constructor
    	FDD = gcnew Form_Dynamic_Download()
    ..
    ..
    	private: Form_Dynamic_Download^ FDD;	// Download Dynamic thread and Form
    
    	public: delegate void PowerEventDEL(System::Object^ sender, PowerEventArgs^ e);
    
    	public: void SetPowerEvent(System::Object^ sender, PowerEventArgs^ e)
            {
                if( /*this->*/ aquaGauge1->InvokeRequired )
                {
                    PowerEventDEL^ d = gcnew PowerEventDEL(this, &Form1::SetPowerEvent);
    				this->Invoke(d, gcnew array<Object^> { sender, e });
    		
                }
                else
                {
    				aquaGauge1->MaxValue = e->Power;
    				aquaGauge1->Value =  e->Voltage;
    		        //aguaGauge1->Value = e->Current .ToString();
    	
                }
            };
    	
    
    	// attach it from the main form.
    	private: System::Void TesssstAttach(void){FDD->PowerEvent +=gcnew PowerEventDEL(this, &Form1::SetPowerEvent);};
    1) Can someone see the (i hope) simple fault i still have?
    2) Second i want the file "PassEventClass.h" which contains only one class to be integrated in the file "Form_Dynamic_Download.h" as they are always a pair.
    when putting it as first the studio IDE cannot edit the form anymore putting it at the end caused other errors (Should be very easy but because of the main 1) error i didn't put much time in looking for a solution for this one)

  6. #6
    Join Date
    Jun 2010
    Location
    Germany
    Posts
    2,675

    Re: Thread with Delegate works want eventhandling

    Quote Originally Posted by NewVisual View Post
    1) Can someone see the (i hope) simple fault i still have?
    What this error message essentially is telling you is that you have two distinct delegate types named PowerEventDEL, wich are member type definitions of distinct forms which even reside in distinct namespaces. Despite their identical name and layout, the two types are not compatible with each other.

    To fix this, you need to "merge" the two in order to be able to exchange them between forms. Since instances of that type are to be exchanged between forms, it may be a good idea not to make the type definition a member of any of the form classes at all, to expess its "globality". And of course the type must only be defined in one namespace (otherwise you'll have two distinct types again). The best place to define your delegate type most probably is in a header file that gets included in the header or implementation file (as needed) of all the form classes that need to know about it. Defining the type in a common .h file (and only there) will avoid problems like the one you encountered here with almost absolute certainty.

    2) Second i want the file "PassEventClass.h" which contains only one class to be integrated in the file "Form_Dynamic_Download.h" as they are always a pair.
    when putting it as first the studio IDE cannot edit the form anymore putting it at the end caused other errors (Should be very easy but because of the main 1) error i didn't put much time in looking for a solution for this one)
    Yeah, that's simply not possible. Actually, the only way I know to handle this situation is to use a separate .h file for the class definition, just like you have it right now. It took quite a while for me to learn that, though (see this related thread: http://www.codeguru.com/forum/showthread.php?t=507099).
    I was thrown out of college for cheating on the metaphysics exam; I looked into the soul of the boy sitting next to me.

    This is a snakeskin jacket! And for me it's a symbol of my individuality, and my belief... in personal freedom.

  7. #7
    Join Date
    Oct 2011
    Posts
    26

    Re: Thread with Delegate works want eventhandling

    Quote Originally Posted by Eri523 View Post
    1) What this error message essentially is telling you is that you have two distinct delegate types named PowerEventDEL, wich are member type definitions of distinct forms which even reside in distinct namespaces. Despite their identical name and layout, the two types are not compatible with each other.
    You helped me out on a similar one before and while re-reading the error and this post i saw that i made 2 (different ) PowerEventDEL's. Solution of course would be reduce it to one unique one.
    Tried it in all 3 .h files but kept generating errors and errors.
    Tonight after reading your advise i again put it in the PassEventClass.h and Voila! no more errors (of course removing the other two) and a working program.
    I still don't know what i did wrong on my previous attempt.

    2) Yeah, that's simply not possible.
    The solution i already have wouldn't be my first choice but it works fine. I will continue programming on some more important ideas i have and leave this the way it is for the moment. In the furure (when i hopefully have some more programming skills) i will have another look at it.
    Thanks again Eri523

  8. #8
    Join Date
    Jun 2010
    Location
    Germany
    Posts
    2,675

    Re: Thread with Delegate works want eventhandling

    Quote Originally Posted by NewVisual View Post
    You helped me out on a similar one before [...].
    Really? I didn't recall that and in fact still don't.

    I still don't know what i did wrong on my previous attempt.
    Perhaps a namespace typo (in addition to initially defining them as members of distinct form classes)? I already wondered anyway why you had two namespaces named WFA_1st_test and WFA_1st_testy, and just now I realized that the y is right next to the t on the US keyboard...
    I was thrown out of college for cheating on the metaphysics exam; I looked into the soul of the boy sitting next to me.

    This is a snakeskin jacket! And for me it's a symbol of my individuality, and my belief... in personal freedom.

  9. #9
    Join Date
    Oct 2011
    Posts
    26

    Re: Thread with Delegate works want eventhandling

    Quote Originally Posted by Eri523 View Post
    Really? I didn't recall that and in fact still don't.
    http://www.codeguru.com/forum/showthread.php?t=517153
    same stupid error (C2664) defining two (exact) the same items in different files are NOT the same. unbelievable i saw that one after posting and not before.

    Errors are (in my case) result of some kind of code blindness.
    I write a piece of code in one file (.H) which i after testing split up in the right (.h and .cpp files) (bad programming style, i know).
    When it doesn't work i study the errors (with msdn & codeguru) and rework the code so it must work.
    If it doesn't i restudy etc etc. Every futher step in making the code work gets me more fustrated and the less study i do and the less thinking is do.

    Problem is that after the first modification i could be almost there (99%) but ruining it by not taking enough time to study what the errors say. (as yu never know how close you are)
    I must say lately by just taking time i manage to correct almost all errors.
    But some appear in this forum (with the solution so it may be of use for others)

  10. #10
    Join Date
    Jun 2010
    Location
    Germany
    Posts
    2,675

    Re: Thread with Delegate works want eventhandling

    Ah, thanks for the link. That's quite some time ago; must have been one of your first threads. And you're right, it's almost exactly the same scenario: attempting to define a class as a member type of distinct forms and then trying to exchange instances of it. It's just the namespace mismatch missing from the older scenario.

    Quote Originally Posted by NewVisual View Post
    Errors are (in my case) result of some kind of code blindness.
    I write a piece of code in one file (.H) which i after testing split up in the right (.h and .cpp files) (bad programming style, i know).
    Admittedly, this is a mistake I sometimes commit myself as well: Carelessly hacking something together and promising myself I'll clean up the mess later... I did that when starting just the app I'm working on right now. And while I guess the share of my total development time spent debugging usually is about 2 to 5 percent, I figure it's easily over a dozen percent this time.

    Also in this app, there's a bunch of closely related classes I defined in one common .h file and one common .cpp file right from the start. So far so good. However, over time, naturally, I added more and more member functions to more and more classes. Many of these functions are quite small and as usually I define those inline in the .h file. Currently the .cpp file has 99 lines and contains 8 function definitions, while the .h file has 380 lines and almost countless inline function definitions, mostly having sizes right around the threshold from which upward I usually define them in the .cpp file... Everything that prevents me from loosing overwiew is just the great Visual Studio IDE.

    [...]
    But some appear in this forum (with the solution so it may be of use for others)
    Yeah, a forum search can be quite useful, sometimes particularly for rather exotic problems that never would be cleared on MSDN. And that's one of the reasons why it's a really good idea to post those Cxxxx (and Lxxxx) error numbers: They are great to search for them!

    Also, it's a good idea (though not done quite often) to mark a thread like this one [RESOLVED] using the Thread Tools menu at the top of the thread display (unless we keep on discussing rather abstract coding style issues now... ). Among other things, this signals to forum users finding the thread later that they may perhaps find a solution to their problem inside.
    I was thrown out of college for cheating on the metaphysics exam; I looked into the soul of the boy sitting next to me.

    This is a snakeskin jacket! And for me it's a symbol of my individuality, and my belief... in personal freedom.

  11. #11
    Join Date
    Oct 2011
    Posts
    26

    Re: Thread with Delegate works want eventhandling

    Quote Originally Posted by Eri523 View Post
    Also, it's a good idea (though not done quite often) to mark a thread like this one [RESOLVED] using the Thread Tools menu at the top of the thread display
    Saw [RESOLVED] topics in the list before and shortly asked my self does a moderator do this (on it's own or after a messages to him) or can a user do this. A very very quick look in the past didn't show me how so i left al topics as they are.
    But from now on (after pointing out the very easy way how) i will be using it.

  12. #12
    Join Date
    Jun 2010
    Location
    Germany
    Posts
    2,675

    Thumbs up Re: [RESOLVED] Thread with Delegate works want eventhandling

    Re [RESOLVED]:

    And now, finally a little status update about the app I mentioned above, where I defined too much stuff in the .h file: Yesterday I was forced to clean up at least this part of the mess in the entire app, since some of the classes defined in the two mentioned files needed to mutually access their members. This only works when separating declaration and implementation of at least one of the classes involved; forward declarations of the classes don't suffice here. Of course it would have worked if I just moved the definitions of the functions actually involved in the mutual accesses into the .cpp file, but that would probably rather even have increased the overall mess. So I decided to go the whole nine yards (at least for this pair of source files... ), and now only these things are still defined in the .h file:
    • Constructors that are empty except for their initializer list.
    • Constructors that are empty except for plain assignments used to initialize base class members (and which may or may not have an initializer list for some of their own members). These constructors are written that way to postpone defining the required base class constructors to initialize the base class members the nice way from the derived class constructor's initializer list until I have a better overview which base class constructors actually are needed for that purpose.
    • Three predicate classes that are defined as public members of another class, including all their member functions. However, all of these functions are one-liners except for one with five lines. The predicate classes need to be accessible from client code in order to specify what to search for to (currently) one search function exposed by the enclosing class.

    Now the .cpp file is 427 lines and the .h file 289 lines. However, these code line counts are not really directly comparable to the ones from the earlier post, since I also added a bunch of additional functionality to the classes.
    I was thrown out of college for cheating on the metaphysics exam; I looked into the soul of the boy sitting next to me.

    This is a snakeskin jacket! And for me it's a symbol of my individuality, and my belief... in personal freedom.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured