もくじ

  • by nika (2006/07/20, Ver1.0β)

自作ライブラリ OSASK用msgboxライブラリ の 詳細と使い方

  • 現在のバージョンは2008年03月11日更新の1.1です。
  • 以下にnaskから利用する場合の関数名とレジスタ値を示しておきます。 Windows互換のmsgboxライブラリです。
    Visual Basic の msgbox関数相当になっています。
    ただし、rightalignやsetforegroundなど、普段使わない機能は現在未実装です。
    ここに書いていない定数などは付属のドキュメントをご覧下さい。


現在の最新版

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

特徴

  • 長い文字列でwindowが大きくなっても、低レベル描画APIを使用することで実行時の省メモリを実現。
  • 英語/日本語モードをライブラリ初期化時に指定可能。
  • 非同期処理で、メインプログラムを停止せずに動作が可能。
  • フルアセンブラによるライブラリでそこそこ高速(笑)。
  • windowsより少し大きい48x48ピクセルの16色アイコン表示可能。
  • 16色アイコンも低レベル描画で解像度/色数を気にしないで使用可能。
  • windowsとほぼ同等の操作性を確保。

改良すべき点

  • 低レベルAPIによって描画されるため、時々ウィンドウ外に描画してしまう可能性がある。
  • 多重にmsgboxをオープンできない。
  • 文字に影などの装飾をすることができない。
  • 文字列が長さ(行数も含む)がデスクトップより大きくても画面外に描画してしまう。
  • タイトルバーの長さがwindowの大きさより長い場合、あふれる部分はカットされてしまう。
  • ボタンを押しているときのボタンの文字の位置がおかしい場合がある(笑)。
  • Win95風ウィンドウ以外のOSASKに対応していない。

msgboxの操作方法の説明

(追記予定)
まだ書かれていません。

C言語から利用するには

まずすること

  • 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ライブラリを初期化する

最初に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関数)

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;
}

※注意:このソースは終了していません。タスクリストに残っています。
  多重起動しすぎると、ハングする場合があります。

表示するボタンの種類を変更する

(この機能はOSASK版msgboxライブラリ V1.1から使用可能です。)
msgboxubc関数を使用するとmsgbox関数のオプション値にmgUserButtonを使用することで、表示するボタンの種類を変更することができます。
特殊な使い方をしたい人向けの機能です。通常の用途では使用する必要はありません。

この機能を使用するには、msgboxubc関数を呼び出します。 以下のフラグを合成(OR)してmsgboxubc関数を呼び出してください。

void msgboxubc(int 7, int userbuttonflag);
    userbuttonflag
        表示させるボタンのフラグです。
        以下の定数をすべて足したものを指定します。


ボタン定数
OKmgfOK
CancelmgfCancel
中止mgfAbort
再試行mgfRetry
無視mgfIgnore
はいmgfYes
いいえmgfNo


日本語フォントを使用したい場合

日本語フォントセットを準備する説明は長くなるのでここには書きません。
APIリファレンスやintroシリーズを参考にして準備してください。

  • 指定するのはフォントセットの先頭のスロット番号にb0を立てたものです。上記日本語の例を参考にしてください。

スクリーンショット達

hellocmb0.png
dosemu1o.png


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じゃない場合は、続くシグナルを続けて送信してください。
            パラメータシグナルの送信の場合、リターン値は不定となります。

msgboxub
    eax     固定値 '7' (予約)
    edx     表示するボタンの種類の論理和
※) これを呼び出した後はmsgboxのオプション値に0x07を指定すると表示するボタンの種類が変更されます。


optionフィールドに指定できる値のリスト

オプション値のリスト

指定したい値をすべてOR演算したものを引数として与えてください。

種類定数の名前意味実際の値備考
ボタンmgOKOnlyOKボタンのみ0
ボタンmgOKCancelOKとキャンセルボタン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未対応


リターン値のリスト

msgboxのクローズ完了シグナル通知後のリターン値の意味です。

戻り値定数の名前意味
1mgOKOKボタンが押された
2mgCancelCancelボタンが押された
3mgAbort中止ボタンが押された
4mgRetry再試行ボタンが押された
5mgIgnore無視ボタンが押された
6mgYesはいボタンが押された
7mgNoいいえボタンが押された
0-ヘルプボタンが押された

コメントらん

  • HpzKtOapLRZBM -- kVvzQCbMR 2008/06/15 (日) 23:44:00
  • LTTAEQSYOLOABlo -- ayeJHfTNkxzC 2008/06/16 (月) 00:17:22
  • NbRfJTSQU -- KffubWXyGi 2008/06/16 (月) 00:18:23

コメントお名前NameLink

[Reload]   [New] [Edit] [Unfreeze] [Diff] [Upload]   [Front page] [List of pages] [Search] [Recent changes] [Backup]   [RSS of recent changes]
Last-modified: 2008/06/16 (Mon) 00:18:14 (6026d)