Delphi Programming / Object Pascal
[掲載 2008年04月07日] [更新 2012年05月07日] Delphi サンプルプログラム集 |
672_連動入力 |
動作確認等 |
Windows XP(SP3) + Delphi XE Pro
Windows 7 U64(SP1) + Delphi XE Pro |
|
672_CoupledInput.zip [553 KB] 2012年05月07日版 (EXE 同梱) |
2つの入力コントロールの入力操作状態を連動させる例です.
ここではリッチエディト (TRichEdit) の操作をそのまま他のリッチエディトへ反映します.RichEdit1 のメッセージを全て RichEdit2 へ送信することで実現しています.
エクセルのセルの表示が,数式バーでの入力と連動しているのと似ています. |
|
図1
設計時画面 |
|
図2
実行画面
- かな漢字入力中
- 変換中の状態もそのまま反映
- もちろん,キャレット (カーソル) 位置も連動する
- エクセルで言えば,上の TRichEdit が数式バーで,下の TRichEdit がセルに相当する
|
unit CoupledInputUnit;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ComCtrls;
type
TForm1 = class(TForm)
RichEdit1: TRichEdit;
RichEdit2: TRichEdit;
Button1: TButton;
Button2: TButton;
procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure RichEdit2Enter(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private 宣言 }
public
{ Public 宣言 }
FOriginalProc : TWndMethod;
procedure SubClassProc(var Msg:TMessage);
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
//=============================================================================
// スクロールバーを表示する場合は予め表示しておかないと,スクロールバーの表
// 示位置が乱れてしまうようだ.
//=============================================================================
procedure TForm1.FormCreate(Sender: TObject);
begin
RichEdit1.Clear;
RichEdit2.Clear;
RichEdit1.HideScrollBars := False;
RichEdit2.HideScrollBars := False;
RichEdit1.ScrollBars := ssVertical;
RichEdit2.ScrollBars := ssVertical;
RichEdit1.HideSelection := False;
RichEdit2.HideSelection := False;
end;
//=============================================================================
// アプリ終了時
// RichEdit1のウィンドウプロシージャーを変更していたら元に戻す
//=============================================================================
procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
if Assigned(FOriginalProc) then begin
RichEdit1.WindowProc := FOriginalProc;
end;
end;
//=============================================================================
// [連動入力開始]
// RichEdit1のウィンドウプロシージャーをSubClassProcというメソッドに変更する
// RichEdit1の新しいWindowProc(SubClassProc)を定義してからSetFocusしてしまう
// と都合が悪い.
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
begin
RichEdit1.SetFocus;
FOriginalProc := RichEdit1.WindowProc;
RichEdit1.WindowProc := SubClassProc;
end;
//=============================================================================
// [連動入力停止]
// RichEdit1のウィンドウプロシージャーを元に戻す
//=============================================================================
procedure TForm1.Button2Click(Sender: TObject);
begin
if Assigned(FOriginalProc) then begin
RichEdit1.WindowProc := FOriginalProc;
RichEdit1.SetFocus;
end;
end;
//=============================================================================
// RichEdit1の新しいウィンドウプロシージャー
// ここでは全てのメッセージをRichEdit2に送っている.
//=============================================================================
procedure TForm1.SubClassProc(var Msg: TMessage);
begin
FOriginalProc(Msg);
//RichEdit2.Perform(Msg.Msg, Msg.WParam, Msg.LParam);でも同じ
SendMessage(RichEdit2.Handle, Msg.Msg, Msg.WParam, Msg.LParam);
end;
//=============================================================================
// RichEdit2にフォーカスが移動したら連動入力を止める
// SubClassProc内で全てのメッセージを処理してしまっているので,RichEdit1の
// OnExitでは連動入力を停止することはできない.
//=============================================================================
procedure TForm1.RichEdit2Enter(Sender: TObject);
begin
if Assigned(FOriginalProc) then begin
RichEdit1.WindowProc := FOriginalProc;
end;
end;
end.
|