Win32 C++:使用 openfilename 并显示位图文件

发布于 2024-12-26 19:45:53 字数 3918 浏览 0 评论 0原文

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

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

下面列出的只是我认为需要完成的代码片段,尽管如此,我相信还有更多的工作要做。

#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 有文件路径,但我无法加载尽管将 __T("F-35C.bmp") 替换为 ofn.lpStrFile,但仍保留位图文件。

如下所示,显示了 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 Developer。带有 Win32 应用程序的版本(不是控制台)。

I'm new here, I'm more adapted in C# then in C++.

Therefore, I require the assistance of C++ experts for this dilemnia I am currently having.

What is listed down below is just the code snippet that i think is necessary to complete, nevertheless, i believe there are still more to be achieved.

#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;
        }

As you can see, as i click my case menu: LoadBitmap

It just loads the openfiledialog and choose the file that i want without showing in the Windows, that is all. What i actually want to do is to load the filepath into the LoadBitmap function instead of hardcoding it in the function ("F-35C.bmp).

I also do know that ofn.lpStrFile has the file path, but I am unable to load the Bitmap file despite replacing __T("F-35C.bmp") with ofn.lpStrFile.

As below shows the function of the LoadBitMap Function.

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;
}

To add on, I am using Microsoft Visual Studio 2010 Developer Version with Win32 Application ( Not Console ).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

这样的小城市 2025-01-02 19:45:53

您已经获得了 LoadBitmap() 参数。这是来自 MSDN

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

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

You've got your LoadBitmap() parameters backwards. This is from MSDN:

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

I'm also fairly certain that you don't need to wrap your filename in __T() macro for function calls.

離殇 2025-01-02 19:45:53

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

I see a problem in the fact that you are opening the file right after the GetOpenFileName call, the dwShareMode parameter in CreateFile is set to 0 ( no sharing is allowed ) and you do not close or use the obtained handle( hf ). This will result in the failure of the LoadImage call, because the file is still open with no sharing at the time of the call.
Solution: Either remove the CreateFile call, because it's useless in this code, or close the handle before calling LoadBitmap.

新一帅帅 2025-01-02 19:45:53

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

加载位图一次,并保留 HBITMAP。然后,绘制代码应以该 HBITMAP 开始。

Do not do all of this inside WM_PAINT, which will be called many MANY times during the execution of your program.

Load the bitmap once, and keep the HBITMAP around. The painting code should then start with that HBITMAP.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文