[BlueLeaf1336]> PROBLEMS> PasteIt>
history | TOP |
2007/02/08:作成
2007/02/21:その前に、デスクトップのダブルクリック検出をこましに
はじめに | TOP |
デスクトップのダブルクリックは、途中でほっぽり出した形になってしまいましたが、仕事じゃないので全然オッケー。次に進むことにします。まずは、About Delphi でずっと前にダウンロードしてきた、Delphi-ML で「壁紙」を検索してみます。オフラインなので。
その前に、デスクトップのダブルクリック検出をこましに(2007/02/21) | TOP |
壁紙のことを、Delphi-ML で調べてみましたが、調べながら思いついたことがあって試してみたところ少しばかりいい感じになりました。
目的語がありませんでしたが、「デスクトップのダブルクリック検出」のことです。
時間がかかるアプリを起動するときってマウスのカーソルが時計になるやん500ミリ秒待ってなおウィンドウができひんからアイコンのダブルクリックとデスクトップのダブルクリックを見まがうんやからそれはそれでおいといてそれとは別にカーソルの変化を監視しとけばどうよスレッドかなんかでひたすらよぅ。やってみよう。
そんなこんなでそれなりにましな感じになりました。でも完璧ではなさそうですけど。
20070221PasteIt.zip(223,250bytes) 実行ファイルとソースコード。
実行結果。各行末の日本語は手で書き加えています。TMemoなので。
「カーソルの監視の変化」なんて大げさに書いてますが、やってることは単純で、GetCursorInfo を使ってカーソルのハンドル(HCURSOR つまるところ HICON)をひたすら取得し比較しているだけです。で、変化がおきたら、前回説明した(はず)、「実行予約」をキャンセルします。
//----------------------------------------------------------------------------- // カーソルハンドルを取得 function GetCursorHandle(): HCURSOR; var LCursorInfo: TCursorInfo; begin FillChar(LCursorInfo, SizeOf(LCursorInfo), 0); LCursorInfo.cbSize := SizeOf(LCursorInfo); GetCursorInfo(LCursorInfo); Result := LCursorInfo.hCursor; end;
ちなみに、その実行予約とキャンセルを処理しているのはこんなスレッドです。
(略) //----------------------------------------------------------------------------- // 時間差で処理を実行するクラス type TExecuteProc = procedure() of object; TTimeLagExecuter = class(TThread) private FTick: Cardinal; procedure ExecProc(); public TimeLag: Cardinal; ExecuteProc: TExecuteProc; protected procedure Execute(); override; procedure Reserve(); procedure Cancel(); public constructor Create(); end; (略) implementation (略) //============================================================================= // 時間差で処理を実行するクラス //----------------------------------------------------------------------------- // コンストラクタ constructor TTimeLagExecuter.Create(); begin inherited Create(True); // 待ち時間初期値 TimeLag := 500; FTick := 0; // 実行関数初期化 ExecuteProc := nil; end; //----------------------------------------------------------------------------- // 処理実行 procedure TTimeLagExecuter.ExecProc(); begin if Assigned(ExecuteProc) then begin ExecuteProc(); end; end; //----------------------------------------------------------------------------- // 処理を予約 procedure TTimeLagExecuter.Reserve(); begin FTick := GetTickCount(); end; //----------------------------------------------------------------------------- // キャンセル procedure TTimeLagExecuter.Cancel(); begin FTick := 0; end; //----------------------------------------------------------------------------- // メインループ procedure TTimeLagExecuter.Execute(); var LPrevCursor: HCURSOR; LCurrCursor: HCURSOR; begin inherited; LPrevCursor := GetCursorHandle(); while not Terminated do begin Sleep(1); // カーソルが変更されたら有無を言わさずキャンセル LCurrCursor := GetCursorHandle(); if (LPrevCursor <> LCurrCursor) then begin Cancel(); LPrevCursor := LCurrCursor; end; if (FTick > 0) and (GetTickCount() - FTick > TimeLag) then begin // 処理実行 Synchronize(ExecProc); Cancel(); end; end; end; (略) end.
アプリ起動時にこのスレッドクラスのインスタンスを作成して、ExecuteProc に実行したい procedure を代入しておきます(いわゆる関数ポインタです)。で、ダブルクリックを検出したら Reserve() を呼び出し、ウィンドウが作成されたら Cancel() を呼び出す。それとは別に、このスレッド自身が、マウスカーソルのハンドルを取得・比較し続けていて、変化したら Cancel() を呼び出しています。
で、Reserve() されてから 500ミリ秒 Cancel() されなければ、ExecuteProc を実行します。ヌルポとガッの関係です。
話は変わって、壁紙に何か自前の画像を組み合わせて書き戻すのって邪魔くさそう...タイル表示とかされてたりしたらどうしよう。
EOF | TOP |