将DIB复制到剪贴板

介绍 最近,我有理由

  

保存一个DIB到剪贴板。在四周的时间里,我尝试了许多方法,但都没有成功 他们工作(非常感谢Chris Losinger和Christian Graus,感谢他们愿意尝试并提供给我 指导,答案,或两者都有)。这篇文章描述了我是如何最终实现我的目标,但也正好属于 分类它不漂亮,但它工作。 考验和磨难 因为我需要这样做的原因超出了本文的范围,所以我只需要说我的 起始点是一个BITMAPINFOHEADER结构体和一个指向表示实际位图的位数组的指针 数据。位图为24位。 起初,我四处徘徊,试图创建一个位图句柄与我的信息。我确信我做得对 但是由于将位图移动到剪贴板的操作一次次失败,我(自然)认为我必须这样做 我真的把它搞砸了,所以我去寻求帮助,最后使用了Chris Maunder的CDIBSectionLite类。 Chris的类包含将我捕获的位图转换为DIBSection所需的所有代码,但它缺少这些代码 将DIB移动到剪贴板。这是一个很好的开始。然而,无论我怎样努力,我还是做不到 无法将位图导入剪贴板。 这一切是如何形成的 在花了一周的时间试图从我的代码(和CDIBSectionLite)中强制出所需的功能之后,我 打电话给微软软件开发者热线(使用我订阅的MSDN上两个可用的免费事件之一)。 微软的那个家伙带我看了一个示例,显然是wincap32编译器附带的。这个示例 程序将捕获所选窗口的内容并将其转换为DIB,并将其存储在剪贴板上。 完美的。 在更改了一个或两个#include语句并更改了文件的名称之后,我编译了我的代码,运行了 结果程序,并bingo - DIB在剪贴板! 我所做的 我做的第一件事是将这个函数添加到CDIBSectionLite类中(记住,它不漂亮,但它很漂亮 工作原理: 隐藏,收缩,复制Code

HANDLE CDIBSectionLite::PutOnClipboard()
{
   HANDLE hResult = NULL;

   if (::OpenClipboard(NULL))
   {
      ::EmptyClipboard();
      ::GdiFlush();

      // borrowed these variables from the sample app
      HDIB     hDib    = NULL;
      HBITMAP  hBitmap = NULL;
      HPALETTE ghPal   = NULL;

      if (m_hBitmap)
      {
         // call the function that converts the bitmap to a DIB
         hDib = BitmapToDIB(m_hBitmap, ghPal);
         if (hDib)
         {
            // ahhh, the sweet smell of success
            hResult = ::SetClipboardData(CF_DIB, hDib);
            if (hResult == NULL)
            {
               _ShowLastError();
            }
         }
         else
         {
            MessageBeep(0);
         }
      }
      ::CloseClipboard();
   }
   return hResult;
}

从微软样例应用程序,我复制了以下文件到我的项目目录: 隐藏,复制Code

DIBUTIL.C
DIBUTIL.H
DIBAPI.H

然后我将DIBUTIL.C文件重命名为DIBUTIL.CPP。在此之后,我必须在该文件中进行以下更改 它会编译。示例应用程序是按原样编译的,但因为我包含了stdafx。h,编译器吐在某种类型上 不匹配,因此有以下变化: 隐藏,复制Code

Line  30:    #include <span class="code-keyword"><windows.h></span>
      to:    #include <span class="code-string">"stdafx.h"</span>

Line 381:    lpbi = GlobalLock(hDIB);
      to:    lpbi = (LPSTR)GlobalLock(hDIB);

Line 524:    lpDIBHdr = GlobalLock(hDIB);
      to:    lpDIBHdr = (LPSTR)GlobalLock(hDIB);

Line 608:    hPal = GetStockObject(DEFAULT_PALETTE);
      to:    hPal = (HPALETTE)GetStockObject(DEFAULT_PALETTE);

最后,我使用了整个shebang如下: 隐藏,复制Code

// I needed to construct the BITMAPINFO structure to be passed to the
// CDIBSectionLite object would be happy
HBITMAP hBitmap;
BITMAPINFO bmi;
memset(&bmi, 0, sizeof(BITMAPINFO));
// use the BITMAPINFOHEADER structure that we captured
bmi.bmiHeader = cb.bih;

CDIBSectionLite dib;
// use the BITMAPINFO struct that we created above and the bits we captured
dib.SetBitmap(&bmi, cb.pBuffer);
dib.PutOnClipboard();

最后 它的工作原理。我并不是真的对从我从文件中挑选出我需要的东西感兴趣 microsoftsample app,我打算把它都留在那里。这是我留给读者的一个练习。 本文附带的zip文件包含修改后的CDIBSectionLite类和修改后的示例应用程序 文件,以及整个示例应用程序源代码的本机形式。需要注意的是,如果按原样编译,则 示例应用程序项目创建(或提供)一个名为DIBAPI.DLL的DLL。这个DLL包含我链接的代码 直接进入我的程序(我不希望它在DLL形式)。 由于我捕获的位图的大小,我没有为CDIBSectionLite配备保存位图的能力 剪贴板除了DIB之外的任何东西。但是,请记住,有可能保存多个项 剪贴板,因此您可以同时(使用示例应用程序代码)在DIB中的剪贴板上放置位图 格式,设备依赖格式,和元文件格式,如果那是绊你的触发器。粘贴的任何应用 剪贴板将/应该拉出最适合它的要求的格式。 本文转载于:http://www.diyabc.com/frontweb/news353.html

原文地址:https://www.cnblogs.com/Dincat/p/13438540.html