MFC应用程序是文档/视图结构支持的时候对工具栏加载图片的问题。
核心思路是延迟图片加载的时机,确保在主框架窗口及其所有子控件都已完全初始化后再进行。使用PostMessage 发送一个自定义消息。
这个方法通过向主框架窗口发送一个自定义消息,将图片加载的操作推迟到当前消息循环处理完毕之后,从而确保窗口已完全就绪。
步骤如下:
定义自定义消息
#define WM_LOAD_TOOLBAR_IMAGES (WM_USER + 101) // 定义一个唯一的自定义消息ID
声明消息处理函数
// MainFrm.h
class CMainFrame : public CFrameWnd
{
// ... 其他成员 ...
protected:
afx_msg LRESULT OnLoadToolbarImages(WPARAM wParam, LPARAM lParam);
DECLARE_MESSAGE_MAP()
};
添加消息映射
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
// ... 其他消息映射 ...
ON_MESSAGE(WM_LOAD_TOOLBAR_IMAGES, &CMainFrame::OnLoadToolbarImages)
END_MESSAGE_MAP()
在 OnCreate 中发送消息
在 CMainFrame::OnCreate 函数中,完成工具栏的基本创建后,使用 PostMessage 发送自定义消息。
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
return -1;
// ... 创建工具栏的代码,例如 m_wndToolBar.Create(...) ...
// ... 加载工具栏资源的代码,例如 m_wndToolBar.LoadToolBar(...) ...
// 【关键步骤】发送自定义消息,延迟加载图片
PostMessage(WM_LOAD_TOOLBAR_IMAGES);
return 0;
}
实现图片加载逻辑
实现消息处理函数,将原本在 OnCreate 中添加图片的代码移动到这里。
LRESULT CMainFrame::OnLoadToolbarImages(WPARAM wParam, LPARAM lParam)
{
// 在这里执行添加图片的代码
int nHigth = 128;
int nWidth = 128;
int nBarhigth = 32;
int nBarwith = 32;
m_wndToolBar.RemoveAllButtons();
m_ToolbarImages.SetImageSize(CSize(nWidth, nHigth)); //注意这里的nWidth和nHigth一定要和资源视图里的toolbar的按钮一致,
HBITMAP hbmp1 = (HBITMAP)LoadImage(NULL, TEXT("res\\storage.bmp"), IMAGE_BITMAP, nWidth, nHigth, LR_LOADFROMFILE | LR_DEFAULTCOLOR | LR_CREATEDIBSECTION); //注意这里的nWidth和nHigth一定要和资源视图里的toolbar的按钮一致,
bmp1.Attach(hbmp1);
m_ToolbarImages.AddImage(bmp1);
m_ToolbarImages.SetTransparentColor(RGB(255, 0, 255));
m_wndToolBar.SetUserImages(&m_ToolbarImages);
m_wndToolBar.SetSizes(CSize(nBarwith * 2 + 8, nBarhigth * 2+8), CSize(nBarwith, nBarhigth)); //调整nBarwith和nBarhigth可起到缩放按钮的作用,加8是为了图片加载到按钮上后,上下左右有预留空间。
m_wndToolBar.InsertButton(CMFCToolBarButton(ID_STROGE, 0, _T("新建"), TRUE));
m_wndToolBar.InsertButton(CMFCToolBarButton(ID_SET, 1, _T("新建"), TRUE));
m_wndToolBar.AdjustSizeImmediate();
// 1. 获取按钮索引
int iIndex = m_wndToolBar.CommandToIndex(ID_STROGE);
if (iIndex != -1)
{
// 2. 创建菜单按钮
// 参数说明:
// ID_MY_DROPDOWN: 命令ID
// hMenu: 关联的下拉菜单句柄 (需要先加载菜单资源)
// iImage: 图标索引 (-1表示无图标)
// bText: 是否显示文本
// bDropArrow: 是否显示下拉箭头
CMenu menu;
menu.LoadMenu(IDR_MENU1); // 加载预先定义好的菜单资源
HMENU hMenu = menu.GetSubMenu(0)->GetSafeHmenu();
CMFCToolBarMenuButton* pMenuBtn = new CMFCToolBarMenuButton(
ID_STROGE,
hMenu,
0,
TEXT("sjw"),
TRUE // 显示下拉箭头
);
// 3. 替换原有按钮
m_wndToolBar.ReplaceButton(ID_STROGE, *pMenuBtn);
}
DockPane(&m_wndToolBar);
return 0;
}
上述方法可以加载工具栏图片。