- このオープンソースプロジェクトは、CとWin32 APIだけで作られた軽量なネイティブWindows Todoアプリケーション
- フレームワークに依存せず、最小容量(最大26.5KB)で動作し、高度なWindows GUIとシステム統合を直接実装
- Todo項目の追加、編集、削除、完了表示といった基本機能に加え、システムトレイ統合や自動起動オプションなど、実用的な生産性機能を提供
- 保存はバイナリファイルで永続化され、AppDataフォルダに最大100件のToDoリストを保存
- 大規模フレームワークなしでOSに非常に密着した古典的なプログラミング手法と、軽い実行環境が強み
🌟 Simple Todo (C / WinAPI)
プロジェクト概要
- このプロジェクトは、CとWin32 APIだけを使ってモダンなネイティブWindows Todoアプリを作成
- 高度なWindows GUIプログラミングとシステム統合能力を示す
- プロジェクト容量は非常に小さく(最大26.5KB)、Windows本来の外観をそのまま維持
✨ 主な機能
- ToDo項目の作成、編集、削除が可能
- タスクを完了済みにできる
- AppDataに永続保存され、常にデータが保持される
- システムトレイと統合され、最小化時にトレイへ移動
- ネイティブなWindowsスタイルの外観を備える
- Windows起動時の自動実行オプションを提供
🛠️ 技術的な詳細
- すべて純粋なCで記述
- GUI実装にはWin32 APIのみを使用
- 極小の実行ファイルサイズ(UPX圧縮時26.5KB)
- システムトレイ統合機能
- マニフェストによるモダンなビジュアルスタイルの適用
💾 データ保存
- すべてのToDoは1つのバイナリファイルに保存
- 保存パス:
%APPDATA%\\TodoApp\\todos.dat
- バイナリ形式で、最大100件の項目を保存可能
📋 必須要件
- Windows OS環境が必要
- MinGW-w64 (GCCコンパイラ) および Windows SDK が必要
🎮 使用方法
bin/todo.exe を実行後、インターフェースを使って以下の操作が可能
- "Add" ボタンで新しいToDoを追加
- 項目を選択後、"Edit" をクリックして修正
- "Delete" で項目を削除
- "Complete" で完了処理
- 各項目の優先度を指定可能
🏗️ プロジェクト構成
src/ フォルダにメインエントリポイント(main.c)、ToDo管理ロジック(todo.c)、構造体宣言(todo.h)、GUI実装(gui.c) が存在
bin/ にコンパイル済み実行ファイルを配置
- ビルドスクリプト(
build.bat)とプロジェクト文書を含む
🔧 開発要素
- Win32 API: ウィンドウ管理およびGUI全体の実装
- Common Controls: モダンなUI要素を使用
- UXTheme: Windowsビジュアルスタイル適用をサポート
- File I/O: データの永続保存を実現
📝 ライセンス
🤝 コントリビューション案内
- Pull Request歓迎
- 誰でもプロジェクトに参加可能
📫 連絡先とリンク
3件のコメント
ロマンがありますね
Hacker Newsの意見
strcpyやsprintfを使っているのが見えたが、真面目にプログラミングするなら長さをチェックする派生版を必ず使うべきだ。コンパイラがすぐ警告を出さなかったのが不思議なくらいだ。Win32 APIには標準Cライブラリ関数を置き換える関数が多い。実行ファイルサイズをもっと減らしたいなら、<Windows.h>だけを使ってcstdlibなしで書いてみることを勧める。memsetの代わりにZeroMemory、memcpyの代わりにCopyMemoryが使える。もちろん生のCコーディングはある時点で非常につらくなるが、最初の何回かは純粋なCで自分でやってみるのが学習にはいちばん役立つ。こういう細かい部分を扱う感覚が身につく。Win32 GUIプログラミングをもっとやってみたいなら、WTL (Windows Template Library) も勧めたい。Win32 APIをC++でラップしてくれるので、動作原理をずっと把握しやすくなるstrcpyの代わりにstrncpyくらいは使うべきだ。そうしないと誰からも延々と指摘される。Zigを使う大きな理由の1つは、こういうありがちなミスが減ることだ。もちろんCでも問題ないmemsetの代わりにZeroMemory、memcpyの代わりにCopyMemoryという話について、MSVCの組み込み関数はrep stos/movs命令を使うので、関数呼び出しよりコードも小さくなり、importテーブルのサイズも減るmemsetやmemcpyの代わりにZeroMemory、CopyMemoryが提供されている理由についての質問。なぜわざわざ既存の標準Cライブラリの代わりにこういうものを作ったのか気になるCreateWindowを毎回苦労して呼ぶより、.rcファイルでダイアログリソースを書いて(Visual Studioにはダイアログエディタもある)、CreateDialogを使っていた。そうするとすべてのコントロールが一度に生成される。アプリケーションmanifestを追加するだけで、モダンなUIスタイルと高解像度DPIにも対応できるuser32:SetProcessDpiAwarenessContext、shcore:SetProcessDpiAwareness、user32:SetProcessDPIAware)でDPI認識設定を試み、かなり古いバージョンなら何も呼ばないbuild.batがcore.autocrlf=falseの設定では正しく動かないことだった。これをcore.autocrlf=trueに変えてクローンし直したらビルドに成功した。mingwのあるツールチェインだと102KBの.exeが出る。つまり278KBよりずっと効率的だ。さらに減らしたければGCCに追加フラグを渡せばよい。gcc -s -Oz -fltoで47KBまでいける。バイナリサイズだけに関心があるなら、改善の余地はかなりあるquickrun.exeを作った人もいた。CとPure Win32 APIだけを使用。バイナリサイズ削減のための裏技はなし。Mingw32コンパイラを使用した、エイリアスで素早くアプリを起動するGUIアプリだYoutubeGOという自分の別アプリもあるので、よければ見てほしいstd::string、std::array、std::list、無名名前空間を使い、mallocもなくせば、コード量は半分になりバグも減るはずだstd::stringやstd::listに置き換えたところで、実際のアセンブリ出力が同じになるわけではない。内部動作を本当に分かっていないのが見えるstd::stringよりLPWSTR(ワイド文字列)を使うほうがAPIとの相性がよく、お勧めだ。char[]のような古い方法よりはLPWSTRを勧める。std::arrayやlistでコードが良くなるとも思えない兄貴たちの鼻息がここまで伝わってくるような感じ…