Tuesday, June 16, 2009

Capturing Input

What's special about mouse (and keyboard) capture?

IMO several objects can capture input, like a designer, drag manager, or any control. A designer is a special case, because it's bound to a special component (form) and its child controls, so that every control must check whether it's in csDesigning state itself, or its parent is in csDesigning state. Since further actions will differ between normal and designing state, a flag in every child control may be the best solution. All other captures are global, so that a check for a non-nil capture object will allow to forward all messages. Hereby the type of the capturing object seems not to play a role, the object captures all system messages from all receiving (windowed) components. In a very general model a reference to a WndProc can be used to allow capturing by objects of any kind. When the capture has to be released, a WM_CANCELMODE can be sent to the WndProc, and then the WndProc is reset to nil.

The global capture should be exclusive, the target can change only when the current target agrees to release the capture, or when the capture inevitably has to be released.

The drag manager should only capture input when the preconditions (threshold) are met. A delayed drag start, or competition between clicks and dragging, can be handled in the receiver of the uncaptured messages. A global variable can hold the position of the last button down message, for the threshold check. With the above convention, that an active capture is signaled by a non-nil WndProc, the messages can be routed immediately to the drag object (Delphi compatible). Then the different behaviour of drag-drop and drag-dock can be implemented in the according drag objects.

No comments:

Post a Comment