2016-01-21 57 views
1

我创建了一个简单的win32应用程序来打开菜单中的对话框,选择位图图像并在窗口上显示或绘制它。现在我面临的问题是,当我从GetOpenFileName方法获得文件名并将其传递给​​函数时,图像无法加载。但是,如果我将文件路径“D:/Splash.bmp”直接传递给函数参数,则会加载图像。问题是GetOpenFileName方法在程序使用“D:/Splash.bmp”时给出了“D:\ Splash.bmp”作为路径。什么可能是错误?如何从菜单中打开图像并显示在win 32程序上?

下面是代码:

//Win32Bitmap.cpp : Defines the entry point for the application.// 

#include "stdafx.h" 
#include "Win32Bitmap.h" 
#include<Windows.h> 
#include <Commdlg.h> 

#define MAX_LOADSTRING 100 

// Global Variables: 
HINSTANCE hInst;        // current instance 
TCHAR szTitle[MAX_LOADSTRING];     // The title bar text 
TCHAR szWindowClass[MAX_LOADSTRING];   // the main window class name 

// Forward declarations of functions included in this code module: 
ATOM    MyRegisterClass(HINSTANCE hInstance); 
BOOL    InitInstance(HINSTANCE, int); 
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); 
INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM); 

int APIENTRY _tWinMain(_In_ HINSTANCE hInstance, 
       _In_opt_ HINSTANCE hPrevInstance, 
       _In_ LPTSTR lpCmdLine, 
       _In_ int  nCmdShow) 
{ 
UNREFERENCED_PARAMETER(hPrevInstance); 
UNREFERENCED_PARAMETER(lpCmdLine); 

// TODO: Place code here. 
MSG msg; 
HACCEL hAccelTable; 

// Initialize global strings 
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING); 
LoadString(hInstance, IDC_WIN32BITMAP, szWindowClass, MAX_LOADSTRING); 
MyRegisterClass(hInstance); 

// Perform application initialization: 
if (!InitInstance (hInstance, nCmdShow)) 
{ 
    return FALSE; 
} 

hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_WIN32BITMAP)); 

// Main message loop: 
while (GetMessage(&msg, NULL, 0, 0)) 
{ 
    if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) 
    { 
     TranslateMessage(&msg); 
     DispatchMessage(&msg); 
    } 
} 

return (int) msg.wParam; 
} 



// 
// FUNCTION: MyRegisterClass() 
// 
// PURPOSE: Registers the window class. 
// 
ATOM MyRegisterClass(HINSTANCE hInstance) 
{ 
WNDCLASSEX wcex; 

wcex.cbSize = sizeof(WNDCLASSEX); 

wcex.style   = CS_HREDRAW | CS_VREDRAW; 
wcex.lpfnWndProc = WndProc; 
wcex.cbClsExtra  = 0; 
wcex.cbWndExtra  = 0; 
wcex.hInstance  = hInstance; 
wcex.hIcon   = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WIN32BITMAP)); 
wcex.hCursor  = LoadCursor(NULL, IDC_ARROW); 
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); 
wcex.lpszMenuName = MAKEINTRESOURCE(IDC_WIN32BITMAP); 
wcex.lpszClassName = szWindowClass; 
wcex.hIconSm  = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL)); 

return RegisterClassEx(&wcex); 
} 

// 
// FUNCTION: InitInstance(HINSTANCE, int) 
// 
// PURPOSE: Saves instance handle and creates main window 
// 
// COMMENTS: 
// 
//  In this function, we save the instance handle in a global variable  and 
//  create and display the main program window. 
// 
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) 
{ 
HWND hWnd; 

hInst = hInstance; // Store instance handle in our global variable 

hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, 
    CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL); 

if (!hWnd) 
{ 
    return FALSE; 
} 

ShowWindow(hWnd, nCmdShow); 
UpdateWindow(hWnd); 

return TRUE; 
} 
bool LoadAndBlitBitmap(LPTSTR szFileName, HDC hdcWin) 
{ 
    HBITMAP hbitmap; 
hbitmap = (HBITMAP)LoadImage(NULL, szFileName, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE); 
if (hbitmap == NULL) 
{ 
    MessageBox(NULL, L"Image couldn't be loaded", L"Error", MB_OK | MB_ICONEXCLAMATION); 
    return false; 
} 

//create a memory device context that is compatible with the window 
HDC hdclocal = CreateCompatibleDC(hdcWin); 
if (hdclocal == NULL) 
{ 
    MessageBox(NULL, L"device context not created", L"Error", MB_OK | MB_ICONEXCLAMATION); 
    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, L"Get object failed", L"Error", MB_OK | MB_ICONEXCLAMATION); 
    return false; 
} 

//select the loaded bitmap into the device context 
HBITMAP holdbitmap = (HBITMAP)SelectObject(hdclocal, hbitmap); 
if (holdbitmap==NULL) 
{ 
    MessageBox(NULL, L"Get object failed", L"Error", MB_OK | MB_ICONEXCLAMATION); 
    return false; 
} 

//transfer the device context from the memory device context to the windows context(actual drawing surface) 
bool qRetBlit = BitBlt(hdcWin, 0, 0, qbitmap.bmWidth, qbitmap.bmHeight, hdclocal, 0, 0, SRCCOPY); 
if (!qRetBlit) 
{ 
    MessageBox(NULL, L"bitblt failed", L"Error", MB_OK | MB_ICONEXCLAMATION); 
    return false; 
} 

//deallocate the resources 

SelectObject(hdclocal, holdbitmap); 
DeleteDC(hdclocal); 
DeleteObject(hbitmap); 
return true; 
} 


// 
// FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM) 
// 
// PURPOSE: Processes messages for the main window. 
// 
// WM_COMMAND - process the application menu 
// WM_PAINT - Paint the main window 
// WM_DESTROY - post a quit message and return 
// 
// 
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) 
{ 
int wmId, wmEvent; 
PAINTSTRUCT ps; 
HDC hdc; 
wchar_t szFileName[MAX_PATH] = L""; 
switch (message) 
{ 
case WM_COMMAND: 
    wmId = LOWORD(wParam); 
    wmEvent = HIWORD(wParam); 
    // Parse the menu selections: 
    switch (wmId) 
    { 
    case IDM_ABOUT: 
     DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About); 
     break; 
    case IDM_EXIT: 
     DestroyWindow(hWnd); 
     break; 
    case ID_FILE_OPEN: 
    { 
     OPENFILENAME ofn; 

     ZeroMemory(&ofn, sizeof(ofn)); 
     ofn.lStructSize = sizeof(ofn); // SEE NOTE BELOW 
     ofn.hwndOwner = hWnd; 
     ofn.lpstrFilter = L"Bitmap Files (*.bmp)\0*.bmp\0All Files (*.*)\0*.*\0"; 
     ofn.lpstrFile = szFileName; 
     ofn.nMaxFile = MAX_PATH; 
     ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY; 
     ofn.lpstrDefExt = L"bmp"; 
     if (GetOpenFileName(&ofn)) 
     { 
      MessageBox(NULL, szFileName, L"path", MB_OK); 
      //InvalidateRect(hWnd, 0, TRUE); 
     } 
    } 
    break; 
    default: 
     return DefWindowProc(hWnd, message, wParam, lParam); 
    } 
    break; 
case WM_PAINT: 
    hdc = BeginPaint(hWnd, &ps); 
    // TODO: Add any drawing code here... 

     LoadAndBlitBitmap(L"D:/Splash.bmp", hdc); 


    EndPaint(hWnd, &ps); 
    break; 
case WM_DESTROY: 
    PostQuitMessage(0); 
    break; 
default: 
    return DefWindowProc(hWnd, message, wParam, lParam); 
} 
return 0; 
} 

// Message handler for about box. 
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) 
{ 
UNREFERENCED_PARAMETER(lParam); 
switch (message) 
{ 
case WM_INITDIALOG: 
    return (INT_PTR)TRUE; 

case WM_COMMAND: 
    if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) 
    { 
     EndDialog(hDlg, LOWORD(wParam)); 
     return (INT_PTR)TRUE; 
    } 
    break; 
} 
return (INT_PTR)FALSE; 
} 
+0

您可能必须删除字符串分隔符引号(双引号)'''“' – milevyo

+0

@Priyank没有反馈?我的回答是否帮助您解决问题?如果确实如此,请考虑将其标记为已接受 –

+0

Thankyou @MarkoPopovic,解决了这个问题。 –

回答

0

反斜杠是没有问题的。实际上,Windows倾向于正斜杠上的反斜杠。您的问题在于,您已将您的szFileName缓冲区设为本地窗口过程功能(WndProc)。当您单击菜单项以选择一个文件时,消息WM_COMMAND将被发送到该窗口并由其窗口过程处理。你已经正确地实现了打开对话框并检索文件路径。但是,处理完成后,函数WndProc将退出并销毁堆栈中的所有局部变量,包括szFileName中包含的文件路径。

要解决您的问题,请将szFileName设为全局变量,以免它被破坏。另外请注意,您选择图像文件后,窗口不会自动更新,需要指导窗口通过将呼叫此代码后重新绘制本身GetOpenFileName

InvalidateRect(hWnd, NULL, TRUE); 
UpdateWindow(hWnd); 

这将无效整个窗口区域并安排重新绘制窗口(这意味着消息WM_PAINT将再次发送到窗口并由WndProc处理)。

相关问题