* もくじ [#j36bdcd6] -by [[nika]] (2006/07/20, Ver1.0β)~ -もくじですが、リンクは使用できません。単にURLに"#"がつくだけです。~ ---- #contents * 自作ライブラリ OSASK用msgboxライブラリ の 詳細と使い方 [#h7517300] -現在のバージョンは2006年07月20日更新の1.0βです。 -以下にnaskから利用する場合の関数名とレジスタ値を示しておきます。 Windows互換のmsgboxライブラリです。~ Visual Basic の msgbox関数相当になっています。~ ただし、rightalignやsetforegroundなど、普段使わない機能は現在未実装です。~ ここに書いていない定数などは付属のドキュメントをご覧下さい。~ ~ ** 現在の最新版 [#o76542f6] 現在のバージョンは2006年07月20日更新の1.0βです。~ ライブラリファイルのダウンロードは''[[自作LIBファイル]]''からダウンロードできます。~ 以下のC言語サンプルソースも含まれています(再展開が必要です)。~ ** 特徴 [#n7c50e77] -長い文字列でwindowが大きくなっても、低レベル描画APIを使用することで実行時の省メモリを実現。 -英語/日本語モードをライブラリ初期化時に指定可能。 -非同期処理で、メインプログラムを停止せずに動作が可能。 -フルアセンブラによるライブラリでそこそこ高速(笑)。 -windowsより少し大きい48x48ピクセルの16色アイコン表示可能。 -16色アイコンも低レベル描画で解像度/色数を気にしないで使用可能。 -windowsとほぼ同等の操作性を確保。 ** 改良すべき点 [#p04d6870] -低レベルAPIによって描画されるため、時々ウィンドウ外に描画してしまう可能性がある。 -多重にmsgboxをオープンできない。 -文字に影などの装飾をすることができない。 -文字列が長さ(行数も含む)がデスクトップより大きくても画面外に描画してしまう。 -タイトルバーの長さがwindowの大きさより長い場合、あふれる部分はカットされてしまう。 -ボタンを押しているときのボタンの文字の位置がおかしい場合がある(笑)。 ---- * 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 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関数) [#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は、これだけのコードを必要とします。 ** 日本語フォントを使用したい場合 [#hbeece3a] 日本語フォントセットを準備する説明は長くなるのでここには書きません。~ [[APIリファレンス:http://com-nika.osask.jp/p0cref.html]]やintroシリーズを参考にして準備してください。~ --指定するのは''フォントセット''の先頭のスロット番号にb0を立てたものです。上記日本語の例を参考にしてください。~ ** スクリーンショット達 [#y023963e] #ref(hellocmb0.png) #ref(dosemu1.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じゃない場合は、続くシグナルを続けて送信してください。 パラメータシグナルの送信の場合、リターン値は不定となります。 ~ * optionフィールドに指定できる値のリスト [#ja1bdc7b] **オプション値のリスト [#s11f5678] 指定したい値をすべてOR演算したものを引数として与えてください。~ |種類|定数の名前|意味|実際の値|備考| |ボタン|mgOKOnly|OKボタンのみ|0|| |ボタン|mgOKCancel|OKとキャンセルボタン|1|| |ボタン|mgAbortRetryIgnore|中止/再試行/無視ボタン|2|| |ボタン|mgYesNoCancel|はい/いいえ/キャンセルボタン|3|| |ボタン|mgYesNo|はい/いいえボタン|4|| |アイコン|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] -None -- ''None'' SIZE(10){2007/05/12 (土) 22:30:08} -test -- 名無しさん SIZE(10){2007/10/11 (木) 16:42:46} -test2 -- 名無しさん SIZE(10){2007/10/11 (木) 17:12:27} -test4 -- 名無しさん SIZE(10){2007/10/11 (木) 17:15:08} #comment