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

Author Topic: SFML Win32 - Messages (ie: Scrollbars)  (Read 3865 times)

0 Members and 1 Guest are viewing this topic.

Grimlen

  • Newbie
  • *
  • Posts: 29
    • View Profile
    • Email
SFML Win32 - Messages (ie: Scrollbars)
« on: October 04, 2013, 08:52:41 am »
I'm trying to setup scrollbars in a simple SFML window.
The main reason why I need scrollbars is I'm trying to make a simple wave editor using
the sound functions in SFML. The scrollbars will be used for scrolling through the wave (hscrolling) and also
zooming in on it (vscrolling).

However I'm having trouble just even getting simple events like: WM_CREATE to popup once I've
created a window. I'm also confused how to integrate win32 into SFML becaue of how it's setup.
There's no wndproc callback now...so how does it know which window is getting a callback?

Anyways here's my code, maybe someone can tell me how to get a simple WM_CREATE event working:
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Graphics.hpp>
#include <windows.h>
#include <cmath>

HWND button;


////////////////////////////////////////////////////////////
/// Function called whenever one of our windows receives a message
///
////////////////////////////////////////////////////////////
LRESULT CALLBACK onEvent(HWND handle, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
        // Quit when we close the main window
        case WM_CLOSE :
        {
            PostQuitMessage(0);
            return 0;
        }

        // Quit when we click the "quit" button
        case WM_COMMAND :
        {
            if (reinterpret_cast<HWND>(lParam) == button)
            {
                PostQuitMessage(0);
                return 0;
            }
        }
    }

    return DefWindowProc(handle, message, wParam, lParam);
}


////////////////////////////////////////////////////////////
/// Entry point of application
///
/// \param Instance : Instance of the application
///
/// \return Error code
///
////////////////////////////////////////////////////////////
INT WINAPI WinMain(HINSTANCE instance, HINSTANCE, LPSTR, INT)
{
    // Define a class for our main window
    WNDCLASS windowClass;
    windowClass.style         = 0;
    windowClass.lpfnWndProc   = &onEvent;
    windowClass.cbClsExtra    = 0;
    windowClass.cbWndExtra    = 0;
    windowClass.hInstance     = instance;
    windowClass.hIcon         = NULL;
    windowClass.hCursor       = 0;
    windowClass.hbrBackground = reinterpret_cast<HBRUSH>(COLOR_BACKGROUND);
    windowClass.lpszMenuName  = NULL;
    windowClass.lpszClassName = TEXT("Test");
    RegisterClass(&windowClass);

    // Main Window
    HWND window = CreateWindow(TEXT("Test"), TEXT("SFML Win32"), WS_SYSMENU | WS_VISIBLE | WS_HSCROLL | WS_VSCROLL, 200, 200, 660, 520, NULL, NULL, instance, NULL);

    // Add a button for exiting
    button = CreateWindow(TEXT("BUTTON"), TEXT("Quit"), WS_CHILD | WS_VISIBLE, 560, 440, 80, 40, window, NULL, instance, NULL);

    // Let's create two SFML views
    /*
        HWND view1 = CreateWindow(TEXT("STATIC"), NULL, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS, 20,  20, 300, 400, window, NULL, instance, NULL);
    HWND view2 = CreateWindow(TEXT("STATIC"), NULL, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS, 340, 20, 300, 400, window, NULL, instance, NULL);
    sf::RenderWindow SFMLView1(view1);
    sf::RenderWindow SFMLView2(view2);
        */

    // Create a clock for measuring elapsed time
    sf::Clock clock;

    // Loop until a WM_QUIT message is received
    MSG message;
    message.message = static_cast<UINT>(~WM_QUIT);
    while (message.message != WM_QUIT)
    {
        if (PeekMessage(&message, NULL, 0, 0, PM_REMOVE))
        {
            // If a message was waiting in the message queue, process it
            TranslateMessage(&message);
                        switch(message.message){
                        case WM_CREATE:
                                MessageBox(window, TEXT("MESSAGE"), TEXT("Hello"), 0);
                                break;
                        }
            DispatchMessage(&message);
        }
        else
        {
            float time = clock.getElapsedTime().asSeconds();

            // Clear views
            /*
                        SFMLView1.clear();
            SFMLView2.clear();


            // Display each view on screen
            SFMLView1.display();
            SFMLView2.display();
                        */

        }
    }

    // Destroy the main window (all its child controls will be destroyed)
    DestroyWindow(window);

    // Don't forget to unregister the window class
    UnregisterClass(TEXT("Test"), instance);

    return EXIT_SUCCESS;
}
 

Grimlen

  • Newbie
  • *
  • Posts: 29
    • View Profile
    • Email
Re: SFML Win32 - Messages (ie: Scrollbars)
« Reply #1 on: October 04, 2013, 06:35:46 pm »
Got it working.
Clearly I didn't realize I had a "WndProc" all ready in the code.

However I have another question.

Now I'm trying to display a sprite (knight.png) in my main win32 window.
I achieved this. However, for some reason:
1) The background is black and not default gray
2) When I scroll with my scrollbars, the background changes to gray and erases my sprite while scrolling, and puts the background color back to black and draws my sprite again after I stop scrolling.

Here's my updated code with drawing a sprite in a Win32 window:
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Graphics.hpp>
#include <windows.h>
#include <cmath>


HWND button;


////////////////////////////////////////////////////////////
/// Function called whenever one of our windows receives a message
///
////////////////////////////////////////////////////////////
LRESULT CALLBACK onEvent(HWND handle, UINT message, WPARAM wParam, LPARAM lParam)
{
        SCROLLINFO si;

        RECT clientRect;
        GetClientRect(handle, &clientRect);
        int iVertPos, iHorzPos;

    switch (message)
    {
                case WM_CREATE:
                MessageBox(handle, TEXT("MESSAGE"), TEXT("Hello"), 0);
                break;

                case WM_HSCROLL:
                        si.cbSize = sizeof(si);
                        si.fMask = SIF_ALL;

                        GetScrollInfo(handle, SB_HORZ, &si);
                        iHorzPos = si.nPos;

                        switch (LOWORD(wParam))
                        {
                        case SB_LINELEFT:
                                si.nPos -=1;
                                break;

                        case SB_LINERIGHT:
                                si.nPos += 1;
                                break;

                        case SB_PAGELEFT:
                                si.nPos -= si.nPage;
                                break;

                        case SB_PAGERIGHT:
                                si.nPos += si.nPage;
                                break;
                       
                        case SB_THUMBTRACK:
                                si.nPos = si.nTrackPos;
                                break;
                       

                        default:
                                break;
                        }

                        si.fMask = SIF_POS;
                        SetScrollInfo(handle, SB_HORZ, &si, TRUE);
                        GetScrollInfo(handle, SB_HORZ, &si);

                        if (si.nPos != iHorzPos)
                        {
                                InvalidateRect(handle, &clientRect, TRUE);
                                UpdateWindow(handle);
                        }
                        return 0;
         case WM_VSCROLL:
                        si.cbSize = sizeof(si);
                        si.fMask = SIF_ALL;
                        GetScrollInfo(handle, SB_VERT, &si);
                        iVertPos = si.nPos;
                        switch(LOWORD(wParam)){
                                case SB_TOP:
                                        si.nPos = si.nMin;
                                        break;

                                case SB_BOTTOM:
                                        si.nPos = si.nMax;
                                        break;

                                case SB_LINEUP:
                                        si.nPos--;
                                        break;

                                case SB_LINEDOWN:
                                        si.nPos++;
                                        break;

                                case SB_PAGEUP:
                                        si.nPos -= si.nPage;
                                        break;

                                case SB_PAGEDOWN:
                                        si.nPos += si.nPage;
                                        break;

                                case SB_THUMBTRACK:
                                        si.nPos = si.nTrackPos;
                                        break;

                                default:
                                        break;
                                }

                si.fMask = SIF_POS;
                SetScrollInfo(handle, SB_VERT, &si, TRUE);
                GetScrollInfo(handle, SB_VERT, &si);
                if(iVertPos != si.nPos){
                        InvalidateRect(handle, &clientRect, TRUE);
                        UpdateWindow(handle);
                }
                return 0;
        // Quit when we close the main window
        case WM_CLOSE :
        {
            PostQuitMessage(0);
            return 0;
        }

        // Quit when we click the "quit" button
        case WM_COMMAND :
        {
            if (reinterpret_cast<HWND>(lParam) == button)
            {
                PostQuitMessage(0);
                return 0;
            }
        }
    }

    return DefWindowProc(handle, message, wParam, lParam);
}

LRESULT CALLBACK freqEvent(HWND handle, UINT message, WPARAM wParam, LPARAM lParam){
        switch(message){
        case WM_CREATE:

                break;
        }
        return DefWindowProc(handle, message, wParam, lParam);
}


////////////////////////////////////////////////////////////
/// Entry point of application
///
/// \param Instance : Instance of the application
///
/// \return Error code
///
////////////////////////////////////////////////////////////
INT WINAPI WinMain(HINSTANCE instance, HINSTANCE, LPSTR, INT)
{
    // Define a class for our main window
    WNDCLASS windowClass;
    windowClass.style         = 0;
    windowClass.lpfnWndProc   = &onEvent;
    windowClass.cbClsExtra    = 0;
    windowClass.cbWndExtra    = 0;
    windowClass.hInstance     = instance;
    windowClass.hIcon         = NULL;
    windowClass.hCursor       = 0;
    windowClass.hbrBackground = reinterpret_cast<HBRUSH>(COLOR_BACKGROUND);
    windowClass.lpszMenuName  = NULL;
    windowClass.lpszClassName = TEXT("Main");
    RegisterClass(&windowClass);

    // Define a class for our frequency window
    WNDCLASS freqClass;
    freqClass.style         = 0;
    freqClass.lpfnWndProc   = &freqEvent;
    freqClass.cbClsExtra    = 0;
    freqClass.cbWndExtra    = 0;
    freqClass.hInstance     = instance;
    freqClass.hIcon         = NULL;
    freqClass.hCursor       = 0;
    freqClass.hbrBackground = reinterpret_cast<HBRUSH>(COLOR_BACKGROUND);
    freqClass.lpszMenuName  = NULL;
    freqClass.lpszClassName = TEXT("Freq");
    RegisterClass(&freqClass);

        sf::Texture texture;
        if (!texture.loadFromFile("knight.png"))
        {
                // error...
        }
        sf::Sprite sprite;
        sprite.setTexture(texture);

    // Main Window
    HWND window = CreateWindow(TEXT("Main"), TEXT("Sound Editor"), WS_SYSMENU | WS_VISIBLE | WS_HSCROLL | WS_VSCROLL, 200, 200, 660, 520, NULL, NULL, instance, NULL);
        //Frequency Window
        HWND freqWnd = CreateWindow(TEXT("Freq"), TEXT("Frequency"), WS_SYSMENU | WS_VISIBLE, 200, 200, 660, 520, NULL, NULL, instance, NULL);
    // Add a button for exiting
    button = CreateWindow(TEXT("BUTTON"), TEXT("Quit"), WS_CHILD | WS_VISIBLE, 560, 440, 80, 40, window, NULL, instance, NULL);

        sf::RenderWindow SFMLViewMain(window);

    // Let's create two SFML views
    /*
        HWND view1 = CreateWindow(TEXT("STATIC"), NULL, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS, 20,  20, 300, 400, window, NULL, instance, NULL);
    HWND view2 = CreateWindow(TEXT("STATIC"), NULL, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS, 340, 20, 300, 400, window, NULL, instance, NULL);
    sf::RenderWindow SFMLView1(view1);
    sf::RenderWindow SFMLView2(view2);
        */

    // Create a clock for measuring elapsed time
    sf::Clock clock;

    // Loop until a WM_QUIT message is received
    MSG message;
    message.message = static_cast<UINT>(~WM_QUIT);
    while (message.message != WM_QUIT)
    {
        if (PeekMessage(&message, NULL, 0, 0, PM_REMOVE))
        {
            // If a message was waiting in the message queue, process it
            TranslateMessage(&message);
            DispatchMessage(&message);
        }
        else
        {
            float time = clock.getElapsedTime().asSeconds();
                        SFMLViewMain.clear();
                        SFMLViewMain.draw(sprite);
                        SFMLViewMain.display();
                       
            // Clear views
            /*
                        SFMLView1.clear();
            SFMLView2.clear();


            // Display each view on screen
            SFMLView1.display();
            SFMLView2.display();
                        */

        }
    }

    // Destroy the main window (all its child controls will be destroyed)
    DestroyWindow(window);
        DestroyWindow(freqWnd);

    // Don't forget to unregister the window class
    UnregisterClass(TEXT("Main"), instance);
        UnregisterClass(TEXT("Freq"), instance);
    return EXIT_SUCCESS;
}
 
« Last Edit: October 04, 2013, 07:14:46 pm by Grimlen »

Ixrec

  • Hero Member
  • *****
  • Posts: 1241
    • View Profile
    • Email
Re: SFML Win32 - Messages (ie: Scrollbars)
« Reply #2 on: October 04, 2013, 10:16:15 pm »
I know nothing about the Win32 API but I happen to know something about SFML that might answer your first question.

The prototype for sf::RenderWindow.clear() is:
Quote
void    clear (const Color &color=Color(0, 0, 0, 255))

That means that clear() with no arguments defaults to using the color black when it clears the screen.  So try giving it an explicit color argument if you want it to be some other color.

Grimlen

  • Newbie
  • *
  • Posts: 29
    • View Profile
    • Email
Re: SFML Win32 - Messages (ie: Scrollbars)
« Reply #3 on: October 05, 2013, 03:16:09 am »
Well I even got rid of the clear() this time and it's still black.
But the main problem I'm having is the scrollbar, when I move it, the drawing + black background goes away.
When I stop moving the scrollbar, it goes back to normal (draws the sprite and the black background).

How do I get it to stop getting rid of the sprite when I move the scrollbars?