首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> 關於VC++

Visual C++ 剪貼板操作完全指南:文本、圖元文件、位圖、自定義格式與監聽

     編輯:關於VC++

前言

在 VC++/MFC 中操作剪貼板其實相當簡單。本文系統介紹六大核心場景:文本、WMF 圖元文件、位圖、自定義格式、剪貼板變更監聽、自動粘貼到他應用窗口。

一、文本內容操作

1. 將文本複製到剪貼板

CString source = _T("要複製的文本內容");
if (OpenClipboard()) {
    EmptyClipboard();
    HGLOBAL hGlob = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, (source.GetLength() + 1) * sizeof(TCHAR));
    LPTSTR pBuf = (LPTSTR)GlobalLock(hGlob);
    _tcscpy_s(pBuf, source.GetLength() + 1, source);
    GlobalUnlock(hGlob);
    SetClipboardData(CF_UNICODETEXT, hGlob); // Unicode 版本
    CloseClipboard();
}

關鍵點: 必須使用 GMEM_MOVEABLE | GMEM_DDESHARE 分配可移動共享內存;Unicode 程序用 CF_UNICODETEXT,ANSI 程序用 CF_TEXT。

2. 從剪貼板獲取文本

CString fromClipboard;
if (OpenClipboard()) {
    HANDLE hData = GetClipboardData(CF_UNICODETEXT);
    if (hData) {
        LPTSTR pBuf = (LPTSTR)GlobalLock(hData);
        fromClipboard = pBuf;
        GlobalUnlock(hData);
    }
    CloseClipboard();
}

二、WMF 圖元文件操作

1. 複製增強圖元文件到剪貼板

if (OpenClipboard()) {
    EmptyClipboard();
    CMetaFileDC* pDC = new CMetaFileDC();
    pDC->CreateEnhanced(NULL, NULL, NULL, _T("MetaFile Description"));
    // 在 pDC 上繪圖...
    HENHMETAFILE hEMF = pDC->CloseEnhanced();
    SetClipboardData(CF_ENHMETAFILE, hEMF);
    CloseClipboard();
    delete pDC;
}

2. 從剪貼板讀取並繪製圖元文件

if (OpenClipboard()) {
    HENHMETAFILE hEMF = (HENHMETAFILE)GetClipboardData(CF_ENHMETAFILE);
    if (hEMF) {
        CClientDC dc(this);
        CRect rect(0, 0, 200, 200);
        dc.PlayMetaFile(hEMF, rect);
    }
    CloseClipboard();
}

三、位圖操作

1. 保存位圖到剪貼板

if (OpenClipboard()) {
    EmptyClipboard();
    CBitmap bmp;
    CClientDC screenDC(this);
    CDC memDC;
    memDC.CreateCompatibleDC(&screenDC);
    CRect rect(0, 0, 200, 200);
    bmp.CreateCompatibleBitmap(&screenDC, rect.Width(), rect.Height());
    CBitmap* pOldBmp = memDC.SelectObject(&bmp);
    // 在 memDC 上繪圖...
    memDC.SelectObject(pOldBmp);
    SetClipboardData(CF_BITMAP, bmp.Detach()); // 傳遞 HBITMAP 所有權
    CloseClipboard();
}

2. 從剪貼板讀取位圖並繪製

if (OpenClipboard()) {
    HBITMAP hBmp = (HBITMAP)GetClipboardData(CF_BITMAP);
    if (hBmp) {
        CBitmap bmp;
        bmp.Attach(hBmp); // 不獲取所有權,僅包裝
        CClientDC dc(this);
        CDC memDC;
        memDC.CreateCompatibleDC(&dc);
        CBitmap* pOld = memDC.SelectObject(&bmp);
        BITMAP bmInfo;
        bmp.GetBitmap(&bmInfo);
        dc.BitBlt(0, 0, bmInfo.bmWidth, bmInfo.bmHeight, &memDC, 0, 0, SRCCOPY);
        memDC.SelectObject(pOld);
        bmp.Detach(); // 釋放包裝,不刪除對象
    }
    CloseClipboard();
}

四、自定義格式數據

使用 RegisterClipboardFormat 註冊唯一格式名,實現任意結構體數據的跨進程傳遞。

struct MyFormatData {
    long val1;
    int  val2;
};

// 寫入
UINT uFmt = RegisterClipboardFormat(_T("MY_CUSTOM_FORMAT"));
if (OpenClipboard()) {
    EmptyClipboard();
    MyFormatData data = { 100, 200 };
    HGLOBAL hGlob = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, sizeof(MyFormatData));
    MyFormatData* pBuf = (MyFormatData*)GlobalLock(hGlob);
    *pBuf = data;
    GlobalUnlock(hGlob);
    SetClipboardData(uFmt, hGlob);
    CloseClipboard();
}

// 讀取
if (OpenClipboard()) {
    HANDLE hData = GetClipboardData(uFmt);
    if (hData) {
        MyFormatData* pBuf = (MyFormatData*)GlobalLock(hData);
        MyFormatData data = *pBuf;
        GlobalUnlock(hData);
        // 使用 data...
    }
    CloseClipboard();
}

五、監聽剪貼板內容變更

通過設置剪貼板查看器鏈,接收 WM_DRAWCLIPBOARD 消息:

// 初始化時調用
SetClipboardViewer(); // 將當前窗口加入查看器鏈

// 消息映射
ON_MESSAGE(WM_DRAWCLIPBOARD, OnClipChange)

// 處理函數
afx_msg LRESULT OnClipChange(WPARAM, LPARAM) {
    CTime time = CTime::GetCurrentTime();
    SetDlgItemText(IDC_CHANGED_DATE, time.Format(_T("%a, %b %d, %Y -- %H:%M:%S")));
    DisplayClipboardText(); // 自定義顯示函數
    return 0;
}

// 退出時調用 ChangeClipboardChain 移除鏈節點

六、自動將數據粘貼到另一應用程序窗口

獲取目標窗口句柄後發送粘貼消息:

SendMessage(hTargetWnd, WM_PASTE, 0, 0);

前提是目標窗口已獲得焦點並處理 WM_PASTE 消息。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved