システムメニューの左マウス押下での処理メッセージの流れを監視するには

解決


おも  2008-01-19 08:31:24  No: 29363

環境 Delphi6 Personal Win2000

質問したいことが少し複雑なので、質問内容に対して適切な質問タイトルとなっていないかも知れませんがよろしくお願いします。

1組のキーボードとマウスで複数のPCを操作する「どこドア」の機能をアプリケーションの付随機能として組み込もうとしています。
現在、操作元PCでマウスフックし、それを得て、操作先のPCにマウス操作命令を送信し、
        
SetCursorPos(pMs.X,pMs.Y);
MOUSE_EVENT(MOUSEEVENTF_LEFTDOWN,0,0,0,0);

で左マウス押下等の動作を実現できています。

しかし、この操作を実現している自製アプリケーションのシステムメニュー(最小化、最大化、閉じる)で左マウス押下をすると、その時点で、操作先でマウス操作命令(Label表示で確認)が受信されなくなり、以降は遠隔操作ができません。
現在、把握している現象は以下の通りです。

・操作先でマウス操作命令を処理するアプリケーションのどのフォームの場合でも現象は起こる
・遠隔操作が不能となっても、操作先PCを直接マウスで操作すればマウスは動き、システムメニューから離れる、あるいはクリック動作を完結させると、その後はまた遠隔操作可能に復帰
・マウス操作命令を処理しない他のアプリケーションのシステムメニュー操作の場合には起こらない
・押下のところを続けてMOUSE_EVENT(MOUSEEVENTF_LEFTUP,0,0,0,0)を実行し、クリックの処理にしてやると最大化/最小化/閉じると言った本来の動作が実現
・マウス操作命令受信部をスレッドにして独立させても現象は変わらず

これらから、システムメニューの押下のメッセージ処理部で処理が滞っていると思いますが、操作先PCでデバッグモードにしても、それ自体がメッセージを発してしまうので、今の私にはこれ以上調べる手段がありません。

そこで、
1.操作実現アプリケーションのシステムメニューに対する操作でも問題なく動作する方法
2.さらに調査を進めるために、メッセージ処理の流れを追う方法

に関して何か良いアドバイスがあればよろしくお願いします。

一応、アプリケーションから切り離して、システムメニューを操作することのない別アプリケーションでの作成で目的自体は達成しようと考えていますが、可能であるのならば現在のやり方で実現したいです。よろしくお願いします。


KHE00221  2008-01-20 05:07:57  No: 29364

押下のところを続けてMOUSE_EVENT(MOUSEEVENTF_LEFTUP,0,0,0,0)を実行し、クリックの処理にしてやると最大化/最小化/閉じると言った本来の動作が実現
ってことは・・・なんとなく UP系のメッセージ を処理していないような気がするけど?


おも  2008-01-20 06:30:11  No: 29365

KHE00221さん、レス有難うございます。
>>なんとなく UP系のメッセージ を処理していないような気がするけど?

すこし誤解されているようなので追加説明をしておきます。

マウス操作命令を受け取っての処理部は

SetCursorPos(pMs.X,pMs.Y);

case WM_Msg of
  WM_LBUTTONDOWN:   MOUSE_EVENT(MOUSEEVENTF_LEFTDOWN,0,0,0,0);
  WM_LBUTTONUP:     MOUSE_EVENT(MOUSEEVENTF_LEFTUP,0,0,0,0);
  WM_RBUTTONDOWN:   MOUSE_EVENT(MOUSEEVENTF_RIGHTDOWN,0,0,0,0);
  WM_RBUTTONUP:     MOUSE_EVENT(MOUSEEVENTF_RIGHTUP,0,0,0,0);

  WM_NCLBUTTONDOWN: MOUSE_EVENT(MOUSEEVENTF_LEFTDOWN,0,0,0,0);
  WM_NCLBUTTONUP:   MOUSE_EVENT(MOUSEEVENTF_LEFTUP,0,0,0,0);
  WM_NCRBUTTONDOWN: MOUSE_EVENT(MOUSEEVENTF_RIGHTDOWN,0,0,0,0);
  WM_NCRBUTTONUP:   MOUSE_EVENT(MOUSEEVENTF_RIGHTUP,0,0,0,0);
end;

という形で、この処理をしているアプリケーションのシステムメニュー以外の部分では、左右マウスの押下、押上のすべての動作が実現しています。

>>押下のところを続けてMOUSE_EVENT(MOUSEEVENTF_LEFTUP,0,0,0,0)を実行し、クリックの処理にしてやると最大化/最小化/閉じると言った本来の動作が実現
というのは、以下のようにコードを変更した時のことです。

SetCursorPos(pMs.X,pMs.Y);

case WM_Msg of
  WM_LBUTTONDOWN:begin
                    MOUSE_EVENT(MOUSEEVENTF_LEFTDOWN,0,0,0,0);
                    MOUSE_EVENT(MOUSEEVENTF_LEFTUP,0,0,0,0);
                end;
  WM_LBUTTONUP:     MOUSE_EVENT(MOUSEEVENTF_LEFTUP,0,0,0,0);
  WM_RBUTTONDOWN:   MOUSE_EVENT(MOUSEEVENTF_RIGHTDOWN,0,0,0,0);
  WM_RBUTTONUP:     MOUSE_EVENT(MOUSEEVENTF_RIGHTUP,0,0,0,0);

  WM_NCLBUTTONDOWN: MOUSE_EVENT(MOUSEEVENTF_LEFTDOWN,0,0,0,0);
  WM_NCLBUTTONUP:   MOUSE_EVENT(MOUSEEVENTF_LEFTUP,0,0,0,0);
  WM_NCRBUTTONDOWN: MOUSE_EVENT(MOUSEEVENTF_RIGHTDOWN,0,0,0,0);
  WM_NCRBUTTONUP:   MOUSE_EVENT(MOUSEEVENTF_RIGHTUP,0,0,0,0);
end;

上記のコード変更は、

1.操作元PCで左マウス押下フック
2.操作元PCから左マウス押下操作命令送信
3.操作先PCで左マウス押下操作命令受信
4.操作先PCで左マウス押下処理

5.操作元PCで左マウス押上フック
6.操作元PCから左マウス押上操作命令送信
7.操作先PCで左マウス押上操作命令受信
8.操作先PCで左マウス押上処理

といった流れを

1.操作元PCで左マウス押下フック
2.操作元PCから左マウス押下操作命令送信
3.操作先PCで左マウス押下操作命令受信
4.操作先PCで左マウス押下処理
5.操作先PCで左マウス押上処理

という流れに変更したということです。

そして、確認しているのは、この処理を実行するアプリケーションのシステムメニューで、変更前のコードでは、6.操作元PCから左マウス押上操作命令送信はしているのに、7.操作先PCで左マウス押上操作命令受信(Label表示で確認)ができていないということです。


KHE00221  2008-01-20 07:14:18  No: 29366

送信しているのに受信しないというのは・・・HOOKの話じゃないよね

>システムメニューの押下のメッセージ処理部で処理が滞っていると思いますが

こうなっていようが  送受信  には関係ない話だからね

操作元のフックを DLL を使わずに WH_MOUSE をフックすると
システムメニュー表示とかフォームサイズ変更でフックしなくなるみたいなんだけど

操作元を操作したりはしてないのかな?

WH_JOURNALRECORD なら問題ないみたいだけど


KHE00221  2008-01-20 07:18:15  No: 29367

1PCで直接座標指定などで

5.操作元PCで左マウス押上フック
6.操作元PCから左マウス押上操作命令送信
7.操作先PCで左マウス押上操作命令受信
8.操作先PCで左マウス押上処理

この操作を行なった場合にも同じ状況になるのかな?

あと対象が自作アプリ以外でもおきるのかな?


KHE00221  2008-01-20 07:20:31  No: 29368

7.操作先PCで左マウス押上操作命令受信(Label表示で確認)

これは受信イベント事態がおきていないって事なのかな?


おも  2008-01-20 09:16:05  No: 29369

>>送信しているのに受信しないというのは・・・HOOKの話じゃないよね

操作元でのフックは引き続き正常で、操作元PCから操作先PCへマウス操作命令を出しているのに受信しないということです。

>>>システムメニューの押下のメッセージ処理部で処理が滞っていると思いますが

>>こうなっていようが  送受信  には関係ない話だからね

私もそうあるべきとは思いますが、現状では、システムメニュー押下によって、他の処理も受け付けなくなっているように思います。ただ、操作先PCを直接マウスで操作しようとするとできるので、全く処理を受け付けないというわけでもないようです。

>>操作元のフックを DLL を使わずに WH_MOUSE をフックすると
>>システムメニュー表示とかフォームサイズ変更でフックしなくなるみたいなんだけど

う〜ん、今回の問題はフック自体ではないのですが、なんか関係がありそうな現象ですね。

>>操作元を操作したりはしてないのかな?

操作元では、マウスフックしたところですべてのメッセージはフックしたメッセージとしてWndProcに送り、
1.WM_MOUSEMOVEは、操作先PCへのマウス操作命令送信とそのままのデフォルト処理
2.WM_MOUSEMOVE以外は、操作先PCへのマウス操作命令送信のみ

ということで、操作元PCはマウスがどこにあるかがわかるようにマウス移動だけしている状態です。

>>1PCで直接座標指定などで

>>5.操作元PCで左マウス押上フック
>>6.操作元PCから左マウス押上操作命令送信
>>7.操作先PCで左マウス押上操作命令受信
>>8.操作先PCで左マウス押上処理

>>この操作を行なった場合にも同じ状況になるのかな?

スレッドにはしていませんが、TEidtのOnChangeにコードを書き、そこでマウス操作命令を処理するようにして確認してみました。結果は、同じようです。システムメニューの押下でEdit1への入力が不可能になり、ここで、直接マウスで、システムメニューから離れて、クライアント領域でクリックしてやると元に戻り、そこまでに押していたキーが一気にEdit1へ入力されました。

あと、最初の投稿で書いた把握している現象の二番目は少し違っていたようです。
>>・遠隔操作が不能となっても、操作先PCを直接マウスで操作すればマウスは動き、システムメニューから離れる、あるいはクリック動作を完結させると、その後はまた遠隔操作可能に復帰

システムメニューから離れるだけではだめで、クリック動作の完結が必要なようです。

>>あと対象が自作アプリ以外でもおきるのかな?

起きません。それから、自作アプリといっても、マウス操作処理をしているアプリだけです。そのアプリであれば、どのフォームでも同じです。

>>これは受信イベント事態がおきていないって事なのかな?

受信した命令テキストの表示が変化しませんので、そうだと思います。操作先PCを直接マウスで操作して遠隔操作可能な状態に復帰させると、それまでの遠隔操作不能時に行っていた操作元PCでの動作が一気に起こり、操作先PCで、マウスが色々動いたりします。これは、先ほどの1PCでTEditを使った場合と同じですね。

あと、今回の1PCでのTEditを使った場合のチェック中に気がついたのですが、フォームのクライアント領域で左マウス押下した場合に、TEditへの入力は、通常のアルファベット、BaskSpaceキー等は問題ないですが、→、←は効かなくなりますね。


おも  2008-01-20 09:34:25  No: 29370

>>あと、今回の1PCでのTEditを使った場合のチェック中に気がついたのですが、フォームのクライアント領域で左マウス押下した場合に、TEditへの入力は、通常のアルファベット、BaskSpaceキー等は問題ないですが、→、←は効かなくなりますね。

自己レスですが、メモ帳のシステムメニューを左押下すると、点滅しているカーソルが点滅しなくなりました。また、例えば、現在入力中のこの入力欄のカーソルもIEですが、そのシステムメニューボタンを左押下すると点滅がとまります。

システムメニューが左マウス押下された状態というのは、その時点で処理している一連の命令は最後まで実行されるが、それ以降は、マウスメッセージのみしか受け付けないという仕様なのではと思えてきました。


KHE00221  2008-01-20 09:39:02  No: 29371

操作先でテキストの変化が起きないときに

操作元でフックが起きていないと読むのが普通でしょうが・・・・

2.WM_MOUSEMOVE以外は、操作先PCへのマウス操作命令送信のみ

の時にデフォルト処理を行なえばうまくいきそうですが・・・


おも  2008-01-20 09:48:49  No: 29372

>>操作先でテキストの変化が起きないときに

>>操作元でフックが起きていないと読むのが普通でしょうが・・・・

操作元PCでの6.操作元PCから左マウス押上操作命令送信もLabel表示確認しており、操作先PCでの遠隔操作不能時にも、操作元PCでのマウス操作により、操作元PCのLabel表示は変化しており、フックは問題ありません。

>>2.WM_MOUSEMOVE以外は、操作先PCへのマウス操作命令送信のみ

>>の時にデフォルト処理を行なえばうまくいきそうですが・・・

これは、操作元PCでの処理ですが、操作元PCにおいて、デフォルト処理することが、操作先PCでの動作と何か関係しますか?


KHE00221  2008-01-20 18:16:49  No: 29373

受信した命令テキストの表示が変化しませんので、そうだと思います。操作先PCを直接マウスで操作して遠隔操作可能な状態に復帰させると、それまでの遠隔操作不能時に行っていた操作元PCでの動作が一気に起こり、操作先PCで、マウスが色々動いたりします。これは、先ほどの1PCでTEditを使った場合と同じですね。

ならば操作元が送信していないと見るのが普通だと思うんだけど・・・

操作元PCでの6.操作元PCから左マウス押上操作命令送信もLabel表示確認しており、操作先PCでの遠隔操作不能時にも、操作元PCでのマウス操作により、操作元PCのLabel表示は変化しており、フックは問題ありません。

って・・・・

どういう事よ?


KHE00221  2008-01-20 18:20:07  No: 29374

>>あと対象が自作アプリ以外でもおきるのかな?

起きません。それから、自作アプリといっても、マウス操作処理をしているアプリだけです。そのアプリであれば、どのフォームでも同じです。

ということは DELPHIで作成したアプリに全てなるのかな?

DELPHI側が想定していないメッセージ処理をするから問題が発生するわけで

となるとDELPHI側のメッセージ処理に問題があるのか・・・


KHE00221  2008-01-20 18:26:49  No: 29375

受信側を以下のようにして普通に操作できるんだけどね・・・

procedure TForm1.IdTCPServer1Execute(AThread: TIdPeerThread);
var
    Host : String;
    Port : Integer;
    X,Y : Word;
    MSG : Cardinal;
begin
    StatusBar1.Panels[0].Text := DateTimeToStr(Now);

    Host := AThread.Connection.Socket.Binding.PeerIP;
    Port := AThread.Connection.Socket.Binding.Port;

    AThread.Connection.ReadBuffer(MSG,SizeOf(MSG));
    AThread.Connection.ReadBuffer(X,SizeOf(X));
    AThread.Connection.ReadBuffer(Y,SizeOf(Y));
    SetCursorPos(X,Y);
    case MSG of
      WM_LBUTTONDOWN,WM_NCLBUTTONDOWN:MOUSE_EVENT(MOUSEEVENTF_LEFTDOWN ,0,0,0,0);
      WM_RBUTTONDOWN,WM_NCRBUTTONDOWN:MOUSE_EVENT(MOUSEEVENTF_RIGHTDOWN,0,0,0,0);
      WM_LBUTTONUP  ,WM_NCLBUTTONUP  :MOUSE_EVENT(MOUSEEVENTF_LEFTUP   ,0,0,0,0);
      WM_RBUTTONUP  ,WM_NCRBUTTONUP  :MOUSE_EVENT(MOUSEEVENTF_RIGHTUP  ,0,0,0,0);
    end;
    AThread.Connection.Disconnect;
end;


おも  2008-01-20 18:40:55  No: 29376

KHE00221さん、レス有難うございます。

>>って・・・・

>>どういう事よ?

やはりシステムメニューの左マウス押下はマウス操作以外のすべての処理を止めてしまうということです。

>>ということは DELPHIで作成したアプリに全てなるのかな?

>>DELPHI側が想定していないメッセージ処理をするから問題が発生するわけで

>>となるとDELPHI側のメッセージ処理に問題があるのか・・・

DELPHI側のメッセージ処理に問題があるというよりは、WINDOWSの仕様のようです。

今回は、マウスの遠隔操作機能を実現しようとして現象が起こったために、原因を突き止めるのに遠回りしましたが把握しました。

まず、Windows付属のゲームであるマインスイーパを実行してみてください。スタートすれば、自動的にタイムカウントが増えていくと思います。しかし、システムメニュー(例えば、最小化)を左マウス押下のみした状態では、タイムカウントは停止します。そして、システムメニューから離したところで、左マウス押上すると、タイムカウントは押下していた間はカウントされず、押下したところからカウントされています。つまり、システムメニューでの左マウス押下ですべての処理がとまっているのです。

さらに、DelphiでフォームにTLabelとTTimerを置き、時刻表示を行ってみたところ、これも、システムメニューの左マウス押下により表示が停止しました。

よって、マウス操作を処理するアプリケーション自体でシステムメニューに対してマウス操作するということは、そのアプリケーションのいかなる処理も停止してしまうので、他の方法を考えないといけないかと思います。

>>受信側を以下のようにして普通に操作できるんだけどね・・・

これはまだ確認してませんが、とりあえず投稿しておきます。


KHE00221  2008-01-20 18:48:45  No: 29377

試してみたけど止まらないよ?

BDS 2006 + XP だけど


おも  2008-01-20 19:01:37  No: 29378

XPでマインスイーパをやってみましたけど、現象は同じでした。

そちらの環境ではマインスイーパの最小化ボタンを左マウス押下状態でも、タイムカウントは続いているのでしょうか?


KHE00221  2008-01-20 19:30:12  No: 29379

最大化とか移動しても止まりませんよ

マインスイーパー自体最小化するとカウント止まるけど?


おも  2008-01-20 20:14:59  No: 29380

>>最大化とか移動しても止まりませんよ

最大化ボタンは元々無効ですよね?
移動はシステムメニューの押下ではなく、タイトルバーの押下なので問題ないと思います。

>>マインスイーパー自体最小化するとカウント止まるけど?

そのようですね。従って、最小化はしなくても、最小化ボタンの押下のみでカウントがとまるような処理かもしれませんので、これ自体では判断できないようですね。

では、メモ帳で点滅しているカーソルは、最小化ボタンの押下ではどうなりますか?

また、より複雑な私本来のしたいことが実現できているということなのですが、念の為に確認させてください。

Formに
TLabel 2個
TTimer 1個
TButton 1個
をおいて、

〜Unit1始まり〜

unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    Label1: TLabel;
    Label2: TLabel;
    Button1: TButton;
    Timer1: TTimer;
    procedure Button1Click(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
  private
    { Private 宣言 }
    MyThread:TMyThread;
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
    MyThread:=TMyThread.Create(False);
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  Label1.Caption:=FormatDateTime('hh:mm:ss',now);
end;

end.

〜Unit1終わり〜

〜Unit2始まり〜
unit Unit2;

interface

uses
  Classes,SysUtils,Forms;

type
  TMyThread = class(TThread)
  private
    { Private 宣言 }
    procedure UpdateCaption;
  protected
    procedure Execute; override;
  end;

implementation

uses Unit1;

procedure TMyThread.UpdateCaption;
begin
  Form1.Label2.Caption:= FormatDateTime('hh:mm:ss',now);
end;

procedure TMyThread.Execute;
begin
  while True do begin
    Application.ProcessMessages;
    Synchronize(UpdateCaption);
  end;
end;

end.

〜Unit2終わり〜

というアプリケーションをつくり実行してみてください。

起動で、Label1の時刻表示が開始され、Button1クリックで、スレッドによるLabel2の時刻表示が開始されます。私の環境では、最小化ボタンの左マウス押下で、これらの時刻表示は両方とも停止します。そちらの環境では問題なく動作しますでしょうか?あるいは、私のコード自体に致命的な間違いが存在するでしょうか?

お手数をおかけしますがよろしくお願いします。


おも  2008-01-20 20:23:07  No: 29381

Delphi6 Personal+Win2000でコンパイルしたアプリをWin2000、XPの両方の環境で実行しましたが、結果は同じでした。


KHE00221  2008-01-20 20:27:07  No: 29382

↑のプログラムを別PCで起動して、遠隔操作して、
システムメニュー(アイコンクリックするとでてくるやつ)
の最小をMouseDownした状態でもタイマーは両方止まりませんよ?
そしてMouseUpすると最小化します


おも  2008-01-20 20:42:58  No: 29383

>>システムメニュー(アイコンクリックするとでてくるやつ)

これって、タスクバーのアプリケーションアイコンのことですか?

>>の最小をMouseDownした状態

これは、そのアイコンを右クリックして出てくるポップアップメニューの最小化をマウスダウンした状態ですか?

>>でもタイマーは両方止まりませんよ?
>>そしてMouseUpすると最小化します

これは、私も遠隔操作では確認してませんが、同じで動いています。また、元々のアプリも、タスクバーのアイコン右クリップ→ポップアップメニューでの最小化とかは動作しています。

で、もう一つ確認お願いします。
少しネットで調べただけでそう呼ぶのかと思い、そのまま使っていましたが、私の言っているシステムメニューとはウインドウの右上に並ぶ最小化、最大化、閉じるボタンです。

今までの動作はすべてのこの部分のボタンの左マウス押下で確認していただいたのでしょうか?


KHE00221  2008-01-20 21:17:16  No: 29384

アイコンをクリックして出るメニューです。

ウィンドウの最小化ボタンを押すとタイマーは止まりますね。マインスイーパーだろうが、↑のプログラムだろうが

これは仕様ですね

遠隔操作で最小化ボタンとか最大化、元に戻すをクリックした所  正常に動作しましたが


KHE00221  2008-01-20 21:19:49  No: 29385

>ウィンドウの最小化ボタンを押すとタイマーは止まりますね。マインスイーパーだろうが、↑のプログラムだろうが

これは直接操作でなるので遠隔操作でも同じでしょう


おも  2008-01-20 21:33:04  No: 29386

KHE00221さん、どうも有難うございました。

そして、こちらの説明が不十分であったために、要らぬお手数をおかけしましたことをお詫びします。

円満な形ではありませんが、一応、解決ということかなと思いますが、他の有用な情報を頂ける可能性もありますので、解決チェックせずに、もうしばらく待ってみます。

どうも有難うございました。


KHE00221  2008-01-20 22:10:35  No: 29387

>アイコンをクリックして出るメニューです。

タスクバーのアイコンじゃないよ?


おも  2008-01-20 22:43:14  No: 29388

あっ、もう一つ誤解していたようですね。

>>>アイコンをクリックして出るメニューです。

>>タスクバーのアイコンじゃないよ?

ウインドウの左上のアイコンですね。
こちらのメニューでの最小化の左マウス押下では、時刻表示等は問題なく動作していますね。

やはり、ウインドウ右上の三つのボタンだけは違うようですね。


KHE00221  2008-01-21 00:03:34  No: 29389

とりあえず作ってみたから・・・(ソース付き)

http://khe00221.image.coocan.jp/index.php?FrontPage%2FOpenSource%2FRemoteControl

マウス操作とキーボード操作を遠隔操作可能で
操作中はマウス・キーの使用不可で

サーバー接続解除もしくは CTRL+ALT+DELでHOOK解除


おも  2008-01-21 01:01:59  No: 29390

KHE00221さん、どうも有難うございます。

作っていただいたものだと、最小化、最大化、閉じるボタンの左マウス押下で時計とかは一時停止するようですが、遠隔操作自体は不能にはなりませんね!!!

すばらしいです。

ただ、その後、最小化ボタンから離れたところで押上すると、私の環境では、画面のOFFのような形になるようです?

残念ながら、Delphiのバージョンが違うので、そのまま手を加えて色々試すことはできませんが、ソースをつけていただいているので、詳細はこれから見てみようと思っています。

それから、少し使ってみた感じでの改善点を2つお伝えしておきます。

1.本家どこドアでも書いてあるのですが、キーボードは信頼性を重視してTCP通信、マウスはUDP通信で高速性重視となっています。実際、UDPだとスムーズになります。このため、ポートは二つですね。私は指定ポートと、影でその1つ隣と言う感じで使ってました。高速性に絡めてですが、個別動作直後のSleep(50)は必要ですか?少なくともマウス操作では動作がぎこちなくなっていると思います。

2.操作元PCと操作先PCの画面サイズが違った場合への対応

それから、私は、WM_MOUSEWHEELの処理のみSendInputを使ったのですが、すべて置き換えられていますね。


おも  2008-01-21 01:05:19  No: 29391

>>個別動作直後のSleep(50)は必要ですか?少なくともマウス操作では動作がぎこちなくなっていると思います。

失礼しました。WM_MOUSEMOVE自体にはSleep(50)はないですね。


KHE00221  2008-01-21 02:59:51  No: 29392

SendInput で MouseDown をすると 省エネモードに突入して画面OFFに
なるみたいです・・・・
省エネモードOFFにしておけば問題ないですが・・・・

MOUSE_EVENT で行なえば問題ありません。

Sleep(50) は入れないと 動作がおかしくなります
エキスプローラで ダブルクリックするとプロパティが表示されるようになります


KHE00221  2008-01-21 03:06:11  No: 29393

あくまでプログラム内のみでの動作です

単発でやれば問題ないです


KHE00221  2008-01-21 03:11:56  No: 29394

SendInput する前に  

AThread.Connection.Disconnect;

しないといけないみたいです。


おも  2008-01-21 03:45:53  No: 29395

>>Sleep(50) は入れないと 動作がおかしくなります
>>エキスプローラで ダブルクリックするとプロパティが表示されるようになります

了解です。

ところで、こちらでも、最小化ボタン左マウス押下でも、引き続き遠隔操作可能にできました。

KHE00221さんのソースを検討したところ、これといった決め手を見つけることもできませんでしたが、ただ、最小化ボタン左マウス押下中も、

procedure TForm1.IdTCPServer1Execute(AThread: TIdPeerThread);

の部分が有効で処理ができているのだということは分かりました。私の環境ではTIdPeerThreadについては良くわからないのですが、スレッドなのだろうということで、こちらのスレッドを見直してみました。

考えた結果、最小化ボタンを押して処理が止まっているフォーム内での処理をスレッドで利用したりしていると、いくらスレッドを使ったとしても、その先へ進めないのではと思い至りました。

で、そういう改善を加えた結果、最小化ボタン左マウス押下でも、引き続き遠隔操作可能にできました。

この考え方で、前掲の時刻表示アプリケーションでも、最小化ボタンの左マウス押下した場合に、Label1の時刻表示は停止しますが、Label2の時刻表示は変化し続けるようになりました。

コードにすると簡単なことで、Unit2で

procedure TMyThread.UpdateCaption;
begin
  Form1.Label2.Caption:= FormatDateTime('hh:mm:ss',now);

  //ここを加える
  Form1.Update;
end;

procedure TMyThread.Execute;
begin
  while True do begin
    Application.ProcessMessages;

    //Synchronizeをやめる
    //Synchronize(UpdateCaption);
    UpdateCaption;
  end;
end;

とします。Synchronizeをやめる弊害には注意しないといけないと思いますが、これによって、思い通りの機能を実現することができました。

ご親切にお付き合いくださって本当に有難うございました。


KHE00221  2008-01-21 07:39:09  No: 29396

MouseMoveのみをUDPにすると MouseDown してから MouseMove の間にウェイトが掛かる

MouseDown,MouseUp も UDP にすると 右上ボタンをクリックにすると止まる(これかな?)

なので TCP/IP のみ使用じゃないと駄目ぽいですな。 

Indy を使用しなければいけそうな気もしますが


KHE00221  2008-01-22 03:35:28  No: 29397

>MouseMoveのみをUDPにすると MouseDown してから MouseMove の間にウェイトが掛かる

これは受信側プログラムだから起きていたみたいです


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

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






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