0

I'm trying to get files path through the drag and drop functionality offered by the windows.h header but I encounter a problem when I want to encapsulate my code inside a class :

Work correctly :

LONG_PTR originalsfmlcallback;

LRESULT CALLBACK callback(HWND handle, UINT message, WPARAM wParam, LPARAM lParam)
{
    if(message == WM_DROPFILES)
    {
        HDROP hdrop = reinterpret_cast<HDROP>(wParam);
        WORD a = 0;

        POINT p;
        p.x = 0;
        p.y = 0;

        if(DragQueryPoint(hdrop, &p))
        {
            auto size = DragQueryFile(hdrop, a, (LPSTR) NULL, 0);
            char fichier[size+1];
            DragQueryFile(hdrop, a, fichier, sizeof(fichier));
            std::cout << "FILE : [" << size << "] " << fichier << std::endl;
        }
        else
        {
            std::cout << "Failed to get point" << std::endl;
        }

        DragFinish(hdrop);
    }

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

int main()
{
    const int w = 1000;
    const int h = 800;
    sf::RenderWindow window(sf::VideoMode(w, h), "SFML window");

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

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

        window.clear();
        //...draw something
        window.display();
    }

    return EXIT_SUCCESS;
}

Get error :

class Dragger
{
    Dragger(HWND handle)
    {
        DragAcceptFiles(handle, TRUE);
        originalsfmlcallback = SetWindowLongPtrW(handle, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(callback)); //HERE THE ERROR : Reference to non-static...
    }

private:

    LRESULT CALLBACK callback(HWND handle, UINT message, WPARAM wParam, LPARAM lParam)
    {
        if(message == WM_DROPFILES)
        {
            HDROP hdrop = reinterpret_cast<HDROP>(wParam);
            WORD a = 0;

            POINT p;
            p.x = 0;
            p.y = 0;

            if(DragQueryPoint(hdrop, &p))
            {
                auto size = DragQueryFile(hdrop, a, (LPSTR) NULL, 0);
                char fichier[size+1];
                DragQueryFile(hdrop, a, fichier, sizeof(fichier));
                std::cout << "FILE : [" << size << "] " << fichier << std::endl;
            }
            else
            {
                std::cout << "Failed to get point" << std::endl;
            }

            DragFinish(hdrop);
        }

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

private:

    LONG_PTR originalsfmlcallback;

};


int main()
{
    const int w = 1000;
    const int h = 800;
    sf::RenderWindow window(sf::VideoMode(w, h), "SFML window");

    Dragger dragger(window.getSystemHandle());

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

        window.clear();
        //...draw something
        window.display();
    }

    return EXIT_SUCCESS;
}

I am not an expert in c++ and even less in winapi, there are certain features that I have difficulty understanding, such as preprocessor directives or macros. Thank you for your help !

Al Tilmidh
  • 33
  • 5
  • 1
    Are you having difficulty understanding the error message? If so, it would help if we could see the message that you are having trouble understanding. I suspect it involves `SetWindowLongPtrW` expecting a _function pointer_ and not a pointer-to-class-member. – Drew Dormann Jun 15 '22 at 18:10
  • @DrewDormann yes, that's the source of the problem `reference to non-static member function must be called` – Al Tilmidh Jun 15 '22 at 18:18
  • Also, note that using `SetWindowLongPtr(GWLP_WNDPROC)` is the *old* way to subclass a window. You *should* use `SetWindowSubclass()` instead. See [Subclassing Controls](https://learn.microsoft.com/en-us/windows/win32/controls/subclassing-overview) and [Safer subclassing](https://devblogs.microsoft.com/oldnewthing/20031111-00/?p=41883) – Remy Lebeau Jun 15 '22 at 19:59

0 Answers0