Delphi Tips 
-----------------------------

キーワード:Standard

>> Index

03/04 エディットコントロールで右寄せ表示
09/24 Delphi7 のコンボボックスの空文字列でエラー
06/27 コンボボックスにブラウザのURL入力のような自動補完機能を付けたい
06/27 TMemoで、先頭行/最終行/指定行へ移動する。
06/25 ComboBoxのDropDownListの幅を変更する
06/25 ボタン間を矢印キーで移動させるロジック
05/17 2つの TMemo のスクロールを同期させる
05/17 2つの TRichEdit のスクロールを同期させる
09/11 Editコントロールで入力を数値専用にする
09/11 TMemo のキャレットを非表示にする
09/11 エディットコントロールにポップアップウィンドウをつけたい
09/08 IME に未確定文字列を入力
09/08 ショートカットキーに'+'を使う。
09/07 右寄せ・数値入力可能なEditコンポーネントを作りたい。
09/06 ButtonのCaptionで改行を使って文字を複数段で表示したい
09/06 キーボードでボタンを押したとき、ボタンをちゃんと沈ませたい
09/06 カーソルキーでボタン(TButton)のフォーカス移動をやめさせたい
09/06 エディットコントロールにコンボボックスのようなボタンをつけたい
09/05 ドッカブルメニュー(ツールバー形式のメニュー)を実現したい。
08/31 LinesプロパティエディタでTabを入力する
08/14 ショートカットキーのキー名を独自に設定する
05/19 コンボボックスのリスト部分の幅を指定する
02/11 IME 入力で読み仮名を取得する
02/11 半角カナを確定無しで直接入力させる
02/11 下の図柄がすける透明パネル
02/11 表示中のポップアップメニューを消す
02/08 PopupMenu に MainMenu のサブ項目をそのまま表示する
02/08 自作コントロールで IME 入力時の変換候補をキャレット位置に表示したい
02/08 フォームの印刷時にComboBoxの内容が印刷されない
02/08 TMemoで入力*行数*を制限したい

最終更新: 7351 日前

0204  D1   D2   D3   D4   D5   D6   D7   3.1   95   98    作成: 1999/08/16 osamu rev 1.4
   B1   B3   B4   B5   B6   B7   NT3   NT4   2K   XP  更新: 2004/03/04 osamu 編集
エディットコントロールで右寄せ表示

>TEditで表示したい内容が数字なため右寄せにしたいと
>思っています。しかし、調べた限りでは右に寄ってく
>れません。

Delphian World などで既存のコンポーネントを入手するのが一番楽チンですね。( http://www.delphianworld.com/ )

自分で作る場合:
Win98とそれ以前のWinとでは作り方が異なります。
これはWindows98が右寄せEditをサポートしたからです。
『Win98で右寄せ・数値入力可能なEditコンポーネントを作る』
というTipsを参照ください。
こちらでは簡単に完璧に右寄せEditが作れませす。

Win98以前のWinでは
Editの代わりにTMemoを使い、1LineのTMemoをEditに見せかけます。

TMemoを配置して
1、Alignment Property を taRightJustify にする。
2、WordWrap Property を False にする。

WantReturns Property を False にして改行を入力させないようにしても
Ctrl+JやCtrl+Returnを押すと改行コードが入力されてしまいます。
そこで改行された時に改行を解除する動作をコーディングします。
procedure TForm1.Memo1KeyUp(Sender: TObject; var Key: Word;
  Shift: TShiftState);
var
  SelStartBuf: Integer;
  S: string;
begin
  if Memo1.SelLength>0 then exit;

  SelStartBuf := Memo1.SelStart;
  S := Memo1.Text;

  if pos(#13,S)<>0 then//改行コードのCRを削除
  begin
      Delete(S,pos(#13,S),1);
      Dec( SelStartBuf );
  end;
  if pos(#10,S)<>0 then
  begin
      Delete(S,pos(#10,S),1);//改行コードLFを削除
      Dec( SelStartBuf );
  end;

  Memo1.Text := S;
  Memo1.SelStart :=  SelStartBuf;
(*
また、TMemoを右寄せにしているとWordWrap:=falseが効果ありません。
文字が増えるとどうしても改行されてしまいます。
それに対応して改行されたらその時の文字数を保持して左寄せに変えます。
LengthShowはFormのメンバーとして変数宣言してください。
*)
  if Memo1.Lines[1]<>'' then//改行されたなら
  begin
    SelStartBuf := Memo1.SelStart ;
    Memo1.Alignment := taLeftJustify;
    Memo1.SelStart := SelStartBuf;
    LengthShow := Length(Memo1.Lines[0]);//LengthShow変数に
  end;//表示可能文字数を保持
(*
文字数が減ったら元に戻さなければいけません。
*)
  if LengthShow<>0 then//LengthShowに保持数があるなら
    if Length(Memo1.Lines[0])<LengthShow then//文字が減ったら
    begin
      SelStartBuf := Memo1.SelStart;
      Memo1.Alignment := taRightJustify;
      Memo1.SelStart := SelStartBuf;
    end;
end;//KeyUpイベント終わり

単純に、改行された時の文字数=表示の限界、とみなして
その文字数以下になれば右寄せに変えるという動作ですので
プロポーショナルフォントの場合では文字幅が異なりますのでちょっと変な動作になりそう。
また、左寄せの状況で文字を削除していくと左寄せという事がばれる動作をします。
更に、キー入力以外でテキストを代入するような動作は考慮していません。

その辺は、自分で作ってね。出来たら、このTipsを更新してくだされ。
参照: [Delphi-ML:9195] [Delphi-ML:41622] <コンポーネント >

0344  D1   D2   D3   D4   D5   D6   D7   3.1   95   98    作成: 2003/07/03 osamu rev 1.4
   B1   B3   B4   B5   B6   B7   NT3   NT4   2K   XP  更新: 2003/09/24 osamu 編集
Delphi7 のコンボボックスの空文字列でエラー

Delphi7 では、コンボボックスに空文字列を入れておくと、
  ComboBox1.Items.Add('');
この Item を Items[0] などとして参照した時にアクセスバイオレーションエラーが発生してしまいます。

これは、以前の Delphi が Item 保持領域として 4096 などの固定値を使っていたのに対して、Delphi7 からは CB_GETLBTEXTLEN を使ってバッファを動的に確保するようになったためで、それ自体は正しいことなのですが、Item の長さが 0 の時に正しくバッファが確保されないためにエラーが発生してしまいます。

エラーの詳しい内容は、[Delphi-ML:77352][Delphi-ML:77360][Delphi-ML:77366]を見てみてください。回避方法としては、Amaito さんの [Delphi-ML:77357] のように、

StdCtrls.pasをプロジェクトと同じフォルダにコピーして、2325行を

  //if Len <> CB_ERR then
  if Len > 0 then

とするのが良いようです。(CB_ERR は負の値なので、Len > 0 で Len=0 と Len=CB_ERR との両方の場合に対応しています)

[Delphi-ML:72969] でもすでに同じ問題が報告されていました。

## 実は編集後のコードにもちょっとした仕様バグが含まれています。
## TListBox.Items などと動作を合わせるのであれば、CB_ERR
## の場合には空文字列を返すのではなく例外を投げるべきだと
## 思います。
参照: [Delphi-ML:72969] [Delphi-ML:77352] [Delphi-ML:77357] [Delphi-ML:77360] [Delphi-ML:77366] <バグ> <コンポーネント >

0171  D1   D2   D3   D4   D5   D6   D7   3.1   95   98    作成: 1999/03/08 osamu rev 1.2
   B1   B3   B4   B5   B6   B7   NT3   NT4   2K   XP  更新: 2003/06/27 osamu 編集
コンボボックスにブラウザのURL入力のような自動補完機能を付けたい

ひきさんのページにサンプルコードを見つけることができます。ひきさんに感謝しつつ、ご利用下さい。

[Delphi壁の穴]-[その一:Delphiを覗く]
http://hp.vector.co.jp/authors/VA009712/take/delphi/kabedel.htm#autocomplete
参照: <コンポーネント >

0172  D1   D2   D3   D4   D5   D6   D7   3.1   95   98    作成: 1999/03/08 osamu rev 1.2
   B1   B3   B4   B5   B6   B7   NT3   NT4   2K   XP  更新: 2003/06/27 osamu 編集
TMemoで、先頭行/最終行/指定行へ移動する。

ひきさんのページにサンプルソースを見つけることができます。ひきさんに感謝しつつ活用しましょう。

[Delphi壁の穴]-[その1:Delphiを覗く]
http://hp.vector.co.jp/authors/VA009712/take/delphi/kabedel.htm#memomove
参照: <コンポーネント >

0043  D1   D2   D3   D4   D5   D6   D7   3.1   95   98    作成: 1999/02/08 osamu rev 1.2
   B1   B3   B4   B5   B6   B7   NT3   NT4   2K   XP  更新: 2003/06/25 osamu 編集
ComboBoxのDropDownListの幅を変更する

エディット部分はそのままで、ドロップダウンする部分の幅だけを変更したければ、

    ComboBox1.Perform(CB_SETDROPPEDWIDTH, 幅, 0);

とします。
「幅」はピクセル単位となります。
参照: [Delphi-ML:19165] <コンポーネント >

0337  D1   D2   D3   D4   D5   D6   D7   3.1   95   98    作成: 2003/06/25 osamu rev 1.1
   B1   B3   B4   B5   B6   B7   NT3   NT4   2K   XP  更新: 2003/06/25 osamu 編集
ボタン間を矢印キーで移動させるロジック

Q.フォーム上にボタンがたくさんあり、上下左右の矢印キーによって、実際のボタンの配置から期待される順序でフォーカスを動かしたいのですが。

A.設計時の手間はかかるのですが、各ボタンを個別にパネルの上に乗せてしまえば、矢印キーによる通常のフォーカス移動を無効にできるので、ボタンの OnKeyUp イベント内で移動先を設定できると思うのですがいかがでしょうか。
参照: [Delphi-ML:75689] <コンポーネント >

0321  D1   D2   D3   D4   D5   D6   D7   3.1   95   98    作成: 2002/05/17 osamu rev 1.4
   B1   B3   B4   B5   B6   B7   NT3   NT4   2K   XP  更新: 2002/05/17 osamu 編集
2つの TMemo のスクロールを同期させる

Q:
memo1 のスクロールバーを動かすと、memo2 も同じようにスクロールさせたいです。

A:[Delphi-ML:67004] Halbow さん
垂直スクロールバーについてだけ、回答します。Memo1 と Memo2 は Width や Height 、Font.Size など同一のプロパティーであると仮定しています。

TRichEdit で同様のことをする方法が[Tips:322]にあります。

type
  TForm1 = class(TForm)
    Memo1: TMemo;
    Memo2: TMemo;
    procedure FormCreate(Sender: TObject);
  private
    { Private 宣言 }
  public
    Memo1Proc:TWndMethod;
    MKEY:WORD;
    procedure Memo1SuclassProc(var Msg:TMessage);
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.FormCreate(Sender: TObject);
begin
  Memo1Proc := Memo1.WindowProc;
  Memo1.WindowProc := Memo1SuclassProc;
end;

procedure TForm1.Memo1SuclassProc(var Msg: TMessage);
begin
  Memo1Proc(Msg);
  case Msg.Msg of
    WM_VSCROLL:Memo2.Dispatch(Msg);
    CN_COMMAND:
      if (Msg.WParamHi = EN_VSCROLL) then begin
        case MKEY of
          VK_DOWN:Memo2.Perform(EM_LINESCROLL,0,1);
          VK_UP  :Memo2.Perform(EM_LINESCROLL,0,-1);
          VK_HOME:if (GetAsyncKeyState(VK_CONTROL) and $8000) <> 0 then begin
            Memo2.SelStart := 0;
            Memo2.Perform(EM_SCROLLCARET,0,0);
          end;
          VK_END:if (GetAsyncKeyState(VK_CONTROL) and $8000) <> 0 then begin
            Memo2.SelStart := Length(Memo2.Text);
            Memo2.Perform(EM_SCROLLCARET,0,0);
          end;
        end;
        MKEY := 0;
      end;
    CN_KEYDOWN:MKEY := Msg.WParam;
  end;
end;
参照: [Delphi-ML:67004] <コンポーネント > [Tips:322]

0322  D1   D2   D3   D4   D5   D6   D7   3.1   95   98    作成: 2002/05/17 osamu rev 1.1
   B1   B3   B4   B5   B6   B7   NT3   NT4   2K   XP  更新: 2002/05/17 osamu 編集
2つの TRichEdit のスクロールを同期させる

2つのTMemo のスクロールを同期させるやり方が[Tips:321]にありますが、実は TRichEdit だと同じようにしてもうまく行きません。

解決方法は、やはり Halbow さんの[Delphi-ML:67313]にあります。

うまく行かないのは、TRichEdit では CN_COMMAND を通じたスクロール通知メッセージ EN_VSCROLL が発行されないためです。EM_SETEVENTMASK というメッセージを送って、LParam に ENM_SCROLL を設定すると、親に EN_VSCROLL を通知するようになります。

親にイベントを通知するかどうかをプログラムで設定するためのこのようなマスクについて、[Delphi-ML:67328]にさらに詳しい説明があります。

  public
    RichEdit1Proc:TWndMethod;
    MKEY:WORD;
    procedure RichEdit1SuclassProc(var Msg:TMessage);
    procedure SyncVScroll;
    procedure PageDown;
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

uses
  richedit;

procedure TForm1.FormCreate(Sender: TObject);
begin
  RichEdit1Proc := RichEdit1.WindowProc;
  RichEdit1.WindowProc := RichEdit1SuclassProc;
end;

procedure TForm1.FormShow(Sender: TObject);
var
  MASK:LPARAM;
begin
  MASK := RichEdit1.Perform(EM_GETEVENTMASK,0,0);
  RichEdit1.Perform(EM_SETEVENTMASK,0,MASK or ENM_SCROLL);
end;

procedure TForm1.RichEdit1SuclassProc(var Msg: TMessage);
begin
  RichEdit1Proc(Msg);
  case Msg.Msg of
    WM_VSCROLL:RichEdit2.Dispatch(Msg);
    CN_COMMAND:begin
      if (Msg.WParamHi = EN_VSCROLL) then
        case MKEY of
          VK_DOWN,VK_UP,VK_PRIOR:SyncVScroll;
          VK_NEXT:PageDown;
          VK_HOME,VK_END:
            if (GetAsyncKeyState(VK_CONTROL) and $8000) <> 0 then
              SyncVScroll;
        end;
    end;
    CN_KEYDOWN:MKEY := Msg.WParam;
  end;
end;

procedure TForm1.SyncVScroll;
var
  Msg:TWMScroll;
begin
  Msg.Msg := WM_VSCROLL;
  Msg.Pos := GetScrollPos(RichEdit1.Handle,SB_VERT);
  Msg.ScrollBar := 0;
  Msg.ScrollCode := SB_THUMBTRACK;
  RichEdit2.Dispatch(Msg);
  Msg.ScrollCode := SB_THUMBPOSITION;
  RichEdit2.Dispatch(Msg);
  Msg.ScrollCode := SB_ENDSCROLL;
  RichEdit2.Dispatch(Msg);
end;

procedure TForm1.PageDown;
var
  Msg:TWMScroll;
begin
  Msg.Msg := WM_VSCROLL;
  Msg.Pos := 0;
  Msg.ScrollBar := 0;
  Msg.ScrollCode := SB_PAGEDOWN;
  RichEdit2.Dispatch(Msg);
end;
参照: [Delphi-ML:67313] [Delphi-ML:67328] <Win95> <コンポーネント > [Tips:321]

0223  D1   D2   D3   D4   D5   D6   D7   3.1   95   98    作成: 1999/08/28 おばQ rev 1.3
   B1   B3   B4   B5   B6   B7   NT3   NT4   2K   XP  更新: 1999/09/11 K.Takaoka 編集
Editコントロールで入力を数値専用にする

入力を数値のみにする場合は、Handleの生成を確認した後
SetWindowLong(Edit1.Handle, GWL_STYLE,
    GetWindowLong(Edit1.Handle,GWL_STYLE) or ES_NUMBER);
でできます。

SetWindowLong による指定はウィンドウの再生成が行われた時に無効になりますので、Delphi4 のドッキングウィンドウや、Toolbar97 などのコンポーネントを同時に利用される場合には CreateParams をオーバーライドしたコンポーネントを作成するかフローティング状態の変更通知を受け取るたびに SetWindowLong を行う必要があります。
参照: [Delphi-ML:9195] [Delphi-ML:41622] <コンポーネント >

0243  D1   D2   D3   D4   D5   D6   D7   3.1   95   98    作成: 1999/09/09 osamu rev 1.2
   B1   B3   B4   B5   B6   B7   NT3   NT4   2K   XP  更新: 1999/09/11 K.Takaoka 編集
TMemo のキャレットを非表示にする

> メモコンポーネントでキャレットを消したいのです。

以下のコードでうまくいっています

// TExMemo=class(TMemo)
// TExMemo.WMSetFocusはWM_SETFOCUSのメッセージハンドラ
Procedure TExMemo.WMSetFocus(var Msg:TWMKeyDown);
Begin
 Inherited;
 HideCaret(Handle);
End;


参照: [Delphi-ML:33802] <コンポーネント >

0235  D1   D2   D3   D4   D5   D6   D7   3.1   95   98    作成: 1999/09/06 西坂良幸 rev 1.3
   B1   B3   B4   B5   B6   B7   NT3   NT4   2K   XP  更新: 1999/09/11 K.Takaoka 編集
エディットコントロールにポップアップウィンドウをつけたい

エディットコントロールにボタンをつけた、コンボボックスもどきは、カスタムコントロールでよく見かけます。ボタンを押すと小ウィンドウが開くヤツです。これはどのように作るのでしょうか。

このような小ウィンドウをインプレースコントロールと呼びます。
ポイントは、小ウィンドウの親をコントロールにすることと、独自のフォーカスを与えないことです。これさえ理解できれば後は、小ウィンドウのVisbleの切り替えで開いたり閉じたりします。

ここでは、プロパティを受け渡すことを無視し、ただ開閉だけをやってみます。(マウス右ボタンで開く)

//  定義部
  TxEdit = class;

  // インプレースコントロール ここではリストボックス
  TinPlaceList = class(TListbox)
  private
    FEdit: TxEdit;
  protected
    procedure CreateWnd; override;
    procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
  public
    constructor CreateList(AOwner: TComponent; Edit: TxEdit);
  end;

  // ここでは、TEditから継承する
  TxEdit = class(TEdit)
  private
    FInplaceList:TListbox;
  protected
    procedure Mousedown(Button: TMouseButton; Shift: TShiftState;
      X, Y: Integer); override;
  public
    constructor Create(AOwner: TComponent);override;
    destructor Destroy;override;
    procedure DropDown;
  end;

// 実装部

//コンストラクタでコントロールに接続させる
constructor TInplaceList.CreateList(AOwner: TComponent; Edit: TxEdit);
begin
  inherited Create(AOwner);
  // 小ウィンドウに親のポインタを持たせて接続する
  FEdit := TxEdit(Edit);
  Visible := false;
end;

// インプレースコントロールの生成とフォーカス制御
procedure TInplaceList.CreateWnd;
begin
  inherited CreateWnd;
   //親の変更を行う
  if not (csDesigning in ComponentState) then
    Windows.SetParent(Handle, 0);
  //独自のフォカスメッセージを避ける
  CallWindowProc(DefWndProc, Handle, WM_SETFOCUS, 0, 0);
end;

//とりあえずマウス(左右)で閉じることにする
procedure TInplaceList.MouseUp(Button: TMouseButton; Shift: TShiftState;
    X, Y: Integer);
begin
  inherited MouseUp(Button, Shift, X, Y);
  if Button = mbLeft then
  begin
    // プロパティの受け渡しをここらで行う
    Hide;
  end;
  if Button = mbRight then
    Hide;
end;

// コンストラクタで、インプレースコントロールを生成
constructor TxEdit.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FInplaceList := TInplaceList.CreateList(Self, Self);
  with FInplaceList do
  begin
    Parent := Self;
    TabStop := false;
    Visible := false;
    Top := FInplaceList.Top + Self.Height;
  end;
end;

// デストラクタで念のため明示的に解放する
destructor TxEdit.Destroy;
begin
  FInplaceList.free;
  inherited Destroy;
end;

// ドロップダウンリストの開閉のメソッドを作成する
procedure TxEdit.DropDown;
var
  xyPos: TPoint;
begin
  if (FInplaceList <> nil) and not FInplaceList.Visible then
  with FInplaceList do
  begin
    xyPos := Self.ClientToScreen(Point(0 + Self.Width - Width,  Self.Height));
    SetWindowPos(Handle, 0, xyPos.X, xyPos.Y, 0, 0, SWP_NOSIZE or SWP_NOACTIVATE);
    Windows.SetFocus(Handle);
    Visible := not Visible;
    // プロパティの受け渡しをここらで行う
  end;
  Invalidate;
end;

// マウス右ボタンで開く
procedure TxEdit.Mousedown(Button: TMouseButton; Shift: TShiftState;
  X, Y: Integer);
begin
  if Button = mbRight then
    DropDown;
  inherited Mousedown(Button, Shift, X, Y);
end;

TListBoxのかわりに、何でも使えます。TPanelなら、電卓、カレンダなどになりますね。TGridでもいいですね。
実際にカスタムコントロールを作るときは
・やはりボタンをつける
・キーボード入力にも対応させる
・必要なプロパティの受け渡しを行う
・ドロップダウンなどイベントを記述する
・ロストフォーカスで開きっぱなしにしない
などが必要でしょうか。

参照: [Delphi-ML:40241] <コンポーネント開発> <コンポーネント >

0239  D1   D2   D3   D4   D5   D6   D7   3.1   95   98    作成: 1999/09/08 osamu rev 1.1
   B1   B3   B4   B5   B6   B7   NT3   NT4   2K   XP  更新: 1999/09/08 osamu 編集
IME に未確定文字列を入力

> プログラム中からIMEに未変換・未確定文字列として送りたいのですが。。。
>
> 例
> プログラムで渡す文字列    へいせい10ねん
>           ↓
>          IME              「へいせい10ねん」(未変換・未確定)

方法1
  「へいせい10ねん」を「heisei10nenn」もしくは、
  「ヘイセイ10ネン」(ほんとは半角)に変換し、キーボードイベントとして
  sendkeysや、keybd_event APIでIMEに送る。
  ローマ字変換か、カナ変換かは、ImmGetConversionStatus APIで
  判断出来ます。

  Edit1.SetFocus;
  SendKeys('heisei10nenn',true);

方法2
  ImmSetCompositionString APIでIMEに直接セットする。

  var
    IMC:HIMC;
    BufLen:longint;
    Buf:string;
  begin
    Edit1.SetFocus;
    IMC:=ImmGetContext(Edit1.Handle);
    Buf:='へいせい10ねん';
    BufLen:=length(Buf);
//MS-IME98
    ImmSetCompositionStringA(IMC,SCS_SETSTR,PChar(Buf),BufLen,nil,0);

//ATOK12
    ImmSetCompositionStringW(IMC,SCS_SETSTR,PChar(Buf),BufLen,nil,0);

    ImmReleaseContext(Edit1.Handle,IMC);
  end;

MS-IME98とATOK12でテストしましたが、ATOK12の場合、UniCodeの方のAPIで実行しないとちゃんと動作しませんでした。
なぜなのかは、よくわかりません(^^;

#詳しくは、英語のヘルプやAPIの解説書等で調べてください。
参照: [Delphi-ML:32185] <その他Windows関連> <Windows> <コンポーネント >

0003  D1   D2   D3   D4   D5   D6   D7   3.1   95   98    作成: 1999/02/08 osamu rev 1.3
   B1   B3   B4   B5   B6   B7   NT3   NT4   2K   XP  更新: 1999/09/08 osamu 編集
ショートカットキーに'+'を使う。

Delphi2.0 以上では、『!"#$%&'()=~|^{}`*+_?><』など、101のフルキー側(テンキーを除いた部分)で、Shiftと同時にキーを押さなければ入力できない文字はショートカットに使えない。
テンキーがついてたり、JISキーボードならばワンキーで押せるものもあるのに。

こういったキーを使うには、ShortCut プロパティにキーコードを直接セットすればいい。

たとえば、

    Test2.ShortCut:=$6B;  // <- + キーのキーコード

でも、これだとメニューの右端にキー名が表示されない。 (;_;)
対処方法は [Tips:4]
参照: [Delphi-ML:17954] [Tips:4] <コンポーネント > <メニュー>

0224  D1   D2   D3   D4   D5   D6   D7   3.1   95   98    作成: 1999/08/28 おばQ rev 1.1.1.5
   B1   B3   B4   B5   B6   B7   NT3   NT4   2K   XP  更新: 1999/09/07 西坂良幸 編集
右寄せ・数値入力可能なEditコンポーネントを作りたい。

Win98 以降では、次のようにすれば完璧な右寄せエディタが作成できます。
 WindowsNT4 では SP3 (User32.Dll が 03/11/97 07:04p Intel, 03/11/97 06:14p Alpha) から利用できます。


type
 TRgEdit = class(TEdit)
 protected
   procedure CreateParams(var params: TCreateParams); override;
 end;

procedure TRgEdit.CreateParams(var params: TCreateParams);
begin
 inherited CreateParams(params);
 with Params do
   Style := Style or ES_RIGHT;
end;

 追記のバージョン以前、またDelhi3以前は、
   Style := Style or WS_MULTILINE or ES_RIGHT and not WS_VSCROLL and not WS_AUTOVSCROLL ;

とします。
また、入力を数字専用される場合は、上記にES_NUMBERを論理和
させます。

以下は、Alignment、NumOnly の各プロパティを作成する例です
(FAlignment、FNumOnlyやプロパティ定義部分は省略しています)

procedure TRgEdit.CreateParams(var params: TCreateParams);
const
 Alignments: array[TAlignment]of Word = (ES_LEFT, ES_RIGHT, ES_CENTER);
 NumlOnlies: array[Boolean]of Word = (0, ES_NUMBER);
begin
 inherited CreateParams(Params);
 Params.Style := Params.Style  
         or Alignments[FAlignment]
         or NumlOnlies[FNumlonly];
end;

procedure TRgEdit.SetAlignment(NewValue: TAlignment);
begin
  if FAlignment <> NewValue then
  begin
    FAlignment := NewValue;
    RecreateWnd;// CreateParamsを呼び出すのではないことに注意
  end;
end;

procedure TRgEdit.SetNumlOnly(NewValue: Boolean);
begin
  if FNumlOnly <> NewValue then
  begin
    FNumlOnly := NewValue;
    RecreateWnd;
  end;
end;
参照: [Delphi-ML:9195] [Delphi-ML:41622] <コンポーネント >

0123  D1   D2   D3   D4   D5   D6   D7   3.1   95   98    作成: 1999/02/08 osamu rev 1.3
   B1   B3   B4   B5   B6   B7   NT3   NT4   2K   XP  更新: 1999/09/06 西坂良幸 編集
ButtonのCaptionで改行を使って文字を複数段で表示したい

Windows95では #13#10 挿入することにより思った通り表示できるのですが
WindowsNTの場合は改行されません。

procedure TForm1.Button1Click(Sender: TObject);
begin
  SetWindowLong(Button1.Handle, GWL_STYLE, GetWindowLong(Button1.Handle, GWL_STYLE) or BS_MULTILINE);
  Button1.Caption := 'ABC' + #13#10 + 'DEF';
end;


なお、コンポ−ネント化する場合はCreateParamsをオーバーライドして下さい。
この方法は、TButtonControl系(TRadioButton,TCheckBox)でほとんど使えますが、オーナードロー系(TBitBtn,TSpeedButtonなど)のボタンではできません。

また、以下のプロパティエディッタをインストールすれば、オブジェクトインスペクタで,改行コードを入力を'\n'ですることが出来るようになります。

// 定義部
type
  // 複数行の入力を\nで受け入れるプロパティエディッタ
  TMultCapProperty = Class(TCaptionProperty)
  Public
    Function GetValue: string; Override;
    Procedure SetValue(const Value: string); Override;
  End;

procedure Register;


// 実装部
// 置き換える関数
procedure ReplaceStr(var Source : string; Search, Replace : string);
  function XPos(Source, Search : string):integer;
  begin
    if StrPos(PChar(Source), PCHar(Search)) = nil then
      result := 0
    else
      result := StrPos(PChar(Source), PCHar(Search)) - PChar(Source) + 1;
  end;
var
  p, L1, L2 : Integer;
begin
  L2 := Length(Search);
  p := XPos(Source, Search);
  while p <> 0 do
  begin
    L1 := Length(Source);
    if p = 1 then
      Source := Replace + Copy(Source, L2 + 1, L1)
    else
      Source := Copy(Source, 1, p - 1) + Replace +
              Copy(Source, p + L2, L1);
    p := XPos(Source, Search);
  end;
end;

function TMultCapProperty.GetValue: string;
begin
  Result := GetStrValue;
  // 以下3つのパターンがある
  ReplaceStr(Result, #13 + #10, '\n');
  ReplaceStr(Result, #10, '\n');
  ReplaceStr(Result, #13, '\n');
end;

procedure TMultCapProperty.SetValue(const Value: string);
var
  Caption : string;
begin
  Caption := Value;
  ReplaceStr(Caption, '\n', #13);
  SetStrValue(Caption);
end;

// プロパティエディタとして登録する
procedure Register;
begin
  // TLabelのCaptionプロパティエディタの登録--'\n'で改行入力
  RegisterPropertyEditor(TypeInfo(TCaption), TLabel; , 'Caption', TMultCapProperty);
  // TButtonのCaptionプロパティエディタの登録--'\n'で改行入力
  // ただし上記BS_MULTILINEが設定されていないとダメ
  RegisterPropertyEditor(TypeInfo(TCaption), TButton; , 'Caption', TMultCapProperty);
end;

参照: [Delphi-ML:17735] [Delphi-ML:39679] [builder:6270] <コンポーネント開発> <コンポーネント >

0063  D1   D2   D3   D4   D5   D6   D7   3.1   95   98    作成: 1999/02/08 osamu rev 1.2
   B1   B3   B4   B5   B6   B7   NT3   NT4   2K   XP  更新: 1999/09/06 西坂良幸 編集
キーボードでボタンを押したとき、ボタンをちゃんと沈ませたい

BM_SETSTATE メッセージを使うとできます。
コンポーネント化は、ちょっと長くなるので、詳細は [Delphi-ML:19607] を見てください。

以下、スペースキーでの例です。
procedure TForm1.Button1KeyPress(Sender: TObject; var Key: Char);
begin
  if Key = #32 then
    SendMessage(Button1.Handle,BM_SETSTATE,1,0);
end;

procedure TForm1.Button1KeyUp(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  if Key = 32 then
    SendMessage(Button1.Handle,BM_SETSTATE,0,0);
end;


コーディングだけで呼ぶ場合は

  SendMessage(Button1.Handle,BM_SETSTATE,1,0);
  Button1.Click;
  Sleep(100);   // 適当に好みで決める
  PostMessage(Button1.Handle,BM_SETSTATE,0,0);

参照: [Delphi-ML:19607] <コンポーネント >

0237  D1   D2   D3   D4   D5   D6   D7   3.1   95   98    作成: 1999/09/06 西坂良幸 rev 1.1
   B1   B3   B4   B5   B6   B7   NT3   NT4   2K   XP  更新: 1999/09/06 西坂良幸 編集
カーソルキーでボタン(TButton)のフォーカス移動をやめさせたい


TButtonのOnKeyPress、OnKeyDownなどでやってみてもダメですね。これは、Windowsのボタンの仕様です。
フォームへのCM_DialogKeyメッセージをとらえて処理すると可能です。

procedure TForm1.CMDialogKey(var Msg:TCMDialogKey);
begin
    case Msg.CharCode of
    VK_UP,VK_DOWN,VK_LEFT,VK_RIGHT :  Msg.CharCode:=0;
    end;
    inherited;
end;


このメッセ−ジはタブキー(VK_TAB)もとらえることが出来ます。
参照: [Delphi-ML:3691] [Delphi-ML:33541] <フォーム> <コンポーネント >

0236  D1   D2   D3   D4   D5   D6   D7   3.1   95   98    作成: 1999/09/06 西坂良幸 rev 1.1
   B1   B3   B4   B5   B6   B7   NT3   NT4   2K   XP  更新: 1999/09/06 西坂良幸 編集
エディットコントロールにコンボボックスのようなボタンをつけたい


エディットをParentとするフォーカスを持たないTSpeedButtonを、貼り付けてやれば簡単です。
注意するのは、編集領域がボタンに重ならないようにEM_SETRECTNPを送ることですが、このメッセージが有効になるには、TEditのスタイルフラッグにES_MULTILINEを加えなければなりません。

以下の例は、ボタンを押せば単にメッセージボックスがでるだけのものです。

// 定義部
  TxEdit = class(TEdit)
  private
    FButton: TSpeedButton;
    FOnButtonClick: TNotifyEvent;
    procedure SetEditRect;
    procedure WMSize(var Message: TWMSize); message WM_SIZE;
  protected
    procedure ButtonClick (Sender: TObject);
    procedure CreateParams(var Params: TCreateParams); override;
    procedure CreateWnd; override;
  public
    constructor Create(AOwner: TComponent); override;
  published
    property OnButtonClick: TNotifyEvent read FOnButtonClick write FOnButtonClick;
  end;

// 実装部
constructor TxEdit.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  // ボタンを作成する
  FButton := TSpeedButton.Create (Self);
  with FButton do
  begin
    Parent := Self;
    Width := 18;
    Height := Height - 4;
    // リソースから ▼ のビットマップ(10×8程度×2)を読むのは省略
    // NumGlyphs := 2;
    // result.Glyph.LoadFromResourceName(HInstance,'????');
    CurSor := crArrow;
    OnClick := ButtonClick;
  end;
end;

// スタイルフラッグにES_MULTILINEが必要です。
procedure TxEdit.CreateParams(var Params: TCreateParams);
begin
  inherited CreateParams(Params);
  Params.Style := Params.Style or ES_MULTILINE;
end;

// ハンドルが生成されてからSetEditRectを呼ぶ
procedure TxEdit.CreateWnd;
begin
  inherited CreateWnd;
  SetEditRect;
end;

// エディット(編集)領域を再設定する(ボタンの部分を排除)
procedure TxEdit.SetEditRect;
var
  Loc: TRect;
begin
  SendMessage(Handle, EM_GETRECT, 0, LongInt(@Loc));
  Loc.Right := ClientWidth - FButton.Width - 2;
  SendMessage(Handle, EM_SETRECTNP, 0, LongInt(@Loc));
end;

// 常に左端にアジャストさせる
procedure TxEdit.WMSize(var Message: TWMSize);
begin
  inherited;
  if FButton <> nil then
  begin
    if NewStyleControls and Ctl3D then
      FButton.SetBounds(Width - FButton.Width - 4, 0, FButton.Width, Height - 4)
    else FButton.SetBounds (Width - FButton.Width, 1, FButton.Width, Height - 2);
    SetEditRect;
  end;
end;

// ボタンのクリックに対応するイベントを設定する
procedure TxEdit.ButtonClick (Sender: TObject);
begin
  if Assigned(FOnButtonClick) then FOnButtonClick(self);
  ShowMessage('ボタンが押されました')
  // ここに必要な処理を書く
end;

この他、CM_EnabledChangeを捕まえて、EditとボタンのEnabledを同期させることが必要でしょうか。
参照: <コンポーネント開発> <コンポーネント >

0198  D1   D2   D3   D4   D5   D6   D7   3.1   95   98    作成: 1999/07/09 osamu rev 1.3
   B1   B3   B4   B5   B6   B7   NT3   NT4   2K   XP  更新: 1999/09/05 西坂良幸 編集
ドッカブルメニュー(ツールバー形式のメニュー)を実現したい。

 Delphi4でドッカブルメニューを実現するにはどうしたら良いのでしょうか?
 IDEでは実現されているので、出来るとは思うのですが...。

アメリカのインプライズのサイトで、ドッカブルメニューのコンポが配られていますよ。使用した感じ日本語環境でも大丈夫そうです。まぁ、多分かなりの問い合わせがあったんでしょうね。

TMenubar -> http://www.borland.com/devsupport/delphi/downloads/index.html
このコンポーネントを使わない場合は、以下の手順で行います。[Delphi-ML:35243][Delphi-ML:35223] Oyats、fumika

・フォームにTCoolBarを配置し、そのTCoolBarの上にTToolBarを配置
・TToolBarのShowCaptionプロパティをTrue、FlatプロパティをTrue、EdgeBordersのedTopプロパティをFalseにする
・フォームにTMainMenuを配置
・TMainMenuのメニューエディッタで、作りたいメニューを作る(MenuItemの作成)
・TToolBarの上にTToolButtonを作成し、各TToolButtonのMenuItemプロパティにTMainMenuの各MenuItem(Parent)を対応させる
・各TToolButtonのGroupedプロパティをTrue、AutoSizeプロパティをTrueにする
・フォームのMenuプロパティをnilにする(メニュー表示を消す)
・フォームのOnShortCutイベントに次のハンドラを設定する

procedure TForm1.FormShortCut(var Msg: TWMKey; var Handled: Boolean);
begin
  Handled := Handled or MainMenu1.IsShortCut(Msg);
end;


TMenuBarを使う人も
http://member.nifty.ne.jp/cosmic/delphi/tips_vcl.html#tmenubar
は覗いておきましょう。
参照: [Delphi-ML:32742] [Delphi-ML:35223] <Win95> <コンポーネント >

0231  D1   D2   D3   D4   D5   D6   D7   3.1   95   98    作成: 1999/08/31 おばQ rev 1.1
   B1   B3   B4   B5   B6   B7   NT3   NT4   2K   XP  更新: 1999/08/31 おばQ 編集
LinesプロパティエディタでTabを入力する

TMemoやTRichEditでは設計時にLinesプロパティを
設定することが出来ます。

文字列リストの設定ダイアログ(という名前か?)
というLinesのプロパティエディタが表示されて編集します。
常識ですね。

さて、ここでTabキーを押してもTabが入力出来ません!
さあ、困った困ったどうしよう。

そういう時にはCtrl+Tabキーを押します。
参照: <Win95> <コンポーネント >

0004  D1   D2   D3   D4   D5   D6   D7   3.1   95   98    作成: 1999/02/08 osamu rev 1.2
   B1   B3   B4   B5   B6   B7   NT3   NT4   2K   XP  更新: 1999/08/14 osamu 編集
ショートカットキーのキー名を独自に設定する

例えば、テンキーの + キーをショートカットにした場合に、'Num +'とか表示させたい。
TMenuItem.AppendTo()を参照すると、

    TestMenu1.Caption:=TestMenu1.Caption+#9+'Num +'+#0;

とすればよいことが分かる。

キャプションとショートカット名との間にはさんだタブ文字と、自動で追加されるショートカットを隠すために最後にくっつけられた #0 とが味噌。
参照: [Delphi-ML:17989] <コンポーネント > <メニュー>

0191  D1   D2   D3   D4   D5   D6   D7   3.1   95   98    作成: 1999/05/19 osamu rev 1.1
   B1   B3   B4   B5   B6   B7   NT3   NT4   2K   XP  更新: 1999/05/19 osamu 編集
コンボボックスのリスト部分の幅を指定する

>コンボボックスをクリックして表示されるリストの幅を
>コンボボックスコントロール自体の幅よりも広くして
>表示することはできないでしょうか?

ComboBox1->Perform(CB_SETDROPPEDWIDTH, 幅, 0);

です。詳細は Win32.hlp(English) を参照してください。
参照: [builder:12689] <コンポーネント >

0168  D1   D2   D3   D4   D5   D6   D7   3.1   95   98    作成: 1999/02/11 osamu rev 1.1
   B1   B3   B4   B5   B6   B7   NT3   NT4   2K   XP  更新: 1999/02/11 osamu 編集
IME 入力で読み仮名を取得する

以下のコードを含んだ関数を作成し、追跡したいところで
     Application->OnMessage = AppMessage;
と書けばよいのではないでしょうか? はずしていたらすみません。

void __fastcall TForm1::AppMessage(TMessage &Msg, bool &Handled)
{
     if (Msg.message == WM_IME_ENDCOMPOSITION)
     {
          int nRetVal;                   //APIの戻り値を格納
          HIMC hImcIMEHandle;            //IMEのコンテキストを格納
          char cBuff[256];

          hImcIMEHandle = ImmGetContext(Handle);
          //変換結果の「読み」を取得
          nRetVal = ImmGetCompositionString(hImcIMEHandle,
GCS_RESULTREADSTR,
                cBuff, sizeof(cBuff));
          cBuff[nRetVal] = '\0';
          AnsiString strTemp = cBuff;
          //IMEのコンテキストを開放する
          nRetVal = ImmReleaseContext(Handle, hImcIMEHandle);

          //cBuffに対して処理をする(入力された文字列)
     }
}

でcBuffに入力された文字が入ってきていると思います。
このコードを実行するにはimm.hが必要です。
参照: [builder:6815] <その他Windows関連> <Windows> <コンポーネント >

0160  D1   D2   D3   D4   D5   D6   D7   3.1   95   98    作成: 1999/02/11 osamu rev 1.1
   B1   B3   B4   B5   B6   B7   NT3   NT4   2K   XP  更新: 1999/02/11 osamu 編集
半角カナを確定無しで直接入力させる

> IMEの制御についてお聞きしたいのですが、例えばTEditのIMEMode
> プロパティを半角カナに設定した時、「アイウエオ(半角)」と打
> ちこんだ後リターンキーで確定をしなければなりませんが、ここで
> 入力される文字(半角カナ)を随時確定していきたいのですが、どの
> ようにすればよろしいでしょうか?

[スマートな解法]

Edit1の ImeMode プロパティを imSKata にして

uses Imm;

procedure TForm1.Edit1Enter(Sender: TObject);
var
  Imc: HIMC;
  Conversion, Sentence: DWORD;
begin
  Imc := ImmGetContext(Handle);
  ImmGetConversionStatus(Imc, Conversion, Sentence);
  ImmSetConversionStatus(Imc, Conversion, IME_SMODE_NONE);
  ImmReleaseContext(Handle, Imc);
end;

[スマートではないがいろいろ応用が利きそう]

procedure TForm1.Edit1KeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
type
  TLetters = set of 'A'..'z';
const
  Vowels: TLetters = ['A', 'E', 'I', 'O', 'U', 'a', 'e', 'i', 'o', 'u'];
begin
  if (Key<>VK_RETURN) and (Chr(Key) in Vowels) then
  begin
    Keybd_event(VK_RETURN,0,0,0);
    Keybd_event(VK_RETURN,0,KEYEVENTF_KEYUP,0);
  end;
end;
参照: [Delphi-ML:31097] <その他Windows関連> <Windows> <コンポーネント >

0139  D1   D2   D3   D4   D5   D6   D7   3.1   95   98    作成: 1999/02/11 osamu rev 1.1
   B1   B3   B4   B5   B6   B7   NT3   NT4   2K   XP  更新: 1999/02/11 osamu 編集
下の図柄がすける透明パネル

実行時に透明になるパネルコンポーネントです。

unit NkTransparent;

interface
uses
  Windows, Messages, SysUtils, Classes, Graphics,
  Controls, Forms, Dialogs;

type
  // 透明で 背景消去を行わない コンテナウィンドウコントロール
  TNkTransparent = class(TCustomControl)
  private
    procedure WMEraseBkGnd(var Msg: TWMEraseBkGnd);
              message WM_ERASEBKGND;
  protected
    procedure CreateParams(var Params: TCreateParams); override;
  public
    constructor Create(AOwner: TComponent); override;
  end;

procedure Register;

implementation

constructor TNkTransparent.Create;
begin
  inherited;
  Width := 100; Height := 100;
  // 上にコントロールが貼りつけられるようにする
  ControlStyle := ControlStyle + [csAcceptsControls];
end;

procedure TNkTransparent.WMEraseBkGnd;
begin
  // 実行時は背景消去をしない
  if csDesigning in ComponentState then inherited;
end;


procedure TNkTransParent.CreateParams(var Params: TCreateParams);
begin
  inherited;
  // 実行時は「透明」なウィンドウ
  if not (csDesigning in ComponentState) then
    Params.ExStyle := Params.Exstyle + WS_EX_TRANSPARENT;
end;

procedure Register;
begin
  RegisterComponents('NakCtrl', [TNkTransparent]);
end;

end.
参照: [Delphi-ML:24485] <コンポーネント >

0135  D1   D2   D3   D4   D5   D6   D7   3.1   95   98    作成: 1999/02/11 osamu rev 1.1
   B1   B3   B4   B5   B6   B7   NT3   NT4   2K   XP  更新: 1999/02/11 osamu 編集
表示中のポップアップメニューを消す

>プログラム上でポップアップメニューを表示するにはPopup メソッドを
>使えば出来るのですが、逆に非表示させるにはどうしたらよいのでしょう。
>よろしくお願いします。

キーボードイベントを送って非表示にする、というのはどうでしょう。

procedure TForm1.FormCreate(Sender: TObject);
begin
  Timer1.Interval := 1000;
  Timer1.Enabled := False;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  Timer1.Enabled := True;
  PopupMenu1.Popup(Button1.ClientOrigin.x,
    Button1.ClientOrigin.y + Button1.Height);
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  keybd_event(VK_ESCAPE, 0, 0, 0);
  keybd_event(VK_ESCAPE, 0, KEYEVENTF_KEYUP, 0);
  Timer1.Enabled := False;
end;

以上のコードで実行すると、ボタンを押すとポップアップしますが、約1秒後にポップアップが非表示になります。
参照: [Delphi-ML:24269] <メニュー> <コンポーネント >

0066  D1   D2   D3   D4   D5   D6   D7   3.1   95   98    作成: 1999/02/08 osamu rev 1.1
   B1   B3   B4   B5   B6   B7   NT3   NT4   2K   XP  更新: 1999/02/08 osamu 編集
PopupMenu に MainMenu のサブ項目をそのまま表示する

一つのメニューアイテムを、同時に二つのメニューに結び付ける事は出来ないようなので、実行時に、MainMenu と PopupMenu 、それぞれが開く時点で、共有するアイテムをそのメニューに結びつけ直す、という方法をとりました。ある位置から下を全部共有アイテムとする仕様です。

結び付け直すタイミングですが、PopupMenu の方は、OnPopup イベントで良いのですが、MainMenu の方は、(エディットメニュー以下をすべて使う場合に) Edit1 のOnClick だと、位置がずれたりしてうまくないので、WndProc をオーバーライドして、WM_INITMENU メッセージに応答させました。

以下は PASCAL 翻訳版

const COMMON_ITEM_START = 3;   // 共有アイテムの始まる位置

procedure TForm1.PopupMenu1Popup(Sender: TObject);
var Item: TMenuItem;
begin
  while Edit1.Count > COMMON_ITEM_START do begin
    Item:= Edit1.Items[COMMON_ITEM_START];
    Edit1.Remove(Item);
    PopupMenu1.Items.Add(Item);
  end;
end;

procedure TForm1.WndProc(var Msg: TMessage);
var Item: TMenuItem;
begin
  if (Msg.Msg=WM_INITMENU) and (Msg.WParam=Menu.Handle) then begin
    while PopupMenu1.Items.Count > COMMON_ITEM_START do begin
      Item:= PopupMenu1.Items[COMMON_ITEM_START];
      PopupMenu1.Items.Remove(Item);
      Edit1.Add(Item);
    end;
  end;
  inherited WndProc(Msg);
end;

参照: [builder:5012] <コンポーネント > <メニュー>

0083  D1   D2   D3   D4   D5   D6   D7   3.1   95   98    作成: 1999/02/08 osamu rev 1.1
   B1   B3   B4   B5   B6   B7   NT3   NT4   2K   XP  更新: 1999/02/08 osamu 編集
自作コントロールで IME 入力時の変換候補をキャレット位置に表示したい

IMEが編集を開始する直前にWM_IMESTARTCOMPOSITION というメッセージを送って来るので、そのメッセージを捕らえて設定してやります。

class TCustom : public TCustomControl
{
  ・・・・・・・・・・・・

   void __fastcall IMEStart(TMessage& Message);

   BEGIN_MESSAGE_MAP
      MESSAGE_HANDLER( WM_IME_STARTCOMPOSITION ,TMessage,IMEStart)
   END_MESSAGE_MAP(TCustomControl)
};

void __fastcall TCustom::IMEStart(TMessage& Message)
{
  //  IMEの位置をキャレットのポジションに設定
  COMPOSITIONFORM CompForm;
  POINT pt;
  LOGFONT lf;
  HIMC hImc=ImmGetContext(Handle);

  //キャンバスのフォントと同じに設定する
  GetObject(Canvas->Font->Handle,sizeof(LOGFONT),&lf);
  ImmSetCompositionFont(hImc,&lf);

  //キャレットのポジションに設定する
  ImmGetCompositionWindow(hImc,&CompForm);
  CompForm.dwStyle=CFS_POINT;
  GetCaretPos(&pt);
  CompForm.ptCurrentPos=pt;
  ImmSetCompositionWindow(hImc,&CompForm);

  ImmReleaseContext(Handle, hImc);

  // その他の処理
  ・・・・・・・・・・・・・
}
参照: [builder:5269] <その他Windows関連> <コンポーネント開発> <Windows> <コンポーネント >

0040  D1   D2   D3   D4   D5   D6   D7   3.1   95   98    作成: 1999/02/08 osamu rev 1.1
   B1   B3   B4   B5   B6   B7   NT3   NT4   2K   XP  更新: 1999/02/08 osamu 編集
フォームの印刷時にComboBoxの内容が印刷されない

Delphi3 になって、フォームの印刷時に TComboBox の内容(テキスト)が印刷表示されなくなりました。
Delphi2 ではちゃんと印刷されます。

kohiroさんが[Delphi-ML:19070]で解法を示してくださっています。
参照: [Delphi-ML:19070] <印刷> <バグ> <フォーム> <コンポーネント >

0018  D1   D2   D3   D4   D5   D6   D7   3.1   95   98    作成: 1999/02/08 osamu rev 1.1
   B1   B3   B4   B5   B6   B7   NT3   NT4   2K   XP  更新: 1999/02/08 osamu 編集
TMemoで入力*行数*を制限したい

アンドゥを犠牲にすれば、

procedure TForm1.Memo1Change(Sender: TObject);
const MaxLineCount=5;
begin
    if Memo1.Lines.Count>MaxLineCount then
        Memo1.Perform(EM_UNDO,0,0);
    Memo1.Perform(EM_EMPTYUNDOBUFFER,0,0);
end;

というのがうまく動きそうです。
参照: [Delphi-ML:5738] <Win95> <コンポーネント >

[新規作成] [最新の情報に更新]

How To
Lounge
KeyWords

Tips
Delphi
Home
Osamu Takeuchi osamu@big.or.jp

.