none
C++/WinRTでWin2Dを使用し、ボタンをクリックしたら図形を描画する方法 RRS feed

回答

  • CanvasControlのInvalidate()でDrawイベントが呼ばれます

    <Page
        x:Class="BlankApp1.MainPage"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:BlankApp1"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:canvas="using:Microsoft.Graphics.Canvas.UI.Xaml"    
        mc:Ignorable="d" >
    
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition />
            </Grid.ColumnDefinitions>
    
            <StackPanel Grid.Column="0" Background="LightGoldenrodYellow">
                <Button Click="ClickHandler1" Margin="5">Test1</Button>
                <Button Click="ClickHandler2" Margin="5">Test2</Button>
            </StackPanel>
    
            <canvas:CanvasControl Grid.Column="1" x:Name="canvas1"  ClearColor="Aqua"
                Draw="CanvasControl_Draw" 
                PointerPressed="CanvasControl_PointerPressed"/>
        </Grid>
    
    </Page
    //pch.h
    #pragma once
    #include <windows.h>
    #include <unknwn.h>
    #include <restrictederrorinfo.h>
    #include <hstring.h>
    #include <winrt/Windows.Foundation.h>
    #include <winrt/Windows.Foundation.Collections.h>
    #include <winrt/Windows.ApplicationModel.Activation.h>
    #include <winrt/Windows.UI.Xaml.h>
    #include <winrt/Windows.UI.Xaml.Controls.h>
    #include <winrt/Windows.UI.Xaml.Controls.Primitives.h>
    #include <winrt/Windows.UI.Xaml.Data.h>
    #include <winrt/Windows.UI.Xaml.Interop.h>
    #include <winrt/Windows.UI.Xaml.Markup.h>
    #include <winrt/Windows.UI.Xaml.Navigation.h>
    
    #include <winrt/Windows.UI.Input.h>
    #include <winrt/Windows.UI.Xaml.Input.h>
    
    #include <Microsoft.Graphics.Canvas.UI.Xaml.h>
    //MainPage.idl
    
    namespace BlankApp1
    {
        [default_interface]
        runtimeclass MainPage : Windows.UI.Xaml.Controls.Page
        {
            MainPage();
    
            // xamlにx:Nameで定義した名前のCanvasControlに紐づけるプロパティ
            Microsoft.Graphics.Canvas.UI.Xaml.CanvasControl canvas1{ get; };
        }
    }
    //MainPage.h
    
    #pragma once
    
    #include "MainPage.g.h"
    
    using namespace winrt;
    using namespace winrt::Windows::Foundation;
    using namespace winrt::Windows::UI::Input;
    using namespace winrt::Windows::UI::Xaml;
    using namespace winrt::Microsoft::Graphics::Canvas::UI::Xaml;
    
    namespace winrt::BlankApp1::implementation
    {
    	struct MainPage : MainPageT<MainPage>
    	{
    		int flag = 0;
    		float cx = 10;
    		float cy = 10;
    		float radius = 10;
    
    		MainPage();
    
    		void ClickHandler1(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::RoutedEventArgs const& args);
    		void ClickHandler2(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::RoutedEventArgs const& args);
    
    		void CanvasControl_PointerPressed(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::UI::Xaml::Input::PointerRoutedEventArgs const& e);
    
    		// CanvasControlのDrawイベント
    		void CanvasControl_Draw(CanvasControl const& sender, CanvasDrawEventArgs const& args);
    
    		void draw1(CanvasDrawEventArgs const& args);
    		void draw2(CanvasDrawEventArgs const& args);
    
    		
    	};
    }
    
    namespace winrt::BlankApp1::factory_implementation
    {
    	struct MainPage : MainPageT<MainPage, implementation::MainPage>
    	{
    	};
    }

    #include "pch.h"
    #include "MainPage.h"
    #include "MainPage.g.cpp"
    
    using namespace winrt;
    using namespace Windows::Foundation;
    using namespace Windows::UI::Input;
    using namespace Windows::UI::Xaml;
    using namespace Microsoft::Graphics::Canvas::UI::Xaml;
    
    namespace winrt::BlankApp1::implementation
    {
    	MainPage::MainPage()
    	{
    		InitializeComponent();
    	}
    
    	/// <summary>ボタン1のクリックイベント</summary>
    	void MainPage::ClickHandler1(IInspectable const&, RoutedEventArgs const&)
    	{
    		flag = 1;
    
    		CanvasControl c1 = this->canvas1(); //xamlとidlに定義してあるCanvasControl
    		c1.Invalidate(); //描画を指示(Drawイベントを発生させる)
    	}
    
    	/// <summary>ボタン1のクリックイベント</summary>
    	void MainPage::ClickHandler2(IInspectable const&, RoutedEventArgs const&)
    	{
    		flag++;
    		if (this->radius < 1000)
    		{
    			this->radius += 10;
    		}
    		this->canvas1().Invalidate(); //描画を指示(Drawイベントを発生させる)
    	}
    
    	void MainPage::CanvasControl_PointerPressed(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::UI::Xaml::Input::PointerRoutedEventArgs const& e)
    	{
    		CanvasControl canvas = sender.as<CanvasControl>();
    		PointerPoint pp = e.GetCurrentPoint(canvas);
    		Point p = pp.Position();
    
    		//CanvasControlをクリックした位置を円の中心に
    		cx = p.X;
    		cy = p.Y;
    
    		flag = 2;
    		canvas.Invalidate();
    	}
    
    
    	void MainPage::CanvasControl_Draw(CanvasControl const& sender, CanvasDrawEventArgs const& args)
    	{
    		switch (flag)
    		{
    		case 0:
    			break;
    
    		case 1:
    			draw1(args);
    			break;
    
    		default:
    			draw2(args);
    
    			flag = 2;
    			break;
    		}
    	}
    
    	void MainPage::draw1(CanvasDrawEventArgs const& args)
    	{
    		args.DrawingSession().DrawText(L"Hello, world!", 10, 10, winrt::Windows::UI::Colors::Black());
    	}
    
    	void MainPage::draw2(CanvasDrawEventArgs const& args)
    	{
    		args.DrawingSession().DrawCircle(this->cx, this->cy, this->radius, winrt::Windows::UI::Colors::BlueViolet(), 5);
    	}
    }

    個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)

    • 回答としてマーク fghck856 2022年7月18日 11:25
    2022年7月18日 8:15

すべての返信

  • CanvasControlのInvalidate()でDrawイベントが呼ばれます

    <Page
        x:Class="BlankApp1.MainPage"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:BlankApp1"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:canvas="using:Microsoft.Graphics.Canvas.UI.Xaml"    
        mc:Ignorable="d" >
    
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition />
            </Grid.ColumnDefinitions>
    
            <StackPanel Grid.Column="0" Background="LightGoldenrodYellow">
                <Button Click="ClickHandler1" Margin="5">Test1</Button>
                <Button Click="ClickHandler2" Margin="5">Test2</Button>
            </StackPanel>
    
            <canvas:CanvasControl Grid.Column="1" x:Name="canvas1"  ClearColor="Aqua"
                Draw="CanvasControl_Draw" 
                PointerPressed="CanvasControl_PointerPressed"/>
        </Grid>
    
    </Page
    //pch.h
    #pragma once
    #include <windows.h>
    #include <unknwn.h>
    #include <restrictederrorinfo.h>
    #include <hstring.h>
    #include <winrt/Windows.Foundation.h>
    #include <winrt/Windows.Foundation.Collections.h>
    #include <winrt/Windows.ApplicationModel.Activation.h>
    #include <winrt/Windows.UI.Xaml.h>
    #include <winrt/Windows.UI.Xaml.Controls.h>
    #include <winrt/Windows.UI.Xaml.Controls.Primitives.h>
    #include <winrt/Windows.UI.Xaml.Data.h>
    #include <winrt/Windows.UI.Xaml.Interop.h>
    #include <winrt/Windows.UI.Xaml.Markup.h>
    #include <winrt/Windows.UI.Xaml.Navigation.h>
    
    #include <winrt/Windows.UI.Input.h>
    #include <winrt/Windows.UI.Xaml.Input.h>
    
    #include <Microsoft.Graphics.Canvas.UI.Xaml.h>
    //MainPage.idl
    
    namespace BlankApp1
    {
        [default_interface]
        runtimeclass MainPage : Windows.UI.Xaml.Controls.Page
        {
            MainPage();
    
            // xamlにx:Nameで定義した名前のCanvasControlに紐づけるプロパティ
            Microsoft.Graphics.Canvas.UI.Xaml.CanvasControl canvas1{ get; };
        }
    }
    //MainPage.h
    
    #pragma once
    
    #include "MainPage.g.h"
    
    using namespace winrt;
    using namespace winrt::Windows::Foundation;
    using namespace winrt::Windows::UI::Input;
    using namespace winrt::Windows::UI::Xaml;
    using namespace winrt::Microsoft::Graphics::Canvas::UI::Xaml;
    
    namespace winrt::BlankApp1::implementation
    {
    	struct MainPage : MainPageT<MainPage>
    	{
    		int flag = 0;
    		float cx = 10;
    		float cy = 10;
    		float radius = 10;
    
    		MainPage();
    
    		void ClickHandler1(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::RoutedEventArgs const& args);
    		void ClickHandler2(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::RoutedEventArgs const& args);
    
    		void CanvasControl_PointerPressed(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::UI::Xaml::Input::PointerRoutedEventArgs const& e);
    
    		// CanvasControlのDrawイベント
    		void CanvasControl_Draw(CanvasControl const& sender, CanvasDrawEventArgs const& args);
    
    		void draw1(CanvasDrawEventArgs const& args);
    		void draw2(CanvasDrawEventArgs const& args);
    
    		
    	};
    }
    
    namespace winrt::BlankApp1::factory_implementation
    {
    	struct MainPage : MainPageT<MainPage, implementation::MainPage>
    	{
    	};
    }

    #include "pch.h"
    #include "MainPage.h"
    #include "MainPage.g.cpp"
    
    using namespace winrt;
    using namespace Windows::Foundation;
    using namespace Windows::UI::Input;
    using namespace Windows::UI::Xaml;
    using namespace Microsoft::Graphics::Canvas::UI::Xaml;
    
    namespace winrt::BlankApp1::implementation
    {
    	MainPage::MainPage()
    	{
    		InitializeComponent();
    	}
    
    	/// <summary>ボタン1のクリックイベント</summary>
    	void MainPage::ClickHandler1(IInspectable const&, RoutedEventArgs const&)
    	{
    		flag = 1;
    
    		CanvasControl c1 = this->canvas1(); //xamlとidlに定義してあるCanvasControl
    		c1.Invalidate(); //描画を指示(Drawイベントを発生させる)
    	}
    
    	/// <summary>ボタン1のクリックイベント</summary>
    	void MainPage::ClickHandler2(IInspectable const&, RoutedEventArgs const&)
    	{
    		flag++;
    		if (this->radius < 1000)
    		{
    			this->radius += 10;
    		}
    		this->canvas1().Invalidate(); //描画を指示(Drawイベントを発生させる)
    	}
    
    	void MainPage::CanvasControl_PointerPressed(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::UI::Xaml::Input::PointerRoutedEventArgs const& e)
    	{
    		CanvasControl canvas = sender.as<CanvasControl>();
    		PointerPoint pp = e.GetCurrentPoint(canvas);
    		Point p = pp.Position();
    
    		//CanvasControlをクリックした位置を円の中心に
    		cx = p.X;
    		cy = p.Y;
    
    		flag = 2;
    		canvas.Invalidate();
    	}
    
    
    	void MainPage::CanvasControl_Draw(CanvasControl const& sender, CanvasDrawEventArgs const& args)
    	{
    		switch (flag)
    		{
    		case 0:
    			break;
    
    		case 1:
    			draw1(args);
    			break;
    
    		default:
    			draw2(args);
    
    			flag = 2;
    			break;
    		}
    	}
    
    	void MainPage::draw1(CanvasDrawEventArgs const& args)
    	{
    		args.DrawingSession().DrawText(L"Hello, world!", 10, 10, winrt::Windows::UI::Colors::Black());
    	}
    
    	void MainPage::draw2(CanvasDrawEventArgs const& args)
    	{
    		args.DrawingSession().DrawCircle(this->cx, this->cy, this->radius, winrt::Windows::UI::Colors::BlueViolet(), 5);
    	}
    }

    個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)

    • 回答としてマーク fghck856 2022年7月18日 11:25
    2022年7月18日 8:15
  • gekka 様

    いつもお世話になります。詳細なコードの提示ありがとうございます。

    ご提示いただいたコードを試してみますので、少し時間をください。

    2022年7月18日 9:52
  • gekka 様

    ありがとうございました。ご教示いただいたコードで、ボタン1クリックで「Hello World!」と表示され、ボタン2クリックで円弧が表示されました。これが私のやりたかったことです。

    後は、今回ご教示いただいたコードを少し勉強して、私なりのプログラムを作成していきたいと思います。

    毎回のことですが、本当に感謝申し上げます。

    2022年7月18日 11:23