Bài giảng Lập trình C trên Windows: Các kỹ thuật xử lý Clipboard - Nguyễn Tri Tuấn

pdf 49 trang phuongnguyen 2330
Bạn đang xem 20 trang mẫu của tài liệu "Bài giảng Lập trình C trên Windows: Các kỹ thuật xử lý Clipboard - Nguyễn Tri Tuấn", để tải tài liệu gốc về máy bạn click vào nút DOWNLOAD ở trên

Tài liệu đính kèm:

  • pdfbai_giang_lap_trinh_c_tren_windows_cac_ky_thuat_xu_ly_clipbo.pdf

Nội dung text: Bài giảng Lập trình C trên Windows: Các kỹ thuật xử lý Clipboard - Nguyễn Tri Tuấn

  1. Lập trình C trên Windows Các kỹ thuật xử lý Clipboard Nguyễn Tri Tuấn Khoa CNTT – ĐH.KHTN.Tp.HCM Email: nttuan@ fit.hcmuns.edu.vn Nội dung  Giới thiệu Clipboard  Các kiểu định dạng sử dụng trong Clipboard  Các kỹ thuật cơ bản sử dụng Clipboard C4W - Clipboard - Nguyen Tri Tuan - DH.KHTN Tp.HCM13/06/2003 2 1
  2. [1] Giới thiệu Clipboard  Clipboard là gì ?  Nhu cầu sử dụng Clipboard  Các cơ chế Clipboard trong Windows  Giới thiệu về tiện ích Clipboard Viewer C4W - Clipboard - Nguyen Tri Tuan - DH.KHTN Tp.HCM13/06/2003 3 [1] Giới thiệu Clipboard - Clipboard là gì ?  Clipboard là một vùng nhớ chung của Windows mà tất cả các ứng dụng đều có thể truy cập đến  Clipboard là một phương thức chuyển dữ liệu chuẩn được Windows cung cấp, cho phép chia xẻ thông tin giữa các ứng dụng. C4W - Clipboard - Nguyen Tri Tuan - DH.KHTN Tp.HCM13/06/2003 4 2
  3. [1] Giới thiệu Clipboard - Nhu cầu sử dụng Clipboard  Clipboard được sử dụng để cài đặt cho các thao tác thông dụng: Cut, Copy, Paste, Drag and Drop. Một ứng dụng có nhu cầu đặt dữ liệu vào Clipboard để sau đó một ứng dụng khác (hoặc chính nó) có thể truy xuất và sử dụng  Một ứng dụng chỉ nên chuyển dữ liệu vào và ra Clipboard khi có yêu cầu từ người sử dụng. Không được sử dụng Clipboard để chuyển dữ liệu mà người sử dụng không biết C4W - Clipboard - Nguyen Tri Tuan - DH.KHTN Tp.HCM13/06/2003 5 [1] - Các cơ chế Clipboard trong Windows  Cơ chế Windows Clipboard API chuẩn  Cơ chế OLE Clipboard C4W - Clipboard - Nguyen Tri Tuan - DH.KHTN Tp.HCM13/06/2003 6 3
  4. [1] - Giới thiệu về tiện ích Clipboard Viewer  Clipboard Viewer là một cửa sổ hiển thị nội dung hiện thời của Clipboard  Clipboard Viewer là một tiện ích hỗ trợ cho người sử dụng và không tác động đến chức năng chuyển giao dữ liệu của Clipboard C4W - Clipboard - Nguyen Tri Tuan - DH.KHTN Tp.HCM13/06/2003 7 [1] - Giới thiệu về tiện ích Clipboard Viewer  Có nhiều Clipboard Viewer có thể chạy trên Windows ở cùng một thời điểm. Tuy nhiên, Windows chỉ giữ handle của một Clipboard Viewer hiện hành  Chỉ có Clipboard Viewer hiện hành được Windows gửi thông điệp mỗi khi có sự thay đổi nội dung Clipboard  Clipboard Viewer hiện hành có nhiệm vụ gửi các thông điệp này đến cho các Clipboard Viewer khác trong chuỗi xích Clipboard Viewer C4W - Clipboard - Nguyen Tri Tuan - DH.KHTN Tp.HCM13/06/2003 8 4
  5. [2] Các kiểu định dạng sử dụng trong Clipboard  Giới thiệu  Định dạng chuẩn  Định dạng riêng C4W - Clipboard - Nguyen Tri Tuan - DH.KHTN Tp.HCM13/06/2003 9 [2] Các kiểu định dạng - Giới thiệu  Dữ liệu chuyển vào Clipboard cần phải có một định dạng nhất định để các chương trình sử dụng nó có thể truy xuất chính xác  Định dạng dữ liệu được xác định bởi tham số uFormat trong hàm : ƒ SetClipboardData(UINT uFormat, HANDLE hMem) ƒ hMem là handle của khối bộ nhớ chứa dữ liệu có định dạng tương ứng với uFormat C4W - Clipboard - Nguyen Tri Tuan - DH.KHTN Tp.HCM13/06/2003 10 5
  6. [2] Các kiểu định dạng - Giới thiệu  Clipboard API chuẩn cho phép sử dụng các kiểu định dạng sau đây: ƒ Các định dạng chuẩn ƒ Các định dạng riêng C4W - Clipboard - Nguyen Tri Tuan - DH.KHTN Tp.HCM13/06/2003 11 [2] Các kiểu định dạng - Giới thiệu  Lưu ý : ƒ Một ứng dụng có thể cùng lúc đặt nhiều đối tượng dữ liệu vào Clipboard (bằng cách gọi liên tiếp hàm SetClipboardData), các đối tượng này thể hiện cùng một nội dung dữ liệu nhưng ở các định dạng khác nhau (và do đó đôi khi có hàm lượng thông tin khác nhau) C4W - Clipboard - Nguyen Tri Tuan - DH.KHTN Tp.HCM13/06/2003 12 6
  7. [2] Các kiểu định dạng - Định dạng chuẩn  Các định dạng Clipboard chuẩn (Standard Clipboard Formats) là các định dạng sử dụng cho Clipboard được Windows hỗ trợ  Định danh của định dạng chuẩn được định nghĩa trong Winuser.h C4W - Clipboard - Nguyen Tri Tuan - DH.KHTN Tp.HCM13/06/2003 13 [2] Các kiểu định dạng - Định dạng chuẩn  Các định dạng sử dụng với dữ liệu text: ƒ CF_TEXT: dữ liệu là chuỗi ký tự ANSI , mỗi dòng kết thúc với 2 ký tự carriage return và linefeed (CR,LF). Ký tự NULL báo hiệu kết thúc dữ liệu ƒ CF_UNICODETEXT: dữ liệu là chuỗi ký tự Unicode, mỗi dòng chấm dứt bằng CR,LF. Ký tự NULL (2 byte 0) báo hiệu kết thúc dữ liệu. Chỉ được hỗ trợ trong môi trường Windows NT/2000/XP ƒ CF_OEMTEXT: tương tự như CF_TEXT nhưng sử dụng cho tập ký tự OEM C4W - Clipboard - Nguyen Tri Tuan - DH.KHTN Tp.HCM13/06/2003 14 7
  8. [2] Các kiểu định dạng - Định dạng chuẩn  Định dạng sử dụng với các bitmap: ƒ CF_BITMAP : handle của một bitmap (HBITMAP) ƒ CF_DIB: khối bộ nhớ định nghĩa một Device Independent Bitmap (DIB), bắt đầu bằng cấu trúc BITMAPINFO, theo sau là các bit của bitmap ƒ CF_DIBV5: khối bộ nhớ chứa cấu trúc BITMAPV5HEADER, theo sau là thông tin về bảng màu và các bit của bitmap C4W - Clipboard - Nguyen Tri Tuan - DH.KHTN Tp.HCM13/06/2003 15 [2] Các kiểu định dạng - Định dạng chuẩn  Định dạng sử dụng cho dữ liệu Metafile: ƒ CF_METAFILEPICT: một Metafile Picture đuợc định nghĩa bởi cấu trúc METAFILEPICT, dựa trên hỗ trợ metafile cũ của Windows ƒ CF_ENHMETAFILE: handle của một metafile mở rộng (HENHMETAFILE) C4W - Clipboard - Nguyen Tri Tuan - DH.KHTN Tp.HCM13/06/2003 16 8
  9. [2] Các kiểu định dạng - Định dạng chuẩn  Một số định dạng khác: ƒ CF_HDROP: Một danh sách các tập tin sử dụng với các dịch vụ cắt/dán file, kéo/thả file ƒ CF_PALETE: handle của một bảng màu, thường được sử dụng kết hợp khi dữ liệu được đặt vào Clipboard phụ thuộc vào một bảng màu ƒ Ngoài ra, còn một số định dạng: CF_WAVE, CF_SYLK, CF_DIF, CF_TIFF, CF_PENDATA, CF_RIFF, CF_LOCALE và các định dạng kết hợp với định dạng dữ liệu riêng C4W - Clipboard - Nguyen Tri Tuan - DH.KHTN Tp.HCM13/06/2003 17 [2] Các kiểu định dạng - Định dạng chuẩn  Hệ thống tự thực hiện việc chuyển đổi định dạng dữ liệu giữa các định dạng sau: ƒ CF_TEXT, CF_OEMTEXT, CF_UNICODETEXT ƒ CF_BITMAP, CF_DIB, CF_DIBV5 ƒ Từ CF_DIB và CF_DIBV5 sang CF_PALETE ƒ CF_METAFILEPICT, CF_ENHMETAFILE C4W - Clipboard - Nguyen Tri Tuan - DH.KHTN Tp.HCM13/06/2003 18 9
  10. [2] Các kiểu định dạng - Định dạng riêng  Nhu cầu: ƒ Nhiều ứng dụng làm việc với định dạng riêng. Nếu chuyển dữ liệu vào hoặc ra Clipboard bằng các định dạng chuẩn có thể sẽ không bảo toàn được thông tin Muốn chuyển dữ liệu bảng tính qua lại giữa các ứng dụng Excel thì phải sử dụng định dạng riêng C4W - Clipboard - Nguyen Tri Tuan - DH.KHTN Tp.HCM13/06/2003 19 [2] Các kiểu định dạng - Định dạng riêng  Phương pháp: Windows cho phép một chương trình có thể sử dụng định dạng dữ liệu riêng cho mình theo một trong 2 cách sau: ƒ Cách 1: Đăng ký định dạng mới (Registered Clipboard Formats) với hàm ƒ UINT RegisterClipboardFormat (LPCTSTR lpszFormat) ƒ lpszFormat: tên của định dạng mới C4W - Clipboard - Nguyen Tri Tuan - DH.KHTN Tp.HCM13/06/2003 20 10
  11. [2] Các kiểu định dạng - Định dạng riêng  Cách 1: Đăng ký định dạng mới ƒ Hàm trả về giá trị usigned int là định danh của định dạng mới. Định danh này sẽ được sử dụng như tham số trong các hàm chuyển/nhận dữ liệu vào/từ Clipboard: SetClipboardData và GetClipboardData ƒ Nếu 2 hay nhiều ứng dụng đăng kí định dạng với cùng một tên thì định dạng chỉ được đăng kí một lần, và giá trị trả về trong các lời gọi hàm RegisterClipboardFormat là như nhau. Điều này cho phép các ứng dụng chia xẻ dữ liệu với cùng một định dạng riêng C4W - Clipboard - Nguyen Tri Tuan - DH.KHTN Tp.HCM13/06/2003 21 [2] Các kiểu định dạng - Định dạng riêng  Cách 2: Sử dụng định dạng riêng do Windows cung cấp ƒ Không cần đăng ký ƒ mà sử dụng một giá trị từ CF_PRIVATEFIRST (0x200) đến CF_PRIVATELAST (0x2FF) như là định danh của định dạng riêng C4W - Clipboard - Nguyen Tri Tuan - DH.KHTN Tp.HCM13/06/2003 22 11
  12. [2] Các kiểu định dạng - Định dạng riêng - Clipboard Viewer  Vấn đề: -MS Paint - MS Notepad - Dữ liệu Text theo định dạng riêng trong Các ứng dụng MS Word thông thường không hiểu được C4W - Clipboard - Nguyen Tri Tuan - DH.KHTN Tp.HCM13/06/2003 23 [2] Các kiểu định dạng - Định dạng riêng  Giải pháp: ƒ Một chương trình sử dụng định dạng riêng có thể chuyển cùng nội dung dữ liệu vào Clipboard nhưng ở một số định dạng chuẩn như:  CF_DSPTEXT, CF_DSPBITMAP, CF_DSPMETAFILEPICT, CF_DSPENHMETAFILE: các định dạng này cho phép Clipboard Viewer hiển thị dữ liệu dưới dạng Text, Bitmap, Metafile Picture hoặc Enhanced Metafile  CF_OWNERDISPLAY: Chủ Clipboard (ứng dụng cuối cùng chuyển dữ liệu vào Clipboard) có trách nhiệm hiển thị và cập nhật cho cửa sổ Clipboard Viewer bằng cách đáp ứng các thông điệp do cửa sổ này gửi đến C4W - Clipboard - Nguyen Tri Tuan - DH.KHTN Tp.HCM13/06/2003 24 12
  13. [2] Các kiểu định dạng - Định dạng riêng  Giải pháp : (tt)  Các định dạng chuẩn khác như CF_TEXT, CF_BITMAP, để các ứng dụng thông dụng như Notepad, Paint có thể hiển thị được nội dung dữ liệu trong Clipboard C4W - Clipboard - Nguyen Tri Tuan - DH.KHTN Tp.HCM13/06/2003 25 [3] Các kỹ thuật cơ bản sử dụng Clipboard  Vấn đề định vị bộ nhớ trong Windows  Chuyển dữ liệu vào Clipboard  Nhận dữ liệu từ Clipboard  Truy vấn trên nhiều định dạng  Kỹ thuật viết một Clipboard Viewer đơn giản C4W - Clipboard - Nguyen Tri Tuan - DH.KHTN Tp.HCM13/06/2003 26 13
  14. [3] Các kỹ thuật - Định vị bộ nhớ trong Windows  Sơ lược vấn đề định vị bộ nhớ trong Windows  Một số hàm quản lý vùng nhớ toàn cục  Ví dụ C4W - Clipboard - Nguyen Tri Tuan - DH.KHTN Tp.HCM13/06/2003 27 [3] - Định vị bộ nhớ trong Windows – Sơ lược  Windows 32 bits quản lý bộ nhớ ảo (virtual memory) và sử dụng kỹ thuật phân trang  Vùng nhớ toàn cục là vùng nhớ dùng chung cho tất cả các tiến trình. Khái niệm này chỉ có trên hệ điều hành Windows 16 bits nhưng vẫn được hỗ trợ trên Win32 C4W - Clipboard - Nguyen Tri Tuan - DH.KHTN Tp.HCM13/06/2003 28 14
  15. [3] - Định vị bộ nhớ trong Windows – Sơ lược  Các hàm quản lý vùng nhớ toàn cục chậm và cung cấp ít tính năng hơn các hàm quản lý bộ nhớ khác nên ít được dùng  Tuy nhiên, chúng vẫn được dùng với DDE, Clipboard và các đối tượng dữ liệu OLE C4W - Clipboard - Nguyen Tri Tuan - DH.KHTN Tp.HCM13/06/2003 29 [3] - Định vị bộ nhớ trong Windows – Các hàm  HGLOBAL GlobalAlloc (UINT uFlags, T_SIZE dwBytes) ƒ Hàm dùng để cấp phát một khối nhớ toàn cục mới ƒ Nếu thành công, hàm trả về handle của khối nhớ toàn cục, nếu không, trả về NULL ƒ dwBytes: số byte được cấp phát ƒ uFlags: xác định cách cấp phát vùng nhớ  GMEM_FIXED: cấp phát vùng nhớ cố định  GMEM_MOVEABLE: cấp phát một vùng nhớ có thể di chuyển (địa chỉ trong không gian địa chỉ ảo có thể thay đổi)  GMEM_ZEROINIT: cấp phát vùng nhớ với các byte được khởi tạo bằng 0  GHND: kết hợp GMEM_MOVEABLE và GMEM_ZEROINIT  GPTR: kết hợp GMEM_FIXED và GMEM_ZEROINIT C4W - Clipboard - Nguyen Tri Tuan - DH.KHTN Tp.HCM13/06/2003 30 15
  16. [3] - Định vị bộ nhớ trong Windows – Các hàm  GlobalAlloc : ƒ Khi sử dụng hàm GlobalAlloc để cấp phát vùng nhớ cho dữ liệu trong Clipboard, nên sử dụng cờ GMEM_MOVEABLE ƒ Lý do: cho phép hệ thống di chuyển khối nhớ trong không gian địa chỉ ảo, hạn chế tình trạng phân mảnh không gian địa chỉ ảo khi phải xóa và cấp phát lại nhiều lần C4W - Clipboard - Nguyen Tri Tuan - DH.KHTN Tp.HCM13/06/2003 31 [3] - Định vị bộ nhớ trong Windows – Các hàm  HGLOBAL GlobalRealloc(HGLOBAL hMem, T_SIZE dwBytes, UINT uFlags) ƒ Hàm dùng để cấp phát lại một khối nhớ toàn cục ƒ Hàm trả về handle của khối nhớ vừa được cấp phát lại ƒ hMem: handle của khối nhớ global cần cấp phát lại ƒ dwBytes: số byte của khối nhớ mới ƒ uFlags: cờ xác định cách cấp phát lại C4W - Clipboard - Nguyen Tri Tuan - DH.KHTN Tp.HCM13/06/2003 32 16
  17. [3] - Định vị bộ nhớ trong Windows – Các hàm  SIZE_T GlobalSize (HGLOBAL hMem) ƒ Hàm được sử dụng để lấy kích thước của một khối nhớ global ƒ Trả về số bytes của khối nhớ ƒ hMem: handle của khối nhớ cần lấy kích thước C4W - Clipboard - Nguyen Tri Tuan - DH.KHTN Tp.HCM13/06/2003 33 [3] - Định vị bộ nhớ trong Windows – Các hàm  HGLOBAL GlobalFree(HGLOBAL hMem) ƒ Hàm dùng để giải phóng một khối nhớ toàn cục ƒ Nếu thành công, trả về NULL, nếu không, trả về giá trị bằng với handle của khối nhớ ƒ hMem: handle của khối nhớ cần được giải phóng C4W - Clipboard - Nguyen Tri Tuan - DH.KHTN Tp.HCM13/06/2003 34 17
  18. [3] - Định vị bộ nhớ trong Windows – Các hàm  LPVOID GlobalLock (HGLOBAL hMem) ƒ Hàm dùng để khóa một khối nhớ toàn cục (cố định khối nhớ), sau mỗi lần gọi hàm, số lần khóa tăng lên 1. Khối nhớ có thuộc tính GMEM_FIXED luôn có số lần khóa bằng 0 ƒ Trả về con trỏ, trỏ đến phần tử đầu tiên của khối ƒ hMem: handle của khối nhớ toàn cục C4W - Clipboard - Nguyen Tri Tuan - DH.KHTN Tp.HCM13/06/2003 35 [3] - Định vị bộ nhớ trong Windows – Các hàm  BOOL GlobalUnlock(HGLOBAL hMem) ƒ Số lần khóa giảm đi 1 sau mỗi lần gọi hàm, khóa được bỏ (khối nhớ được phép di chuyển) khi số lần khóa bằng 0 ƒ Không tác động đến khối nhớ được cấp phát với cờ GMEM_FIXED ƒ Trả về TRUE nếu khối vẫn còn bị khóa (số lần khóa lớn hơn 0) ƒ Nếu trả về FALSE và hàm GetLastError trả về NO_ERROR, khóa khối được mở C4W - Clipboard - Nguyen Tri Tuan - DH.KHTN Tp.HCM13/06/2003 36 18
  19. [3] - Định vị bộ nhớ trong Windows – Ví dụ // Cấp một khối nhớ toàn cục, kích thước 256 bytes HGLOBAL hGlobal; hGlobal = GlobalAlloc(GMEM_MOVEABLE, 256); // Khai báo một con trỏ kiểu int int *p; // Truy xuất khối nhớ, gán giá trị cho các // phần tử kiểu int p = (int*) GlobalLock(hGlobal); for (int i=0; i<GlobalSize(hGlobal)/sizeof(int); i++) p[i] = 1; // Kết thúc truy xuất GlobalUnlock(hGlobal); C4W - Clipboard - Nguyen Tri Tuan - DH.KHTN Tp.HCM13/06/2003 37 [3] Các kỹ thuật - Chuyển dữ liệu vào Clipboard  Các bước cơ bản  Dữ liệu với định dạng chuẩn  Dữ liệu với định dạng riêng  Kỹ thuật Delayed Rendering C4W - Clipboard - Nguyen Tri Tuan - DH.KHTN Tp.HCM13/06/2003 38 19
  20. [3] - Chuyển dữ liệu – Các bước cơ bản  Các bước cần thực hiện để chuyển dữ liệu vào Clipboard: ƒ Bước 1: Mở Clipboard với hàm OpenClipboard ƒ Bước 2: Loại bỏ dữ liệu hiện có trong Clipboard với hàm EmptyClipboard ƒ Bước 3: Sử dụng hàm SetClipboardData để chuyển khối nhớ toàn cục hoặc các đối tượng khác (như bitmap handle) chứa dữ liệu vào Clipboard ƒ Bước 4: Đóng Clipboard với hàm CloseClipboard C4W - Clipboard - Nguyen Tri Tuan - DH.KHTN Tp.HCM13/06/2003 39 [3] - Chuyển dữ liệu – Các bước cơ bản  Các hàm liên quan: ƒ BOOL OpenClipboard(HWND hWnd)  hWnd: handle cửa sổ  (MFC) BOOL CWnd::OpenClipboard() ƒ BOOL EmptyClipboard(void) ƒ HANDLE SetClipboardData(UINT uFormat, HANDLE hMem)  uFormat: định dạng dữ liệu trong Clipboard  hMem: handle của dữ liệu thuộc định dạng xác định  Trả về: handle khối nhớ toàn cục của dữ liệu ƒ BOOL CloseClipboard(void) C4W - Clipboard - Nguyen Tri Tuan - DH.KHTN Tp.HCM13/06/2003 40 20
  21. [3] - Chuyển dữ liệu – Các bước cơ bản  Lưu ý: ƒ Khối nhớ toàn cục là một khối bộ nhớ được trả về từ hàm GlobalAlloc. Có thể sử dụng thêm các hàm liên quan như GlobalLock để nhận con trỏ trỏ tới khối nhớ và thiết lập giá trị cho dữ liệu trước khi chuyển vào Clipboard ƒ Trong Win32, GlobalAlloc ít được sử dụng (và được thay bằng HeapAlloc). Tuy nhiên, GlobalAlloc còn được dùng trong lập trình Clipboard vì Clipboard yêu cầu handle vùng nhớ chứ không phải con trỏ C4W - Clipboard - Nguyen Tri Tuan - DH.KHTN Tp.HCM13/06/2003 41 [3] - Chuyển dữ liệu – Các bước cơ bản  Lưu ý :(tt) ƒ Tại một thời điểm chỉ có một chương trình có thể mở Clipboard ƒ Lời gọi OpenClipboard giúp ngăn cản nội dung Clipboard bị thay đổi trong khi một chương trình đang sử dụng Clipboard ƒ Clipboard nên được làm rỗng trước khi được nhận dữ liệu mới C4W - Clipboard - Nguyen Tri Tuan - DH.KHTN Tp.HCM13/06/2003 42 21
  22. [3] - Chuyển dữ liệu – DL với định dạng chuẩn VD.1 Chuyển dữ liệu text vào Clipboard char szText[ ] = “Hello, World” ; int nLen = strlen(szText); // Mở Clipboard if (OpenClipboard()) { // Xoá dữ liệu trong Clipboard EmptyClipboard(); // Định vị khối bộ nhớ với k.thước đủ lưu chuỗi HANDLE hData = GlobalAlloc(GHND, nLen + 1); // Khoá khối bộ nhớ để nhận con trỏ tương ứng char *pszData = (char *) GlobalLock(hData); C4W - Clipboard - Nguyen Tri Tuan - DH.KHTN Tp.HCM13/06/2003 43 [3] - Chuyển dữ liệu – DL với định dạng chuẩn VD.1 // Chép nội dung dữ liệu vào vùng nhớ strcpy(pszData, szText); // Bỏ khoá khối GlobalUnlock(hData) ; // Chuyển dữ liệu vào Clipboard với // định dạng chuẩn CF_TEXT SetClipboardData(CF_TEXT, hData); // Đóng Clipboard CloseClipboard(); } C4W - Clipboard - Nguyen Tri Tuan - DH.KHTN Tp.HCM13/06/2003 44 22
  23. [3] - Chuyển dữ liệu – DL với định dạng chuẩn  Lưu ý: ƒ Không được đưa handle vùng nhớ bị khoá cho Clipboard ƒ Vùng nhớ đã được chuyển cho Clipboard không còn thuộc phạm vi sử dụng của ứng dụng. ƒ Giải pháp: tạo sẵn bản sao của vùng nhớ hoặc sử dụng handle do SetClipboardData trả về C4W - Clipboard - Nguyen Tri Tuan - DH.KHTN Tp.HCM13/06/2003 45 [3] - Chuyển dữ liệu – DL với định dạng chuẩn VD.2  Chuyển dữ liệu bitmap vào Clipboard  Không như Ví dụ 1 chuyển một khối nhớ cho Clipboard, trong ví dụ này chúng ta sẽ chuyển vào Clipboard một handle của bitmap  Input : hBitmap là handle của bitmap cần chuyển vào Clipboard C4W - Clipboard - Nguyen Tri Tuan - DH.KHTN Tp.HCM13/06/2003 46 23
  24. [3] - Chuyển dữ liệu – DL với định dạng chuẩn VD.2 // Mở Clipboard if (OpenClipboard()) { // Làm rỗng Clipboard EmptyClipboard(); // Chuyển dữ liệu vào Clipboard với định // dạng chuẩn CF_BITMAP SetClipboardData(CF_BITMAP, hBitmap); // Đóng Clipboard CloseClipboard(); } C4W - Clipboard - Nguyen Tri Tuan - DH.KHTN Tp.HCM13/06/2003 47 [3] - Chuyển dữ liệu – DL với định dạng chuẩn VD.3: Chuyển dữ liệu với định dạng CF_HDROP ƒ Là phương pháp mà Windows 98 và Windows 2000 sử dụng để thực hiện các thao tác Cut, Copy và Paste trên các tập tin hay thư mục ƒ HDROP là handle của vùng nhớ toàn cục. Vùng nhớ này chứa một cấu trúc DROPFILES và theo sau là một danh sách các tên file kết thúc bằng 2 ký tự NULL ƒ Cấu trúc DROPFILES: typedef struct _DROPFILES { DWORD pFiles; // Offset of file list POINT pt; BOOL fNC; BOOL fWide; // ANSI or Unicode text } DROPFILES, FAR * LPDROPFILES; C4W - Clipboard - Nguyen Tri Tuan - DH.KHTN Tp.HCM13/06/2003 48 24
  25. [3] - Chuyển dữ liệu – DL với định dạng chuẩn VD.3: // Danh sách file names TCHAR szFiles [3][32] = { _T ( “C:\\TaiLieu.doc” ) , _T ( “C:\\TaiLieu.zip” ) , _T ( “” ) } ; // Mở Clipboard if (OpenClipboard()) { // Làm rỗng Clipboard EmptyClipboard(); // Định vị vùng nhớ đủ kích thước int nSize=sizeof(DROPFILES)+sizeof(szFiles); HANDLE hData = GlobalAlloc(GHND , nSize); C4W - Clipboard - Nguyen Tri Tuan - DH.KHTN Tp.HCM13/06/2003 49 [3] - Chuyển dữ liệu – DL với định dạng chuẩn VD.3: // Khởi tạo dữ liệu cho vùng nhớ LPDROPFILES pDropFiles = (LPDROPFILES) GlobalLock (hData); pDropFiles Æ pFiles = sizeof(DROPFILES); pDropFiles Æ fWide = FALSE ; // Ansi text LPBYTE pData = (LPBYTE) pDropFiles + sizeof(DROPFILES); CopyMemory(pData, szFiles, sizeof(szFiles)); GlobalUnlock(hData); // Chuyển dliệu định dạng CF_HDROP vào Clipboard SetClipboardData(CF_HDROP, hData); // Đóng Clipboard CloseClipboard(); } C4W - Clipboard - Nguyen Tri Tuan - DH.KHTN Tp.HCM13/06/2003 50 25
  26. [3] - Chuyển dữ liệu – DL với định dạng riêng  Phương pháp  Thêm vào các định dạng khác C4W - Clipboard - Nguyen Tri Tuan - DH.KHTN Tp.HCM13/06/2003 51 [3] - Chuyển dữ liệu – DL với định dạng riêng  Phương pháp: ƒ Để sử dụng định dạng riêng , trước hết cần xác định định danh cho định dạng riêng bằng cách  Đăng ký định dạng riêng mới, hoặc  Sử dụng một số nguyên từ CF_PRIVATEFIRST đến CF_PRIVATELAST làm định danh cho định dạng ƒ sau đó chuyển dữ liệu với định dạng này vào Clipboard theo cách tương tự như định dạng chuẩn C4W - Clipboard - Nguyen Tri Tuan - DH.KHTN Tp.HCM13/06/2003 52 26
  27. [3] - Chuyển dữ liệu – DL với định dạng riêng Ví dụ:  Giả sử rằng chúng ta có một cấu trúc mô tả một hình tròn như sau: struct CIRCLE { POINT center; // Tâm int radius; // Bán kính COLORREF color; // Màu tô };  Chúng ta cần chuyển một hình tròn được mô tả bởi cấu trúc CIRCLE vào Clipboard C4W - Clipboard - Nguyen Tri Tuan - DH.KHTN Tp.HCM13/06/2003 53 [3] - Chuyển dữ liệu – DL với định dạng riêng Ví dụ: (tt)  Tạo một con trỏ CIRCLE *pData trỏ tới một đối tượng hình tròn cụ thể  Đăng ký định dạng riêng cho cấu trúc hình tròn này UINT nID = RegisterClipboardFormat(_T(“CircleFormat”));  Lấy khối bộ nhớ toàn cục hGlobal đủ lưu dữ liệu, sau đó chép tất cả dữ liệu cần thiết định nghĩa hình tròn vào khối nhớ này // Cấp phát khối bộ nhớ đủ lưu cấu trúc hình tròn HGLOBAL hGlobal = GlobalAlloc(GHND,sizeof(CIRCLE)); // Khoá khối để lấy địa chỉ khối CIRCLE *pGlobal = (CIRCLE*) GlobalLock(hGlobal); // Chép dữ liệu định nghĩa đường tròn vào khối nhớ CopyMemory(pGlobal, pData, sizeof(CIRCLE)); // Bỏ khoá khối GlobalUnlock(hGlobal); C4W - Clipboard - Nguyen Tri Tuan - DH.KHTN Tp.HCM13/06/2003 54 27
  28. [3] - Chuyển dữ liệu – DL với định dạng riêng Ví dụ: (tt)  Thực hiện thao tác chuyển dữ liệu vào Clipboard: // Mở và làm rỗng Clipboard OpenClipboard(); EmptyClipboard(); // Chuyển dữ liệu với định dạng nID // vào Clipboard SetClipboardData(nID, hGlobal); // Đóng Clipboard CloseClipboard(); C4W - Clipboard - Nguyen Tri Tuan - DH.KHTN Tp.HCM13/06/2003 55 [3] - Chuyển dữ liệu – DL với định dạng riêng  Thêm vào các định dạng khác: ƒ Các ứng dụng sử dụng định dạng riêng thường sử dụng thêm một số định dạng chuẩn khác để đặt dữ liệu vào Clipboard. Điều này tạo cơ hội cho các ứng dụng chuẩn thông thường có thể lấy được nội dung dữ liệu ƒ Ví dụ: Khi được copy, một bảng tính của Excel sẽ được lưu với hơn 30 định dạng, nhờ đó chúng ta có thể sử dụng MS Paint và MS Notepad để nhận dữ liệu. Tuy nhiên, chỉ có một định dạng là thực sự thể hiện đầy đủ định dạng gốc của một bảng tính Excel C4W - Clipboard - Nguyen Tri Tuan - DH.KHTN Tp.HCM13/06/2003 56 28
  29. [3] - Chuyển dữ liệu – DL với định dạng riêng  Thêm vào các định dạng khác: (tt) ƒ Chuyển nhiều định dạng vào Clipboard: gọi liên tiếp các hàm SetClipboardData giữa 2 thao tác làm rỗng và đóng Clipboard ƒ Ví dụ: EmptyClipboard(); SetClipboardData(CF_TEXT, hGlobalText); SetClipboardData(CF_BITMAP, hGlobalBmp); CloseClipboard(); ƒ Nhận dữ liệu từ Clipboard: sử dụng nhiều lần hàm GetClipboardData với định dạng thích hợp C4W - Clipboard - Nguyen Tri Tuan - DH.KHTN Tp.HCM13/06/2003 57 [3] - Chuyển dữ liệu – DL với định dạng riêng Lưu ý:  Khi một chương trình gọi EmptyClipboard, tất cả handle được giữ bởi Clipboard đều được loại bỏ C4W - Clipboard - Nguyen Tri Tuan - DH.KHTN Tp.HCM13/06/2003 58 29
  30. [3] - Chuyển dữ liệu – Kỹ thuật Delayed Rendering Vấn đề:  Khi chuyển dữ liệu vào Clipboard, chúng ta tạo bản sao của dữ liệu trong một khối nhớ toàn cục và trao khối nhớ này cho Clipboard  nếu dữ liệu quá lớn  và người dùng không bao giờ dán dữ liệu vào ứng dụng khác Æ gây lãng phí bộ nhớ Khắc phục:  Dùng kỹ thuật Delayed Rendering (DR) C4W - Clipboard - Nguyen Tri Tuan - DH.KHTN Tp.HCM13/06/2003 59 [3] - Chuyển dữ liệu – Kỹ thuật Delayed Rendering  DR cho phép một ứng dụng nói rằng: “Tôi có dữ liệu sẵn sàng trong Clipboard, nhưng tôi sẽ không chép nó vào Clipboard nếu không được ứng dụng nào yêu cầu” Phương pháp:  Dùng SetClipboardData với tham số handle vùng nhớ bằng NULL C4W - Clipboard - Nguyen Tri Tuan - DH.KHTN Tp.HCM13/06/2003 60 30
  31. [3] - Chuyển dữ liệu – Kỹ thuật Delayed Rendering Phương pháp: (tt)  Xử lý các thông điệp: ƒ WM_RENDERFORMAT: cho biết có một ứng dụng yêu cầu dữ liệu. Chủ Clipboard cần xử lý thông điệp này để chuyển dữ liệu vào Clipboard  Chủ Clipboard (Clipboard owner) là cửa sổ cuối cùng đặt dữ liệu vào Clipboard. Khi một ứng dụng gọi OpenClipboard, Windows lưu handle cửa sổ yêu cầu bởi hàm này. Đây là handle của cửa sổ mở Clipboard. Khi nhận một lời gọi EmptyClipboard, Windows sẽ đặt cửa sổ này là chủ Clipboard  Lưu ý: Chủ Clipboard không được gọi hàm OpenClipboard và CloseClipboard lần nữa C4W - Clipboard - Nguyen Tri Tuan - DH.KHTN Tp.HCM13/06/2003 61 [3] - Chuyển dữ liệu – Kỹ thuật Delayed Rendering  Xử lý các thông điệp: (tt) ƒ WM_RENDERALLFORMATS: được Windows gởi cho chủ Clipboard trước khi ứng dụng chủ Clipboard kết thúc. Khi đó, Clipboard vẫn còn chứa handle dữ liệu NULL  Chủ Clipboard cần: mở Clipboard, xóa Clipboard, chuyển tất cả dữ liệu vào Clipboard và đóng nó lại ƒ WM_DESTROYCLIPBOARD: được Windows gởi cho chủ Clipboard để thông báo cho ứng dụng biết nó không còn trách nhiệm với dữ liệu trong Clipboard nữa (xảy ra khi hàm EmptyClipboard được gọi). Ứng dụng có thể giải phóng tài nguyên đã sử dụng cho trường hợp Delayed Render. C4W - Clipboard - Nguyen Tri Tuan - DH.KHTN Tp.HCM13/06/2003 62 31
  32. [3] - Chuyển dữ liệu – Kỹ thuật Delayed Rendering Ví dụ: / Chuyển bitmap vào Clipboard với DR / // MessageMap ON_COMMAND(ID_EDIT_COPY, OnEditCopy) ON_WM_RENDERFORMAT() ON_WM_RENDERALLFORMATS() // Chép handle NULL vào Clipboard khi user Copy void CMyWindow::OnEditCopy() { OpenClipboard(); EmptyClipboard(); SetClipboardData(CF_BITMAP, NULL); CloseClipboard(); } C4W - Clipboard - Nguyen Tri Tuan - DH.KHTN Tp.HCM13/06/2003 63 [3] - Chuyển dữ liệu – Kỹ thuật Delayed Rendering Ví dụ: (tt) // Xử lý thông điệp WM_RENDERFORMAT // nFormat là giá trị wParam trong thông điệp, // chứa định dạng do chương trình khác yêu cầu void CMyWindow::OnRenderFormat(UINT nFormat) { if (nFormat == CF_BITMAP) { // Tạo bản sao của bitmap, là hBitmap // Đưa dữ liệu vào clipboard SetClipboardData(CF_BITMAP, hBitmap); } } C4W - Clipboard - Nguyen Tri Tuan - DH.KHTN Tp.HCM13/06/2003 64 32
  33. [3] - Chuyển dữ liệu – Kỹ thuật Delayed Rendering Ví dụ: (tt) // Xử lý WM_RENDERALLFORMATS void CMyWindow::OnRenderAllFormats() { OpenClipboard(); EmptyClipboard(); OnRenderFormat(CF_BITMAP); CloseClipboard(); } C4W - Clipboard - Nguyen Tri Tuan - DH.KHTN Tp.HCM13/06/2003 65 [3] Các kỹ thuật - Nhận dữ liệu từ Clipboard  Các bước cơ bản  Ví dụ -Nhận dữ liệu với định dạng chuẩn  Ví dụ -Nhận dữ liệu với định dạng riêng C4W - Clipboard - Nguyen Tri Tuan - DH.KHTN Tp.HCM13/06/2003 66 33
  34. [3] - Nhận dữ liệu - Các bước cơ bản  Quy trình nhận dữ liệu từ Clipboard: ƒ Bước 1: Mở Clipboard ƒ Bước 2: Sử dụng GetClipboardData để nhận handle của khối bộ nhớ toàn cục hoặc của các đối tượng khác với định dạng dữ liệu xác định HANDLE GetClipboardData(UINT uFormat ); Nếu Clipboard không chứa dữ liệu với định dạng uFormat, hàm trả về NULL ƒ Bước 3: Tạo dữ liệu sao chép của dữ liệu trong khối bộ nhớ ƒ Bước 4: Đóng Clipboard C4W - Clipboard - Nguyen Tri Tuan - DH.KHTN Tp.HCM13/06/2003 67 [3] - Nhận dữ liệu - Các bước cơ bản  Lưu ý: ƒ Handle nhận từ GetClipboardData không thuộc chương trình gọi, do đó phải thực hiện sao chép. Chương trình không thể giải phóng hay thay đổi dữ liệu do handle này tham chiếu ƒ Các bước sao chép dữ liệu khối nhớ:  Khoá khối để nhận con trỏ  Sao chép dữ liệu con trỏ ra bên ngoài  Bỏ khoá khối C4W - Clipboard - Nguyen Tri Tuan - DH.KHTN Tp.HCM13/06/2003 68 34
  35. [3] - Nhận dữ liệu - Ví dụ (Định dạng chuẩn) VD.1: Nhận text từ Clipboard char *szText; // Chứa dữ liệu if (OpenClipboard()) { // Nhận handle vùng nhớ HANDLE hData = GetClipboardData(CF_TEXT); if (hData != NULL) { // Lấy con trỏ tương ứng char *pData = (char *)GlobalLock(hData); szText = new char[strlen(pData)+1]; strcpy(szText, pData); // Copy dữ liệu GlobalUnlock(hData); // Bỏ khoá khối } // Đóng Clipboard CloseClipboard(); } C4W - Clipboard - Nguyen Tri Tuan - DH.KHTN Tp.HCM13/06/2003 69 [3] - Nhận dữ liệu - Ví dụ (Định dạng chuẩn) Ví dụ 2: Nhận bitmap từ Clipboard // Mở Clipboard if (OpenClipboard()) { // Lấy handle bitmap HBITMAP hBitmap = (HBITMAP) GetClipboardData(CF_BITMAP); if (hBitmap != NULL) { // Tạo bản sao chép của bitmap } // Đóng Clipboard CloseClipboard(); } C4W - Clipboard - Nguyen Tri Tuan - DH.KHTN Tp.HCM13/06/2003 70 35
  36. [3] - Nhận dữ liệu - Ví dụ (Định dạng chuẩn) VD.3: Nhận dữ liệu định dạng CF_HDROP  Khi nhận dữ liệu định dạng CF_HDROP từ Clipboard, chúng ta có thể sử dụng hàm DragQueryFile để đọc danh sách các tên file trong khối bộ nhớ ƒ UINT DragQueryFile(HDROP hDrop, UINT iFile, LPTSTR lpszFile, UINT cch) hDrop : handle cấu trúc HDROP iFile : chỉ số trong danh sách. Giá trị -1: hàm trả về số lượng phần tử của danh sách lpszFile : lưu chuỗi kết quả cch : số ký tự của lpszFile C4W - Clipboard - Nguyen Tri Tuan - DH.KHTN Tp.HCM13/06/2003 71 [3] - Nhận dữ liệu - Ví dụ (Định dạng chuẩn) Ví dụ 3: (tt) if (OpenClipboard()) { // Lấy handle khối nhớ HDROP hDrop = (HDROP) GetClipboardData(CF_HDROP); if (hDrop) { // Đếm số tên flle trong danh sách int nCount = DragQueryFile(hDrop, (UINT) -1, NULL, 0); // Duyệt danh sách tên file if (nCount) { TCHAR szFile[MAX_PATH]; for (int i=0; i < nCount; i++) { DragQueryFile(hDrop, i, szFile, sizeof(szFile)/sizeof(TCHAR)); // Xử lý tương ứng với từng tên file } } } CloseClipboard(); } C4W - Clipboard - Nguyen Tri Tuan - DH.KHTN Tp.HCM13/06/2003 72 36
  37. [3] - Nhận dữ liệu - Ví dụ (Định dạng riêng) VD.4: Nhận cấu trúc mô tả hình tròn struct CIRCLE strCircle; // Lưu kết quả if (OpenClipboard()) { HANDLE hData = GetClipboardData(nID); struct CIRCLE *p = (struct CIRCLE *) GlobalLock(hData); // Sao chép dữ liệu strCircle.center = pÆcenter; GlobalUnlock(hData); CloseClipboard(); } C4W - Clipboard - Nguyen Tri Tuan - DH.KHTN Tp.HCM13/06/2003 73 [3] Các kỹ thuật - Truy vấn trên nhiều định dạng  Các hàm thường dùng  Các ví dụ C4W - Clipboard - Nguyen Tri Tuan - DH.KHTN Tp.HCM13/06/2003 74 37
  38. [3] Các kỹ thuật - Truy vấn trên nhiều định dạng  Xảy ra khi trong Clipboard có nhiều dữ liệu với các định dạng khác nhau.  Các hàm thường sử dụng: Tên hàm Mô tả CountClipboardFormats Đếm số định dạng trong Clipboard EnumClipboardFormats Duyệt qua các định dạng IsClipboardFormatAvailable Xác định một định dạng có trong Clipboard hay không GetPriorityClipboardFormat Xác định định dạng đầu tiên có trong Clipboard từ một danh sách ưu tiên các định dạng C4W - Clipboard - Nguyen Tri Tuan - DH.KHTN Tp.HCM13/06/2003 75 [3] Các kỹ thuật - Truy vấn trên nhiều định dạng VD.1: Xác định CF_TEXT có trong Clipboard ? if (OpenClipboard()) { if (IsClipboardFormatAvailable(CF_TEXT)) { // Lấy dữ liệu } CloseClipboard(); } C4W - Clipboard - Nguyen Tri Tuan - DH.KHTN Tp.HCM13/06/2003 76 38
  39. [3] Các kỹ thuật - Truy vấn trên nhiều định dạng VD.2: Duyệt qua danh sách các định dạng if (OpenClipboard()) { UINT nFormat = 0; // Bắt đầu duyệt từ vị trí 0 while (nFormat = EnumClipboardFormats(nFormat)) { // nFormat chứa ID của format kế tiếp trong // Clipboard } CloseClipboard(); } C4W - Clipboard - Nguyen Tri Tuan - DH.KHTN Tp.HCM13/06/2003 77 [3] Các kỹ thuật - Truy vấn trên nhiều định dạng VD.3: truy xuất dữ liệu trong Clipboard dựa trên 1 danh sách các định dạng có độ ưu tiên UINT nFormats[3] = { nID, // ưu tiên 1 CF_TEXT, // ưu tiên 2 CF_BITMAP // ưu tiên 3 }; if (OpenClipboard()) { UINT nFormat = GetPriorityClipboardFormat(nFormats, 3); if (nFormat > 0) { // nFormat chứa định dạng của dữ liệu đầu tiên trong // Clipboard trùng với nID, CF_TEXT, hoặc CF_BITMAP } CloseClipboard(); } C4W - Clipboard - Nguyen Tri Tuan - DH.KHTN Tp.HCM13/06/2003 78 39
  40. [3] Các kỹ thuật - Xây dựng Clipboard Viewer  Chuỗi xích Clipboard Viewer  Các thông điệp liên quan  Một số hàm thông dụng  Ví dụ C4W - Clipboard - Nguyen Tri Tuan - DH.KHTN Tp.HCM13/06/2003 79 [3] - Clipboard Viewer - Chuỗi xích Clipboard Viewer  Các ứng dụng Clipboard Viewer phải tham gia vào “chuỗi xích Clipboard Viewer”  Trong chuỗi xích Clipboard Viewer chỉ có một Clipboard Viewer hiện hành trực tiếp nhận thông điệp từ Windows khi có sự thay đổi nội dung Clipboard hoặc thay đổi chuỗi xích Clipboard Viewer  Các Clipboard Viewer có nhiệm vụ gửi thông điệp đến cho Clipboard Viewer đứng kề sau nó trong chuỗi xích Clipboard Viewer (trừ khi nó là viewer cuối cùng) C4W - Clipboard - Nguyen Tri Tuan - DH.KHTN Tp.HCM13/06/2003 80 40
  41. [3] - Clipboard Viewer - Chuỗi xích Clipboard Viewer  Ứng dụng tham gia vào chuỗi xích Clipboard Viewer bằng cách gọi hàm SetClipboardViewer: HWND hWndNextViewer = SetClipboardViewer(hWndNewViewer); (MFC) HWND CWnd::SetClipboardViewer() ƒ hWndNewViewer: handle của cửa sổ mới được đưa vào chuỗi xích Clipboard Viewer. Cửa sổ mới thêm vào sẽ là Clipboard Viewer hiện hành ƒ Trả về handle của cửa sổ Clipboard Viewer liền sau trong chuỗi xích, bằng NULL nếu cửa sổ mới là Viewer duy nhất C4W - Clipboard - Nguyen Tri Tuan - DH.KHTN Tp.HCM13/06/2003 81 [3] - Clipboard Viewer - Chuỗi xích Clipboard Viewer  Các Clipboard Viewer phải lưu giữ handle của Viewer kề sau nó trong chuỗi xích Clipboard Viewer. (Nhận được khi gọi hàm SetClipboardViewer và có thể thay đổi khi có thông điệp WM_CHANGECBCHAIN)  Các Clipboard Viewer sử dụng hàm SendMessage để gửi thông điệp đến cho Clipboard Viewer liền sau nó (ngoại trừ viewer cuối cùng) C4W - Clipboard - Nguyen Tri Tuan - DH.KHTN Tp.HCM13/06/2003 82 41
  42. [3] - Clipboard Viewer - Chuỗi xích Clipboard Viewer  Khi chương trình muốn gỡ khỏi Clipboard Viewer chain, gọi hàm ChangeClipboardChain: BOOL ChangeClipboardChain(HWND hWndRemove, HWND hWndNext); (MFC) BOOL CWnd::ChangeClipboardChain (HWND hWndNext); ƒ hWndRemove: handle của cửa sổ muốn gỡ khỏi chuỗi xích Clipboard Viewer ƒ hWndNext: handle cửa sổ nằm liền sau hWndRemove trong chuỗi xích Clipboard Viewer C4W - Clipboard - Nguyen Tri Tuan - DH.KHTN Tp.HCM13/06/2003 83 [3] - Clipboard Viewer – Các thông điệp liên quan  Thông điệp WM_DRAWCLIPBOARD: ƒ Được gửi đến cho cửa sổ Clipboard Viewer khi có sự thay đổi nội dung Clipboard ƒ Viewer khi nhận thông điệp cần cập nhật lại vùng hiển thị của mình cho phù hợp với nội dung Clipboard mới ƒ Viewer sau khi xử lý thông điệp sẽ gửi thông điệp đến cho Viewer kế C4W - Clipboard - Nguyen Tri Tuan - DH.KHTN Tp.HCM13/06/2003 84 42
  43. [3] - Clipboard Viewer – Các thông điệp liên quan  Thông điệp WM_CHANGECBCHAIN: ƒ Được gửi đến cho các Clipboard Viewer khi có một Viewer gọi hàm ChangeClipboardChain. ƒ wParam: handle của cửa sổ được gỡ khỏi chuỗi xích ƒ lParam: handle của cửa sổ liền sau cửa sổ được gỡ khỏi chuỗi. ƒ Nếu Viewer nhận ra wParam là handle của cửa sổ liền sau (hWndNextViewer), nó sẽ cập nhật lại hWndNextViewer =(HWND) lParam; ƒ Nếu không, chuyển thông điệp đến cho Viewer kế tiếp. C4W - Clipboard - Nguyen Tri Tuan - DH.KHTN Tp.HCM13/06/2003 85 [3] - Clipboard Viewer – Các thông điệp liên quan  Các thông điệp: ƒ WM_ASKCBFORMATNAME ƒ WM_PAINTCLIPBOARD ƒ WM_SIZECLIPBOARD ƒ WM_VSCROLLCLIPBOARD ƒ WM_HSCROLLCLIPBOARD Được cửa sổ Clipboard Viewer gửi đến chủ Clipboard khi cần hiển thị dữ liệu có định dạng CF_OWNERDISPLAY. C4W - Clipboard - Nguyen Tri Tuan - DH.KHTN Tp.HCM13/06/2003 86 43
  44. [3] - Clipboard Viewer – Một số hàm thông dụng  HWND GetClipboardOwner(void): ƒ Trả về handle của cửa sổ hiện đang là chủ Clipboard ƒ Nếu Clipboard không có chủ, trả về NULL (Clipboard vẫn có thể có dữ liệu khi không có chủ)  UINT EnumClipboardFormats(UINT uFormat): ƒ Liệt kê các định dạng hiện có trong Clipboard ƒ Thực hiện việc liệt kê tuần tự với tham số uFormat =0 cho lần gọi hàm đầu tiên, các lần gọi sau uFormat là định dạng được trả về từ lần gọi trước ƒ Nếu thành công, trả về định dạng kế tiếp trong Clipboard ƒ Nếu trả về 0 và hàm GetLastError trả về ERROR_SUCCESS, không còn định dạng nào trong Clipboard nữa C4W - Clipboard - Nguyen Tri Tuan - DH.KHTN Tp.HCM13/06/2003 87 [3] - Clipboard Viewer – Một số hàm thông dụng  int GetClipboardFormatName(UINT uFormat, LPSTR lpszFormatName, int iMaxLength): ƒ Hàm lấy tên của một định dạng đã được đăng ký ƒ uFormat: định danh của định dạng ƒ lpszFormatName: con trỏ của buffer sẽ nhận tên định dạng ƒ iMaxLength: chiều dài tối đa buffer C4W - Clipboard - Nguyen Tri Tuan - DH.KHTN Tp.HCM13/06/2003 88 44
  45. [3] - Clipboard Viewer – Ví dụ // xử lý thông điệp WM_CREATE int CMainWindow::OnCreate (LPCREATESTRUCT lpCreateStruct) { // tham gia vào Clipboard Viewer chain hWndNextViewer = SetClipboardViewer(); return 0; } C4W - Clipboard - Nguyen Tri Tuan - DH.KHTN Tp.HCM13/06/2003 89 [3] - Clipboard Viewer – Ví dụ // xử lý thông điệp WM_CHANGECBCHAIN void CMainWindow::OnChangeCbChain (HWND hWndRemove, HWND hWndAfter) { // cập nhật lại handle window kế tiếp // trong chain if (hWndRemove==hWndNextViewer) hWndNextViewer = hWndAfter; else if (hWndNextViewer != NULL) SendMessage(hWndNextViewer, WM_CHANGECBCHAIN, (WPARAM)hWndRemove, (LPARAM)hWndAfter); return 0; } C4W - Clipboard - Nguyen Tri Tuan - DH.KHTN Tp.HCM13/06/2003 90 45
  46. [3] - Clipboard Viewer – Ví dụ // xử lý thông điệp WM_DESTROY void CMainWindow::OnDestroy() { // gỡ khỏi chuỗi xích ChangeClipboardChain(hWndNextViewer); PostQuitMessage(0); return 0; } C4W - Clipboard - Nguyen Tri Tuan - DH.KHTN Tp.HCM13/06/2003 91 [3] - Clipboard Viewer – Ví dụ // xử lý thông điệp WM_DRAWCLIPBOARD void CMainWindow::OnDrawClipboard() { if (hWndNextViewer != NULL ) SendMessage(hWndNextViewer, WM_DRAWCLIPBOARD, 0, 0L); // cập nhật lại vùng hiển thị: InvalidateRect(NULL, TRUE); return 0; } C4W - Clipboard - Nguyen Tri Tuan - DH.KHTN Tp.HCM13/06/2003 92 46
  47. [3] - Clipboard Viewer – Ví dụ // xử lý message WM_PAINT với định dạng // uFormat = CF_TEXT void CMainWindow::OnPaint() { RECT rc; CPaintDC dc(this); if (OpenClipboard()) { HGLOBAL hGlobal = GetClipboardData(uFormat); if (hGlobal != NULL) { LPSTR lpstr= (LPSTR) GlobalLock(hGlobal); GetClientRect(&rc); dc.DrawText(lpstr, -1, &rc, DT_LEFT); GlobalUnlock(hGlobal); } CloseClipboard(); } } C4W - Clipboard - Nguyen Tri Tuan - DH.KHTN Tp.HCM13/06/2003 93 [3] - Clipboard Viewer – Ví dụ  Xử lý thông điệp WM_PAINT với định dạng CF_OWNERDISPLAY: ƒ Một ứng dụng khi đưa dữ liệu vào Clipboard có thể dùng định dạng CF_OWNERDISPLAY SetClipboardData(CF_OWNERDISPLAY, NULL); ƒ Khi đó, chủ Clipboard có trách nhiệm: Xử lý các thông điệp được gửi đến từ Clipboard Viewer để hiển thị và cập nhật cửa sổ Clipboard Viewer C4W - Clipboard - Nguyen Tri Tuan - DH.KHTN Tp.HCM13/06/2003 94 47
  48. [3] - Clipboard Viewer – Ví dụ // Xử lý thông điệp WM_PAINT với định dạng // CF_OWNERDISPLAY void CMainWindow::OnPaint() { CPaintDC dc(this); HWND hWndOwner = GetClipboardOwner(); // chuẩn bị thông tin cấu trúc PAINTSTRUCT // để gởi cho cửa sổ chủ Clipboard HGLOBAL hGlobal = GlobalAlloc(MEM_MOVEABLE, sizeof(PAINTSTRUCT)); LPPAINTSTRUCT lpps = GlobalLock(hGlobal); CopyMemory(lpps, &dc.m_ps, sizeof(PAINTSTRUCT)); C4W - Clipboard - Nguyen Tri Tuan - DH.KHTN Tp.HCM13/06/2003 95 [3] - Clipboard Viewer – Ví dụ GlobalUnlock(hGlobal); // gửi thông điệp cho cửa sổ chủ Clipboard // yêu cầu vẽ SendMessage(hWndOwner, WM_PAINTCLIPBOARD, (WPARAM) m_hWnd, (LPARAM) hGlobal); // huỷ khối nhớ toàn cục sau khi đã sử dụng GlobalFree(hGlobal); } C4W - Clipboard - Nguyen Tri Tuan - DH.KHTN Tp.HCM13/06/2003 96 48
  49. Cám ơn - Hỏi & Đáp C4W - Clipboard - Nguyen Tri Tuan - DH.KHTN Tp.HCM13/06/2003 97 49