Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

[SFML] Błędny event GainedFocus po zmianie pozycji lub rozmiaru okna.

Ostatnio zmodyfikowano 2014-06-25 14:27
Autor Wiadomość
maly
Temat założony przez niniejszego użytkownika
[SFML] Błędny event GainedFocus po zmianie pozycji lub rozmiaru okna.
» 2014-06-24 18:18:50
Niewiem czy to tylko u mnie ale kiedy aplikacja straci fokusa wywoływany jest dodatkowo sf::Event::GainedFocus a przy odzyskaniu fokusa ten event już się nie wywołuje.
C/C++
#include <SFML/Graphics.hpp>
#include <iostream>

int main()
{
    sf::RenderWindow app( sf::VideoMode( 320, 200 ), "SFML window" );
   
    while( app.isOpen() )
    {
        //app.setPosition(app.getPosition());
        app.setSize( app.getSize() );
       
        sf::Event event;
        while( app.pollEvent( event ) )
        {
            if( event.type == sf::Event::Closed )
                 app.close();
            else if( event.type == sf::Event::LostFocus )
                 std::cout << "LostFocus" << std::endl;
            else if( event.type == sf::Event::GainedFocus )
                 std::cout << "GainedFocus" << std::endl;
           
        }
       
        app.clear();
        app.display();
    }
    return 0;
}

Mam wrażenie że w metodach void WindowImplWin32::setPosition(const Vector2i& position) i void WindowImplWin32::setSize(const Vector2u& size) dla funkcji SetWindowPos brakuje flagi SWP_NOACTIVATE.

Pytanie czy ten kod wam działa tak samo źle?
P-112649
DejaVu
» 2014-06-24 18:48:26
SFML ma sporo błędów na poziomie obsługi eventów. Focus nie zadziała Ci również poprawnie, gdy stracisz focusa, a następnie klikniesz na renderowanym oknie, a nie na belce tytułowej okna.
P-112650
maly
Temat założony przez niniejszego użytkownika
» 2014-06-24 18:56:32
Focus nie zadziała Ci również poprawnie, gdy stracisz focusa, a następnie klikniesz na renderowanym oknie, a nie na belce tytułowej okna
To akurat już od jakiegoś czasu jest naprawione, problem w tym że niewiem czy mój problem to bug czy feature;)
P-112651
Monika90
» 2014-06-24 23:05:30
Mam wrażenie że w metodach void WindowImplWin32::setPosition(const Vector2i& position) i void WindowImplWin32::setSize(const Vector2u& size) dla funkcji SetWindowPos brakuje flagi SWP_NOACTIVATE.
Tak, bez tej flagi SetWindowPos wysyła komunikat WM_ACTIVATE, co powoduje wysłanie WM_SETFOCUS, ale czy ta flaga powinna tam być, czy nie to nie wiadomo. Może użytkownicy tej biblioteki oczekują tego, że zmiana pozycji, czy rozmiaru okna aktywuje je.

Bug może być w innym miejscu. Możesz zrobić eksperyment. Usuń z pliku WindowImplWin32.cpp ten kod
C/C++
// Gain focus event
case WM_SETFOCUS:
{
    Event event;
    event.type = Event::GainedFocus;
    pushEvent( event );
    break;
}
zastąp go takim
C/C++
// Gain focus event
case WM_NCACTIVATE:
{
    if( wParam )
    {
        Event event;
        event.type = Event::GainedFocus;
        pushEvent( event );
    }
    break;
}
rekompiluj bibliotekę i sprawdź czy to pomogło
P-112676
maly
Temat założony przez niniejszego użytkownika
» 2014-06-25 07:23:23
Sprawdziłem i rozwiązało by to problem jednak muszę działać na standardowym SFML-u, więc dopóki niewiem czy używane w nim rozwiązanie to świadomy wybór czy nieświadomy błąd zastosuję tymczasowo funkcje.
C/C++
//void WindowImplWin32::setPosition(const Vector2i& position)
void setWindowPositionWin32( const sf::Vector2i & position, const sf::Window & window )
{
    sf::WindowHandle m_handle = window.getSystemHandle();
   
    // - SWP_NOZORDER, + SWP_NOACTIVATE
    SetWindowPos( m_handle, NULL, position.x, position.y, 0, 0, SWP_NOSIZE | SWP_NOACTIVATE );
}

//void WindowImplWin32::setSize(const Vector2u& size)
void setWindowSizeWin32( const sf::Vector2u & size, const sf::Window & window )
{
    sf::WindowHandle m_handle = window.getSystemHandle();
   
    // SetWindowPos wants the total size of the window (including title bar and borders),
    // so we have to compute it
   
    RECT rectangle = { 0, 0, static_cast < long >( size.x ), static_cast < long >( size.y ) };
    AdjustWindowRect( & rectangle, GetWindowLong( m_handle, GWL_STYLE ), false );
    int width = rectangle.right - rectangle.left;
    int height = rectangle.bottom - rectangle.top;
    // - SWP_NOZORDER, + SWP_NOACTIVATE
    SetWindowPos( m_handle, NULL, 0, 0, width, height, SWP_NOMOVE | SWP_NOACTIVATE );
}

Zastanawiam się czy na czymś innym niż Windows SFML też tak się zachowuje.
P-112687
MrPoxipol
» 2014-06-25 08:50:12
Jak działa to możesz wysłać pull requesta. Może Gomila zatwierdzi.
P-112688
Monika90
» 2014-06-25 13:54:42
Można zapytać na tamtejszym forum, czy aktywowanie okna po wywołaniu setSize i setPosition było zamierzeniem twórców SFML, jak nie to niech dodadzą tam SWP_NOACTIVATE. Choć to prawdopodobnie nie rozwiąże wszystkich problemów.

Ale tak w ogóle, to dlaczego autor tematu chce zmieniać rozmiary okna, gdy nie jest ono aktywne?
Nie zmieniaj to nie będzie problemu.


Zastanawiam się czy na czymś innym niż Windows SFML też tak się zachowuje.
Nie wiem, ale prawie na pewno nie. To taka specyfika Windows, okno może być aktywne i mieć fokus, ale nie być na pierwszym planie, wtedy zdarzenia klawiatury trafiają do jakiegoś zupełnie innego okna.
P-112714
maly
Temat założony przez niniejszego użytkownika
» 2014-06-25 14:27:04
dlaczego autor tematu chce zmieniać rozmiary okna, gdy nie jest ono aktywne?
Okno na bieżąco dostosowuje rozmiar do zawartości, wcześniej myślałem o jakimś ScrollBar ale uznałem to za niepotrzebną komplikację.

Można zapytać na tamtejszym forum
O mały włos a bym zapytał ale trochę zmieniłem koncepcję i niepotrzebna mi już informacja o fokusie lub jego braku.

Tak czy siak dzięki za pomoc:)
P-112718
« 1 »
  Strona 1 z 1