昆明公司建设网站制作,seo网站推广是什么,照片书那个网站做的好,海纳企业网站建设模板剪贴板是由系统定义的#xff0c;并不属于任何一个特定的进程。系统中所有进程都可以访问和设置剪贴板。剪贴板最大的特点就是数据传输没有明确的目标#xff0c;数据是被动访问的#xff1b;剪贴板的内容可以被多次访问#xff0c;直到新的数据写入。剪贴板是一种可供选择…剪贴板是由系统定义的并不属于任何一个特定的进程。系统中所有进程都可以访问和设置剪贴板。剪贴板最大的特点就是数据传输没有明确的目标数据是被动访问的剪贴板的内容可以被多次访问直到新的数据写入。剪贴板是一种可供选择的进程间通信方式但由于系统中任何一个进程都可以都可以无限制地访问剪贴板因此它是一种不可靠的通信方式。 1获取和设置剪贴板数据 涉及到的API有OpenClipboard、EmptyClipboard、SetClipboardData、GetClipboardData、CloseClipboard等。 OpenClipboard用于打开剪贴板获得剪贴板的句柄 BOOL WINAPI OpenClipboard( __in_opt HWND hWndNewOwner //指定的窗口可以收到剪贴板操作所产生的消息 //如果为NULL则采用当前任务的窗口 ); EmptyClipboard用于清空剪贴板中的内容 BOOL WINAPI EmptyClipboard(void); SetClipboardData用于设置剪贴板的内容 HANDLE WINAPI SetClipboardData( __in UINT uFormat, //指定数据格式可以是标准系统格式也可以是用户自定义格式 __in_opt HANDLE hMem //需要设置的数据的内存句柄需使用全局内存管理的函数分配和 //设置且在分配时需指定GMEM_MOVEABLE标志 ); GetClipboardData用于从剪贴板获取数据 HANDLE WINAPI GetClipboardData( __in UINT uFormat //指定获取的数据的格式获得的数据使用句柄返回 ); 2一般来说利用剪贴板进行数据通信是不具有实时性所有操作都依赖于用户。除非使用剪贴板查看器Viewer这样就可以立即知道剪贴板中内容的变化。 系统提供了WM_DRAWCLIPBOARD消息用于监视剪贴板的变化。如果调用SetClipboardViewer函数设置了窗口为剪贴板查看器那么当剪贴板中内容变化时所注册的查看器窗口就会收到WM_CHANGECBCHAIN消息和WM_DRAWCLIPBOARD消息。SetClipboardViewer函数原型如下 HWND WINAPI SetClipboardViewer( __in HWND hWndNewViewer //指定监视窗口 ); 剪贴板查看器的代码例子如下 HINSTANCE hinst; UINT uFormat (UINT)(-1); BOOL fAuto TRUE; LRESULT CALLBACK MainWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { static HWND hwndNextViewer; HDC hdc; HDC hdcMem; PAINTSTRUCT ps; LPPAINTSTRUCT lpps; RECT rc; LPRECT lprc; HGLOBAL hglb; LPSTR lpstr; HBITMAP hbm; HENHMETAFILE hemf; HWND hwndOwner; switch (uMsg) { case WM_PAINT: //收到WM_PAINT消息后显示剪贴板中的数据 hdc BeginPaint(hwnd, ps); // Branch depending on the clipboard format. //uFormat全局变量在WM_DRAWCLIPBOARD和WM_COMMAND //消息处理中使用SetAutoView设置 //根据剪贴板中数据的不同格式使用不同的显示方式 switch (uFormat) { case CF_OWNERDISPLAY: //剪贴板的所有者必须显示并刷新Viewer的窗口 hwndOwner GetClipboardOwner();//获得剪贴板的所有者 //获取剪贴板的数据 hglb GlobalAlloc(GMEM_MOVEABLE, sizeof(PAINTSTRUCT)); lpps (LPPAINTSTRUCT)GlobalLock(hglb); memcpy(lpps, ps, sizeof(PAINTSTRUCT)); GlobalUnlock(hglb); //向剪贴板所有者发送WM_PAINTCLIPBOARD消息 SendMessage(hwndOwner, WM_PAINTCLIPBOARD, (WPARAM) hwnd, (LPARAM) hglb); GlobalFree(hglb); break; case CF_BITMAP: //位图 hdcMem CreateCompatibleDC(hdc); if (hdcMem ! NULL) { if (OpenClipboard(hwnd)) //打开剪贴板 { hbm (HBITMAP) GetClipboardData(uFormat); //获取剪贴板的数据 //将位图选择进DC显示在窗口客户区 SelectObject(hdcMem, hbm); GetClientRect(hwnd, rc); BitBlt(hdc, 0, 0, rc.right, rc.bottom, hdcMem, 0, 0, SRCCOPY); CloseClipboard();//关闭剪贴板 } DeleteDC(hdcMem); //释放DC } break; case CF_TEXT: //文本 if (OpenClipboard(hwnd)) //打开剪贴板 { hglb GetClipboardData(uFormat); //获得剪贴板数据 lpstr GlobalLock(hglb); //将文本绘制在窗口客户区 GetClientRect(hwnd, rc); DrawText(hdc, lpstr, -1, rc, DT_LEFT); GlobalUnlock(hglb); CloseClipboard();//关闭剪贴板 } break; case CF_ENHMETAFILE: //增强格式图元文件 if (OpenClipboard(hwnd)) //打开剪贴板 { hemf GetClipboardData(uFormat); //获取剪贴板数据 //调用PlayEnhMetaFile在窗口客户区上显示 GetClientRect(hwnd, rc); PlayEnhMetaFile(hdc, hemf, rc); CloseClipboard(); } break; case 0: //剪贴板为空 GetClientRect(hwnd, rc); //在客户区中央显示 DrawText(hdc, The clipboard is empty., -1, rc, DT_CENTER | DT_SINGLELINE | DT_VCENTER); break; default: //不支持的其他格式 GetClientRect(hwnd, rc); DrawText(hdc, Unable to display format., -1, rc, DT_CENTER | DT_SINGLELINE | DT_VCENTER); } EndPaint(hwnd, ps); break; case WM_SIZE: //如果窗口大小改变通知剪贴板所有者窗口 if (uFormat CF_OWNERDISPLAY) { hwndOwner GetClipboardOwner();//获取剪贴板所有者 hglb GlobalAlloc(GMEM_MOVEABLE, sizeof(RECT)); lprc GlobalLock(hglb); GetClientRect(hwnd, lprc); GlobalUnlock(hglb); SendMessage(hwndOwner, WM_SIZECLIPBOARD, (WPARAM) hwnd, (LPARAM) hglb); GlobalFree(hglb); } break; case WM_CREATE: //当窗口创建时在剪贴板Viewer链中增加一个 hwndNextViewer SetClipboardViewer(hwnd); break; case WM_CHANGECBCHAIN: // If the next window is closing, repair the chain. if ((HWND) wParam hwndNextViewer) hwndNextViewer (HWND) lParam; // Otherwise, pass the message to the next link. else if (hwndNextViewer ! NULL) SendMessage(hwndNextViewer, uMsg, wParam, lParam); break; case WM_DESTROY: //窗口hwnd销毁时从剪贴板查看器链中移除 ChangeClipboardChain(hwnd, hwndNextViewer); PostQuitMessage(0); break; case WM_DRAWCLIPBOARD: // clipboard contents changed. // Update the window by using Auto clipboard format. SetAutoView(hwnd); // Pass the message to the next window in clipboard // viewer chain. SendMessage(hwndNextViewer, uMsg, wParam, lParam); break; case WM_INITMENUPOPUP: //当popup菜单弹出时收到此消息 if (!HIWORD(lParam)) //根据剪贴板中内容的格式设置菜单 InitMenu(hwnd, (HMENU) wParam); break; case WM_COMMAND: //处理用户菜单输入 switch (LOWORD(wParam)) { case IDM_EXIT: //用户点击“退出”菜单项 DestroyWindow(hwnd); break; case IDM_AUTO: //用户点击“Auto”菜单项 SetAutoView(hwnd); //设置显示格式为自动 break; default: fAuto FALSE; uFormat LOWORD(wParam); InvalidateRect(hwnd, NULL, TRUE); } break; default: //其他消息 return DefWindowProc(hwnd, uMsg, wParam, lParam); } return (LRESULT) NULL; } /********************************************************** * void WINAPI SetAutoView(HWND hwnd) * 获取剪贴板的主要格式并设置显示方式 **********************************************************/ void WINAPI SetAutoView(HWND hwnd) { static UINT auPriorityList[] { CF_OWNERDISPLAY, CF_TEXT, CF_ENHMETAFILE, CF_BITMAP }; //设置剪贴板主要格式设置显示格式 //uFormat在收到WM_PAINT消息时用到 uFormat GetPriorityClipboardFormat(auPriorityList, 4); fAuto TRUE; InvalidateRect(hwnd, NULL, TRUE); UpdateWindow(hwnd); } /************************************************************** * 功能根据剪贴板中内容的格式设置菜单项供用户选择显示方式 * 参数hwnd--窗口句柄 * hmenu--菜单句柄 **************************************************************/ void WINAPI InitMenu(HWND hwnd, HMENU hmenu) { UINT uFormat; char szFormatName[80]; LPCSTR lpFormatName; UINT fuFlags; UINT idMenuItem; // If a menu is not the display menu, no initialization is necessary. if (GetMenuItemID(hmenu, 0) ! IDM_AUTO) return; // Delete all menu items except the first. while (GetMenuItemCount(hmenu) 1) DeleteMenu(hmenu, 1, MF_BYPOSITION); // Check or uncheck the Auto menu item. fuFlags fAuto ? MF_BYCOMMAND | MF_CHECKED : MF_BYCOMMAND | MF_UNCHECKED; CheckMenuItem(hmenu, IDM_AUTO, fuFlags); // If there are no clipboard formats, return. if (CountClipboardFormats() 0) return; // Open the clipboard. if (!OpenClipboard(hwnd)) return; // Add a separator and then a menu item for each format. AppendMenu(hmenu, MF_SEPARATOR, 0, NULL); uFormat EnumClipboardFormats(0); while (uFormat) { // Call an application-defined function to get the name // of the clipboard format. lpFormatName GetPredefinedClipboardFormatName(uFormat); // For registered formats, get the registered name. if (lpFormatName NULL) { // Note that, if the format name is larger than the // buffer, it is truncated. if (GetClipboardFormatName(uFormat, szFormatName, sizeof(szFormatName))) lpFormatName szFormatName; else lpFormatName (unknown); } // Add a menu item for the format. For displayable // formats, use the format ID for the menu ID. if (IsDisplayableFormat(uFormat)) { fuFlags MF_STRING; idMenuItem uFormat; } else { fuFlags MF_STRING | MF_GRAYED; idMenuItem 0; } AppendMenu(hmenu, fuFlags, idMenuItem, lpFormatName); uFormat EnumClipboardFormats(uFormat); } CloseClipboard(); } BOOL WINAPI IsDisplayableFormat(UINT uFormat) { switch (uFormat) { case CF_OWNERDISPLAY: case CF_TEXT: case CF_ENHMETAFILE: case CF_BITMAP: return TRUE; } return FALSE; } 3剪贴板中存在各种数据格式系统使用一个UINT类型的数据来表示剪贴板中数据类型。在这些格式信息中有很多是各种应用程序之间通用的比如文本、位图等。这些数据格式由系统预先定义称为标准格式当然应用程序也可自行定义剪贴板的数据格式这样可以方便地在同一个应用程序的不同实例间进行数据传递而不用对数据格式进行过多的处理典型的就包括word。 常见标准格式 CF_BITMAP //位图句柄(HBITMAP) CF_DIB //内存位置包含BITMAPINFO结构和位图数据 CF_ENHMETAFILE //增强的图元文件句柄(HENHMETAFILE) CF_OEMTEXT //OEM字符集的字符串(以CR-LF格式换行) CF_OWNERDISPLAY //由剪贴板查看器查看的格式 CF_PALETTE //调色板数据 CF_RIFF //标准的CF_WAVE波形数据 CF_TEXT //ANSI字符串(以CR-LF格式换行) CF_WAVE //PCM波形 CF_TIFF //Tagged图像文件格式 CF_UNICODETEXT //Unicode字符串 自定义格式 调用函数RegisterClipboardFormat可以自定义格式 UINT WINAPI RegisterClipboardFormat(//返回值是系统分配的格式类型值(UINT) __in LPCTSTR lpszFormat //格式名 ); 多种格式 很多情况下数据的格式不止一种比如格式化的文本有效的格式不止一种例如从Word中复制的数据、从网页中复制的数据等因此可能存在多重格式。 以下几个API函数是用于获取当前剪贴板中的格式信息的 GetPriorityClipboardFormat的功能是检测剪贴板中是否有paFormatPriorityList参数指定的格式数组中的格式存在如果有则返回格式数组中的第一个剪贴板当前具有的格式 int WINAPI GetPriorityClipboardFormat( __in UINT *paFormatPriorityList, //格式数组存储用于检测的格式信息 __in int cFormats //paFormatPriorityList数组的大小 ); CountClipboardFormats函数用于返回当前剪贴板中具有的不同格式的数量 int WINAPI CountClipboardFormats(void); EnumClipboardFormats函数用于列举当前剪贴板中的所有格式 UINT WINAPI EnumClipboardFormats( __in UINT format //指定一个已知的格式通过函数返回值返回下一个格式 ); GetUpdatedClipboardFormats函数用于获取当前剪贴板的所有格式 BOOL WINAPI GetUpdatedClipboardFormats( __out PUINT lpuiFormats, //指向用于保存返回的格式数组的缓冲区 __in UINT cFormats, //lpuiFormats可以容纳的格式信息的数量 __out PUINT pcFormatsOut //返回真是的数组大小 ); 由于剪贴板数据会有多种格式在调用GetClipboardData函数获取数据时应该指定格式。一般情况下指定不同格式将获得不同的内容。 剪贴板数据的格式信息 每一个剪贴板格式都有一个格式名格式名是一个字符串使用GetClipboardFormatName函数可以获得 int WINAPI GetClipboardFormatName( __in UINT format, //要检索的格式ID __out LPTSTR lpszFormatName, //存储返回的格式名的缓冲区 __in int cchMaxCount //拷贝到缓冲区的最大数据长度 );