W moim jest miejsce, w którym chcę posłuchać kluczowych zdarzeń i przechwycić klucz ESC
i obsłużyć go w moim komponencie, skonsumować/"zjeść" naciśnięcie klawisza, tak że na przykład formularz właściciela nie będzie go obsługiwał na tym etapie. Podobnie jak w TDragObject
po uruchomieniu przeciągnij i anuluj, naciskając ESC
.W jaki sposób mój TComponent może przechwycić klucz ESC i obsłużyć go?
Problem polega na tym, że TDragObject
ma, który jest powiadamiany przez jego właściciela o numerze CN_KEYDOWN
. Ale nikt nie powiadamia mojego komponentu.
Czy muszę zastąpić formularz WindowProc
moim własnym? Jeśli tak, to jak to zrobić poprawnie "po książce", że tak powiem?
Wystarczy być w 100% jasne:
TMyComponent = class(TComponent)
zrobiłem mały test i wydaje się działać:
TMyComponent = class(TComponent)
private
FOldWindowProc: TWndMethod;
FParentForm: TCustomForm;
procedure FormWindowProc(var Message: TMessage);
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
end;
...
constructor TMyComponent.Create(AOwner: TComponent);
begin
if not (AOwner is TWinControl) then
raise Exception.Create('TMyComponent.Create: Owner must be a TWinControl');
inherited Create(AOwner);
// hook parent form
FParentForm := GetParentForm(TWinControl(Owner));
if Assigned(FParentForm) then
begin
FOldWindowProc := FParentForm.WindowProc;
FParentForm.WindowProc := FormWindowProc;
end;
end;
destructor TMyComponent.Destroy;
begin
// unhook parent form
if Assigned(FParentForm) then
FParentForm.WindowProc := FOldWindowProc;
inherited;
end;
procedure TMyComponent.FormWindowProc(var Message: TMessage);
begin
FOldWindowProc(Message);
if Message.Msg = CM_CHILDKEY then // CM_CHILDKEY -> CM_DIALOGKEY -> CM_DIALOGCHAR
begin
OutputDebugString('CM_CHILDKEY');
if Message.WParam = VK_ESCAPE then
begin
Beep;
// do my stuff...
Message.Result := 1; // consume keystroke
end;
end;
end;
Zastanawiam się, czy jest to podejście właściwe/tylko.
Przeciąganie obejmuje nową pętlę modalną. To nie jest opcja dla ciebie. Trudno zobaczyć, jak możesz to zrobić bez współpracy z gospodarzem. –
@DavidHeffernan, OP powiedział "jak w TDragObject", to tylko przykład i zakładam, że OP chce tylko klucza ESC, nic więcej, nic mniej. ESC jest klawiszem dialogu. Po prostu nie mam 1 minuty na odświeżenie komunikatu code/API/windows. –
@Cosmin Pętla modalna operacji przeciągania jest właścicielem i pompuje kolejkę. I tak można uzyskać naciśnięcia klawiszy. Ale komponent w formularzu nie ma takiego luksusu. Jak zamierzasz wejść do pętli komunikatów aplikacji? –