SendMessageの設定の仕方

解決


大和撫こ  2007-08-21 20:57:15  No: 66049

VC2005のMFCから
SendMessage(hwnd, WM_SETTEXT, 0, "処理終了です!" );
でAPIを使おうとしているのですが、
なぜか4個の引数は使えないのエラーが出ます。
SendMessageは4個の引数のはずなんですが?
何がおかしいのでしょうか?
MFCからSendMessageのAPIを使うには
インクルードや何かしらのインポートをしないと
いけないのでしょうか?
どなたか方法を教えてください。


Blue  2007-08-21 21:20:59  No: 66050

どのクラスの中で使っていますか?
CWndの派生クラスで使うと、CWnd::SendMessageが呼ばれてしまいます。
明に(メンバ関数ではなく)グローバルのSendMessageを使いたい場合は
頭に :: を付けるとうまくいくでしょう。


大和撫こ  2007-08-21 22:40:23  No: 66051

ご回答ありがとうございます!
教えてももらったように修正した。
ですが、また問題が起こりました。

スパイでクラス名を調べたところ
WindowsForms10.EDIT.app.0.14fd2b5とクラス名が分かりました。
FindWindowExでクラス名のところに
WindowsForms10.EDIT.app.0.14fd2b5としたところ
ハンドルがエラーになるので削っていくと
EDITでハンドルが取得できました。
取得できたのえSendMessageで送ったのですが。
まったく動作しません。
やはりハンドル取得のやり方が行けないのでしょうか?
コードを乗せましたので、間違いを指摘してもらえれば・・・・
と思います。
宜しくお願いします。
HWND hWnd;

hWnd = ::FindWindowEx(NULL, NULL, "EDIT", NULL);

::SendMessage(hWnd, WM_SETTEXT, 0, (LPARAM)"処理終了です!" );


大和撫こ  2007-08-21 22:41:30  No: 66052

ちなみに送信先はVBの自作アプリです。


Blue  2007-08-21 22:43:40  No: 66053

>EDITでハンドルが取得できました。
本当にこれで間違いないですか?
Spy++でのウィンドウハンドルとFindExのウィンドウハンドルが一致していますか?

というか、別アプリのテキストボックスに値を入れたいってことでしょうか?
(だったらFindWindowExで親ウィンドウを指定しなくてもいいのかなぁと。)


Blue  2007-08-21 22:50:23  No: 66054

Spy++を使えるのであればコントロールIDを調べれるのでは?

http://madia.world.coocan.jp/cgi-bin/vbnet/wwwlng.cgi?print+200708/07080013.txt
アルウィンドウの子ウィンドウという関係であれば
SendDlgItemMessageを使ってみるとよいでしょう。


大和撫こ  2007-08-22 00:19:21  No: 66055

spyでのハンドルが000108B4
に対し
findwindowexで取得できるハンドルが
67785みたいな感じでBとか文字列が入ってないのもおかしいなぁと
思っていました。

::SendDlgItemMessage(hDlg,textbox1, WM_SETTEXT, 0,(LPARAM)"処理終了です!");
をやってみたんですが、
エラーがでます。
VBのVCにあたるIDってnameだと思うんですが、それを指定すると変な感じになります。完全に違うと思いますが?
どうしたらいいのでしょうか?


Blue  2007-08-22 00:26:40  No: 66056

ですから、Spy++のウィンドウ検索を使ってコントロールIDの値を使ってください。
(ウィンドウ プロパティのダイアログにコントロールIDを示す値が載っています)


大和撫こ  2007-08-22 00:35:33  No: 66057

Blueさんのいうとおり
ウィンドウプロパティのコントロールIDを以下のように
していしましたがエラーがでます。どうしたらいいのですか?
::SendDlgItemMessage(hDlg,0006086C, WM_SETTEXT, 0,(LPARAM)"処理終了です!");


Blue  2007-08-22 00:39:16  No: 66058

>0006086C
16進の値ですので10進になおすか頭に0xを付けてください。
(C言語基礎レベル)

::SendDlgItemMessage(hDlg,0x0006086C, WM_SETTEXT, 0,(LPARAM)"処理終了です!");

それと、
>エラーがでます
はなるべく載せてください。


大和撫こ  2007-08-22 00:53:44  No: 66059

すみません。
HWND hDlg;
::SendDlgItemMessage(hDlg,0x0006086C, WM_SETTEXT, 0,(LPARAM)"処理終了です!");
とやると
Run-Time Check Failure #3 - The variable 'hDlg' is being used without being defined.
というエラーがでます。
結局ハンドルを取得しないといけないのでしょうか?


Blue  2007-08-22 00:56:52  No: 66060

>結局ハンドルを取得しないといけないのでしょうか?
えぇ?なぜ今頃。。。

ハンドルを取得しないとどのウィンドウなのかわかんないですよね?
(コントロールIDは一意ではない。)
VBのアプリのウィンドウハンドルはFindWindowとかで取得してください。


大和撫こ  2007-08-22 01:04:46  No: 66061

取得できれば
SendMessageでよかったのではないのでしょうか?
SendDlgItemMessageだったら取得できなくてもいいから
紹介してくれたのかと思っていました。
結局取得するのだったら
SendMessageの方が短くていいとおもうのですが?
SendDlgItemMessageの利点はなんなんでしょう。
それにコントロールIDってspy++で見たところ毎回変わっているようなんですが。

とりあえず、
WindowsForms10.EDIT.app.0.14fd2b5という不可解なクラス名を指定しても
ハンドルが取得できないのが問題だと思うんですが?

ここを教えて頂けないでしょうか?


Blue  2007-08-22 01:29:11  No: 66062

整理します。

VBのForm→親ウィンドウ・・・(1)
VBのFormの中のTextBox→Formの子ウィンドウ・・・(2)

という関係であるため、(2)のウィンドウハンドルを取得するためには
どうしても(2)のウィンドウハンドルを取得する必要があります。

(1)のウィンドウハンドルはFindWindow(またはFindWindowEx)等で取得します。
このとき必要な情報は「ウィンドウタイトル名」および「クラス名」
です。
ウィンドウのタイトルバーに出る文字が一意であれば、ふつうはこれを指定して取得します。

HWND hWnd;
hWnd = ::FindWindow(NULL, _T("VBのウィンドウタイトル名"));

で、次に子ウィンドウの取得方法ですが、
・EnumChildWindows
・FindWindowEx
・GetDlgItem
等方法があります。
EnumChildWindowsはCALLBACK関数が必要になるので初心者向けではないので
省略します。
下の2は親ウィンドウのウィンドウハンドルから取得します。

FindWindowExの場合、TextBoxの場合クラス名で取得することになります。
ここで同じクラス名のコントロールがいくつもあるとき、FindWindowExは
工夫しなければ使いづらいです。

そこでコントロールIDと呼ばれる一意で普遍な値があるので、
それを使って取得するというのがGetDlgItemです。
# ということで
# >それにコントロールIDってspy++で見たところ毎回変わっているようなんですが。
# は本当なのかなぁと。

よって、コードで書くと

HWND hEdit = ::GetDlgItem(hWnd, 0xXXXXXXX);

と取得できます。
で結局のところSendMessageをhEditに対して使うので通しで書くと

HWND hWnd;
hWnd = ::FindWindow(NULL, _T("VBのウィンドウタイトル名"));
HWND hEdit = ::GetDlgItem(hWnd, 0xXXXXXXX);
::SendMessage(hEdit, WM_SETTEXT, 0, (LPARAM)"処理終了です!");

となるわけです。

ここで、私がSendDlgItemMessageを押したのはしたの2行を1行でかけるという点です。

HWND hWnd;
hWnd = ::FindWindow(NULL, _T("VBのウィンドウタイトル名"));
::SendDlgItemMessage(hEdit, 0xXXXXXXXX, WM_SETTEXT, 0, (LPARAM)"処理終了です!");

まぁ、これがいやならSendDlgItemMessageを使わないでいいです。

で、
>WindowsForms10.EDIT.app.0.14fd2b5という不可解なクラス名を指定しても
>ハンドルが取得できないのが問題だと思うんですが?
はどこで指定しているのかによります。
(1)を取得して、(2)を取得するときにFindWindowExの第3引数に指定しているのか?
ってことです。


Blue  2007-08-22 01:29:49  No: 66063

しょっぱな間違えていた...orz

>どうしても(2)のウィンドウハンドルを取得する必要があります。
どうしても(1)のウィンドウハンドルを取得する必要があります。


大和撫こ  2007-08-22 01:51:20  No: 66064

やったあ〜♪♪♪
Blueさんの教えのとおりやったら成功しました〜♪
ここまでくるのに苦節、半日ーーー
ありがとうございました〜♪
解決とさせていただきます!
::GetDlgItemを知らないのが
一番のネックだったみたいですね。
本当にありがとうございました!


荣荣  2008-06-02 06:27:48  No: 66065

看不懂啦


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

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






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