* 自作ライブラリ OSASK用msgboxライブラリについて [#h7517300]
* 自作ライブラリ OSASK用msgboxライブラリに詳細/使い方 [#h7517300]
-by [[nika]] (2006/07/20, Ver1.0β)~
~
Windows互換のmsgboxライブラリです。~
Visual Basic の msgbox関数相当になっています。~
ただし、rightalignやsetforegroundなど、普段使わない機能は現在未実装です。~
ライブラリファイルのダウンロードは[[自作LIBファイル]]からダウンロードできます。~
ここに書いていない定数などは付属のドキュメントをご覧下さい。~

~
** naskでの使い方 [#j06b9a02]
-まず、以下の宣言と定数の定義をします
--msgbox.h としてファイルにまとめられています(インクルード機能を使うには、CPP0.exeを通す必要があります)。
 ; 外部関数の使用宣言
 extern			msgbox, msgboxinit
** C言語から利用するには [#sf10e137]
-msgboxライブラリの定義をincludeする~
利用するソースの最初の方へ以下のどちらかをリストを追加します。
--同じフォルダに置く場合(そのアプリケーションだけで利用する場合)
 #include "msgboxc.h"
--ライブラリ専用フォルダに置いている場合(全アプリケーションで利用可能にする場合)
 #include <msgboxc.h>

-makefileにライブラリの使用を記述する~
msgbox.libを取り込んでコンパイルしなければ実際のルーチンが組み込まれないので注意してください。~
makefileに以下の行を変更します。
            :
            :
 mallocsize = 512k
 mmarea     = 512k
 objs       = $(TARGET).obj msgbox.lib
 
 ; 定数の宣言
 ; ・ボタンの種類
 mgOKOnly		equ	0
 mgOKCancel		equ	1
 mgAbortRetryIgnore	equ	2
 mgYesNoCancel		equ	3
 mgYesNo		equ	4
 mgRetryCancel		equ	5	; 独自拡張(変更するかも知れません)
 mgAbortIgnore		equ	6	; 独自拡張(変更するかも知れません)
 mgCancelOnly		equ	7	; 独自拡張(変更するかも知れません)
 ; ・アイコン
 mgCritical		equ	0x000010 ; ×
 mgQuestion		equ	0x000020 ; ?
 mgExclamation		equ	0x000030 ; !
 mgInformation		equ	0x000040 ; i
 mgCrit			equ	mgCritical
 mgQues			equ	mgQuestion
 mgExcl			equ	mgExclamation
 mgInfo			equ	mgInformation
 ; ・デフォルトのボタン
 mgButton1		equ	0x000000 ; 左から順番に
 mgButton2		equ	0x000100
 mgButton3		equ	0x000200
 mgButton4		equ	0x000300
 ; ・その他
 mgApplicationModal	equ	0x000000
 mgSystemModal		equ	0x001000 ; OSASKでは未対応
 ; ・拡張設定(未対応)
 mgHelpButton		equ	0x004000 ; "ヘルプ"ボタンも表示
 mgSetForeground	equ	0x010000 ; 未対応
 mgRightAlign		equ	0x080000 ; 未対応(右側に詰めるらしい)
 mgRtlReading		equ	0x100000 ; 未対応(右から左へ読むようにする、ウィンドウの×ボタンも左側になるらしい)
 ; ・戻り値(押されたボタン番号)
 mgOK			equ	1
 mgCancel		equ	2
 mgAbort		equ	3
 mgRetry		equ	4
 mgIgnore		equ	5
 mgYes			equ	6
 mgNo			equ	7
 incpath    = ../z_tools/guigui00/
            :
            :
要はOBJSにmsgbox.libを追加するだけです。

-msgboxライブラリを初期化する~
最初にmsgboxライブラリを初期化しておかなければなりません。といっても、msgboxinitを1度呼び出しておけばいいだけです。簡単だと思います。~
 void msgboxinitc(int 0, int signalbase, int fontsetslot, char *windowtitle);
     signalbase
         シグナル番号のベース値です。この番号から約80個の連続したシグナルが来る様になります。
         このシグナルを受信したら、すみやかにmsgboxsignalcへリダイレクトしてください。
     fontsetslot
         使用するフォントセットのスロット番号です。
         日本語フォントも使用できますが、パラメータのb0を1にして関数を呼び出さないと有効になりません。
         システムフォントセットを使用する場合はb0を1にしないで下さい。breakしてしまいます。
     windowtitle
         msgboxウィンドウのタイトルバーの文字列で、ASCIIZ文字列へのポインタです。
         この文字列には日本語は使用することはできません。使用しても落ちることはありませんが、
         文字化けしてしまいます。
     0
         この値は将来の拡張用に予定されていて、現在の値は0です。
         次のバージョンでも動作できるように、値を変更しないで下さい。
 
上記枠内を参考に値をセッティングして下さい。ただし日本語フォントの扱いは注意が必要です。~
以下は基本のセッティング例です。大体はこの値にしておけば問題ないです。
 /* msgboxライブラリを初期化する */
 static char windowtitle[] = "DOS Emulater beta";
 msgboxinitc(0, 0x1000 /* signalbase */, 0xC0 /* fontset slot */, windowtitle /* titlestring */);
 /* 0x1000とかするより#define SIG_MSGBOX 0x1000などdefineして使った方がいいと思う。 */
これでmsgboxライブラリを使用する準備が整いました。次はmsgboxcを使用して実際にオープンしてみます。
その前に日本語フォントセットを0x3A0に定義した場合の例も以下に記します。
 /* msgboxライブラリを日本語環境用に初期化する */
 static char windowtitle[] = "DOS Emulater alpha";
 msgboxinitc(0, 0x1000 /* signalbase */, 0x3A1 /* fontset slot & used japanese flag */, \ 
             windowtitle /* titlestring */);
~
''以下未完成''
-msgboxライブラリを初期化する
-実際にmsgboxを使うとき
-日本語フォントを使えるようにする

-実際にmsgboxを使うとき(msgboxc関数とmsgboxsignalc関数)~
 void msgboxc(int windowslot, char *messagestring, int optionvalue, int closesignal);
     windowslot
         msgboxで使用するwindowのスロット番号です。重複は許されません。
     messagestring
         ASCIIZ文字列へのポインタで、本文です。
         この文字列の長さによって自動的にwindowのサイズが変わります。
         ※windowが大きくなりすぎる場合、windowは最大サイズになりますが文字列が改行されません(現在)。
     optionvalue
         ボタンの種類やアイコンの表示などを設定するオプション値です。0を指定した場合はOKのみになります。
         WindowsのVisual Basicシリーズと互換なので、現在はそちらで検索してください。
     closesignal
         msgboxのwindowが閉じられたときに送られるシグナルです。
         シグナルの長さは8バイトで、最初の4バイトでclosesignalで指定した値が返され、次に
         msgboxのリターン値が返されます。
 
 int msgboxsignalc(int signalnum);
     signalnum
         受信したシグナル番号を通知するために使用します。このプロセスで各種動作をします。
     リターン値
         このシグナルに必要なパラメータシグナルの個数(1個4バイト)。この値が0でない場合は、
         ユーザーアプリ側でgetparam0などして同じ関数を呼び出して下さい。
         パラメータの送信に使用した場合のリターン値は保障されません。
上記枠内を参考に値をセッティングしてお使い下さい。~
msgboxcを呼んでもすぐに戻ってきます。windowが閉じられるまで待つ場合は各自waitsignalしてください。~
指定したシグナルの範囲をリダイレクトしないと、msgboxが動かなくなるので注意してください。~
~
これを直接呼ぶより、自分のサブルーチンでラッピングした方が使いやすいと思われます。~
以下は簡単なメッセージを表示する場合の例です。
 /* "hellocmb0.c":helloをmsgbox上で表示するようにした例 */
 /*  stack:4k malloc:1k */
 
 /* このソースの説明はありません。msgboxライブラリのサンプルプログラムです */
 
 #include <guigui00.h>
 #include "msgboxc.h"
 
 #define	AUTO_MALLOC	0
 #define	REWIND_CODE	1
 
 static int *signalbox0, *sig_ptr;
 void initsignalbox();
 const int getsignal();
 int getparam();
 
 void OsaskMain()
 {
 	static char windowtitle[] = "hellocmb0";
 	static char msgstr[] = "hello, world!";
 	
 	/* ライブラリの初期化(必ず最初にやらなければならない) */
 	lib_init(AUTO_MALLOC);
 
 	/* シグナルボックス初期化 */
 	initsignalbox();
 
 	/* msgboxライブラリの初期化 */
 	msgboxinitc(0, 0x1000 /* signalbase */, 0xC0 /* fontset slot */, windowtitle /* titlestring */);
 	
 	/* msgboxのwindowを開く */
 	msgboxc(0x200 /* window slot */, msgstr /* text */, 0 /* option */, 0x100 /* close signal */);
 	
 	/* windowが閉じられるまでの処理 */
 	for (;;) {
 		int retcode, sigcnt, signow;
 		/* シグナルを取得して保持 */
 		retcode = getsignal();
 		if (retcode == 0) {
 			/* シグナルがないので、シグナルが来るまでスリープ */
 			lib_waitsignal(0x0001, 0, 0);
 		} 
 		if ((retcode >= 0x1000)&&(retcode < 0x1050)) {
 			/* ライブラリに送るべきシグナルがきたのでリダイレクトする */
 			sigcnt = msgboxsignalc(retcode);
 			for (signow = 0; signow < sigcnt; signow++) {
 				/* パラメータが必要な場合はそれも連続で送信する */
 				msgboxsignalc(getparam());
 			}
 		}
 		if (retcode == 0x100) {
 			/* msgboxのwindowが閉じられたのでリターン値を取得してスリープ */
 			getparam();
 			for (;;) {
 				lib_waitsignal(0x0001, 0, 0);
 				getsignal();
 			}
 			
 		}
 	}
 }
 void initsignalbox()
 /* シグナルボックス初期化 */
 {
 	sig_ptr = signalbox0 = lib_opensignalbox(256, AUTO_MALLOC, 0, REWIND_CODE);
 	return;
 }
 
 const int getsignal()
 /* 0が返されたら、シグナルなし */
 {
 	int signal;
 	if (*sig_ptr == REWIND_CODE) {
 		/* REWINDシグナルを受け取った */
 		/* 直後の値の分だけシグナルを処理したことにして、ポインタを先頭に戻す */
 		lib_waitsignal(0x0000, *(sig_ptr + 1), 0);
 		sig_ptr = signalbox0;
 	}
 	signal = *sig_ptr;
 	if (signal != 0) {
 		sig_ptr++;
 		/* 1シグナル受け取ったことをライブラリに通知 */
 		lib_waitsignal(0x0000, 1, 0);
 	}
 	return signal;
 }
 
 int getparam()
 {
 	int param = *sig_ptr++;
 	lib_waitsignal(0x0000, 1, 0);
 	return param;
 }
※注意:このソースは終了していません。タスクリストに残っています。~
  多重起動しすぎると、ハングする場合があります。~
--非同期版のmsgboxは、これだけのコードを必要とします。
-日本語フォントを使用したい場合~
日本語フォントセットを準備する説明は長くなるのでここには書きません。~
[[APIリファレンス:http://com-nika.osask.jp/p0cref.html]]やintroシリーズを参考にして準備してください。~
--指定するのは''フォントセット''の先頭のスロット番号にb0を立てたものです。上記日本語の例を参考にしてください。
-スクリーンショット
#ref(hellocmb0.png)
~
* msgboxライブラリの仕様について [#a1917b55]
-msgboxのwindowは非同期で動作します。具体的にはmsgboxが表示されている間もアプリ側は別の処理をすることができます。
-非同期で動作していますが、同時に2つ以上のmsgboxをopenしてはいけません。内部バッファがリエントラントではありません。
-msgboxのwindowがオープンされていないときは、msgboxに関係するシグナルが来ないことが保証されます。
-必ずmsgboxcを呼び出す前に1度以上初期化ルーチン(msgboxsignalc)を呼び出して下さい。また、msgboxのwindowがオープンされている時に初期化しないで下さい。
-今のところ、windowの強制クローズはありません。
-現在のバージョンは2006年07月20日更新の1.0βです。
-以下にnaskから利用する場合の関数名とレジスタ値を示しておきます。
 msgboxinit
     edx     フォントセットのスロット番号とフラグ
     ecx     使用するシグナル番号の最小値
     ebx     msgboxのwindowのcaption(タイトルバーの文字列),ASCIIZ
     eax     予約
 ※)日本語のフォントセットを使用するには、フォントセットスロットのb0=1にして初期化する必要があります。
 
 msgbox
     ds:edx  表示する文字列(ASCIIZ)
     ebx     使用するwindowのスロット番号
     ecx     リターン値を通知する為のシグナル番号
     eax     オプション値(ボタンのタイプやアイコンの指定など)
 ※)シグナルを受信することでmsgboxのwindowが閉じられたことを検出してください。
 
 msgboxsignal
     eax     送信するシグナル値
             (このプロセスで各種の動作を実行します)
     リターン値(eax)
             このシグナルのパラメータの個数が返されます。
             パラメータの個数が0じゃない場合は、続くシグナルを続けて送信してください。
             パラメータシグナルの送信の場合、リターン値は不定となります。
~
----
* コメントらん [#a2446b9b]
#comment


[リロード]   [トップ] [一覧] [単語検索] [最終更新]   [最終更新のRSS]