码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2015-08-02 10:06:12      阅读:201      评论:0      收藏:0      [点我收藏+]

标签:

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

 

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

标签:

原文地址:http://www.cnblogs.com/5iedu/p/4695110.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!