スマホに親しんだ若者がWindows 10で現代的な C++/Win32 のプログラムを作る場合に役立てばいいなと思って作りました。
文字がわからなければ、親か先生に「あいうえお」と「アルファベット」を教えてもらって下さい。
パソコンの使い方が分からなければ、パソコン関係の本を調べる。Windowsを知らなければWindowsの本を調べる。
単語がわからなかったらGoogleで調べる。https://google.co.jp
漢字がわからなかったら漢和辞典を見る。
無関係なことや細かいことは飛ばしてもよい。
調べても調べてもわからなかったらひとまず、ほっといて先読みしてみる。
高機能なテキストエディタ(サクラエディタ、秀丸、VS Code など)をダウンロード&インストールする。この本ではサクラエディタの使用を推奨する。
サクラエディタ https://sakura-editor.github.io/download.html
テキストエディタを起動して文字を書いて保存する。保存するには、右上の「ファイル」メニューから「上書き保存」を選ぶ。
ファイルを編集したいなら、テキストエディタにファイルアイコンをドラッグ&ドロップしてそれを開き、エディタで編集して保存する。
キーボードの左上の「半角/全角」キーを押すと、日本語入力モードに入ったり出ることができる。日本語入力モードで適当に入力して「変換」キーを押して漢字交じりに変換、Enterキーで確定を繰り返すと日本語が入力できる。
以下の2つの文字列を比較してほしい:
- "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789#!@"
- "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789#!@"
前者が全角(ぜんかく)文字で、後者が半角(はんかく)文字である。昔のパソコンでは全角文字は半角文字の二倍の幅を持っていた。半角文字の多くは英語のASCII文字と互換性があり、英語圏でも同じデータでやり取りできるが、全角文字を日本語ではないパソコンで表示しようとすると問題が発生することがある。
プログラミングでは主に半角文字を使う。
プログラミングで使うファイルや識別子の名前は、基本的に日本語や全角文字は使えないと考えた方がいいだろう。ファイル名には使えない特殊な文字がいくつかある。
ファイル名は1字でも間違うと動かないことがあるので、全角半角の区別、大文字小文字の区別ができるようになろう。
Windowsではファイル名には大文字小文字の区別がないが、他のシステムでも使うファイルについては大文字小文字を意識する必要がある。
ファイル名の最後に「.txt」「.png」などのドット(dot)で始まる文字列が付いているのが拡張子。
拡張子は半角でなければならない。Windowsでは拡張子がファイルの種類を区別している。拡張子が1字でも違うとファイルが開かないことがある。
https://ja.wikipedia.org/wiki/%E6%8B%A1%E5%BC%B5%E5%AD%90
拡張子が見えなければ、Windowsで拡張子が見える設定にしないといけない。開発現場では拡張子表示は必須。
フォルダとは、ファイルを入れる入れ物であり、エクスプローラやデスクトップを右クリックして出てくる「新規作成」メニューの「フォルダー」を選べば作成できる。さらにフォルダの中に別のフォルダや複数のファイルを入れることができる。ファイルをまとめたり、分類するときに便利だ。
例えば、Windows 10 には、C:
ドライブにWindows
というフォルダ(C:\Windows
)があり、この中にWindowsのシステムファイルが含まれている。さらにこの中にsystem32
フォルダ(C:\Windows\system32
)がある。
C:
ドライブのルートに「dev」というフォルダを作り、その中に「cxx」「bash」というフォルダを作ってみよう。
この C:\Windows\system32
というのが、フォルダのパス(path)と呼ばれる文字列で、フォルダの位置を表す。passwordとまぎらわしいので、混同しないように。\
(バックスラッシュ)は、パスの区切りと呼ばれる。パスの区切りは環境によって異なり、Windowsでは\
であり、Bashでは/
(スラッシュ)である。
パスは、相対的な位置を表す「相対パス」と、絶対的な位置を表す「絶対パス」に分類される。
1個のドット(.
)は、現在のフォルダを表す特殊なフォルダ名で、2個のドット(..
)は、一つ上のフォルダを表す特殊なフォルダ名である。例えば、C:\Windows\system32\..
はC:\Windows\system32
の一つ上、すなわち、C:\Windows
と同じ意味である。
C:\Windows\system32
は絶対パスで、..\system32
は相対パスである。
テキストデータの中から素早く文字列を探すには、検索機能を使う。サクラエディタでは、Ctrl+F
キー(Ctrl
キーを押しながらF
キー)で検索を開始できる。
複数のテキストファイルからある文字列を探すには、サクラエディタでgrep
(グレップ)機能を使う(「検索」メニュー→「Grep...」)。
Windowsでは、ファイルを開くと、ファイルが変更されないようにロックすることができる。ロックされたファイルは開いたり、変更できない。ファイルが開けない場合は、すでに開いているプログラムがないか確認しよう。
Windowsのプログラムのほとんどは、.exe
という拡張子を持ったEXEファイルで出来ている。EXEファイルをダブルクリックするとプログラムを起動できるかもしれない。.exe
の実行に必要なDLL
ファイル(*.dll
)が足りないと、実行に失敗する。
Windowsで実行したプログラムは、「プロセス」という単位で実行される。プロセスはタスクバーを右クリックすれば出てくる「タスクマネージャ」から操作できる。1個のEXEファイルから複数のプロセスを同時に起動できる。
プロセスは、使用しているEXEファイルとDLLファイルをロックする。そのため、実行中はEXEファイルを変更できないので、ビルドの前にそのプログラムを終了させる必要がある。終了できない場合はタスクマネージャからプロセスを強制終了しよう。
WindowsでC/C++コンパイラを使いたい場合、Visual Studio か MSYS2 を使うといい。Visual Studio(以下VS)はパワフルな統合開発環境(IDE)で非常に使いやすい。MSYS2はCUIベースの開発環境で、低スペックのPCでも使える。MSYS2は最小限のWindows開発環境「MinGW」にLinuxライクなBashシェルを追加したようなもので、ちょびっとLinux風に使える開発環境だ。
簡単なプログラムをコンパイルしたい場合は、最近ではオンラインコンパイラという選択肢もあるが、ソースファイルが1つしか使えないとか、そもそもWin32をサポートしていないなどの制限がある。
今回は次のようなC++プログラムを試してみる。
#include <cstdio>
int main(void)
{
printf("Hello, world\n");
}
念のため、プログラミングで使う記号について確認しよう。以下は半角英数モードで入力する。
#include
の#
はシャープ記号で、キーボードのShift
キーを押しながらキーボード左上の「3
」を押せば入力できる。<cstdio>
の<
と>
は、不等号であり、Shift
キーを押しながら「ね
」、もしくは「る
」を押せば入力できる。(
と)
は、丸カッコであり、Shift
キーを押しながらキーボード中央の「8
」または「9
」を押せば入力できる。"
は、二重引用符であり、Shift
キーを押しながらキーボード左上の「2
」を押せば入力できる。\
は、バックスラッシュ(\)または半角の円記号(¥)であり、半角英数モードでキーボード右下の「ろ
」を押せば入力できる。;
は、セミコロンである。半角英数モードでキーボードの「け
」を押せば入力できる。
オンラインコンパイラ codepad.org
を使ってみよう。http://codepad.org を開き、C++
を選び、次のようにC++プログラムを記述する:
#include <cstdio>
int main(void)
{
printf("Hello, world\n");
}
そして間違いがないか確認して、Submit
ボタンを押せば、Hello, world
というメッセージがOutput
(出力)に表示される。
エラーが発生したときは、エラーメッセージを読み、どの行番号でエラーが発生しているのかを確認して、全角半角、大文字小文字、記号の違いに注意して修正し、再びSubmit
ボタンを押してやり直す。
https://gist.github.com/Hamayama/eb4b4824ada3ac71beee0c9bb5fa546d
MSYS2にパッケージを追加する場合は、GUIを使わず、pacman
というパッケージマネージャで追加する。
pacmanでcmake、gcc、g++、makeをインストールする。
- MSYS2 を普通に起動する。黒い画面が開かれる。
- Linux ライクなシェル「Bash」が使えるので、Bash のコマンドをいくつか試す。
https://qiita.com/zayarwinttun/items/0dae4cb66d8f4bd2a337
※ Windows のショートカットファイルを活用すれば、起動が楽になるかも。
cd (パス名)
は現在のフォルダ位置を移動するコマンド。
cd ..
は一つ上のフォルダへ移動するコマンド(ドットが2つ)。
ls
は現在のフォルダのファイル一覧を表示するコマンド。
mkdir (フォルダ名)
は、現在の位置にフォルダを作成するコマンド。
start .
は現在のフォルダを開くコマンド。
C++を使う場合は、VS の「Visual C++」が必要。「Visual C++」を選んでインストールすること。
古いWindows(XPとか)をサポートしないなら、VS のバージョンは最新のもの (VS 2019) でよい。 あなたが古代人で、Windows 2000をサポートしたいなら VS 2008からインストールする。 Windows XP以降をサポートしたいなら、VS 2012 以前をインストールすること。
古いバージョンのVSから順番にインストールするとうまくいく。
VSとMSYS2共通のビルドシステムとして CMake を使う。CMakeはLinuxやMacでも使える、クロスプラットフォームなビルドシステムである。
CMake https://cmake.org/
VS用のCMakeとMSYS2用のCMakeを別々にインストールする必要がある。VS用はGUIのインストーラを使ってMSYS2の外側にインストールする。MSYS2にはpacman
というパッケージマネージャでMSYS2の内部にCUIのCMakeをインストールする。MSYS2 には、特別なCMakeが用意されており、それはpacman
でインストールする。MSYS2ではCMakeをGUIでインストールしないことに注意しよう。VS用のCMakeをインストールするときは、MSYS2に影響しないよう、PATH環境変数を変更しない設定にしよう。
最近のVSには、CMakeが付属しているので、それを使うと簡単かもしれない(未確認)。
- プロジェクトのフォルダに
CMakeLists.txt
というテキストファイルを作成する。CMakeLists.txt
には、プロジェクトのビルド方法を特殊な言葉で記述する。 - CMakeプログラムを起動して
CMakeLists.txt
からビルドに必要なMakefile
ファイルもしくはプロジェクトファイルを生成させる。 - 生成されたファイルを使ってプロジェクトをビルドする。
まずは試しに、黒いコンソール画面に「hello, world!
」と表示させるC/C++プログラムを作ってみよう。
次のようなコマンドで適当な名前のフォルダ(例えば hello
)を作る。
$ mkdir hello
$ cd hello
$ start .
フォルダhelloの中に次のような内容のテキストファイル hello.cpp
を作る。
#include <stdio.h>
int main(void)
{
printf("hello, world!\n");
return 0;
}
テキストファイルCMakeLists.txt
を作る。
cmake_minimum_required(VERSION 2.4)
project(hello CXX)
add_executable(hello hello.cpp)
ここでcmake_minimum_required(VERSION 2.4)
はCMakeのバージョンを指示するための「おまじない」である。project(hello CXX)
は、プロジェクト名(ここではhello
)と言語(ここではCXX
、すなわちC++)を指定している。add_executable(hello hello.cpp)
は、実行可能ファイル(executable)の名前(hello
)と作成方法を指定している。
フォルダに移動して CMake でビルドする。EXEファイルhello.exe
ができればビルド成功。
$ cd hello # hello フォルダに移動。
$ cmake -G "MSYS Makefiles" . # CMake を実行する。
$ make -j3 # make でビルドする。
$ ls *.exe # ファイルの存在確認。
hello.exe
hello.exeを実行してみる。
$ ./hello.exe
hello, world!
実行して、hello, world!
と表示されれば成功。このプログラムはprintf関数を使うだけの純粋なC/C++のコンソールプログラムである。次はWin32プログラムを作ってみよう。
./hello.exe
というのは、「現在のフォルダのhello.exe
」を意味する。Bashでは情報セキュリティのため、./
を指定しないといけない。
HelloWin32
というフォルダを作成し、その中に次のようなhello.cpp
ファイルを作成する。
#include <windows.h>
int main(void)
{
MessageBoxA(NULL, "Hello, Win32", "HelloWin32", 0);
return 0;
}
さらにテキストファイルCMakeLists.txt
を作る。
cmake_minimum_required(VERSION 2.4)
project(HelloWin32 CXX)
add_executable(HelloWin32 WIN32 HelloWin32.cpp)
ここで、add_executable
にWIN32
を指定していることに注意しよう。これはコンソールアプリじゃなくて、Win32アプリであることを意味する。ビルドしてみよう。
$ cd HelloWin32 # HelloWin32 フォルダに移動。
$ cmake -G "MSYS Makefiles" . # CMake を実行する。
$ make -j3 # make でビルドする。
ビルドが完了したらHelloWin32.exe
を実行してみる。
$ ./HelloWin32.exe
メッセージボックスが表示されれば成功。しかし、HelloWin32.exe
をダブルクリックすると実行に失敗する。これはHelloWin32.exe
にMSYS2に依存するDLLがあるためだ。-static
コンパイルオプションを指定すれば、静的リンクになり、ダブルクリックでも実行できる。CMakeでそれを指定するのは、次のように記述する。
cmake_minimum_required(VERSION 2.4)
project(HelloWin32 CXX)
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
# using Clang
set(CMAKE_C_FLAGS "-static")
set(CMAKE_CXX_FLAGS "-static")
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
# using GCC
set(CMAKE_C_FLAGS "-static")
set(CMAKE_CXX_FLAGS "-static")
elseif (MSVC)
# replace "/MD" with "/MT" (building without runtime DLLs)
set(CompilerFlags
CMAKE_C_FLAGS
CMAKE_C_FLAGS_DEBUG
CMAKE_C_FLAGS_RELEASE
CMAKE_C_FLAGS_RELWITHDEBINFO
CMAKE_CXX_FLAGS
CMAKE_CXX_FLAGS_DEBUG
CMAKE_CXX_FLAGS_RELEASE
CMAKE_CXX_FLAGS_RELWITHDEBINFO)
foreach(CompilerFlags ${CompilerFlags})
string(REPLACE "/MD" "/MT" ${CompilerFlags} "${${CompilerFlags}}")
endforeach()
endif()
add_executable(HelloWin32 WIN32 HelloWin32.cpp)
ダイアログボックス(dialog box)という仕組みを使えば、ボタンを押したりテキストボックスに入力するなど、GUIで対話的なWin32プログラムが作成できる。
ダイアログボックスを作成するには、リソーエディタを使う。
リソーエディタ https://katahiromz.web.fc2.com/re/ja/
まずは、リソーエディタをGUIで普通にインストールする。
- リソーエディタを起動する。
ウェブサービスを利用するためには、ユーザIDとパスワードを使ってログインすることが、個人認証のために必要。
まず、名無しで活動するか、実名で活動するか考える。実力がないなら実名は避けたほうがいい。
アルファベットと数字を組み合わせて、適当に自分のユーザIDを決める(覚えやすいのがいい)。
パスワードは十分長くて(12字以上)推測されにくいものを使う(短かったり、単純だと簡単にハッキングされる)。
ユーザIDとパスワードは家のカギのように大事。わすれないようにしよう。
パスワードはサービスごとに分けた方がいい。
GMail はGoogleが運営するウェブメールサービスだ。GMail でメールアドレスを取得する。必要事項を入力する。ログインすれば使えるようになる。
GMail https://mail.google.com
GitHubは有用なソースコードがごろごろ転がっていて開発の参考になる。
メールアドレスを使ってGitHubでアカウントを取得する。
GitHub https://github.com
ローカルでGitの初期設定が必要。
https://qiita.com/wnoguchi/items/f7358a227dfe2640cce3
GitHubにログインしたら緑色の「New」ボタンを押して新規レポジトリを作成する。表示された画面に従ってGitコマンドをいくつか入力すれば GitHubのレポジトリを作成できる。レポジトリ名は「test」。
$ mkdir test # testフォルダを作成。
$ cd test # testフォルダへ移動。
$ echo "# test" >> README.md # README.mdファイルを作成。
$ git init # ローカルレポジトリの初期化。
$ git commit -m "first commit" # コミット。
$ git remote add origin https://github.com/katahiromz/test.git # リモートレポジトリの設定。
$ git push -u origin master # プッシュ(アップロードされる)。
最後のコマンドでユーザIDとパスワードが要求されるので入力する(入力内容は画面に表示されない)。
再び緑色の「New」ボタンを押してhello.cpp
を全世界に公開しよう。
$ cd .. # 一つ上のフォルダへ移動。
$ cd hello # helloフォルダへ移動。
$ git init # ローカルレポジトリの初期化。
$ git add hello.cpp CMakeLists.txt # レポジトリにファイルを追加。
$ git commit -m "first commit" # 追加したファイルをコミット。
$ git remote add origin https://github.com/katahiromz/hello.git # リモートレポジトリの設定。
$ git push -u origin master # プッシュ(アップロード)。
https://github.com/katahiromz/hello.git
のkatahiromz
には自分のIDが入る。
.gitignore
ファイルはテキストファイルで、改行区切りで無視したいファイルのパターン(ワイルドカード)を記載する。
ビルドなどでフォルダやファイルが勝手に作られるが、それをレポジトリには含めたくないとき、本質的に重要ではないファイルやフォルダ、でかすぎるファイルなどは、.gitignore
に記載するとよい。記載例は下の通り。
*.autosave
*.cmake
*.dir
*.exe
*.filters
*.idb
*.map
*.ncb
*.o
*.obj
*.opensdf
*.res
*.sdf
*.sln
*.suo
*.tds
*.user
*.vcproj
*.vcxproj
*~
.vs
CMakeCache.txt
CMakeFiles
Debug
Makefile
Release
TMP1.$$$
build
ipch
x64
*-old
*.skrold
ワイルドカードでは、*
(アスタリスク)と?
(疑問符)は特殊な意味がある。*
は任意の0文字以上の文字列にマッチする。
この.gitignore
ファイルをレポジトリに追加しておく。
$ git add .gitignore
$ git commit -m "add .gitignore"
$ git push
この.gitignore
ファイルを追加しておけば、git status
の実行結果に無視ファイルが出てこないし、git add -A
しても無視ファイルは追加されない。
新しいフォルダhello-win32
に以下の内容のhello-win32.cpp
を作成する。
#include <windows.h>
INT WINAPI
WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
INT nCmdShow)
{
MessageBoxA(NULL, "This is a Win32 application", "Hello, Win32", MB_ICONINFORMATION);
return 0;
}
Win32
アプリではmain関数ではなくWinMain関数がメイン関数になる。
CMakeLists.txt
ファイルを作成する。
cmake_minimum_required(VERSION 2.4)
project(hello-win32 CXX)
add_executable(hello-win32 WIN32 hello-win32.cpp)
add_executable
にWIN32
という記述が増えていることに注意。
CMakeとmakeでビルドする。
$ cd hello-win32
$ cmake -G "MSYS Makefiles" .
$ make -j3
実行するとGUIでメッセージボックスが表示されるだろう。
$ ./hello-win32