オブジェクトカラーでウィンドウを塗りつぶす

Windows XP などのOSで、Cls 1 を実行すると、黒っぽい色で塗りつぶされてため、

別途標準色を取得して、塗りつぶすプログラムです。

ソース

#module

#deffunc Normalcls

clrobj 0,-1

syscolor 15

boxf

pos 0,0

color 0,0,0

return

#global

上記コードの解説

#module ~ #global 間がモジュール空間となり、

メインプログラムが実行されている空間とはまた別の空間となります。

clrobj でオブジェクトをすべて削除し、

syscolor 15 で、システムカラーを取得して設定します。

boxf で設定された色で画面をすべて塗りつぶします。

pos 0,0 で、次にオブジェクトが書き始められるのが 0,0 になるように戻します

color 0,0,0 で次の色を黒に設定します

以上のようなことが実行されるようになっております。

使用方法

プログラムコード内で、

NormalCls

と書いていただければ実行されます。

拡張子を自動でつける。

ダイアログボックスなどで保存先を指定したときに、拡張子が指定されないことがあります。

そのときに、拡張子の有無を判定し、なければ後につけるプログラムとなります。

ソース

// サンプルプログラム

dialog "txt",17,"テキストファイル"

if stat=0:end:else:name=refstr

// ここまで

if instr(name,0,".")=-1:name=name+".txt"

//サンプルプログラム

mes name

//ここまで

上記コードの解説

このコードで重要となっているのが、

if instr(name,0,".")=-1:name=name+".txt"

というコードになっています。

まず、 if instr(name,0,".")=-1

という構文で、 instr (文字列検索命令) で検索して、結果が「ない」(-1)であれば拡張子を追加し、

「ある」(見つかった場所が入る = -1 以外)であれば、そのままにする

という構文になっています。

拡張子は自由に設定でき、設定を変えたから内容が変わるといったことはありませんので、

自由に ".txt" の部分を書き換えて拡張子を設定してください。

文字を大文字、小文字でそろえる

アルファベットでは、同じ文字でも「大文字」と「小文字」の二種類があり、

検索などをするときには、このような部分を吸収する必要がある場合があります。

そのようなときに、どちらか一方にあわせてしまおうというものです。

ソース

#uselib "USER32.DLL"

#func charLowerA "CharLowerA" sptr

#func charUpperA "CharUpperA" sptr

上記コードの解説

このコードでは、

USER32.dll というWindows が標準で持っているファイルの中に含まれる機能を使って、

処理をするために、HSP側にそれを使うんだということを宣言するものです。

使用方法

内容は変数 DATA に入っているものとすると、

小文字にする場合

CharLowerA Data

大文字にする場合

CharUpperA Data

くぼんだオブジェクトを作成

一つ奥に入ったような、

ボタンを押し込んだときのような状態を擬似的に作るものです。

ソース

#module "objbox_module"

#uselib "USER32.DLL"

#func global DrawEdge "DrawEdge" sptr,sptr,sptr,sptr

#deffunc objbox int v1,int v2,int v3,int v4,int v5

#define BDR_RAISEDOUTER 0x0001 //辺の外側を隆起

#define BDR_SUNKENOUTER 0x0002 //辺の外側を陥没

#define BDR_RAISEDINNER 0x0004 //辺の内側を隆起

#define BDR_SUNKENINNER 0x0008 //辺の内側を陥没

#define BF_RECT 0xF

dim rect,4

rect = v1,v2,v3,v4

DrawEdge hdc, varptr(rect), BDR_SUNKENINNER | BDR_SUNKENOUTER, BF_RECT

if v5=1:redraw 1 return

#global

上記コードの解説

#module ~ #Global がモジュール空間になります。

その中で、くぼんだオブジェクトを作成する命令がUSER32.dll 内にありますので、

それを使うと #uselib と #func 命令で宣言します。

そのあと、RECT 構造体という、場所を指定するものに値を代入し、

命令を呼んで (DrawEdge~) オブジェクトを書きます。

使用方法

Objbox x1,y1,x2,y2

という形で、 objbox に続いて、

書き始める場所 (x1,y1) を指定し、そのあとに続いて

書き終わる場所 (x2,y2) を指定し、その指定された中に描画されます。

なお、ここで作成されたものは、別に特殊なものでも何者でもなく、

普通にmes 命令などで上からかけるものですので、別段抵抗もなく使えるかと思います。

録音をする

HSPで変数内に直接録音をしていこうというものです。

レベルメータといったソフトは、ここで紹介されているような方法を使用して作成されています

1.#Func 命令を使っての命令の登録

まず、録音をするために、 Windows に標準で付いてくるファイルの中の

winmm.dll というファイルを使用します。

「その中のこの命令を使うよ」ということをHSP側に伝えてやる処理が必要となります。

ソース

#uselib "winmm.dll"

#func global waveInOpen "waveInOpen" int,int,int, int,int,int

#func global waveInPrepareHeader "waveInPrepareHeader" int,int,int

#func global waveInReset "waveInReset" int

#func global waveInStart "waveInStart" int #func global waveInStop "waveInStop" int

#func global waveInAddBuffer "waveInAddBuffer" int,int,int

#func global waveInUnprepareHeader "waveInUnprepareHeader" int,int,int

#func global waveInClose "waveInClose" int

解説

#uselib 命令が、どの拡張機能の入ったファイルを使うのか。ということを指定し、

#func 命令が、その中の ~ という機能を利用しますという意味を持っていて、

二つペアで使います。

2.WaveFormatex 構造体の構築

次に、 「WaveFormatex 構造体」というものを作成します。

この中には主に、

「ステレオなのかモノラルなのか (チャンネル数)」

「一つの値の記録に何ビット使うか (ビットレート)」

「一秒間に何回記録するか (サンプリング周波数)」

という録音の根本の設定をしていくものになります。

ソース

ch=2 //チャンネル数

freq=22050 //サンプリング周波数

bitrate=8 //ビットレート

dim Waveformatex,5 //構造体のサイズを確保

Waveformatex(0)=1+(ch<<16)

Waveformatex(1)=freq

Waveformatex(2)=freq*bitrate/8*ch

Waveformatex(3)=bitrate/8*ch|(bitrate<<16)

Waveformatex(4)=0

解説

ch= freq= bitrate= でそれぞれ、

チャンネル数、サンプリング周波数、ビットレート を指定しています。

チャンネル数  1=モノラル 2=ステレオ

サンプリング周波数 電話 = 11025 ラジオ = 22050 CD=44100

ビットレート 8=1バイト=peek 等で読み書き 16=2バイト=wpeek 等で読み書き

あまり推奨はされていませんが、サンプリング周波数など、決まった値というものはありませんので、

わかっている場合は自由に設定してもかまいません。

そして、代入された値は計算によって値が出され、Waveformatex 構造体に代入されます。

参考までに・・ MSDN - Waveformatex

3.録音準備

実際に録音をするまでの直前の設定をしていきます。

2で設定した内容は、処理全体に関わってくるものですが、

これから設定していくものは、個別の設定の内容になります。

ソース

SAMPLES=640

BUFFERS=4  //バッファ数

BUFLEN=SAMPLES*ch*bitrate/8  //変数の確保すべきサイズの計算

dim wavehdr,8,BUFFERS  //wavehdr構造体の確保

dim buf,BUFLEN,BUFFERS  //記憶変数の確保

dim hwi,50  //ハンドルが代入される変数の確保

waveInOpen varptr(hwi),-1,varptr(Waveformatex),hwnd,0,$00010000 //デバイスを開く

if stat!0: dialog "waveInOpenに失敗しました。error:"+stat,1 : end //エラーがあれば終了

repeat BUFFERS

wavehdr.0.cnt = varptr(buf.0.cnt)

wavehdr.1.cnt =BUFLEN

waveInPrepareHeader hwi,varptr(wavehdr.0.cnt),32 //バッファを初期化

waveInAddBuffer hwi,varptr(wavehdr.0.cnt),32 //バッファを登録

loop

解説

各機能の説明はコード中のコメントをみていただければわかるのですが、

ここでは、どの変数に実際の内容を記録していくかというものを指定していきます。

まず、上から見ていきますと、SAMPLES には、サンプル数を指定します。

これは、その変数にはいくつ分のデータを入れるかということを指定します。

その変数に指定された数だけ記録されたら、録音処理は終了 ということになります。

次に、BUFFERS に、管理するバッファの数を指定します。

これは、この録音関係の命令とは関係なく、本サンプル上での独自設定となります。

録音を連続して行うためには、事前にいくつかの変数を登録しておく必要があります。

ここの設定は、連続していくつの変数を登録するかと言うことを指定します。

なお、数を多くすると、安定しますがメモリを食い、少なくすると不安定ですがメモリをあまり使いません。

設定された値は、自動的に計算されて構造体に代入されます。

MSDN - waveInOpen

MSDN - waveInPrepareHeader

MSDN - waveInAddBuffer

MSDN(US) - WAVEHDR

4.録音を開始

ここまで長々と設定をしてきましたが、やっと録音開始となります。

ここでは、録音を開始してから、録音を続ける方法までを解説します。

ソース

waveInStart hwi //録音を開始する

oncmd gosub *GET,$000003C0 //割り込み

onexit *EXIT //「5」の後始末のための割り込み

Stop

*GET

dupptr whdr,lparam,32 //クローンメモリを作成

dupptr wdata, whdr.0, BUFLEN/4*4+4 //さらにクローンメモリを作り、バッファを取り出す

waveInAddBuffer wparam,lparam,32 //バッファを追加

Return

解説

まず、 waveInStart で、録音を開始し始めます。

しかし、録音を開始しただけでは録音が終了した変数もわかりませんし、第一完了したかもわかりません

この waveInStart というものは、終了したら MM_WIM_DATA というものを返します。

(MM_WIM_DATA = $000003C0)

そして、録音が終了したら連続して記録できるようにメモリをもう一度指定してやります。

取得が終了したら、 *GET 内にジャンプしますので、 wdata から直接データを取り出してお使いください。

MSDN - waveInStart

5.後始末。

使ったら後始末をしてやる必要があります。

ソース

*EXIT

waveInReset hwi

waveInClose hwi

End

解説

waveInReset で、登録してある変数をすべていったん外し、

waveInClose で、録音処理はすべて終わったよ。と言ってやります。

この処理をしないと、エラーが発生してしまうために、必ず行う必要があります

MSDN - waveInReset

MSDN - waveInClose

最後に。

今回の解説でわかりづらかったと思いますので、サンプルプログラムを掲載しておきます。

このプログラムをみながらいじってみると直感的にわかると思います

SAMPLE.HSP