zoukankan      html  css  js  c++  java
  • 第12章 剪贴板_12.3 实现一个剪贴板查看器

     12.3.1 剪贴板查看器链

    (1)Windows下可运行任意个剪贴板查看器,但只有一个是“当前剪贴板查看器”,Windows只维护这个剪贴板查看器的窗口句柄,并在剪贴板内容改变时,通知它。

    (2)当A程序注册为剪贴板查看器时,就成为当前查看器。Windows会把上个当前查看器B的窗口句柄交给A程序来保存。当A收到剪贴板消息时,要发送给查看器链中的下一个程序,即B的窗口过程。

    12.3.2 剪贴板查看器函数和消息

    (1)将程序加入剪贴板查看器链

     static HWND hwndNextViewer;

     case WM_CREATE:

    hwndNextViewer =SetClipboardViewer(hwnd);//hwndNextViewer得保存下来,这是

                                            //剪贴板消息的下一个接收者。

     (2)WM_DRAWCLIPBOARD消息

         ①剪贴板内板改变时,会发送这消息给当前查看器(最新注册的那个)。

         ②剪贴板查看器链中的每个程序都应通用SendMessage把消息传给下一个查看器

    (hwndNextViewer),直到hwndNextViewer为NULL。

    ③不要把WM_DRAWCLIPBOARD与WM_PAINTCLIPBOARD混为一谈

     消息

    消息发起者

    WM_DRAWCLIPBOARD

    Windows自动发送的,通知查看器剪贴板内容发生了变化。

    WM_PAINTCLIPBOARD

    查看器(即手动发送的),发给使用CF_OWNERDISP格式的程序

    ④WM_DRAWCLIPBOARD消息的处理

        case WM_DRAWCLIPBOARD:

           if(hwndNextViewer)SendMessage(hwndNextViewer,message,wParam,lParam);

           InvalidateRect(hwnd,NULL,TRUE);

           return 0;

    (3)退出剪贴板查看器链:ChangeClipboardChain(hwnd,hwndNextViewer);

      ①当某个程序退出查看器链时,Windows会向当前查看器发送WM_CHANGECBCHAIN消息。

    case WM_CHANGECBCHAIN:  //wParam:要退出链的窗口句柄。lParam:它的下个剪贴板查看器
         if((HWND)wParam == hwndNextViewer) //要退出的窗口w是不是我的下个查看器消息接收者?
              hwndNextViewer =(HWND)lParam; //如果是,将A的消息接收者(lParam)转到我的接收者。
         else if(hwndNextViewer)   //如果要退出的不是我的下个接收者,将退出消息转发下去。
            SendMessage(hwndNextViewer,message,wParam,lParam);
    
         return 0;

      ②程序终止时,必须从查看器链退出中。

       case WM_DESTROY:

            ChangeClipboardChain(hwnd,hwndNextViewer);

            PostQuitMessage(0);

    (4)获得第一个剪贴板查看器(即当前查看器)的窗口句柄:hwndViewer= GetClipboardViewer();

    12.3.3 一个简单的剪贴板查看器

      ①可实时感知剪贴板内容发生变化(eg.迅雷的下载地址监测)

      ②本程序只监测CF_TEXT的变化。

    【ClipView程序】
    效果图

    /*------------------------------------------------------------
    CLIPVIEW.C -- Simple Clipboard Viewer
    (c) Charles Petzold, 1998
    ------------------------------------------------------------*/
    #include <windows.h>
    LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                       PSTR szCmdLine, int iCmdShow)
    {
        static TCHAR szAppName[] = TEXT("ClipView");
        HWND         hwnd;
        MSG          msg;
        WNDCLASS     wndclass;
        wndclass.style = CS_HREDRAW | CS_VREDRAW;
        wndclass.lpfnWndProc = WndProc;
        wndclass.cbClsExtra = 0;
        wndclass.cbWndExtra = 0;
        wndclass.hInstance = hInstance;
        wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
        wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
        wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
        wndclass.lpszMenuName = NULL;
        wndclass.lpszClassName = szAppName;
        if (!RegisterClass(&wndclass))
        {
            MessageBox(NULL, TEXT("This program requires Windows NT!"),
                       szAppName, MB_ICONERROR);
            return 0;
        }
    
        hwnd = CreateWindow(szAppName,                  // window class name
                            TEXT("Simple Clipboard Viewer(Text Only)"), // window caption
                            WS_OVERLAPPEDWINDOW,        // window style
                            CW_USEDEFAULT,              // initial x position
                            CW_USEDEFAULT,              // initial y position
                            CW_USEDEFAULT,              // initial x size
                            CW_USEDEFAULT,              // initial y size
                            NULL,                       // parent window handle
                            NULL,                       // window menu handle
                            hInstance,                  // program instance handle
                            NULL);                     // creation parameters
    
        ShowWindow(hwnd, iCmdShow);
        UpdateWindow(hwnd);
    
        while (GetMessage(&msg, NULL, 0, 0))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
        return msg.wParam;
    }
    LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
        HDC         hdc;
        PAINTSTRUCT ps;
        RECT        rect;
        static HWND hwndNextViewer;
        HGLOBAL     hGlobal;
        PTSTR       pGlobal;
        switch (message)
        {
        case WM_CREATE:
            //加入剪贴板查看器链
            hwndNextViewer = SetClipboardViewer(hwnd);
            return 0;
        case WM_CHANGECBCHAIN: //当有程序退出剪贴板查看器链时
            //wParam:要退出查看器链的窗口句柄,lParam:它的下一个消息接收者。
            if ((HWND)wParam == hwndNextViewer) //退出窗口是我的下个消息接收者?
            {
                hwndNextViewer = (HWND)lParam; //如果是,将该窗的下个消息接收者(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);
    #ifdef UNICODE
            hGlobal = GetClipboardData(CF_UNICODETEXT);
    #else 
            hGlobal = GetClipboardData(CF_TEXT);
    #endif
            if (hGlobal != NULL)
            {
                pGlobal = GlobalLock(hGlobal);
                DrawText(hdc, pGlobal, -1, &rect,
                         DT_EXPANDTABS);
                GlobalUnlock(hGlobal);
            }
    
            CloseClipboard();
    
            EndPaint(hwnd, &ps);
            return 0;
    
        case WM_DESTROY:
            //退出剪贴板查看器链
            ChangeClipboardChain(hwnd, hwndNextViewer);
            PostQuitMessage(0);
            return 0;
        }
        return DefWindowProc(hwnd, message, wParam, lParam);
    }
  • 相关阅读:
    网络测量中基于Sketch方法的简单介绍
    Reading SBAR SDN flow-Based monitoring and Application Recognition
    Reading Meticulous Measurement of Control Packets in SDN
    Reading SketchVisor Robust Network Measurement for Sofeware Packet Processing
    ovs加dpdk在日志中查看更多运行细节的方法
    后缀数组
    (转载)LCA问题的Tarjan算法
    Codeforces Intel Code Challenge Final Round (Div. 1 + Div. 2, Combined) A. Checking the Calendar(水题)
    Vijos 1816统计数字(计数排序)
    卡特兰数
  • 原文地址:https://www.cnblogs.com/5iedu/p/4695148.html
Copyright © 2011-2022 走看看