C#,Visual Studio 2010 (.NET Framework 4.0) で作りたいのですが、「自作アプリからAPIで他のアプリとデータをやり取りする方法」というキーワードで検索しましたが、良くわかりませんでした。
やりたい事は、
namespace NowplayingAPL
{
public partial class MainWindow : Form
{
で定義されたウィンドウのMainWindow.TextBox.Text からデータを受け取り、編集後 MainWindow.TextBox.Text にデータを挿入したいです。 編集処理は作成済みです。
Declare Function FindWindow Lib "user32.dll" Alias "FindWindowA" _
(ByVal lpClassName As String, ByVal lpWindowName As String) As Integer
( http://d.hatena.ne.jp/maeyan/20091227/1261848549 )
…が参考になりそうなのですが、C#での定義方法から分かりません。
C# , ・・・ の環境で実現できるでしょうか?できるのなら、他に必要な情報はありますか?
データを受け取る事が難しければ、データを挿入するだけでも構いません。
ソースを結合すれば、なんなくやりたい事は実現できるのですが、訳あって、面倒な方法を取っています。
教えて頂けば、幸いです。
A 回答 (2件)
- 最新から表示
- 回答順に表示
No.2
- 回答日時:
> C# での宣言方法を教えて頂けませんか?
http://msdn.microsoft.com/ja-jp/library/vstudio/ …
http://www.atmarkit.co.jp/fdotnet/dotnettips/024 …
この回答への補足
回答ありがとうございます。今、電卓を起動して、ボタンを押す処理を作っています。
http://stackoverflow.com/questions/5241984/findw …
そのままですが…、まずは、最小限ソースを弄って、動く状態にする所から始めています。
using System.Runtime.InteropServices; を追加しました。
テスト用のボタンをクリックしたときに、処理します、
private void ButtonTest_Click(object sender, EventArgs e)
{
IntPtr hwnd = IntPtr.Zero;
IntPtr hwndChild = IntPtr.Zero;
//Get a handle for the Calculator Application main window
hwnd = FindWindow(null, "Calculator");
if (hwnd == IntPtr.Zero)
{
if (MessageBox.Show("Couldn't find the calculator" +
" application. Do you want to start it?",
"TestWinAPI",
MessageBoxButtons.YesNo) == DialogResult.Yes)
{
System.Diagnostics.Process.Start("Calc");
//BringWindowToTop("Calculator", true);
//SetForegroundWindow((IntPtr)hwnd);
}
}
else
{ //elseの条件を通る事がありません。FindWindowもおかしいのかもしれません(汗)
//Get a handle for the "1" button
hwndChild = FindWindowEx(hwnd, IntPtr.Zero, "Button", "1");
//send BN_CLICKED message
SendMessage(hwndChild, BN_CLICKED, 0, IntPtr.Zero); //BN_CLICKEDの所でビルドエラーになります。
//Get a handle for the "+" button
hwndChild = FindWindowEx(hwnd, IntPtr.Zero, "Button", "+");
//send BN_CLICKED message
SendMessage(hwndChild, BN_CLICKED, 0, IntPtr.Zero);
//Get a handle for the "2" button
hwndChild = FindWindowEx(hwnd, IntPtr.Zero, "Button", "2");
//send BN_CLICKED message
SendMessage(hwndChild, BN_CLICKED, 0, IntPtr.Zero);
//Get a handle for the "=" button
hwndChild = FindWindowEx(hwnd, IntPtr.Zero, "Button", "=");
//send BN_CLICKED message
SendMessage(hwndChild, BN_CLICKED, 0, IntPtr.Zero);
//BringWindowToTop("Calculator", true);
}
}
// Find window by Caption, and wait 1/2 a second and then try again.
public static IntPtr FindWindow(string windowName, bool wait)
{
IntPtr hWnd = FindWindow(null, windowName);
while (wait && hWnd == IntPtr.Zero)
{
System.Threading.Thread.Sleep(500);
hWnd = FindWindow(null, windowName);
}
return hWnd;
}
// THE FOLLOWING METHOD REFERENCES THE SetForegroundWindow API
public static void BringWindowToTop(string windowName, bool wait)
{
IntPtr hWnd = FindWindow(windowName, wait);
if (hWnd != IntPtr.Zero)
{
SetForegroundWindow((IntPtr)hWnd);
}
}
//// For Windows Mobile, replace user32.dll with coredll.dll
[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
// Find window by Caption only. Note you must pass IntPtr.Zero as the first parameter.
[DllImport("user32.dll", EntryPoint = "FindWindow", SetLastError = true)]
public static extern IntPtr FindWindowByCaption(IntPtr ZeroOnly, string lpWindowName);
[DllImport("User32.dll")]
public static extern int SetForegroundWindow(IntPtr hWnd);
//[DllImport("user32.dll", SetLastError = true)]
//static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string className, string windowTitle);
[DllImport("user32.dll")]
private static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
//private static extern IntPtr SendMessage (IntPtr hWnd, uint Msg, IntPtr wParam, ref COPYDATASTRUCT lParam);
}
}
「エラー 1 名前 'BN_CLICKED' は現在のコンテキスト内に存在しません。」と出るので、
public const System.UInt32 BN_CLICKED = 245;
としてみましたが、他の所がエラーになります。
引数おIntPtrとintとが型が違っていて、無理やりキャストとかしてました(意味がないですね)
残骸が残っていたらすみません。途中経過報告のつもりです。
最終的には、目的のアプリケーションを起動し、クラス名、ウィンドウ名、オブジェクト名を指定して、データを挿入したいです。
↓これを参考にするつもりです。
http://www.pinvoke.net/default.aspx/user32.findw …
SPY++ というツールを使って、目的の機能は実現しました。
お二方、アドバイスを頂き有難う御座いました。
親クラスから、一個一個たどって行かなければならないのですね。
ただ、このクラス名を指定するやり方は、私以外の環境でも動くのでしょうか?
(動かないとすると、このコーディングの意味がありませんが・・・)
public const uint WM_GETTEXT = 0x000D;
public const uint WM_SETTEXT = 0x000C;
private string GetOrSetText(String myMode)
{
IntPtr hwnd = IntPtr.Zero;
IntPtr hwndChild = IntPtr.Zero;
//Get a handle for the Calculator Application main window
hwnd = FindWindow(null, "メインアプリ");
//hwnd = FindWindow("CalcFrame", "電卓");
if (hwnd == IntPtr.Zero)
{
//MessageBox.Show("アプリが起動されていません。",
// "警告",
// MessageBoxButtons.OK);
string myPath = GetAppPath() + "\\" + "メインアプリ.exe";
if (System.IO.File.Exists(myPath))
{
System.Diagnostics.Process.Start(myPath);
//メッセージキューに現在あるWindowsメッセージをすべて処理する
//System.Windows.Forms.Application.DoEvents();
System.Threading.Thread.Sleep(1500);
//Get a handle for the Calculator Application main window
hwnd = FindWindow(null, "メインアプリ");
}
else
{
MessageBox.Show("「メインアプリ」を起動して下さい。",
"警告",
MessageBoxButtons.OK);
return "";
}
}
// http://oshiete.goo.ne.jp/qa/7220109.html
//メインウィンドウのハンドル取得
hwnd = FindWindowEx(hwnd, IntPtr.Zero, "WindowsForms10.SysTabControl32.app.0.******_r**_ad1", null);
//タブウィンドウのハンドル取得
hwnd = FindWindowEx(hwnd, IntPtr.Zero, null, "設定");
//フレームのハンドル取得
hwnd = FindWindowEx(hwnd, IntPtr.Zero, null, "詳細設定");
//テキストボックスのハンドル取得
hwndChild = FindWindowEx(hwnd, IntPtr.Zero, "WindowsForms10.EDIT.app.0.*******_r**_ad1", null);
if (hwndChild == IntPtr.Zero)
{
//MessageBox.Show("対象オブジェクトが見つかりませんでした。",
// "警告",
// MessageBoxButtons.OK);
return "";
}
if (myMode.Equals("GET"))
{
StringBuilder sb1 = new StringBuilder(1024);
SendMessage(hwndChild, WM_GETTEXT, (IntPtr)sb1.Capacity, sb1);
this.EditBOX.Text = sb1.ToString();
return this.EditBOX.Text;
}
else if(myMode.Equals("SET"))
{
//hwnd = FindWindow(null, "メインアプリ");
//WakeupWindow(hwnd);
StringBuilder sb2 = new StringBuilder(this.EditBOX.Text);
SendMessage(hwndChild, WM_SETTEXT, IntPtr.Zero, sb2);
return this.EditBOX.Text;
}else{
MessageBox.Show("プログラミングエラーです。引数にGETかSETを指定して下さい。",
"警告",
MessageBoxButtons.OK);
return "";
}
}
[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr ptr, StringBuilder lParam);
____________________________________________________________________________________
以上となりました。何かお気づきの点がありましたら、お教え下さい。11月中に締め切る予定です。
No.1
- 回答日時:
その相手のアプリケーションがどんなインターフェースを持っているのかがわからなければ、答えようが無いと思うのですが。
例えば、その処理の本体が.NETのDLLになっていて、参照追加して 「 相手アプリAPI.処理(MainWindow.TextBox.Text) ; 」で済むケースもあるし
相手のコントロールに直接Sendkeyとかで送信して、結果をコピペするようなことをしなければならないかもしれません。
この回答への補足
早速の回答ありがとうございます。
すみません、はしょり過ぎて、本体はDLLではありません。私が作った方もDLLではありません。両方EXEです。上手く言えずに申し訳ありませんm(_ _)m
ただ、テキストボックス同士でデータをやり取りしたいだけです(汗)
ちょっと自分で試行錯誤してみるので、
Declare Function FindWindow Lib "user32.dll" Alias "FindWindowA" _
(ByVal lpClassName As String, ByVal lpWindowName As String) As Integer
Declare Function FindWindowEx Lib "user32.dll" Alias "FindWindowExA" _
(ByVal hwndParent As Integer, ByVal hwndChildAfter As Integer, _
ByVal lpszClass As String, ByVal lpszWindow As String) As Integer
Declare Function SendMessage Lib "user32.dll" Alias "SendMessageA" _
(ByVal hWnd As Integer, ByVal MSG As Integer, _
ByVal wParam As Integer, ByVal lParam As Integer) As Integer
の C# での宣言方法を教えて頂けませんか?
(参考URLでも結構です)
お礼の欄に申し訳ありません。クラス名の指定が上手くいきません。その他も・・・
前回の参考にしたWebページでは、FindWindowがオーバーライドされている様だったので、
標準に戻した。
しかし、
hwnd = FindWindow(null, "電卓"); は、通るのに
hwnd = FindWindow("Calc", "電卓"); が通らない
ここでいうクラス名とはどうやって調べればいいのか?
BN_CLICKED とは定数なので、自分で決まった値に定義していいのか? // http://wisdom.sakura.ne.jp/system/winapi/windata …
または、BN_CLICKEDの前に何か、つけるのか?
外部アプリは、タスクトレイに常駐し、アイコンをダブルクリックするか or 右クリック→設定で
MainWindowが表示される。
この場合、オブジェクト名は、MainWindow.TextBox.Text なので、クラス名はMainWindow.TextBoxに
なるのではないか?
【ソースコード】
private void notifyIcon1_MouseDoubleClick(object sender, MouseEventArgs e)
{
this.Show();
this.WindowState = FormWindowState.Normal;
this.Activate();
}
や
private void 設定ToolStripMenuItem_Click(object sender, EventArgs e)
{
this.Show();
this.WindowState = FormWindowState.Normal;
this.Activate();
}
で、MainWindowが呼び出されている。その中にテキストボックスがある。
(なお、設定画面などはタブで切り替えられるようになっている。)
SetForegroundWindow( hwnd ); は、外部MainWindowが背後に既に開かれている場合、ちゃんと手前にくるが、
私がやりたいのはhide(最小化?)されているウィンドウをshowしたい
かといって、BringWindowToTop(hWnd)が使えそうだが、定義の方法が分からない。
private const int WM_LBUTTONDBLCLK = 0x0203;
hwndChild = FindWindowEx(hwnd, IntPtr.Zero, "notifyIcon1", null);
SendMessage(hwndChild, WM_LBUTTONDBLCLK, 0, IntPtr.Zero); // http://chokuto.ifdef.jp/urawaza/hsgetmsg1.html
としてもみたが、ビルドエラー。アイコンをダブルクリックを実行したかった。
また、hwndChildが常に0なので、
private const int WM_GETTEXT = 0x000D;
StringBuilder strBuilder = new StringBuilder();
SendMessage(hwndChild, WM_GETTEXT, strBuilder.Capacity, strBuilder);
まで辿り着けない。
【定義部】
[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, int wParam, StringBuilder lParam);
質問だらけで、すみません。
【まとめサイト】
http://www.shise.net/wiki/wiki.cgi?page=C%23%2F% …
【その他】
http://uchukamen.com/Programming1/WindowFunctions/
http://oshiete.goo.ne.jp/qa/7220109.html
できれば、ご教授お願いします。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- その他(Microsoft Office) マクロVBAについて 1 2022/09/06 18:12
- Visual Basic(VBA) VBAのユーザーフォームのテキストボックスに入力制限をしたい 6 2022/11/15 08:28
- Visual Basic(VBA) batからexeを実行し戻り値を受け取る バッチからEXEの結果を受け取りたいのですが、 下記のバッ 1 2023/07/04 15:13
- Visual Basic(VBA) 別シートのデータを参照して値を入れたい。 まとめデータシートのC列D列の値を商品一覧シートのコードが 7 2022/08/17 13:20
- Ruby pandasでsqlite3にテーブル作成・追加・読み出しでindexの取り扱い方教えてください 5 2023/03/08 09:57
- Visual Basic(VBA) 【前回の続きです、ご教示ください】VBAの記述方法がわかりません。 2 2022/08/16 16:44
- Visual Basic(VBA) 【前回の続き続きです、ご教示ください】VBAの記述方法がわかりません。 2 2022/08/24 20:49
- Visual Basic(VBA) 【VBA】Excelで罫線を引きたい 3 2022/07/14 12:04
- Visual Basic(VBA) batからexeを実行し戻り値を受け取る EXEの実行内容の結果によって、戻り値を0か1かで返したい 1 2023/07/04 16:40
- Excel(エクセル) マクロでテキストファイルを読み込んだ際の最終セルにデータと改行が含まれる問題の改善方法 2 2022/03/25 16:50
このQ&Aを見た人はこんなQ&Aも見ています
-
とっておきの「夜食」教えて下さい
真夜中に小腹がすいたときにこっそり作るメニュー、こっそり家を抜け出して食べに行くお店… 人には言えない、けど自慢したい、そんなあなたの「とっておきの夜食」を教えて下さい。
-
秘密基地、どこに作った?
小さい頃、1度は誰もが作ったであろう秘密基地。 大人の今だからこそ言える、あなたの秘密基地の場所を教えてください!
-
これ何て呼びますか Part2
あなたのお住いの地域で、これ、何て呼びますか?
-
おすすめのモーニング・朝食メニューを教えて!
コメダ珈琲店のモーニング ロイヤルホストのモーニング 牛丼チェーン店の朝食などなど、おいしいモーニング・朝食メニューがたくさんありますよね。
-
とっておきの「まかない飯」を教えて下さい!
飲食店で働く方だけが食べられる、とっておきの「まかない飯」。 働いてらっしゃる方がSNSなどにアップしているのを見ると、表のメニューには出てこない秘密感もあって、「食べたい!!」と毎回思ってしまいます。
-
他のアプリケーションをクリックしたときのイベントを得る方法
Visual Basic(VBA)
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・【大喜利】【投稿~11/22】このサンタクロースは偽物だと気付いた理由とは?
- ・お風呂の温度、何℃にしてますか?
- ・とっておきの「まかない飯」を教えて下さい!
- ・2024年のうちにやっておきたいこと、ここで宣言しませんか?
- ・いけず言葉しりとり
- ・土曜の昼、学校帰りの昼メシの思い出
- ・忘れられない激○○料理
- ・あなたにとってのゴールデンタイムはいつですか?
- ・とっておきの「夜食」教えて下さい
- ・これまでで一番「情けなかったとき」はいつですか?
- ・プリン+醤油=ウニみたいな組み合わせメニューを教えて!
- ・タイムマシーンがあったら、過去と未来どちらに行く?
- ・遅刻の「言い訳」選手権
- ・好きな和訳タイトルを教えてください
- ・うちのカレーにはこれが入ってる!って食材ありますか?
- ・おすすめのモーニング・朝食メニューを教えて!
- ・「覚え間違い」を教えてください!
- ・とっておきの手土産を教えて
- ・「平成」を感じるもの
- ・秘密基地、どこに作った?
- ・【お題】NEW演歌
- ・カンパ〜イ!←最初の1杯目、なに頼む?
- ・一回も披露したことのない豆知識
- ・これ何て呼びますか
- ・初めて自分の家と他人の家が違う、と意識した時
- ・「これはヤバかったな」という遅刻エピソード
- ・これ何て呼びますか Part2
- ・許せない心理テスト
- ・この人頭いいなと思ったエピソード
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・好きなおでんの具材ドラフト会議しましょう
- ・餃子を食べるとき、何をつけますか?
- ・あなたの「必」の書き順を教えてください
- ・ギリギリ行けるお一人様のライン
- ・10代と話して驚いたこと
- ・大人になっても苦手な食べ物、ありますか?
- ・14歳の自分に衝撃の事実を告げてください
- ・家・車以外で、人生で一番奮発した買い物
- ・人生最悪の忘れ物
- ・あなたの習慣について教えてください!!
- ・都道府県穴埋めゲーム
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
pandasでsqlite3にテーブル作成...
-
csvデータ不要列の削除をbatフ...
-
エクセルで去年のデータを今年...
-
エクセル 2つの列にある値の完...
-
EXCELで外部データの取り込みが...
-
JDBCを使ってdate型へのINSERT...
-
追加クエリで重複データなしで...
-
ACCESS VBAでSeekメソッドの処...
-
フラグをたてるってどういうこ...
-
UPDATEで既存のレコードに文字...
-
SELECT INTOで一度に複数の変数...
-
【SQL】他テーブルに含まれる値...
-
既存データをINSERT文にして出...
-
PostgreSQLのtimestamp型で時間...
-
オラクルのUPDATEで複数テーブル
-
右向き、左向きの速度が最大と...
-
SQLサーバに対するSQL文で抽出...
-
MySQLで数字の値のもののみを取...
-
結合したテーブルをSUMしたい
-
ADO+ODBCでテーブルに接続する...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
csvデータ不要列の削除をbatフ...
-
Excel VBAのユーザーフォームで...
-
【VB】セルが空になるまで処理...
-
追加クエリで重複データなしで...
-
pandasでsqlite3にテーブル作成...
-
JDBCを使ってdate型へのINSERT...
-
ListBoxにAddItemする際、重複...
-
マクロでファイルを読み込み、...
-
VBAでの行数を揃える方法
-
自作アプリからAPIで他のアプリ...
-
VBAで、新しい値のみを抜き出す...
-
エクセル 2つの列にある値の完...
-
MySQLでauto_incrementをつかわ...
-
【ExcelVBA】範囲選択の方法に...
-
Accessでパラメーター以外の削...
-
Excelのマクロでの部分的な重複...
-
EXCELで外部データの取り込みが...
-
ACCESS VBAでSeekメソッドの処...
-
エクセルで去年のデータを今年...
-
vacummdbについて
おすすめ情報