程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> Win32開發入門(21):復制、粘貼及剪貼板操作

Win32開發入門(21):復制、粘貼及剪貼板操作

編輯:關於C++

我要提醒一下大家,看了我的博文學到的知識,千萬不要用於實際開發,不然你會被你的上司罵: “媽的,這些東西哪來的,從來沒有人這樣做過。”不信你試試,腦細胞被凍結的經理或者技術總監們 肯定會這樣說的。

如果是一些有X年工作經驗(X永遠不可能大於100)的程序員肯定會說:“你 怎麼這麼不成熟?”你如果被別人這麼說之後,不知道你會不會很傷心,或者很生氣?

我呢, 曾經被N個人這樣教育過,不過你猜猜我當時的心情,我非常高興,喜悅。為什麼呢?

你不妨想 想,當一個人說你不成熟的時候,你說他其實在說什麼,他其實是在說他自己很成熟,就因為他自己熟 得快腐爛了,滿身惡臭,才會顯得你不成熟,仔細想想,是不是這個事兒?

那麼,成熟到底好 不好呢?我相信小學生都有這樣的常識,當一個果子熟透了的時候,會怎麼樣?它會從樹枝上高空墜落 ,然後狠巴巴地摔到地上,粉身碎骨。呵呵,所以,你現在明白了吧,當別人說我不成熟的時候,我會 非常高興,我心裡想:“快了快了,你快完蛋了。”

好,牛皮吹完,樂一樂。下面開始干正事 ,今天咱們來認識一下怎麼操作粘貼板,即復制和粘貼數據。我不知道大家看不看恐怖片,反正我現在 不得不嚇你一回。這個粘貼板的操作,其實挺痛苦的,所以,如果在實際開發中,我肯定用CLR的類來 弄,是的,這是我的做事原則,哪種方法最簡單就用哪種,這叫什麼?效率最大化,只有閒著沒事干的 人才會簡單問題復雜化。

不過呢,畢竟這裡咱們要了解一下在Win32下操作粘貼板的,所以呢, 我還是用API來解決,至於CLR方法,相信你比我更會用,你不信算了,反正我信了,我不是菜鳥,但我 是菜鶴。

讀寫粘貼板就像我們上廁所一樣,首先打開廁所門(調用OpenClipboard函數),然後 大動作(SetClipboardData或GetClipboardData),干完了出來,關上廁所門(調用CloseClipboard) 。

我說它有點痛苦是因為操作的時睺,與我們平常讀寫一些數據不同,數據寫入到剪貼板後就 由操作系統接管了,期間你不能任意讀寫,就像公共廁所是提供給你用的,你不能在裡面給人家裝修, 拆掉人家的東西。

一、復制數據

我這裡就不弄太復雜了,就復制一串文本吧,這也常 用。先看看代碼。

//復制內容     
//打開剪貼板     
OpenClipboard(hdlg);     
//清空剪貼板     
EmptyClipboard();     
//向剪貼板中放東西     
HWND hedt = GetDlgItem(hdlg, IDC_EDTCPY);     
WCHAR ntext[100];     
SendMessage(hedt, WM_GETTEXT, (WPARAM)100, (LPARAM)ntext);     
//分配內存     
HGLOBAL hgl = GlobalAlloc(GMEM_MOVEABLE, 100 * sizeof(WCHAR));     
LPWSTR lpstrcpy = (LPWSTR)GlobalLock(hgl);     
memcpy(lpstrcpy, ntext, 100 * sizeof(WCHAR));     
GlobalUnlock(hgl);     
SetClipboardData(CF_TEXT, lpstrcpy);     
//關閉剪貼板     
CloseClipboard();

大家看到,在打開剪貼板後,要先清空一下,調用EmptyClipboard函數, 把裡面的東西清了,才能放東西進去。但是我們不能直接用SetClipboardData設置數據,不然你試試, 會失敗,因為數據雖然是我們放進去的,但他歸系統管,雖然我們的房子是自己買的,但也歸小區物業 公司管理。

因此,我們要通過內存拷貝來完成,GlobalAlloc函數分配全局內存塊,不過標志參 數要用GMEM_MOVEABLE,為什麼,看MSDN怎麼說的。

你可能會問,SetClipboardData中的參數是 HANDLE類型的,為什麼不用轉換就能與

If SetClipboardData succeeds, the system owns the object identified by the hMem parameter. The application may not write to or free the data once ownership has been transferred to the system, but it can lock and read from the data until the CloseClipboard function is called. (The memory must be unlocked before the Clipboard is closed.) If the hMem parameter identifies a memory object, the object must have been allocated using the function with the GMEM_MOVEABLE flag.

這段話不知道你看 懂了沒有,反正我看不懂,很難翻譯,干脆不譯了。就是這段話告訴了我們,用GlobalAlloc分配內存 時要用GMEM_MOVEABLE標志。既然內存是動的(當然物理內存是固定的),那我們在拷貝前當然要把它 鎖定,拷貝完了再解鎖,防止這塊內存被外星人意外修改了。

二、粘貼數據

復制完了, 就粘貼了。

else if(LOWORD(wParam) == IDC_BTNPAST)     
{     
    HWND hedtPas = GetDlgItem(hdlg, IDC_EDTPAST);     
    OpenClipboard(hdlg);     
    //判熂是否為文本內容     
    if(IsClipboardFormatAvailable(CF_TEXT))     
    {     
        //取出數據     
        HGLOBAL hg = GetClipboardData(CF_TEXT);     
        //鎖定內存塊     
        LPWSTR wstr = (LPWSTR)GlobalLock(hg);     
        if(wstr != NULL)     
        {     
            SendMessage(hedtPas, WM_SETTEXT, NULL, (LPARAM)wstr);     
        }     
        GlobalUnlock(hg);     
    }     
    CloseClipboard();     
}

這裡干嗎要用IsClipboardFormatAvailable來檢測一下剪貼板中是不是CF_TEXT格式的數據 呢?因為在你復制了文本後,有可能在這期間其他程序把其他數據放到剪貼板上了,所以,要檢查一下 好,謹慎一點總是沒有錯的。

也許你會問,GetClipboardData不是返回HANDLE類型嗎?怎麼可 以賦給HGLOBAL類型的變量而不用轉換呢,你把開對應頭文件看看就懂了,HGLOBAL就是HANDLE。

好了,就這樣吧,只要你簡單了解操作過程就夠了,不必深究,呵呵,因為有比這更簡單的方 法。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved