2012-01-11 1 views
0

Я новичок здесь, я более адаптирован в C#, затем в C++.Win32 C++: использование openfilename и отображение растрового файла

Поэтому мне нужна помощь экспертов 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).

Я также знаю, что fromn.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 с помощью приложения Win32 (не консоль).

+0

Итак, в чем же вопрос? Я не вижу вопроса в вашем посте. Может быть, вы должны точно указать, где указана ваша проблема. – Xeo

+1

Просто предположите здесь (ваш код должен быть как можно короче и по-прежнему показывать проблему), но у вас есть «hf = CreateFile (...)» после того, как вы получите имя файла от пользователя. Вам не нужно, и это может привести к сбою загрузки битмапа, если режим совместного доступа несовместим. – tinman

+0

Спасибо всем за комментарий, оценили. Вопрос: В настоящее время я хочу заменить hardcoded «F-35C.bmp» на lpStrFile OpenFileName. Но это не работает, извините и спасибо еще раз. – Newbie

ответ

1

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

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

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

+0

LoadBitmap() он называет его собственным кодом, а не Win32 API. – tinman

+0

Привет! Большое вам спасибо, я тоже это понял! – Newbie

+0

- tinman, функция LoadBitmap не была моей, я взял функции откуда-то еще, что я забыл, где это было, в любом случае, действительно благодарен всем вам за помощь! Спасибо! – Newbie

1

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

1

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

Загрузите растровое изображение один раз и держите HBITMAP вокруг. Затем код окраски должен начинаться с HBITMAP.

Смежные вопросы