HTMLでのplaceholderみたいなのを、Memoで実現させるには?

解決


かんとく  2014-07-15 04:07:36  No: 46457

お世話になっております。

DelphiXE2,Windows7です。

Memoに、注意書きを入れたいと思います。
例えば、ソフト起動時に、Memoに「お名前を入力してください。」という文字を薄いグレー色で表示させます。

そのMemoに、ユーザが1文字でも入力したら、「お名前を入力してください。」は消えて、Memoにはユーザが入力した値が黒色で入ります。
ユーザ操作「Delete」「BackSpace」等でMemoの値が空になったら、再度「お名前を入力してください。」を表示したいです。

HTMLで言えば、<input>要素のplaceholder属性で実現できると思います。
これと同じようなことをしたいです。

よろしくお願いします。


通りすがり  2014-07-15 06:06:33  No: 46458

これですか?

Vcl.StdCtrls.TCustomEdit.TextHint - XE2 API Documentation
http://docwiki.embarcadero.com/Libraries/XE2/ja/Vcl.StdCtrls.TCustomEdit.TextHint


かんとく  2014-07-15 17:10:45  No: 46459

ありがとうございます。

サンプルコードを試してみましたが、うまくいきませんでした。

TCustomEdit
というのは、自分で作らないといけないコントロールなのでしょか?
ツールパレットでは、見つけきれませんでした。

もう少し、調べてみます。


DEKO  2014-07-15 20:21:49  No: 46460

TextHint は Vista 以降の OS で使えます。
但し、TEdit 等の TCustomEdit 派生コンポーネントのみです。

TEdit なら、TextHint プロパティに "お名前を入力してください。" と設定するだけです。TMemo での TextHint 実装例は StackOverflow にあります。

[CueText equivalent for a TMemo]
http://stackoverflow.com/questions/1465845/cuetext-equivalent-for-a-tmemo


通りすがり  2014-07-15 21:00:03  No: 46461

EM_SETCUEBANNER message (Windows)
http://msdn.microsoft.com/en-us/library/windows/desktop/bb761639.aspx

には明確に
> You cannot set a cue banner on a multiline edit control or on a rich edit control.
とあるので、TMemoではWindows標準の方法はだめですね。失礼しました。DEKOさんの投稿にあるStackOverflowの方法でしょうかね…


かんとく  2014-07-16 08:04:46  No: 46462

ありがとうございました。

Memoでは難しそうですが、Editを使って、うまくいきました。

とりあえず、Editを使います。

今後の参考のために、試行錯誤して分かったことをメモしておきます。

①デザイン時や、FormCreate時などに、
edit1.Text:='';
をする。

②ユーザが入力した文字列をDeleteやBackSpaceで消して欄が空になっても、
Focusが他に移らないと、TextHintが表示されない。

ありがとうございました。


通りすがり  2014-07-16 19:47:14  No: 46463

TEditのTextHintが、Textが空でかつフォーカスを持っていない状態でないと表示されない件は、TextHintを指定したタイミングで
  if CheckWin32Version(5, 1) and StyleServices.Enabled then
  begin
    SendTextMessage(Edit1.Handle,EM_SETCUEBANNER,WPARAM(1),Edit1.TextHint);
  end;
とすることで動作を変更することができます(usesにVcl.Themesを追加)。


かんとく  2014-07-17 07:59:20  No: 46464

ありがとうございます。

ご教授いただいた、「TextHintを指定したタイミング」というのは、具体的にいつでしょうか?

例えば、
・Edit1Change
とか
・FormCreate
とか、
procedureで教えていただけると、ありがたいです。

(ちなみに、Edit1Change、FormCreateで試してみましたが、うまくいきませんでした。)

よろしくお願いします。


通りすがり  2014-07-17 19:22:21  No: 46465

もしTextHintが予めプロパティとして指定されたもののみならば、OnShowイベントでいいんじゃないですかね。
TextHintにコードで文字列を代入するなら、その代入直後には必要です。
ためしにボタンをフォーム上において、ボタンのOnClickで試してみてください。
(TFormのOnCreateはタイミングとしては早すぎるのかもしれません)


かんとく  2014-07-18 09:08:42  No: 46466

ありがとうございます。

TextHintに文字列を代入するのを、デザイン画面でプロパティとして入力して、
コードでFormShowのprocedureに

if CheckWin32Version(5, 1) and StyleServices.Enabled then
   begin
     SendTextMessage(Edit1.Handle,EM_SETCUEBANNER,WPARAM(1),Edit1.TextHint);
   end;

を書きました。

このとき、実行前の段階で、
EM_SETCUEBANNER
の部分に赤い波線が入っていて、実行すると、
「DCCエラー  未定義の識別子:EM_SETCUEBANNER」
というメッセージが表示されるので、
このEM_SETCUEBANNERが未定義ということがうまくいかない原因ではないかな、と思います。

(ちなみに、「usesにVcl.Themesを追加」は行っています)

usesにさらに何かを追加すればいいんですかね?

よろしくお願いします。


deldel  2014-07-18 17:54:43  No: 46467

こういう場合の力技として、私がよくするのは、
C:\Program Files\Embarcadero\
の中を、EM_SETCUEBANNERを含むファイルが無いか検索することです。

今回は、Winapi.CommCtrl.pas というファイルの中に、
EM_SETCUEBANNER = ECM_FIRST + 1;
というのが見つかりましたから、これをusesすればいのかなと(試してませんが^^;)。


かんとく  2014-07-19 08:01:37  No: 46468

なるほど!
すばらしい技です。

usesにWinapi.CommCtrlを追加したら、うまくいきました。

ユーザがDelete、BackSpace等の操作をして、editの欄が空になった時に、フォーカスがeditにあるのに、(カーソルがeditの中で点滅している状態で)
TextHintが表示されました。

この技は、これからも使わせていただこうと思います。

ほんとにありがとうございました。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加