C++ GDI+ 在透明分层窗口上绘制文本

标签 c++ windows gdi+ layered

(非托管 C++) 我已经成功地将 PNG 文件绘制到可以在桌面上拖动的透明分层窗口,但现在我的问题是在透明分层窗口上绘制文本

这是我的代码和我在中间绘制文本的尝试,重要的是要注意我使用的是 screenDC 而不是 WM_PAINT 消息中的那个

[编辑] 在评论后更新了代码,现在我只是想在获取我需要使用的 HBITMAP 版本之前在位图上写文本 这次我使用 DrawString 因为 textout() 不是 GDI+,我希望 DrawString 真的是 GDI+ 哈哈 不过还是不行,想知道我做错了什么

void Draw() // draws a frame on the layered window AND moves it based on x and y
{
    HDC screenDC( NULL ); // grab screen
    HDC sourceDC( CreateCompatibleDC(screenDC) );

    POINT pos = {x,y}; // drawing location
    POINT sourcePos = {0,0}; // top left of image
    SIZE size = {100,100}; // 100x100 image

    BLENDFUNCTION blendFunction = {0};
    HBITMAP bufferBitmap = {0};
    Bitmap* TheBitmap = crnimage; // crnimage was already loaded earlier

    // ------------important part goes here, my attempt at drawing text ------------//

 Gdiplus::Graphics     Gx(TheBitmap);

// Font* myFont =    new Font(sourceDC);
 Font myFont(L"Arial", 16);


 RectF therect;
 therect.Height = 20;
 therect.Width = 180;
 therect.X = 0;
 therect.Y = 0;

 StringFormat format;
 format.SetAlignment(StringAlignmentCenter);
 format.GenericDefault();
 Gdiplus::SolidBrush   GxTextBrush(Gdiplus::Color(255, 255, 0,255));


 WCHAR thetext[] = L"Sample Text";

 int stats = Gx.DrawString(thetext, -1, &myFont, therect, &format, &GxTextBrush);
 if(stats) // DrawString returns nonzero if there is an error
     msgbox(stats); 
 stats = Gx.DrawRectangle(&Pen(Color::Red, 3), therect);
 // the rectangle and text both draw fine now

 // ------------important part goes here, my attempt at drawing text ------------//

    TheBitmap->GetHBITMAP(0, &bufferBitmap);
    HBITMAP oldBmpSelInDC;
    oldBmpSelInDC = (HBITMAP)SelectObject(sourceDC, bufferBitmap);

    // some alpha blending
    blendFunction.BlendOp = AC_SRC_OVER;
    blendFunction.SourceConstantAlpha = wndalpha;
    blendFunction.AlphaFormat = AC_SRC_ALPHA;
    COLORREF colorKey( RGB(255,0,255) );
    DWORD flags( ULW_ALPHA);

    UpdateLayeredWindow(hWnd, screenDC, &pos, & size, sourceDC, &sourcePos,
    colorKey, &blendFunction, flags);

    // release buffered image from memory
    SelectObject(sourceDC, oldBmpSelInDC);
    DeleteDC(sourceDC);
    DeleteObject(bufferBitmap); 

    // finally release the screen
    ReleaseDC(0, screenDC);
}

这两天我一直在尝试在我的分层窗口上写文本,但从这些尝试中我知道有几种方法可以做到这一点 (不幸的是,我不知道到底是怎么回事)

我看到的通常选项是在位图上绘制文本,然后渲染位图本身

  1. Use Gdi+ to load a bitmap
  2. Create a Graphics object from the bitmap
  3. Use DrawString to write text to the bitmap
  4. Dispose of the Graphics object
  5. Use the bitmap Save method to save the result to a file

显然也可以从 DC 制作图形对象,然后在 DC 上绘制文本,但我还是不知道如何做到这一点

最佳答案

总体方法看起来不错,但我认为您在调用 DrawString 时遇到了一些问题。查看 MSDN 上的文档(尤其是示例) .

Gx.DrawString(thetext, 4, NULL, therect, NULL,  NULL)

可能需要指定第三个、第五个和第六个参数(字体、格式和画笔)。文档没有说它们是可选的。为这些传递 NULL 可能会导致 GDI+ 将调用视为空操作。

第二个参数不应在字符串中包含终止符 L'\0'。如果您的字符串始终终止,则使用 -1 可能是最安全的。

关于C++ GDI+ 在透明分层窗口上绘制文本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4783781/

相关文章:

c# - Winforms 中的自定义 ListView?

c++ - MODBUS TCP 应答转换为浮点 C++

c++ - Qt Creator(设计器): Single text line with horizontal scrollbar

windows - 从 Windows PC 修改远程 Ubuntu 服务器上的文件

c - 在 x,y 位置的 Windows 控制台中打印

windows - Windows下的git svn clone large repo : out of memory - not a large file issue

c# - 如何在线条图中找到圆弧或开放曲线?

asp.net-mvc - GDI+ 中发生一般性错误

c++ - 生成所有长度未知的组合

C++ "vector iterator not decrementable"?