0

DirectX 11 プロジェクトで DDS ファイルを開こうとしていますが、ほとんどの場合、開くことができません。失敗するたびに E_ACCESSDENIED エラーが発生します。動作させる唯一の方法は、現在のディレクトリまたはサブディレクトリへの相対パスを配置することです。親ディレクトリへの相対パスの場合、または絶対パスの場合、関数は失敗します。

問題は、FileOpenPicker を使用して画像を開きたいということです。そのため、どの場合でも絶対パスを取得します...

私は自分の機能を共有します:

void Element::FileOpenDialog()
{
    FileOpenPicker^ fileOpenPicker = ref new FileOpenPicker();
    fileOpenPicker->ViewMode = PickerViewMode::Thumbnail;
    fileOpenPicker->SuggestedStartLocation = PickerLocationId::PicturesLibrary;
    fileOpenPicker->CommitButtonText = "Load";
    fileOpenPicker->FileTypeFilter->Append(".dds");
    create_task(fileOpenPicker->PickSingleFileAsync()).then([this](StorageFile^ file)
    {
        if (file)
        {
            m_fullPath = const_cast<wchar_t*>(file->Path->Data());
            wcout << m_fullPath  << endl; // prints the correct path of the selected file

            m_loadedImage = false;
        }
        m_choseImage = true; // Checking in another code if the user chose an image to load.
    });
}

そして、関数を呼び出してテクスチャをロードします...

bool Texture::LoadFile(wchar_t* path, GameWindow^ gameWindow)
{
    m_gameWindow = gameWindow;
    ComPtr<ID3D11Resource> resource = nullptr;
    if (!FH::ThrowIfFailed(CreateDDSTextureFromFile(m_gameWindow->dev.Get(), L"texture.dds", resource.GetAddressOf(), m_texture.ReleaseAndGetAddressOf()))) return false; // Works
    if (!FH::ThrowIfFailed(CreateDDSTextureFromFile(m_gameWindow->dev.Get(), L"texture\\texture.dds", resource.GetAddressOf(), m_texture.ReleaseAndGetAddressOf()))) return false; // Works
    if (!FH::ThrowIfFailed(CreateDDSTextureFromFile(m_gameWindow->dev.Get(), L"..\\texture.dds", resource.GetAddressOf(), m_texture.ReleaseAndGetAddressOf()))) return false; // E_ACCESSDENIED
    if (!FH::ThrowIfFailed(CreateDDSTextureFromFile(m_gameWindow->dev.Get(), path, resource.GetAddressOf(), m_texture.ReleaseAndGetAddressOf()))) return false; // E_ACCESSDENIED
    return true;
}

ええと、理由がわからないので、あなたの助けを求めるためにここに来ました.

どうもありがとうございました!

4

1 に答える 1

1

UWP アプリケーションには、ファイル ピッカーが選択している場所への直接のファイル アクセスはありません。これFileOpenPickerは、ユーザーに代わって行うブローカーですが、標準のファイル I/O は使用できず、WinRT API のみを使用できます。選択されたファイルは、ローカル ファイル システム上にさえない場合があることに注意してください。直接 I/O アクセスできる唯一のファイルの場所は、インストールされたフォルダー (読み取り専用)、一時フォルダー (読み取り/書き込み)、およびアプリケーション データ フォルダー (読み取り/書き込み) です。

詳細については、MSDN の「ファイル アクセスとアクセス許可 (Windows ランタイム アプリ) 」を参照してください。

解決策は、選択した仲介ファイルを、アクセスできる一時ファイルの場所にCreateDDSTextureFromFileコピーしてから、一時コピーで使用することです。

#include <ppltasks.h>
using namespace concurrency;

using Windows::Storage;
using Windows::Storage::Pickers;

create_task(openPicker->PickSingleFileAsync()).then([](StorageFile^ file)
{
    if (file)
    {
        auto tempFolder = Windows::Storage::ApplicationData::Current->TemporaryFolder;
        create_task(file->CopyAsync(tempFolder, file->Name, NameCollisionOption::GenerateUniqueName)).then([](StorageFile^ tempFile)
        {
            if (tempFile)
            {
                HRESULT hr = CreateDDSTextureFromFile(..., tempFile->Path->Data(), ...);
                DeleteFile(tempFile->Path->Data());
                DX::ThrowIfFailed(hr);
            }
        });
    });

これについては、DirectX Tool Kit wikiで詳細に説明されており、書き込みケースもそこで説明されています。

于 2016-03-24T05:14:41.673 に答える