It's important to know that you need to call InitCommonControlsEx function with INITCOMMONCONTROLSEX structure members: dwSize (size in bytes) & dwICC. (which common controls class to load) if you want to use common controls.
Suppose we want to use these 2 common controls (DTP, and Listview)

You can add these lines of code in your WinMain function or in WM_INITDIALOG section if you're working on a dialog based app or in your WM_CREATE section if you're working on a window based app:
INITCOMMONCONTROLSEX icex;
icex.dwSize = sizeof(INITCOMMONCONTROLSEX);
icex.dwICC = ICC_DATE_CLASSES | ICC_LISTVIEW_CLASSES;
InitCommonControlsEx(&icex);
dwICC member could be combinations of these:
ICC_ANIMATE_CLASS
ICC_BAR_CLASSES
ICC_COOL_CLASSES
ICC_DATE_CLASSES
ICC_HOTKEY_CLASS
ICC_INTERNET_CLASSES
ICC_LINK_CLASS
ICC_LISTVIEW_CLASSES
ICC_NATIVEFNTCTL_CLASS
ICC_PAGESCROLLER_CLASS
ICC_PROGRESS_CLASS
ICC_STANDARD_CLASSES
ICC_TAB_CLASSES
ICC_TREEVIEW_CLASSES
ICC_UPDOWN_CLASS
ICC_USEREX_CLASSES
ICC_WIN95_CLASSES
It's also important to note that the effect of each call to InitCommonControlsEx is cumulative, that is if you call InitCommonControlsEx with ICC_DATE_CLASSES flag and then you call InitCommonControlsEx again with ICC_TREEVIEW_CLASSES, both common controls class are registered.
Failure to do this, You might end up something like wasting your precious 30 mins with head scratching. :)
Mungkin ada benarnya juga kata pengantar di blog Windows SDK yang membahas tentang ESE, bahwa sedikit orang tahu / minimal pernah dengar ESE.
Apa itu ESE? Rokok produksi Korea yang cukup terkenal di Indonesia atau European Society of Endocrinology ?
Dua - dua nya bukan :)
Penjelasan yang (menurut saya) paling singkat & tepat untuk ESE atau Extensible Storage Engine adalah:
Windows' embeddable & transactional database engine
Sedangkan penjelasan yang detail ada di wikipedia.
Embeddable? Ya, ESE dapat kita sisipkan ke dalam aplikasi yang kita buat, tersembunyi. ESE mirip dengan produk Microsoft lainnya, yaitu SQL Server CE dalam hal runs in-process with application, namun yang menjadi perbedaan mencolok adalah dukungan terhadap SQL queries. ESE tidak mendukung SQL queries.
Tidak mendukung SQL queries? Jadi?
Tentunya dengan menentukan terlebih dahulu queries yang akan kita gunakan. Lebih lanjut akan dibahas di bawah.
Kemudian Transactional? Ya, ACID with savepoints, lazy commits and robust crash recovery.
Contoh penggunaan ESE adalah Active Directory, Windows Desktop Search, Windows Mail, Microsoft Exchange, Microsoft Updates, Local Security Policy, dll.
Lalu apa yang kita bisa manfaatkan dari ESE? Kalau aplikasi yang akan kita bangun mempunyai kebutuhan untuk storing data dengan queries yang simple dan telah (dapat) kita prediksikan sebelumnya (detail dapat dilihat pada posting saya sebelumnya tentang Berkeley DB, yang semoga saja tidak lenyap ditelan bumi sewaktu ada masalah dengan situs geeks), maka tentu saja ESE akan jadi sangat berguna.
Lalu apa saja keunggulan ESE? Berikut daftarnya, yang saya ambil kembali dari blog Laurion Burchall (Software Design Engineer, ESENT Team):
- ACID transactions with savepoints, lazy commits and robust crash recovery.
- Snapshot isolation.
- Record-level locking — multi-versioning provides non-blocking reads.
- Highly concurrent database access.
- Flexible meta-data (tens of thousands of columns, tables and indexes are possible).
- Indexing support for integer, floating point, ASCII, Unicode and binary columns.
- Sophisticated index types including conditional, tuple and multi-valued.
- Individual columns can be up to 2GB in size. A database can be up to 16TB in size.
- Can be configured for high performance or low resource usage.
- No administration required (even the database cache size can adjust itself automatically).
- No download. Your application uses the esent.dll which comes with the operating system.
OK, cukup dengan teori.
Alur tipikal dari ESE adalah sebagai berikut:
JetCreateInstance()
JetInit()
JetBeginSession()
JetAttachDatabase()
JetOpenDatabase()
JetOpenTable()
JetCloseTable()
JetCloseDatabase()
JetDetachDatabase()
JetEndSession()
JetTerm()
Berikut contohnya:
#include <windows.h>
#include <esent.h>
#define Call(func) { \
err = (func); \
if(err < JET_errSuccess) { \
goto HandleError; \
} \
} \
BOOL CreateESE(HWND hwnd)
{
JET_ERR err;
JET_INSTANCE instance;
JET_SESID sesid;
JET_DBID dbid;
JET_TABLEID tableid;
JET_COLUMNID columnid;
JET_COLUMNDEF columndef = {0};
char szBuffer[32] = "";
char *pszData = "Holla Mundo";
Call(JetCreateInstance(&instance, "instance"));
Call(JetSetSystemParameter(&instance, JET_sesidNil, JET_paramCircularLog, 1, NULL));
Call(JetInit(&instance));
Call(JetBeginSession(instance, &sesid, 0, 0));
/* Create database first if not exists */
Call(JetCreateDatabase(sesid, "MyDatabase.db", 0, &dbid, JET_bitDbOverwriteExisting));
Call(JetBeginTransaction(sesid));
/* Create table too */
Call(JetCreateTable(sesid, dbid, "MyTable", 0, 100, &tableid));
columndef.cbStruct = sizeof(columndef);
columndef.coltyp = JET_coltypLongText;
/* We use no unicode */
columndef.cp = 1252;
Call(JetAddColumn(sesid, tableid, "MyColumn", &columndef, NULL, 0, &columnid));
Call(JetCommitTransaction(sesid, JET_bitCommitLazyFlush));
Call(JetBeginTransaction(sesid));
Call(JetPrepareUpdate(sesid, tableid, JET_prepInsert));
Call(JetGetTableColumnInfo(sesid, tableid, "MyColumn", &columndef, sizeof (JET_COLUMNDEF), JET_ColInfo));
Call(JetSetColumn(sesid, tableid, columndef.columnid, pszData, strlen(pszData) + 1, 0, 0));
Call(JetUpdate(sesid, tableid, NULL, 0, NULL));
Call(JetCommitTransaction(sesid, 0));
/* Start querying record */
Call(JetMove(sesid, tableid, JET_MoveFirst, 0)); do {
Call(JetBeginTransaction(sesid));
Call(JetRetrieveColumn(sesid, tableid, 0, szBuffer, sizeof(szBuffer), NULL, 0, NULL));
Call(JetCommitTransaction(sesid, 0));
SendMessage(GetDlgItem(hwnd, IDC_LIST_NAME), LB_ADDSTRING, 0, (LPARAM) szBuffer);
}
while(JET_errSuccess == JetMove(sesid, tableid, JET_MoveNext, 0));
JetCloseTable(sesid, tableid);
JetEndSession(sesid, 0);
JetTerm(instance);
return TRUE;
}
Bagi saya, (seperti halnya Berkeley DB) ESE ini sangat menarik. Beberapa poin yang terutama saya sukai dari ESE ini adalah: mekanisme crash recovery, runtime yang ada di mana - mana (well, sebenarnya mulai dari Windows 2000) sehingga memudahkan deployment, dan tak lupa performanya.
Namun, seperti saya kutip di atas dari blog Windows SDK tentang ESE, sedikit orang tahu / minimal pernah dengar ESE. Ini sungguh disayangkan, karena banyak industri yang dapat memanfaatkan ESE, contoh: log & billing management (telco, banking, dll)
(mungkin) Hambatan terbesar bagi yang ingin mengenal ESE lebih dalam adalah minimnya informasi tentang ESE itu sendiri (dokumentasi, sample code, dll). Dan ini saya rasakan sendiri.
Bahkan setahu saya di MSDN yang membahas tentang ESE pun, minim sekali (tidak lebih dari 15 halaman?)
Semoga ke depan ESE bisa berkembang, dan jangan sampai seperti beberapa teknologi Microsoft lainnya yang kandas di tengah jalan. Semoga :)
P.S
Saya sertakan contoh aplikasi sederhana yang memanfaatkan ESE, yang saya buat dengan menggunakan Visual Studio 2008. UI juga dibuat sesederhana mungkin (Win32 + C)
EsentFirstAttempt.zip
Lagi hujan nih di sukabumi, jadi kepikiran juga untuk evaluasi 2008. What have I done. Di tahun 2008 ini ada beberapa kejadian besar dalam hidup saya (eg. getting married, serius ngegarap usaha microISV, dll)
Salah satu yang tidak ketinggalan penting menurut saya adalah perkenalan dengan komunitas geeks.netindonesia.net. Kalau tidak salah waktu itu saya dateng ke event berbau IT, yang namanya iMulai, di Blitz Megaplex. Di flyer, saya lihat ada beberapa link yang menarik, salah satunya geeks.netindonesia.net, ya udah mulai deh ikutan.. walau pertama cuma lirik - lirik. Jujur kesan pertama ikutan komunitas ini: bingung. Kok semua pada ngomongin .NET? Lha yang lain pada kemana? Ditambah saya sendiri datang dari dunia yang jadoel.. jadi serasa manusia purba :)
Ah tapi as time goes on, saya bertemu dengan orang - orang yang luar biasa (salah satunya Pak Risman), melalui percakapan demi percakapan, saya merasa sangat diterima, and i mean it.
Nah, sekarang 2008 sudah lewat 1 hari. Dalam beberapa perbincangan yang cukup intens dengan beberapa teman saya (sesama shareware author), saya merasa ada beberapa hal yang harus saya ubah. Salah satunya adalah software (esp. UI) usability.
Untuk beberapa tahun belakangan ini, seolah sudah menjadi ciri khas sendiri buat saya UI berikut:
Tabernus

Win32MyAdmin

Libellus

Saya ingat awal tahun 2005, saat saya masih bekerja di salah satu perusahaan di Kelapa Gading, salah seorang rekan saya (he called himself as the father of all magabutterz :)) bahkan pernah `nyeletuk, dia bilang: "ah.. si mbah (yes, that's me) mah dah ketauan model (desain) tampilan software nya". Walaupun ini cuma sekedar omongan kosong alias intermezzo, namun saya merasa ada benarnya juga. Tanpa sadar saya sudah memprogram otak saya, sehingga saat mulai pada stage - stage awal desain prototipe software yang akan saya buat, sudah terkonsep UI nya. Dan (again), tanpa sadar ini terbawa terus hingga sekarang. Benar - benar menakjubkan bagaimana alam bawah sadar kita bekerja.
Sekarang kembali lagi ke UI's yackety yak. WPF benar - benar menarik perhatian saya. Coba lihat Ahmad Masykur Organization Chart Viewer. Manis!
Kembali saya jadi ingat, saat saya mengerjakan aplikasi HRD untuk Spers TNI (2004 or something). Kurang lebih konsepnya sama dengan apa yang mas Ahmad Masykur buat, hanya spesifik untuk lingkungan militer. Saya ingat pengerjaannya cukup challenging. Banyak sekali kontrol yang harus dibuat sendiri (melalui owner & custom draw) untuk memfasilitasi keinginan pengguna (contoh: penggunaan warna pada kontrol untuk me-marking status personel seseorang (normal, soon will be retired, need to be retired now, etc)). Bandingkan dengan apa yang WPF lakukan. (walaupun sampai saat ini saya alergi dengan enkapsulasi yang berlebihan).
Saya tidak tahu apa jadinya apabila WPF sudah ada dari tahun 2003 :)
OK, mungkin sudah saatnya saya digging up sesuatu yang baru, terlebih untuk UI. (ada teman saya yang rekomendasiin Adobe AIR), but wait.. tentunya ini (saran, pemikiran, dll) tidak akan serta merta saya telan begitu saja. Ada banyak hal juga yang dapat menjadi konstrain buat saya, yaitu: efisiensi. Saya (juga) alergi kepada teknologi yang cumbersome (terutama buat pengguna).
Oh ya, saya berharap rencana - rencana saya lainnya di tahun 2009 ini bisa terlaksana, salah satunya yang sedang saya ngobrolin dengan Pak Risman.
Semoga.