Reputation: 3056
Core problem: I don't like the way how TcxGrid delete (that is initiated by the default Ctrl+Del shortcut key for the TcxGrid or by the Delete button of the cx-navigator) is working: it is simple and direct call to the delete of the underlying dataset, there is no TcxGrid(/DataController).OnDelete(Sender: TObject, var AHandled: Boolean)
event for the cxGrid or cxGridDataView. And from https://www.devexpress.com/Support/Center/Question/Details/Q308755/tcxgrid-deleting-record I understand that I can only configure the confirmation message, but I have no control over the Delete itself, i.e., I can not implement custom Delete and therefore I don't even try to ask for the straight solution of this problem. My question is about workaround.
That is why I am refusing to use cx-navigator and I opt to introduce TAction that handles Ctrl+Del shortcut key for the entire form. I have multiple grids on the form each with its own problematic Delete procedure that should be handled in non-standard way by the custom procedure.
That is why my DeleteAction determines the ActiveControl (TcxGridSite, TcxGrid) initially and then calls relevant Delete procedure afterwards. All that is fine. But some other components (e. g. TcxDBTextEdit) have default Ctrl+Del handling as well and that handling is very, very good. But if shortcut key Ctrl+Del is handled by action (and it is marked as handled even in the case when no active grid can not be found and therefor even in the case when ActionExecute has not done anything useful) then further propagation is stopped. That can be observed empirically and that can be seen theoretically from http://edn.embarcadero.com/article/38447 .
But maybe still there is some workaround how the shortcut key that has been processed by the ActionExecute can still be propagated further to the default components if they are Active controls.
I know that TAction is for (form-wide global) menu functionality but TcxGrid is not extensible enough and that is why should try to stretch the Delphi TAction design as well.
Upvotes: 1
Views: 391
Reputation: 54832
Probably there would be various ways to achieve the processing you require, there are quite a few places you can intervene during key processing, as you've already read from Peter Below's article linked in your question.
A place to intervene that I can think of which would contain all the pieces together is the form's IsShortCut
method. One probable disadvantage of such a method could be that you'd have to implement it on all the forms that you want their key handling behavior changed.
Normally key processing continues only if it's not handled by shortcuts. Below solution reports the shortcut to be not processed for that reason, but then has to cause the execution of the action manually. I tested the code with a regular edit as can be seen, but I guess it shouldn't make any difference.
function TForm1.IsShortCut(var Message: TWMKey): Boolean;
begin
if (ActiveControl is TEdit) and (Message.CharCode = VK_DELETE) and
(KeyDataToShiftState(Message.KeyData) = [ssCtrl]) then begin
Result := False; // if you don't require the action to be executed, just exist here
ActionList1.IsShortCut(Message); // executes the action, ignore result
// returning false will result in main form's shortcut handler to be called
// below is only required if this is the main form
if Application.MainForm = Self then
Message.CharCode := 0;
end else
Result := inherited IsShortCut(Message);
end;
Upvotes: 2