TOP Column Menu 戻る
WideStudio かんどころ(5)
WideStudioによる無作法なC++  2003/05/03

第五回 本格的カレンダーのプログラムを作る
カレンダーの論理(2)

さて、前回で画面が完成したことになりました。
さて前回の カレンダーの論理(1) で一番難しい日移動ボタンの配置論理を学びました。Ⅱの画面の⑤の配置です。


次にこのカレンダープロ部ラムの決め事を作っておきましょう。各々の配列グループではそのオブジェクト(ボタンやラベル)は全て同じ大きさにするということです。次に、全体の大き を決定するのは日付ボタンの配列番号[0]だとします。
つまり部品の大きさについては以下のとおりとします。
もう一つ位置の決定ですが、日移動のボタンの位置についての算出方法はすでに前回で、説明してあります。ここでは全ての部品の位置について確認してみましょう。
部品の位置を決定するプロパティの変数名と取得関数と設定関数については下の表のとおりです。
取得関数 設定関数
上の位置 getProperty(WSNy) setProperty(WSNy,data)
左の位置 getProperty(WSNx) setProperty(WSNx,data)
高さ getProperty(WSNheight) setProperty(WSNheight,data)
getProperty(WSNwidth) setProperty(WSNwidth,data)
表示文字列 getProperty(WSNlabelString) getProperty(WSNlabelString,ttl)
(注意) dataは設定数字でttlは設定文字列です。
実プログラムではこのプロパティをポイントしてやらなければなりません。
つまり ddbtn[0]->setProperty(WSNx,0)みたいにです。
各オブジェクトの位置設定と関数
下の関数は一括して取り扱うファイルのなかで設定しておきます。そのファイルはオブジェクトを取り扱いますので以下のinclude とexternを記入してあることとします。

#include<string.h>
#include<stdlib.h>
#include <WSCvlabel.h>
#include <WSCvbtn.h>
  extern WSCvlabel* newvlab_000;
  extern WSCvbtn** ddbtn;
  extern WSCvbtn** mmbtn;
  extern WSCvbtn** mvyy;
  extern WSCvlabel** yb;
  extern WSCvlabel* newwin000;

// 以下関数
int set_ttl(int f_wd);
int set_day(int offset_yobi,int max_day,int sty,int wd);
int set_month(int sty,int wd);
int set_yobi(int sty,int wd);
void set_ttlString(char *ttl);
void set_form(int wd,int ht);
②の前年移動ボタンの位置は上の位置はゼロ、左の位置はゼロと言う風にしておきます。
①の表示ラベルの位置は上の位置はゼロ、左の位置前年移動ボタン(yymb[0])の横幅です。厳密にはyymv[0]の左位置+yymv[0]の幅ですが、左位置はゼロに設定しておきましたね。
引数
f_wd = このフォームウィンドウの横幅
帰り値=次のy軸の位置となります。

int set_ttl(int f_wd)
{
    int i,ht;
    char *mvyy_ttl[]={"<<前年移動","次年移動>>",NULL};
    newvlab_000->setProperty(WSNwidth,f_wd-((int)(mvyy[0]->getProperty(WSNwidth)) )*2);
    newvlab_000->setProperty(WSNx,(int)(mvyy[0]->getProperty(WSNwidth)));
    newvlab_000->setProperty(WSNy,0);
    mvyy[1]->setProperty(WSNwidth,(int)(mvyy[0]->getProperty(WSNwidth)));
    ht=(int)(mvyy[0]->getProperty(WSNheight));
    mvyy[0]->setProperty(WSNx,0);
    mvyy[1]->setProperty(WSNx,f_wd-(int)(mvyy[1]->getProperty(WSNwidth)) );
    for(i=0;i<2;i++){
        mvyy[i]->setProperty(WSNy,0);
        mvyy[i]->setProperty(WSNheight,ht);
        mvyy[i]->setProperty(WSNlabelString,mvyy_ttl[i]);
    }
    return(ht);
}
③の月移動ボタンについては2列にしましたので、⑤の日移動ボタン(ddbtn[])と同じ論理を使います。ただ、日移動ボタンと違い曜日などによって移動することはありませんの 単純です。
引数
sty = mmbtn[0]のy軸の位置
wd = このボタンの横幅
帰り値=次のy軸の位置となります。

int set_month(int sty,int wd)
{
    int i,x,y;
    char dmy[6];
    int ht;
    ht=(int)(mmbtn[0]->getProperty(WSNheight));
    for(i=0;i<12;i++){
        x = wd * (i % 6);
        y = sty + ht * (i /6);
        mmbtn[i]->setProperty(WSNheight,ht);
        mmbtn[i]->setProperty(WSNwidth,wd);
        mmbtn[i]->setProperty(WSNx,x);
        mmbtn[i]->setProperty(WSNy,y);
        sprintf(dmy,"%02d月",i+1);
        mmbtn[i]->setProperty(WSNlabelString,dmy);
    }
    return((sty+ht*2));
}
④の曜日表示用ラベルは一列です。帰り値は次のy軸の位置となります。
引数
sty = yb[0]のy軸の位置
wd = このボタンの横幅
帰り値=次のy軸の位置となります。

int set_yobi(int sty,int wd)
{
    char *yb_ttl[]={
    "日","月","火","水","木","金","土",NULL
    };
    int i,x,ht;
    ht=(int)(yb[0]->getProperty(WSNheight));
    for(i=0;i<7;i++){
        x=i*wd;
        yb[i]->setProperty(WSNheight,ht);
        yb[i]->setProperty(WSNwidth,wd);
        yb[i]->setProperty(WSNx,x);
        yb[i]->setProperty(WSNy,sty);
        yb[i]->setProperty(WSNlabelString,yb_ttl[i]);
    }
    return((sty+ht));
}
⑤今回のプログラムの山場で前回の説明は大部分がこの部分の考え方でした。
引数
offset_yobi = この月の1日の曜日をあらわします。
max_day = この月の最大日を表します。つまり、31,30,29,28の何れかの数字ですね。
sty = yb[0]のy軸の位置
wd = このボタンの横幅
帰り値=次のy軸の位置となります。(この場合はフォームウィンドウの高さを表します。)

int set_day(int offset_yobi,int max_day,int sty,int wd)
{
    int i,x,y;
    char ttl[6];
    int ht;
    ht=(int)(ddbtn[0]->getProperty(WSNheight));
    for(i=0;i<max_day;i++){
        sprintf(ttl,"%02d日",i+1);
        y=((i+offset_yobi)/7)*ht+sty;
        x=((i+offset_yobi) % 7)*wd;
        ddbtn[i]->setProperty(WSNwidth,wd);
        ddbtn[i]->setProperty(WSNx,x);
        ddbtn[i]->setProperty(WSNy,y);
        ddbtn[i]->setProperty(WSNlabelString,ttl);
    }
    if(max_day<31){ //mx_dayが31日より小さい時は対象外の日を隠す
        for(i=max_day;i<31;i++) ddbtn[i]->setProperty(WSNvis,False);
    }
    return(y+ht);
}
カレンダー全体の大きさを設定する関数です
引数
wd = カレンダーの横幅
ht = カレンダーの高さ(縦幅)
関数 void set_form(int wd,int ht)
{
  newwin000->setProperty(WSNwidth,wd);
  newwin000->setProperty(WSNheight,ht);
}
年月日表示部分に年月日を表示する関数です。
引数
ttlは表示する文字列です。

void set_ttlString(char *ttl)
{
  newvlab_000->setProperty(WSNlabelString,ttl);
}