G++でコンパイル、ビルドできるwindowsプログラム

 今では開発環境が充実しており「簡単に」ウィンドウプログラムを開発することが出来ます。しかし、生成されるプログラムは色々なDLLやコンポーネントが必要であることが多いです。ビルドすると色々なファイルが生成されるわけです。

ただ、こちらとしては一個のEXEファイルだけで十分なわけです。今回はそのニーズにこたえるコードを説明します。

このコードは簡易的なテキストエディタです。元々はChatGPTに作成してもらった、単機能なものです。コピペ、簡単な編集、表示内容の拡大縮小が出来ます。通信や管理できない領域へのデータ保存は一切していないので安心です。

実用品としても十分使えますが、簡易的な開発実験も出来るファイルだと考えます。以下がソースコードです。

  1. #include <windows.h>
  2. /*
  3. メモ代わりに使える通信機能も保存機能もないエディタです。
  4. パスワードやメモなどセキュリティー的に危ない物を一時的に保管するのに役立ちます。
  5. G++で各自がコンパイルすれば危ない機能とか事前に確認できます。
  6. 試用する前にコードレビューも出来るので安心して使ってください。
  7. コンパイル・ビルド方法
  8. g++ -o hoge.exe piyo.cpp -mwindows
  9. */
  10. // メニューアイテムのID
  11. #define IDM_FONT_SIZE_INCREASE 101
  12. #define IDM_FONT_SIZE_DECREASE 102
  13. #define IDM_ALLSELECT 103
  14. //定数
  15. #define FONT_SIZE_MIN 10
  16. #define FONT_SIZE_MAX 100
  17. //アクセラレーターテーブル
  18. ACCEL accel[] = {
  19.   { FCONTROL | FVIRTKEY, 'W', IDM_FONT_SIZE_INCREASE },
  20.   { FCONTROL | FVIRTKEY, 'S', IDM_FONT_SIZE_DECREASE },
  21.   { FCONTROL | FVIRTKEY, 'A', IDM_ALLSELECT },
  22.  };
  23. // フォントサイズを変更する関数
  24. void ChangeFontSize(HWND hTarget,HFONT *pfFont,int delta) {
  25.     LOGFONTW lf;
  26.     GetObjectW(*pfFont, sizeof(LOGFONTW), &lf);
  27.     lf.lfHeight += delta;
  28.     if (lf.lfHeight < FONT_SIZE_MIN) {
  29.         lf.lfHeight = FONT_SIZE_MIN;
  30.     }
  31.     if (lf.lfHeight > FONT_SIZE_MAX) {
  32.         lf.lfHeight = FONT_SIZE_MAX;
  33.     }
  34.     DeleteObject(*pfFont);
  35.     *pfFont = CreateFontIndirectW(&lf);
  36.     SendMessageW(hTarget, WM_SETFONT, (WPARAM)*pfFont, TRUE);
  37. }
  38. // ウィンドウプロシージャ
  39. LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
  40. static HWND hEdit;
  41. static HMENU hMenu;
  42. static HFONT hFont;
  43.     
  44.     switch (uMsg) {
  45.         case WM_COMMAND:
  46.             // メニューアイテムが選択された場合
  47.             switch (LOWORD(wParam)) {
  48.                 case IDM_FONT_SIZE_INCREASE:
  49.                      ChangeFontSize(hEdit,&hFont,2);
  50.                     break;
  51.                 case IDM_FONT_SIZE_DECREASE:
  52.                      ChangeFontSize(hEdit,&hFont,-2);
  53.                     break;
  54.                 case IDM_ALLSELECT:
  55.                      SendMessage(hEdit, EM_SETSEL, 0, -1);
  56.                     break;
  57.             }
  58.             break;
  59.         case WM_CREATE:
  60.             // エディットコントロールを作成
  61.             hEdit = CreateWindowExW(WS_EX_CLIENTEDGE, L"EDIT", L"", WS_CHILD | WS_VISIBLE | WS_VSCROLL | ES_MULTILINE | ES_AUTOVSCROLL,
  62.                                     10, 10, 400, 300, hwnd, (HMENU)0, GetModuleHandleW(NULL), NULL);
  63.  // メニューを作成
  64.             hMenu = CreateMenu();
  65.             AppendMenuW(hMenu, MF_STRING, IDM_FONT_SIZE_INCREASE, L"拡大 ctrl+W");
  66.             AppendMenuW(hMenu, MF_STRING, IDM_FONT_SIZE_DECREASE, L"縮小 ctrl+S");
  67.             AppendMenuW(hMenu, MF_STRING, IDM_ALLSELECT, L"全選択 ctrl+A");
  68.             SetMenu(hwnd, hMenu);
  69.             // デフォルトフォントを設定
  70.             hFont = CreateFontW(32, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_OUTLINE_PRECIS,
  71.                                 CLIP_DEFAULT_PRECIS, CLEARTYPE_QUALITY, DEFAULT_PITCH | FF_DONTCARE, L"Arial");
  72.             SendMessageW(hEdit, WM_SETFONT, (WPARAM)hFont, TRUE);
  73.             break;
  74.         case WM_SIZE:
  75.              // ウィンドウサイズが変更された場合、エディットコントロールも調整
  76.             MoveWindow(hEdit, 10, 10, LOWORD(lParam) - 20, HIWORD(lParam) - 20, TRUE);
  77.             break;
  78.         case WM_DESTROY:
  79.             // 終了時にメモリを解放
  80.             PostQuitMessage(0);
  81.             break;
  82.         default:
  83.             return DefWindowProcW(hwnd, uMsg, wParam, lParam);
  84.     }
  85.     return 0;
  86. }
  87. // エントリーポイント
  88. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
  89.     
  90.     // ウィンドウクラスの登録
  91.     WNDCLASSW wc = {0};
  92.     wc.lpfnWndProc = WindowProc;
  93.     wc.hInstance = hInstance;
  94.     wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
  95.     wc.lpszClassName = L"SimpleEditWindowClass";
  96.     RegisterClassW(&wc);
  97.     //アクセラレーターテーブルの作成
  98.     HACCEL hAccel = CreateAcceleratorTableA(accel,sizeof(accel)/sizeof(accel[0]));
  99.     
  100.     
  101.     // ウィンドウの作成
  102.     HWND hwnd = CreateWindowExW(0, L"SimpleEditWindowClass", L"シンプルテキストメモ", WS_OVERLAPPEDWINDOW,
  103.                                 CW_USEDEFAULT, CW_USEDEFAULT, 640, 480, NULL, NULL, hInstance, NULL);
  104.     // ウィンドウ表示
  105.     ShowWindow(hwnd, nCmdShow);
  106.     UpdateWindow(hwnd);
  107.     // メッセージループの処理(アクセラレーターテーブルの処理付)
  108.     MSG msg;
  109.    while (GetMessage(&msg, NULL, 0, 0))
  110.     {
  111.         if (!TranslateAccelerator(hwnd, hAccel, &msg))
  112.         {
  113.             TranslateMessage(&msg);
  114.             DispatchMessage(&msg);
  115.         }
  116.     }    
  117.     
  118.     return static_cast<int>(msg.wParam);
  119. }

このコードを「hoge.cpp」という名前で保存してから、「g++ -o hoge.exe piyo.cpp -mwindows」でコンパイル、ビルドすると piyo,exe が作成されます。その実行ファイルを開くことで簡易的なテキストエディタを表示させることが出来ます。

ぜひ、プログラミングの入門として活用してみて下さい。コードの追加も普通なCやC++の知識で可能です。分からない人は以下の本で勉強してみて下さい。

ウィンドウズアプリ入門 クリップボードにコピーされたらメッセージを受信する方法

 Windowsアプリでコピーされたときにイベントを取得できると便利です。例えばコピーされた内容を画面に表示したい場合などです。 もちろんタイマーイベントで定期的にポーリングをする方法もありますが、やや無駄な処理かもしれません。 Windowsとしてはコピーされたときのイベントを...