Monitor the changes and content of the clipboard in the application
Stove@vip.sina.com
The clipboard is a system-level heap space in Windows. Any application in the system has access to the clipboard, and can read the clipboard content by clipboard messages and using the clipboard API. Therefore, the use of the clipboard can not only interact data in the same application, but also interact between unread applications. Especially when interacting between applications, applications often need to make real-time perception of changes in the contents of the clipboard, that is, the application must monitor changes in the contents of the clipboard.
Windows applications are messaging. Similarly when the clipboard content changes, Windows provides a clipboard change message, so you want to sense changes in the contents of the clipboard in real time. The key is that the application must respond and process the Windows triggering clipboard change message. .
The first step is to register the window as Clipboard Viewer
Need to explain two concepts first: Clipboard Viewer and Clipboard Viewer Chain.
Clipboard Viewer is a window that needs to get and display the contents of the clipboard. By the CLIPBOARD Viewer mechanism, the application can obtain changes in the clipboard without affecting the contents of the clipboard. Clipboard Viewer displays the clipboard content of the system-defined standard format, or you can display the contents of the custom private data format. The window is registered as Clipboard Viewer by calling a function setClipboardViewer.
Clipboard Viewer Chain is a Windows System Link list that saves the CLIPBOARD Viewer window and the front and rear relationship between them. When a window is registered as a Clipboard Viewer, he will be added to the Clipboard Viewer Chain and get the handle of the next Viewer window in the list. The handle must be saved to use when responding to the message, the function of the handle is described below. Windows is whose Clipboard Viewer can receive and respond to clipboard change messages through Clipboard Viewer Chain.
Step 2, respond to the change of the clipboard change message, determine and remove the clipboard content
Two messages must be handled correctly in the message response: WM_DrawClipboard and WM_Changecbchain.
When the content of the clipboard changes, Windows will trigger the WM_DRAWCLIPBOARD message and give the message to the first window of the Clipboard Viewer Chain. Each CLIPBOARD viewer window, including the first window, after a response and processing, the message must be sent to the next CLIPBOARD Viewer window according to the handle of the next window in its saved linked list. The window can take the clipboard content in this message and determine whether the window is incremented by the monitor, if it is performed.
When a CLIPBoard Viewer window is logged out, the system will trigger WM_CHANGECBCHAIN and give the message to the first window of the Clipboard Viewer Chain. Each window must handle the message.
In the third step, log out the window from the Clipboard Viewer Chain
When the window no longer needs to monitor the clipboard change message, or when the window is to be turned off, you must call the ChangeClipboardChain function to log out the window from the Clipboard Viewer Chain. After the logout, the system will trigger the WM_CHANGECBCHAIN message, just like the WM_DRAWCLIPBOARD message, the message is sent to the first window of the Clipboard Viewer Chain. The following code example is logged out when the window is turned off.
The following code snippet gives an example of whether or not to copy the URL address in the monitor clipboard. If the content in the clipboard is the URL address, it is displayed on the window interface. In order to make the sample code have a generality, the general Windows program code and the MFC-based generation-based code are given below. Other languages To implement this feature, you can refer to the Windows program code. The completion code of the two demo is invited to see attachment. Windows program sample code
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:
// Register this window to Clipboard Viewer Chain,
/ / Save the handle of the next window in the Clipboard Viewer Chain in CLIPBOARD Viewer Chain
HWndNextViewer = setClipboardViewer (hwnd);
Break;
Case WM_CHANGECBCHAIN: // Clipboard Viewer logout
// If the cancellation of the Clipboard Viewer window is the next window of this window,
// modify the next window handle saved in this window.
/ / Otherwise, pass the message to the next window of Clipboard Viewer Chain
IF ((hwnd) wparam == hwndNextViewer)
HWndNextViewer = (hwnd) lparam;
Else if (HWndNextViewer! = null)
SendMessage (HWndNextViewer, Message, WPARAM, LPARAM);
Break;
Case WM_DrawClipboard: // Clipboard content change
// Trigger on_paint to display URL content
InvalidateRect (HWND, NULL, TRUE);
UpdateWindow (HWND);
/ / Otherwise, pass the message to the next window of Clipboard Viewer Chain
SendMessage (HWndNextViewer, Message, WPARAM, LPARAM);
Break;
Case WM_DESTROY:
// Log out this window from Clipboard Viewer Chain
Changeclipboardchain (hwnd, hwndnextview);
PostquitMessage (0);
Break;
/ / -------------------------------------------------------------------------------------------- ----------------
Case WM_COMMAND:
WMID = loword (wparam);
WMEVENT = HiWord (WPARAM);
// Parse the menu Select:
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); / / Determine if the content in the clipboard is a URL address, if it is displayed
NFORMAT = getPriorityClipboardFormat (anformats, sizeof (anformats));
IF (nformat == cf_text)
{
Openclipboard (hwnd);
Hglobal HMEM = getClipboardData (NFORMAT);
LPTSTR LPSTR = (LPTSTR) Globalock (HMEM);
IF (strstr (lpstr, "http: //")! = NULL ||
Strstr (LPSTR, "ftp: //")! = 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 program sample code
First, you want to map the following messages and inherit the following functions.
AFX_MSG Void Onchangecbchain (HWND HWNDREMOVE, HWND HWNDAFTER);
AFX_MSG Void OnDrawClipboard ();
AFX_MSG void onDestroy ();
Virtual void onInitialupdate ();
Void cmonitorURLVIEW :: OnIitialupdate ()
{
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);
// Register this window to Clipboard Viewer Chain,
/ / Save the handle of the next window in the Clipboard Viewer Chain in CLIPBOARD Viewer Chain
m_hwndnextviewer = setClipboardViewer ();
}
Void cmonitorURLVIEW :: ONDESTROY ()
{
Clistview :: ONDESTROY ();
// Log out this window from Clipboard Viewer Chain
Changeclipboardchain (M_HWndNextViewer);
}
// Clipboard Viewer logout
Void cmonitorurlview :: onchangecbchain (hwnd hwndremove, hwnd hwndafter)
{
// If the cancellation of the Clipboard Viewer window is the next window of this window,
// modify the next window handle saved in this window.
CView :: OnChangecbchain (HWndremove);
IF (hwndremove == m_hWndnextViewer) m_hwndnextviewer = hwndAfter;
}
// The content change of the clipboard, determines whether the content in the clipboard is the URL address, if it is displayed
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))
{
LPTSTR LPSZTEXT = (LPTSTR) GlobalLock (HMEM);
CSTRING STRURL = LPSZTEXT;
Strurl = Strurl.spanexCluding ("/ r / n");
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 ();
}
}