shincodeのブログ

プログラミング初心者のC#のお勉強

Outlook予定表を読み取り起動するエヴァ風タイマーのソースコード<C#>

Clock.xaml

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApplication1"
        mc:Ignorable="d"
        Title="スケジューラー" Height="354" Width="276" ShowInTaskbar="False" Closing="Window_Closing" Loaded="Window_Loaded">
    <Grid>
        <Button x:Name="button" Content="再取得" HorizontalAlignment="Left" Height="22" VerticalAlignment="Top" Width="78" Click="button_Click" Margin="180,10,0,0"/>
        <TextBox x:Name="textBox" HorizontalAlignment="Left" Height="286" Margin="0,37,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Width="268"/>
        <TextBlock HorizontalAlignment="Left" TextWrapping="Wrap" Text="おはようございます。" VerticalAlignment="Top"/>
        <TextBlock HorizontalAlignment="Left" TextWrapping="Wrap" Text="本日のご予定は以下になります。" VerticalAlignment="Top" Margin="0,16,0,0"/>
    </Grid>
</Window>

MainWindow.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading;

namespace WpfApplication1
{
    /// <summary>
    /// MainWindow.xaml の相互作用ロジック
    /// </summary>
    public partial class MainWindow : Window
    {

        private DispatcherTimer m_Timer = null;
        private List<Schedule> ScheduleList = new List<Schedule>();
        public MainWindow()
        {

            InitializeComponent();

            // タイマーを作成する
            m_Timer = new DispatcherTimer(DispatcherPriority.Normal, this.Dispatcher);
            m_Timer.Interval = TimeSpan.FromMinutes(1);
            m_Timer.Tick += M_Timer_Tick;
            // タイマーの実行開始
            m_Timer.Start();
            Clock clk = new Clock(DateTime.Now.AddSeconds(45),"第三応接室にて会議は行われます。");
            clk.Show();
            this.Top = 0;
            this.Left = 0;
        }

        private void M_Timer_Tick(object sender, EventArgs e)
        {
            for(int i =0; i< ScheduleList.Count; i++)
            {
                Schedule sch = ScheduleList[i];
                if (!sch.IsHandled && sch.Start.Ticks-DateTime.Now.Ticks < 1200000000)
                {
                    //移動先を帰る

                    //クロックを出す
                    if (sch.Start.Ticks - DateTime.Now.Ticks > 0)
                    {
                        Clock clk = new Clock(sch.Start, sch.Location);
                        clk.Show();
                    }
                    sch.IsHandled = true;
                }
                else if(sch.IsHandled &&  DateTime.Now.Ticks- sch.Stop.Ticks > 0)
                {
                    //在室に変える。


                    ScheduleList.Remove(sch);
                    i--;
                }
            }

        }

        private void button_Click(object sender, RoutedEventArgs e)
        {
            textBox.Text = "";
            Microsoft.Office.Interop.Outlook.Application outlook
                = new Microsoft.Office.Interop.Outlook.Application();
            Microsoft.Office.Interop.Outlook.NameSpace ns = outlook.GetNamespace("MAPI");
            Microsoft.Office.Interop.Outlook.MAPIFolder oFolder = ns.GetDefaultFolder(Microsoft.Office.Interop.Outlook.OlDefaultFolders.olFolderCalendar);
            


            Microsoft.Office.Interop.Outlook.Items oItems = oFolder.Items;

            Microsoft.Office.Interop.Outlook.AppointmentItem oAppoint = oItems.GetFirst();
            while (oAppoint != null)
            {
                if (
                    (oAppoint.Start <= DateTime.Today & DateTime.Today.AddDays(1) <= oAppoint.End) || //終日の予定?
                    ((DateTime.Today < oAppoint.Start & oAppoint.Start < DateTime.Today.AddDays(1)) || (DateTime.Today < oAppoint.End & oAppoint.End < DateTime.Today.AddDays(1)))
                    )
                {
                    textBox.Text += "Subject: " + oAppoint.Subject + "\r\n";
                    textBox.Text += "場所: " + oAppoint.Location + "\r\n";
                    textBox.Text += "開始時刻: " + oAppoint.Start.ToString("MM/dd")+" " + oAppoint.Start.ToShortTimeString() + "\r\n";
                    textBox.Text += "終了時刻: " + oAppoint.End.ToString("MM/dd") + " " + oAppoint.End.ToShortTimeString() + "\r\n";
                    textBox.Text += "---\r\n";
                    Schedule sch = new Schedule();
                    sch.Start = oAppoint.Start;
                    sch.Stop = oAppoint.End;
                    if (oAppoint.Location != "")
                    {
                        sch.Location = oAppoint.Location;
                    }
                    else
                    {
                        sch.Location = "不明";
                    }
                    sch.Subject = oAppoint.Subject;
                    ScheduleList.Add(sch);
                }
                oAppoint = oItems.GetNext();
            }

            

        }

        private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            e.Cancel = true;
            this.Hide();
        }

        private async void Window_Loaded(object sender, RoutedEventArgs e)
        {
            this.button_Click(sender, e);
            await Task.Run(() => 
            {
                System.Threading.Thread.Sleep(5000);
            });
            this.Hide();
        }
    }

    public class Schedule
    {
        public DateTime Start;
        public DateTime Stop;
        public string Location;
        public string Subject;
        public bool IsHandled = false;
    }
}


Clock.xaml

<Window x:Class="WpfApplication1.Clock"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApplication1"
        mc:Ignorable="d"
        Title="Clock" Height="52.75" Width="151.25" WindowStyle="None" Background="Transparent" Loaded="Window_Loaded" ResizeMode="NoResize" ShowInTaskbar="False" Topmost="True">
    <Grid x:Name="MainGrid" Opacity="1" Height="53" VerticalAlignment="Top" HorizontalAlignment="Left" Width="151">
        <Grid.Background>
            <LinearGradientBrush EndPoint="1,0" MappingMode="RelativeToBoundingBox" StartPoint="0,0">
                <GradientStop Color="#FF00D11C" Offset="1"/>
                <GradientStop Color="#FFD66B11"/>
                <GradientStop Color="#FFFFDB3A" Offset="0.325"/>
                <GradientStop Color="#FFFAFA37" Offset="0.548"/>
                <GradientStop Color="#FFE3F533" Offset="0.652"/>
                <GradientStop Color="#FFFCF338" Offset="0.423"/>
            </LinearGradientBrush>
        </Grid.Background>
        <Rectangle Fill="Black" HorizontalAlignment="Left" Height="27" Margin="11,16,0,0" Stroke="Black" VerticalAlignment="Top" Width="134"/>
        <Rectangle Fill="Black" HorizontalAlignment="Left" Height="12" Margin="93,4,0,0" Stroke="Black" VerticalAlignment="Top" Width="52"/>

        <TextBlock x:Name="textBlock" HorizontalAlignment="Left" TextWrapping="Wrap" Text="会議時間まで" FontSize="10" VerticalAlignment="Top"/>
        <TextBlock x:Name="textBlock2" HorizontalAlignment="Left" TextWrapping="Wrap" Text="あと" VerticalAlignment="Top" FontSize="7" Margin="0,16,0,0"/>
        <TextBlock x:Name="Time" HorizontalAlignment="Left" TextWrapping="Wrap" Text="{Binding RemainingTime}" VerticalAlignment="Top" FontSize="30" Margin="-4,8,0,0" FontFamily="Quartz MS" Width="114" RenderTransformOrigin="0.5,0.5" Foreground="#FFEAE018">
            <TextBlock.RenderTransform>
                <TransformGroup>
                    <ScaleTransform ScaleX="0.7"/>
                    <SkewTransform/>
                    <RotateTransform/>
                    <TranslateTransform/>
                </TransformGroup>
            </TextBlock.RenderTransform>
        </TextBlock>
        <TextBlock x:Name="Locate" HorizontalAlignment="Left" TextWrapping="Wrap" Text="{Binding Location}" VerticalAlignment="Top" FontSize="10" Margin="85,5,0,0" FontFamily="Quartz MS" Width="68" RenderTransformOrigin="0.5,0.5" Foreground="#FFEAE018" Height="36">
            <TextBlock.RenderTransform>
                <TransformGroup>
                    <ScaleTransform ScaleX="0.7"/>
                    <SkewTransform/>
                    <RotateTransform/>
                    <TranslateTransform/>
                </TransformGroup>
            </TextBlock.RenderTransform>
        </TextBlock>
    </Grid>
</Window>


Clock.xaml.cs

//Clock.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.ComponentModel;

namespace WpfApplication1
{
    /// <summary>
    /// Clock.xaml の相互作用ロジック
    /// </summary>
    public partial class Clock : Window
    {
        public DateTime Start;
        public string Basyo;
        public Clock(DateTime StartTime,string Location)
        {
            Basyo = Location;
            Start = StartTime;
            InitializeComponent();
            this.Top = 0;
            this.Left = 0;
        }

        private async void Window_Loaded(object sender, RoutedEventArgs e)
        {
            //文回せ
            DispItems DI = new DispItems();
            DI.Location = Basyo;
            DI.RemainingTime = "";
            this.DataContext = DI;
            bool IsEnd = false;
            await Task.Run(() =>
            {
                string TimeString = "";
                while (!IsEnd)
                {

                    long RemainTics = Start.Ticks - DateTime.Now.Ticks;
                    int min = (int)(RemainTics / 600000000);
                    int sec = (int)((RemainTics - 600000000 * min) / 10000000);
                    double subsec = (RemainTics - 600000000 * min - 10000000 * sec) / 100000;
                    TimeString = min.ToString() + ":" + sec.ToString("00") + ":" + subsec.ToString("00");
                    DI.RemainingTime = TimeString;
                    if (RemainTics < 0)
                    {
                        IsEnd = true;

                    }
                    System.Threading.Thread.Sleep(10);
                    if (RemainTics < 300000000)
                    {
                        this.Dispatcher.Invoke(new Action(() => {
                            Locate.Foreground = new SolidColorBrush(Color.FromArgb(255, 255, 0, 0));
                            Time.Foreground = new SolidColorBrush(Color.FromArgb(255, 255, 0, 0));
                            MainGrid.Background = new SolidColorBrush(Color.FromArgb(255, 255, 0, 0));
                        }));
                    }
                    
                }
                this.Dispatcher.Invoke(new Action(() => {
                Locate.Foreground = new SolidColorBrush(Color.FromArgb(255, 50, 50, 50));
                Time.Foreground = new SolidColorBrush(Color.FromArgb(255, 50, 50, 50));
                MainGrid.Background = new SolidColorBrush(Color.FromArgb(255, 50, 50, 50));
                }));
                DI.RemainingTime = "0:00:00";
                System.Threading.Thread.Sleep(2000);

            });
            
            this.Close();
        }
    }

    public  class DispItems: INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        private void NotifyPropertyChanged(string info)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(info));
            }
        }
        private string _RemainingTime;
        public string RemainingTime
        {
            get { return this._RemainingTime; }
            set
            {
                if (value != this._RemainingTime)
                {
                    this._RemainingTime = value;
                    NotifyPropertyChanged("RemainingTime");
                }
            }
        }
        private string _Location;
        public string Location
        {
            get { return this._Location; }
            set
            {
                if (value != this._Location)
                {
                    this._Location = value;
                    NotifyPropertyChanged("Location");
                }
            }
        }
    }

}