お世話になります。
こちらのHPの「API技術関連」のウインドウに関するプログラムで、「EnumWindows(全てのウインドウを列挙する)」をD.L.して使用した際に、「DLLが正しく呼び出せません」(実行時エラー49)が出ます。
デバックすると command1のClickにおいて、
Ret = EnumChildWindows(hWnd, AddressOf EnumChildProc, 0)
が選択されています。
どうしたものでしょうか…
当方VB6.0です。
よろしくお願いします。
エラーがエラーですから、使用方法云々の問題ではないと思います。
たぶん、宣言がおかしいとかの問題ではないでしょうか?
ここからのコピーペーストなら、たとえば文字が抜けてるとか、
要らないスペースが入ってるとか。
宣言部分を書いてくれれば、アドバイスできるかもしれません。
お世話になります。
標準モジュールの宣言部は以下の様になっています。
Public Declare Function EnumWindows Lib "user32" (ByVal lpEnumFunc As Long, lPalam As Long) As Long
Public Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hWnd As Long, ByVal lpString As String, ByVal cch As Long) As Long
Public Function Rekkyo(ByVal Handle As Long) As Boolean
いかがでしょうか…
よろしくお願い致します。
おや、何にも問題なさそうですね…。
と思いきや、調べてみると、"あれ?"が一点。
lpEnumFuncですけど、本当は
> BOOL CALLBACK EnumWindowsProc(
> HWND hwnd, // 親ウィンドウへのハンドル
> LPARAM lParam // アプリケーションで定義された値
> );
上のように定義されています。
VBに直すと、こういう具合です。
> Function EnumWindowsProc(ByVal hwnd As Long, ByVal lParam As Long) As Long
(両方とも、MicroSoftよりの引用。
要は最後に、lParamというByValのLong型変数がついただけです)
ところで、上のを見直してみて気づいたんですけど、宣言文にはEnumChildWindowsなんて関数ありませんけど。
そっちのAPIの宣言はどうなってます?あとコールバックのほうも。
ついでに、戻り値に使ってるRetですけど、使ってないなら不要かも。
(成功したかどうかが入るので、必要といえば必要なものの、失敗時の処理がいらないのなら別になくてもいい)
VBは最適化しないはずなので、4バイトの無駄使いになるかもしれません。
う…ん。
すみません。私初心者なもんで…よく内容が理解できないところが…
最初にも申しましたが、このHPのサンプルプログラム”EnumWindows(全てのウインドウを列挙する)”をダウンロードして実行した結果エラーが出てしまうんです。
そちらの方を見ていただいのですが…
よろしくお願いしますm(__)m
んー、じゃあ、ここで書いたことのとおり解釈しますけど…。
上の宣言は、"EnumWindows"というAPIを、プログラム内で使うことを宣言したわけです。
でも、あなたが使おうとしたのは"EnumChildWindows"という別のAPIです。
それでは、使えないはずですよね。ということです。
APIはAPIビューアで宣言文をコピーできます。
うちの おんぷむらのうら>旧学校>ツール紹介のページにて、
おすすめのAPIビューアを書いていますから、見てみてください。
>たかみちえさん
お世話になっております。
早速APIビューアを試してみました。
EnumWindowsの宣言文を今まで話しておりますソースの宣言箇所にコピペしたのですが、結果は同じでした(>_<)
ひとつ言い忘れていましたが、実行させた時にウインドウ名が列挙されることはされるのですが、列挙された後にエラーが出るという感じです。
表現が下手で申し訳ございません。
最初に少し話題を整理したいと思いますが、
はぎーさんの発言で
>「EnumWindows(全てのウインドウを列挙する)」をD.L.して使用した際に
とあるのに、同じ発言で
>Ret = EnumChildWindows(hWnd, AddressOf EnumChildProc, 0)
と、「EnumChildWindows」を使用しています。
次のはぎーさんの発言で、
>Public Declare Function EnumWindows Lib "user32" (ByVal lpEnumFunc As Long, lPalam As Long) As Long
とあるので、
EnumWindowsだったと解釈しています
(と、言うより両方やって両方同じエラーだったのかもしれませんね。)
そこで混乱してしまったようで、
たかみちえさんも
> lpEnumFuncですけど、本当は
>> BOOL CALLBACK EnumWindowsProc(
>> HWND hwnd, // 親ウィンドウへのハンドル
>> LPARAM lParam // アプリケーションで定義された値
>> );
> 上のように定義されています。
と、EnumWindows「Proc」の宣言を見てしまったようです。
ちょっと重箱の隅をつつくようですが、
この辺の誤解を解いておいたほうがいいと思いましたので。
さて、肝心の話ですが、
これら(EnumWindowsとEnumChildWindows)のCALLBACK関数に
操作させる関数は、
第一引数にHWND,第二引数にLPARAMをとるようです。(少なくともWinXPでは)
ところが、EnumWindowsのサンプルプロジェクトでは
>Public Function Rekkyo(ByVal Handle As Long) As Boolean
と宣言されており、(以前のバージョンのウィンドウズでは動いたのかもしれません)
引数が渡せないため、エラーが起こったのだと思います。
ので、
Public Function Rekkyo(ByVal Handle As Long,lparam As Long) As Boolean
とすることで、エラーを回避することができます。
(As longよりAs Objectのほうがいいのかも。)
EnumChildWindowsのほうも、同様に、第二引数を追加して
Public Function EnumChildProc(ByVal hWnd As Long, lparam As Long) As Long
とすれば、動きます。
あ"、失礼。
勘違いしていたのは私で、
> lpEnumFuncですけど、本当は
>> BOOL CALLBACK EnumWindowsProc(
>> HWND hwnd, // 親ウィンドウへのハンドル
>> LPARAM lParam // アプリケーションで定義された値
>> );
> 上のように定義されています。
というのは要するに私の後半部分となんらかわるところがありませんね。
あぁ重箱の隅に入りたい(汗)
ありがとうございますm(__)m
ばっちり動作しました。
お世話になりました。
ツイート | ![]() |