* もくじ [#j36bdcd6]
-by [[nika]] (2006/07/20, Ver1.0β)~
//-もくじですが、リンクは使用できません。単にURLに"#"がつくだけです。~
----
#contents
* 自作ライブラリ OSASK用msgboxライブラリ の 詳細と使い方 [#h7517300]
-現在のバージョンは2008年03月11日更新の1.1です。
-以下にnaskから利用する場合の関数名とレジスタ値を示しておきます。
Windows互換のmsgboxライブラリです。~
Visual Basic の msgbox関数相当になっています。~
ただし、rightalignやsetforegroundなど、普段使わない機能は現在未実装です。~
ここに書いていない定数などは付属のドキュメントをご覧下さい。~

~
** 現在の最新版 [#o76542f6]
現在のバージョンは2008年03月11日更新の1.1です。~
ライブラリファイルのダウンロードは''[[自作LIBファイル]]''からダウンロードできます。~
以下のC言語サンプルソースも含まれています(再展開が必要です)。~

** 特徴 [#n7c50e77]
-長い文字列でwindowが大きくなっても、低レベル描画APIを使用することで実行時の省メモリを実現。
-英語/日本語モードをライブラリ初期化時に指定可能。
-非同期処理で、メインプログラムを停止せずに動作が可能。
-フルアセンブラによるライブラリでそこそこ高速(笑)。
-windowsより少し大きい48x48ピクセルの16色アイコン表示可能。
-16色アイコンも低レベル描画で解像度/色数を気にしないで使用可能。
-windowsとほぼ同等の操作性を確保。
** 改良すべき点 [#p04d6870]
-低レベルAPIによって描画されるため、時々ウィンドウ外に描画してしまう可能性がある。
-多重にmsgboxをオープンできない。
-文字に影などの装飾をすることができない。
-文字列が長さ(行数も含む)がデスクトップより大きくても画面外に描画してしまう。
-タイトルバーの長さがwindowの大きさより長い場合、あふれる部分はカットされてしまう。
-ボタンを押しているときのボタンの文字の位置がおかしい場合がある(笑)。
-Win95風ウィンドウ以外のOSASKに対応していない。
----
* msgboxの操作方法の説明 [#a96d0b51]
''(追記予定)''~
まだ書かれていません。~

* C言語から利用するには [#sf10e137]
** まずすること [#q902e414]
-msgboxライブラリの定義をincludeする~
利用するソースの最初の方へ以下のどちらかをリストを追加します。
--同じフォルダに置く場合(そのアプリケーションだけで利用する場合)
 #include "msgboxc.h"
--ライブラリ専用フォルダに置いている場合(全アプリケーションで利用可能にする場合)
 #include <msgboxc.h>

-makefileにライブラリの使用を記述する~
msgbox.libを取り込んでコンパイルしなければ実際のルーチンが組み込まれないので注意してください。~
makefileに以下の行を変更します。
            :
            :
 mallocsize = 512k
 mmarea     = 512k
 objs       = $(TARGET).obj msgbox.lib
 
 incpath    = ../z_tools/guigui00/
            :
            :
要はOBJSにmsgbox.libを追加するだけです。

** msgboxライブラリを初期化する [#bcf5856d]
最初に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 Emulator beta";
 msgboxinitc(0, 0x1000 /* signalbase */, 0xC0 /* fontset slot */, windowtitle /* titlestring */);
 /* 0x1000とかするより#define SIG_MSGBOX 0x1000などdefineして使った方がいいと思う。 */
これでmsgboxライブラリを使用する準備が整いました。次はmsgboxcを使用して実際にオープンしてみます。
その前に日本語フォントセットを0x3A0に定義した場合の例も以下に記します。
 /* msgboxライブラリを日本語環境用に初期化する */
 static char windowtitle[] = "DOS Emulator alpha";
 msgboxinitc(0, 0x1000 /* signalbase */, 0x3A1 /* fontset slot & used japanese flag */, \ 
             windowtitle /* titlestring */);
~
** 実際にmsgboxを使うとき(msgboxc関数とmsgboxsignalc関数) [#g92d4b71]
 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 */
 
 /* このソースの説明が"hellocmb0.txt"に書かれています */
 
 #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 */, windowtitle /* titlestring */);
 	
 	/* msgboxのwindowを開く */
 	msgboxc(0x200 /* window slot */, msgstr /* text */, 0 /* option */, 0x100 /* close */);
 	
 	/* 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は、これだけのコードを必要とします。
** 表示するボタンの種類を変更する [#dc0aee99]
(この機能はOSASK版msgboxライブラリ V1.1から使用可能です。)~
msgboxubc関数を使用するとmsgbox関数のオプション値にmgUserButtonを使用することで、表示するボタンの種類を変更することができます。~
特殊な使い方をしたい人向けの機能です。通常の用途では使用する必要はありません。~
~
この機能を使用するには、msgboxubc関数を呼び出します。
以下のフラグを合成(OR)してmsgboxubc関数を呼び出してください。
 void msgboxubc(int 7, int userbuttonflag);
     userbuttonflag
         表示させるボタンのフラグです。
         以下の定数をすべて足したものを指定します。
~
|ボタン|定数|
|OK|mgfOK|
|Cancel|mgfCancel|
|中止|mgfAbort|
|再試行|mgfRetry|
|無視|mgfIgnore|
|はい|mgfYes|
|いいえ|mgfNo|
~

** 日本語フォントを使用したい場合 [#hbeece3a]
日本語フォントセットを準備する説明は長くなるのでここには書きません。~
[[APIリファレンス:http://com-nika.osask.jp/p0cref.html]]やintroシリーズを参考にして準備してください。~
--指定するのは''フォントセット''の先頭のスロット番号にb0を立てたものです。上記日本語の例を参考にしてください。~
** スクリーンショット達 [#y023963e]
#ref(hellocmb0.png)
#ref(dosemu1o.png)
~
//* msgboxライブラリの仕様について [#a1917b55]
//-msgboxのwindowは非同期で動作します。具体的にはmsgboxが表示されている間もアプリ側は別の処理をすることができます。
//-非同期で動作していますが、同時に2つ以上のmsgboxをopenしてはいけません。内部バッファがリエントラントではありません。
//-msgboxのwindowがオープンされていないときは、msgboxに関係するシグナルが来ないことが保証されます。
//-必ずmsgboxcを呼び出す前に1度以上初期化ルーチン(msgboxsignalc)を呼び出して下さい。また、msgboxのwindowがオープンされている時に初期化しないで下さい。
//-今のところ、windowの強制クローズはありません。
* naskで利用するには [#zc1c7fbf]
参考までに、以下にファンクションを書いておきます。~
希望者がいれば、こちらにも説明やサンプルソースを書きますので、コメントらんでつっこんで下さい~。
 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じゃない場合は、続くシグナルを続けて送信してください。
             パラメータシグナルの送信の場合、リターン値は不定となります。
 
 msgboxub
     eax     固定値 '7' (予約)
     edx     表示するボタンの種類の論理和
 ※) これを呼び出した後はmsgboxのオプション値に0x07を指定すると表示するボタンの種類が変更されます。
~
* optionフィールドに指定できる値のリスト [#ja1bdc7b]
**オプション値のリスト [#s11f5678]
指定したい値をすべてOR演算したものを引数として与えてください。~
|種類|定数の名前|意味|実際の値|備考|
|ボタン|mgOKOnly|OKボタンのみ|0||
|ボタン|mgOKCancel|OKとキャンセルボタン|1||
|ボタン|mgAbortRetryIgnore|中止/再試行/無視ボタン|2||
|ボタン|mgYesNoCancel|はい/いいえ/キャンセルボタン|3||
|ボタン|mgYesNo|はい/いいえボタン|4||
|ボタン|mgUserButton|キャンセル|7|変更可|
|アイコン|mgCritical|致命的エラーなど|10h|"×"|
|アイコン|mgQuestion|ユーザへの問いかけ|20h|"?"|
|アイコン|mgExclamation|ユーザへの警告|30h|"!"|
|アイコン|mgInformation|ユーザへのアドバイス|40h|"i"|
|デフォ位置|mgButton1(~4)|デフォルトのカーソルのボタン位置(左から)|0x000~0x300||
|その他|mgApplicationModal|未対応|0||
|その他|mgSystemModal|未対応|0x1000||
|ボタン拡張|mgHelpButton|ヘルプボタンの追加|0x4000|現在はヘルプでも閉じてしまう|
|その他|mgSetForeground|強制的にフォーカスを奪う|0x8000|未対応|
|その他|mgRightAlign|右側に詰める|0x080000|未対応|
|その他|mgRtlReading|左右を逆にする|0x100000|未対応|
~
**リターン値のリスト [#xe0fe6ff]
msgboxのクローズ完了シグナル通知後のリターン値の意味です。
|戻り値|定数の名前|意味|
|1|mgOK|OKボタンが押された|
|2|mgCancel|Cancelボタンが押された|
|3|mgAbort|中止ボタンが押された|
|4|mgRetry|再試行ボタンが押された|
|5|mgIgnore|無視ボタンが押された|
|6|mgYes|はいボタンが押された|
|7|mgNo|いいえボタンが押された|
|0|-|ヘルプボタンが押された|
----
* コメントらん [#a2446b9b]
-HpzKtOapLRZBM -- ''kVvzQCbMR'' SIZE(10){2008/06/15 (日) 23:44:00}
-LTTAEQSYOLOABlo -- ''ayeJHfTNkxzC'' SIZE(10){2008/06/16 (月) 00:17:22}
-NbRfJTSQU -- ''KffubWXyGi'' SIZE(10){2008/06/16 (月) 00:18:23}

#comment

[Reload]   [New] [Edit] [Diff] [Upload]   [Front page] [List of pages] [Search] [Recent changes] [Backup]   [RSS of recent changes]