Clipboard viewers don't have to be as sophisticated as CLIPBRD.EXE. A clipboard viewer can, for instance, display only one clipboard format. The CLIPVIEW program, shown in Figure 16-2, is a clipboard viewer that displays only the CF_TEXT format.
CLIPVIEW.MAK
#------------------------
# CLIPVIEW.MAK make file
#------------------------
clipview.exe : clipview.obj clipview.def
link clipview, /align:16, NUL, /nod slibcew libw, clipview
rc clipview.exe
clipview.obj : clipview.c
cl -c -Gsw -Ow -W2 -Zp clipview.c
CLIPVIEW.C
/*-----------------------------------------
CLIPVIEW.C -- Simple Clipboard Viewer
(c) Charles Petzold, 1990
-----------------------------------------*/
#include <windows.h>
long FAR PASCAL WndProc (HWND, WORD, WORD, LONG) ;
int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance,
LPSTR lpszCmdLine, int nCmdShow)
{
static char szAppName [] = "ClipView" ;
HWND hwnd ;
MSG msg ;
WNDCLASS wndclass ;
if (!hPrevInstance)
{
wndclass.style = CS_HREDRAW | CS_VREDRAW ;
wndclass.lpfnWndProc = WndProc ;
wndclass.cbClsExtra = 0 ;
wndclass.cbWndExtra = 0 ;
wndclass.hInstance = hInstance ;
wndclass.hIcon = NULL ;
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;
wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ;
wndclass.lpszMenuName = NULL ;
wndclass.lpszClassName = szAppName ;
RegisterClass (&wndclass) ;
}
hwnd = CreateWindow (szAppName, "Simple Clipboard Viewer (Text Only)",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInstance, NULL) ;
ShowWindow (hwnd, nCmdShow) ;
UpdateWindow (hwnd) ;
while (GetMessage (&msg, NULL, 0, 0))
{
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
return msg.wParam ;
}
long FAR PASCAL WndProc (HWND hwnd, WORD message, WORD wParam, LONG lParam)
{
static HWND hwndNextViewer ;
HANDLE hGMem ;
HDC hdc ;
LPSTR lpGMem ;
PAINTSTRUCT ps ;
RECT rect ;
switch (message)
{
case WM_CREATE :
hwndNextViewer = SetClipboardViewer (hwnd) ;
return 0 ;
case WM_CHANGECBCHAIN :
if (wParam == hwndNextViewer)
hwndNextViewer = LOWORD (lParam) ;
else if (hwndNextViewer)
SendMessage (hwndNextViewer, message, wParam, lParam) ;
return 0 ;
case WM_DRAWCLIPBOARD :
if (hwndNextViewer)
SendMessage (hwndNextViewer, message, wParam, lParam) ;
InvalidateRect (hwnd, NULL, TRUE) ;
return 0 ;
case WM_PAINT :
hdc = BeginPaint (hwnd, &ps) ;
GetClientRect (hwnd, &rect) ;
OpenClipboard (hwnd) ;
if (hGMem = GetClipboardData (CF_TEXT))
{
lpGMem = GlobalLock (hGMem) ;
DrawText (hdc, lpGMem, -1, &rect, DT_EXPANDTABS) ;
GlobalUnlock (hGMem) ;
}
CloseClipboard () ;
EndPaint (hwnd, &ps) ;
return 0 ;
case WM_DESTROY :
ChangeClipboardChain (hwnd, hwndNextViewer) ;
PostQuitMessage (0) ;
return 0 ;
}
return DefWindowProc (hwnd, message, wParam, lParam) ;
}
CLIPVIEW.DEF
;-------------------------------------
; CLIPVIEW.DEF module definition file
;-------------------------------------
NAME CLIPVIEW
DESCRIPTION 'Simple Clipboard Viewer (c) Charles Petzold, 1990'
EXETYPE WINDOWS
STUB 'WINSTUB.EXE'
CODE PRELOAD MOVEABLE DISCARDABLE
DATA PRELOAD MOVEABLE MULTIPLE
HEAPSIZE 1024
STACKSIZE 8192
EXPORTS WndProc
CLIPVIEW processes WM_CREATE, WM_CHANGECBCHAIN, WM_DRAWCLIPBOARD, and WM_DESTROY messages as discussed above. The WM_PAINT message simply opens the clipboard and uses GetClipboardData with a format of CF_TEXT. If the function returns a global memory handle, CLIPVIEW locks it and uses DrawText to display the text in its client area.
A clipboard viewer that handles data formats beyond the five standard formats (as CLIPBRD.EXE does) has additional work to do, such as displaying the names of all the formats currently in the clipboard. You can do this by calling EnumClipboardFormats and obtaining the names of the nonstandard formats from GetClipboardFormatName. A clipboard viewer that uses the CF_OWNERDISPLAY format must send these four messages to the clipboard to display the data:
WM_PAINTCLIPBOARD | WM_VSCROLLCLIPBOARD |
WM_SIZECLIPBOARD | WM_HSCROLLCLIPBOARD |
If you want to write such a clipboard viewer, you have to obtain the window handle of the clipboard owner using GetClipboardOwner and send that window these messages when you need to update the clipboard viewer's client area.