Win32 C ++: использование имени открытого файла и отображение файла растрового изображения - PullRequest
0 голосов
/ 11 января 2012

Я новичок здесь, я более адаптирован в 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 есть путь к файлу, но я не могу загрузить файл Bitmap, несмотря на замену __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 (не консоль).

Ответы [ 3 ]

1 голос
/ 11 января 2012

Я вижу проблему в том, что вы открываете файл сразу после вызова GetOpenFileName, для параметра dwShareMode в CreateFile установлено значение 0 (совместное использование запрещено), и вы не закрываете и не используете полученный дескриптор (hf),Это приведет к сбою вызова LoadImage, поскольку файл все еще открыт без общего доступа во время вызова.Решение. Либо удалите вызов CreateFile, поскольку он бесполезен в этом коде, либо закройте дескриптор перед вызовом LoadBitmap.

1 голос
/ 11 января 2012

Не делайте все это внутри WM_PAINT, который будет вызываться много раз во время выполнения вашей программы.

Загрузите растровое изображение один раз и сохраняйте HBITMAP.Код рисования должен начинаться с этого HBITMAP.

1 голос
/ 11 января 2012

У вас есть LoadBitmap() параметры в обратном направлении.Это из MSDN :

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

Я также вполне уверен, что вам не нужно заключать ваше имя файла в макрос __T() для вызовов функций.

...