Ada kalanya kita perlu mengkomunikasikan 2 (atau lebih) program lokal yang sedang berjalan (proses) untuk keperluan tertentu, contoh monitoring agent, packer sniffer, process viewer, dll
Banyak cara untuk ini:
- socket
- pipes (anonymous / named)
- shared memory
- temporary file
Sering kali kita merasa untuk mengkomunikasikan beberapa proses untuk sesuatu yang sederhana begitu rumit. Untuk socket, kita harus membuat "parent to babysit the child" (istilah Raymond Chen). Kemudian untuk pipes, kita harus CreatePipe, ReadFile, WriteFile, sambil berharap kita tidak lupa untuk CloseHandle, dst..
Masak untuk mengirim data yang sederhana begitu saja `njlimet? Apa tidak ada cara yang sederhana?
Well, sebenarnya ada.. gunakan saja WM_COPYDATA!
Secara teknis kurang lebih seperti ini:
Pada sisi pengirim data (sender), sender melewatkan struktur COPYDATASTRUCT yang berisikan data yang akan dikirimkan sebagai LPARAM dari WM_COPYDATA.
Contoh:
typedef struct SMSDATA {
char szMsisdn[15];
char szMessage[161];
};
...
void OnCopyData(LPARAM lParam)
{
COPYDATASTRUCT MyCDS;
HWND hDestination;
struct SMSDATA SMSData;
/* clear the structure first */
memset(&SMSData, 0, sizeof(struct SMSDATA));
GetDlgItemText(hParent, IDC_EDIT_NOMOR, SMSData.szMsisdn, 15);
GetDlgItemText(hParent, IDC_EDIT_ISI, SMSData.szMessage, 161);
MyCDS.dwData = 0;
MyCDS.cbData = sizeof(struct SMSDATA);
MyCDS.lpData = &SMSData;
hDestination = FindWindow(NULL, "SMSbox :: The SMS Manager");
if( hDestination != NULL ) {
SendMessage( hDestination, WM_COPYDATA, (WPARAM)(HWND) hParent, (
LPARAM)(COPYDATASTRUCT*) &MyCDS );
}
...
}
Lalu pada sisi receiver (penerima), langsung ambil & proses data.
Contoh:
case WM_COPYDATA:
{
PCOPYDATASTRUCT pMyCDS;
struct SMSDATA SMSData;
pMyCDS = (PCOPYDATASTRUCT) lParam;
/* Clear & fill the structure */
memset(&SMSData, 0, sizeof(struct SMSDATA));
memcpy(&SMSData, (const void *)pMyCDS->lpData, sizeof(struct SMSDATA));
...
Simple & straightforward right?
Beberapa hal berikut layak mendapat perhatian saat menggunakan WM_COPYDATA:
1. Kita harus yakin receiver (penerima) benar - benar pihak yang dituju, dan bukan hanya sekedar sama namanya (via FindWindow()), atau kalaupun benar yang dituju.. sangat baik untuk dicheck kembali instancenya (karena sering kita menjalankan program yang sama, bersamaan dalam waktu yang sama (???), contoh: web browser, dll
2. Berkaitan dengan poin #1, penggunaan WM_COPYDATA yang sembrono (broadcasting WM_COPYDATA secara membabi buta) bisa bikin polusi :)
3. Hati - hati terhadap penyalahgunaan WM_COPYDATA, contoh mengirimkan WM_COPYDATA bogus untuk tujuan yang negatif, contoh: membuat program crash, dll
4. Data yang hendak dilewatkan tidak boleh berupa pointer (this hit me once), alasannya cukup jelas saya rasa.