フォーラム


ゲスト  

ようこそ ゲスト さん。このフォーラムに投稿するには 登録が必要です。

ページ: [1]
トピック: InkEdit を使いたい
DEKO
管理者
投稿数: 2689
InkEdit を使いたい
on: 2013/04/06 12:28 Sat

"InkEdit は RichEdit のスーパーセット" な訳で、TRichEdit をチョイといじると InkEdit になるのです。TEdit をいじって IP アドレスコントロールにするようなものですね。

[uInkEdit.pas]
unit uInkEdit;

interface

uses
Winapi.Windows, Winapi.Messages, Winapi.RichEdit, Vcl.Controls, Vcl.ComCtrls;

type
TInkMode =
(IM_Disabled = 0,
IM_Ink = 1,
IM_InkAndGesture = 2);

TInkInsertMode =
(IEM_InsertAsText = 0,
IEM_InsertAsInk = 1);

TInkDisplayMode =
(IDM_Ink = 0,
IDM_Text = 1);

TInkEditStatus =
(IES_Idle = 0,
IES_Collecting = 1,
IES_Recognizing = 2);

TInkEdit = class(Vcl.ComCtrls.TRichEdit)
private
function GetUseMouseForInput: Boolean;
procedure SetUseMouseForInput(const Value: Boolean);
protected
procedure CreateParams(var Params: TCreateParams); override;
published
property UseMouseForInput: Boolean read GetUseMouseForInput write SetUseMouseForInput;
end;

const
InkEditClassName = 'INKEDIT';
IEC__BASE = WM_USER + $0200;
EM_GETINKMODE = IEC__BASE + 1;
EM_SETINKMODE = IEC__BASE + 2;
EM_GETINKINSERTMODE = IEC__BASE + 3;
EM_SETINKINSERTMODE = IEC__BASE + 4;
EM_GETDRAWATTR = IEC__BASE + 5;
EM_SETDRAWATTR = IEC__BASE + 6;
EM_GETRECOTIMEOUT = IEC__BASE + 7;
EM_SETRECOTIMEOUT = IEC__BASE + 8;
EM_GETGESTURESTATUS = IEC__BASE + 9;
EM_SETGESTURESTATUS = IEC__BASE + 10;
EM_GETRECOGNIZER = IEC__BASE + 11;
EM_SETRECOGNIZER = IEC__BASE + 12;
EM_GETFACTOID = IEC__BASE + 13;
EM_SETFACTOID = IEC__BASE + 14;
EM_GETSELINK = IEC__BASE + 15;
EM_SETSELINK = IEC__BASE + 16;
EM_GETMOUSEICON = IEC__BASE + 17;
EM_SETMOUSEICON = IEC__BASE + 18;
EM_GETMOUSEPOINTER = IEC__BASE + 19;
EM_SETMOUSEPOINTER = IEC__BASE + 20;
EM_GETSTATUS = IEC__BASE + 21;
EM_RECOGNIZE = IEC__BASE + 22;
EM_GETUSEMOUSEFORINPUT = IEC__BASE + 23;
EM_SETUSEMOUSEFORINPUT = IEC__BASE + 24;
EM_SETSELINKDISPLAYMODE = IEC__BASE + 25;
EM_GETSELINKDISPLAYMODE = IEC__BASE + 26;

IECN__BASE = $0800;
IECN_STROKE = IECN__BASE + 1;
IECN_GESTURE = IECN__BASE + 2;
IECN_RECOGNITIONRESULT = IECN__BASE + 3;

var
FInkEditModule: THandle;

implementation

{ TInkEdit }

procedure TInkEdit.CreateParams(var Params: TCreateParams);
const
dHideScrollBars: array[Boolean] of DWORD = (ES_DISABLENOSCROLL, 0);
dHideSelections: array[Boolean] of DWORD = (ES_NOHIDESEL, 0);
begin
if FInkEditModule = 0 then
begin
FInkEditModule := LoadLibrary('InkEd.dll');
if FInkEditModule <= HINSTANCE_ERROR then
FInkEditModule := 0;
end;
inherited CreateParams(Params);

CreateSubClass(Params, InkEditClassName);
with Params do
begin
Style := Style or dHideScrollBars[HideScrollBars] or
dHideSelections[HideSelection];
WindowClass.style := WindowClass.style and not (CS_HREDRAW or CS_VREDRAW);
end;
end;

function TInkEdit.GetUseMouseForInput: Boolean;
begin
result := SendMessage(Self.Handle, EM_GETUSEMOUSEFORINPUT, 0, 0) <> 0;
end;

procedure TInkEdit.SetUseMouseForInput(const Value: Boolean);
begin
SendMessage(Self.Handle, EM_SETUSEMOUSEFORINPUT, WPARAM(Value), 0);
end;

initialization
FInkEditModule := 0;

finalization
if FInkEditModule <> 0 then
FreeLibrary(FInkEditModule);
end.

 
新規に追加したプロパティは UseMouseForInput だけです。他に必要なプロパティがあればご自由に実装しちゃってください。インクジェスチャ (バックスペースとか) はデフォルトで有効になってますので、一般的に必要そうなものといえば RecTimeOut (インク入力タイムアウト時間) くらいですかね?

TInkEdit を動的作成して使ってもいいのですが、設計時に形だけでもあると便利ですよね。そんな時はフォームに TRichEdit を貼って小細工をします。

unit Unit1;

interface

uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes,
Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ComCtrls,
uInkEdit;

type
TRichEdit = class(TInkEdit); // これを追加

TForm1 = class(TForm)
RichEdit1: TRichEdit;
procedure FormCreate(Sender: TObject);
private
{ Private 宣言 }
public
{ Public 宣言 }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
RichEdit1.UseMouseForInput := True;
end;

end.

 
これだけで TRichEdit が InkEdit に化けます。

CreateParams() をオーバーライドするという、よくある手法で TInkEdit を実装しています。プロパティの追加は EM_~ メッセージを SendMessage() で処理するだけなので、Microsoft の "InkEdit Messages (Win32 Only) (Windows)" を参考にすれば実装は難しくないと思います。

余談ですが、インクジェスチャとバッティングするので 一画目が横棒の漢字はインク入力が困難です ("三十" とか)。これを回避するには、やや右肩上がりでインク入力してください…右肩下がりでも大丈夫な事が多いですが、それは縁起がよろしくないでしょう?

See Also:
[InkEdit Messages (Win32 Only) (Windows)]
http://msdn.microsoft.com/en-us/library/windows/desktop/ms696342%28v=vs.85%29.aspx

[InkEdit が使えない場合には?]
http://ht-deko.minim.ne.jp/ft1302.html#130219

ページ: [1]
WP Forum Server by ForumPress | LucidCrew
バージョン: 1.7.5 ; ページロード: 0.03 sec.