在應用程式中監視剪貼簿的變化和內容 (轉)
在應用中監視剪貼簿的變化和內容:namespace prefix = o ns = "urn:schemas--com::office" />
to:stove@vip.sina.com">stove@vip.sina.com
剪貼簿是中級的堆空間,系統中任何一個應用程式對剪貼簿都有訪問權,可以透過剪貼簿訊息和使用剪貼簿來讀寫剪貼簿內容。因此使用剪貼簿不僅可以在同一個應用程式內互動資料,也可以在不通應用程式之間互動資料。尤其是在不通應用程式之間互動時,應用程式往往需要對剪貼簿內容的變化做到實時感知,即應用程式要能監視剪貼簿內容的變化。
Windows應用是訊息的,同理當剪貼簿內容發生變化時,Windows提供了剪貼簿變化訊息,因此要實時感知剪貼簿內容的變化,關鍵是應用程式要能響應和處理Windows觸發的剪貼簿變化訊息。
第一步,要將視窗註冊為Clipboard Viewer
需要首先解釋兩個概念:Clipboard Viewer和Clipboard Viewer Chain。
Clipboard Viewer是一個需要取得並顯示剪貼簿內容的視窗,透過Clipboard Viewer這個機制,應用程式可以在不影響剪貼簿內容的情況下獲取剪貼簿的變化訊息。Clipboard Viewer可以顯示系統定義的標準格式的剪貼簿內容,也可以顯示應用自定義的私有資料格式的內容。透過SetClipboardViewer將視窗註冊為Clipboard Viewer。
Clipboard Viewer Chain是儲存Clipboard Viewer視窗以及他們之間的前後向關係的一個Windows系統連結串列,當一個視窗註冊為Clipboard Viewer後,他會被加入Clipboard Viewer Chain,並得到連結串列中下一個Viewer視窗的控制程式碼,該控制程式碼必須儲存以在響應訊息時使用,該控制程式碼的作用在下文說明。Windows正是透過Clipboard Viewer Chain保證了所有Clipboard Viewer能接收和響應剪貼簿變化訊息。
第二步,響應剪貼簿變化訊息,判斷和取出剪貼簿內容
在訊息響應裡必須正確處理兩個訊息:WM_DRAWCLIPBOARD和WM_CHANGECBCHAIN。
當剪貼簿內容發生變化時,Windows將觸發WM_DRAWCLIPBOARD訊息,並將該訊息送給Clipboard Viewer Chain的第一個視窗。每一個Clipboard Viewer視窗,包括第一個視窗在響應和處理該訊息後,必須根據其儲存的連結串列中的下一個視窗的控制程式碼將該訊息傳送給下一個Clipboard Viewer視窗。視窗可以在該訊息中取出剪貼簿內容,並判斷是否是該視窗增在監視的內容,如果是就進行相應的處理。
當某個Clipboard Viewer視窗登出時,系統將觸發WM_CHANGECBCHAIN,並將該訊息送給Clipboard Viewer Chain的第一個視窗。每一個視窗必須處理該訊息。
第三步,將視窗從Clipboard Viewer Chain中登出
當視窗不再需要監視剪貼簿變化訊息,或視窗要關閉時,必須呼叫ChangeClipboardChain函式將視窗從Clipboard Viewer Chain中登出。登出後系統會觸發WM_CHANGECBCHAIN訊息,同WM_DRAWCLIPBOARD訊息一樣,該訊息會給傳送給Clipboard Viewer Chain的第一個視窗處理。下面程式碼示例當視窗被關閉時進行登出。
下面的程式碼片斷給出了監視剪貼簿中是否複製了URL地址的例子,如果剪貼簿中的內容是URL地址,則將其顯示在視窗介面上。為使示例程式碼具有一般性,下面給出了一般Windows程式程式碼和基於MFC的代程式碼。其他語言要實現該功能可以參考Windows程式程式碼。兩個DEMO的完成程式碼請見附件。
Windows程式示例程式碼
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
unsigned int anFormats[] = {CF_TEXT};
unsigned int nFormat;
switch (message)
{
//----------------------------------------------------------------
case WM_CREATE:
//將本視窗註冊到Clipboard Viewer Chain,
//並儲存Clipboard Viewer Chain中下一個視窗的控制程式碼
hwndNextViewer = SetClipboardViewer(hWnd);
break;
case WM_CHANGECBCHAIN: //Clipboard Viewer登出
//如果登出的Clipboard Viewer視窗是本視窗的下一個視窗,
//則修改本視窗儲存的下一個視窗控制程式碼,
//否則將該訊息傳遞到Clipboard Viewer Chain的下一個視窗
if ((HWND) wParam == hwndNextViewer)
hwndNextViewer = (HWND) lParam;
else if (hwndNextViewer != NULL)
SendMessage(hwndNextViewer, message, wParam, lParam);
break;
case WM_DRAWCLIPBOARD: //剪貼簿內容變化
//觸發ON_PAINT顯示URL內容
InvalidateRect(hWnd, NULL, TRUE);
UpdateWindow(hWnd);
//否則將該訊息傳遞到Clipboard Viewer Chain的下一個視窗
SendMessage(hwndNextViewer, message, wParam, lParam);
break;
case WM_DESTROY:
//從Clipboard Viewer Chain登出本視窗
ChangeClipboardChain(hWnd, hwndNextViewer);
PostQuitMessage(0);
break;
//----------------------------------------------------------------
case WM_COMMAND:
wmId = LO(wParam);
wmEvent = HIWORD(wParam);
// Parse the menu ions:
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX,
hWnd, (DLGPROC)About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
//判斷剪貼簿中的內容是否為URL地址,如是則顯示
nFormat = GetPriorityClipboardFormat(anFormats,sizeof(anFormats));
if(nFormat == CF_TEXT)
{
OpenClipboard(hWnd);
HGLOBAL hMem = GetClipboardData(nFormat);
LPTSTR lpstr = (LPTSTR)GlobalLock(hMem);
if(strstr(lpstr,"http://") != NULL ||
strstr(lpstr,"://") != NULL ||
strstr(lpstr,"file://") != NULL)
{
RECT rt;
GetClientRect(hWnd, &rt);
DrawText(hdc, lpstr, -1, &rt, DT_LEFT);
}
GlobalUnlock(hMem);
CloseClipboard();
}
EndPaint(hWnd, &ps);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
MFC程式示例程式碼
首先要對映以下訊息和繼承以下函式
afx_msg void OnChangeCbChain(HWND hWndRemove, HWND hWndAfter);
afx_msg void OnDrawClipboard();
afx_msg void OnDestroy();
virtual void OnInitialUpdate();
void CMonitorUrlView::OnInitialUpdate()
{
CListView::OnInitialUpdate();
m_pListCtrl = &GetListCtrl();;
m_pListCtrl->SetExtendedStyle(LVS_EX_FULLROWSELECT |
LVS_EX_GRIDLINES |
LVS_EX_TRACKSELECT |
LVS_EX_TWOCLICKACTIVATE |
LVS_EX_UNDERLINECOLD);
m_pListCtrl->ModifyStyle(LVS_TYPEMASK, LVS_REPORT);
m_pListCtrl->InsertColumn(0, "URL",LVCFMT_LEFT,600,1);
//將本視窗註冊到Clipboard Viewer Chain,
//並儲存Clipboard Viewer Chain中下一個視窗的控制程式碼
m_hwndNextViewer = SetClipboardViewer();
}
void CMonitorUrlView::OnDestroy()
{
CListView::OnDestroy();
//從Clipboard Viewer Chain登出本視窗
ChangeClipboardChain(m_hwndNextViewer);
}
//Clipboard Viewer登出
void CMonitorUrlView::OnChangeCbChain(HWND hWndRemove, HWND hWndAfter)
{
//如果登出的Clipboard Viewer視窗是本視窗的下一個視窗,
//則修改本視窗儲存的下一個視窗控制程式碼,
CView::OnChangeCbChain(hWndRemove,hWndAfter);
if(hWndRemove == m_hwndNextViewer)
m_hwndNextViewer = hWndAfter;
}
//剪貼簿內容變化,判斷剪貼簿中的內容是否為URL地址,如是則顯示
void CMonitorUrlView::OnDrawClipboard()
{
CView::OnDrawClipboard();
unsigned int anFormats[] = {CF_TEXT};
unsigned int nFormat =
GetPriorityClipboardFormat(anFormats,sizeof(anFormats));
if(nFormat == CF_TEXT)
{
HGLOBAL hMem;
OpenClipboard();
if(hMem = ::GetClipboardData(CF_TEXT))
{
LPTSTR lpszText = (LPTSTR) GlobalLock(hMem);
CString strURL = lpszText;
strURL = strURL.SpanExcluding(" ");
if(strURL.Left(7).CompareNoCase("http://") == 0 ||
strURL.Left(6).CompareNoCase("ftp://") == 0 ||
strURL.Left(7).CompareNoCase("file://") == 0)
{
m_pListCtrl->InsertItem(0,lpszText);
}
GlobalUnlock(hMem);
}
CloseClipboard();
}
}
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752019/viewspace-956450/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- JavaScript複製內容到剪貼簿JavaScript
- python兩種獲取剪貼簿內容的方法Python
- Ember for Mac創意剪貼簿應用Mac
- 非同步剪貼簿API:解放剪貼簿操作非同步API
- 教你JavaScript實現一鍵複製內容剪貼簿JavaScript
- Mac 剪貼簿命令Mac
- AllClips for mac(剪貼簿管理程式)Mac
- Win10系統剪貼簿在哪?怎麼清空剪貼簿Win10
- 剪貼簿檢視管理器Pastebot最新啟用版AST
- 使用 JS 剪貼簿 APIJSAPI
- 剪貼簿與PythonPython
- 剪貼簿小工具
- esProc 利用剪貼簿強化 Excel 計算Excel
- JS複製內容到剪貼簿(相容FF/Chrome/Safari所有瀏覽器)JSChrome瀏覽器
- 實現網路螞蟻的實時監視剪貼簿功能 (轉)
- Paste:您的Mac剪貼簿管家ASTMac
- RobotGo v0.45.0 釋出, 增加程式管理和剪貼簿OTGGo
- 原生JS實現貼上到剪貼簿JS
- win10剪貼簿在哪裡_win10剪貼簿怎麼開啟Win10
- 【Qt 6】讀寫剪貼簿QT
- 剪貼簿操作 Clipboard API 教程API
- Salesforce LWC學習(二十八) 複製內容到系統剪貼簿(clipboard)Salesforce
- 剪貼簿複製貼上操作彙總
- rdesktop共享剪貼簿的問題
- 剪貼簿中的觀察者(Observer)模式Server模式
- 常用的剪貼簿管理工具CopyQ、ClipboardFusion、ClipAngel、Ditto和ClipDiary,它們提供了更強大的剪貼簿功能,允許使用者儲存、管理和快速訪問歷史剪貼簿內容。下面分別介紹這些工具及其相關的命令引數。
- ClipboardAction for mac剪貼簿管理器Mac
- PasteNow for mac(剪貼簿工具)中文ASTMac
- ClipboardManager for mac(剪貼簿管理器)Mac
- 讓vim支援系統剪貼簿
- VB.NET中監視資料夾的變化 (轉)
- 剪貼簿大觀園(三): Clipboard 問答集 (轉)
- 在RxRichEdit中插入圖片的完美解決方法(不使用剪貼簿) (轉)
- Linux下Java剪貼簿的訪問LinuxJava
- Paste:Mac剪貼簿歷史的魔法師ASTMac
- iPaste:剪貼簿界的一股清流AST
- ClipboardManager for mac(智慧剪貼簿管理器)Mac
- PhotosCollage for Mac(照片剪貼簿製作工具)Mac