c#:
2 Questions: (1) The documentation says application.run() creates a standard message loop on the current thread and "optionally" shows a form. This is really confusing because I was of the understanding that application.run() creates a message loop for the form and passes all messages to it. If showing the form is optional, and I want to to display 2 forms, which form will application.run() pass the windows messages to? (2) I believe there is an internal WndProc() function internally maintained and exposed through events in C#? When I inherit from a base class (say System.Control) and my derived class being Form, the paint event is "inherited from Control" right, so my Form should have its own paint event right. But then I've read a book that said OnPaint() of Control is responsible for calling the registered event handlers, but how can it call event handlers that derived classes have registered? Isn't that the job of the OnPaint() method of the derived class (in this case form). Thanks a lot, Warm Regards, Joel.
First, that was so *not cool*. Why in the world did you set the follow-up to: field to the dotnet.general newsgroup? Please, if you are posting a message to a newsgroup, then replies to that message belong in that newsgroup. Conversely, if you think you need to change the follow-up to: field to something entirely different from the newsgroup in which you posted the message, then you are posting to the wrong newsgroup in the first place. There's almost never a good reason to set to the follow-up to: field when posting. That said, here's my answer, in the newsgroup in which you originally posted (I managed to post it twice to the wrong newsgroup before I noticed that you'd changed the follow-up newsgroup on us): [quoted text, click to view] "Joel" <joelagnel@gmail.com> wrote in message news:1160799513.977616.231540@i3g2000cwc.googlegroups.com... >2 Questions: > > (1) > The documentation says application.run() creates a standard > message loop on the current thread and "optionally" shows a > form.
Yes...if you pass a form to Application.Run() it will show that form for you. [quoted text, click to view] > This is really confusing because I was of the understanding > that application.run() creates a message loop for the form and > passes all messages to it.
A message loop isn't for a specific form. It's for a specific thread. [quoted text, click to view] > If showing the form is optional, and I want to to display 2 forms, > which form will application.run() pass the windows messages to?
Whichever one the message is intended for. One need not pass any form to the Application.Run method, and passing a form to the Application.Run method doesn't affect how messages get processed by the forms, other than the Run method doing a little extra handling on the passed-in form so that it returns when that form is closed. Messages get dispatched to the correct form based on its window handle, just as they do with a normal Win32 program with multiple windows. [quoted text, click to view] > (2) > I believe there is an internal WndProc() function internally maintained > and exposed through events in C#?
Yes and no. There is an internal WndProc somewhere, and you do get notification of messages via events. But this isn't the only way to handle some events. If there's already a handler defined in the class already, you can override that method instead of registering an event handler. [quoted text, click to view] > When I inherit from a base class (say System.Control) and my derived > class being Form, the paint event is "inherited from Control" right, so > my Form should have its own paint event right. > But then I've read a book that said OnPaint() of Control is responsible > for calling the registered event handlers, but how can it call event > handlers that derived classes have registered? Isn't that the job of > the OnPaint() method of the derived class (in this case form).
My (very limited :) ) understanding of how this works is this: You can either register an event handler, or you can override the OnPaint method. In either case, you will get your code to run when a paint event happens. The difference is that there can be multiple event handlers, but only one OnPaint method. Personally, I find the concept of multiple paint event handlers to be a little odd, since if you really have multiple places in the code handling the paint event, it seems like there could be some confusion as to how the window actually gets drawn. But I suppose there's probably some situation in which this makes sense, and at least with this design it's consistent with other standard window messages. Anyway, what this means is that you can either register an event handler, in which case the base Control.OnPaint method calls you and other registered event handlers. Or, you can override the OnPaint method itself, in which case the base class version isn't called implicitly, so you need to call it explicitly to ensure that any other event handlers are called. Hope that makes sense. I'm still trying myself to understand whether it's better to register an event handler or override the method, so I'm not sure any of the above necessarily clears things up, as opposed to adding new questions. :) Pete
Thank you for your response and I apologise for posting the follow-up. I feel much better about the first question I asked but I still am very much confused about the paint event handler. I think my question was not clear, I know that we can either override the OnPaint() method of Control or have our own paint event handlers. My confusion is in the second case where Form class itself registers its own event handlers. Form inherits the "paint" event from Control class and then I register whatever event handlers I want using my Form object, I believe Control base class has no idea about these event handlers because the inherited paint event has registered these paint event handlers and they're visible only to the derived class (form) and not the base class (Control)? So How can the base Control class call these event handlers (docs say so) Its the duty of the form class to call its event handlers if any right? Let me take an example: I have a base class with some event defined as protected or public and a derived class which inherits from it. The derived class has inherited the events of the base class. Now I register one or more event handlers in my derived class's event handler (which is inherited). Next the event occurs. When the event occurs, one or more registered event handlers are called right. Events are like multi cast delegates and they call one or more functions in any given order. I want to know, which event holds the delegate list, is it the base class or the derived class? It most obviously should be the derived class, but in the Control-Form case, it seems to be the base class (Control) whose paint event holds the list of the registered paint event handlers of the derived class. Thank you for your time. Warm Regards, Joel [quoted text, click to view] Peter Duniho wrote: > First, that was so *not cool*. Why in the world did you set the follow-up > to: field to the dotnet.general newsgroup? Please, if you are posting a > message to a newsgroup, then replies to that message belong in that > newsgroup. Conversely, if you think you need to change the follow-up to: > field to something entirely different from the newsgroup in which you posted > the message, then you are posting to the wrong newsgroup in the first place. > > There's almost never a good reason to set to the follow-up to: field when > posting. > > That said, here's my answer, in the newsgroup in which you originally posted > (I managed to post it twice to the wrong newsgroup before I noticed that > you'd changed the follow-up newsgroup on us): > > > "Joel" <joelagnel@gmail.com> wrote in message > news:1160799513.977616.231540@i3g2000cwc.googlegroups.com... > >2 Questions: > > > > (1) > > The documentation says application.run() creates a standard > > message loop on the current thread and "optionally" shows a > > form. > > Yes...if you pass a form to Application.Run() it will show that form for > you. > > > This is really confusing because I was of the understanding > > that application.run() creates a message loop for the form and > > passes all messages to it. > > A message loop isn't for a specific form. It's for a specific thread. > > > If showing the form is optional, and I want to to display 2 forms, > > which form will application.run() pass the windows messages to? > > Whichever one the message is intended for. One need not pass any form to > the Application.Run method, and passing a form to the Application.Run method > doesn't affect how messages get processed by the forms, other than the Run > method doing a little extra handling on the passed-in form so that it > returns when that form is closed. Messages get dispatched to the correct > form based on its window handle, just as they do with a normal Win32 program > with multiple windows. > > > (2) > > I believe there is an internal WndProc() function internally maintained > > and exposed through events in C#? > > Yes and no. There is an internal WndProc somewhere, and you do get > notification of messages via events. But this isn't the only way to handle > some events. If there's already a handler defined in the class already, you > can override that method instead of registering an event handler. > > > When I inherit from a base class (say System.Control) and my derived > > class being Form, the paint event is "inherited from Control" right, so > > my Form should have its own paint event right. > > But then I've read a book that said OnPaint() of Control is responsible > > for calling the registered event handlers, but how can it call event > > handlers that derived classes have registered? Isn't that the job of > > the OnPaint() method of the derived class (in this case form). > > My (very limited :) ) understanding of how this works is this: > > You can either register an event handler, or you can override the OnPaint > method. In either case, you will get your code to run when a paint event > happens. The difference is that there can be multiple event handlers, but > only one OnPaint method. > > Personally, I find the concept of multiple paint event handlers to be a > little odd, since if you really have multiple places in the code handling > the paint event, it seems like there could be some confusion as to how the > window actually gets drawn. But I suppose there's probably some situation > in which this makes sense, and at least with this design it's consistent > with other standard window messages. > > Anyway, what this means is that you can either register an event handler, in > which case the base Control.OnPaint method calls you and other registered > event handlers. Or, you can override the OnPaint method itself, in which > case the base class version isn't called implicitly, so you need to call it > explicitly to ensure that any other event handlers are called. > > Hope that makes sense. I'm still trying myself to understand whether it's > better to register an event handler or override the method, so I'm not sure > any of the above necessarily clears things up, as opposed to adding new > questions. :) > > Pete
[quoted text, click to view] "Joel" <joelagnel@gmail.com> wrote in message news:1160999165.328201.103510@h48g2000cwc.googlegroups.com... > Thank you for your response and I apologise for posting the > follow-up.
Apology accepted. :) [quoted text, click to view] > I feel much better about the first question I asked but I > still am very much confused about the paint event handler.
Me too...but I think in a different way than you are. :) [quoted text, click to view] > [...] > I want to know, which event holds the delegate list, is it the base > class or the derived class? > It most obviously should be the derived class, but in the Control-Form > case, it seems to be the base class (Control) whose paint event holds the > list of the registered paint event handlers of the derived class.
It seems that you're not understanding how inheritance works. When a class derived from Control inherits an event from that class, there is no "derived event". The inheriting class simply gets to use the base class's event as if it were its own. In only specific situations will an inherited member of a class be different from the base class's member. In each of those situations, some additional work must be done to explicitly cause the inherited member to actually supercede the base member. At the minimum, a new instance of that member must be defined in the derived class. And typically, this is done only for override (virtual) methods, which ensures that the base class uses the same new instance of the member that the derived class is using. This extra work doesn't exist for the events you're asking about. The derived classes don't define new events that supercede the base class's instances. So when a derived class inherits those events, they are the exact same events known to the base class. It works in exactly the same way that a method in the base class is inherited in the derived class without a new instance of the method being created. When the derived class calls the inherited method, the code that's run is the code that was originally defined for the base class, not some new code that was created as a consequence of the inheritance. Likewise, the inherited event is not some new event that was created through inheritance, but rather just the original event the base class had. So, if you are using the paint event to register a paint handler, you use the same paint event defined in the base Control class, even though you may be dealing with an inherited class. There's no additional event in the derived class unless one has been explicitly defined, and one hasn't been explicitly defined because it's not needed. Pete
Wow, ok, I have a somewhat clear picture of what's going on now thanks to you and this is what I think happens when a paint event occurs in the form object: (1) When a paint event occurs in the form, since form has inherited from control, it is actually the base class paint event we're dealing with here and it calls the OnPaint() method by default in the control class. (2) If we've overriden control's OnPaint() method in the form class, then whenever the paint event occurs, OnPaint() of form class is called. That leaves me with just one doubt, if we register events in form, then Control's OnPaint() method has to individually call each of these registered event handlers (as the docs say). why is this required in the Control class? I mean, when we register event handlers using multi cast delegates and then the event occurs, all the registered event handlers are called automaticaly right? then why does OnPaint() of control have to call these registered event handlers individually? I even read a book with an example like this: There's a form class inheritting from control and registering a paint event handler in the form class. Then there's this other part of the code when the OnPaint() method of the form class overrides the base OnPaint() method. Now in the OnPaint() code (for form class), base.OnPaint() is not called. The form class paints whatever it has to, without calling the base OnPaint() method. As a consequence, the "registered" event handler is not called at all. The book says OnPaint() of Control has to call these registered event handlers which is very confusing because OnPaint() itself is an event handler for the paint event? Thanks a lot! Warm Regards, Joel [quoted text, click to view] Peter Duniho wrote: > "Joel" <joelagnel@gmail.com> wrote in message > news:1160999165.328201.103510@h48g2000cwc.googlegroups.com... > > Thank you for your response and I apologise for posting the > > follow-up. > > Apology accepted. :) > > > I feel much better about the first question I asked but I > > still am very much confused about the paint event handler. > > Me too...but I think in a different way than you are. :) > > > [...] > > I want to know, which event holds the delegate list, is it the base > > class or the derived class? > > It most obviously should be the derived class, but in the Control-Form > > case, it seems to be the base class (Control) whose paint event holds the > > list of the registered paint event handlers of the derived class. > > It seems that you're not understanding how inheritance works. When a class > derived from Control inherits an event from that class, there is no "derived > event". The inheriting class simply gets to use the base class's event as > if it were its own. > > In only specific situations will an inherited member of a class be different > from the base class's member. In each of those situations, some additional > work must be done to explicitly cause the inherited member to actually > supercede the base member. At the minimum, a new instance of that member > must be defined in the derived class. And typically, this is done only for > override (virtual) methods, which ensures that the base class uses the same > new instance of the member that the derived class is using. > > This extra work doesn't exist for the events you're asking about. The > derived classes don't define new events that supercede the base class's > instances. So when a derived class inherits those events, they are the > exact same events known to the base class. It works in exactly the same way > that a method in the base class is inherited in the derived class without a > new instance of the method being created. When the derived class calls the > inherited method, the code that's run is the code that was originally > defined for the base class, not some new code that was created as a > consequence of the inheritance. Likewise, the inherited event is not some > new event that was created through inheritance, but rather just the original > event the base class had. > > So, if you are using the paint event to register a paint handler, you use > the same paint event defined in the base Control class, even though you may > be dealing with an inherited class. There's no additional event in the > derived class unless one has been explicitly defined, and one hasn't been > explicitly defined because it's not needed. > > Pete
[quoted text, click to view] "Joel" <joelagnel@gmail.com> wrote in message news:1161069085.609082.13800@f16g2000cwb.googlegroups.com... > Wow, ok, I have a somewhat clear picture of what's going on now > thanks to you and this is what I think happens when a paint event > occurs in the form object: > > (1) When a paint event occurs in the form, since form has inherited > from control, it is actually the base class paint event we're dealing > with here and it calls the OnPaint() method by default in the control > class.
Sort of, but not exactly. :) There are, as far as I know, two different types of "event" going on here. There's the Windows API "WM_PAINT" event, and there is the .NET "Paint" event. When the WM_PAINT event occurs, this causes the .NET Control class window proc to call the OnPaint method (or maybe there's a more generic .NET window proc that calls the Control class's OnPaint method...I'm not sure). This method then, among other things, calls the delegates assigned to the "OnPaint" event within the class. That is: the Control.OnPaint method is NOT an event handler for the Paint event. It is what calls the event handlers for the Paint event (that is, it "raises" the event). [quoted text, click to view] > (2) If we've overriden control's OnPaint() method in the form class, > then whenever the paint event occurs, OnPaint() of form class is > called.
Whenever the WM_PAINT event occurs, the OnPaint() method of the form class is called. [quoted text, click to view] > That leaves me with just one doubt, if we register events in form, > then Control's OnPaint() method has to individually call each of these > registered event handlers (as the docs say). why is this required in > the Control class?
Good question. Hopefully the above clears it up a little. When you override the OnPaint method, what you are doing is hooking into the response to the WM_PAINT event, *not* the .NET Paint event. Registered event handlers, on the other hand, are trying to respond to the .NET Paint event. Normally, Control.OnPaint is what calls the delegates registered for the Paint event. If you override that method, then your own OnPaint method is called, rather than the Control.OnPaint method. If in your own code you don't call the base OnPaint method, then the code in that method that calls the registered handlers for the Paint method never get called. You could, of course, simply call the delegates directly from the event, rather than calling the base OnPaint method. But from an object-oriented perspective it makes more sense in this case to simply borrow the existing functionality in the base class, rather than trying to reimplement it in your own. [quoted text, click to view] > I mean, when we register event handlers using multi cast delegates > and then the event occurs, all the registered event handlers are called > automaticaly right? then why does OnPaint() of control have to call > these registered event handlers individually?
Because the OnPaint method *isn't* a registered event handler for the Paint event. It's what *calls* the registered event handlers for the Paint event. [quoted text, click to view] > [...] > The book says OnPaint() of Control has to call these registered event > handlers which is very confusing because OnPaint() itself is an event > handler for the paint event?
I hope that I was able to explain above that it's not true that the "OnPaint() itself is an event handler for the paint event". Pete
Thanks a lot, you've been of gr8 help. :) Regards Joel [quoted text, click to view] Peter Duniho wrote: > "Joel" <joelagnel@gmail.com> wrote in message > news:1161069085.609082.13800@f16g2000cwb.googlegroups.com... > > Wow, ok, I have a somewhat clear picture of what's going on now > > thanks to you and this is what I think happens when a paint event > > occurs in the form object: > > > > (1) When a paint event occurs in the form, since form has inherited > > from control, it is actually the base class paint event we're dealing > > with here and it calls the OnPaint() method by default in the control > > class. > > Sort of, but not exactly. :) > > There are, as far as I know, two different types of "event" going on here. > There's the Windows API "WM_PAINT" event, and there is the .NET "Paint" > event. When the WM_PAINT event occurs, this causes the .NET Control class > window proc to call the OnPaint method (or maybe there's a more generic .NET > window proc that calls the Control class's OnPaint method...I'm not sure). > This method then, among other things, calls the delegates assigned to the > "OnPaint" event within the class. > > That is: the Control.OnPaint method is NOT an event handler for the Paint > event. It is what calls the event handlers for the Paint event (that is, it > "raises" the event). > > > (2) If we've overriden control's OnPaint() method in the form class, > > then whenever the paint event occurs, OnPaint() of form class is > > called. > > Whenever the WM_PAINT event occurs, the OnPaint() method of the form class > is called. > > > That leaves me with just one doubt, if we register events in form, > > then Control's OnPaint() method has to individually call each of these > > registered event handlers (as the docs say). why is this required in > > the Control class? > > Good question. Hopefully the above clears it up a little. When you > override the OnPaint method, what you are doing is hooking into the response > to the WM_PAINT event, *not* the .NET Paint event. Registered event > handlers, on the other hand, are trying to respond to the .NET Paint event. > > Normally, Control.OnPaint is what calls the delegates registered for the > Paint event. If you override that method, then your own OnPaint method is > called, rather than the Control.OnPaint method. If in your own code you > don't call the base OnPaint method, then the code in that method that calls > the registered handlers for the Paint method never get called. > > You could, of course, simply call the delegates directly from the event, > rather than calling the base OnPaint method. But from an object-oriented > perspective it makes more sense in this case to simply borrow the existing > functionality in the base class, rather than trying to reimplement it in > your own. > > > I mean, when we register event handlers using multi cast delegates > > and then the event occurs, all the registered event handlers are called > > automaticaly right? then why does OnPaint() of control have to call > > these registered event handlers individually? > > Because the OnPaint method *isn't* a registered event handler for the Paint > event. It's what *calls* the registered event handlers for the Paint event. > > > [...] > > The book says OnPaint() of Control has to call these registered event > > handlers which is very confusing because OnPaint() itself is an event > > handler for the paint event? > > I hope that I was able to explain above that it's not true that the > "OnPaint() itself is an event handler for the paint event". > > Pete
Don't see what you're looking for? Try a search.
|