箭头键不在组件中工作

时间:2011-04-12 08:30:23

标签: delphi pascal custom-component

我使用Gecko SDK,这是一个允许您查看网页的组件 我使用这个组件来创建一个html编辑器。

关闭编辑网页时会出现此问题 问题是箭头键和选项卡不适用于我的组件。我试图找到这个问题的答案,但我找不到。我找到了一个曲目here,但该功能不起作用。

函数Movement (dx, dy)不存在。感谢您帮我解决这个问题。

Procedure Tform1.TraiteMessages(Var msg : TMsg; Var Handled: boolean);
var
  dx, dy : integer;
begin   dx: 0; dy := 0; 
  With msg do
  begin
    IF Message = WM_KEYDOWN then
    Case  wparam of
      VK_LEFT  : dx := -1;
      VK_RIGHT : dx :=  1;
      VK_UP    : dy := -1;
      VK_DOWN  : dy :=  1;
    end;
  end;
  IF (dy = 0) AND (Dx = 0) then Handled := false else
  begin
    handled := true;     // message traité
    Mouvement(dx, dy)    // exécution du tracé 
  end;
end;

3 个答案:

答案 0 :(得分:8)

将其添加到组件的类中:

procedure HandleDlgCode(var Msg:TMessage); message WM_GETDLGCODE;

然后在执行部分:

procedure TComponentClass.HandleDlgCode(var Msg:TMessage);
var
  M: PMsg;
begin
  Msg.Result := DLGC_WANTALLKEYS or DLGC_WANTARROWS or DLGC_WANTCHARS or DLGC_HASSETSEL;
  if Msg.lParam <> 0 then
    begin
      M := PMsg(Msg.lParam);
      case M.message of
        WM_KEYDOWN, WM_KEYUP, WM_CHAR:
        begin
          Perform(M.message, M.wParam, M.lParam);
          Msg.Result := Msg.Result or DLGC_WANTMESSAGE;
        end;
      end;
    end
  else
    Msg.Result := Msg.Result or DLGC_WANTMESSAGE;
end;

我刚从我自己的数字编辑器中复制粘贴此代码,因此它可以正常工作。

答案 1 :(得分:2)

这不是它的完成方式!
这是我们在1996年之前在德尔福做事的方式。
不需要这种复杂的Windows内容。

你正在编辑。
Delphi已经内置了2个编辑器。

  1. TMemo
  2. TRichEdit。
  3. 以TMemo作为您的父母开始,您有一个现成的编辑器,无需捕获光标键。

    interface
    
    type
      TMyComponent = class(TMemo)   
      //                   ^^^^^^^^^^^^^^^^^^^^<<- use this as your parent class
    
    protected
        procedure KeyPress(var Key: Char); override 
      ...
    
     implementation
    
     procedure TMyComponent.KeyPress(var Key: Char);
     begin
       inherited;
       //it works just like this, TMemo does everything.
     end;
    

    事实上,你可以省略KeyPress并开始研究其他事情。

    无需使用低级代码。你这样做太复杂

    获取一本delphi组件设计书。即使对于较旧的Delphi,也没有太大变化。 每个小时花在阅读这个主题的书上将节省20个小时的编码时间。

    祝你好运。

答案 2 :(得分:0)

Procedure Tform1.TraiteMessages(Var msg : TMsg; Var Handled: boolean);
var
  dx, dy : integer;
begin
  dx := 0;
  dy := 0; 
  With msg do
  begin
    IF Message = WM_KEYDOWN then
    begin
      Case  wparam of
        VK_LEFT  : dx := -1;
        VK_RIGHT : dx :=  1;
        VK_UP    : dy := -1;
        VK_DOWN  : dy :=  1;
      end;
    end;
  end;
  Mouvement(dx, dy);
  Handled := ((dy <> 0) or (dx <> 0));
end;

这会清理你的方法......现在,你应该在你的IF语句上放置一个断点,然后在你的Case条件中放置一个断点,首先确定你的消息钩子是否被触发,以及是否正在处理消息是你所期望的。

您的组件是否正确捕获了Key事件?你有另一个视觉组件聚焦?您是否已将表单的“KeyPreview”属性设置为True?

您可能还想尝试使用TApplicationEvents控件来处理您的密钥消息挂钩(如果您的组件是非可视的)。

在我的SVN存储库中查看this unit(用户名和密码都是“anon”,不带引号),因为它演示了即使在非可视组件上拦截和处理键输入也是如此。

希望这有帮助,祝你好运!

相关问题