プログラミング
Jeans & Development | 電子ブロック工房 | 三日坊主 | フロントページ |
WSHでWin32APIを呼び出す-その13 [プログラミング]
2005年10月26日
(←戻る)
前の記事で、Malloc周りを変えたいと書いたが、その為のプログラムの変更を行っていてあることに気が付いた。ver 0.1.2.2 では、ユーザ定義型の変数用のメモリを確保するため、dwtools.dll のソースコードの冒頭部分で次のように記述している。
このままだと、このmBuff[65536]の部分がdllファイルに含まれてしまうため、dll が無駄に大きくなってしまう。つまり、128kb の部分に延々と0xFFが書かれたようなdllファイルが出来てしまうわけだ。
前の記事で、Malloc周りを変えたいと書いたが、その為のプログラムの変更を行っていてあることに気が付いた。ver 0.1.2.2 では、ユーザ定義型の変数用のメモリを確保するため、dwtools.dll のソースコードの冒頭部分で次のように記述している。
#include <windows.h> unsigned short mBuff[65536]={0xFFFF}; int lastMBuff=65536;
このままだと、このmBuff[65536]の部分がdllファイルに含まれてしまうため、dll が無駄に大きくなってしまう。つまり、128kb の部分に延々と0xFFが書かれたようなdllファイルが出来てしまうわけだ。
PHP関数 url_exists(), url_head() [プログラミング]
2005年9月20日
PHPのfile_exists()はリモートファイルでは使えない。そこで、リモートファイル(現在の所、'http://xxx/xxx'のみ)で扱えるurl_exists()とurl_head()を作成した。
作っている途中で"if ( !@fopen($URL,'r') )"でエラートラップすることでURLが有効かどうか調べられることに気がついたが、その時点で殆ど完成していたので完成させてメモを取っておくことにした。
作っている途中で"if ( !@fopen($URL,'r') )"でエラートラップすることでURLが有効かどうか調べられることに気がついたが、その時点で殆ど完成していたので完成させてメモを取っておくことにした。
Delphi で使える InStr() [プログラミング]
2005年9月2日
VB のInStr() 関数はDelphi にはなく、pos()関数を使わなければならず、これは機能的にInStr()より劣る。ならば、InStr()を自分で作ればよい。
(以下、InStr()のコード)
(以下、InStr()のコード)
WSHでWin32APIを呼び出す-その12 [プログラミング]
2005年7月14日
(←戻る)
SFCを機能アップして、メニューが使えるようにした。あと、バグフィックス等を行ったので、安定に走るようになってきている。
メニュー表示をWin32APIで実現させるための方法をWebで探してみたが、なかなか良いのが見つからなかった。というのは、殆どの参考文献がリソースファイルを用いてメニューを表示させているためで、そういったことがSFCではまだ出来ないからである。最終的に参考になったのは、ここで、これを参考にしてMenuクラス、PopupMenuクラスを作成し、それらを用いてメニューを表示するようにした。作成したMenu.vbsの実行画面は以下の通り。

(SFC ver 0.1.2.2はここからダウンロードできます)
SFCを機能アップして、メニューが使えるようにした。あと、バグフィックス等を行ったので、安定に走るようになってきている。
メニュー表示をWin32APIで実現させるための方法をWebで探してみたが、なかなか良いのが見つからなかった。というのは、殆どの参考文献がリソースファイルを用いてメニューを表示させているためで、そういったことがSFCではまだ出来ないからである。最終的に参考になったのは、ここで、これを参考にしてMenuクラス、PopupMenuクラスを作成し、それらを用いてメニューを表示するようにした。作成したMenu.vbsの実行画面は以下の通り。

(SFC ver 0.1.2.2はここからダウンロードできます)
VBscriptでのExecuteの使用 [プログラミング]
2005年7月13日
VBscriptには、Execute命令が存在する。これは、多くの場合インタープリター言語で使用可能な命令なのであるが、結構便利である。最近、これで関数やサブルーチン、クラスなども定義できてしまうのを知り、驚いた。例えば、
と記述すれば、ちゃんと『OK』を表示するダイアログが表示される。ちなみに、『Execute T』と『ShowOK』の二つの行を入れ替えると、エラーになる。
この機能は諸刃の剣と考えた方が良い。使用する場合には、そのExecuteステートメントが何をしているのかが分かるような注釈行を入れた方が良いだろう。でないと、簡単にスパゲッティーができあがってしまう。
そういったことを考慮して使用すると、例えばVBscriptには無い、『#include』のような使い方も出来そうである。VBscriptは元々、HTMLに埋め込んで使用することを前提に設計されているため(HTML では、<SCRIPT SRC="xxxx">が使える)、VBscriptを複数のファイルに分割することが出来ないのであるが、Execute命令を用いればそういったことも出来る。バッチファイル(*.bat)の高機能な代替品として使っている私としては、これは都合がいい。
T="sub ShowOK"+vbcrlf
T=T+"msgbox ""OK"" "+vbcrlf
T=T+"end sub"+vbcrlf
Execute T
ShowOK
T=T+"msgbox ""OK"" "+vbcrlf
T=T+"end sub"+vbcrlf
Execute T
ShowOK
と記述すれば、ちゃんと『OK』を表示するダイアログが表示される。ちなみに、『Execute T』と『ShowOK』の二つの行を入れ替えると、エラーになる。
この機能は諸刃の剣と考えた方が良い。使用する場合には、そのExecuteステートメントが何をしているのかが分かるような注釈行を入れた方が良いだろう。でないと、簡単にスパゲッティーができあがってしまう。
そういったことを考慮して使用すると、例えばVBscriptには無い、『#include』のような使い方も出来そうである。VBscriptは元々、HTMLに埋め込んで使用することを前提に設計されているため(HTML では、<SCRIPT SRC="xxxx">が使える)、VBscriptを複数のファイルに分割することが出来ないのであるが、Execute命令を用いればそういったことも出来る。バッチファイル(*.bat)の高機能な代替品として使っている私としては、これは都合がいい。
WSHでWin32APIを呼び出す-その11 [プログラミング]
2005年7月10日
(←戻る)
さて、前の記事まででWndProcをコールバック関数に指定して、ここから別のVBscriptを別のプロセスとして呼び出すことで、Hello Worldプログラムを作成した。さて、もう少し高度なことが出来るかと考え、こちらのページを参考にさせて頂いて、色々とプログラミングしてみた。
しかしである。いきなり問題が発生した。WinAPIのSetCaptureによりマウスをキャプチャーしようとしてみたが、これが出来ないのである。MSDN曰く、『この関数を使って、ほかのプロセスでマウスのキャプチャを開始することはできません。』ということらしい。今の方法では、WndProcの処理を別のプロセスで行っているため、この不都合が起きる。どうしたらよいだろうか。
さて、前の記事まででWndProcをコールバック関数に指定して、ここから別のVBscriptを別のプロセスとして呼び出すことで、Hello Worldプログラムを作成した。さて、もう少し高度なことが出来るかと考え、こちらのページを参考にさせて頂いて、色々とプログラミングしてみた。
しかしである。いきなり問題が発生した。WinAPIのSetCaptureによりマウスをキャプチャーしようとしてみたが、これが出来ないのである。MSDN曰く、『この関数を使って、ほかのプロセスでマウスのキャプチャを開始することはできません。』ということらしい。今の方法では、WndProcの処理を別のプロセスで行っているため、この不都合が起きる。どうしたらよいだろうか。
WSHでWin32APIを呼び出す-その10 [プログラミング]
2005年7月7日
(←戻る)
あとは、WndProcスクリプトファイル名の指定と、トラックすべきメッセージの指定であるが、こちらの方はそれほど難しくはない。これらの機能のため、DLLに次の関数を追加した。
あとは、WndProcスクリプトファイル名の指定と、トラックすべきメッセージの指定であるが、こちらの方はそれほど難しくはない。これらの機能のため、DLLに次の関数を追加した。
char WndProcScript[256]="wscript.exe wndproc.vbs"; void __stdcall DwSetWndProcScript( char* T ) { int i; for (i=0;i<256;i++) if ( (WndProcScript[i]=T[i])==0) break; } unsigned long TrackHandle[256]; unsigned long TrackMsg[256]; int TrackNum=0; long __stdcall DwSetTrackedHandleMsg(unsigned long hWnd, unsigned long uiMsg) { if (256<=TrackNum) return 0; TrackNum++; TrackHandle[TrackNum]=hWnd; TrackMsg[TrackNum]=uiMsg; return -1; } void __stdcall DwClearTrackedHandleMsg() { TrackNum=0; }
WSHでWin32APIを呼び出す-その9 [プログラミング]
2005年7月7日
(←戻る)
前回までに製作した、dwtools.dllは、『Hello, World!』プログラムに特化したものであり、まだまだ汎用性は低い。現段階では、少なくとも次のような問題が有る。
1)ユーザ定義の構造体を引数に持つAPIを呼び出した際、そのAPIからの戻り値が構造体に収められている場合に、それを取り出す事が出来ない。
2)WndProcで、WM_PAINT, WM_DESTROY以外のメッセージをトラック出来ない。
3)WndProcで呼び出されるスクリプトのファイル名が、wndproc.vbsに限られている。
4)wndproc.vbsで、グローバル変数・スタティック変数を使用することが出来ない。
5)WndProc以外のコールバック処理(EnumXXXX等)が行えない。
これらの内、1)-3)は、解決可能である。4)については、グローバル変数の内容をファイルに保存する形にすれば解決できる(他にも手があるかもしれない)。5)については、DLLの中に新たにコールバック関数を作成するしか手がないが、よく使う『EnumWindows』あたりを実装しておけば、あとは殆ど必要無いのではなかろうか(VB ver4 以前では不可能な機能であったわけだし)。
そこでまず、1)-3)について対処することにした。
前回までに製作した、dwtools.dllは、『Hello, World!』プログラムに特化したものであり、まだまだ汎用性は低い。現段階では、少なくとも次のような問題が有る。
1)ユーザ定義の構造体を引数に持つAPIを呼び出した際、そのAPIからの戻り値が構造体に収められている場合に、それを取り出す事が出来ない。
2)WndProcで、WM_PAINT, WM_DESTROY以外のメッセージをトラック出来ない。
3)WndProcで呼び出されるスクリプトのファイル名が、wndproc.vbsに限られている。
4)wndproc.vbsで、グローバル変数・スタティック変数を使用することが出来ない。
5)WndProc以外のコールバック処理(EnumXXXX等)が行えない。
これらの内、1)-3)は、解決可能である。4)については、グローバル変数の内容をファイルに保存する形にすれば解決できる(他にも手があるかもしれない)。5)については、DLLの中に新たにコールバック関数を作成するしか手がないが、よく使う『EnumWindows』あたりを実装しておけば、あとは殆ど必要無いのではなかろうか(VB ver4 以前では不可能な機能であったわけだし)。
そこでまず、1)-3)について対処することにした。
WSHでWin32APIを呼び出す-その8 [プログラミング]
2005年7月5日
(←戻る)
前回までの記事で、VBscriptとDynaWrapに簡単で汎用的なDLLを加えることで、WinAPIによりウインドウを表示させることが出来た。最後にいよいよ、『Hello, World!』の表示である。これには、コールバック関数の処理をしなければならない。
wscript.exeの実行により開始されたプロセスは、スクリプトの実行用にスレッドを一つ走らせている。前回の記事のtest.vbsでは、新規ウインドウの作成によりスレッドの制御が例のコールバック関数に移るわけであるが、このコールバック関数が終了しない限りスレッドの制御がスクリプトの実行に戻ることはないようである。例えば、『コールバック関数の中でSleep関数の呼び出しを繰り返すようにループさせておき、一度スクリプトに制御を移す。続けて、このスクリプトの実行結果をなにかしらの形で捕らえた時にSleep関数のループから抜け出す。』といったことを試してみたが、全く駄目であった。
前回までの記事で、VBscriptとDynaWrapに簡単で汎用的なDLLを加えることで、WinAPIによりウインドウを表示させることが出来た。最後にいよいよ、『Hello, World!』の表示である。これには、コールバック関数の処理をしなければならない。
wscript.exeの実行により開始されたプロセスは、スクリプトの実行用にスレッドを一つ走らせている。前回の記事のtest.vbsでは、新規ウインドウの作成によりスレッドの制御が例のコールバック関数に移るわけであるが、このコールバック関数が終了しない限りスレッドの制御がスクリプトの実行に戻ることはないようである。例えば、『コールバック関数の中でSleep関数の呼び出しを繰り返すようにループさせておき、一度スクリプトに制御を移す。続けて、このスクリプトの実行結果をなにかしらの形で捕らえた時にSleep関数のループから抜け出す。』といったことを試してみたが、全く駄目であった。
WSHでWin32APIを呼び出す-その7 [プログラミング]
2005年7月4日
(←戻る)
前回までの記事で、ユーザー定義型の構造体を引数に持つWinAPIを呼び出せるようになった。引き続き、VBで出来た『Hello, World!』プログラムを見てみよう。
前回詰まったここの部分は、解決した。続きは…
ここまでは問題なし。Main()関数を見てみる。
一番大きな問題はこの行にある。VBscriptでは、『AddressOf 』は使えない。
前回までの記事で、ユーザー定義型の構造体を引数に持つWinAPIを呼び出せるようになった。引き続き、VBで出来た『Hello, World!』プログラムを見てみよう。
Option Explicit Type POINTAPI x As Long y As Long End Type
前回詰まったここの部分は、解決した。続きは…
Const SW_SHOW = 5 (略) Declare Function LoadIcon Lib "user32" Alias "LoadIconA" _ (ByVal hInstance As Long, ByVal lpIconName As String) As Long (略) Private g_chAppName As String Private g_chClassName As String Private p_hInstance As Long, p_hPreInst As Long Private p_pchCmdLine As String, p_iCmdShow As Integer
ここまでは問題なし。Main()関数を見てみる。
Sub Main() 'WinMainと互換性を持たせるための記述 p_hInstance = App.hInstance p_hPreInst = App.PrevInstance p_pchCmdLine = Command p_iCmdShow = SW_SHOW g_chAppName = "TestApplication" 'アプリケーションの名前 g_chClassName = "TestWndClass" 'ウィンドウクラス名 If InitApplication(p_hInstance, AddressOf WndProc) = True Then
一番大きな問題はこの行にある。VBscriptでは、『AddressOf 』は使えない。