The basic technical notebook about medical electronic calculator (MedicalCalculator).
(Copyright (C) Hee Cheong Lee All Rights Reserved.)
Hee Cheong Lee's Medical Memories


医療領域の計算に特化した計算機プログラム「医電卓(MedicalCalculator)」に関する基本的な技術ノートです。

☆変数の解説

AnsiString rtis="",ais="",ars="",astr_x="",
cmode="",mcmode="";
bool bcmode=0;

double rtid=0,ard=0;

rtis : キーボードから入力された値を格納する文字型変数
ais : テキストボックスに表示されているデータを格納する文字型変数
ars : 累積された計算結果を文字型データとして格納
rtid : キーボードから入力された値を格納する浮動小数点型変数
ard : テキストボックスに表示されているデータを格納する浮動小数点型変数
cmode : 四則演算の種類を格納する文字型変数
mcmode : 医学関数の計算モードを格納する文字型変数
bcmode : 直前に四則演算子が入力された事を判定する変数
(直前に四則演算子が入力された場合はテキストボックスの表示を次回入力で初期化する必要がある)

☆関数の解説

void __fastcall TForm1::FormKeyDown関数はシステムメッセージキューからのWM_KEYDOWNメッセージをキャッチして
ユーザーからどのキーが入力されたかを場合分けしたあとvoid calculator_method関数に受け渡します。
void calculator_method関数は医電卓のメインルーチンで、void __fastcall TForm1::FormKeyDown関数から引数を受けて様々なメソッドを行います。

void calculator_method(int int_input) // 医電卓のメインルーチン。void __fastcall TForm1::FormKeyDown関数から引数を受けてメソッドを場合分けします。
{
bool fx=0;

switch(int_input) // calculator_method(int int_input) に渡された引数で場合分け。
{

ais=Form1->Edit1->Text; // テキストボックスのデータをaisに格納。

case 42: //(*) // ユーザーから「*」の入力があった場合の処理。

if (mcmode!="") { // 医学関数計算処理中の場合。
return; // 医学関数計算処理中の場合は何もしないままここで関数終了。
}

// 医学関数計算処理中でない場合は以下の処理を続行。

try {

bcmode=1;

if (cmode.operator !=("")) { // 既にユーザーが一回以上四則演算子を入力している場合。

if (cmode=="+") { //cmodeに格納されているデータが「+」の場合の処理。
rtid=ais.ToDouble(); // 文字型変数を浮動少数型変数に変換。
ard+=rtid; // 演算処理。
}else if (cmode=="-") { //cmodeに格納されているデータが「-」の場合の処理。
rtid=ais.ToDouble();
ard-=rtid;
}
else if (cmode=="*") { //cmodeに格納されているデータが「*」の場合の処理。
rtid=ais.ToDouble();
ard*=rtid;
}
else if (cmode=="/") { //cmodeに格納されているデータが「/」の場合の処理。
rtid=ais.ToDouble();
ard/=rtid;
}

ais=""; // aisを初期化(今後の新たな計算のためにここでaisを初期化する必要がある)。
Form1->Edit1->Text=DoubleToString(ard); // テキストボックスに演算結果を表示。
cmode="*";

}else { // ユーザーが四則演算子を入力していない場合。
rtid=ais.ToDouble();
ard=rtid;
ais="";
cmode="*"; // 計算モードを「*」に設定(cmodeに「*」を代入)。
}
} catch (...) {

}

break;


break;
case 43: //(+) // ユーザーから「+」の入力があった場合の処理。

<・・・・・途中省略・・・・・>

//ユーザーから「BackSpace」または「Delete」キーの入力を受けたときの処理。

case 1008:
case 46:

Form1->Edit1->Text=
(Form1->Edit1->Text.Delete(Form1->Edit1->Text.Length(),1)); // テキストボックスの表示から一文字削除。
astr_x=astr_x.Delete(astr_x.Length(),1);
break;

case 100:
Form1->Edit1->Text=Form1->Edit1->Text+".";
astr_x+=".";

break;

// 「0」から「9」の数字の入力があった場合の処理。

case 0:
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
case 8:
case 9:

rtis=IntToStr(int_input);

if (Form1->Edit1->Text=="0"||bcmode==1) { // テキストボックスの値が「0」の時とbcmodeが「1」の時はテキストボックスの値を初期化して表示。
Form1->Edit1->Text=rtis;
astr_x=rtis;
bcmode=0;
}else // それ以外の場合は右方向に入力値を追加。
{
Form1->Edit1->Text=Form1->Edit1->Text+rtis;
astr_x+=rtis;
}

break;

case 1000:


break;

default:

break;

}

}

//void __fastcall TForm1::FormKeyDown関数はシステムメッセージキューからのWM_KEYDOWNメッセージをキャッチして
//ユーザーからどのキーが入力されたかを場合分けしたあとvoid calculator_method関数に受け渡します。

void __fastcall TForm1::FormKeyDown(TObject *Sender, WORD &Key,TShiftState Shift)
{
Form1->Button_ENTER->SetFocus();
//ShowMessage(int(Key));
switch(Key)
{

case VK_MULTIPLY: // ユーザーから「*」の入力を受けた場合。
calculator_method(42); // calculator_method関数に「42」を受け渡す。
break;

case VK_ADD: // ユーザーから「+」の入力を受けた場合。
calculator_method(43);
break;

case VK_SUBTRACT: // ユーザーから「-」の入力を受けた場合。
calculator_method(45);
break;

case VK_DIVIDE: // ユーザーから「/」の入力を受けた場合。
calculator_method(47);
break;

case VK_DECIMAL:// ユーザーから「.」の入力を受けた場合。
calculator_method(100);
break;

case 190:
calculator_method(100);
break;

case 8: // ユーザーから「BackSpace」の入力を受けた場合。
calculator_method(1008);
break;

case 48: // ユーザーから「0」の入力を受けた場合。
calculator_method(0);
break;

case 49: // ユーザーから「1」の入力を受けた場合。
calculator_method(1);
break;

case 50:// ユーザーから「2」の入力を受けた場合。
calculator_method(2);
break;

case 51:// ユーザーから「3」の入力を受けた場合。
calculator_method(3);
break;

case 52:// ユーザーから「4」の入力を受けた場合。
calculator_method(4);
break;

case 53:// ユーザーから「5」の入力を受けた場合。
calculator_method(5);
break;

case 54:// ユーザーから「6」の入力を受けた場合。
calculator_method(6);
break;

case 55:// ユーザーから「7」の入力を受けた場合。
calculator_method(7);
break;

case 56:// ユーザーから「8」の入力を受けた場合。
calculator_method(8);
break;

case 57:// ユーザーから「9」の入力を受けた場合。
calculator_method(9);
break;

case 46:// ユーザーから「Delete」の入力を受けた場合。
calculator_method(46);
break;

default:

Key=0;

calculator_method(1000);

break;

}

}

//void __fastcall TForm1::Button_ENTERClick(TObject *Sender)関数は医学関数処理を担う部分です。
//注目すべき部分は、「ENTER」入力の状態と変数に入力された状態を判別して処理を変化させている部分です。


void __fastcall TForm1::Button_ENTERClick(TObject *Sender)
{

if (mcmode=="BMI") { //「BMI」を計算する場合。mcmodeにはvoid __fastcall TForm1::BMI1Click(TObject *Sender)関数によって「BMI」が代入されている。

Form1->Edit1->Text=Form1->Edit1->Text+"→";

if (db_height==0) {// db_heightに値がない場合は入力値をdb_heightに代入して関数終了。
db_height=astr_x.ToDouble();
astr_x="";
return;// 関数終了。
}

if (db_weight==0) {// db_heightに既に値が代入されている場合は関数は終了せずにdb_weightに値が代入される。
db_weight=astr_x.ToDouble();
astr_x="";
Form1->Label1->Caption="BMI:"+astr_result;
Form1->Edit1->Text=
FloatToStr(db_weight/pow(db_height/100,2));// 「BMI」を計算。

p_reset_var();// 変数を初期化。

return;
}

} //

if (mcmode=="GFR(MDRD:MAN:JAPANESE)") { // 「GFR」を計算する場合。

Form1->Edit1->Text=Form1->Edit1->Text+"→";

if (db_age==0) {
db_age=astr_x.ToDouble();
astr_x="";
return;
}

if (db_serum_creatinine==0) {
db_serum_creatinine=astr_x.ToDouble();
astr_x="";
Form1->Label1->Caption=
"GFR(MDRD:MAN:JAPANESE):"+astr_result;
Form1->Edit1->Text=
FloatToStr(175*pow(db_serum_creatinine,-1.154)*pow(db_age,-0.203)*0.741);// 「GFR」を計算。

p_reset_var();

return;
}

} //

if (mcmode=="GFR(MDRD:WOMAN:JAPANESE)") { //

Form1->Edit1->Text=Form1->Edit1->Text+"→";

if (db_age==0) {
db_age=astr_x.ToDouble();
astr_x="";
return;
}

if (db_serum_creatinine==0) {
db_serum_creatinine=astr_x.ToDouble();
astr_x="";
Form1->Label1->Caption=
"GFR(MDRD:WOMAN:JAPANESE):"+astr_result;
Form1->Edit1->Text=
FloatToStr(175*pow(db_serum_creatinine,-1.154)*pow(db_age,-0.203)*0.741*0.742);「GFR」を計算。

p_reset_var();

return;
}

} //

}

//---------------------------------------------------------------------------

//以下の関数群は右クリックメニューにて選択された入力に応じてmcmode変数に値をセットします。

void __fastcall TForm1::BMI1Click(TObject *Sender)
{
p_reset();
mcmode="BMI"; // mcmode変数に「"BMI"」を代入。
Form1->Label1->Caption="BMI" ;
Form1->Label2->Caption="("+a_height+"→"+a_weight+")";
astr_x="";
Form1->Button_ENTER->SetFocus();
}

//---------------------------------------------------------------------------

void __fastcall TForm1::MDRDman1Click(TObject *Sender)
{
p_reset();
mcmode="GFR(MDRD:MAN:JAPANESE)";
Form1->Label1->Caption="GFR(MDRD:MAN:JAPANESE)";
Form1->Label2->Caption="("+a_age+"→"+a_scr+")";
astr_x="";
Form1->Button_ENTER->SetFocus();
}
//---------------------------------------------------------------------------

void __fastcall TForm1::MDRDwoman1Click(TObject *Sender)
{
p_reset();
mcmode="GFR(MDRD:WOMAN:JAPANESE)";
Form1->Label1->Caption="GFR(MDRD:WOMAN:JAPANESE)" ;
Form1->Label2->Caption="("+a_age+"→"+a_scr+")";
astr_x="";
Form1->Button_ENTER->SetFocus();
}
//---------------------------------------------------------------------------

//void __fastcall TForm1::Button_EQUALClick(TObject *Sender)関数は「=」ボタンが入力された時に発動するイベントハンドラ関数です。
//void calculator_method(int int_input)関数の四則演算入力時の処理に非常に良く似たアルゴリズムになっています。


void __fastcall TForm1::Button_EQUALClick(TObject *Sender)
{
if (mcmode!="") {
return;
}

try {

ais=Form1->Edit1->Text;
bcmode=1;

if (cmode.operator !=("")) {

if (cmode=="+") {
rtid=ais.ToDouble();
ard+=rtid;
}else if (cmode=="-") {
rtid=ais.ToDouble();
ard-=rtid;
}
else if (cmode=="*") {
rtid=ais.ToDouble();
ard*=rtid;
}
else if (cmode=="/") {
rtid=ais.ToDouble();
ard/=rtid;
}

ais="";
Form1->Edit1->Text=DoubleToString(ard);
cmode="+";

}else {
rtid=ais.ToDouble();
ard=rtid;
ais="";
cmode="";


}
} catch (...) {
p_reset();

}

cmode="";

}