I had to fix this problem recently, and it is awfully strange. Pressing Ctrl+X and Ctrl+V makes the TActiveFormControl.TranslateAccelerator method return S_FALSE. Pressing Ctrl+C, the return is S_OK. So in order to fix this, I want to return S_FALSE when Ctrl+C is pressed. I do this by creating a new TActiveXControlClass that overrides the TranslateAccelerator method and returns S_FALSE when needed. The only other thing that needs to be done is to use the new class in your TActiveFormFactory.Create call so that we can get calls to our TranslateAccelerator method and do our own custom stuff.
One caveat: Things are working quite well in IE6. I'm not sure what will happen in other ActiveX containers. Use at your own risk, or at least test in whatever container you're deploying to first!
Here's the code. Please let me know what you think. If you see any improvements that can be made, I'd love to hear about those, too. But at least, for now, my customers are happy again.
type TTranslateAcceleratorFormControl = class(TActiveFormControl, IOleInPlaceActiveObject) function TranslateAccelerator(var msg: TMsg): HResult; stdcall; end; { TTranslateAcceleratorFormControl } { When pressing Ctrl+C, the inherited method returns S_OK meaning that the container thinks it did what it needed to, and therefore, the message is consumed. When pressing Ctrl+X or Ctrl+V, the return from the inherited method is S_FALSE. Therefore, we will always call the inherited method to allow for default processing. If the return is S_OK, and the message is WM_KEYDOWN, and we have pressed Ctrl+C, we override the result and return S_FALSE instead. } function TTranslateAcceleratorFormControl.TranslateAccelerator(var msg: TMsg): HResult; begin Result := inherited TranslateAccelerator(msg); if Result = S_OK then begin if (msg.message = WM_KEYDOWN) and (GetKeyState(VK_CONTROL) < 0) and (msg.wParam = 67) then Result := S_FALSE; end; end; initialization TActiveFormFactory.Create( ComServer, //TActiveFormControl, // standard Delphi-generated class TTranslateAcceleratorFormControl, // our replacement class TAFActionTest, Class_AFActionTest, 1, '', OLEMISC_SIMPLEFRAME or OLEMISC_ACTSLIKELABEL, tmApartment); end.
Disclaimer The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.