捐赠 | 广告 | 注册 | 发布 | 上传 | 关于我们    
  粤ICP备10103342号-1 DELPHI盒子 | 盒子文章 | 盒子问答悬赏 | 最新更新 | 盒子检索 | 下载中心 | 高级搜索    
  精品专区 | 繁體中文 | 奖励公告栏 | 直通车账号登陆 | 关闭GOOGLE广告 | 临时留言    
 
广告
评论:进程内可用的软键盘,使用相当简便
aknightchen 498478 2015/7/29 13:08:16
{
  2009-12-13: 源码来源于盒子网友"skertone"
  2015-07-29: aKnightChen修正:
          1>.将单元中String替换为AnsiString,以支持XE2以上版本
          2>.去掉码表中小写"m" --> //sv1 := 'ZXCVBNMm'#$BC#$BE#$BF#$DC#$C0;

}

unit SkbF;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ImgList, Buttons, ComCtrls, ToolWin, ExtCtrls, StdCtrls;

const
   KBW_NORMAL = 38;
   KBH_NORMAL = 39;
type

  TEvent = procedure (iKey: Integer) of object;

  TSKData = record
      x: Integer;
      y: Integer;
      w: Integer;
      h: Integer;
      v1: Word;
      v2: Word;
      Event: TEvent;
  end;


  TfmSkb = class(TForm)
    Image1: TImage;
    imgCapsDown: TImage;
    imgShiftDown: TImage;
    imgCapsUp: TImage;
    imgShiftUp: TImage;
    imgMove: TImage;
    imgBK: TImage;
    procedure Image1MouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure Image1MouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure FormCreate(Sender: TObject);
    procedure FormPaint(Sender: TObject);
  private
    procedure MoveWindow(var Msg: TWmnchittest); message WM_NCHITTEST;

    procedure InitSKBData();
    procedure AddOneRowKBData(xbase,ybase,icount: Integer;sv1,sv2: AnsiString);
    function CheckInputKB(x,y: Integer): Integer;
    procedure EventShift(iKey: Integer);
    procedure EventOther(iKey: Integer);
    procedure EventClose(iKey: Integer);
    procedure WndProc(var Message: TMessage); override;
    procedure KbRepaint();

  public
    { Public declarations }
  end;

var
  fmSkb: TfmSkb;
  G_KBButton: array[0..150] of TSKData;
  G_KBCount: Integer;
  G_KeyCaps,G_KeyShift: Integer;
  G_ShiftState: Boolean;

  function IntOSK: TfmSkb;
implementation


{$R *.dfm}


function IntOSK: TfmSkb;
begin
  if not Assigned(fmSkb) then
  fmSkb := TfmSkb.Create(Application);

  Result := fmSkb;
end;

function TfmSkb.CheckInputKB(x, y: Integer): Integer;
var
  ii: Integer;
begin
  Result := -1;
  for ii := Low(G_KBButton) to High(G_KBButton) do
  if (x > G_KBButton[ii].x) AND (y > G_KBButton[ii].y) AND
     (x < G_KBButton[ii].x + G_KBButton[ii].w) AND
     (y < G_KBButton[ii].y + G_KBButton[ii].h) then
  begin
    Result := ii;
    break;
  end;
end;

procedure TfmSkb.Image1MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
var
  ikey: Integer;
begin

  ikey := CheckInputKB(x,y);
  if(ikey >=0)then
  begin
    BitBlt(Canvas.Handle,G_KBButton[ikey].x + 1,G_KBButton[ikey].y + 1,G_KBButton[ikey].w,G_KBButton[ikey].h,Canvas.Handle,G_KBButton[ikey].x,G_KBButton[ikey].y,SRCCOPY);

    if not Assigned(G_KBButton[ikey].Event) then
    begin
        if G_ShiftState then
        keybd_event(VK_Shift,0,0,0);

        keybd_event(G_KBButton[ikey].v1,0,0,0);
    end;
  end;
end;

procedure TfmSkb.Image1MouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
var
  ikey: Integer;
begin
  ikey := CheckInputKB(x,y);
  if(ikey >=0)then
  begin
        if not Assigned(G_KBButton[ikey].Event) then
        begin

          keybd_event(G_KBButton[ikey].v1,0,KEYEVENTF_KEYUP,0);

          if G_ShiftState then
          keybd_event(VK_Shift,0,KEYEVENTF_KEYUP,0);
        end
        else
          G_KBButton[ikey].Event(iKey);
  end;

  KbRepaint();
end;

procedure TfmSkb.InitSKBData;
var
  ii: Integer;
  xbase,ybase: Integer;
  sv1,sv2: AnsiString;
begin
  G_KBCount := 0;
  G_ShiftState := False;

  ZeroMemory(@G_KBButton[0],Length(G_KBButton) * sizeof(TSKData));

  xbase := 0;
  ybase := 0;
  sv1 := '1234567890'#$BD#$BB;
  sv2 := sv1;
  AddOneRowKBData(xbase,ybase,Length(sv1),sv1,sv2);

  xbase := 54;
  ybase := ybase + KBH_NORMAL + 1;
  sv1 := 'QWERTYUIOP'#$DB#$DD;
  sv2 := sv1;
  AddOneRowKBData(xbase,ybase,Length(sv1),sv1,sv2);


  xbase := 63;
  ybase := ybase + KBH_NORMAL;//     + 1;
  sv1 := 'ASDFGHJKL'#$BA;
  sv2 := sv1;
  AddOneRowKBData(xbase,ybase,Length(sv1),sv1,sv2);

  xbase := 54;
  ybase := ybase + KBH_NORMAL;// + 1;
  //sv1 := 'ZXCVBNMm'#$BC#$BE#$BF#$DC#$C0;
  sv1 := 'ZXCVBNM'#$BC#$BE#$BF#$DC#$C0;   //2015-07-29: aKnightChen修正:去掉"m"
  sv2 := sv1;
  AddOneRowKBData(xbase,ybase,Length(sv1),sv1,sv2);

  xbase := 0;
  ybase := ybase + KBH_NORMAL + 1;
  sv1 := Char(VK_UP) + Char(VK_DOWN) + Char(VK_LEFT) + Char(VK_RIGHT) ;
  sv2 := sv1;
  AddOneRowKBData(xbase,ybase,Length(sv1),sv1,sv2);

  // 退格键
  Inc(G_KBCount,1);
  ybase := 0;
  G_KBButton[G_KBCount].x := 456;
  G_KBButton[G_KBCount].y := ybase;
  G_KBButton[G_KBCount].w := 53;
  G_KBButton[G_KBCount].h := KBH_NORMAL;
  G_KBButton[G_KBCount].v1 := $08;
  G_KBButton[G_KBCount].v2 := $08;

  // Tab
  Inc(G_KBCount,1);
  ybase := ybase + KBH_NORMAL + 1;
  G_KBButton[G_KBCount].x := 0;
  G_KBButton[G_KBCount].y := ybase;
  G_KBButton[G_KBCount].w := 53;
  G_KBButton[G_KBCount].h := KBH_NORMAL;
  G_KBButton[G_KBCount].v1 := $09;
  G_KBButton[G_KBCount].v2 := $09;

  // Caps
  Inc(G_KBCount,1);
  ybase := ybase + KBH_NORMAL;// + 1;
  G_KBButton[G_KBCount].x := 0;
  G_KBButton[G_KBCount].y := ybase;
  G_KBButton[G_KBCount].w := 61;
  G_KBButton[G_KBCount].h := KBH_NORMAL;
  G_KBButton[G_KBCount].v1 := $14;
  G_KBButton[G_KBCount].v2 := $14;

  G_KeyCaps := G_KBCount;

  // Enter
  Inc(G_KBCount,1);
  //ybase := ybase + KBH_NORMAL + 1;
  G_KBButton[G_KBCount].x := 448;
  G_KBButton[G_KBCount].y := ybase;
  G_KBButton[G_KBCount].w := 61;
  G_KBButton[G_KBCount].h := KBH_NORMAL;
  G_KBButton[G_KBCount].v1 := $0D;
  G_KBButton[G_KBCount].v2 := $0D;

  // Shift
  Inc(G_KBCount,1);
  ybase := ybase + KBH_NORMAL;// + 1;
  G_KBButton[G_KBCount].x := 0;
  G_KBButton[G_KBCount].y := ybase;
  G_KBButton[G_KBCount].w := 53;
  G_KBButton[G_KBCount].h := KBH_NORMAL;
  G_KBButton[G_KBCount].v1 := $09;
  G_KBButton[G_KBCount].v2 := $09;
  G_KBButton[G_KBCount].Event := EventShift;

  G_KeyShift :=  G_KBCount;

  // Space
  Inc(G_KBCount,1);
  ybase := ybase + KBH_NORMAL;// + 1;
  G_KBButton[G_KBCount].x := 152;
  G_KBButton[G_KBCount].y := ybase;
  G_KBButton[G_KBCount].w := 174;
  G_KBButton[G_KBCount].h := KBH_NORMAL;
  G_KBButton[G_KBCount].v1 := $20;
  G_KBButton[G_KBCount].v2 := $20;

  // @
  Inc(G_KBCount,1);
  //ybase := ybase + KBH_NORMAL;// + 1;
  G_KBButton[G_KBCount].x := 327;
  G_KBButton[G_KBCount].y := ybase;
  G_KBButton[G_KBCount].w := KBW_NORMAL;
  G_KBButton[G_KBCount].h := KBH_NORMAL;
  G_KBButton[G_KBCount].v1 := Ord('2');
  G_KBButton[G_KBCount].v2 := VK_SHIFT;
  G_KBButton[G_KBCount].Event := EventOther;

  // -
  Inc(G_KBCount,1);
  //ybase := ybase + KBH_NORMAL;// + 1;
  G_KBButton[G_KBCount].x := 327 + KBW_NORMAL;
  G_KBButton[G_KBCount].y := ybase;
  G_KBButton[G_KBCount].w := KBW_NORMAL;
  G_KBButton[G_KBCount].h := KBH_NORMAL;
  G_KBButton[G_KBCount].v1 := $BD;
  G_KBButton[G_KBCount].v2 := $BD;
  G_KBButton[G_KBCount].Event := EventOther;

  // 关闭
  Inc(G_KBCount,1);
  //ybase := ybase + KBH_NORMAL;// + 1;
  G_KBButton[G_KBCount].x := 327 + KBW_NORMAL + KBW_NORMAL;
  G_KBButton[G_KBCount].y := ybase;
  G_KBButton[G_KBCount].w := 53;
  G_KBButton[G_KBCount].h := KBH_NORMAL;
  G_KBButton[G_KBCount].v1 := $00;
  G_KBButton[G_KBCount].v2 := $00;
  G_KBButton[G_KBCount].Event := EventClose;
end;

procedure TfmSkb.FormCreate(Sender: TObject);
begin
  SetWindowPos(Handle,HWND_TOPMOST,Left,Top,Width,Height,0);
  InitSKBData();
end;

procedure TfmSkb.AddOneRowKBData(xbase, ybase, icount: Integer; sv1, sv2: AnsiString);
var
  ii: Integer;
begin
  for ii := 0 to icount - 1 do
  begin
    G_KBButton[ii + G_KBCount].x := xbase + ii * KBW_NORMAL;
    G_KBButton[ii + G_KBCount].y := ybase;
    G_KBButton[ii + G_KBCount].w := KBW_NORMAL;
    G_KBButton[ii + G_KBCount].h := KBH_NORMAL;
    G_KBButton[ii + G_KBCount].v1 := Ord(sv1[ii+1]);
    G_KBButton[ii + G_KBCount].v2 := Ord(sv2[ii+1]);
  end;

  Inc(G_KBCount,icount);
end;

procedure TfmSkb.EventShift(iKey: Integer);
begin
  G_ShiftState := not G_ShiftState;
end;

procedure TfmSkb.EventOther(iKey: Integer);
begin
    if G_KBButton[ikey].v2 = VK_SHIFT then
    keybd_event(VK_Shift,0,0,0);

    keybd_event(G_KBButton[ikey].v1,0,0,0);
    keybd_event(G_KBButton[ikey].v1,0,KEYEVENTF_KEYUP,0);
    
    if G_KBButton[ikey].v2 = VK_SHIFT then
    keybd_event(VK_Shift,0,KEYEVENTF_KEYUP,0);
end;

procedure TfmSkb.MoveWindow(var Msg: TWmnchittest);
var
  p: TPoint;
begin
  Inherited;
  p:=Point(Msg.XPos,Msg.YPos);
  p:=ScreenToClient(p);
  if PtInRect(Rect(imgMove.Left,imgMove.Top,imgMove.Left + imgMove.Width,imgMove.Top + imgMove.Height),p) then
  Msg.Result := HTCAPTION;
end;

procedure TfmSkb.EventClose(iKey: Integer);
begin
  Close();
end;

procedure TfmSkb.WndProc(var Message: TMessage);
begin
  if Message.Msg =  WM_MOUSEACTIVATE then
      Message.Result := MA_NOACTIVATE
  else
  inherited;
end;

procedure TfmSkb.KbRepaint;
var
  ks: TKeyboardState;
begin
  GetKeyboardState(ks);

  BitBlt(Canvas.Handle,0,0,Image1.Width,Image1.Height,imgBK.Canvas.Handle,0,0,SRCCOPY);
  if Odd(ks[VK_CAPITAL])then
      BitBlt(Canvas.Handle,
      G_KBButton[G_KeyCaps].x,
      G_KBButton[G_KeyCaps].y,
      G_KBButton[G_KeyCaps].w,
      G_KBButton[G_KeyCaps].h,
      imgCapsDown.Canvas.Handle,0,0,SRCCOPY)
  else
     BitBlt(Canvas.Handle,
      G_KBButton[G_KeyCaps].x,
      G_KBButton[G_KeyCaps].y,
      G_KBButton[G_KeyCaps].w,
      G_KBButton[G_KeyCaps].h,
      imgCapsUp.Canvas.Handle,0,0,SRCCOPY);

  if  G_ShiftState then
      BitBlt(Canvas.Handle,
      G_KBButton[G_KeyShift].x,
      G_KBButton[G_KeyShift].y,
      G_KBButton[G_KeyShift].w,
      G_KBButton[G_KeyShift].h,
      imgShiftDown.Canvas.Handle,0,0,SRCCOPY)
  else
     BitBlt(Canvas.Handle,
      G_KBButton[G_KeyShift].x,
      G_KBButton[G_KeyShift].y,
      G_KBButton[G_KeyShift].w,
      G_KBButton[G_KeyShift].h,
      imgShiftUp.Canvas.Handle,0,0,SRCCOPY);

       BitBlt(Canvas.Handle,imgMove.Left,imgMove.Top,imgMove.Width,imgMove.Height,imgMove.Canvas.Handle,0,0,SRCCOPY);
end;

procedure TfmSkb.FormPaint(Sender: TObject);
begin
  KbRepaint();
end;

end.
jfyes 39424 2010/1/14 14:57:18
能结合我的外挂式T9拼音输入法的方法,就可以使用不同进程了
http://www.2ccc.com/article.asp?articleid=4916
jfyes 39423 2010/1/14 14:52:00
更新的DEMO http://www.cnblogs.com/jfyes/archive/2010/01/14/1647703.html
dorry 39242 2009/12/14 1:31:58
非常漂亮,实用,谢谢!
第一页 上一页 下一页 最后页 有 4 条纪录 共1页 1 - 4
 用户名:
 密 码:
自动登陆(30天有效)
 
  DELPHI盒子版权所有 技术支持:深圳市麟瑞科技有限公司 1999-2024 V4.01 粤ICP备10103342号-1 更新RSS列表