ab.com コミュニティ https://www.activebasic.com/forum/ |
|
[AB3](+[AB2])呼び出したDLL側で窓を作成して処理する。 https://www.activebasic.com/forum/viewtopic.php?t=549 |
ページ 1 / 1 |
作成者: | 淡幻星 [ 2005年12月11日(日) 00:27 ] |
記事の件名: | [AB3](+[AB2])呼び出したDLL側で窓を作成して処理する。 |
「おぉ!!できるんだ、こういうことも☆」ってノリが全てです(笑)。 【やってること】 DLLを呼び出し、呼び出した先のDLLの内部でウィンドウを作成し、 呼び出し元のウィンドウはロック。 処理が終わった後に、DLL側のウィンドウを破棄し、 ロックを解除し制御を、呼び出し元に返します。 動作確認AB3.13+AB2.59 【以下、コードなど】 『プロジェクト→DLL-プロシージャライブラリ』で作成。 ※DLL内部でグローバル変数を使っていることに注意。 ['DLLのインスタンス記録用]の部分 ※DLLエントリポイント云々[DllMain()の中]にも一行書き込んでいることに注意。 ['窓作成に使うのでDLLのインスタンスを保持。]の部分 DLLコードはこちら。 [ここをクリックすると内容が表示されます] それの呼び出し元のAB2のコードの例は以下です。コード: '#include "DLLonWnd.idx"'ここは任意ですね^^; '------------------------------------------------------------------- ' メモ - このファイルには、DLLの構成要素を記述します。 ' (例:関数定義、グローバル変数、定数定義など) ' ' エクスポートが必要な関数には、"Export" 修飾子を指定します。 ' (例:Function Export FuncName() As Long) '------------------------------------------------------------------- 'DLLのインスタンス記録用 Dim g_hInstance As Long Function Export DllMain(hinstDLL As DWord, fdwReason As DWord, lpvReserved As VoidPtr) As Long 'DLLエントリポイント Select Case fdwReason Case DLL_PROCESS_ATTACH 'DLLがプロセス空間にロードされた時に実行されます。 g_hInstance = hinstDLL '窓作成に使うのでDLLのインスタンスを保持。 _System_StartupProgram() DllMain=1 End Select End Function 'DLLの外から呼ばれる関数。 '窓を作って任意の処理をする。 '実際の処理の内容は下のメッセージループMainProc()に記述する。 Function Export DllWnd( hBaseWnd As Long ) As Long Dim hInstance As DWord Dim WinClass As WNDCLASSEX Dim hWnd As DWord Dim msgMain As MSG '初期値設定処理 FillMemory( VarPtr(WinClass), Len(WinClass), NULL ) hInstance = g_hInstance'GetModuleHandle( NULL ) 'ウインドウクラス生成 With WinClass .cbSize = Len( WinClass ) .hInstance = hInstance .style = CS_HREDRAW or CS_VREDRAW or CS_DBLCLKS .lpszClassName = "WsSelfWnd" .lpszMenuName = "WsSelfMenu" .lpfnWndProc = AddressOf( MainProc ) .hbrBackground = GetStockObject( WHITE_BRUSH ) .cbClsExtra = NULL .cbWndExtra = NULL .hIcon = LoadIcon( hInstance, NULL ) .hCursor = LoadCursor( NULL, IDC_ARROW ) EndWith If( NULL=RegisterClassEx( WinClass ) )Then DllWnd = FALSE EndIf 'ウインドウ生成 hWnd = CreateWindowEx( NULL, "WsSelfWnd", "テストAB3", (WS_OVERLAPPEDWINDOW or WS_VISIBLE), _ CW_USEDEFAULT , CW_USEDEFAULT, _ CW_USEDEFAULT , CW_USEDEFAULT, _ hBaseWnd, NULL, hInstance, NULL ) EnableWindow( hBaseWnd, FALSE )'親窓をロック 'メッセージループ While( GetMessage( msgMain, NULL, 0, 0 ) ) TranslateMessage( msgMain ) DispatchMessage( msgMain ) Wend DllWnd = msgMain.wParam EnableWindow( hBaseWnd, TRUE )'親窓のロックを解除 EndFunction 'メッセージループ Function MainProc( hWnd As DWord, dwMsg As DWord, wParam As DWord, lParam As DWord ) As DWord SelectCase dwMsg Case WM_DESTROY '窓の破棄処理 PostQuitMessage(0) MainProc = 0 ExitFunction 'Case '以下、ここに処理を書いていく。 EndSelect ' デフォルトプロシージャを呼び出す。 MainProc = DefWindowProc( hWnd, dwMsg, wParam, lParam ) End Function DLLファイル名をDLLonWnd.dllとしています。 スペースを押すと、DLLの中のDllWnd()を呼び出して窓を表示します。 それを閉じればAB2側の窓に制御が戻ります。 AB2からの利用例。 [ここをクリックすると内容が表示されます]
コード: Declare Function DllWnd Lib "DLLonWnd.dll" ( ByVal hBaseWnd As Long ) As Long Ver2Wnd( Ownerwnd() ) End Sub Ver2Wnd( ByVal hBaseWnd As Long ) dim hThisWnd As Long dim Message As Long dim wParam As Long dim lParam As Long dim hWnd As Long Dim retAns As Long Window hWnd, hBaseWnd, -1, -1, _ 320, 240, _ "AB2テスト", _ WS_OVERLAPPED or WS_CAPTION or WS_DLGFRAME or WS_SYSMENU or WS_VISIBLE, _ "NORMAL" While 1 GetWndMsg hThisWnd, Message, wParam, lParam If ( hThisWnd<>hBaseWnd ) Then SelectCase Message '終了操作 Case WM_CLOSE Msgbox hWnd, "終了処理" ExitWhile EndSelect 'スペースでDLLの関数呼び出し If KeyState(Asc(" ")) And &H8000 Then retAns = DllWnd( hWnd ) Msgbox hWnd, "ほげ" EndIf EndIf Wend DelWnd hWnd EndSub AB2でプログラムを組んでいて、 負荷の高い処理はAB3/AB4で作ったDLLを呼び出して処理する、 などという変なことをしている人(=私の仲間w)にしか 参考にならないかもしれません(苦笑)。 ついでに。 DLL作成のときは、デバックモードが無いので、 大抵別途に組んで動作を確かめてから関数だけをコピペしてますよね、きっと。 そのときの『動作の確かめ用』のコードも以下に載せておきます。 『プロジェクト→EXE-N88プロンプトベース』で作成。 でも当然ながらN88BASICのプロンプト画面は使いません^^; 使ったらDLLに移したときにエラーします。 あ、Print文とかでデバッグするのは楽になるかも? (『EXE-ベース無し』を選べばよかったのかな?) なにはともあれ、そのときのコードです。 窓作成 [ここをクリックすると内容が表示されます] コード: #N88BASIC ' ↓ ここからプログラムが実行されます Dim retAns As Long retAns = WinMain( _PromptSys_hWnd ) End 'ExitProcess(0)を呼んでいます。 Function WinMain( hBaseWnd As Long ) As Long Dim hInstance As DWord Dim WinClass As WNDCLASSEX Dim hWnd As DWord Dim msgMain As MSG '初期化 FillMemory( VarPtr(WinClass), Len(WinClass), NULL ) hInstance = GetModuleHandle( NULL ) 'ウインドウクラス生成 With WinClass .cbSize = Len( WinClass ) .hInstance = hInstance .style = CS_HREDRAW or CS_VREDRAW or CS_DBLCLKS .lpszClassName = "WsSelfWnd" .lpszMenuName = "WsSelfMenu" .lpfnWndProc = AddressOf( MainProc ) .hbrBackground = GetStockObject( WHITE_BRUSH ) .cbClsExtra = NULL .cbWndExtra = NULL .hIcon = LoadIcon( hInstance, NULL ) .hCursor = LoadCursor( NULL, IDC_ARROW ) EndWith If( NULL=RegisterClassEx( WinClass ) )Then WinMain = FALSE EndIf 'ウインドウ生成 hWnd = CreateWindowEx( NULL, "WsSelfWnd", "テストAB3", (WS_OVERLAPPEDWINDOW or WS_VISIBLE), _ CW_USEDEFAULT , CW_USEDEFAULT, _ CW_USEDEFAULT , CW_USEDEFAULT, _ hBaseWnd, NULL, hInstance, NULL ) While( GetMessage( msgMain, NULL, 0, 0 ) ) TranslateMessage( msgMain ) DispatchMessage( msgMain ) Wend WinMain = msgMain.wParam EndFunction メッセージループ [ここをクリックすると内容が表示されます] 以上二つをプロジェクトに参加させて下さい。コード: 'メッセージループ Function MainProc( hWnd As DWord, dwMsg As DWord, wParam As DWord, lParam As DWord ) As DWord ' TODO: この位置にウィンドウメッセージを処理するためのコードを記述します。 SelectCase dwMsg Case WM_DESTROY PostQuitMessage(0) MainProc = 0 ExitFunction 'Case '以下、ここに処理を書いていく。 EndSelect ' デフォルトプロシージャを呼び出す。 MainProc = DefWindowProc( hWnd, dwMsg, wParam, lParam ) End Function なお、こちらは親ウィンドウ(=DLLでの呼び出し元の窓)であるプロンプトウインドウはロックしていません。 ふむ。 『Win32プログラミング講座 ~ Step14. DLLを作る ~』で思いっきり DLLに窓ハンドル渡して内部で保存ダイアログなどを呼んでいるわけだから、 出来て当然なのか^^; 12/11 2:30修正しました。 |
作成者: | Sinryow [ 2005年12月11日(日) 02:01 ] |
記事の件名: | Re: [AB3](+[AB2])呼び出したDLL側で窓を作成して処理する。 |
微妙なツッコミですが "WinMain"という名前にすると,C言語のWindowsプログラムの始動時関数と同じ名前になるので名前を変えたほうがよいかと思われます(笑)。 |
作成者: | 淡幻星 [ 2005年12月11日(日) 02:40 ] |
記事の件名: | Re: [AB3](+[AB2])呼び出したDLL側で窓を作成して処理する。 |
引用: 微妙なツッコミですが
あ、やっぱ気になりますか?^^;"WinMain"という名前にすると,C言語のWindowsプログラムの始動時関数と同じ名前になるので名前を変えたほうがよいかと思われます(笑)。 そうですね。DLLの方WinMain()→DillWnd()に書き換えておきました。 私もちょっと気になってたのでAB2の呼び出しでAliasなんぞ使ってたのでしたし(笑)。 でもDLLの動作確認用コードの方はそのままに(こっちはEXEですし)。 窓クラスを登録して、CreateWindowして、って作業する関数ですから、 WinMain()そのままなわけで問題はないかと。 こっちの方がしっくり来るんですよね、私としては^^; 引数が違うじゃないか、というツッコミは知りません(笑)。 ん~、Cのコードから写したことがバレバレw あ、蛇足なんですけどせっかくなので≫Sinryowさん AB4のクラスで、仮想メソッドって、 関数の形を宣言するだけで、内容は定義できないんですか? ヘルプを読んだ限りではそう思えたのですが、 C++だったら「オーバーライドされなかったときの動作」として 内容も定義できるんで、どうなんだろうとちょっと疑問。 自分で確かめれば良いんですが(人に聞いたほうが早い♪/マテ)、 知ってましたら&気が向きましたら、お願いします^^; |
作成者: | Sinryow [ 2005年12月11日(日) 10:46 ] |
記事の件名: | Re: [AB3](+[AB2])呼び出したDLL側で窓を作成して処理する。 |
引用: あ、蛇足なんですけどせっかくなので≫Sinryowさん
自分もよく知らなかったので調べてみましたが,ABのVirtualって,C++とかのとは全く違うようです。AB4のクラスで、仮想メソッドって、 関数の形を宣言するだけで、内容は定義できないんですか? ヘルプを読んだ限りではそう思えたのですが、 C++だったら「オーバーライドされなかったときの動作」として 内容も定義できるんで、どうなんだろうとちょっと疑問。 自分で確かめれば良いんですが(人に聞いたほうが早い♪/マテ)、 知ってましたら&気が向きましたら、お願いします^^; C++などでは淡幻星さんのおっしゃった通り「オーバーライドされなかったときの動作」なのです。 http://hwb.ecc.u-tokyo.ac.jp/current/CD ... 8BFF4.html(仮想関数についての簡単な説明。Yahooのキャッシュ) http://wisdom.sakura.ne.jp/programming/cs/cs26.html(C#だがプログラムの例があり分かりやすい) ※自分はABでもC++でもVirtualを使ったことはありません。(核爆) |
作成者: | イグトランス [ 2005年12月11日(日) 13:13 ] |
記事の件名: | |
そこのサイトにはC++のもありますよ。 http://wisdom.sakura.ne.jp/programming/cpp/cpp31.html そしておそらくAB5ではC++などと同じように仮想関数が扱えるようになると思います。 (AB4.2でそうなるという話でしたがどうやらAB4.2は出ないようなので) |
作成者: | 淡幻星 [ 2005年12月11日(日) 15:52 ] |
記事の件名: | Re: [AB3](+[AB2])呼び出したDLL側で窓を作成して処理する。 |
引用: 自分もよく知らなかったので調べてみましたが,ABのVirtualって,C++とかのとは全く違うようです。
わざわざ調べていただいてありがとうございますm(_ _)mふむ。全然違うものなんですね^^; 私の中ではVirtual宣言=仮想関数=オーバーライドだと思ってたんですが、 これが間違いでないにしても、全てじゃなかったんですね(^^;)。 現在のABは 引用: 仮想関数は主にCOMインターフェイスを定義する際に活用します。
にターゲットを絞っているんですね。気になった理由は、 ABでCreateWindow()+WndProcをクラス化してみようと思ったからです。 そうすると継承の際にメンバ関数のオーバーライドが使えないと不便なわけで、 「AB4にはVirtual宣言も導入されてたよな・・・」と思ったしだいでした。 目的としては・・・(略)。 [ここをクリックすると内容が表示されます] ABにはRADがありますから、そんなに必要ないですかw よってノープロブレムかな(笑)一行で必要最低限の窓を作成(最低限の機能を持った窓プロシージャも自動で生成される)できて、後は必要に応じて機能拡張(イベント動作の追加)できるクラスがあると、コード書くとき便利だよな~、というものです。先日C++で組んでみましたが、少なくとも私にとっては思った以上に便利に仕上がりました♪ まぁMFCに、それそのままのCWndクラス?があるみたいですけど^^; 引用: ※自分はABでもC++でもVirtualを使ったことはありません。(核爆)
ちなみに私は、つい最近C++で「おぉ、仮想関数って便利じゃねーか。継承するときは様々だな☆」って 思ったばかりでして(つーか、そのための仕様ですね^^;)。だから使ってみたいのです(笑)。 http://wisdom.sakura.ne.jp/ そこのサイト様は、すごく利用させてもらってます。分かりやすいですよね☆ 私はそこでC/C++の基本と、C/C++でのウィンドウの生成を学びました(^^) 引用: AB5ではC++などと同じように仮想関数が扱えるようになると思います。
そうなんですか。ではそのときを楽しみに待ちます。 詳しい情報をありがとうございました。おかげですっきりしました。 |
ページ 1 / 1 | 全ての表示時間は UTC+09:00 です |
Powered by phpBB® Forum Software © phpBB Limited https://www.phpbb.com/ |