【问题标题】:Button with PNG using GDI+使用 GDI+ 的 PNG 按钮
【发布时间】:2015-02-24 03:48:26
【问题描述】:

我正在尝试将 png 加载到我的按钮,但它没有在我的按钮中显示 png。

我用这个函数创建了我的按钮:

HWND MyControls::CreateButton(LPCTSTR text, int x, int y, int w, int h, HMENU id, HWND hwnd, HINSTANCE hInst, bool png){
        if (png){
            return CreateWindow("BUTTON", text, BS_BITMAP | WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON,
                x, y, w, h, hwnd, id, hInst, NULL);
        }
        else{
            return CreateWindow("BUTTON", text, WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON,
                x, y, w, h, hwnd, id, hInst, NULL);
        }   
}    

将 PNG 添加到按钮 (WM_CREATE):

void MyControls::AddPngBtn(HWND hwnd, const WCHAR* fileName){
    Bitmap bmp(fileName);
    HBITMAP tBmp;
    bmp.GetHBITMAP(Color(0, 0, 0, 0), &tBmp);
    SendMessage(hwnd, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)tBmp);
    ShowWindow(hwnd, SW_SHOW);
    DeleteObject(tBmp);
}    

以及我如何初始化 GDI+:

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow){
    UNREFERENCED_PARAMETER(hPrevInstance);
    UNREFERENCED_PARAMETER(szCmdLine);
    UNREFERENCED_PARAMETER(iCmdShow);

    GdiplusStartupInput gdiplusStartupInput;
    ULONG_PTR gdiplusToken;
    GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);

    if (!Wnd.RegClassEx(hInstance)) return 0;
    if (!Wnd.CreateMyWindow(hInstance)) return 0;

    GdiplusShutdown(gdiplusToken);

    return Wnd.MyMsg();
}    

The LPARAM is not NULL;
My button size: 25x25;
My png size: 24x24;
And i don't have a error in the "Error List".

我应该怎么做,或者我做错了什么?

【问题讨论】:

  • BS_OWNERDRAW 不是我的解决方案,我认为有一种方法可以在没有 BS_OWNERDRAW 的情况下加载 png。第二个问题这个家伙不想使用 GDI+。 (您刚刚删除了您发布的内容)而且我使用标签 c++ 因为我正在考虑使用 c++ 和 gdi+ 的人。而且我知道 Win32 API 是基于 C 的。 Ty 为您提供帮助和时间。
  • 好的,祝你好运。抱歉打扰了。
  • 您可以随时打断。你是高手我还是菜鸟。
  • STM_SETIMAGE 不会复制您传入的位图(一般情况下),因此在销毁控件之前,您不能像正在做的那样删除位图。
  • 您是否查看过这个问题:How to create a C++ button with an icon 和这个答案:How would I load a PNG image using Win32/GDI (no GDI+ if possible)?。似乎 ICO 是要走的路,除非你被 PNG 装箱。或者,也许它可以即时将 PNG 转换为 ICO,然后使用 ICO。我不使用图片按钮,所以我只能帮助您找到可能有用的相关项目。

标签: c++ winapi graphics gdi+


【解决方案1】:

正如 Jonathan Potter 在 cmets 中指出的那样,STM_SETIMAGE 需要 HBITMAP 来支持。清理语义为somewhat convoluted,但一般不能在WM_DESTROY 之前调用DeleteObject

【讨论】:

  • 确实如此。但我不明白为什么我应该只删除 WM_DESTROY 中的对象,因为我在那里调用 PostQuitMessage(0)。
  • 您不应在使用HBITMAP 时删除它。在您收到WM_DESTROY 之前,它一直在使用中(通常),因此您不应在收到WM_DESTROY 之前致电DeleteObject。您根本必须致电DeleteObject,但最终会出现泄漏,该泄漏一直持续到您结束该过程。
猜你喜欢
  • 2011-12-03
  • 1970-01-01
  • 2012-11-04
  • 2012-05-09
  • 2011-06-01
  • 2018-04-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多