imageのハンドル取得について

解決


あいうえお  2004-11-18 20:53:33  No: 11819

こんにちわ。

D&Dで画像を取得するように作成しているのですが、
複数のimageコンポーネントがあり(image1とimage2)どこに
マウスのポイントがあたっているかを取得したいのですが、
image.Handleというのはないようで困ってます。

procedure TForm1.DropFiles(var Msg:TWMDROPFILES);
var
WinHnd : HWND; 
fn : array [0..MAX_PATH] of Char;
P:TPoint;
begin
    DragQueryFile(Msg.Drop, 0, fn, MAX_PATH);
    DragQueryPoint(Msg.Drop, P);
    WinHnd:= WindowFromPoint(ClientToScreen(P));

//** ここでWinHnd の中身を調べてimage1かimage2かを調べたい。

if WinHnd=Image1のハンドル  then
     begin
        Image1.Picture.LoadFromFile(fn);
       img_b.Text := fn;
     end;
if WinHnd=Image2のハンドルthen
     begin
         Image2.Picture.LoadFromFile(fn);
         img_s.Text := fn;
     end;

        DragFinish(msg.Drop);
end;

image1かimage2のどちらの上にマウスが来たかをわかるようにしたいのですが、どのように取得すればよいのでしょうか?
宜しくお願致します。


かきくけお  2004-11-18 21:33:11  No: 11820

TImage は TWinControl の派生クラスではないのでハンドルはありません。

TForm のControlAtPos メソッドをつかいます。ヘルプより

ControlAtPos メソッドは,コントロール内の指定位置にある子コントロールを返します。

function ControlAtPos(const Pos: TPoint; AllowDisabled: Boolean, AllowWinControls:Boolean=False): TControl;

かえってきた TControl を TImage にキャストすると、そのまま操作できます。
最初に is で型チャックを忘れずに。


あいうえお  2004-11-18 23:13:10  No: 11821

かきくけこ  さんありがとうございました。

Control := ControlAtPos(p,true, False);
でコントロールを取得しました。
(引数のパラメータが良くわからなかったんですけど、、)

>かえってきた TControl を TImage にキャストすると、そのまま操作できます。

調べたのですがみつかりません。
どのようにキャストするのでしょうか?

宜しくお願致します。


かきくけこ  2004-11-19 00:52:37  No: 11822

例をあげます。新規で試してください。Form1 に

    Image1: TImage;
    Image2: TImage;
    PaintBox1: TPaintBox;
    ApplicationEvents1: TApplicationEvents;

をデフォルトのサイズでおいてください。そして

procedure TForm1.FormCreate(Sender: TObject);
begin
  with Image1 do begin
    Picture.Bitmap.Width := Width;
    Picture.Bitmap.Height := Height;
    Picture.Bitmap.Canvas.Brush.Color := clLime;
    Picture.Bitmap.Canvas.FillRect(ClientRect);
  end;
  with Image2 do begin
    Picture.Bitmap.Width := Width;
    Picture.Bitmap.Height := Height;
    Picture.Bitmap.Canvas.Brush.Color := clAqua;
    Picture.Bitmap.Canvas.FillRect(ClientRect);
  end;
end;

procedure TForm1.ApplicationEvents1Message(var Msg: tagMSG;
  var Handled: Boolean);
var
  ctrl:TControl;
begin
  if (Msg.hwnd = Handle) and (Msg.message = WM_LBUTTONDOWN) then
  begin
    ctrl := ControlAtPos(Point(LOWORD(Msg.lParam),HIWORD(Msg.lParam)),true,false);
    if ctrl is TImage then
      PaintBox1.Canvas.Draw(0,0,TImage(ctrl).Picture.Graphic)
    else
      PaintBox1.Refresh;
  end;
end;

とします。実行して、Image1 または Image2 のうえでクリックすると
PaintBox1 にその色が反映されます。Form1を直接クリックすると
色が消えます。

TImage(ctrl).Picture.Graphic

に注目してください。キャストの効用です。


あいうえお  2004-11-19 19:38:13  No: 11823

かきくけこさんどうもありがとうございました。
上記ソースで同じように動作しました。
そこで、このように私のソースを修正してみました。

procedure TForm1.DropFiles(var Msg:TWMDROPFILES);
var
WinHnd : HWND; P:TPoint;
ctrl: TControl;
begin

    DragQueryFile(Msg.Drop, 0, fn, MAX_PATH);
    DragQueryPoint(Msg.Drop, P);
    WinHnd:= WindowFromPoint(ClientToScreen(P));

    ctrl := ControlAtPos(P,true,false);

    if ctrl is TImage then
         TImage(ctrl).Picture.LoadFromFile(fn);

        DragFinish(msg.Drop);
end;

ctrlにTimageのimage1やimage2を入れるという形なんですね。

でも、ctrl := ControlAtPos(P,true,false);nのctrlにnilが入ってしまいます。
Pは座標でx220y585などと入っているのになぜでしょうか?

ご教授いただけたらと思います。
宜しくお願致します。


かきくけこ  2004-11-19 20:32:04  No: 11824

ctrl := ControlAtPos(P,true,false);

    if ctrl is TImage then
         TImage(ctrl).Picture.LoadFromFile(fn);

ここの部分だけ Button1Click で確認したらいいんでは?

P に Image1 が必ず含むようなフォームの点の座標を与え、

if ctrl is TImage then Caption := ctrl.Name;

を実行してみてフォームのキャプションに Image1 と表示されたらOK


あいうえお  2004-11-20 00:50:36  No: 11825

かきくけこさんありがとうございます。
試してみましたが動作しました。

しかし、座標取得でわからないところがあります。
例えば実行前のフォームの上にimage1があり、マウスを近づけて
左上座標16,16 となっているのですが、
DragQueryPoint(Msg.Drop, P);  
で座標を取得すると90.85となってしまいます。

Msg.Dropの中がおかしいのでしょうか?

imageをpanelの上においているのですが、パネルの上におくことによって
座標が変わるということがあるのでしょうか?

認識不足で申し訳ありません。
ご教授お願致します。


かきくけこ  2004-11-20 01:59:28  No: 11826

> imageをpanelの上においているのですが

あっ、そうですか。それでは Form の ControlAtPos は使えませんね。
ControlAtPos は直接の子コントロールしかわかりませんから。


あいうえお  2004-11-20 03:01:43  No: 11827

かきくけこさん。
長々ありがとうございました。
ためしにパネルからはずし、フォームの上においてみたら
思ったとおり動作しました。

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


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

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






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