喫茶XRAYトップページ

[スレッド全体
]

[8551] システムボタンのヒント表示をフック返信 削除
2015/3/9 (月) 05:53:48 Mr.XRAY
>  (1) ヒントウィンドウが表示された
>  (2) その対象のフォームがアクティブである
>  (3) マウスカーソルが非クライアント領域にある
>     (ボタン等に[閉じる]のヒントを設定している場合の対策)


(1) の部分だけテストしてみました.
(2) 以下の処理がないので,別のウィンドウでも検出してしまいます.

http://mrxray.on.coocan.jp/Delphi/zip/CloseButton_HintHook.zip
( 463 KB EXE のみ )

[注]
検出結果を TMemo に表示していますが,表示している文字は,ヒントの
テキストではなく,閉じるボタン等のオブジェクトの名前です.


[8553] ツールチップ返信 削除
2015/3/9 (月) 17:46:50 Mr.XRAY
>システムボタンのヒント

ツールチップのことです.


[8556] Re:ツールチップ返信 削除
2015/3/9 (月) 21:28:09 たてぐや
▼ Mr.XRAYさん
 
> まぁ、気が向いたときの調査物件入りです。

 とか言いながらさらっと作っちゃうんだからさすが我らがMr.XRAYさんです。
好奇心と挑戦力に感心します。私にはとても真似できないエネルギーです。ど
うせ私は不善をなす小人です。ちょっと疲れた…。

[8557] Re2:ツールチップ返信 削除
2015/3/9 (月) 21:49:45 Mr.XRAY
▼ たてぐやさん,おかぽんさん.

いまのところ,ここまでです.
時間があったら,やるかどうかはわかりませんです (^^;
ツールチップの情報が取得できれば,直接操作できるのかも知れませんが,
今のところ分かりません.


[8558] Re3:ツールチップ返信 削除
2015/3/9 (月) 23:01:08 たてぐや
▼ Mr.XRAYさん

> とか言いながらさらっと作っちゃうんだから

 そんなふうに見えているけど、その影では大変な労力をつぎ込んでいるのは
よく解ります。
 毎度ですが、ご苦労さまです。

[8559] Re4:ツールチップ返信 削除
2015/3/9 (月) 23:17:37 Mr.XRAY
▼ たてぐやさん

>  そんなふうに見えているけど、その影では大変な労力をつぎ込んでいるのは
> よく解ります。


ですよ.そうなんですよ.ううっ.
たてぐやさん.ありがとうございます.
方針が決まれば,たとえ時間がかかってもスムーズにいくんでけどね.

今回は
[05_オブジェクトのイベントフック - エクセルの起動と終了等を監視]
http://mrxray.on.coocan.jp/Delphi/plSamples/678_IAccessibleInterface.htm#05

を思い出したので,割とすんなりといきましたが.
その,元のサンプルを作るのだって,実は,結構苦労しているんですよね.


[8554] 閉じるボタンのツールチップの表示をフック返信 削除
2015/3/9 (月) 19:37:14 Mr.XRAY
とりあえず,テストで使用したコードです.
動作確認は Windows 7 U64(SP1) + Delphi XE(UP1) Pro です.

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Memo1: TMemo;
    procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private 宣言 }
    hEventHook : THandle;
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

uses OleAcc;

{$R *.dfm}

// Delphi XEにはないので定義
function AccessibleObjectFromEvent(hWnd : HWND; dwObjewctID : DWORD;
  dwChildID : DWORD; out pacc : IAccessible; out pvarChild   : OleVariant):
  HResult;  stdcall; external 'OLEACC.DLL';
function AccessibleObjectFromPoint(ptScreen: TPOINT; out ppAcc: IAccessible;
  out pvarChild: OleVariant): HRESULT ; stdcall; external 'OLEACC.DLL';


//-----------------------------------------------------------------------------
//  ウィンドウのクラス名を取得する関数
//-----------------------------------------------------------------------------
function GetClassNameStr(hWindow: HWND): String;
var
  Buffer : array[0..MAX_PATH-1] of Char;
  Len    : Integer;
begin
  System.FillChar(Buffer, SizeOf(Buffer), #0);
  Len := Windows.GetClassName(hWindow, Buffer, Length(Buffer));
  if Len > 0 then Result := Buffer else Result := '';
end;

//-----------------------------------------------------------------------------
//  フック関数SetWinEventHookのコールバック関数
//-----------------------------------------------------------------------------
procedure WinEventProc(hWinEventHook: THandle; event: DWORD; hwnd: HWND;
  idObject, idChild: Longint; idEventThread, dwmsEventTime: DWORD); stdcall;
var
  LMousePos : TPoint;
  LpAcc     : IAccessible;
  LText     : WideString;
  Lacc      : IAccessible;
  LvarChild : OleVariant;
begin
  //イベントの引数からAcc(IAccessible)とvarChild(OleVariant)を取得
  //#32774はシステムのツールチップのクラス名
  if AccessibleObjectFromEvent(hwnd, idObject, idChild, Lacc, LvarChild) = S_OK then begin
    if GetClassNameStr(hwnd) = '#32774' then begin
      if event = EVENT_OBJECT_SHOW then begin

        //マウスカーソル位置を取得
        GetCursorPos(LMousePos);

        //マウスカーソル位置のIAccessibleオブジェクトを取得
        //AccessibleObjectFromPoint関数の戻り値のvarChildのvtは,常にVT_I4となっている
        if AccessibleObjectFromPoint(LMousePos, LpAcc, LvarChild) = S_OK then begin
          //Nameプロパティの値を取得
          if LpAcc.Get_accName(LvarChild, LText) = S_OK then begin
            Form1.Memo1.Lines.Add(LText);
          end else begin
            Form1.Memo1.Lines.Add('不明');
          end;
        end;
      end;
    end;
  end;
end;

//=============================================================================
//  [Start HOOK] フック開始
//  hEventHook  : フックのハンドル
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
begin
  Memo1.Lines.Clear;
  if hEventHook = 0 then begin
    hEventHook := SetWinEventHook(
                             EVENT_MIN,
                             EVENT_MAX,
                             0,
                             WinEventProc,
                             0,
                             0,
                             WINEVENT_OUTOFCONTEXT);
    if hEventHook = 0 then begin
      Memo1.Lines.Add('フック関数の登録失敗');
    end else begin
      Memo1.Lines.Add('フック開始');
    end;
  end;
end;

//=============================================================================
//  [Stop HOOK] フックの終了
//=============================================================================
procedure TForm1.Button2Click(Sender: TObject);
begin
  if hEventHook <> 0 then begin
    UnhookWinEvent(hEventHook);
    hEventHook := 0;
    Memo1.Lines.Add('フック終了');
  end;
end;

//=============================================================================
//  フォームの作成時 変数の初期化
//=============================================================================
procedure TForm1.FormCreate(Sender: TObject);
begin
  hEventHook := 0;
end;

//=============================================================================
//  フォームを閉じる時は,フックを終了させる
//=============================================================================
procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
  if hEventHook <> 0 then UnhookWinEvent(hEventHook);
end;

end.


[▼次のスレッド]
INCM/CMT
Cyclamen v3.82