Delphi iOS ListBox force selection update - ios

The way Delphi by default updates the selection with a timer can sometimes look funny if people scroll very fast (losing track), so I would like to disable that.
However, what I would like instead is that it would update selection immediately on the OnItemClick event. (i.e. I would like to force update the selection immediately before hen doing the rest of processing in the click event - that would be quite excellent.) However, after having tried quite a few things, this appears quite a bit more cumbersome to achieve than first expected.
I have tried force update selection, force animations, force updateselection etc. but none update the selection because of internal properties. Has anyone sucessfully done with without making changes to the listbox code directly?

Related

Delphi - hold the system messages/prevent UI redrawing?

It may sound silly, but I encountered a few situations, when I would like the application not to show what is happening, until an another specific action happens (stringGrids are filled with data, UI is prepared...). Is there a way to prevent messages from being sent from application to OS?
So, is there some oposit to
application.processmessages
?
Something like:
application.stopProcessingMessages;
fill stringGrids, prepare the UI...
application.processMessagesAgain;
?
Of course, I could run the actions in a separate thread, but there are situations where I either don't want to, or cannot do it in a separate thread.
Check TDataSet.DisableControls for data aware controls, and BeginUpdate / EndUpdate for some VCL / RTL classes (including TStrings), and - specific for the mentioned TStringGrid - see Delphi TStringGrid Flicker
It turned out, that although I thought, that using the WM_SETREDRAW message is the right solution, it has a few disadvantages. The biggest one is, that if used, user can click through the form. So the final solution is simply an empty TPanel placed over the whole form like this
panel1.Left:= 0;
panel1.Top:= 0;
panel1.Width:= frmMain.Width;
panel1.Height:= frmMain.Height;
After the form is prepared, the panel is shrunk, made invisible etc. It reliably hides every flickering and other things, that doesn't look good, and I want to hide them from the user.

Programmatically starting a jQuery UI sortable drag ? - Issues with IE8 compatibility

I'm using jQuery UI Sortable behavior and have come upon a situation in which I needed to start the sortable drag behavior from interaction with another element other than the original handle (which is not visible at the time).
I have managed to put together a way to achieve this thanks to suggestions in some posts and the use of jquery.simulate.js (used to run official jQUI tests) and I can procedurally start the sortable drag process in pretty much all browsers except IE8 and below, simulating the events like so:
item.simulate('mousedown',pos).simulate('mousemove',{ clientX: pos.clientX+1, clientY: pos.clientY});
Problem: In IE8 (or below), after the interaction with the outside 'handle' and simulation of mousedown and mousemove events, the drag is indeed correctly started, but as soon as the user really moves his mouse in any way/shape/form, the drag stops or cancels as if the 'mouseup' event had ocurred to finalize it.
I highly think this is due to some fundamental difference in the old fireEvent (IE8-) method vs the dispatchEvent that everything else uses, but cannot quite figure out how to, or if it's possible to prevent it.
What I'm looking for are snippets of what may be done to correct this or suggestions as to why this is happening and if it can have a workaround of some sort to prevent the cancelling (such as is the behavior that occurs in any other browser using dispatchEvent instead of fireEvent).
Have put together a small example for you of the success (any recent browser) or failure of the situation described: demo
TL;DR: Have put together a small way to procedurally start a jQUI sortable drag (through jquery.simulate.js, link above), but it fails to work or cancels itself in IE8-. Need some guidance or suggestions about how to overcome that. Check above demo

Is there a way to stop a TJvDocServerForm from hiding when its unpinned?

So my problem is that I have a TJvDocServerForm with an image inside, now all functionality works when its pinned, however when its unpinned and I try to use the mousewheel to zoom, the form hides straight after the zoom operation.
The zoom works through a scrollboxmousewheel event that triggers a
timer.
The timer then redraws the larger/smaller image through my own
image class when movement on the mousewheel has stopped.
Through break points it appears the draw is causing the form to
hide.
I believe this has got something to do with the focus being lost, however resetting the focus back to he form directly after the draw does not stop the hide as it has already been told to hide.
Is there a way to somehow lock the form from hiding until after the image has been redrawn?
This functionality (the unpinning thing) is rarely used. This code is extremely complex, and changing it is not recommended unless you like causing regressions. How common is the combination of mouse wheel + unpinning? So rare, I'd let it go, if I were you. If you can live without the unpin feature at all, just change dock styles. Personally I hate the unpinned state and I use a dock style that doesn't even support it. The unpinned "zoom away" animation may be directly linked to the focus-loss. You could store that state, wait until the next time through the message loop and then trigger the animation, if you wanted to, but even I, who have done lots of work in JvDocking source code, would be hesitant to try it.

How to tell what device triggered a particular event in Delphi?

I'm wondering if there's an easy way to tell which input device triggered a particular GUI event.
For example: A TButton.OnClick event gets fired. Did the user trigger it with a keyboard press (shortcut, Enter key for default button, space key for a focused button, etc.) or was it triggered with a mouse click? Is there any easy way to tell?
The reason I'd like to know is so that I can implement keyboard usage hints into some of our applications when the user uses the mouse to initiate actions that could also be done with the keyboard. Our systems on the shop floor are in pretty dusty/dirty environments, and mice tend to not hold up so well in them. Also, in many cases, there's simply not that much room for a mouse to be used. (No, keyboards without numeric keypads is not a solution. They're relied on too heavily.)
However, since our apps run in Windows, users tend to simply use the programs like they would at home -- with a mouse. There's nothing particularly wrong with that, but we've worked hard to optimize the input workflow to be keyboard friendly as well. It'd be nice if there was a low-impact way to indicate to our users that there's a way for them to do the things they're doing without having to grab the mouse.
There's no way to tell from within OnClick. However, you can also attach events to a control that will fire when the mouse rolls over it, which would probably be more appropriate for what you're trying to do anyway. Take a look at the OnMouseEnter and OnMouseLeave events. Also, if you really want something specific to happen when the mouse is clicked, you can attach it to OnMouseUp.

TStringGrid with BOTH editing AND range selection?

Question:
Can anyone point to an article or code samples anywhere on how to
provide BOTH editing AND range selection in a TStringGrid?
Yes, I KNOW there are third-party grids that do this, but it's
frustrating that the built-in grid lacks this basic capability.
Background:
It's pretty normal to expect to be able to both edit a cell in a grid,
and also to select a range of cells such as for a Copy operation.
As delivered, TStringGrid doesn't do that. It's either/or. In fact, the
docs tell us about the grid Options, "When goEditing is included in
Options, goRangeSelect has no effect".
However, it looks like it may be possible to do editing and rangeselects
in a TStringGrid anyway!!! Through careful use of the mousedown,
mouseup, selectcell and exit events, you can get dang close by switching
editing elements on and off at the right times. But I still don't have
it perfect, and that only covers mouse use, not keyboard changes.
I have not used the TStringGrid for this, so I can't provide a specific answer. But am I right in assuming you can manually (in code) start a cell being edited? That link implies it is possible even if the grid doesn't have goEditing included in its Options. (See below to work around this if this is not true.)
If so, I'd suggest the following approach:
Combined selection and edit behaviour
I find this is a good, Windows-standard-behaviour sort of approach:
Leave the grid in selection mode, so mouse and keyboard interaction selects cells
Trigger a cell being edited yourself, based on certain criteria (I think you are on the way to doing this from what you said in your last paragraph.) There are common ways to trigger editing, and the following criteria are what my programs follow when they do something similar with other controls:
Selection is normal. Ie, click to select, click and drag to multi-select, use the keyboard arrows and Shift or Control to select, etc.
A cell enters edit mode when either:
A cell is selected and the user presses Enter or F2 (F2 is the standard "Rename" or "Edit" shortcut, which works in a number of programs)
The user "slow-double-clicks" on a cell - ie, slow-double-clicks to select and edit, or clicks again, after a pause, on an already-selected cell. This mimics Explorer's behaviour, where if a file is selected and you later click on it, it enters the inline edit/rename mode. To implement this, record when a cell was last clicked (and selected.) If it is clicked again, and if the time is greater than GetDoubleClickTime then they have clicked twice, slowly, and enter edit mode. This allows you to distinguish between the first click to select, a double-click (to perform some kind of action), and a slow second click, to enter edit mode.
I also tend to check the mouse position, so that if an object is slow-double-clicked and it wasn't first selected (ie, this both selects the object and then enters edit mode) I verify the mouse hasn't moved very much. I use GetSystemMetrics to find the double-click distance, and check that the slow double click was within this box. (Because it's not a true doubleclick, I actually check the distance times 2. My action code is:
const int iMAX_MOVE_AMOUNT = ::GetSystemMetrics(SM_CYDOUBLECLK) * 2; (sorry, C++ not Delphi, but should be convertable easily enough!)
but I'm actually not certain if this is completely and utterly 100% to Windows guidelines. In practice users find it works as they expect, though.)
That should let you change between selecting and editing at the appropriate times with both the keyboard and the mouse.
Miscellaneous thoughts
You may find some of this is cleaner and easier to implement by subclassing TStringGrid and creating a new component. That will allow you to implement this in normal code and override the inbuilt behaviour (rather than event handlers) while keeping it invisible to the form code. It will also give you lower-level access to the mouse events or Windows messages than are exposed simply through events such as OnMouseDown. Finally, if there are problems with showing the editor when goEditing is included in Options, this will allow you to change that behaviour. You could also add your own events if you want your code to respond to certain things happening, such as creating an OnBeginEdit event, say.
Creating your own components is normally regarded as an advanced Delphi topic, but it's actually remarkably easy once you know how! This site has a few good topics that will introduce you to the subject in general, and if you go this route and encounter problems, Stack Overflow is of course a good place to ask questions :) The Embarcadero Delphi » VCL » Writing Components newsgroup / forum is also an excellent resource, in fact possibly even better than SO for this specific topic.
Hope that helps!
Yes it's old post, but the problem still exist on Delphi XE3.
To manage this feature I used next "trick" in SelectCell procedure :
if (ARow = StringGridParam.Row) then
begin
StringGridParam.Options:= StringGridParam.Options + [goEditing] - [goRowSelect];
end else begin
StringGridParam.Options:= StringGridParam.Options + [goRowSelect] - [goEditing];
end;

Resources