使用 mfc 对话框显示 .bmp 图像时出错

Posted

技术标签:

【中文标题】使用 mfc 对话框显示 .bmp 图像时出错【英文标题】:Error with displaying an .bmp image using mfc dialog 【发布时间】:2013-12-20 10:30:35 【问题描述】:

我正在尝试使用 MFC 应用程序显示位图图像。 我正在使用浏览按钮来选择工作正常的文件。但是当我尝试通过双击文件来加载图像时,应用程序会启动,但图像不会显示。

这是我的浏览按钮代码和打开双击图像的功能。

void COpenImageDlg::OnBnClickedButton1()

    // TODO: Add your control notification handler code here
    CString path;
    CFileDialog dlg(TRUE);
    int result=dlg.DoModal();
    if(result==IDOK)
    
    path=dlg.GetPathName();
    UpdateData(FALSE);
    

    HBITMAP hBmp = (HBITMAP)::LoadImage(NULL, path, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE|LR_CREATEDIBSECTION);
    CBitmap bmp;

    bmp.Attach(hBmp); 

    CClientDC dc(this); 
    CDC bmDC; 
    bmDC.CreateCompatibleDC(&dc); 
    CBitmap *pOldbmp = bmDC.SelectObject(&bmp); 

    BITMAP  bi; 
    bmp.GetBitmap(&bi); 

    dc.BitBlt(0,0,bi.bmWidth,bi.bmHeight,&bmDC,0,0,SRCCOPY); 

    bmDC.SelectObject(pOldbmp);


void COpenImageDlg::OpenImage1(CString path)


    //CString path;
    CFileDialog dlg(TRUE);
    int result=dlg.DoModal();
    if(result==IDOK)
    
    path=dlg.GetPathName();
    UpdateData(FALSE);
    

    HBITMAP hBmp = (HBITMAP)::LoadImage(NULL, path, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE|LR_CREATEDIBSECTION);
    CBitmap bmp;

    bmp.Attach(hBmp); 

    CClientDC dc(this); 
    CDC bmDC; 
    bmDC.CreateCompatibleDC(&dc); 
    CBitmap *pOldbmp = bmDC.SelectObject(&bmp); 

    BITMAP  bi; 
    bmp.GetBitmap(&bi); 

    dc.BitBlt(0,0,bi.bmWidth,bi.bmHeight,&bmDC,0,0,SRCCOPY); 

初始化类:

`BOOL COpenImageApp::InitInstance() // 如果应用程序在 Windows XP 上需要 InitCommonControlsEx() // manifest 指定使用 ComCtl32.dll 版本 6 或更高版本来启用 // 视觉样式。否则,任何窗口创建都会失败。

INITCOMMONCONTROLSEX InitCtrls;
InitCtrls.dwSize = sizeof(InitCtrls);
// Set this to include all the common control classes you want to use
// in your application.
InitCtrls.dwICC = ICC_WIN95_CLASSES;
InitCommonControlsEx(&InitCtrls);

CWinApp::InitInstance();

AfxEnableControlContainer();

// Create the shell manager, in case the dialog contains
// any shell tree view or shell list view controls.
CShellManager *pShellManager = new CShellManager;


// Standard initialization
// If you are not using these features and wish to reduce the size
// of your final executable, you should remove from the following
// the specific initialization routines you do not need
// Change the registry key under which our settings are stored
// TODO: You should modify this string to be something appropriate
// such as the name of your company or organization
SetRegistryKey(_T("Local AppWizard-Generated Applications"));

COpenImageDlg dlg;
m_pMainWnd = &dlg;
INT_PTR nResponse = dlg.DoModal();

char* buff;
char* command_line = GetCommandLine();

buff = strchr(command_line, ' ');
buff++;
buff = strchr(buff, ' ');
buff++;
buff = strchr(buff, ' ');
buff++;

if (buff != NULL)


HBITMAP hBmp = (HBITMAP)::LoadImage(NULL, "C:\Users\Raguvaran\Desktop\tiger.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE|LR_CREATEDIBSECTION);
CBitmap bmp;
bmp.Attach(hBmp); 

dlg.RedrawWindow();
CClientDC dc(m_pMainWnd); 
CDC bmDC; 
bmDC.CreateCompatibleDC(&dc); 
CBitmap *pOldbmp = bmDC.SelectObject(&bmp); 

BITMAP  bi; 
bmp.GetBitmap(&bi); 

dc.BitBlt(0,0,bi.bmWidth,bi.bmHeight,&bmDC,0,0,SRCCOPY); 



//RedrawWindow(dlg, NULL, NULL, RDW_INVALIDATE);
//UpdateWindow(dlg);

if (nResponse == IDOK)

    // TODO: Place code here to handle when the dialog is
    //  dismissed with OK

else if (nResponse == IDCANCEL)

    // TODO: Place code here to handle when the dialog is
    //  dismissed with Cancel


// Delete the shell manager created above.
if (pShellManager != NULL)

    delete pShellManager;


// Since the dialog has been closed, return FALSE so that we exit the
//  application, rather than start the application's message pump.
return FALSE;

`

我对浏览按钮使用了相同的代码,它会显示图像。但是当我双击文件时,图像不显示。请告诉我我做错了什么。

【问题讨论】:

【参考方案1】:

如果您已将应用程序与特定文件扩展名相关联,则当您双击此类文件时(如您所说),它将自动启动。

发生这种情况时,您的应用程序将使用作为命令行参数提供给您的应用程序的文件名(实际上是完整路径)启动。

在 SDI MFC 应用程序中,只要您没有覆盖默认的文件/打开处理机制,这将由框架自动处理,但如果您有一个基于对话框的应用程序,您需要自己为此添加代码。

【讨论】:

我明白你的意思。我添加了这段代码来获取路径。 char* buff; char* command_line = GetCommandLine(); buff = strchr(command_line, ' '); buff++; if (buff != NULL) dlg.OpenImage1(buff); @Khushboo 因此,当您调试该功能时,您是否获得与浏览时完全相同的文件名?请记住,命令行上的第一个参数是应用程序名称本身。 是的,正如我之前所说,我得到了正确的文件名。我检查了那个。但是不知道以后出了什么问题。 @Khushboo 那么问题一定出在您未显示的代码中。浏览按钮代码有什么作用?双击不会调用它,因此不会发生任何事情。 好的,谢谢 :) 我会调查的。【参考方案2】:

在有机会处理命令行之前,您的对话框 COpenImageDlg 已创建并显示在对 DoModal 的调用中。当DoModal 返回时,对话框已经被销毁,因此没有可供代码使用的对话框。

【讨论】:

是的,这就是问题所在。你能告诉我我应该如何解决它吗?我应该在调用 OpenImage1 函数后给DoModal 调用吗?如果我因为CClientDC 而删除此调用,则会收到错误消息。 @Khushboo,解决这个问题的简单方法是在COpenImageDlg 本身内完成所有绘图。要直接打开的文件的路径在对话框打开之前传递到对话框中(Domodal)。这可以通过声明 COpenImageDlg 的公共成员变量并在对话框实例化后从外部设置值来完成。 @Khushboo,在对话框的OnInitDialog函数中,检查这个变量,如果不为空,直接做位图操作。但是,在绘制位图的逻辑序列中存在问题,因为它可能无法正确重新绘制。处理绘图的正确方法是缓存位图并在OnPaintOnEraseBkgnd中绘制。【参考方案3】:

我了解到,当您双击文件以在文件对话框中选择图像时,图像不会显示。我刚刚尝试了您的函数 OnBnClickedButton1 和 OpenImage1 的代码。事实证明,双击选择图像时会显示图像。我在win7上使用VS2010。我希望这会对您有所帮助,尽管我没有发现您的代码错误。

【讨论】:

我不确定你现在是否理解我的意思。我的意思是当我为图像选择打开方式并选择此应用程序时,会出现对话框但没有图像。然后我必须再次浏览才能打开它。【参考方案4】:

我找到了我的问题的答案。 这实际上是一个非常愚蠢的错误。 当我使用命令行读取文件地址时,地址有单斜杠,而我需要使用双斜杠传递地址。 这么傻的虫子。很抱歉浪费您的时间。

【讨论】:

以上是关于使用 mfc 对话框显示 .bmp 图像时出错的主要内容,如果未能解决你的问题,请参考以下文章

MFC - 无法从资源输出 BMP 图像

使用 MFC 在 MS Visual C++ 2008 中处理 .bmp 图像时出现颜色问题

MFC 在控件上显示图片不起作用

VC6.0把显示在对话框中的图像另存为bmp图片在电脑D盘

MFC 对话框 位图按钮 失去焦点

MFC程序打开文件对话框出错的问题解决