Studio one and DnD


#1

Hi Guys,

When DnD a file from Studio One media browser to my plugin, file DnD is not detected.
It’s related to updateFileList in juce_win32_windowing.cpp
which first check text data flavor then file and in that case text is valid but empty while file is valid as well.

By modifying juce code to the following code, it will work fine.
Although I’m not very satisfied. What would be the correct fix in your opinion ?

 if (SUCCEEDED (textData.error) && !SUCCEEDED(fileData.error))
            {
                ownerInfo->dragInfo.text = String (CharPointer_UTF16 ((const WCHAR*) textData.data),
                                                   CharPointer_UTF16 ((const WCHAR*) addBytesToPointer (textData.data, textData.dataSize)));
            }
            else
            {
                if (SUCCEEDED(fileData.error))
                {
                    const LPDROPFILES dropFiles = static_cast<const LPDROPFILES> (fileData.data);
                    const void* const names = addBytesToPointer (dropFiles, sizeof (DROPFILES));
                    if (dropFiles->fWide)
                        ownerInfo->parseFileList (static_cast<const WCHAR*> (names), fileData.dataSize);
                    else
                        ownerInfo->parseFileList (static_cast<const char*>  (names), fileData.dataSize);
                }
                else
                {
                    return fileData.error;
                }
            }

#2

Maybe something along

HRESULT updateFileList (IDataObject* const dataObject)
{
if (ownerInfo == nullptr)
return S_FALSE;

        ownerInfo->dragInfo.clear();
        DroppedData textData (dataObject, CF_UNICODETEXT);
        if (SUCCEEDED (textData.error))
        {
            ownerInfo->dragInfo.text = String (CharPointer_UTF16 ((const WCHAR*) textData.data),
                                               CharPointer_UTF16 ((const WCHAR*) addBytesToPointer (textData.data, textData.dataSize)));
        }
        DroppedData fileData(dataObject, CF_HDROP);
        if (SUCCEEDED(fileData.error))
        {
          const LPDROPFILES dropFiles = static_cast<const LPDROPFILES> (fileData.data);
          const void* const names = addBytesToPointer(dropFiles, sizeof(DROPFILES));
          if (dropFiles->fWide)
            ownerInfo->parseFileList(static_cast<const WCHAR*> (names), fileData.dataSize);
          else
            ownerInfo->parseFileList(static_cast<const char*>  (names), fileData.dataSize);
        }
        else
        {
          return fileData.error;
        }
        return S_OK;
    }

#3

Hmm. I guess it’d be fair to check for files first and then fall back to text, e.g.

        ownerInfo->dragInfo.clear();

        DroppedData fileData (dataObject, CF_HDROP);

        if (SUCCEEDED (fileData.error))
        {
            const LPDROPFILES dropFiles = static_cast<const LPDROPFILES> (fileData.data);
            const void* const names = addBytesToPointer (dropFiles, sizeof (DROPFILES));

            if (dropFiles->fWide)
                ownerInfo->parseFileList (static_cast<const WCHAR*> (names), fileData.dataSize);
            else
                ownerInfo->parseFileList (static_cast<const char*>  (names), fileData.dataSize);

            return S_OK;
        }

        DroppedData textData (dataObject, CF_UNICODETEXT);

        if (SUCCEEDED (textData.error))
        {
            ownerInfo->dragInfo.text = String (CharPointer_UTF16 ((const WCHAR*) textData.data),
                                               CharPointer_UTF16 ((const WCHAR*) addBytesToPointer (textData.data, textData.dataSize)));

            return S_OK;
        }

        return textData.error;

…anyone see any drawbacks with that approach?