Member 12899279 Ответов: 2

Как открыть изображение из ресурсов в photoviewer на языке C++?


я хочу открыть картинку в формате Jpg, bmp или gif
я добавил его к ресурсу, чтобы он был привязан к exe-файлу и не был взят с жесткого диска клиента, который запускает exe-файл
теперь то, что я хочу сделать, это открыть эту картинку и отобразить ее в photoviewer окна os
мой код c++ сделан на пустом проекте с многобайтовым набором символов.
Ниже приведено то, что я получил из сети, но у него есть несколько проблем, таких как, прежде всего, его в UNICODE
затем он использует жесткое кодирование для путей, таких как его использование
WCHAR wsParameters[MAX_PATH] = L"\"C:\\Program Files\\Windows Photo Viewer\\PhotoViewer.dll\" ImageView_Fullscreen ";
это не обязательно, что каждая ОС будет находиться в диске C
тогда на этой линии
WCHAR wsFile[MAX_PATH] = L"E:\\Temp\\test.jpg";

он хранит файл на жестком диске клиента, чего я не хочу делать
поэтому любой suggesstions??

Что я уже пробовал:

void SaveIStreamToFile(IStream *pIStream, LPWSTR pwsFile)
{
	HANDLE hFile;
	LPVOID pv = NULL;
	LARGE_INTEGER li;
	DWORD  nNbBytesWritten;
	ULONG  nNbBytes;
	HRESULT hr;
	int nBufferSize = 4096;

	hFile = CreateFile(pwsFile, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
	if (hFile != INVALID_HANDLE_VALUE)
	{
		pv = (LPSTR)LocalAlloc(LPTR, nBufferSize);
		if (pv)
		{
			LISet32(li, 0);
			pIStream->Seek(li, STREAM_SEEK_SET, NULL);
			do
			{
				hr = pIStream->Read(pv, nBufferSize, &nNbBytes);
				if (SUCCEEDED(hr))
				{
					if (!WriteFile(hFile, pv, nNbBytes, &nNbBytesWritten, NULL))
						hr = E_FAIL;
				}
			} while ((SUCCEEDED(hr)) && (nNbBytes == nBufferSize));
			LocalFree(pv);
		}
		CloseHandle(hFile);
	}
	return;
}
int main()
{
	HRESULT(STDAPICALLTYPE * pSHCreateStreamOnDllResourceW)(PCWSTR pwszDll, PCWSTR pwszName, PCWSTR pwszType, IStream** ppstm);
	HMODULE hInst = LoadLibrary(L"SHLWAPI.DLL");
	if (hInst)
	{
		(FARPROC&)pSHCreateStreamOnDllResourceW = GetProcAddress(hInst, (LPCSTR)MAKEINTRESOURCE(627));
		IStream *pstm;
		if (pSHCreateStreamOnDllResourceW)
		{
			WCHAR wszPath[MAX_PATH];
			GetModuleFileNameW(NULL, wszPath, MAX_PATH);
			HRESULT hr = pSHCreateStreamOnDllResourceW(wszPath, (LPWSTR)MAKEINTRESOURCE(IDR_JPEG1), L"JPEG", &pstm);
			WCHAR wsFile[MAX_PATH] = L"E:\\Temp\\test.jpg";
			SaveIStreamToFile(pstm, wsFile);

			WCHAR wsParameters[MAX_PATH] = L"\"C:\\Program Files\\Windows Photo Viewer\\PhotoViewer.dll\" ImageView_Fullscreen ";
			lstrcat(wsParameters, wsFile);
			WCHAR wsProgram[MAX_PATH] = L"rundll32.exe";
			SHELLEXECUTEINFO sei;
			ZeroMemory(&sei, sizeof(SHELLEXECUTEINFO));
			sei.cbSize = sizeof(SHELLEXECUTEINFO);
			sei.fMask = SEE_MASK_NOASYNC | SEE_MASK_NOCLOSEPROCESS;
			sei.hwnd = NULL;
			sei.lpVerb = L"open";
			sei.lpFile = wsProgram;
			sei.lpParameters = wsParameters;
			sei.nShow = SW_SHOWNORMAL;
			BOOL bReturn = ShellExecuteEx(&sei);
		}
	}
}

Richard MacCutchan

Вы никогда не должны жестко кодировать пути к файлам в своих приложениях. Если вы хотите получить доступ к файлу, то используйте один из классов FileDialog, который позволяет пользователю выбрать его.

2 Ответов

Рейтинг:
2

Dave Kreskowiak

Насколько я могу судить, у вас нет другого выбора, кроме как записать файл, который вы хотите открыть, на диск и открыть его в PhotoViewer оттуда. PhotoViewer не будет открывать изображение из ресурсов.

Единственная альтернатива-написать свой собственный photoviewer в вашем приложении, где вы имеете полный контроль над тем, откуда он получает данные изображения.


Member 12899279

что делать, если я хочу только открыть картинку, не имеет значения, открыта она в photoviewer или нет, но я хочу загружать картинку только из ресурсов, а не с клиентского ПК

Dave Kreskowiak

Внешнее приложение не будет открывать изображение из ресурсов, как это происходит с файлом. Нет такой спецификации пути к файлу, которая работала бы подобным образом.

Рейтинг:
2

Rick York

По-видимому, это решение было бесполезным, поэтому его удалили.


Member 12899279

я сделал эти изменения в коде, но все же он принимает жестко закодированное значение пути, чтобы открыть программу просмотра фотографий с диска C. Есть вероятность, что клиентская ОС может не быть на диске C, тогда этот код сломается.
BOOL CreateTempName(TCHAR* szFileName)
{
TCHAR szTempPath[MAX_PATH];
BOOL bRet = FALSE;
DWORD dwLen = GetTempPath(MAX_PATH, szTempPath);
if (dwLen > 0 && dwLen < MAX_PATH)
{
if (GetTempFileName(szTempPath, TEXT("RES"), 0, szFileName))
Брет = правда;
}
возвращение Брета;
}
void SaveIStreamToFile(IStream *pIStream, LPTSTR pwsFile)
{
Ручка hFile;
LPVOID pv = NULL;
LARGE_INTEGER li;
DWORD nnbbyteswrited;
Тип ulong nNbBytes;
HRESULT hr;
int nBufferSize = 200;

hFile = функция CreateFile(pwsFile, помощью generic_read | помощью generic_write, 0, null, то значению create_always, FILE_ATTRIBUTE_NORMAL, null в);
if (hFile != INVALID_HANDLE_VALUE)
{
pv = (LPSTR)LocalAlloc(LPTR, nBufferSize);
если (pv)
{
LISet32(li, 0);
pIStream->Seek(li, STREAM_SEEK_SET, NULL);
делать
{
hr = pIStream->Read(pv, nBufferSize, &nNbBytes);
если (сменил(ч))
{
if (!WriteFile(hFile, pv, nNbBytes, &nnbbyteswrited, NULL))
hr = E_FAIL;
}
} в то время как амп ((удалось(ч)) &;&ампер; (nNbBytes == nBufferSize));
И localfree(ПВ);
}
CloseHandle(hFile);
}
вернуть;
}
void showPic()
{
//Функцией shellexecute(null, то "открыть", "testpic.jpg", нуль, нуль, и sw_shownormal); //'bitmap1.БМП С'имя растрового ресурса
HRESULT(STDAPICALLTYPE * pSHCreateStreamOnDllResourceW)(LPWSTR pwszDll, LPWSTR pwszName, LPWSTR pwszType, IStream** ppstm);
HMODULE hInst = LoadLibrary("SHLWAPI.DLL");
если (hInst)
{
(FARPROC&)pSHCreateStreamOnDllResourceW = GetProcAddress(hInst, (LPCSTR)MAKEINTRESOURCE(627));
IStream *pstm;
if (pSHCreateStreamOnDllResourceW)
{
char szPath[MAX_PATH];
GetModuleFileNameA(NULL, szPath, MAX_PATH);
WCHAR wszWidePath[MAX_PATH];
MultiByteToWideChar(CP_ACP, 0, szPath, -1, wszWidePath, sizeof(wszWidePath));
HRESULT hr = pSHCreateStreamOnDllResourceW(wszWidePath, (LPWSTR)MAKEINTRESOURCE(IDB_PNG1), L"PNG", &pstm);
TCHAR szTempFile[MAX_PATH];
CreateTempName(szTempFile);
//TCHAR wsFile[MAX_PATH] = TEXT("E:\\Temp\\test.jpg");
// C:\Users\CHRIST~1\AppData\Local\Temp\RESD12.tmp
SaveIStreamToFile(pstm, szTempFile);

TCHAR wsParameters[MAX_PATH] = TEXT("\"C:\\Program файлы\\Windows Photo Viewer\\PhotoViewer.dll\" ImageView_Fullscreen ");
lstrcat(wsParameters, szTempFile);
TCHAR wsProgram[MAX_PATH] = TEXT("rundll32.exe");
SHELLEXECUTEINFO sei;
ZeroMemory(&sei, sizeof(SHELLEXECUTEINFO));
sei.cbSize = sizeof(SHELLEXECUTEINFO);
СИЭ.fMask = SEE_MASK_NOASYNC | SEE_MASK_NOCLOSEPROCESS;
сеи.его hwnd = нуль;
sei.lpVerb = текст("открыть");
sei.lpFile = wsProgram;
СИЭ.lpParameters = wsParameters;
СИЭ.nShow = SW_SHOWNORMAL;
BOOL bReturn = ShellExecuteEx(&sei);
}
}

}
тап_п()
{

резьба th2(showPic);
}