C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

他アプリをforをつかってクリックできません

[トピック内 5 記事 (1 - 5 表示)]  << 0 >>

■84831 / inTopicNo.1)  他アプリをforをつかってクリックできません
  
□投稿者/ たまちゃん2世 (1回)-(2017/08/06(Sun) 17:06:00)

分類:[C#] 

プログラム初心者です。
いろいろ調べて、以下のコードをつかって、プログラムを使って、ペイントで描画できるようになりました。
ですが、String lParamの取り扱い方法がわからず、forをつかって、効率的に操作できません。
Stringで、0xとx座標とy座標を結合した変数ではエラーになってしまいます。
解決方法を教えてください。


以下が、今までのコードです。
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, String lParam);


SendMessage(hwnd, WM_LBUTTONDOWN, MK_LBUTTON, 0x00090009);


0x00090009の代わりに、以下のx_y_positionを使おうとしてもエラーになってしまします。
String x_position = int_x.ToString();
String y_position = int_y.ToString();
String x_y_position = "0x" + x_position + y_position;

引用返信 編集キー/
■84832 / inTopicNo.2)  Re[1]: 他アプリをforをつかってクリックできません
□投稿者/ Azulean (846回)-(2017/08/06(Sun) 18:17:06)
No84831 (たまちゃん2世 さん) に返信
> 0x00090009の代わりに、以下のx_y_positionを使おうとしてもエラーになってしまします。
> String x_position = int_x.ToString();
> String y_position = int_y.ToString();
> String x_y_position = "0x" + x_position + y_position;

16 進数についてきちんと学ばれた方が良いです。
この String だと、y_psition にあるべき間の 0 がないので、別の数字になっています。
さらに言えば、上位(左側)が Y 座標なので、上下(左右)逆ですね。

また、DllImport の lParam を String にしてしまうと、.NET Framework から API を呼び出すときに、「文字列の先頭アドレス」を渡すように変わってしまうので、やりたいことが実現できていません。
元の型に戻した上で、シフト演算か、乗算で y の位置を調整してください。
端的には、lParam = int_y << 16 | int_x; という感じですかね。

// SendInput の方がよいかもしれませんが。
引用返信 編集キー/
■84833 / inTopicNo.3)  Re[2]: 他アプリをforをつかってクリックできません
□投稿者/ たまちゃん2世 (2回)-(2017/08/06(Sun) 21:44:20)
早速の回答ありがとうございます。

それなりに、16進数のことは勉強したつもりですが、
ネットで再度勉強します。

X,Yが逆だとは思っていませんでした。
早速修正しようと思います。

SendMessageで文字列を送るために、Stringにしていました。
文字列を記入した後に、lParamの型を変更できないのでしょうか。


引用返信 編集キー/
■84850 / inTopicNo.4)  Re[3]: 他アプリをforをつかってクリックできません
□投稿者/ 魔界の仮面弁士 (1380回)-(2017/08/09(Wed) 14:09:33)
No84833 (たまちゃん2世 さん) に返信
> SendMessageで文字列を送るために、Stringにしていました。
> 文字列を記入した後に、lParamの型を変更できないのでしょうか。

WM_LBUTTONDOWN は String 値を扱わないので、String にする必要はない筈です。

文字列を受け取るメッセージのためにも SendMessage を使っている場合には、
DllImport した API 宣言をオーバーロードしてやりましょう。すなわち、
String を渡すための SendMessage 宣言(現状のコード)とは別に
IntPtr を渡すための SendMessage 宣言の両方を用意しておくということです。


>>> 0x00090009の代わりに、以下のx_y_positionを使おうとしてもエラーになってしまします。
>>> String x_position = int_x.ToString();
>>> String y_position = int_y.ToString();
>>> String x_y_position = "0x" + x_position + y_position;

int_x = int_y = 9 だった場合、上記のコードだと
0x99(=153)という文字列になってしまいます。
0x00090009 (=589833) とは別の値になってしまうかと。

そもそも今回のケースでは文字列化しても意味が無いのですが、
.ToString() では 10進数表現になるので、16進数にしたいのなら
.ToString("X4") などにするべきだったかと思います。


>> さらに言えば、上位(左側)が Y 座標なので、上下(左右)逆ですね。
> X,Yが逆だとは思っていませんでした。

0x12345678 なら、X = 0x5678 / Y = 0x1234 ですね。

ちなみに .NET Framework 上では、
 static IntPtr MAKELPARAM(int low, int high) {
  return (IntPtr) ((high << 16) | (low & 0xffff));
 }
というメソッドを用意しておき、
 IntPtr lParam = MAKELPARAM(x, y);
のように利用しているようです。


https://msdn.microsoft.com/ja-jp/library/windows/desktop/gg153548.aspx

》 これらのメッセージでは常に、lParam パラメーターに
》 マウス ポインターの x 座標と y 座標が格納されています。
》 lParam の最下位の 16 ビットには x 座標が、
》 次の 16 ビットには y 座標が格納されています。

》 64 ビットの Windows では、lParam は 64 ビット値になります。
》 lParam の上位 32 ビットは使用しません。MSDN のドキュメントでは、
》 lParam の "上位ワード" と "下位ワード" という言葉が使用されます。
》 64 ビット環境の場合、これは下位 32 ビットのうちの
》 下位ワードと上位ワードを意味します。

引用返信 編集キー/
■84875 / inTopicNo.5)  Re[4]: 他アプリをforをつかってクリックできません
□投稿者/ たまちゃん2世 (1回)-(2017/08/13(Sun) 18:48:52)
Azulean様、魔界の仮面弁士様、ありがとうございました。
理解できないこともありますが、当初の目的を達成でき、
forをつかって描画できました。
SendMessageでforをつかって描画すると、意外と遅いこともわかりました。
解決済み
引用返信 編集キー/

このトピックをツリーで一括表示


トピック内ページ移動 / << 0 >>

このトピックに書きこむ