Are events supposed to fire immediately on creation of a form?

Started by Dan English, May 07, 2010, 11:23:36 PM

Previous topic - Next topic

Dan English

I have a form that contains a listview control.  When I run the program, and the form containing the listview is loaded, it seems it's events are fired right away.  For example, I have some code that runs in the LBUTTONUP event.  I don't even click the listview on the form, and this event fires.

Same thing happens with a My Little Grid control on another form I have.  As soon as it's loaded, the MLGN_CELLALTERED is fired.  Seems to me it should only get to that point when I change something in a cell.

There are other events too that fire right away without me doing anything!  All I'm doing is opening forms from a parent form with this:


frmmain_Show hWndForm, %TRUE


Is this normal, or do I have to somehow temporarily disable all events until after the form is fully rendered?

Paul Squires

It is possible that some messages will fire during form creation. For example, FireFly uses SetWindowText api to set the text in a TextBox control during the WM_CREATE. Doing so could generate a EN_CHANGE notification. Having said that, the WM_LBUTTONUP message should not fire during WM_CREATE.

What I do sometimes is create a global variable to suppress messages.


Global gAllowMessages As Long

Function FORM1_WM_CREATE.......

....do some some stuff

   gAllowMessages = %TRUE

End Function

Function FORM1_TEXTBOX_EN_CHANGE......
 
    If gAllowMessages = %FALSE Then Exit Function

End Function


   
I don't have a list of messages that fire but most times you will find that it is a notification message.

Paul Squires
PlanetSquires Software

Dan English

Thanks for the idea, definitely makes sense.

I tried to implement it, but it doesn't seem to be consistently working.

In FF_AppStart, I put

Global gAllowMessages As Long

And in FORM1_WM_CREATE, I have


gAllowMessages = %FALSE
' populate listview function call...
gAllowMessages = %TRUE


And as the first line of the offending listview event (WM_LBUTTONUP), I have


If gAllowMessages = %FALSE Then Exit Function


Unfortunately it ignores the %FALSE setting of gAllowMessages, and continue right into the WM_LBUTTONUP event.  I've checked many times, and gAllowMessages does not seem to get reset anywhere.

Now here's an interesting observation....  if I modify the FORM1_WM_CREATE code to this


gAllowMessages = %FALSE
MsgBox str$(gAllowMessages)
' populate listview function call...
gAllowMessages = %TRUE


It works!  It's almost like the MsgBox call "registers" the change (it shows "0", or false), and the WM_LBUTTONUP exists as desired.  Of course, having a MsgBox pop up isn't exactly useful.  Could this be a bug of some sort?

Paul Squires

It's not a bug based on my understanding. Personally, I really don't know why your WM_LBUTTONUP is fireing. That doesn't make much sense because the mouse is not doing anything during form creation.

I can look at your project for you if you wish.
Paul Squires
PlanetSquires Software

David Kenny

Dan,

Have you tried creating a test project and put a msgbox call in the WM_LBUTTONUP event to see what happens on app startup?
In your original project, did you try to create the WM_LBUTTONUP event, or did it just show up?  You might find it useful to look at the generated code and even to use PBEdit to run it in the debugger.

David

Dan English

Paul -- thank you for the offer.  Let me see if I can trace through my code start to finish and narrow it down.  I don't want to waste your time if I did something completely stupid.  :)

David -- thanks for the idea.  I created a new project from scratch.  It has two forms.  To model it after my problematic application, the main form contains a button which launches a child modal form.  That modal form has a listview control, in which a MsgBox has been placed within the WM_LBUTTONUP event.  When I run the program, and click the main button to launch the form, no MsgBox appears.  It works as expected.  So as Paul said (and which also makes sense to me), the WM_LBUTTONUP is not firing, which is expected behaviour.

So after the success of the test project, I jumped back to my problem app.  No success yet... still firing off those events immediately.  I've got to have some erroneous code in there that is triggering this.  I'm going to go trace the sequence of events best I can.  I'm hoping something becomes clear before I'm forced to decode the generated code.  Not looking forward to that!

Dan English

Alright, two hours later, and I still can't get the WM_LBUTTONUP event to stop firing automatically.  I've even stripped down the app of several of its child forms and modules.  It's absolutely bare bones now, and still firing the event.  Driving me a little nuts right now...

Could someone else please run this attached project and let me know if a message box pops up when clicking the "CLICK ME!" label?

Thanks!

Cho Sing Kum

The problem may not be what you were thinking causes it.

1) frmPayMain displayed centrescreen.
2) I click on the Label5 "CLICK ME!".
3) Before I could even let go of the mouse, frmPay006 showed on top of frmPayMain and with my mouse on it.
4) I let go of the mouse and FRMPAY006_LVWPAY006_WM_LBUTTONUP fired.

If I move frmPayMain away to one side such that my mouse will not be on top of frmPay006, there is no problem.

To solve this:

Replace the Click Me! label with a Command Button. This way even with frmPay006 on top, the FRMPAY006_LVWPAY006_WM_LBUTTONUP will NOT fire. I tested this.

Edit: With the CommandButton, frmPay006 only show when the mouse button is let go. This explain why.

Edit again: If you need to use Label for whatever reason, then use

FRMPAYMAIN_LABEL5_WM_LBUTTONUP to show frmPay006

instead of

FRMPAYMAIN_LABEL5_STN_CLICKED


Paul Squires

You are correctly showing the frmPay006 form in response to the STN_CLICKED message handler for the Label. That is no problem. The way I see it is that the popup form displays between the time that you press down on the mouse and release it. By the time you release the mouse the ListView is the control underneath is thereby triggering the LBUTTONUP for the listview.

Personally, I would not use LBUTTONUP to test for any type of "click" message event. If you want to know when a row in the listview has been clicked on then use the code in this post: http://www.planetsquires.com/protect/forum/index.php?topic=1935.msg15937#msg15937

The @pNMLV.iItem variable holds the number of the row that is clicked on.

Likewise, you could respond to the TVN_SELCHANGED notification message whenever the slection of a row in the listview changes.

Paul Squires
PlanetSquires Software

Dan English

Ok, things are finally on track.  You guys are right -- that makes sense what's going on.  Thank you for pointing this out!

I changed my main form to use command buttons, and moved the *_Show lines into the corresponding command button click events.  No more event firing on listviews-contained forms.  However, a form on which a My Little Grid control control appears is firing its CELLALTERED event immediately.  I suspect this is unrelated though, and is firing due to the fact I immediately populate the grid on the form's WM_CREATE (thus altering all its cells and presumably triggering the CELLALTERED event).

Might have to try the gAllowMessages flag in this case...

Paul Squires

Quote from: Dan English on May 10, 2010, 12:40:58 PMHowever, a form on which a My Little Grid control control appears is firing its CELLALTERED event immediately.  I suspect this is unrelated though, and is firing due to the fact I immediately populate the grid on the form's WM_CREATE (thus altering all its cells and presumably triggering the CELLALTERED event).

Might have to try the gAllowMessages flag in this case...
I agree. using gAllowMessages should fix that problem.
Paul Squires
PlanetSquires Software

Roger Garstang

#11
Gotta be careful anywhere you use messageboxes too as usually they don't "cleanup" when they process messages.  They take a KeyDown or MouseDown, but usually don't clear the up of either.  I always suggest using Down messages only. When processing Keys this is important too since key repeat fires multiple keydown but one keyup, so if you want to capture accurately a keyup won't do it.  Your processing can begin quicker too since the down is the first event.

Dan English

Finally got rolling again on the project after a short break.  Thanks for the help guys.

(And for that bonus link to the listview double-click code... put that in and it's working great!)