• 第12章 剪贴板_12.1 剪贴板的简单用法


    12.1 剪贴板的简单用法

    12.1.1 剪贴板的标准格式

    分类

    标准格式

    说明

    文本格式

    CF_TEXT

    以NULL结尾的ANSI字符集,每行结尾含有回车换行符,最后的NULL表示整个数据的结束。

    CF_OEMTEXT

    以NULL结尾的OEM字符集,供MS-DOS下的剪贴板使用

    CF_UNICODETEXT

    类似CF_TEXT,每行以回车换行结束,字符两个NULL标志着整个数据的结束。

    CF_SYLK

    含有微软件符号链接(Symbolic Link)格式数据的内存块。用与Excel程序交换,是一种ASCII格式,每行以回车换行符结束,但不一定以NULL结尾,现在很少用到。

    位图相关

    CF_BITMAP

    设备相关位图

    CF_DIB

    设备无关位图的内存块(以位图信息结构开头,接着有可能是颜色表和位图的位)

    CF_PALETTE

    指向调色板的句柄,通常与CF_DIB一起使用

    CF_TIFF

    标签图像文件格式的内存块

    图元

    文件

    格式

    CF_METAFILEPICT

    基于Windows过去支持的图元文件

    CF_ENHMETAFILE

    指向32位Windows版本支持的增强型图元文件

    其他

    格式

    CF_PENDATA

    和Windows画笔扩展一起使用

    CF_WAVE

    声音波形文件

    CF_RIFF

    资源交换文件格式的多媒体数据

    CF_HDROP

    和拖放服务一起使用的文件列表

    12.1.2 内存分配——GlobalAlloc(uiFlags,dwSize)

    (1)全局内存块的创建(用GlobalAlloc,而不能用malloc)

    ①固定内存块:hGlobal = GlobalAlloc(GMEM_FIXED|GMEM_ZEROPOINT,dwSize);

    A、返回值:指向全局内存块的句柄(全局句柄),Fixed时,实际上也是内存块的指针。

    B 、GPTR标志:#define GPTR  (GMEM_FIXED | GMEM_ZEROPOINT)

    C 、GMEM_FIXED标志指明了该内存块的虚拟地址不可更改(但Windows会通过改变页表移动物理内存的内存块)。

    ②可移动内存块:hGlobal = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROPOINT,dwSize);

    A、返回值:返回全局句柄,但不是该内存块的指针。(因为Windows可能会移动虚拟地址),其指针的获取方法:

     int* pGlobal;

     GLOBALHANDLE hGlobal;

     hGlobal = GlobalAlloc(GHND,1024);

     pGlobal =(int*) GlobalLock(hGlobal); //锁定内存块以获取指针(防虚址被改变)。

       ……

     GlobalUnlock(hGlobal);//解锁内存块,Windows又可以自由移动该内存块了

    B、GHND标志:#define GHND (GMEM_MOVEABLE| GMEM_ZEROPOINT)

    C、GMEM_MOVEABLED标志Windows能在虚拟内存中移动内存块(不并移动物理内存)

     (2)其它标准内存管理函数

    内存重分配函数

    hGlobal = GlobalReAlloc(hGlobal,dwSize,uiFlags);

    获取内存块大小

    dwSize = GlobalSize(hGlobal);

    获取内存块句柄

    hGlobal = GlobalHandle(p); //p为指向内存块的地址(指可移动内存块)

    释放内存函数

    GlobalFree(hGlobal);

    (3)为什么要用全局句柄,而不直接用指针?(点这里的链接

    12.1.3 把文本传到剪贴板——以ANSI字符串传到剪贴板例

    //1、分配全局内存块(可移动、可供其他应该程序共享)
    hGlobal = GlobalAlloc(GHND|GMEM_SHARE,iLength+1); //GMEM_SHARE表示内存块能被其他程序共享
    
    //2、将字符串复制到全局内存块
    pGlobal = GlobalLock(hGlobal); //锁定内存,获取指针
    
    for(int i=0;i<wLength,i++)   //复制字符串,不需要加NULL,因为GMEM_ZEROPOINT了。
       *pGlobal++ = *pString++;
    
    GlobalUnlock(hGlobal);       //解锁内存块
    //3、将内存块传入剪贴板 OpenClipboard(hwnd); //打开剪贴板并清空。注意:Open和Close要在同一消息里进行。 EmptyClipboard(); hData =SetClipboardData(CF_TEXT,hGlobal);//将内存句柄传给剪贴板。(hGlobal一定会先被解锁) …… //1、这时不能再通过hGlobal使用这块内存了, 因为hGlobal …… // 这句柄是程序本身的。但该内存块己属剪贴板,而不属于本程 // 序了。这里应当把hGlobal当作是无效的。 //2、如果需要继续使用数据,应再复制一份或从剪贴板中读取。 //3、从剪贴板读取的方法:SetClipboardData返回的是全 // 指向剪贴板中那块内存的全局句柄hData,可利用这个句柄 // (而不是传入该函数的句柄hGlobal)。然后锁定内存,再通过 // 获取指针来访问剪贴板。最后解锁hData句柄。 CloseClipboard(); //关闭剪贴板

     12.1.4 从剪贴板取得文本

    //1、确定剪贴板是否包含CF_TEXT格式的文本
    bAvailable = IsClipboardFormatAvailable(CF_TEXT); //不需要打开剪贴板
    
    //2、将文本传出
    OpenClipboard(hwnd);              //打开剪贴板得,得传入窗口句柄。
    
    hGlobal = GetClipboardData(CF_TEXT);//如果hGlobal为NULL,表示没有文本,再次确认文本是否存在。
                                        //注意,这里的句柄不属于程序,而是属于剪贴板,该句柄只在
                                        //GetClipboardData和CloseClipboard之间有效。
    pText = (char*)malloc(GlobalSize(hGlobal)));  //分配复制文本的缓冲区 
    
    pGlobal = GlobalLock(hGlobal);
    strcpy(pText,pGlobal);              //复制文本
    GlobalUnlock(hGlobal);
    
    CloseClipboard();                   //关闭剪贴板

    12.1.5 打开和关闭剪贴板

    ①无论何时,只有一个程序可以打开剪贴板。OpenClipboard(hwnd)打开剪贴板,使hWnd指向的窗口成为剪贴板的拥有者,一直持续到CloseClipboard()函数的调用后结束。在此期间,剪贴板为拥有者所独占,其他进程将无法对剪贴板内容进行修改。

    ②剪贴板的内容并不可靠,在用户复制后,调用粘贴之前的这段时间内其他程序修改了剪贴板的内容。

    ③由于GetClipboardData()获取的数据句柄是属于剪贴板的,因此用户程序必须在调用CloseClipboard()函数之前使用它。

    ④关闭剪贴板之前,不要弹出消息框或对话框——因为其他程序无法使用剪贴板。

    OpenClipboard(hwnd);
    ……              //1、这里不要弹出消息框,会使其他程序无法使用剪贴板。
    
                      //2、这里也不要使用对话框,因为对话框内的一些编辑控件可能需要
    
    //使用剪贴板来剪切或粘贴。
    CloseClipboard();

    12.1.6 剪贴板和Unicode

    (1)Unicode格式的用CF_UNICODETEXT

    (2)利用剪贴板在两个字符集之间进行文本格式的转换:将ANSI转为Unicode

           ①SetClipboardData时用CT_TEXT

           ②而GetClipboard用CT_UNICODETEXT

    【ClipText程序】
    效果图

     

    /*------------------------------------------------------------
    CLIPTEXT.C -- The Clipboard and Text
    (c) Charles Petzold, 1998
    ------------------------------------------------------------*/
    #include <windows.h>
    #include "resource.h"
    #ifdef UNICODE
    #define CF_TCHAR CF_UNICODETEXT
    TCHAR szDefaultText[] = TEXT("Default Text - Unicode Version");
    TCHAR szCaption[] = TEXT("Clipboard Text Transfers - Unicode Version");
    #else
    #define CF_TCHAR CF_TEXT
    TCHAR szDefaultText[] = TEXT("Default Text - ANSI Version");
    TCHAR szCaption[] = TEXT("Clipboard Text Transfers - ANSI Version");
    #endif // UNICODE
    LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                       PSTR szCmdLine, int iCmdShow)
    {
        static TCHAR szAppName[] = TEXT("ClipText");
        HWND         hwnd;
        MSG          msg;
        WNDCLASSEX     wndclass;
        HACCEL hAccel;
        wndclass.style = CS_HREDRAW | CS_VREDRAW;
        wndclass.cbSize = sizeof(WNDCLASSEX);
        wndclass.lpfnWndProc = WndProc;
        wndclass.cbClsExtra = 0;
        wndclass.cbWndExtra = 0;
        wndclass.hInstance = hInstance;
        wndclass.hIcon = LoadIcon(hInstance, szAppName);
        wndclass.hIconSm = LoadIcon(hInstance, szAppName);
        wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
        wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
        wndclass.lpszMenuName = szAppName;
        wndclass.lpszClassName = szAppName;
        if (!RegisterClassEx(&wndclass))
        {
            MessageBox(NULL, TEXT("This program requires Windows NT!"),
                       szAppName, MB_ICONERROR);
            return 0;
        }
    
        hwnd = CreateWindow(szAppName,                  // window class name
                            szCaption, // 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);
    
        hAccel = LoadAccelerators(hInstance, szAppName);
        while (GetMessage(&msg, NULL, 0, 0))
        {
            if (!TranslateAccelerator(hwnd, hAccel, &msg))
            {
                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 PTSTR pText;
        BOOL         bEnable;
        HGLOBAL      hGlobal;
        PTSTR        pGlobal;
        switch (message)
        {
        case WM_CREATE:
            SendMessage(hwnd, WM_COMMAND, IDM_EDIT_RESET, 0);
            return 0;
        case WM_INITMENUPOPUP:
            EnableMenuItem((HMENU)wParam, IDM_EDIT_PASTE, IsClipboardFormatAvailable(CF_TCHAR) ? MF_ENABLED : MF_GRAYED);
    
            bEnable = pText ? MF_ENABLED : MF_GRAYED;
            EnableMenuItem((HMENU)wParam, IDM_EDIT_CUT, bEnable);
            EnableMenuItem((HMENU)wParam, IDM_EDIT_COPY, bEnable);
            EnableMenuItem((HMENU)wParam, IDM_EDIT_DELETE, bEnable);
            break;
        case WM_COMMAND:
            switch (LOWORD(wParam))
            {
            case IDM_EDIT_PASTE:
                OpenClipboard(hwnd);
                hGlobal = GetClipboardData(CF_TCHAR);
                if (hGlobal != NULL)
                {
                    pGlobal = GlobalLock(hGlobal);  //锁定内存块,获取指针
                    if (pText)
                    {
                        free(pText);
                        pText = NULL;
                    }
                    pText = malloc(GlobalSize(hGlobal));
                    lstrcpy(pText, pGlobal);
                    GlobalUnlock(hGlobal);
                    InvalidateRect(hwnd, NULL, TRUE);
                }
                CloseClipboard();
                return 0;
            case IDM_EDIT_CUT:
            case IDM_EDIT_COPY:
                if (!pText)
                    return 0;
                //分配内存并拷贝数据到全局内存块里
                hGlobal = GlobalAlloc(GHND | GMEM_SHARE, (lstrlen(pText) + 1)*sizeof(TCHAR));
                pGlobal = GlobalLock(hGlobal);
                lstrcpy(pGlobal, pText);
                GlobalUnlock(hGlobal);
                //将内存块传入剪贴板
                OpenClipboard(hwnd);
                EmptyClipboard();
                SetClipboardData(CF_TCHAR, hGlobal);
                CloseClipboard();
                if (LOWORD(wParam) == IDM_EDIT_COPY)
                    return 0;
                //剪切时,继续向下执行。
            case IDM_EDIT_DELETE:
                if (pText)
                {
                    free(pText);
                    pText = NULL;
                }
                InvalidateRect(hwnd, NULL, TRUE);
                return 0;
            case IDM_EDIT_RESET:
                if (pText)
                {
                    free(pText);
                    pText = NULL;
                }
                pText = (PTSTR)malloc((lstrlen(szDefaultText) + 1)*sizeof(TCHAR));
                lstrcpy(pText, szDefaultText);
                InvalidateRect(hwnd, NULL, TRUE);
                return 0;
            }
            break;
        case WM_PAINT:
            hdc = BeginPaint(hwnd, &ps);
    
            GetClientRect(hwnd, &rect);
    
            DrawText(hdc, pText, -1, &rect, DT_EXPANDTABS | DT_WORDBREAK);
    
            EndPaint(hwnd, &ps);
            return 0;
    
        case WM_DESTROY:
            PostQuitMessage(0);
            return 0;
        }
        return DefWindowProc(hwnd, message, wParam, lParam);
    }

    //resource.h

    //{{NO_DEPENDENCIES}}
    // Microsoft Visual C++ 生成的包含文件。
    // 供 ClipText.rc 使用
    //
    #define IDM_EDIT_CUT                    40001
    #define IDM_EDIT_COPY                   40002
    #define IDM_EDIT_PASTE                  40003
    #define IDM_EDIT_DELETE                 40004
    #define IDM_EDIT_RESET                  40005
    // Next default values for new objects
    // 
    #ifdef APSTUDIO_INVOKED
    #ifndef APSTUDIO_READONLY_SYMBOLS
    #define _APS_NEXT_RESOURCE_VALUE        103
    #define _APS_NEXT_COMMAND_VALUE         40012
    #define _APS_NEXT_CONTROL_VALUE         1001
    #define _APS_NEXT_SYMED_VALUE           101
    #endif
    #endif

    //ClipText.rc

    // Microsoft Visual C++ generated resource script.
    //
    #include "resource.h"
    #define APSTUDIO_READONLY_SYMBOLS
    /////////////////////////////////////////////////////////////////////////////
    //
    // Generated from the TEXTINCLUDE 2 resource.
    //
    #include "winres.h"
    /////////////////////////////////////////////////////////////////////////////
    #undef APSTUDIO_READONLY_SYMBOLS
    /////////////////////////////////////////////////////////////////////////////
    // 中文(简体,中国) resources
    #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS)
    LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED
    #ifdef APSTUDIO_INVOKED
    /////////////////////////////////////////////////////////////////////////////
    //
    // TEXTINCLUDE
    //
    1 TEXTINCLUDE
    BEGIN
    "resource.h"
    END
    2 TEXTINCLUDE
    BEGIN
    "#include ""winres.h""
    "
    ""
    END
    3 TEXTINCLUDE
    BEGIN
    "
    "
    ""
    END
    #endif    // APSTUDIO_INVOKED
    /////////////////////////////////////////////////////////////////////////////
    //
    // Menu
    //
    CLIPTEXT MENU
    BEGIN
    POPUP "&Edit"
    BEGIN
    MENUITEM "Cu&t	Ctrl+X", IDM_EDIT_CUT
    MENUITEM "&Copy	 Ctrl+C", IDM_EDIT_COPY
    MENUITEM "&Paste	Ctrl+V", IDM_EDIT_PASTE
    MENUITEM "&Delete	Del", IDM_EDIT_DELETE
    MENUITEM SEPARATOR
    MENUITEM "&Reset", IDM_EDIT_RESET
    END
    END
    /////////////////////////////////////////////////////////////////////////////
    //
    // Accelerator
    //
    ClipText ACCELERATORS
    BEGIN
    "^C", IDM_EDIT_COPY, ASCII, NOINVERT
    "^X", IDM_EDIT_CUT, ASCII, NOINVERT
    "^V", IDM_EDIT_PASTE, ASCII, NOINVERT
    VK_DELETE, IDM_EDIT_DELETE, VIRTKEY, NOINVERT
    END
    #endif    // 中文(简体,中国) resources
    /////////////////////////////////////////////////////////////////////////////
    #ifndef APSTUDIO_INVOKED
    /////////////////////////////////////////////////////////////////////////////
    //
    // Generated from the TEXTINCLUDE 3 resource.
    //
    /////////////////////////////////////////////////////////////////////////////
    #endif    // not APSTUDIO_INVOKED
  • 相关阅读:
    谷歌Google Chrome浏览器打开新的标签页设置指定固定网址
    Vue子组件和父组件、子组件调用父组件的方法、父组件调用子组件方法、子组件与父组件间的传值
    查询Linux服务器出口IP、curl命令查询Linux公网出口IP、Windows服务器查询出口IP
    mysql查询是对字段进行补0操作,可用于树状结构整体排序
    mysql批量update更新,mybatis中批量更新操作
    CentOS 6.8下网卡配置、桥接模式和NAT连接模式、VMware虚拟机克隆网卡配置
    杂七杂八
    解决SpringMVC拦截器中Request数据只能读取一次的问题
    Redis安装教程及可视化工具RedisDesktopManager下载安装
    JAVA获取客户端请求的当前网络ip地址(附:Nginx反向代理后获取客户端请求的真实IP)
  • 原文地址:https://www.cnblogs.com/5iedu/p/4695110.html
Copyright © 2020-2023  润新知