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

[CPP] [WinAPI] Dziwny przebieg działania programu

Ostatnio zmodyfikowano 2015-05-17 21:42
Autor Wiadomość
TheReclif
Temat założony przez niniejszego użytkownika
» 2015-03-30 21:47:35
A mógłbyś odpowiedzieć mi na pytanie?:
czym jest uVector?(możliwe, że normalnym Vectorem, ale upewniam się)
P-129600
RazzorFlame
» 2015-03-30 22:34:03
uVectorF - normalny wektor - x, y
uVector3F - x,y,z
uVector4F - x,y,z,w

EDIT:
uVector < int > vWindowSize;
Wtedy jeszcze klasa uVector była szablonem, obecnie zmieniłem trochę konwencję i wygląda to mniej więcej tak:
C/C++
class VectorF
{
public:
    float x, y;
};
class Vector3F
{
public:
    float x, y, z;
};
class Vector4F
{
public:
    float x, y, z, w;
};
Oczywiście jest tam jeszcze dość dużo funkcji, więc nie będe o nich mówił. Kod dotyczący samych wektorów ma jakieś 1200 linii.
P-129604
TheReclif
Temat założony przez niniejszego użytkownika
» 2015-03-31 20:12:53
Mam kolejne pytanie: w abstrakcyjnej klasie okna są dwie funkcje parseMessage, które według mnie są pętlami komunikatów. Czy jest tak, jak myślę? Nie jestem tego pewien i dodatkowo proszę jeszcze o ich treść w klasach dziedziczących po niej. Wystarczy nawet informacja, która wywołuje drugą i jaką funkcję spełniają jej argumenty.
P-129668
RazzorFlame
» 2015-03-31 20:37:09
C/C++
////////////////////////////////////////////////////////////////////////////////////////////////////
void Window::parseMessage( UINT message, WPARAM wParam, LPARAM lParam )
{
    if( getHandle() != GetActiveWindow() && hasFocus() )
    {
        Event ms;
        ms.m_type = Event::WindowLostFocus;
        m_eventList.addEvent( ms );
        checkFocus();
    }
    if( getHandle() == GetActiveWindow() && !hasFocus() )
    {
        Event ms;
        ms.m_type = Event::WindowGainedFocus;
        m_eventList.addEvent( ms );
        checkFocus();
    }
   
    switch( message )
    {
    case WM_CLOSE:
        {
            Event ms;
            ms.m_type = Event::WindowClosed;
            m_eventList.addEvent( ms );
            break;
        }
    case WM_DESTROY:
        {
            PostQuitMessage( 0 );
            break;
        }
    case WM_KEYDOWN:
        {
            Event ms;
            ms.m_type = Event::KeyPressed;
            ms.m_key = Key::WPARAMtoKey( wParam );
            m_eventList.addEvent( ms );
            break;
        }
    case WM_KEYUP:
        {
            Event ms;
            ms.m_type = Event::KeyReleased;
            ms.m_key = Key::WPARAMtoKey( wParam );
            m_eventList.addEvent( ms );
            break;
        }
    case WM_MOUSEMOVE:
        {
            Event ms;
            ms.m_type = Event::MouseMoved;
            ms.m_mousePosition = Mouse::getPosition( * this );
            m_eventList.addEvent( ms );
            break;
        }
    case WM_LBUTTONDOWN:
        {
            Event ms;
            ms.m_type = Event::MouseButtonPressed;
            ms.m_mouseButton = Mouse::Left;
            ms.m_mousePosition = Mouse::getPosition( * this );
            m_eventList.addEvent( ms );
            break;
        }
    case WM_LBUTTONUP:
        {
            Event ms;
            ms.m_type = Event::MouseButtonReleased;
            ms.m_mouseButton = Mouse::Left;
            m_eventList.addEvent( ms );
            break;
        }
    case WM_RBUTTONDOWN:
        {
            Event ms;
            ms.m_type = Event::MouseButtonPressed;
            ms.m_mouseButton = Mouse::Right;
            m_eventList.addEvent( ms );
            break;
        }
    case WM_RBUTTONUP:
        {
            Event ms;
            ms.m_type = Event::MouseButtonReleased;
            ms.m_mouseButton = Mouse::Right;
            ms.m_mousePosition = Mouse::getPosition( * this );
            m_eventList.addEvent( ms );
            break;
        }
    case WM_MBUTTONDOWN:
        {
            Event ms;
            ms.m_type = Event::MouseButtonPressed;
            ms.m_mouseButton = Mouse::Middle;
            ms.m_mousePosition = Mouse::getPosition( * this );
            m_eventList.addEvent( ms );
            break;
        }
    case WM_MOUSEWHEEL:
        {
           
            Event ms;
            ms.m_type = Event::MouseWheelMoved;
            ms.m_mouseWheelDelta = GET_WHEEL_DELTA_WPARAM( wParam ) / 120;
            ms.m_mousePosition = Mouse::getPosition( * this );
            m_eventList.addEvent( ms );
            break;
        }
    case WM_MBUTTONUP:
        {
            Event ms;
            ms.m_type = Event::MouseButtonReleased;
            ms.m_mouseButton = Mouse::Middle;
            ms.m_mousePosition = Mouse::getPosition( * this );
            m_eventList.addEvent( ms );
            break;
        }
    case WM_DROPFILES:
        {
            if( isAcceptingFiles() )
            {
                Event ms;
                ms.m_type = Event::FilesDropped;
                ms.m_mousePosition = Mouse::getPosition( * this );
               
                TCHAR lpszFile[ MAX_PATH ] = { 0 };
                HDROP hDrop =( HDROP ) wParam;
               
                ms.m_filesCount = DragQueryFile( hDrop, 0xFFFFFFFF, NULL, NULL );
                if( ms.m_filesCount > 0 )
                {
                    for( int i = 0; i < ms.m_filesCount; i++ )
                    {
                        lpszFile[ 0 ] = '\0';
                        if( DragQueryFile( hDrop, i, lpszFile, MAX_PATH ) )
                        {
                            ms.m_files.push_back( wstring( lpszFile ) );
                        }
                    }
                }
                DragFinish( hDrop );
                m_eventList.addEvent( ms );
                break;
            }
        }
    case WM_SIZE:
        {
            if( isReachable() )
            {
                // Consider only events triggered by a maximize or a un-maximize
                if( wParam != SIZE_MINIMIZED && !m_resizing && privGetVideoMode() != getVideoMode() )
                {
                    updateVideoMode();
                    if( m_windowType == WindowType::DirectXDevice )
                    {
                        Device * pDevice = dynamic_cast < Device *>( this );
                        if( pDevice->getVideoDriver3D() )
                        {
                            pDevice->getVideoDriver3D()->setVideoMode( m_videoMode );
                            pDevice->getVideoDriver3D()->privResized();
                        }
                    }
                   
                    // Push a resize event
                    Event ms;
                    ms.m_type = Event::WindowResized;
                    ms.m_videoMode = getVideoMode();
                    m_eventList.addEvent( ms );
                }
            }
            break;
        }
    case WM_ENTERSIZEMOVE:
        {
            m_resizing = true;
            break;
        }
        // Stop resizing
    case WM_EXITSIZEMOVE:
        {
            m_resizing = false;
            if( isReachable() )
            {
                // Ignore cases where the window has only been moved
                if( privGetVideoMode() != getVideoMode() )
                {
                    updateVideoMode();
                    if( m_windowType == WindowType::DirectXDevice )
                    {
                        Device * pDevice = dynamic_cast < Device *>( this );
                        if( pDevice->getVideoDriver3D() )
                        {
                            pDevice->getVideoDriver3D()->setVideoMode( m_videoMode );
                            pDevice->getVideoDriver3D()->privResized();
                        }
                    }
                    // Push a resize event
                    Event ms;
                    ms.m_type = Event::WindowResized;
                    ms.m_videoMode = getVideoMode();
                    m_eventList.addEvent( ms );
                }
            }
            break;
        }
    case WM_GETMINMAXINFO:
        {
            // set the MINMAXINFO structure pointer
            MINMAXINFO * lpMinMaxInfo = NULL;
            lpMinMaxInfo =( MINMAXINFO FAR * ) lParam;
            if( getMinVideoMode() != VideoMode( 0, 0, 0 ) )
            {
                lpMinMaxInfo->ptMinTrackSize.x = getMinVideoMode().x;
                lpMinMaxInfo->ptMinTrackSize.y = getMinVideoMode().y;
            }
            if( getMaxVideoMode() != VideoMode( 0, 0, 0 ) )
            {
                lpMinMaxInfo->ptMaxTrackSize.x = getMaxVideoMode().x;
                lpMinMaxInfo->ptMaxTrackSize.y = getMaxVideoMode().y;
            }
            break;
        }
        default:
        break;
       
    }
}
Jak Ci to coś pomoże :)
P-129673
TheReclif
Temat założony przez niniejszego użytkownika
» 2015-03-31 22:55:53
A przykład można przykład użycia tej funkcji(a raczej wiedzę, jakie mają znaczenie wartości, które przekazujemy jako argumenty dla tej funkcji)?
P-129708
RazzorFlame
» 2015-04-01 08:22:00
Sugeruj się raczej funkcją którą podałem w tym temacie a nie tym starszym. Na poprzedniej stronie podałem Ci aktualną wersję kodu statycznej funkcji, która ma za zadanie dostarczenie windowsowych zdarzeń do właściwego okna. Stamtąd, gdy już znamy prawidłowe okno czyli ten kawałek kodu:
C/C++
if( pWnd != nullptr )
{
    return pWnd->defaultProcedure( hwnd, uMsg, wParam, lParam );
}
Wywołujemy niestatyczną metodę klasy Window, która wygląda tak:
C/C++
LRESULT CALLBACK Window::defaultProcedure( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
    parseMessage( msg, wParam, lParam );
    switch( msg )
    {
    case WM_CLOSE:
        break;
    case WM_DESTROY:
        PostQuitMessage( 0 );
        break;
        default:
        return DefWindowProc( hWnd, msg, wParam, lParam );
    }
    return 0;
}
Nie obsługuję tutaj WM_CLOSE, żeby użytkownik sam wybrał czy okno ma się zamknąć po naciśnięciu X. Tak wygląda stworzenie okna:
C/C++
////////////////////////////////////////////////////////////////////////////////////////////////////
bool Window::create( wstring _name, wstring _classname, UINT a_style, VideoMode vMode )
{
    m_windowType = WindowType::NormalWindow;
    if( !vMode.isValid() ) vMode = VideoMode::GetDesktopMode();
   
    wchar_t * __name =( wchar_t * ) _name.c_str();
    wchar_t * __classname =( wchar_t * ) _classname.c_str();
    RECT nRect = { 0, 0, vMode.x, vMode.y };
   
    int _style = privToWindowStyle( a_style );
   
    AdjustWindowRect( & nRect, _style, false );
    VectorF __size;
    __size.x =( float )( nRect.right - nRect.left );
    __size.y =( float )( nRect.bottom - nRect.top );
   
    m_videoMode = VideoMode( __size.x, __size.y, vMode.bpp );
   
    m_hWindow = CreateWindowEx( WS_EX_CLIENTEDGE, __classname, __name, _style,
    CW_USEDEFAULT, CW_USEDEFAULT,( int ) __size.x,( int ) __size.y, NULL, NULL, GetModuleHandle( NULL ), static_cast < AbstractWindow *>( this ) );
    m_bReachable = m_hWindow != nullptr;
    return m_bReachable;
}
Funkcja privToWindowStyle konwertuje mój zestaw styli na taki windowsowy, sugerowałem się SFML-em:
C/C++
int Window::privToWindowStyle( int style )
{
    DWORD win32Style = WS_VISIBLE;
    if( style == WindowStyle::None )
    {
        win32Style |= WS_POPUP;
    }
    else
    {
        if( style & WindowStyle::Titlebar ) win32Style |= WS_CAPTION | WS_MINIMIZEBOX;
       
        if( style & WindowStyle::Resize ) win32Style |= WS_THICKFRAME | WS_MAXIMIZEBOX;
       
        if( style & WindowStyle::Close ) win32Style |= WS_SYSMENU;
       
    }
   
    return win32Style;
}
No i wypełnienie WNDCLASSEX oczywiście w klasie WindowClass:
C/C++
WindowClass::WindowClass()
{
    m_bRegistered = false;
}
WindowClass::WindowClass( const wchar_t * sName, bool reg, Color brush, UINT style, HICON hIcon, HICON hIconSm, HCURSOR hCur )
{
    create( sName, reg, brush, style, hIcon, hIconSm, hCur );
}

bool WindowClass::create( const wchar_t * sName, bool reg, Color brush, UINT style, HICON hIcon, HICON hIconSm, HCURSOR hCur )
{
    m_bRegistered = false;
   
    ZeroMemory( & m_WindowClass, sizeof( WNDCLASSEX ) );
   
    m_sClassName = sName;
   
    m_WindowClass.cbSize = sizeof( WNDCLASSEX );
    m_WindowClass.style = style;
   
    m_WindowClass.lpfnWndProc = AbstractWindow::DefaultProcedure;
   
    m_WindowClass.cbClsExtra = 0;
    m_WindowClass.cbWndExtra = 0;
   
    m_WindowClass.hInstance = GetModuleHandle( nullptr );
   
    m_WindowClass.hCursor = hCur;
    m_WindowClass.hIcon = hIcon;
    m_WindowClass.hIconSm = hIconSm;
   
    m_WindowClass.hbrBackground = CreateSolidBrush( RGB( brush.r, brush.g, brush.b ) );
   
    m_WindowClass.lpszClassName = sName;
   
    m_WindowClass.lpszMenuName = nullptr;
   
    if( reg ) doRegister();
   
    if( reg && !isRegistered() ) return false;
    else return true;
   
}

bool WindowClass::doRegister()
{
    m_bRegistered = RegisterClassEx( & m_WindowClass ) != 0;
    return isRegistered();
}
bool WindowClass::unRegister()
{
    m_bRegistered = !( UnregisterClass(( wchar_t * ) m_sClassName.c_str(), GetModuleHandle( nullptr ) ) );
    return !isRegistered();
}

bool WindowClass::isRegistered() { return m_bRegistered; }
Zwróć uwagę na tą linijkę:
C/C++
m_WindowClass.lpfnWndProc = AbstractWindow::DefaultProcedure;
Podaję tutaj adres do statycznej metody. Nie musisz nigdzie w pamięci zapisywać instancji HINSTANCE bo funkcja GetModuleHandle Ci ją zwróci.
Masz tutaj jeszcze kod klasy Event
C/C++
class Event
{
    UINT m_mouseButton,
    m_key,
    m_type,
    m_filesCount;
   
    vector < wstring > m_files;
   
    VideoMode m_videoMode;
   
    VectorF m_mousePosition;
   
    float m_mouseWheelDelta;
public:
    /** \brief Constructor
             *
             * \return nothing
             *
             */
    Event();
   
    // Standard Members
   
    UINT getKey();
    UINT getType();
    UINT getMouseButton();
    UINT getFilesCount();
    float getMouseWheelDelta();
    vector < wstring > & getFiles();
    VideoMode getVideoMode();
    VectorF getMousePosition();
   
    enum
    {
        Unknown = 0,
       
        KeyPressed,
        KeyReleased,
        MouseButtonPressed,
        MouseButtonReleased,
        MouseWheelMoved,
        MouseMoved,
        FilesDropped,
        WindowResized,
        WindowLostFocus,
        WindowGainedFocus,
        WindowClosed
    };
   
    friend class Window;
    friend class EventList;
};
class EventList
{
    // edge members
    vector < Event > m_events;
    // End
   
    // WinAPI members
    MSG m_hMessage;
    // End
public:
    /** \brief Constructor
             *
             * \return nothing
             *
             */
    EventList();
   
    /** \brief Adds message to vector
             *
             * \return nothing
             *
             */
    void addEvent( Event );
   
    /** \brief Returns first event on vector
             *
             * \return Returns first event on vector
             * Additional info: removes first event on vector
             */
    Event popEvent();
   
    /** \brief Returns message on vector
             *
             * \param Event id                            as UINT
             * \return Returns message on vector
             *
             */
    Event getEvent( UINT id = 0 );
   
    /** \brief Returns pointer to WinAPI message
             *
             * \return Returns pointer to WinAPI message
             *
             */
    LPMSG getHMessage();
   
    friend class Window;
   
};
Z tym kodem bez problemu powinieneś napisać dobrzę obsługę okna, wtedy okienko Ci się będzie zamykać.

Wow... nie spodziewałem się, że aż tyle tego było.
P-129714
TheReclif
Temat założony przez niniejszego użytkownika
» 2015-04-07 21:38:14
Kolejne pytanie: gdzie wywoływana jest metoda GetObjectFromWindow należąca do klasy AbstractWindow i w jakich celach?
P-130378
RazzorFlame
» 2015-04-09 20:52:32
Człowieku, podałem Ci niezły kawałek kodu, z którym bez problemu byś sobie poradził. Jak byk w kodzie na poprzedniej stronie widać gdzie i jak wywołuje GetObjectFromWindow. Poczytaj o tym jak tworzy się wrappery do WinAPI. Musisz nauczyć się samemu rozwiązywać problemy.
C/C++
AbstractWindow * pWnd = nullptr;

// If window has just been created
if( uMsg == WM_NCCREATE )
{
    SetWindowLong( hwnd, GWLP_USERDATA,( long )(( LPCREATESTRUCT( lParam ) )->lpCreateParams ) );
}

// Get pointer of a window
pWnd = GetObjectFromWindow( hwnd );
Masz bardzo przejrzyście napisane, nie wiem czego jeszcze Ci potrzeba. Przy tworzeniu okna, podaje się wskaźnik na dynamic_cast<AbstractWindow*>(this) w ostatnim argumencie CreateWindowEx, dzięki temu GetObjectFromWindow potrafi uzyskać adres okna z użyciem hWnd.
P-130469
1 « 2 » 3
Poprzednia strona Strona 2 z 3 Następna strona