Ken Phipps wrote: > I'm trying to create a simple component to draw rows/columns of > buttons. The first thing I'm trying to get done is the mouse event > handling. I was able to figure out how to catch the windows messages > and have them trigger published events from some examples I've found, > but I'm having a problem it. If you click very quickly in rapid > succession, the control seems to steal the mouse input for the entire > application. You can't even click on the form's close button as the > click gets taken. > > In a test project, I notice that in a listbox that displays the > events when they are fired, when it shows a MouseUp event firing > without a corresponding MouseDown, that's when the control will begin > to steal all mouse input from that point onward. You have to kill the > app at that point. I read a post through a Google search about > problems like this happening with TGraphicControl descendants, so I > tried changing it to a TCustomPanel, but the problem is still there.
TGraphicControl already has mouse events. Are you sure the default handling isn't sufficient for your needs? Remember that TGraphicControl doesn't have a handle of its own. It's just painted onto its parent. Any messages the control receives are second-hand -- messages that the windowed control decided to forward to the TGraphicControl. When you click a control rapidly, you're creating double-clicks as well as clicks. The message sequence usually looks like this: wm_LButtonDown wm_LButtonUp wm_LButtonDblClk wm_LButtonUp So that could explain your "up-with-down" phenomenon. It's possible for a control to capture the mouse events, so they all go to that control instead of the control the mouse cursor is currently over. Capture is supposed to be terminated when the mouse gets clicked, though, so even if the first click of the close button doesn't work, the next should, unless the control is re-capturing the mouse each time. It shouldn't be doing that, though. I don't recall how capturing works in the VCL; search Controls.pas for "capture" and see what it turns up. > procedure TMyButtonPanel.WM_LBUTTONDOWN(Var Msg: TWMLButtonDown); > begin > if Assigned(FOnMouseDown) then FOnMouseDown(Self, mbLeft, > KeysToShiftState(Msg.Keys), Msg.XPos, Msg.YPos); > if Assigned(FOnMouseClick) then FOnMouseClick(Self, 0); Merely depressing the mouse button does not usually count as a click. A click is a mouse down and a mouse up. If you're going to handling any kind of dragging, then you also need to pay attention to where the clicks occur; if the mouse up happens far enough away from the mouse down, then it's a drag and drop, not a click. In these message handlers, you're not calling the inherited methods. You're omiting code that would normally run. That's a problem until you veryify that all the code is stuff you _intend_ to skip. If you haven't already figured it out, writing a component will require reading a lot of the VCL source code, not only to see how descendants work, but to see how other unrelated controls respond to certain events or use features that you think you might need. Most of the Delphi documentation was not written with component developers as an audience. -- Rob _______________________________________________ Delphi mailing list -> [email protected] http://www.elists.org/mailman/listinfo/delphi

