■ VC++2017で、新規のWindowsフォームアプリケーションをつくる方法 | |
VC++ 2015までは、新規のWindowsフォームアプリケーションを何とかつくることができましたが、VC++ 2017では新規のWindowsフォームアプリケーションをつくることが極めて難しくなってしまったようです。( → URL ) 新規のWindowsフォームアプリケーションは VC#で作成してほしいというのがマイクロソフトの方針と思われます。サポート費用削減なのでしょうか? サンプルコードやツール類は
C++よりも遙かに C# の方が充実しています。 過去のしがらみがなく全くなく、新規にWindowsフォームアプリケーションをつくる場合はVC#でつくる方がよいと思います。 VC++ 2017ではWindowsフォームアプリケーションの新規作成が大変難しくなりましたが、 既存のWindowsフォームアプリケーションの変更はサポートされています。 したがって、VC++ 2017で新規のWindowsフォームアプリケーションを作りたい場合は VC++2017より前のバージョンで作成した新規のプロジェクトを、VC++ 2017で開き変更する方法でアプリケーションを新規作成する方法がよいと思います。 VC++2010で新規作成したブランクのプロジェクトファイルを以下にダウンロードできるようにしてあります。必要な方は、ご利用ください。 ( → URL ) <参考> 以下、上記URLからダウンロードしたファイルを利用した場合です。 @はじめてプロジェクトファイル開いた時にでるダイアログ画面です。 [Windows SKD バージョン] 及び[プラットフォームツールセット] は、いずれも "アップグレードなし" に変更して OKをクリックします。 これらをアップグレードすると (最新のコンパイラと相性が悪いようで)多々警告がでたりします。 ![]() (クリックで拡大します) AダウンロードしたプロジェクトファイルをVC++ 2017で開いたあと、ヘルプのダイアログを開きバージョンを確認した画面です。 ![]() (クリックで拡大します) |
■ フォームに ”Hello World !!" を表示する
フォームへ ”定番の”Hellow World !!”を表示するソースコードです。 VC++の場合、やり方はいろいろありますが フォームにラベルコンポーネントを貼り付けるMVC(Model
View Controller)による方法です。 <Form1.h 抜粋> |
||
public: Form1(void) { InitializeComponent(); label1->Text = ""; } private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) { label1->Text = "Hello World !!"; } |
![]() |
|
■ DOS窓(コンソール)に”Hellow World !!”を表示する
DOS窓(コンソール)に”Hellow World !!”を表示する方法は大きく分けて3つあります。 @ C言語版 A C++版 B C++/CLI版(.NET版) <プロジェクト作成要領> [ファイル]→[新規作成]→[プロジェクト] 新しいプロジェクトダイアログ: [VC++]→[Win32]→[Win32コンソールアプリケーション] →「プロジェクト名設定」 Win32アプリケーションウィザート:空のプロジェクトチェックボックス→ON ソリューションエクスプローラ:プロジェクト名右クリック→プロパティのページを表示 プロジェクトのプロパティ:構成→すべての構成: 全般:共通ランタイムサポート→共通言語ランライム(/clr) ★ ブレークポイントを return 0 の後において実行した場合、コンソールウィンドウがVisual Stadioの ウィンドウの後ろ側となり見えなくなっている時があります。 |
![]() |
|
@ C言語版 プログラム例 |
||
#include <stdio.h> int main() { printf("Hellow World !! \n"); return 0; } |
||
A C++版 プログラム例 |
||
#include<iostream> int main() { std::cout<<"Hellow World !!\n"; return 0; } |
||
B C++/CLI 版 ( .NET版 )プログラム例 |
||
using namespace System; int main() { Console::Write("Hellow World !! \n"); return 0; } |
|
コンソールアプリケーションの場合、[ Ctrl ] + [ F5 ] または [デバック]→[デバックなし]で実行するとプログラム終了後、コンソール ウィンドウは自動的に閉じなくなります。 |
![]() |
プログラムを停止して表示しておきたいソースコードの箇所に While(1); を追加する ![]() |
![]() |
VC++で scanf()を使うと 以下のようなエラーがでてしまいます。 これはscanf()が、確保しているメモリより多くの入力データをキーボードなどから入力した場合メモリデータを破壊してしまう安全でない(危険な)関数であるのでVC++では使用を禁じているためです。 例の
2. 文字入力で 50文字以上(51文字以上ではない 以て、文字列の末尾に\0がつく)打鍵するとアプリ実行中にメモリ破壊が発生してしまいます。 エラー C4996 'scanf': This function or variable may be unsafe. Consider using scanf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. 安全でない危険な関数ですが注意して使う場合は、プロセッサに対して以下の命令を追記することで 非安全で危険な関数の使用許可をだすことになり、scanf()が使えるようになります。 #pragma warning(disable: 4996) //参照 → URL (例) |
|||
#include <stdio.h> #pragma warning(disable: 4996) //特定のコード行に対するエラー/警告をオフにする //scanfに対するエラー/警告をオフにする int main() { //1. 数値入力 int a = 0; printf("数値を入力してください\n"); scanf("%d", &a); printf("a = %d", a); printf("\n\n"); //2. 文字入力 char str[50]; printf("文字列を入力してください\n"); scanf("%s", str); printf("%s\n", str); return 0; } |
|||
<実行結果> | |||
数値を入力してください 256 a = 256 文字列を入力してください Hellow Hellow 続行するには何かキーを押してください . . . |
|||
VC++では、scanf()の代わりに 安全になったscanf_s() と云うC11(注) 以降に標準ライブラリ関数に追加された関数が推奨されています。ただし、オプション扱い (注) 2011年にISO から発行された Cの 標準規格です。 |
|||
#include <stdio.h> int main() { //1. 数値入力 int a = 0; printf("数値を入力してください\n"); scanf_s("%d", &a); printf("a = %d", a); printf("\n\n"); //2. 文字入力 char str[50]; printf("文字列を入力してください\n"); scanf_s("%s", str); printf("%s\n", str); return 0; } |
|||
<実行結果> | |||
数値を入力してください 256 a = 256 文字列を入力してください Hellow 続行するには何かキーを押してください . . . |
|
以下のようにすることにより引数を取得できます。 @メニュー: [プロジェクト] → 「○○○○のプロパティ] → ○○○○のダイアログが開く A○○○○ダイアログ: 構成: 「デバック」を選択 構成のプロパティ: 「デバック」を選択 コマンド引数欄: △△△△ □□□□ ▲▲▲▲ ★ コマンド引数欄に所要の引き数△△△△ □□□□ ▲▲▲▲を記載する。文字列の区切りは半角の空白です。 ★ プログラム例はコマンド欄に下記引数jを記載した場合です。 Hellow World !!!! temp.bmp |
− |
<プログラム例> int main(int argc, char *argv[] ) { char *p; int i; for(i=0; i<argc; i++) { p=argv[i]; printf("argv[%d]= %s\n",i,p); } return 0; } |
− | |
|
![]() |
− |
■ 例外処理
数値にならない文字列をテキストボックスに入れて 合計ボタンをクリックすると例外が発生します。
<プログラム例> Form1.h抜粋 |
||
<プログラム例> public: Form1(void) { InitializeComponent(); textBox1->TextAlign = HorizontalAlignment::Right; //文字を右端へ textBox2->TextAlign = HorizontalAlignment::Right; //文字を右端へ textBox3->TextAlign = HorizontalAlignment::Right; //文字を右端へ } private: System:: Void button1_Click(System::Object^ sender, System::EventArgs^ e) { double d; System::Windows::Forms::DialogResult ret; //MessageBoxボタンの戻り値 String^ str1 = textBox1->Text; String^ str2 = textBox2->Text; try // { d = Convert::ToDouble(str1) + Convert::ToDouble(str2); //文字列を実数へ変換 //Convert::ToInt32(str) } catch(Exception^ ) { ret = MessageBox::Show( "実数を入力してください", //表示文字列 "実数に変換できません", //タイトルバー文字列 MessageBoxButtons::YesNoCancel, //表示されるボタンの種類 MessageBoxIcon::Information, //表示されるアイコンの種類 MessageBoxDefaultButton::Button1//(表示されるボタンのなかで) //デフォルト扱いボタンの指定); if(ret == System::Windows::Forms::DialogResult::No)Form1::Close(); //フォームを閉じる else { textBox1->Text = ""; textBox2->Text = ""; textBox3->Text = ""; return; } } textBox3->Text = d.ToString(); //文字列に変換して表示 } |
<数字を入れた場合> ![]() <数字に変換できない文字を入れた場合> ![]() |
■ ポインタ渡し
VC++での ポインタ渡しの関数の例です ボタンをクリックすると ポインタを渡した関数で+1をインクリメントしたものを表示するプログラムです |
<プログラム例> private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) { int* ptr1; int value1 = 100; ptr1 = &value1; //ポインタを初期化(アドレスをセット)//*ptr1 = value1; はNG myFunc1(ptr1); textBox1->Text = String::Format("{0}",*ptr1); } private: void myFunc1(int* ptr) { *ptr = *ptr+ 1; } //------------------------------------------------------------ private: System::Void button2_Click(System::Object^ sender, System::EventArgs^ e) { int value2 = 200; myFunc2(&value2); //ポインタ宣言を省略して直接渡し textBox2->Text = String::Format("{0}",value2); } private: void myFunc2(int* ptr) { *ptr = *ptr+ 1; }
|
<実行結果>![]() |
■ フォームを追加する
下記要領で追加します。
@[プロジェクト]→[新しい項目の追加]→新しい項目のウィンドウ
A新しいウィンドウのVisual C++のUI、Windowsフォームを選択 → フォームを追加する。
B命名したフォームのヘッダーファイルをメインフォームのヘッダーファイルにグローバルにインクルード
C追加フォームクラスのインスタンスを生成し、ShowDialog()メソッドで開く
<プログラム例> Form1h 抜粋 |
||
#include "OptionForm.h" //追加したOptionformのヘッダーファイルをインクルード namespace Form_Add { using namespace System; using namespace System::ComponentModel; using namespace System::Collections; using namespace System::Windows::Forms; using namespace System::Data; using namespace System::Drawing; public ref class Form1 : public System::Windows::Forms::Form { public: Form1(void) { InitializeComponent(); } private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) { OptionForm^ optfrm = gcnew OptionForm(); //追加のフォームのインスタンスを生成 optfrm->ShowDialog(); //フォームを開く }
|
![]() |
<プログラム例>
main() { }