D&D したウィンドウにフォーカスを与えるには?

解決


メルル  2006-04-27 06:06:51  No: 21206

フォーム上にファイルをD&Dするアプリです。

WMDropFile(var Msg: TWMDropFiles);
このルーチンでファイル・ネームを受け取って、
例えば Memo1 などに Add すると即時表示されるのですが、
ドロップするファイルにフォーカスがあるためか、
フォームそのものはフォーカスを失った状態です。
そこで、このルーチンの先頭に

BringToFront;
SetFocus;

を入れてフォームにフォーカスを獲得しようとしているのですが、
フォーカスを失ったままで困っています。
該当ファイル・タイプ以外がドロップされると、エラー・ダイアログを
表示させるようにしているのですが、フォームにフォーカスが移った時点でしか
それが出ないので・・・。
どうかアドバイス、よろしくお願いいたします。


forever  2006-04-27 07:29:21  No: 21207

ウィンドウをアクティブにしたいのでしたら
var
  pt: TPoint;
  h: hwnd;
begin
    //マウスカーソル位置
    GetCursorPos(pt);
    //からウィンドウを探す
    h:=WindowFromPoint(pt);
    
    //見つかったらフォアグラウンドに持ってくる
    if h<>0 then
      SetForegroundWindow(h);
    
でなんとかなります。
    

>該当ファイル・タイプ以外がドロップされると、エラー・ダイアログを
>表示させるようにしているのですが、フォームにフォーカスが移った時点でしか
>それが出ないので・・・。

「ドロップできません」的なメッセージを表示したいんでしょうか?
だとしたら、ドロップそのものを禁止したほうがよいような気がします。


メルル  2006-04-27 07:44:03  No: 21208

foreverさん
できました。。。ありがとうございます。m(__)m

>ドロップそのものを禁止したほうがよいような
・・禁止マークにさせれば良さそうですね・・。

WMDropFile(var Msg: TWMDropFiles);

の仕様がよく分からないため、まぁいいか・・で済ませてしまって・・。
またちょっと調べてみます。
ありがとうございました。

#VCL のものでできると、ひょっとしたら・・な感じなんですけど、
#そこがよくわからなくて、ネットから拾ってきた方法でやってしまってます。


メルル  2006-04-27 07:46:49  No: 21209

一応、質問そのものは達成したので、解決です。


forever  2006-04-27 07:47:49  No: 21210

なにやってんだ。
ごめん

SetForegroundWindow(Handle)

だけでよかった(汗)


メルル  2006-04-27 08:21:32  No: 21211

何件か見てみましたが、ファイル種で、禁止にしたものは
見つからずじまいでした。また、VCL では
外部からの D&D はできない・・とも書いてあったり・・。

拡張子が違っていれば、カーソルを変更して、あとは、
「処理なし (Exit)」にすればいいかも知れませんね。これなら
ダイアログの必要もないわけですね。
・・・そう思って、テストしてみたところ、
Cursor := crNo;
これの効果が出ませんでした。で、このイベント・ルーチンの先頭に
これを配置しても「受け入れ可カーソル」のままでした。
ちょっと難しそうです・・。


メルル  2006-04-27 08:31:14  No: 21212

>なにやってんだ。

いやいいですよ。。
コピペして張り付けた瞬間に、マウス位置など関係なさそうだなーと
思ってましたから・・。

SetForegroundWindow(Handle) をいただけただけでハッピーです。。
これって、API の命令のようですね。Delphi のヘルプでは出ませんでした。
一応、Delphi Ver.1 の日本語版 API ヘルプは所有しているんですが、
Win3.1 の頃のですし、API 使ってまで・・な感じもあったりで、
ほとんど使わない先代の PC の中に眠ったままだったりします。


おまけ  2006-04-27 18:27:53  No: 21213

Win2000,XPあたりでは...
https://www.petitmonte.com/bbs/answers?question_id=3625


メルル  2006-04-27 21:34:03  No: 21214

おお、いろいろ難しいんですね・・。プロ・ソフトではないので、
実装しなくてもまぁ・・なんですが、この情報をいただけたことによって、
マニュアルに、「環境によって・・・の場合があります」と書けますね。

単純に、fsStayOnTop なども試してはみていたのですが、最全面に来るものの
フォーカスが来なくて、なんじゃそら・・な感じでした(笑)。

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


メルル  2006-04-28 00:46:15  No: 21215

さらに(たぶん)ベター解決・・。

この問題で、悩む人のために、経緯を残しておきます。
OSバージョン問題があるようなので、もう一工夫・・と
ちょっとやってみました。
ルーチンそのものは稼動しているようなので、自前のダイアログを
作ってみたらどうだろうと、下のようにしてみました。

type
  TForm2 = class(TCustomForm)
  private
    { Private 宣言 }
  public
    { Public 宣言 }
  end;

var
  Form2: TForm2;

件のルーチンの先頭に・・・。

  if Form2 <> nil then  // すでに作られていたら破棄する
    Form2.Free;

  Form2 := TForm2.CreateNew(self);//フォーム動的生成

  with  Form2 do
  begin
    Top := 100;
    Left := 100;
    Show;
    Button1 :=  TButton.Create(Form2);
    with  Button1 do
    begin
      Parent :=  Form2;
      Caption := 'My Botton';
      OnClick := Button1Click;
    end;
  end;

・・を入れて・・・とかやると、背部に隠れていたものの、
即時表示できました。で、BringToFront; でも入れるか・・と
ヘルプしてみたところ、最小化の質問で教えてもらった、
Application 。この中にも

Application.BringToFront;

・・がありました。これを使うと、上のような自前のダイアログとかでなくても、
また、わざさわざフオーカスをゲットしなくても、質問を上げた状態から、
この1行の追加で、一気に解決しました。
これだと、どのOSでも行ける可能性は高そうに思います。

大ボケ的なこと、いろいろありますね(笑)。


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

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






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