コンボボックスのフォーカス

解決


orz  2007-02-25 02:32:10  No: 25074

フォーム上に Style=csDropDown のコンボボックスがある
このコンボボックスにフォーカスがあり、表示中の文字列は選択状態にない
(SelectAllではなく、非選択 or 部分選択)

別のアプリに切り換え戻ってくると、SelectAll の状態になっている
別のフォームに切り換えて戻ってきても同じ。

さて、ここで質問。

SelectAll 状態にしない方法はありますか?


えーと  2007-02-25 11:28:00  No: 25075

あります。


orz  2007-02-26 22:08:05  No: 25076

> あります。
それは、メッセージの処理(WM_COMMANDあたり?)で、なにかするのでしょうか?
それとも、コンボボックススタイル設定で、自動的になるものなんでしょうか?

もう一声、ヒントをお願いします。

# 「ないよ」って返事を期待したから、あるなししか聞いてない俺に反省


■\(_"_);  2007-02-26 23:19:56  No: 25077

「あるよ」その1

procedure TForm1.ApplicationEvents1Activate(Sender: TObject);
begin
  ComboBox1.SelLength := 0;
end;


えーと  2007-02-27 01:35:14  No: 25078

こんな感じ。フォーム間の遷移でも有効です。

    { Private 宣言 }
  public
    procedure WMActivate(var Msg:TWMActivate); message WM_ACTIVATE;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

...

procedure TForm1.WMActivate(var Msg:TWMActivate);
var
  hEdit: HWND;
  k: integer;
begin
  if ActiveControl is TComboBox then
  begin
    hEdit := GetWindow(TComboBox(ActiveControl).Handle, GW_CHILD);
    if hEdit <> 0 then
    begin
      k := SendMessage(hEdit, EM_LINELENGTH, 0, 0);
      PostMessage(hEdit, EM_SETSEL, k, k);
    end;
  end;
end;


えーと  2007-02-27 01:38:25  No: 25079

ちょっと訂正。

if ActiveControl is TComboBox then

この部分を

if (ActiveControl is TComboBox) and (Msg.Active <> WA_INACTIVE) then

にしてください。


orz  2007-02-27 02:49:42  No: 25080

お二方のレスありがとうございます。

どちらも、無条件選択解除にしてしまうわけですね。

Editのように、「選択状態を維持する」ことはできない
コンボボックスの仕様なんでしょうか?

そして今頃思いついた単語「ソフトウェアキーボード」
これに近いことをしているのであります。
ということで、「ソフトウェアキーボード」の手法が使えないか、
調査してみます。

せっかく回答頂いたところ恐縮ではございますが、これにて〆ます。
ありがとうございました。


〆開け  2007-02-27 04:32:54  No: 25081

「ソフトウェアキーボード」というのは、入力対象のウィンドウのActive状態を
強制的に維持している(「ソフトウェアキーボード」のボタンをクリックしても
入力対象のウィンドウは非Activeにならない)ので、今回のテーマの参考には
ならないと思うのですが。
他からComboBoxにフォーカスが移ると SelectAllの状態になってしまうのは、
「そういう仕様だ」と諦めるしかないのでは?


えーと  2007-02-27 07:08:04  No: 25082

>Editのように、「選択状態を維持する」ことはできない
>コンボボックスの仕様なんでしょうか?

できますよーー。

でも、質問は

>SelectAll 状態にしない方法はありますか?

でしたから。

  private
    { Private 宣言 }
    selStart, selEnd: integer;
  public
    { Public 宣言 }
    procedure WMActivate(var Msg: TWMActivate); message WM_ACTIVATE;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

uses
  Unit2;

procedure TForm1.WMActivate(var Msg: TWMActivate);
var
  hEdit: HWND;
begin
  if Msg.Active <> WA_INACTIVE then
  begin
    if ActiveControl is TComboBox then
    begin
      hEdit := GetWindow(ActiveControl.Handle,GW_CHILD);
      PostMessage(hEdit, EM_SETSEL, selStart, selEnd);
    end;
  end
  else
  if Msg.Active = WA_INACTIVE then
  begin
    if ActiveControl is TComboBox then
    begin
      hEdit := GetWindow(ActiveControl.Handle,GW_CHILD);
      SendMessage(hEdit, EM_GETSEL, WParam(@SelStart), LParam(@selEnd));
    end;
  end;
end;


orz  2007-02-27 08:04:38  No: 25083

えーと さん、重ね重ねありがとうございます。

そうです、全て自分の質問の仕方が悪かったのです。
HNがごとく、 orz ・・・

>      k := SendMessage(hEdit, EM_LINELENGTH, 0, 0);
>      PostMessage(hEdit, EM_SETSEL, k, k);
しかも、ここで、「あ〜できないのね」と、早とちり。

テストもろくにせず、質問者として最低と呼ばれても仕方がないです。
猛省しますので、また機会がありましたら、よろしくお願いします。

レスいただいたコードは、備忘録に蓄えておきます。
今回は、前述の通りソフトウェアキーボード(まがい?)に挑戦します。
ありがとうございました。


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

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






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