【问题标题】:Win32 C++: Using a openfilename and displaying a bitmap fileWin32 C++:使用 openfilename 并显示位图文件
【发布时间】:2012-02-07 21:07:56
【问题描述】:

我是新来的,我更适应 C# 而不是 C++。

因此,我需要 C++ 专家的帮助来解决我目前遇到的这种困境。

下面列出的只是我认为需要完成的代码sn-p,但是,我相信还有更多的事情要做。

#include "stdafx.h"
#include "winmain.h"
#include "Resource.h"
#include <stdio.h>
#include <CommDlg.h>
#include <windows.h>

OPENFILENAME ofn;
TCHAR szFile[260];

switch (message)
    {
    case WM_COMMAND:
        wmId    = LOWORD(wParam);
        wmEvent = HIWORD(wParam);
        // Parse the menu selections:
        switch (wmId)
        {
                               case ID_FILE_LOADBITMAP:
            bBitmap = !bBitmap;
            InvalidateRect(hWnd,0,TRUE);
            break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }

case WM_PAINT:
        hdc = BeginPaint(hWnd, &ps);
        // TODO: Add any drawing code here...
if(bBitmap)
        {
        ZeroMemory(&ofn, sizeof(ofn));
        ofn.lStructSize = sizeof(ofn);
        ofn.hwndOwner = hWnd;
        ofn.lpstrFile = szFile;
        //
        // Set lpstrFile[0] to '\0' so that GetOpenFileName does not 
        // use the contents of szFile to initialize itself.
        //
        ofn.lpstrFile[0] = '\0';
        ofn.nMaxFile = sizeof(szFile);
        ofn.nFilterIndex = 1;
        ofn.lpstrFileTitle = NULL;
        ofn.nMaxFileTitle = 0;
        ofn.lpstrInitialDir = NULL;
        ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;

        // Display the Open dialog box. 

        if (GetOpenFileName(&ofn)==TRUE) 
            hf = CreateFile(ofn.lpstrFile, GENERIC_READ,
                0, (LPSECURITY_ATTRIBUTES) NULL,
                OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,
                (HANDLE) NULL);

    LoadBitmap(__T("F-35C.bmp"), hdc);

        EndPaint(hWnd, &ps);
        break;
        }

如您所见,当我单击我的案例菜单时:LoadBitmap

它只是加载 openfiledialog 并选择我想要的文件而不在 Windows 中显示,仅此而已。我真正想做的是将文件路径加载到LoadBitmap函数中,而不是在函数中硬编码(“F-35C.bmp)。

我也知道 ofn.lpStrFile 有文件路径,但我无法加载位图文件,尽管用 ofn.lpStrFile 替换了 __T("F-35C.bmp")。

如下所示为LoadBitMap函数的功能。

bool LoadBitmap(LPCWSTR szFileName, HDC hWinDC)
{
    // Load the bitmap image file
    HBITMAP hBitmap;
    hBitmap = (HBITMAP)::LoadImage(NULL, szFileName, IMAGE_BITMAP, 0, 0,
        LR_LOADFROMFILE);
    // Verify that the image was loaded
    if (hBitmap == NULL) {
        ::MessageBox(NULL, __T("LoadImage Failed"), __T("Error"), MB_OK);
        return false;
    }

    // Create a device context that is compatible with the window
    HDC hLocalDC;
    hLocalDC = ::CreateCompatibleDC(hWinDC);
    // Verify that the device context was created
    if (hLocalDC == NULL) {
        ::MessageBox(NULL, __T("CreateCompatibleDC Failed"), __T("Error"), MB_OK);
        return false;
    }

    // Get the bitmap's parameters and verify the get
    BITMAP qBitmap;
    int iReturn = GetObject(reinterpret_cast<HGDIOBJ>(hBitmap), sizeof(BITMAP),
        reinterpret_cast<LPVOID>(&qBitmap));
    if (!iReturn) {
        ::MessageBox(NULL, __T("GetObject Failed"), __T("Error"), MB_OK);
        return false;
    }

    // Select the loaded bitmap into the device context
    HBITMAP hOldBmp = (HBITMAP)::SelectObject(hLocalDC, hBitmap);
    if (hOldBmp == NULL) {
        ::MessageBox(NULL, __T("SelectObject Failed"), __T("Error"), MB_OK);
        return false;
    }

    // Blit the dc which holds the bitmap onto the window's dc
    BOOL qRetBlit = ::BitBlt(hWinDC, 0, 0, qBitmap.bmWidth, qBitmap.bmHeight,
        hLocalDC, 0, 0, SRCCOPY);
    if (!qRetBlit) {
        ::MessageBox(NULL, __T("Blit Failed"), __T("Error"), MB_OK);
        return false;
    }

    // Unitialize and deallocate resources
    ::SelectObject(hLocalDC, hOldBmp);
    ::DeleteDC(hLocalDC);
    ::DeleteObject(hBitmap);
    return true;
}

补充一点,我正在使用 Microsoft Visual Studio 2010 开发者版本和 Win32 应用程序(不是控制台)。

【问题讨论】:

  • 那么,真正的问题是什么?我在您的帖子中没有看到问号。也许你应该准确地突出你的问题所在。
  • 只是一个猜测(你的代码应该尽可能短并且仍然显示问题)但是在你从用户那里得到文件名之后你有'hf = CreateFile(...)'。不需要,如果共享模式不兼容,可能会导致位图加载失败。
  • 感谢大家的评论,感谢。问题是:目前我想用 OpenFileName 的 lpStrFile 替换硬编码的“F-35C.bmp”。但它不起作用,对不起,再次感谢。
  • 是的,我也尝试使用完整路径,但我确实需要用 / 替换 \,试图弄清楚如何做,目前正在谷歌搜索,如果有任何更简单的方法对我来说获取文件名,那就太好了!
  • 您不需要翻转 \,除非文件在当前文件夹中,否则您需要完整路径。

标签: c++ image bitmap device openfiledialog


【解决方案1】:

不要在WM_PAINT 中执行所有这些操作,在您的程序执行期间会多次调用它。

加载位图一次,并保留HBITMAP。绘画代码应该以HBITMAP开头。

【讨论】:

    【解决方案2】:

    我发现一个问题是您在调用 GetOpenFileName 后立即打开文件,CreateFile 中的 dwShareMode 参数设置为 0(不允许共享)并且您没有关闭或使用获得的句柄(hf) .这将导致 LoadImage 调用失败,因为在调用时文件仍处于打开状态且没有共享。 解决方案:要么去掉 CreateFile 调用,因为它在这段代码中没有用,要么在调用 LoadBitmap 之前关闭句柄。

    【讨论】:

      【解决方案3】:

      你的LoadBitmap() 参数倒过来了。这是来自MSDN

      HBITMAP LoadBitmap(
        __in  HINSTANCE hInstance,
        __in  LPCTSTR lpBitmapName
      );
      

      我也相当确定您不需要将文件名包装在 __T() 宏中以进行函数调用。

      【讨论】:

      • 他调用的 LoadBitmap() 是他自己的代码,不是 Win32 API 的。
      • 嗨!非常感谢,我也刚刚意识到!
      • - tinman,LoadBitmap 函数不是我的,我是从别的地方拿的函数,我忘了它在哪里,无论如何,非常感谢大家帮助我!谢谢!
      猜你喜欢
      • 2021-04-12
      • 2011-01-17
      • 2015-04-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-02
      相关资源
      最近更新 更多