10 puan yazan GN⁺ 2025-05-12 | 3 yorum | WhatsApp'ta paylaş
  • Bu açık kaynak proje, yalnızca C ve Win32 API ile geliştirilmiş hafif bir yerel Windows Todo uygulamasıdır
  • Framework'e bağımlı olmadan minimum boyutta (en fazla 26.5KB) çalışır ve gelişmiş Windows GUI ile sistem entegrasyonunu doğrudan uygular
  • Todo öğesi ekleme, düzenleme, silme, tamamlandı olarak işaretleme gibi temel işlevlerin yanı sıra sistem tepsisi entegrasyonu ve otomatik başlatma seçeneği gibi gerçek üretkenlik özellikleri sunar
  • Depolama, ikili dosya üzerinden kalıcıdır ve AppData klasöründe en fazla 100 yapılacaklar listesini saklar
  • Büyük framework'ler olmadan işletim sistemine çok yakın klasik programlama yaklaşımı ve hafif çalışma ortamı öne çıkan güçlü yanlarıdır

🌟 Simple Todo (C / WinAPI)

Proje genel bakışı

  • Bu proje, yalnızca C ve Win32 API kullanarak modern bir yerel Windows Todo uygulaması oluşturur
  • Gelişmiş Windows GUI programlama ve sistem entegrasyonu yeteneklerini sergiler
  • Proje boyutu son derece küçüktür (en fazla 26.5KB) ve Windows'un kendine özgü görünümünü korur

✨ Başlıca özellikler

  • Yapılacak öğeleri oluşturma, düzenleme ve silme mümkündür
  • Görevler tamamlandı olarak işaretlenebilir
  • AppData'ya kalıcı olarak kaydedilir, böylece veriler her zaman korunur
  • Sistem tepsisi ile entegredir ve simge durumuna küçültüldüğünde tepsiye taşınır
  • Yerel Windows stili görünüme sahiptir
  • Windows başlangıcında otomatik çalıştırma seçeneği sunulur

🛠️ Teknik ayrıntılar

  • Tamamı saf C ile yazılmıştır
  • GUI uygulaması için yalnızca Win32 API kullanılır
  • Küçük çalıştırılabilir dosya boyutu (UPX ile sıkıştırıldığında 26.5KB)
  • Sistem tepsisi entegrasyonu
  • Manifest aracılığıyla modern görsel stiller uygulanır

💾 Veri depolama

  • Tüm yapılacaklar tek bir ikili dosyada saklanır
  • Depolama yolu: %APPDATA%\TodoApp\todos.dat
  • İkili formattadır ve en fazla 100 öğe saklayabilir

📋 Gereksinimler

  • Windows işletim sistemi ortamı gerekir
  • MinGW-w64 (GCC derleyicisi) ve Windows SDK gerekir

🎮 Kullanım

  • bin/todo.exe çalıştırıldıktan sonra arayüz üzerinden şu işlemler yapılabilir
  • "Add" düğmesiyle yeni yapılacak ekleme
  • Bir öğeyi seçip "Edit"e tıklayarak düzenleme
  • "Delete" ile öğe silme
  • "Complete" ile tamamlandı olarak işaretleme
  • Her öğe için öncelik belirlenebilir

🏗️ Proje yapısı

  • src/ klasöründe ana giriş noktası (main.c), yapılacak yönetim mantığı (todo.c), yapı tanımı (todo.h), GUI uygulaması (gui.c) bulunur
  • bin/ içinde derlenmiş çalıştırılabilir dosya yer alır
  • Derleme betiği (build.bat) ve proje belgeleri dahildir

🔧 Geliştirme öğeleri

  • Win32 API: pencere yönetimi ve GUI'nin genel uygulaması
  • Common Controls: modern UI öğelerinin kullanımı
  • UXTheme: Windows görsel stillerinin uygulanmasına destek
  • File I/O: kalıcı veri depolamayı gerçekleştirir

📝 Lisans

  • MIT lisansı ile serbestçe kullanılabilir ve değiştirilebilir

🤝 Katkı rehberi

  • Pull Request'ler memnuniyetle karşılanır
  • Herkes projeye katılabilir

📫 İletişim ve bağlantılar

3 yorum

 
aer0700 2025-05-13

Tam bir nostalji havası var.

 
GN⁺ 2025-05-12
Hacker News görüşleri
  • Win32 GUI programlamasında sevdiğim bir taraf var; biraz tuhaf olsa da Raymond Chen’in bloguna bakınca nedeni anlaşılıyor. Win32 API, 8088 işlemci döneminden geliyor ve bazı şeyler belirli bir şekilde yapılırsa 40 bayt kod tasarrufu sağlıyor ya da bir register daha az kullanıyor. Eskiden MinGW ve Petzold’un kitabıyla pek çok basit GUI uygulamasını kendim yazmıştım. Custom control’ler, grafik/metin çizimi, scroll işleme, hit test gibi her şeyi elle yapmak gerçekten çok eğlenceliydi. Uygulamada strcpy, sprintf kullandığını gördüm; eğer ciddi programlama yapılıyorsa mutlaka uzunluk kontrolü olan varyantlar kullanılmalı. Derleyicinin hemen uyarı vermemiş olmasına şaşırdım. Win32 API’de standart C kütüphanesi işlevlerinin yerine geçebilecek pek çok fonksiyon da var. Çalıştırılabilir dosya boyutunu daha da küçültmek istiyorsan sadece <Windows.h> kullanıp cstdlib olmadan yazmayı denemeni öneririm. memset yerine ZeroMemory, memcpy yerine CopyMemory kullanılabilir. Elbette raw C ile kod yazmak bir noktadan sonra oldukça acı verici hâle geliyor ama ilk birkaç seferde bunu saf C ile yapmak öğrenmek için en faydalısı. Bu tür küçük ayrıntılarla uğraşırken mimari sezgi gelişiyor. Win32 GUI programlamayı daha fazla denemek istersen WTL’yi (Windows Template Library) de öneririm; Win32 API’yi C++ ile sarmalayarak nasıl çalıştığını anlamayı çok daha kolaylaştırıyor.
    • Bugünlerde en azından strcpy yerine strncpy kullanmak gerekir; yoksa herkes bunu sürekli eleştirir. Zig kullanmanın büyük nedenlerinden biri de bu tür yaygın hataları azaltması. Tabii C de gayet olur.
    • memset yerine ZeroMemory, memcpy yerine CopyMemory denmesiyle ilgili olarak, MSVC intrinsic’leri rep stos/movs komutlarını kullanıyor; böylece fonksiyon çağrısından daha küçük kod çıkıyor ve import table boyutu da azalıyor.
    • Ben de eskiden bunu çok yapardım; dürüst olmak gerekirse native code ile native UI geliştirebilme becerisini özlüyorum.
    • memset ve memcpy yerine ZeroMemory, CopyMemory sunmalarının nedeni neydi diye merak ediyorum; neden mevcut standart C kütüphanesi yerine özellikle bunları yapmışlar?
  • Eskiden her seferinde zahmetle CreateWindow çağırmak yerine .rc dosyalarıyla dialog resource yazılırdı (Visual Studio’da bir dialog editor de var) ve CreateDialog kullanılırdı. Böylece tüm kontroller tek seferde oluşturulurdu. Sadece application manifest ekleyerek modern UI stili ve yüksek DPI desteği de sağlanabiliyor.
    • Bu yöntemi kullanınca kontroller arasında Tab ile gezinme gibi klavye kısayolları da otomatik geliyor. Yalnız yeniden boyutlandırma gibi şeyleri yine elle yapmak gerekiyor ama kodu hızlıca genişletmek mümkün ve zor da değil.
    • Petzold’un kitabında da geçen bir yöntem, bakmanı tavsiye ederim.
  • Ben de zamanında Linux için benzer bir şeyi 2KiB’nin altında assembly ile yapmıştım. C ile yazıp dinamik linkleme kullanırsan Linux’ta 20KiB altında yapmak kolay. Windows’ta yerleşik özellik daha fazla olduğu için daha da kolay olmalı diye düşünüyorum. O yüzden bu tür denemeleri desteklemek istiyorum. Yazının sonundaki linking seçeneklerine bakarsan boyutu daha da küçültmek kolay olabilir.
  • Framework olmadan yapınca DPI scaling sırasında fontlar bulanıklaşıyor, Tab desteği yok, metin alanlarında Ctrl-A ile seçme gibi modern öncesi framework’lerin temel özelliklerinin çoğu yok, satır eklerken hatalar var. O zaman bunun hangi açıdan "modern" olduğu merak konusu.
    • DPI farkındalığı ayarlamak için bir örnek eklenmiş; kod, sürüme göre farklı Windows fonksiyonlarıyla (user32:SetProcessDpiAwarenessContext, shcore:SetProcessDpiAwareness, user32:SetProcessDPIAware) DPI farkındalığını etkinleştirmeyi deniyor. Gerçekten çok eski sürümlerde ise hiçbir şey çağrılmıyor.
    • "Modern" sözü pek uymuyor; boyut büyük ama işlevler eksik (kontroller arasında Tab geçişini elle eklemek kolay gerçi).
  • 6502 ile programlama yapmış biri olarak artık 278KB’nin hafif sayılması bana acı veriyor.
    • Binary boyutu analizi yaparken ilk engelin build.bat dosyasının core.autocrlf=false ayarında düzgün çalışmaması olduğunu gördüm. Bunu core.autocrlf=true yapıp yeniden clone edince derleme başarılı oldu. MinGW’nin belirli bir toolchain’i 102KB’lık bir .exe üretiyor; yani 278KB’den çok daha verimli. Daha da küçültmek istersen GCC’ye ek flag’ler verilebilir. gcc -s -Oz -flto ile 47KB’ye kadar inmek mümkün. Sadece binary boyutuyla ilgileniliyorsa geliştirilecek çok yer var.
    • Bu boyuta ulaşılmasının nedeni platform ve executable formatı; stack trace bilgisi, dinamik linkleme altyapısı, exception handling tabloları gibi şeyler yer kaplıyor.
    • Demoscene yarışmalarına "64KB TODO uygulaması" kategorisi eklenmesini istiyorum.
    • Açıkçası bu kadar büyük olması şaşırtıcı; eskiden ikon boyutu hariç daha küçük olurdu diye hatırlıyorum. Acaba MinGW’den mi kaynaklanıyor?
    • 6502 mi? O lüks sayılır. Benim zamanımda çoğu kez ortada CPU bile yoktu.
    • Win32 assembly programlamasının bir anda popüler olduğu günleri hatırlatıyor; özellikle shareware indirmelerinin büyüdüğü dönemde çok ilgi görüyordu. Erken dönem Palm Pilot 68k programlamasını da düşündürüyor. Retro olmayan assembly’nin son parıltıları gibiydi.
    • Birisi 15KB’lık quickrun.exe de yapmıştı. Sadece C ve saf Win32 API kullanıyordu. Binary boyutunu azaltmak için özel bir hile yoktu, Mingw32 derleyicisi kullanılmıştı. Alias ile uygulamaları hızlı başlatan bir GUI uygulamasıydı.
    • Bu akşam ben de Z80 ve 64KB RAM’li bir sistemi emüle eden emülatörümün debug işlemiyle uğraşıyorum. Bazen zamanın ve ortamın ne kadar değiştiğini böyle anlıyorum. Yine de boyut artışı kadar çok büyük ilerleme de kaydedilmedi mi diye düşünüyorum.
    • 8 bit’ten 64 bit mimariye geçince sadece adres pointer’ları bile 8 kat büyüyor. Şikâyet etmek yerine bu değişimin kendisinin sanat olduğunu düşünmek lazım.
    • 278KB, 5 1/4 inç floppy diskete ancak sığacak bir boyut.
  • Bu uygulama sadece eğlence için, kendi başıma yapmak istediğim bir şeydi. Yorumlarda dendiği gibi daha mantıklı olarak C++ ya da başka bir dil seçilebilirdi ama benim için asıl keyif denemekti.
    • Yaklaşık 30 yıl önce ben de neredeyse aynı şekilde ilk Windows programımı yazmıştım. Tek fark, benim C++ derleyicisi kullanmamış olmamdı; o dönemde C tarzı kodu C++ derleyicisiyle yazmak resmî belgelerde önerilen yöntemdi. C++, C’nin üst kümesi olduğu için Microsoft da buna yatkındı.
    • Dürüstçe söylemek gerekirse Windows 11’in varsayılan yapılacaklar uygulamasındansa senin uygulamanı çok daha fazla kullanmak isterim.
    • Win32 API kullanırken hangi dili seçersen seç işin özü çok değişmiyor. Hatta dili değiştirince daha da kafa karıştırıcı olabilir. C++ stiline fazla takılmak, Win32 API’yi ilk kez öğrenen biri için işleri daha da karıştırabilir. Bu tür basit/şirin kişisel projelerle Win32 API’ye alışmak bence geliştirici olarak temel eğitim sayılır.
    • Ayrı olarak YoutubeGO diye başka bir uygulamam da var, ona da bakarsan sevinirim.
    • Böyle temiz native UI projeleri benim de programlamayı öğrenme motivasyonum olmuştu; o yüzden empati kuruyor ve takdir ediyorum.
  • Web’de ya da yazılımlarda 278KB telemetri gönderebilmek için megabaytlarca JS ya da C# yüklenen bir kültür varken, böyle denemeler ferahlatıcı geliyor.
    • C# + WinForms ile yapılmış benzer bir uygulama diskte 10KB’den küçük ve yalnızca 6MB RAM kullanıyor; bu uygulama ise 1.5MB RAM kullanıyor. İkisi de anında açılıyor.
  • Şu hâliyle statik kütüphaneler linklenmiş gibi görünüyor; DLL ile linklense uygulama boyutu dramatik biçimde küçülebilir.
    • Aslında biraz tersi. Eğer programla birlikte DLL’leri de dağıtmak zorundaysan (ve bu DLL’ler işletim sisteminde yerleşik değilse), her DLL kendi C runtime’ını da taşıdığı için toplam boyut daha da büyür. Her şeyi tek bir EXE’ye statik olarak koyarsan C runtime yalnızca bir kez eklenir ve kullanılmayan fonksiyonlar kolayca atılabilir. DLL’ler ancak birden çok program aynı DLL’i paylaşıyorsa boyut avantajı sağlar.
    • CRT’yi (runtime library) statik linklemek gereksiz kodu azaltma açısından hatta daha avantajlı olabilir. DLL’i dinamik linklersen ayrıca Microsoft’un VCRUNTIME DLL’lerinin kurulması gerekebilir. Visual Studio’da MSVCRT’ye dinamik linklemek de pek kolay değil. Tabii LGPL uyumluluğu gerektiren durumlar hariç.
  • Son zamanlarda çıkan hızlı dosya gezgini File Pilot’ı hatırlattı; C ile yazılmış ve yalnızca 1.8MB.
  • "Modern", "native" bir Windows todo uygulaması deniyor ama gerçekten modern olan tarafı ne, emin değilim. Ayrıca C++ ile yazılsa birçok sorun da önlenebilir, global değişkenler de kaldırılabilir. std::string, std::array, std::list, anonymous namespace kullanıp malloc’ı da çıkarırsan kod yarı uzunluğa iner ve hata sayısı azalır.
    • Global değişkenlerin 500 satır civarındaki bir uygulamada çok etkisi yok; kullanımları da gayet açık. std::string ve std::list’e geçince ortaya çıkan assembly’nin aynı kalacağını sanmak, iç işleyişi pek bilmediğini gösteriyor.
    • Petzold’un kitabının güncel baskısında bile Visual C++ ile C++ modunda derleniyor ve C/C++ ortak sözdizimi öneriliyor. Windows 95 döneminde bile neredeyse hiç kimse sadece C ile yazmıyordu; o sırada ana akım diller zaten VB, Delphi ve C++ olmuştu.
    • Standart string veya array/list kullanalım görüşüne karşılık, WinAPI’yi doğrudan kullanıyorsan std::string yerine API ile daha uyumlu olduğu için LPWSTR (wide string) kullanmak daha mantıklı olabilir ve tavsiye edilir. char[] gibi eski yöntemlerdense LPWSTR daha uygun. std::array ya da list kullanmanın da kodu daha iyi yapacağını sanmıyorum.
    • Modern sayılmaz ama temele yakın programlama, alttaki mekanizmanın nasıl çalıştığını gerçekten anlamaya yardımcı oluyor. Sorun alanı da basit olduğu için kavraması kolay. Öğrenme için iyi bir proje bence. Hatta bunun assembly sürümüyle yapılmış örneklerini de merak ediyorum.
 
roxie 2025-05-16

Ağabeylerin nefesi buraya kadar ulaşıyor gibi bir his...