剪贴板(下)-剪贴板查看器

本文介绍了一个简单的剪贴板查看器实现方法,通过Windows API函数SetClipboardViewer和ChangeClipboardChain加入及退出剪贴板查看器链,并处理WM_CHANGECBCHAIN和WM_DRAWCLIPBOARD消息来响应剪贴板内容的变化。
//要成为剪贴板查看器必须做到以下几点
//1.调用SetClipboardViewer,把自己加入到剪贴板查看器链
//在这一步中, 要保存在这条链中,紧跟自己后面的剪贴板查看器的窗口句柄
//2.加入了剪贴板查看器链,在适当时候就必须退出这个链.
//所以,在程序退出时,调用ChangeClipboardChain把自己从剪贴板查看器链移除
//3.处理由于其他剪贴板查看器的上述操作引起的消息 WM_CHANGECBCHAIN
//4.处理WM_DRAWCLIPBOARD, 真正地查看剪贴板,即把剪贴板的内容显示出来
//这当然就要对不同的数据类型(例如文字类型和图片类型的数据)采取不同的方法显示
//我这个例子就只简单地处理文字类型的数据, 所以比较简单


#include 
<windows.h>

//过程函数的返回值都是LRESULT,类型都是CALLBACK
LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam);
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPTSTR lpszCmdLine,int nCmdShow)
{
    HWND hwnd;        
//主窗口句柄,在CreateWindow中赋值
    MSG msg;        //消息变量,在GetMessage中使用
    WNDCLASS wndclass;        //窗口类
    TCHAR* szAppName = TEXT("CBViewer");    //类名和窗口名
    wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);    //窗口背景
    wndclass.hCursor = LoadCursor(NULL,IDC_ARROW);        //鼠标
    wndclass.hIcon = LoadIcon(NULL,IDI_APPLICATION);    //图标
    wndclass.lpszClassName = szAppName;        //类名
    wndclass.cbClsExtra = 0;        //类的额外参数
    wndclass.cbWndExtra = 0;        //窗口的额外参数.用于基于同一窗口类的窗口各自区分.
                                    
//在自定义对话框类时必须指定为DLGWINDOWEXTRA的大小
    wndclass.lpszMenuName = NULL;    //菜单名.可以用作子窗口的id
    wndclass.style = CS_HREDRAW | CS_VREDRAW;    //窗口风格
    wndclass.lpfnWndProc = WndProc;        //窗口过程
    wndclass.hInstance = hInstance;        //包含窗口过程的实例句柄

    
if!RegisterClass(&wndclass) )        //注册窗口类
        return 0;
    hwnd 
= CreateWindow(                //创建窗口
                szAppName,                //窗口类名
                szAppName,                //窗口标题
                WS_OVERLAPPEDWINDOW,    //窗口风格
                CW_USEDEFAULT,            //初始的x坐标
                CW_USEDEFAULT,            //初始的y坐标
                CW_USEDEFAULT,            //初始的宽度
                CW_USEDEFAULT,            //初始的高度
                NULL,                    //父窗口
                NULL,                    //菜单
                hInstance,                //和窗口相关的实例句柄
                NULL                    //额外参数
                );
    ShowWindow( hwnd,nCmdShow );        
//显示窗口
    UpdateWindow( hwnd );                //更新窗口
    while( GetMessage(&msg,NULL,0,0) )    //消息循环
    {
        TranslateMessage(
&msg);            //将WM_XXXKEYXXX消息翻译为WM_CHAR消息
        DispatchMessage(&msg);            //传递消息到窗口过程
    }    
    
return msg.wParam;                    //返回
}
LRESULT WINAPI WndProc( HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam )
{
    
static HWND hwndNextViewer;    //剪贴板查看器链的下一个窗口
    switch( message )
    {
    
case WM_CREATE:
        {
            hwndNextViewer 
= SetClipboardViewer(hwnd);
            
return 0;
        }
    
case WM_CHANGECBCHAIN:
        
if( hwndNextViewer == (HWND)wParam )
        {
            hwndNextViewer 
= (HWND)lParam;
        }
        
else if( hwndNextViewer != NULL )
        {
            SendMessage(hwndNextViewer, message, wParam, lParam );
        }
        
return 0;
    
case WM_DRAWCLIPBOARD:
        {
            
if( hwndNextViewer != NULL )
            {
                SendMessage(hwndNextViewer, message, wParam, lParam);
            }
            InvalidateRect(hwnd, NULL, TRUE);
            
return 0;
        }
    
case WM_PAINT:
        {
            HDC hdc;
            PAINTSTRUCT ps;
            HGLOBAL hglobal; 
            
char* pText;
            RECT rc;
            OpenClipboard(hwnd);
            hdc 
= BeginPaint(hwnd, &ps);
            hglobal 
= GetClipboardData(CF_TEXT);
            
if(hglobal != NULL)
            {
                pText 
= (char*)GlobalLock(hglobal);                
                GetClientRect(hwnd, 
&rc);
                DrawText(hdc, pText, 
-1&rc, DT_CENTER);
                GlobalUnlock(hglobal);
                
            }
            CloseClipboard();
            EndPaint(hwnd, 
&ps);
            
return 0;
        }
    
case WM_DESTROY:
        ChangeClipboardChain(hwnd, hwndNextViewer);
        PostQuitMessage(
0);
        
return 0;
    }
    
return DefWindowProc( hwnd,message,wParam,lParam );
}
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值