Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: (SOLVED)My implementation of dragndrop files for window is not working at all.  (Read 2536 times)

0 Members and 1 Guest are viewing this topic.

Me-Myself-And-I

  • Jr. Member
  • **
  • Posts: 93
    • View Profile
Hello. I'm trying to implement dragndrop files functionality into my sf::window for windows 11 using the window handle and WINAPI. So far I have this but it doesn't do anything. The window shows it allows dragndrop but it doesn't receive any path to the dropped files.

int main(int argc,char* argv[])
{
       
               
       
       
        IntRect workarea;
        workarea=getWorkArea();
        RenderWindow window(VideoMode(workarea.width,workarea.height),"Desk Engine",Style::None);
        window.setPosition(Vector2i(0,0));     
       
        //Set SFML to allow dragNdrop and hide from taskbar.
        WindowHandle handle = window.getSystemHandle();
        SetWindowLongPtrA(handle,GWL_EXSTYLE,WS_EX_ACCEPTFILES|WS_EX_TOOLWINDOW);

        DragAcceptFiles(handle, TRUE);
       
        while(window.isOpen())
        {
               
                Event e;
                while(window.pollEvent(e))
                {
                        if(e.type==Event::Closed)
                                window.close();
                }
               
                //Handle DRAG and DROP
                MSG msg;
        while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
        {
            if (msg.message == WM_DROPFILES)
            {
                HDROP hDrop = (HDROP)msg.wParam;
                char filePath[MAX_PATH];
                DragQueryFileA(hDrop, 0, filePath, MAX_PATH);
                DragFinish(hDrop);
                cout << filePath << endl;
            }
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
       
        //render stuff
}
 
Thanks in advance!
« Last Edit: September 12, 2024, 04:14:35 am by Me-Myself-And-I »

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11027
    • View Profile
    • development blog
    • Email
Re: My implementation of dragndrop files for window is not working at all.
« Reply #1 on: September 10, 2024, 07:55:13 am »
You're passing NULL has the window handle, so there's no connection between the window an the inserted event pump.
SFML already implements an event pump, so you can't just write another one next to it, but you'll have to insert your own callback for event processing like this:

#include <SFML/Graphics.hpp>
#include <Windows.h>

LONG_PTR SfmlEventCallback = 0x0;

LRESULT CALLBACK CustomEventCallback(HWND handle, UINT message, WPARAM wParam, LPARAM lParam)
{
    if (message == WM_MENU...)
    {
        // Your event handling
    }

    return CallWindowProcW(reinterpret_cast<WNDPROC>(SfmlEventCallback), handle, message, wParam, lParam);
}

int main()
{
    auto app = sf::RenderWindow{ { 640u, 480u }, "Custom Event Handling" };
    HWND handle = app.getSystemHandle();

    SfmlEventCallback = SetWindowLongPtrW(handle, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(CustomEventCallback));

    while (app.isOpen())
    {
        for (auto event = sf::Event{}; app.pollEvent(event);)
        {
            if (event.type == sf::Event::Closed)
            {
                app.close();
            }
        }

        app.clear();
        app.display();
    }
}
 

And here's some code from FRex for a custom file drop handling:

#include <SFML/Window.hpp>
#include <iostream>
#include <Windows.h>

LONG_PTR originalsfmlcallback = 0x0;

LRESULT CALLBACK mycallback(HWND handle, UINT message, WPARAM wParam, LPARAM lParam)
{
    if(message == WM_DROPFILES)
    {
        HDROP hdrop = reinterpret_cast<HDROP>(wParam);
        POINT p;
        p.x = 0;
        p.y = 0;
        if(DragQueryPoint(hdrop, &p))
            std::printf("Point is %d, %d\n", p.x, p.y);
        else
            std::cout << "Failed to get point" << std::endl;

        const UINT filescount = DragQueryFile(hdrop, 0xFFFFFFFF, NULL, 0);
        for(UINT i = 0; i < filescount; ++i)
        {
            const UINT bufsize = DragQueryFile(hdrop, i, NULL, 0);
            std::wstring str;
            str.resize(bufsize + 1);
            if(DragQueryFile(hdrop, i, &str[0], bufsize + 1))
            {
                std::string stdstr;
                sf::Utf8::fromWide(str.begin(), str.end(), std::back_inserter(stdstr));
                std::cout << stdstr << std::endl;
            }
        }
        DragFinish(hdrop);
        std::cout << "-------------" << std::endl;
    }//if WM_DROPFILES
    return CallWindowProcW(reinterpret_cast<WNDPROC>(originalsfmlcallback), handle, message, wParam, lParam);
}

int main(int argc, char ** argv)
{
    sf::Window app(sf::VideoMode(640u, 480u), "Drag and Drop from USERLAND");
    HWND handle = app.getSystemHandle();

    DragAcceptFiles(handle, TRUE);
    originalsfmlcallback = SetWindowLongPtrW(handle, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(mycallback));

    while(app.isOpen())
    {
        sf::Event eve;
        while(app.pollEvent(eve))
        {
            if(eve.type == sf::Event::Closed)
                app.close();

        }//while app poll event eve
        app.display();
    }//while app is open
}
 
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Me-Myself-And-I

  • Jr. Member
  • **
  • Posts: 93
    • View Profile
Re: My implementation of dragndrop files for window is not working at all.
« Reply #2 on: September 10, 2024, 11:28:37 pm »
Thankyou so much! :D This is just what i've been looking for.
btw the function DragQueryFile didn't work for me with the third parameter being wstring. I changed it to char fPath(MAX_PATH); and that worked. I don't know if thats better or worse but I just thought i'd mention the aforementioned wstring didn't work for me. Thanks again for your help. ;D