c++ - 从文件资源管理器中选择图像后将图像放在屏幕上
问题描述
我正在尝试编写用户能够从他们的计算机中选择图像的代码。我能够让一段代码在用户选择图像时窗口会自行更新的地方工作。所以,我继续在屏幕上添加了一些按钮,现在,图像甚至不会加载到屏幕上。我很困惑为什么。这不是图像大小,因为我也选择了一个小图像来加载。
这是我放置图像的功能:
void putImage(HDC hdc, HWND hWnd)
{
Graphics graphic(hdc);
Image* image = Image::FromFile(filePath);
Status status = graphic.DrawImage(image, 10, 20);
RECT updateRect = { 0 };
updateRect.left = 10;
updateRect.top = 10;
updateRect.right = updateRect.left + image->GetWidth();
updateRect.bottom = updateRect.top + image->GetHeight();
RedrawWindow(hWnd, &updateRect, NULL, RDW_INVALIDATE);
}
这是我的油漆:
case WM_PAINT: {
PAINTSTRUCT ps;
HDC screen = BeginPaint(hWnd, &ps);
HPAINTBUFFER hbuff = BeginBufferedPaint(ps.hdc, &ps.rcPaint, BPBF_COMPATIBLEBITMAP, NULL, &screen);
if (hbuff)
{
RECT rc;
GetClientRect(hWnd, &rc);
FillRect(screen, &rc, GetSysColorBrush(COLOR_WINDOW));
putImage(screen, hWnd);
hr = EndBufferedPaint(hbuff, TRUE);
}
EndPaint(hWnd, &ps); } break;
我刚刚添加了带有 WS_VISIBLE 和 WS_CHILD 的 CreateWindowW 按钮。
解决方案
如果您设置文件的绝对路径,您的代码将起作用。值得一提的是,您可以评论RedrawWindow
,因为此功能会反复刷新窗口并导致闪烁。
这是一个可重现的示例,您可以尝试:
#include <Windows.h>
#include <ObjIdl.h>
#include <gdiplus.h>
#include <uxtheme.h>
#include <shobjidl_core.h>
#pragma comment (lib,"Gdiplus.lib")
#pragma comment(lib,"Uxtheme")
#define MAX_LOADSTRING 100
#define IDB_BUTTON1 101
using namespace Gdiplus;
using namespace std;
void putImage(HDC, HWND);
void Opendialog();
HWND hwnd;
PWSTR pszFilePath;
BOOL flag = 0;
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
switch (message)
{
case WM_CREATE:
{
HWND hwndButton = CreateWindow(
L"BUTTON", // Predefined class; Unicode assumed
L"OK", // Button text
WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON, // Styles
500, // x position
10, // y position
100, // Button width
100, // Button height
hwnd, // Parent window
(HMENU)IDB_BUTTON1, // No menu.
(HINSTANCE)GetWindowLongPtr(hwnd, GWLP_HINSTANCE),
NULL); // Pointer not needed.
}
break;
case WM_COMMAND:
{
int wmId = LOWORD(wParam);
// Parse the menu selections:
switch (wmId)
{
case IDB_BUTTON1:
Opendialog();
flag = 1;
InvalidateRect(hwnd, NULL, FALSE);
default:
return DefWindowProc(hwnd, message, wParam, lParam);
}
}
break;
case WM_PAINT:
{
HRESULT hr = S_OK;
PAINTSTRUCT ps;
HDC screen = BeginPaint(hwnd, &ps);
// TODO: Add any drawing code that uses hdc here...
if (flag == 1)
{
HPAINTBUFFER hbuff = BeginBufferedPaint(ps.hdc, &ps.rcPaint, BPBF_COMPATIBLEBITMAP, NULL, &screen);
if (hbuff)
{
RECT rc;
GetClientRect(hwnd, &rc);
FillRect(screen, &rc, GetSysColorBrush(COLOR_WINDOW));
putImage(screen, hwnd);
hr = EndBufferedPaint(hbuff, TRUE);
}
flag = 0;
}
EndPaint(hwnd, &ps);
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, message, wParam, lParam);
}
return 0;
};
HINSTANCE hinst;
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevinstance, PSTR szCmdLine, int iCmdShow) {
GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
//Initialize GDI+
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
hinst = GetModuleHandle(NULL);
// create a window class:
WNDCLASS wc = {};
wc.lpfnWndProc = WndProc;
wc.hInstance = hinst;
wc.lpszClassName = L"win32";
// register class with operating system:
RegisterClass(&wc);
// create and show window:
hwnd = CreateWindow(L"win32", L"My program", WS_OVERLAPPEDWINDOW | WS_HSCROLL | WS_VSCROLL, 0, 0, 1000, 800, NULL, NULL, hinst, NULL);
if (hwnd == NULL) {
return 0;
}
ShowWindow(hwnd, SW_SHOW);
MSG msg = {};
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
void putImage(HDC hdc, HWND hWnd)
{
Graphics graphic(hdc);
Image* image = Image::FromFile(pszFilePath);
Status status = graphic.DrawImage(image, 10, 20);
RECT updateRect = { 0 };
updateRect.left = 10;
updateRect.top = 10;
updateRect.right = updateRect.left + image->GetWidth();
updateRect.bottom = updateRect.top + image->GetHeight();
// RedrawWindow(hWnd, &updateRect, NULL, RDW_INVALIDATE);
}
void Opendialog()
{
HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED |
COINIT_DISABLE_OLE1DDE);
if (SUCCEEDED(hr))
{
IFileOpenDialog* pFileOpen;
// Create the FileOpenDialog object.
hr = CoCreateInstance(CLSID_FileOpenDialog, NULL, CLSCTX_ALL,
IID_IFileOpenDialog, reinterpret_cast<void**>(&pFileOpen));
if (SUCCEEDED(hr))
{
// Show the Open dialog box.
hr = pFileOpen->Show(NULL);
// Get the file name from the dialog box.
if (SUCCEEDED(hr))
{
IShellItem* pItem;
hr = pFileOpen->GetResult(&pItem);
if (SUCCEEDED(hr))
{
hr = pItem->GetDisplayName(SIGDN_FILESYSPATH, &pszFilePath);
// Display the file name to the user.
if (SUCCEEDED(hr))
{
// MessageBox(NULL, pszFilePath, L"File Path", MB_OK);
CoTaskMemFree(pszFilePath);
}
pItem->Release();
}
}
pFileOpen->Release();
}
CoUninitialize();
}
}
调试:
更新:
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <tchar.h>
#include <string>
#include<string.h>
#include <iostream>
#include <uxtheme.h>
#include <shobjidl.h>
#include <objidl.h>
#include <gdiplus.h>
#include <gdiplusheaders.h>
#pragma comment (lib,"Gdiplus.lib")
#pragma comment (lib, "uxtheme.lib")
#pragma comment(lib, "user32.lib")
#pragma warning(disable:4996)
using namespace Gdiplus;
#define FILE_OPEN 1
#define FILE_MENU_EXIT 3
#define MENU_HELP 4
static TCHAR szWindowClass[] = _T("DesktopApp");
static TCHAR szTitle[] = _T("Multi-Purpose Media Editor");
HINSTANCE hInst;
HMENU hMenu;
PWSTR filePath;
int flag = 0;
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
void AddMenus(HWND);
void AddControls(HWND);
void OpenFileWindow(HWND);
void putImage(HDC, HWND);
std::wstring s2ws(const std::string&);
//Main Function for Windows Desktop Application
int CALLBACK WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance,
_In_ LPSTR lpCmdLine, _In_ int nCmdShow)
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = 0;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, IDI_APPLICATION);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, IDI_APPLICATION);
if (!RegisterClassEx(&wcex))
{
MessageBox(NULL,
_T("Call to RegisterClassEx failed!"),
_T("Windows Desktop Guided Tour"),
NULL);
return 1;
}
hInst = hInstance;
DEVMODE settings;
EnumDisplaySettings(NULL, 0, &settings);
HWND hWnd = CreateWindow(
szWindowClass,
szTitle,
WS_OVERLAPPEDWINDOW | WS_CAPTION | WS_SYSMENU,
CW_USEDEFAULT, CW_USEDEFAULT,
GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN),
NULL,
NULL,
hInstance,
NULL
);
Gdiplus::GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
Gdiplus::GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
if (!hWnd)
{
MessageBox(NULL,
_T("Call to CreateWindow failed!"),
_T("Windows Desktop Guided Tour"),
NULL);
return 1;
}
ShowWindow(hWnd, nCmdShow);
// Main message loop:
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int)msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HRESULT hr;
PAINTSTRUCT ps;
HDC hdc;
switch (message)
{
case WM_CREATE:
AddMenus(hWnd);
AddControls(hWnd);
hr = BufferedPaintInit();
break;
case WM_COMMAND:
switch (wParam)
{
case FILE_MENU_EXIT:
// File Menu Exit
DestroyWindow(hWnd);
break;
case FILE_OPEN:
OpenFileWindow(hWnd);
flag = 1;
InvalidateRect(hWnd, NULL, FALSE);
break;
}
break;
case WM_PAINT: {
PAINTSTRUCT ps;
HDC screen = BeginPaint(hWnd, &ps);
/*Gdiplus::Graphics gf(screen);
Gdiplus::Bitmap jpgicon(L"jpg-icon.png");
Gdiplus::Bitmap pdficon(L"pdf-icon.png");
gf.DrawImage(&jpgicon, 10, 10);
gf.DrawImage(&pdficon, 900, 10);*/
if (flag)
{
HPAINTBUFFER hbuff = BeginBufferedPaint(ps.hdc, &ps.rcPaint, BPBF_COMPATIBLEBITMAP, NULL, &screen);
if (hbuff)
{
RECT rc;
GetClientRect(hWnd, &rc);
FillRect(screen, &rc, GetSysColorBrush(COLOR_WINDOW));
//DrawText(screen, L"Multi-Purpose Media Editor", -1, &rc, DT_BOTTOM | DT_VCENTER | DT_SINGLELINE);
putImage(screen, hWnd);
hr = EndBufferedPaint(hbuff, TRUE);
}
flag = 0;
}
EndPaint(hWnd, &ps); } break;
case WM_DESTROY:
BufferedPaintUnInit();
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
break;
}
return 0;
}
void AddMenus(HWND hWnd)
{
hMenu = CreateMenu();
HMENU hFileMenu = CreateMenu();
HMENU hSubMenu = CreateMenu();
// File Open Submenu
/*AppendMenu(hSubMenu, MF_STRING, FILE_OPEN_JPG, s2ws("JPG").c_str());
AppendMenu(hSubMenu, MF_STRING, FILE_OPEN_PDF, s2ws("PDF").c_str());*/
// File Popup Menu
// (UINT_PTR)hSubMenu <- for submenu
AppendMenu(hFileMenu, MF_POPUP, FILE_OPEN, s2ws("Open").c_str());
AppendMenu(hFileMenu, MF_SEPARATOR, NULL, NULL);
AppendMenu(hFileMenu, MF_STRING, FILE_MENU_EXIT, s2ws("Exit").c_str());
// Main Menu
AppendMenu(hMenu, MF_POPUP, (UINT_PTR)hFileMenu, s2ws("File").c_str());
AppendMenu(hMenu, MF_STRING, MENU_HELP, s2ws("Help").c_str());
SetMenu(hWnd, hMenu);
}
void AddControls(HWND hWnd)
{
// Static and Edit Controls
CreateWindowW(L"static", L"Multi-Purpose Media Editor", WS_VISIBLE | WS_CHILD | WS_BORDER | SS_CENTER, GetSystemMetrics(SM_CXSCREEN) / 2, 10, 180, 30, hWnd, NULL, NULL, NULL);
// Button on Window
//CreateWindowW(L"button", L"JPG Editor", WS_VISIBLE | WS_CHILD, 190, 150, 100, 30, hWnd, NULL, NULL, NULL);
//CreateWindowW(L"button", L"PDF Editor", WS_VISIBLE | WS_CHILD, 770, 150, 100, 30, hWnd, NULL, NULL, NULL);
CreateWindowW(L"button", L"Edit Image", WS_VISIBLE | WS_CHILD, GetSystemMetrics(SM_CXSCREEN) / 4, 3 * GetSystemMetrics(SM_CYSCREEN) / 4, 100, 30, hWnd, (HMENU)FILE_OPEN, NULL, NULL);
CreateWindowW(L"button", L"Edit PDF", WS_VISIBLE | WS_CHILD, 3 * GetSystemMetrics(SM_CXSCREEN) / 4, 3 * GetSystemMetrics(SM_CYSCREEN) / 4, 100, 30, hWnd, NULL, NULL, NULL);
}
void OpenFileWindow(HWND hWnd)
{
HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
if (SUCCEEDED(hr))
{
IFileOpenDialog* pFileOpen;
// Create the FileOpenDialog object.
hr = CoCreateInstance(CLSID_FileOpenDialog, NULL, CLSCTX_ALL,
IID_IFileOpenDialog, reinterpret_cast<void**>(&pFileOpen));
if (SUCCEEDED(hr))
{
// Show the Open dialog box.
hr = pFileOpen->Show(NULL);
// Get the file name from the dialog box.
if (SUCCEEDED(hr))
{
IShellItem* pItem;
hr = pFileOpen->GetResult(&pItem);
if (SUCCEEDED(hr))
{
PWSTR pszFilePath;
hr = pItem->GetDisplayName(SIGDN_FILESYSPATH, &pszFilePath);
// Display the file name to the user.
if (SUCCEEDED(hr))
{
char szBuffer[255];
WideCharToMultiByte(CP_ACP, 0, pszFilePath, -1, szBuffer, sizeof(szBuffer), NULL, NULL);
// JPG/JPEG/PNG
if (1)
{
filePath = pszFilePath;
}
// PDF
//else if ()
//{
//}
// Error MSG
else
{
MessageBox(NULL, L"Not a supported media!", L"Error", MB_OK);
}
//LoadImageW(hInst, pszFilePath, 0, 0, 0, LR_DEFAULTSIZE);
//MessageBox(NULL, pszFilePath, L"File Path", MB_OK);
CoTaskMemFree(pszFilePath);
}
pItem->Release();
}
}
pFileOpen->Release();
}
CoUninitialize();
}
}
void putImage(HDC hdc, HWND hWnd)
{
Graphics graphic(hdc);
Image* image = Image::FromFile(filePath);
Status status = graphic.DrawImage(image, 10, 20);
RECT updateRect = { 0 };
updateRect.left = 10;
updateRect.top = 10;
updateRect.right = updateRect.left + image->GetWidth();
updateRect.bottom = updateRect.top + image->GetHeight();
//RedrawWindow(hWnd, &updateRect, NULL, RDW_INVALIDATE);
//RedrawWindow(hWnd, NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW);
}
std::wstring s2ws(const std::string& s)
{
int len;
int slength = (int)s.length() + 1;
len = MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, 0, 0);
wchar_t* buf = new wchar_t[len];
MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, buf, len);
std::wstring r(buf);
delete[] buf;
return r;
}
推荐阅读
- stata - 如何在我的数据集中列出负值?
- ios - 没有名为“UIUserActivityRestoring”的类型或协议
- c# - .NET 的 Equals 方法的真正含义是什么?
- elasticsearch - 如何使用elasticsearch进行包含/喜欢查询?
- php - 如何使用 php 解析和创建 JSON 元组
- java - 测量 JVM 上的算法执行时间。
- excel - 输入框作为下拉列表(组合框)
- javascript - 在特定元素中向下滚动
- wcf - 大文件传输时 WCF 内存泄漏
- linkedin - LinkedIn JavaScript SDK“您必须指定一个有效的 JavaScript API 域作为此密钥配置的一部分。”