新規記事の投稿を行うことで、非表示にすることが可能です。
2018年04月27日
《その371》C++/CX
C++/CX
Visual_Studio_2017 の ユニバーサルWindowsプラットフォーム(略称:UWP)を使用してアプリを開発する手段としては、主に、
(1) 画像等は XAML,プログラムは C++/CX
(2) 画像等は XAML,プログラムは C#
(3) 画像等は XAML,プログラムは VisualBasic.NET
(4) 画像等は HTML & CSS,プログラムは JavaScript.NET
の4種類があります。
(1) の C++/CX は、UWP上でアプリを開発するために C++ をベースに開発された言語です。
ですから、このブログの《364》以降の C++ は、主として C++/CX を使ってきたわけです。
String^ s;
btn->Content = "表示";
z11.ToString();
などの、あまり見かけない記述が出てきたのは、そのせいです。
C++/CX で書かれたプログラムは、Windowsランタイム(略称:WinRT)環境で動作します。
この言語で記述されたプログラムは、コンパイルによって、C++ 等と同じように直接 マシン語に変換されます(C++/CX は .NET_Framework を直接扱うことができません)。
これに対して (2)〜(4) の場合は、.NET環境(ドットNET環境)で動作します。これらの言語は、コンパイルされると、マシン語ではなく、CIL と呼ばれる .NET環境用の形式に変換されます。
以上、今 やっていることの位置付けが、いまいち理解できていなかったので、自分なりに少し整理してみました。
2018年04月25日
《その370》Page_Loaded イベントハンドラ
これまでのプログラムは、すべて、ボタンクリックに対するイベントハンドラでした。
今回のプログラムは「きょうの日付」を表示するだけのものですが、プログラム開始時点のページ読込み完了イベントに対するイベントハンドラになっています。
また、通常の C++ で普通に行われているような、独自の関数を定義して使用したりもしています。定義した関数は、今日の日付を取得する func()、曜日を決定する day_of_week() の2つです。
VS に CalendarViewツールなども用意されているので、日付を表示するだけのプログラムは、あまり意味がありませんが、とりあえず・・・。
今回の例では、C++ の知識がそのまま使えたので、ちょっとホッとしています (・ω・`;)ゞ
フォームの外周部分をクリックして選択します。
プロパティの右上にある稲妻マークをクリックします。
Loaded欄の枠内をダブルクリックします。
MainPage.xaml.cpp の編集画面が表示されるので、プログラムを記述します。
//
// MainPage.xaml.cpp
// MainPage クラスの実装。
//
#include "pch.h"
#include "MainPage.xaml.h"
using namespace App4;
using namespace Platform;
using namespace Windows::Foundation;
using namespace Windows::Foundation::Collections;
using namespace Windows::UI::Xaml;
using namespace Windows::UI::Xaml::Controls;
using namespace Windows::UI::Xaml::Controls::Primitives;
using namespace Windows::UI::Xaml::Data;
using namespace Windows::UI::Xaml::Input;
using namespace Windows::UI::Xaml::Media;
using namespace Windows::UI::Xaml::Navigation;
MainPage::MainPage()
{
InitializeComponent();
}
void App4::MainPage::
cal_SelectedDatesChanged(
Windows::UI::Xaml::Controls::CalendarView^ sender,
Windows::UI::Xaml::Controls::
CalendarViewSelectedDatesChangedEventArgs^ args)
{
// String^ str = cal->SelectedDates->ToString();
// box->Text = str;
// struct tm local = cal->SelectedDates;
}
int y, m, d;
void func() {
time_t timeUTC = time(NULL);
struct tm local;
localtime_s(&local, &timeUTC);
y = local.tm_year + 1900;
m = local.tm_mon + 1;
d = local.tm_mday;
}
String^ day_of_week() {
int yy = y; int mm = m;
if (mm == 1 || mm == 2) { yy--; mm += 12; }
int tmp = (yy + yy / 4 - yy / 100 + yy
/ 400 + (13 * mm + 8) / 5 + d) % 7;
String^ wd[] = {"日", "月", "火", "水", "木", "金", "土"};
return wd[tmp];
}
void App4::MainPage::
Page_Loaded(
Platform::Object^ sender,
Windows::UI::Xaml::RoutedEventArgs^ e)
{
func();
box_y->Text = y.ToString();
box_m->Text = m.ToString();
box_d->Text = d.ToString();
box_wd->Text = day_of_week();
}
MainPage.xaml 画面です。
実行画面です。
2018年04月23日
《その369》画像の表示・非表示
画像の表示・非表示
前回《その367》、プロジェクトに画像を取り込みましたが、
今回は、その画像の表示・非表示をボタンクリックで切りかえるアプリを作成します。
Button のプロパティを変更します。
(名前を "btn" にして、共通 Content を "消去" に変更しました。)
ボタンの文字が "消去" に変わりました。
稲妻マークをクリックし、Click欄の枠内をダブルクリックします。
btn_Click関数の記述画面が表示されるので、コードを記述します。
(記述するのは、赤文字のコードのみです。)
//
// MainPage.xaml.cpp
// MainPage クラスの実装。
//
#include "pch.h"
#include "MainPage.xaml.h"
using namespace App3;
using namespace Platform;
using namespace Windows::Foundation;
using namespace Windows::Foundation::Collections;
using namespace Windows::UI::Xaml;
using namespace Windows::UI::Xaml::Controls;
using namespace Windows::UI::Xaml::Controls::Primitives;
using namespace Windows::UI::Xaml::Data;
using namespace Windows::UI::Xaml::Input;
using namespace Windows::UI::Xaml::Media;
using namespace Windows::UI::Xaml::Navigation;
MainPage::MainPage()
{
InitializeComponent();
}
void App3::MainPage::
btn_Click(
Platform::Object^ sender,
Windows::UI::Xaml::RoutedEventArgs^ e)
{
// img が Visible であれば Collapsed に変更し、
// btn の文字を"表示"にします。
if (img->Visibility
== Windows::UI::Xaml::Visibility::Visible)
{
img->Visibility
= Windows::UI::Xaml::Visibility::Collapsed;
btn->Content = "表示";
}
// if文が不成立なら、else if文を実行します。
// img が Collapsed であれば Visible に変更し、
// btn の文字を"消去"にします。
else if (img->Visibility
== Windows::UI::Xaml::Visibility::Collapsed)
{
img->Visibility
= Windows::UI::Xaml::Visibility::Visible;
btn->Content = "消去";
}
}
アプリをスタートして、消去ボタンを押してみます。
画像が消え、ボタンの文字が "表示" になります。表示ボタンを押してみます。
再び画像が現れ、ボタンの文字が "消去" に戻ります。
《その368》画像の取込み
今回は、プロジェクトに画像を取り込む方法について だけの内容です。
フォーム上に画像を表示させるまでの手順を確認します。
ファイル(F) -> 新規作成(N) -> プロジェクト(P)
Visual C++ -> Windows ユニバーサル -> 空のアプリ(ユニバーサル Windows)
そのまま OK
ソリューションエクスプローラーで 追加(D) -> 既存の項目(G)
表示されるエクスプローラーで、画像を選択します。
Assetsフォルダのリストに、選択した img01.png が表示されました。
MainPage.xaml -> 開く(O)
フォームのサイズ等を調整します。
表示(V) -> ツールボックス(X)
Image を選択します。
Image をドラッグ&ドロップします。
Image のプロパティで、img01.png を選択しました。
画像が表示されました。
2018年04月21日
《その367》2行2列の行列計算アプリ
2行2列の行列計算
入力された文字列を数値に変換する手順が、あまりキレイではありませんが・・・。
int::Parse を使おうとするとエラーになってしまうので、まわりくどいコードになってしまいました。
MainPage.xaml の コントロール配置図です。
以下は、MainPage.xaml のコードです。
自動で作成されるコードなので、小さいフォントにしました (^^;)
確認が必要な場合は、コピペしてください m(_ _ )m
<Page
x:Class="App4.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:App4"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid Background="White" Margin="-10,10,10,-10">
<TextBox x:Name="a11" HorizontalAlignment="Left" Margin="200,150,0,0" Text="" VerticalAlignment="Top" PlaceholderText="整数値"/>
<TextBox x:Name="a21" HorizontalAlignment="Left" Margin="200,200,0,0" Text="" VerticalAlignment="Top" PlaceholderText="整数値"/>
<TextBox x:Name="a12" HorizontalAlignment="Left" Margin="300,150,0,0" Text="" VerticalAlignment="Top" PlaceholderText="整数値"/>
<TextBox x:Name="a22" HorizontalAlignment="Left" Margin="300,200,0,0" Text="" VerticalAlignment="Top" PlaceholderText="整数値"/>
<TextBox x:Name="b11" HorizontalAlignment="Left" Margin="450,150,0,0" Text="" VerticalAlignment="Top" PlaceholderText="整数値"/>
<TextBox x:Name="b21" HorizontalAlignment="Left" Margin="450,200,0,0" Text="" VerticalAlignment="Top" PlaceholderText="整数値"/>
<TextBox x:Name="b12" HorizontalAlignment="Left" Margin="550,150,0,0" Text="" VerticalAlignment="Top" PlaceholderText="整数値"/>
<TextBox x:Name="b22" HorizontalAlignment="Left" Margin="550,200,0,0" Text="" VerticalAlignment="Top" PlaceholderText="整数値"/>
<TextBox x:Name="c11" HorizontalAlignment="Left" Margin="740,150,0,0" Text="" VerticalAlignment="Top" IsReadOnly="True" Background="#33ECE559"/>
<TextBox x:Name="c21" HorizontalAlignment="Left" Margin="740,200,0,0" Text="" VerticalAlignment="Top" IsReadOnly="True" Background="#33ECE559"/>
<TextBox x:Name="c12" HorizontalAlignment="Left" Margin="840,150,0,0" Text="" VerticalAlignment="Top" IsReadOnly="True" Background="#33ECE559"/>
<TextBox x:Name="c22" HorizontalAlignment="Left" Margin="840,200,0,0" Text="" VerticalAlignment="Top" IsReadOnly="True" Background="#33ECE559"/>
<TextBlock HorizontalAlignment="Left" Margin="165,136,0,0" Text="(" TextWrapping="Wrap" VerticalAlignment="Top" Height="108" Width="32" FontSize="72"/>
<TextBlock HorizontalAlignment="Left" Margin="415,136,0,0" Text="(" TextWrapping="Wrap" VerticalAlignment="Top" Height="108" Width="32" FontSize="72"/>
<TextBlock HorizontalAlignment="Left" Margin="705,136,0,0" Text="(" TextWrapping="Wrap" VerticalAlignment="Top" Height="108" Width="32" FontSize="72"/>
<TextBlock HorizontalAlignment="Left" Margin="920,136,0,0" Text=")" TextWrapping="Wrap" VerticalAlignment="Top" Height="108" Width="32" FontSize="72"/>
<TextBlock HorizontalAlignment="Left" Margin="630,136,0,0" Text=")=" TextWrapping="Wrap" VerticalAlignment="Top" Height="108" Width="87" FontSize="72"/>
<TextBlock HorizontalAlignment="Left" Margin="380,136,0,0" Text=")" TextWrapping="Wrap" VerticalAlignment="Top" Height="108" Width="32" FontSize="72"/>
<Button Content="計算" HorizontalAlignment="Left" Margin="740,72,0,0" VerticalAlignment="Top" Width="89" FontSize="24" Click="Button_Click"/>
</Grid>
</Page>
以下は、ボタンクリック時に作動するプログラム Button_Click関数です。
//
// MainPage.xaml.cpp
// MainPage クラスの実装。
//
#include "pch.h"
#include "MainPage.xaml.h"
using namespace App4;
using namespace Platform;
using namespace Windows::Foundation;
using namespace Windows::Foundation::Collections;
using namespace Windows::UI::Xaml;
using namespace Windows::UI::Xaml::Controls;
using namespace Windows::UI::Xaml::Controls::Primitives;
using namespace Windows::UI::Xaml::Data;
using namespace Windows::UI::Xaml::Input;
using namespace Windows::UI::Xaml::Media;
using namespace Windows::UI::Xaml::Navigation;
MainPage::MainPage()
{
InitializeComponent();
}
void App4::MainPage::
Button_Click(Platform::Object^ sender,
Windows::UI::Xaml::RoutedEventArgs^ e)
{
String^ s11 = a11->Text; std::wstring p11(s11->Data());
const wchar_t* v11 = p11.c_str(); int x11 = _wtoi(v11);
String^ s12 = a12->Text; std::wstring p12(s12->Data());
const wchar_t* v12 = p12.c_str(); int x12 = _wtoi(v12);
String^ s21 = a21->Text; std::wstring p21(s21->Data());
const wchar_t* v21 = p21.c_str(); int x21 = _wtoi(v21);
String^ s22 = a22->Text; std::wstring p22(s22->Data());
const wchar_t* v22 = p22.c_str(); int x22 = _wtoi(v22);
String^ t11 = b11->Text; std::wstring q11(t11->Data());
const wchar_t* w11 = q11.c_str(); int y11 = _wtoi(w11);
String^ t12 = b12->Text; std::wstring q12(t12->Data());
const wchar_t* w12 = q12.c_str(); int y12 = _wtoi(w12);
String^ t21 = b21->Text; std::wstring q21(t21->Data());
const wchar_t* w21 = q21.c_str(); int y21 = _wtoi(w21);
String^ t22 = b22->Text; std::wstring q22(t22->Data());
const wchar_t* w22 = q22.c_str(); int y22 = _wtoi(w22);
int z11 = x11 * y11 + x12 * y21;
int z12 = x11 * y12 + x12 * y22;
int z21 = x21 * y11 + x22 * y21;
int z22 = x21 * y12 + x22 * y22;
c11->Text = z11.ToString();
c12->Text = z12.ToString();
c21->Text = z21.ToString();
c22->Text = z22.ToString();
}
アプリをスタートして、数値を入力した状態です。
計算ボタンを押して、結果が表示されました。
《その366》Windowsユニバーサルアプリ(3)
前回の続きです。ごく単純なアプリですが、一通りの手順を確認できます。
前回《365》の状態です。
TextBox をクリックします。
右下に TextBox のプロパティ画面が現れます。
名前を「box」にしました。
PlaceHolderText を「ここに入力」にしました。
TextBlock をクリックします。
右下に TextBlock のプロパティ画面が現れます。
名前を「block」にし、フォントとフォントサイズを変更しました。
Button をクリックします。
Button プロパティ画面右上の稲妻マークをクリックします。
Click欄の枠内をダブルクリックします。
ボタンクリック時の動作を記述するための
Button_Clickイベントハンドラ編集画面が現れます。
コードを書き込みます。書き込んだのは、
String^ str = box->Text;
block->Text = str;
の2行だけです。
デバッグ(D) -> デバッグなしで開始(H)
アプリの開始です。
テキストボックスに文字を入力します。
ボタンを押します。
2018年04月20日
《その365》Windowsユニバーサルアプリ(2)
初めに、超簡単な Windowsユニバーサルアプリを作ってみたいと思います。
いきなりプログラムではなくて、その前段階のビジュアル的な準備があります。コマンドプロンプトのときの感じとは、全然違ってますね。
ファイル(F) -> 新規作成(N) -> プロジェクト(P)
Visual C++ -> Windowsユニバーサル -> 空白のアプリ(ユニバーサル Windows)-> OK
ここは、そのまま OK
ソリューション エクスプローラー で、MainPage.xaml を開く
※ マウス右ボタン&開く or ダブルクリック )
このような画面になります。
表示(V) -> ツールボックス(X)
ツールの一覧が表示されます。
ツールボックスから、使いたいパーツをドラッグ&ドロップ
(全体のサイズも調整できます。)
配置の調整をします。配置は適当で大丈夫です
以上で、とりあえず準備ができました。
次回は、これを超単純なアプリに仕上げたいと思います。
2018年04月19日
《その364》Windowsユニバーサルアプリ(1)
「ユニバーサル Windows プラットフォーム開発」のインストール
このブログではこれまでずっと、C++ の出力結果を、コマンドプロンプト上で確認してきました。
C++ の学習という点から考えれば、やっと上っ面が理解できたかなっていう段階です。
本当は、これからがいよいよ本番で、学ぶことが山ほどあるわけなんですが、ちょっと脇道にそれてみようかなと思います。
これからしばらくの間、Windowsユニバーサルアプリがどんなものなのか、これも上っ面だけになってしまうと思いますが、少し調べてみたいと思います。
「ユニバーサル Windows プラットフォーム」でのプログラム作りは、C++ よりも C# のほうがやりやすいみたいですが、C++ しか知らないのでこれで行くしかありません。
私の Visual Studio 2017 は、Windowsユニバーサルを扱える設定になっていないので、
「Visual studio インストーラー」で追加のインストールが必要です。
ファイル(F) -> 新規作成(N) -> プロジェクト(P) -> Visual Studio インストーラーを開く
表示されるインストーラーの画面で、
「ユニバーサル Windows プラットフォーム開発」にチェックを入れて、変更ボタンを押します。
Windows 10 の設定変更
Windows 10 の設定変更も必要です。
設定 -> 更新とセキュリティ -> 開発者向け
表示されるラジオボタンで開発者モードを選択します。
2018年04月17日
《その363》コンテナデータのファイル処理
コンテナデータのファイル処理
コンテナとして、下記のプログラムでは、ベクトルコンテナを使用しています。
コンテナに格納するのは、クラス Student のオブジェクトです。
プログラムは、コンテナデータを score.txtファイルに書き出した後、記憶域上のデータを、一旦 消去します。
その後、プログラムは、データをファイルから読み込みなおして、それを画面に表示します。
以下は、プログラムです。
#include <fstream>
#include <iomanip>
#include <string>
#include <vector>
#include <iostream>
using namespace std;
class Student {
string name;
int score;
public:
Student(string s, int x)
: name(s), score(x) { }
string get_name() const{ return name; }
int get_score() const{ return score; }
};
int main() {
// ベクトルコンテナを作成します。
vector<Student>* pvec = new vector<Student> ;
// 以下のデータをベクトルコンテナに格納します。
pvec->push_back(Student("Nojima", 925));
pvec->push_back(Student("Shimano", 560));
pvec->push_back(Student("Sakagami", 810));
pvec->push_back(Student("Uesaka", 660));
pvec->push_back(Student("Kimura", 990));
pvec->push_back(Student("Muraki", 740));
ofstream fos("score.txt");
if (!fos) {
cout << "ファイルをオープンできません。";
}
else {
// データを、ファイル score.txt に書き出します。
for (vector<Student>::size_type i = 0; i < pvec->size(); i++)
fos << ' ' << (*pvec)[i].get_name()
<< ' ' << (*pvec)[i].get_score();
}
fos.close();
// ベクトルコンテナを delete して、
// 記憶域上のベクトルデータを消去します。
delete pvec;
// 新たにベクトルオブジェクト vec を作成し、
// この vec にファイルの内容
// を読み込みます。
vector<Student> vec;
ifstream fis("score.txt");
if (!fis) {
cout << "ファイルをオープンできません。";
}
else {
for (;;) {
if (fis.eof()) break;
string tmp1; int tmp2;
fis >> tmp1; fis >> tmp2;
vec.push_back(Student(tmp1, tmp2));
}
}
// コンテナ vec の内容を表示して、
// 読込みが成功していることを確認します。
for (vector<Student>::size_type i = 0; i < vec.size(); i++)
cout << right << setw(2) << i + 1 << ' '
<< setw(10) << left << vec[i].get_name()
<< vec[i].get_score() << '\n';
}
2018年04月16日
《その362》「関数へのポインタ」「データメンバへのポインタ」 の受渡し
「関数へのポインタ」「データメンバへのポインタ」 の受渡し
ブログの記事が多くなってきたので、「C++ 全記事目次」を右側に設置しました。
これで調べてみると、今回の記事は、《164》〜《166》辺りの復習ということになります。
下記のプログラムは複雑に見えますが、やっていることは非常に単純です。
Aaa型オブジェクト obj_a のデータメンバ num の値である 1326 と、str の値である "Yamada" を表示するだけなので、
内容的には、
cout << obj_a.num << '\n';
cout << obj_a.get_str() << '\n';
の2行で済む話です。
以下は、プログラムの説明です。
◆main関数は、データ出力用の関数 f を、2回呼び出します。
1回目と2回目の違いは、引数として渡す関数へのポインタが func1 であるか func2 であるか、だけです。
※関数名 func1, func2 は、その関数へのポインタとみなされます。
◆クラスのメンバへのポインタでは、ポインタ型、すなわち
・データメンバへのポインタ型
・メンバ関数へのポインタ型
が、少し複雑な形式なので注意が必要です。プログラムのコメントとコードをご覧ください。
◆main関数は、
クラスオブジェクト
クラスオブジェクトのデータメンバへのポインタ
クラスオブジェクトのメンバ関数へのポインタ
関数名
の4つを引数として、関数 f を呼び出します。
◆関数 f は、main関数から4つの引数を受け取ります。
それらを受け取る仮引数の書き方も少し複雑です。プログラムのコメントとコードをご覧ください。
◆関数 f は、main関数からの指示に従って、func1 あるいは func2 を呼び出します。
f_pointer(x, p, fp);
受け取った引数を、そのまま渡すだけなので簡単です。
◆関数 func1, func2 の3つの仮引数は、関数 f の引数と同じものです。
2つの関数 func1, func2 は、出力表示の形が少し違うだけです。
プログラムとしては、全く意味のないものですが、
・関数への ポインタ定義とその受渡し
・クラスのデータメンバへの ポインタ定義とその受渡し
・クラスのメンバ関数への ポインタ定義とその受渡し
を確認することができます。
以下は、プログラムです。
#include <string>
#include <iostream>
using namespace std;
class Aaa
{
string str;
public:
int num;
Aaa(string s, int n = 10)
: str(s), num(n) { }
string get_str() const{ return str; }
};
// 仮引数がわかりにくい形をしていますが、この説明は、
// 関数 f の仮引数のところでしています。
void func1(Aaa& x, int Aaa::* p, string (Aaa::* fp)() const)
{
// 間接ドット演算子を利用して、
// Aaa::num にアクセスしています。
cout << x.*p << '\n';
// メンバ関数へのポインタを使って、
// Aaa::get_str関数を呼び出します。
cout << (x.*fp)() << '\n';
}
void func2(Aaa& x, int Aaa::* p, string (Aaa::* fp)() const)
{
cout << "氏名 : " << x.*p << '\n';
cout << "番号 : " << (x.*fp)() << '\n';
}
void f(
// f_pointer は、
// 関数 func1 あるいは func2 を指すポインタ
// を受け取るための仮引数です。
// 関数の型を明記する必要があります。
void (*f_pointer)(Aaa&, int Aaa::*, string(Aaa::*)() const),
// x は、Aaa型オブジェクトへの参照を受け取るため
// の仮引数です。
Aaa& x,
// p は、Aaa型オブジェクトの int型データメンバ
// へのポインタを受け取るための仮引数です。
int Aaa::* p,
// fp は、Aaa型オブジェクトのメンバ関数 get_str
// を指すポインタを受け取るための仮引数です。
string (Aaa::* fp)() const
) {
cout << "------\n";
// 引数に受け取った関数 f_pointer、すなわち
// func1 または func2 を呼び出します。
// 引数 x, p, fp は受け取ったものをそのまま
// 使っています。
f_pointer(x, p, fp);
}
int main() {
// Aaa型オブジェクト obj_a を生成します。
Aaa obj_a("Yamada", 1326);
// ptr はデータメンバ Aaa::num を指すポインタです。
int Aaa::* ptr = &Aaa::num;
// fptr はメンバ関数 Aaa::get_str を指すポインタです。
string (Aaa::* fptr)() const = &Aaa::get_str;
// func1 は関数 func1 を指すポインタです。
f(func1, obj_a, ptr, fptr);
// func2 は関数 func2 を指すポインタです。
f(func2, obj_a, ptr, fptr);
}