简体   繁体   English

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

[英]C++ GDI+ drawing text on a transparent layered window

(unmanaged C++) I already succeeded drawing PNG files to a transparent layered window that I can drag around the desktop, but now my problem is drawing text on a transparent layered window (非托管C ++)我已经成功将PNG文件绘制到可以在桌面上拖动的透明分层窗口中,但是现在我的问题是在透明分层窗口上绘制文本

Here's my code and my attempt at drawing text in the middle, it's important to note that i'm using the screenDC instead of using the one in WM_PAINT messages 这是我的代码,也是我尝试在中间绘制文本的尝试,需要注意的是,我使用的是screenDC而不是WM_PAINT消息中的那个

[edit] updated code after the comments, now i'm just trying to write text on the bitmap before getting the HBITMAP version which i need to use this time I'm using DrawString because textout() isn't GDI+, I hope DrawString really is GDI+ lol still doesn't work though, wonder what i'm doing wrong [编辑]在评论后更新了代码,现在我只是想在获取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);
}

I've been trying to write text on my layered window for two days now, but from those attempts I know there are several ways I can go about doing this (unfortunately I have no idea how exactly) 我已经尝试在分层窗口上写文本两天了,但是通过这些尝试,我知道可以通过多种方法进行此操作(不幸的是,我不知道该怎么做)

The usual option I see is drawing text on a bitmap, then rendering the bitmap itself 我看到的通常选项是在位图上绘制文本,然后渲染位图本身

  1. Use Gdi+ to load a bitmap 使用Gdi +加载位图
  2. Create a Graphics object from the bitmap 从位图创建图形对象
  3. Use DrawString to write text to the bitmap 使用DrawString将文本写入位图
  4. Dispose of the Graphics object 处置Graphics对象
  5. Use the bitmap Save method to save the result to a file 使用位图保存方法将结果保存到文件

Apparently one can also make a graphics object from a DC, then draw text on the DC, but again i have no clue as to how to do this 显然,也可以从DC制作图形对象,然后在DC上绘制文本,但是同样我不知道如何执行此操作

The overall approach looks right, but I think you've got some problems with the DrawString call. 整体方法看起来不错,但是我认为DrawString调用存在一些问题。 Check out the documentation (especially the sample) on MSDN . 查看MSDN上的文档(尤其是示例)。

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

The third, fifth, and sixth parameters (font, format, and brush) probably need to be specified. 可能需要指定第三,第五和第六个参数(字体,格式和画笔)。 The documentation doesn't say that they are optional. 该文档没有说它们是可选的。 Passing NULL for these is probably causing GDI+ to treat the call as a no-op. 为这些传递NULL可能会导致GDI +将呼叫视为无操作。

The second parameter should not include the terminating L'\\0' in the string. 第二个参数不应在字符串中包含终止符L'\\ 0'。 It's probably safest to use -1 if your string is always terminated. 如果您的字符串始终终止,则使用-1可能是最安全的方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM