第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\0"
END
2 TEXTINCLUDE
BEGIN
"#include ""winres.h""\r\n"
"\0"
END
3 TEXTINCLUDE
BEGIN
"\r\n"
"\0"
END
#endif    // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Menu
//
CLIPTEXT MENU
BEGIN
POPUP "&Edit"
BEGIN
MENUITEM "Cu&t\tCtrl+X", IDM_EDIT_CUT
MENUITEM "&Copy\t Ctrl+C", IDM_EDIT_COPY
MENUITEM "&Paste\tCtrl+V", IDM_EDIT_PASTE
MENUITEM "&Delete\tDel", 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
时间: 2024-10-05 23:37:01

第12章 剪贴板_12.1 剪贴板的简单用法的相关文章

第12章 剪贴板_12.2 剪贴板的高级用法

12.2.1 使用多种数据项 (1)设置多种数据项 OpenClipboard(hwnd); EmptyClipboard(); //下面设置多种数据项,但这3种数据项必须不同,且在Empty和CloseClipboard间设置. //将文本字符串写到位图或图元文件中,这样字符串即可被文读文本的程序访问.也可 //被读位图的程序访问,但这些程序没办法轻易判断出位图中其实还含有字符串. SetClipboardData(CF_TEXT,hGlobalText); //每次,每个数据项只能是一种格式

第12章-Swing编程 --- 使用JToolBar创建工具条

Swing提供了JToolBar类来创建工具条,创建JToolBar对象时可以指定如下两个参数: -->name: 该参数指定该工具条的名称. -->orientation:该参数指定该工具条的方法. JToolBar对象还有如下几个常用方法: -->JButton add(Action a): 通过Action对象为JToolBar添加对应的工具按钮. -->void addSeparator(Dimension size):向工具条中添加指定大小的分隔符. -->void

公开课视频-《第11章 配置-Citrix-企业网盘-第12章 配置-UPM》

***************************************************************************************** <大企业云桌面部署实战>-培训班-即将开课,包学包会,欢迎咨询:3313395633(QQ) ***************************************************************************************** <大企业云桌面部署实战>-精讲课

JS读书笔记:《JavaScript框架设计》——第12章 异步处理

一.何为异步   执行任务的过程可以被分为发起和执行两个部分. 同步执行模式:任务发起后必须等待直到任务执行完成并返回结果后,才会执行下一个任务. 异步执行模式:任务发起后不等待任务执行完成,而是马上执行下一个任务,当任务执行完成时则会收到通知. 面对IO操作频繁的场景,异步执行模式可在同等的硬件资源条件下提供更大的并发处理能力,也就是更大的吞吐量. 但由于异步执行模式打破人们固有的思维方式,并且任务的发起和任务的执行是分离的,从而提高编程的复杂度. 多线程.多进程均可实现异步模式. 二.从回调

第 12 章 命令模式【Command Pattern】

以下内容出自:<<24种设计模式介绍与6大设计原则>> 今天讲命令模式,这个模式从名字上看就很简单,命令嘛,老大发命令,小兵执行就是了,确实是这个意思,但是更深化了,用模式来描述真是是世界的命令情况.正在看这本书的你,我猜测分为两类:已经工作的和没有工作的,先说没有工作的,那你为啥要看这本书,为了以后工作呗,只要你参见工作,你肯定会待在项目组,那今天我们就以项目组为例子来讲述命令模式. 我是我们部门的项目经理,就是一个项目的头,在中国做项目,项目经理就是什么都要懂,什么都要管,做好

《深入Java虚拟机学习笔记》- 第12章 整数运算

Java虚拟机提供几种进行整数算术运算的操作码,他们执行基于int和long类型的运算.当byte.short和char类型值参与算术运算时,首先会将它们转换为int类型.这些操作码都不会抛出异常,溢出在这里通常可以被忽略. 整数加法 操作码 操作数 说明 iadd (无) 从栈中弹出两个int类型数,相加,然后将所得int类型结果压回栈 ladd (无) 从栈中弹出两个long类型数,相加,然后将所得long类型结果压回栈 将一个常量与局部变量相加 操作码 操作数 说明 iinc vindex

ASM:《X86汇编语言-从实模式到保护模式》第12章:存储器的保护

12章其实是11章的拓展,代码基本不变,就是在保护模式下展开讨论. ★PART1:存储器的保护机制 1. 修改段寄存器的保护 当执行把段选择子传到段寄存器的选择器部分的时候,处理器固件在完成传送之前,要检查和确认选择子是正确的,并且该选择子选择的描述符也是正确的.假如索引号是正确的,也就是说明索引号8+7要小于等于边界.如果超过边界,那么处理器就会终止处理,产生异常中断13,同时段寄存器的原值保持不变. 同时处理器还要对描述符的类别进行检查,如果描述符的类别进行确认,举个例子来说,如果描述符的类

《构建之法》第10、11、12章

第10章问题:书上说一些好的功能还会有副作用,这里所说的副作用是指什么?是指功能没完善还是?(第十章10.2.1  P196第五) 第11章问题:开发阶段还有日常管理,这样不会浪费团队做项目的时间,做一个项目既要做Sprint计划,又要每日例会,还要规格说明书.功能说明书.列典型用户与典型场景                   描述等等,当这些完成后,确定还有时间弄项目吗?(第十一章11.2节) 第12章问题:用户体验和质量,有时候并不能同时做到很好,那么这两个当中那个要重要一点?要牺牲哪个取

c#发送数据到剪贴板及从剪贴板获取数据

我以winform为例,设计两个textbox控件,分别命名为:textbox1和textbox2,设计两个button控件,分别命名:为btn_send和btn_get. 代码如下: <span style="font-family:Microsoft YaHei;font-size:14px;"> private void btn_send_Click(object sender, EventArgs e) { try { Clipboard.SetText(textB