Win10 Calender

記念日をタイプして曜日と経過日数を計算します。
基本的な関数を MainPage.xaml.cpp に直接記述します。

前田稔の超初心者のプログラム入門

基本的な関数を作成

  1. Windows 10 で TextBox から記念日を取得して曜日と経過日数を計算します。
    今回は Class 分けをしないで MainPage に全てのソースコードを組み込んで、解り易くプログラミングしてみました。
  2. C++ では後位参照が起こらなければ、プロトタイプ宣言を省略することが出来ます。
    後位参照が起こらないように基本的な関数を MainPage.xaml.cpp の using の直後に追加します。
    1. MTBL[12] は1月~12月までの累積日数の配列です。
      WTBL[7] は曜日を表示する配列です。
      ToDay は西暦1年1月1日から今日までの通算日数を格納する領域です。
      int MTBL[12] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
      String^ WTBL[7]= {"日曜日", "月曜日", "火曜日", "水曜日", "木曜日", "金曜日", "土曜日"};
      int ToDay;      //1年1月1日からの通算日数
      
    2. 出力ウインドウに印字する関数です。
      void  Debug(Platform::String^ msg, int v)
      {   Platform::String^ str = "\n★[" + msg + "] " + v.ToString() + "\n";
          OutputDebugString(str->Data());
      }
      
    3. 閏年を調べる関数です。
      // 閏年を調べる関数
      bool  Uruu(int year)
      {   if (year%400==0)    return(true);
          if (year%100==0)    return(false);
          if (year%4==0)      return(true);
          return(false);
      }
      
    4. 西暦1年1月1日からの通算日数を調べる関数です。
      yy が閏年で3月以前のときは1日減らします。
      // 西暦1年1月1日からの通算日数を調べる関数
      int  Days(int yy, int mm, int dd)
      {   int w;
          w = (yy-1)*365;     //年*365
          w += (yy/4 - yy/100 + yy/400 + MTBL[mm-1] + dd);
          if (mm<3 && Uruu(yy))  w--;
          return(w);
      }
      
    5. '/' で区切られた文字列を切り分けて vector でリターンする関数です。
      STL の vector を使うときは <vector> を #include します。
      受け取った str を s にコピーして、後部に '/' を付加します。
      s.find_first_not_of(L" ,/", Col) で「, /」以外の文字を検索します。
      s.find_first_of(L" ,/", Col) で「/」を検索します。
      Word.assign(s, Col, wk - Col) で文字列 s の Col から wk-Col 文字を切り出します。
      vt.push_back(_wtoi(Word.data())) で 数値(int)に変換して vector に追加します。
      #include <string>       // STL の String を使う
      
      // '/' で区切られた文字列を数値に変換して vector でリターン
      std::vector<int> Split(Platform::String^ str)
      {   std::vector<int> vt;
          std::wstring s;
          std::wstring Word;
          int    Size, Col, wk;
          s = str->Data();
          s += L"/";
          OutputDebugString(s.data());
          Size = s.length() - 1;
          vt.clear();
          for (Col = 0; Col < Size;)
          {   wk = s.find_first_not_of(L" ,/", Col);
              Col = wk;
              wk = s.find_first_of(L" ,/", Col);
              if (wk==Col)        break;
              Word = Word.assign(s, Col, wk - Col);
              vt.push_back(_wtoi(Word.data()));
              Col = wk + 1;
          }
          return vt;
      }
      
  3. 基本関数が作成できた所で、テストしてみましょう。
    Debug() 関数と Days() 関数のテストです。
    MainPage::MainPage()
    {   InitializeComponent();
        Debug(L"Test Message", 123);
        Debug(L"通算日数", Days(2019,4,16));
    }
    
    Debug() 関数と Split() 関数のテストです。
    MainPage::MainPage()
    {   InitializeComponent();
        std::vector<int> vect;
        vect = Split("2019/4/16");
        for(int i=0; i<3; i++)
            Debug("vect",vect[i]);
    }
    

メインプログラム

  1. 基本関数が完成したら、メインプログラムの作成です。
    ページ先頭の画像を参考に TextBlock と TextBox と Button を貼り付けます。
        <Grid>
            <TextBlock HorizontalAlignment="Left" Margin="120,80,0,0" Text="記念日" TextWrapping="Wrap"
                VerticalAlignment="Top" Height="32" Width="60"/>
            <TextBlock HorizontalAlignment="Left" Margin="380,80,0,0" Text="曜日" TextWrapping="Wrap"
                VerticalAlignment="Top" Height="32" Width="60"/>
            <TextBlock HorizontalAlignment="Left" Margin="520,80,0,0" Text="経過日数" TextWrapping="Wrap"
                VerticalAlignment="Top"/>
            <TextBox x:Name="textBox" HorizontalAlignment="Left" Margin="100,120,0,0" Text="yyyy/mm/dd"
                VerticalAlignment="Top" Height="32" Width="130"/>
            <Button Content="実行" Margin="260,120,0,0" VerticalAlignment="Top" Click="Button_Click"/>
            <TextBox x:Name="textBox1" HorizontalAlignment="Left" Margin="360,120,0,0" Text="TextBox"
                VerticalAlignment="Top" Height="32" Width="80"/>
            <TextBox x:Name="textBox2" HorizontalAlignment="Left" Margin="500,120,0,0" Text="TextBox"
                VerticalAlignment="Top" Height="32" Width="100"/>
        </Grid>
    
  2. MainPage.xaml.h で Button_Click() 関数を宣言します。
        private:
            void Button_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
    
  3. MainPage.xaml.cpp の Constructor で ToDay を求めます。
    int     ToDay;  //1年1月1日からの通算日数
    MainPage::MainPage()
    {
        int yy,mm,dd;
        InitializeComponent();
        Windows::Globalization::Calendar^ cal = ref new Windows::Globalization::Calendar();
        yy = cal->Year;
        mm = cal->Month;
        dd = cal->Day;
        ToDay = Days(yy, mm, dd);
    }
    
  4. MainPage.xaml.cpp の Button_Click() 関数で曜日と経過日数を計算して表示します。
    void App1::MainPage::Button_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
    {
        String^ str;
        std::vector<int> vect;
        int ans, wk;
        str = ref new String(textBox->Text->Data());
        vect = Split(str);
        wk = Days(vect[0], vect[1], vect[2]);
        ans = ToDay - wk + 1;
        wk= wk%7;
        textBox1->Text = WTBL[wk];
        textBox2->Text = ans.ToString();
    }
    

超初心者のプログラム入門(C/C++)