標籤:amp 操作 one net 多次 tran idc dcl itme
??
上一篇我們學習了常見的通用對話方塊,本篇來瞭解剪貼簿的使用,它經常使用於複製粘貼功能。
剪貼簿是Windows最早就增加的功能,因為該功能很有用,我們差點兒每天都會使用到。通過剪貼簿,我們就能夠將資料從一個應用程式傳遞到還有一個應用程式,是一種簡單的處理序間通訊。
很多文檔處理軟體都有複製、剪下、粘貼功能,這些都是用Windows剪貼簿實現的,當然我們也能夠在我們的程式中實現自己的剪貼簿功能。本篇我們就來實現自己的剪貼簿。使用剪貼簿時,都是先把來源資料先傳到剪貼簿上。再在須要的時候從剪貼簿傳輸到目的處。所以看起來我們就是直接從源直接搬到目的處。
Windows的控制項比方EditBox,已經在控制項內部實現了複製、剪下和粘貼功能,所以我們能直接使用。但我們非常多控制項是沒有這個功能的。比方靜態文本控制項,自己建立的表單等,我們就沒有辦法直接拷貝粘貼,這些都是須要我們自己實現的。
還是老規矩。以下我們先介紹剪貼簿經常使用函數,然後用執行個體來示範基本使用方法。
無論是複製還是粘貼,使用剪貼簿首先要開啟它,開啟剪貼簿API函數例如以下:
BOOL OpenClipboard(HWND hWndNewOwner);
唯一參數hWndNewOwner是和剪貼簿關聯的表單控制代碼,假設該參數為NULL,則關聯到當前任務。
在從源設定資料到剪貼簿之前,必須先清空剪貼簿。同一時候得到剪貼簿的佔有權。API函數例如以下:
Bool EmptyClipboard(void)
該函數沒有參數。
向剪貼簿設定資料。也就是拷貝操作:
HANDLE SetClipboardData(UINT uFormat, HANDLE hMem);
參數uFormat表示要設定傳輸到剪貼簿上的資料格式,提前定義的格式有十幾種。我們這裡列出幾個最經常使用的,其它請參考MSDN:
CF_TEXT:表示要設定的格式為以NULL結尾的ANSI字串。及標C的字串。這是最簡單的剪貼簿資料格式。
CF_UNICODETEXT:格式為包括Unicode字元集的字串。
CF_BITMAP:格式為裝置相關的位元影像。
參數hMem:設定資料的控制代碼,一般為GlobalAlloc函數返回的控制代碼。
設定完資料或者從剪貼簿擷取資料之後。須要關閉剪貼簿,否則其它應用程式無法再開啟剪貼簿。API函數為:
Bool CloseClipboard(void);
該函數沒有參數。
從剪貼簿擷取資料。也就是粘貼操作,API函數為:
HANDLE GetClipboardData(UINT uFormat);
參數uFormat就是想要擷取的資料格式。
查詢剪貼簿中是否有指定格式的資料:
BOOL IsClipboardFormatAvailable(UINT format);
參數format就是想要查詢的資料格式,該函數不須要開啟剪貼簿。
以上幾個就是最基本的剪貼簿相關函數:
以下我們用這些函數來完畢主要的文本複製粘貼和映像複製粘貼功能。為了示範。我們設定了一幅圖和一行文本作為資料來源。同一時候建立兩個button“copy image”和“copy text”分別用於複製映像和文本,當點擊時複製對於的資料。
為了程式簡潔。我用了滑鼠左鍵來抬起作為粘貼觸發,粘貼的位置就是抬起滑鼠時的滑鼠位置,您能夠在不同的地方多次點擊後抬起滑鼠來反覆粘貼,詳細代碼例如以下:
#include <windows.h>#include <tchar.h>#define IDC_LABEL 1000#define IDC_COPY_IMG 1001#define IDC_COPY_TXT 1002static TCHAR szAppName[] = TEXT("Clipboard Demo");static LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM);int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow){ HWND hWnd; MSG msg; WNDCLASS wndclass; wndclass.style = CS_HREDRAW | CS_VREDRAW; wndclass.lpfnWndProc = WndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = hInstance; wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); wndclass.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH); wndclass.lpszMenuName = NULL; wndclass.lpszClassName = szAppName; if (!RegisterClass(&wndclass)) { MessageBox (NULL, TEXT("This program requires Windows NT!"), szAppName, MB_ICONERROR); return 0; } hWnd = CreateWindow(szAppName, // window class name szAppName, // window caption WS_OVERLAPPEDWINDOW, // window style CW_USEDEFAULT, // initial x position CW_USEDEFAULT, // initial y position 400, // initial x size 300, // initial y size NULL, // parent window handle NULL, // window menu handle hInstance, // program instance handle NULL); // creation parameters ShowWindow(hWnd, iCmdShow); UpdateWindow(hWnd); while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam;}static int DrawBmp(HDC hDC, int xDst, int yDst, int width, int height, int BytesPerPixel, unsigned char *pPixels){int ret = -1;HDC hdcMem;BITMAPINFO bmi;BYTE *pBits = NULL;memset(&bmi, 0x00, sizeof(BITMAPINFO));bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);bmi.bmiHeader.biWidth = width;bmi.bmiHeader.biHeight = height;bmi.bmiHeader.biPlanes = 1;bmi.bmiHeader.biBitCount = BytesPerPixel*8;bmi.bmiHeader.biCompression = BI_RGB;hdcMem = CreateCompatibleDC(hDC);if (hdcMem){HBITMAP hBitmap = CreateDIBSection(NULL, &bmi, DIB_RGB_COLORS, (void **)&pBits, NULL, 0);if (hBitmap){HGDIOBJ hOldBmp = SelectObject(hdcMem, hBitmap);memcpy(pBits, pPixels, width * height * BytesPerPixel);BitBlt(hDC, xDst, yDst, width, height, hdcMem, 0, 0, SRCCOPY);SelectObject(hdcMem, hOldBmp);DeleteObject(hBitmap);ret = 0;}DeleteDC(hdcMem);}return ret;}static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam){HDC hDC;static HBITMAP hBmp;static BITMAP bm;switch (message){case WM_CREATE:CreateWindow(TEXT("STATIC"), TEXT("你好,World!"), WS_CHILD|WS_VISIBLE, 10, 160, 100, 20, hWnd, (HMENU)IDC_LABEL, NULL, NULL);CreateWindow(TEXT("BUTTON"), TEXT("copy image"), WS_CHILD|WS_VISIBLE, 10, 190, 100, 20, hWnd, (HMENU)IDC_COPY_IMG, NULL, NULL);CreateWindow(TEXT("BUTTON"), TEXT("copy text"), WS_CHILD|WS_VISIBLE, 10, 220, 100, 20, hWnd, (HMENU)IDC_COPY_TXT, NULL, NULL);hBmp = (HBITMAP)LoadImage(NULL, TEXT("start.bmp"), IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);GetObject(hBmp, sizeof(BITMAP), &bm);return 0;case WM_PAINT:{PAINTSTRUCT ps;hDC = BeginPaint(hWnd, &ps);HDC hMemDC = CreateCompatibleDC(hDC);HBITMAP hOldBitmap = (HBITMAP)SelectObject(hMemDC, hBmp);BitBlt(hDC, 10, 10, bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY);DeleteDC(hMemDC);EndPaint(hWnd, &ps);}return 0;case WM_COMMAND:{int id = LOWORD(wParam);switch (id){case IDC_COPY_IMG:{BOOL ret;BYTE *pData = NULL;BITMAPINFO bmpInfo;bmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);bmpInfo.bmiHeader.biWidth = bm.bmWidth;bmpInfo.bmiHeader.biHeight = bm.bmHeight;bmpInfo.bmiHeader.biPlanes = 1;bmpInfo.bmiHeader.biBitCount = 32;bmpInfo.bmiHeader.biCompression = BI_RGB;HDC hClientDC = GetDC(hWnd);HDC hMemDC = CreateCompatibleDC(hClientDC);HBITMAP hBitmap = CreateDIBSection(hMemDC, &bmpInfo, DIB_RGB_COLORS, (void **)&pData, NULL, 0);SelectObject(hMemDC, hBitmap);ret = BitBlt(hMemDC, 0, 0, bm.bmWidth, bm.bmHeight, hClientDC, 10, 10, SRCCOPY);DeleteDC(hMemDC);LONG len = bm.bmWidth * bm.bmHeight * 4;HGLOBAL hClipData = GlobalAlloc(GHND, len);BYTE *pClipData = (BYTE *)GlobalLock(hClipData);memcpy(pClipData, pData, len);ret = GlobalUnlock(hClipData);ret = OpenClipboard(hWnd);ret = EmptyClipboard();SetClipboardData(CF_BITMAP, hClipData);ret = CloseClipboard();DeleteObject(hBitmap);ReleaseDC(hWnd, hClientDC);MessageBox(hWnd, TEXT("image has been copy into clipboard"), TEXT("info"), MB_OK);}break;case IDC_COPY_TXT:{BOOL ret;TCHAR buf[256];GetWindowText(GetDlgItem(hWnd, IDC_LABEL), buf, _countof(buf));int len = _tcslen(buf) + 1;HGLOBAL hClipData = GlobalAlloc(GHND, len * sizeof(TCHAR));TCHAR *pClipData = (TCHAR *)GlobalLock(hClipData);memcpy(pClipData, buf, len * sizeof(TCHAR));pClipData[len-1] = (TCHAR)0;ret = GlobalUnlock(hClipData);ret = OpenClipboard(hWnd);ret = EmptyClipboard();SetClipboardData(CF_TEXT, hClipData);ret = CloseClipboard();MessageBox(hWnd, TEXT("text has been copy into clipboard"), TEXT("info"), MB_OK);}break;default:break;}}return 0;case WM_LBUTTONUP:{BOOL ret;WORD xPos = LOWORD(lParam); WORD yPos = HIWORD(lParam);ret = IsClipboardFormatAvailable(CF_BITMAP);if (ret){ret = OpenClipboard(hWnd);HGLOBAL hglb = GetClipboardData(CF_BITMAP);//len = GlobalSize(hglb);BYTE *pClipData = (BYTE *)GlobalLock(hglb);HDC hClientDC = GetDC(hWnd);DrawBmp(hClientDC, xPos, yPos, bm.bmWidth, bm.bmHeight, 4, pClipData);GlobalUnlock(hglb);CloseClipboard();ReleaseDC(hWnd, hClientDC);}ret = IsClipboardFormatAvailable(CF_TEXT);if (ret){ret = OpenClipboard(hWnd);HGLOBAL hglb = GetClipboardData(CF_TEXT);TCHAR *pClipData = (TCHAR *)GlobalLock(hglb);HDC hClientDC = GetDC(hWnd);int len = _tcslen(pClipData);//len = GlobalSize(hglb);TextOut(hClientDC, xPos, yPos, pClipData, len);GlobalUnlock(hglb);CloseClipboard();ReleaseDC(hWnd, hClientDC);}}return 0;case WM_DESTROY:DeleteObject(hBmp);PostQuitMessage(0);return 0 ;}return DefWindowProc (hWnd, message, wParam, lParam);}
示範範例中在設定剪貼簿時。須要用GlobalAlloc函數分配全域記憶體,設定和擷取資料前須要GlobalLock函數鎖定記憶體一般拷貝資料,使用後再用GlobalUnlock函數解鎖記憶體,這幾個函數在使用剪貼簿基本成了討論,照葫蘆畫瓢即可了,要瞭解具體參數請查看MSDN。
本示範範例程式程式執行後,分別點擊了拷貝映像和拷貝文本本任意點擊,效果例如以下:
總的來說剪貼簿的基本應用還是比較簡單。相關的其它或很多其它的資訊請查看MSDN。
對本文有什麼疑議請給我留言。
很多其它經驗交流能夠增加Windows編程討論QQ群:454398517。
關注公眾平台:程式猿互動聯盟(coder_online),你能夠第一時間擷取原創技術文章,和(java/C/C++/Android/Windows/Linux)技術大牛做朋友,線上交流編程經驗,擷取編程基礎知識,解決編程問題。程式猿互動聯盟,開發人員自己的家。
轉載請註明出處http://www.coderonline.net/?
p=1815。謝謝合作!
【Windows編程】系列第九篇:剪貼簿使用