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を使うとき(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は、これだけのコードを必要とします。