Operasi Clipboard

Jendela harus menggunakan clipboard saat memotong, menyalin, atau menempelkan data. Jendela menempatkan data pada clipboard untuk operasi potong dan salin dan mengambil data dari clipboard untuk operasi tempel. Bagian berikut menjelaskan operasi ini dan masalah terkait.

Untuk menempatkan data atau mengambil data dari clipboard, jendela harus terlebih dahulu membuka clipboard dengan menggunakan fungsi OpenClipboard. Hanya satu jendela yang dapat membuka clipboard pada satu waktu. Untuk mengetahui jendela mana yang membuka clipboard, panggil fungsi GetOpenClipboardWindow. Setelah selesai, jendela harus menutup clipboard dengan memanggil fungsi CloseClipboard.

Topik berikut dibahas di bagian ini.

Operasi Potong dan Salin

Untuk menempatkan informasi di clipboard, jendela terlebih dahulu menghapus konten clipboard sebelumnya dengan menggunakan fungsi EmptyClipboard. Fungsi ini mengirim pesan WM_DESTROYCLIPBOARD ke pemilik clipboard sebelumnya, membebaskan sumber daya yang terkait dengan data di clipboard, dan menetapkan kepemilikan clipboard ke jendela yang membuka clipboard. Untuk mengetahui jendela mana yang memiliki clipboard, panggil fungsi GetClipboardOwner.

Setelah mengosongkan clipboard, jendela menempatkan data di clipboard dalam format clipboard sebanyak mungkin, diurutkan dari format clipboard yang paling deskriptif ke yang paling tidak deskriptif. Untuk setiap format, jendela memanggil fungsi SetClipboardData , menentukan pengidentifikasi format dan handel memori global. Handel memori bisa NULL, menunjukkan bahwa jendela merender data berdasarkan permintaan. Untuk informasi selengkapnya, lihat Penyajian Tertunda.

Tempel Operasi

Untuk mengambil informasi tempel dari clipboard, jendela terlebih dahulu menentukan format clipboard yang akan diambil. Biasanya, jendela menghitung format clipboard yang tersedia dengan menggunakan fungsi EnumClipboardFormats dan menggunakan format pertama yang dikenalinya. Metode ini memilih format terbaik yang tersedia sesuai dengan kumpulan prioritas ketika data ditempatkan di clipboard.

Atau, jendela dapat menggunakan fungsi GetPriorityClipboardFormat. Fungsi ini mengidentifikasi format clipboard terbaik yang tersedia sesuai dengan prioritas yang ditentukan. Jendela yang hanya mengenali satu format clipboard hanya dapat menentukan apakah format tersebut tersedia dengan menggunakan fungsi IsClipboardFormatAvailable.

Setelah menentukan format clipboard yang akan digunakan, jendela memanggil fungsi GetClipboardData. Fungsi ini mengembalikan handel ke objek memori global yang berisi data dalam format yang ditentukan. Jendela dapat mengunci objek memori secara singkat untuk memeriksa atau menyalin data. Namun, jendela tidak boleh membebaskan objek atau membiarkannya terkunci untuk jangka waktu yang lama.

Kepemilikan Clipboard

Pemilik clipboard adalah jendela yang terkait dengan informasi pada clipboard. Jendela menjadi pemilik clipboard ketika menempatkan data di clipboard, khususnya, ketika memanggil fungsi EmptyClipboard. Jendela tetap menjadi pemilik clipboard hingga ditutup atau jendela lain mengotori clipboard.

Ketika clipboard dikosongkan , pemilik clipboard menerima pesan WM_DESTROYCLIPBOARD . Berikut adalah beberapa alasan mengapa jendela mungkin memproses pesan ini:

  • Jendela tertunda penyajian satu atau beberapa format clipboard. Sebagai respons terhadap pesan WM_DESTROYCLIPBOARD , jendela mungkin membebaskan sumber daya yang dialokasikan untuk merender data berdasarkan permintaan. Untuk informasi selengkapnya tentang penyajian data, lihat Penyajian Tertunda.
  • Jendela menempatkan data pada clipboard dalam format clipboard privat. Data untuk format clipboard privat tidak dikosongkan oleh sistem ketika clipboard dikosongkan. Oleh karena itu, pemilik clipboard harus membebaskan data saat menerima pesan WM_DESTROYCLIPBOARD. Untuk informasi selengkapnya tentang format clipboard privat, lihat Format Clipboard.
  • Jendela menempatkan data pada clipboard menggunakan format clipboard CF_OWNERDISPLAY . Sebagai respons terhadap pesan WM_DESTROYCLIPBOARD , jendela mungkin membebaskan sumber daya yang digunakannya untuk menampilkan informasi di jendela penampil clipboard. Untuk informasi selengkapnya tentang format alternatif ini, lihat Format Tampilan Pemilik.

Penyajian Tertunda

Saat menempatkan format clipboard di clipboard, jendela dapat menunda penyajian data dalam format tersebut hingga data diperlukan. Untuk melakukannya, aplikasi dapat menentukan NULL untuk parameter hData dari fungsi SetClipboardData. Ini berguna jika aplikasi mendukung beberapa format clipboard, beberapa atau semuanya memakan waktu untuk dirender. Dengan meneruskan handel NULL , jendela merender format clipboard kompleks hanya ketika dan jika diperlukan.

Jika jendela menunda penyajian format clipboard, jendela harus siap untuk merender format berdasarkan permintaan selama itu adalah pemilik clipboard. Sistem mengirimkan pesan WM_RENDERFORMAT kepada pemilik clipboard ketika permintaan diterima untuk format tertentu yang belum dirender. Setelah menerima pesan ini, jendela harus memanggil fungsi SetClipboardData untuk menempatkan handel memori global pada clipboard dalam format yang diminta.

Aplikasi tidak boleh membuka clipboard sebelum memanggil SetClipboardData sebagai respons terhadap pesan WM_RENDERFORMAT. Membuka clipboard tidak diperlukan, dan upaya apa pun untuk melakukannya akan gagal karena clipboard saat ini sedang ditahan terbuka oleh aplikasi yang meminta format untuk dirender.

Jika pemilik clipboard akan dihancurkan dan telah menunda penyajian beberapa atau semua format clipboard, pemilik clipboard akan menerima pesan WM_RENDERALLFORMATS. Setelah menerima pesan ini, jendela harus membuka clipboard, periksa apakah itu masih pemilik clipboard dengan fungsi GetClipboardOwner , lalu tempatkan handel memori yang valid di clipboard untuk semua format clipboard yang disediakannya. Ini memastikan bahwa format ini tetap tersedia setelah pemilik clipboard dihancurkan.

Tidak seperti WM_RENDERFORMAT, aplikasi yang merespons WM_RENDERALLFORMATS harus membuka clipboard sebelum memanggil SetClipboardData untuk menempatkan handel memori global apa pun di clipboard.

Format clipboard apa pun yang tidak dirender sebagai respons terhadap pesan WM_RENDERALLFORMATS berhenti tersedia untuk aplikasi lain dan tidak lagi dijumlahkan oleh fungsi clipboard.

Panduan Penyajian Tertunda

Penyajian tertunda adalah fitur performa, memungkinkan aplikasi untuk menghindari melakukan pekerjaan untuk merender data clipboard dalam format yang mungkin tidak pernah diminta. Namun, menggunakan penyajian tertunda melibatkan tradeoff berikut yang harus dipertimbangkan:

  • Menggunakan penyajian tertunda menambahkan beberapa kompleksitas ke aplikasi, mengharuskannya untuk menangani dua pesan jendela penyajian, seperti yang dijelaskan di atas.
  • Menggunakan penyajian tertunda berarti aplikasi kehilangan opsi untuk menjaga UI tetap responsif jika merender data membutuhkan waktu yang cukup sehingga terlihat oleh pengguna. Dengan penyajian tertunda, jika data pada akhirnya diperlukan, jendela harus merender data saat memproses pesan jendela penyajian, seperti yang dijelaskan di atas. Akibatnya, jika data sangat memakan waktu untuk dirender, aplikasi mungkin menjadi sangat tidak responsif (digantung) saat penyajian terjadi, karena tidak ada pesan jendela lain yang dapat diproses saat pesan jendela penyajian sedang diproses. Aplikasi yang tidak menggunakan penyajian tertunda mungkin memilih untuk merender data pada utas latar belakang untuk menjaga respons UI saat penyajian terjadi, mungkin memberikan opsi kemajuan atau pembatalan, yang tidak tersedia saat menggunakan penyajian tertunda.
  • Menggunakan penyajian tertunda, tambahkan sejumlah kecil overhead jika data pada akhirnya diperlukan. Saat menggunakan penyajian penundaan, jendela awalnya memanggil fungsi SetClipboardData dengan handel NULL , dan jika data nanti diperlukan, jendela harus merespons pesan jendela dan memanggil fungsi SetClipboardData untuk kedua kalinya dengan handel ke data yang dirender, seperti yang dijelaskan di atas. Akibatnya, jika data pada akhirnya diperlukan, menggunakan penyajian tertunda menambahkan biaya pemrosesan pesan jendela dan memanggil fungsi SetClipboardData untuk kedua kalinya. Biaya ini kecil tetapi bukan nol. Jika aplikasi hanya mendukung satu format clipboard, dan jika data selalu akhirnya diminta, menggunakan penyajian tertunda hanya menambahkan jumlah overhead yang kecil ini (biaya bervariasi menurut perangkat keras; perkiraannya adalah antara 10 dan 100 mikrodetik). Namun, jika data kecil, overhead penggunaan penyajian yang tertunda dapat melebihi biaya untuk merender data, yang dapat mengalahkan tujuan menggunakan penyajian tertunda untuk meningkatkan performa. (Dalam pengujian, untuk data yang sudah dalam bentuk akhir, overhead penggunaan penyajian tertunda secara konsisten melebihi biaya untuk menyalin data ke clipboard jika datanya 100 KiB atau kurang. Pengujian ini tidak termasuk biaya untuk merender data, hanya untuk menyalinnya setelah dirender.)
  • Penyajian tertunda adalah keuntungan performa bersih jika menghemat lebih banyak waktu daripada yang ditambahkan dalam overhead. Untuk menentukan overhead rendering yang tertunda, mengukur adalah yang terbaik, tetapi 10 hingga 100 mikrodetik adalah perkiraan. Untuk menghitung penghematan penggunaan penyajian tertunda untuk setiap format clipboard, ukur biaya untuk merender data dalam format tersebut dan tentukan seberapa sering format tersebut akhirnya diminta (berdasarkan pesan jendela yang dijelaskan di atas). Kalikan biaya penyajian data dengan persentase waktu data tidak akhirnya diminta (sebelum clipboard dikosongkan atau kontennya berubah) untuk menentukan penghematan penyajian tertunda untuk setiap format clipboard. Penyajian tertunda adalah keuntungan performa bersih jika penghematan melebihi biaya overhead.
  • Sebagai pedoman konkret, untuk aplikasi yang hanya mendukung satu format clipboard, seperti teks, di mana data tidak terlalu mahal untuk dirender, pertimbangkan untuk menempatkan data langsung di clipboard jika ukuran data adalah 4 KiB atau kurang.

Memori dan Papan Klip

Objek memori yang akan ditempatkan pada clipboard harus dialokasikan dengan menggunakan fungsi GlobalAlloc dengan bendera GMEM_MOVEABLE.

Setelah objek memori ditempatkan di clipboard, kepemilikan handel memori tersebut ditransfer ke sistem. Ketika clipboard dikosongkan dan objek memori memiliki salah satu format clipboard berikut, sistem membebaskan objek memori dengan memanggil fungsi yang ditentukan:

Fungsi untuk membebaskan objek Format clipboard
DeleteMetaFile
CF_DSPENHMETAFILE
CF_DSPMETAFILEPICT
CF_ENHMETAFILE
CF_METAFILEPICT
DeleteObject
CF_BITMAP
CF_DSPBITMAP
CF_PALETTE
GlobalFree
CF_DIB
CF_DIBV5
CF_DSPTEXT
CF_OEMTEXT
CF_TEXT
CF_UNICODETEXT
tidak ada
CF_OWNERDISPLAY
Ketika clipboard dikosongkan dari objek CF_OWNERDISPLAY , aplikasi itu sendiri harus membebaskan objek memori.