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

[WinApi] Wrapper - działa przy kompilatorze GCC, przy MSVC 8 nie.

Ostatnio zmodyfikowano 2014-09-14 16:46
Autor Wiadomość
RazzorFlame
Temat założony przez niniejszego użytkownika
[WinApi] Wrapper - działa przy kompilatorze GCC, przy MSVC 8 nie.
» 2014-09-14 16:01:18
Dosyć specyficzny problem. Chciałem przesiąść się z GCC na MSVC 8 (miałem dużo problemów ale to nie jest ważne). Napisałem wrapper w GCC, wszystko działa pięknie. Kiedy jednak ustawie kompilator w Code::Blocks na Microsoft Visual Studio 5/8 i go skonfiguruje to mimo tego, że podczas kompilacji nie dostaje żadnych błędów Okno nie może się utworzyć ponieważ funkcja RegisterClassEx zwraca 0. Kodu w ogóle nie zmieniałem, jedynie kompilator. W GCC wszystko ładnie śmigało. Przesiadłem się na MSVC bo chcę pisać w DirectX11. Tak więc tutaj kawałki kodu:
C/C++
WindowClass::WindowClass( string sName, uVector3 < unsigned char > brush, bool reg, UINT style, HICON hIcon, HICON hIconSm, HCURSOR hCur )
{
    WindowClass();
   
    ZeroMemory( & wndClass, sizeof( WNDCLASSEX ) );
   
    className = sName;
   
    wndClass.cbSize = sizeof( WNDCLASSEX );
    wndClass.style = 0;
   
    wndClass.lpfnWndProc = DefWindowProc;
   
    wndClass.cbClsExtra = 0;
    wndClass.cbWndExtra = 0;
   
    wndClass.hInstance = GetModuleHandle( NULL );
   
    wndClass.hCursor = hCur;
    wndClass.hIcon = hIcon;
    wndClass.hIconSm = hIconSm;
   
    wndClass.hbrBackground = CreateSolidBrush( RGB( brush.x, brush.y, brush.z ) );
   
    wndClass.lpszClassName =( char * ) sName.c_str();
    wndClass.lpszMenuName = NULL;
   
    if( reg ) doRegister();
   
}

bool WindowClass::doRegister()
{
    registered = RegisterClassEx( & wndClass ) != 0;
    if( !isRegistered() ) errorManager.addError( Error( "e20000", "Cannot register class \"" + className + "\"!" ) );
   
    return isRegistered();
}
Tak wygląda program testowy tego wrappera:
C/C++
#include <v3de.hpp>
#include <string>

#pragma comment(lib, "user32.lib")

v3de::MessageManager mgr;
v3de::KeyManager kmgr;

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{
   
    v3de::WindowClass wClass( "nazwaklasy" );
    if( !wClass.doRegister() )
    {
        return - 1;
    }
    v3de::Window app( "Okienko", "nazwaklasy", WS_OVERLAPPEDWINDOW, v3de::uVector < int >( 800, 600 ), false, true );
    if( !app.isReachable() ) return - 2;
   
    while( mgr.getMessage()->message != WM_QUIT )
    {
        if( !mgr.checkMessages( app ) )
        {
        }
        else
        {
            if( mgr.getMsg().type == v3de::Message::KeyDown )
                 cout << mgr.getMsg().key << endl;
           
        }
       
    }
    return 0;
}
Ja już na prawdę nie mam siły. Próbowałem chyba wszystkiego. Zdaje się na Waszą pomoc.

Edit:
Dodam jeszcze że reszta parametrów konstruktora WindowClass ma swoje domyślne wartości:
C/C++
WindowClass( string, uVector3 < unsigned char > = uVector3 < unsigned char >( 0, 0, 0 ), bool = false, UINT = 0,
HICON = LoadIcon( NULL, IDI_APPLICATION ),
HICON = LoadIcon( NULL, IDI_APPLICATION ),
HCURSOR = LoadCursor( NULL, IDC_ARROW ) );
P-116983
Monika90
» 2014-09-14 16:25:46
ta linia kodu wewnątrz konstuktora nie wygląda na sensowną
C/C++
WindowClass();
co chciałeś w ten sposób uzyskać?

C/C++
wndClass.lpszClassName =( char * ) sName.c_str();
po wyjściu z konstruktora wskaźnik lpszClassName będzie nieważny

C/C++
if( reg ) doRegister();

z kodu który podałeś nie wynika jaką wartość ma reg więc nie wiem co się stanie...

A swoją drogą, MSVC 8 jest z 2005 roku, to jest zabytek.
P-116984
RazzorFlame
Temat założony przez niniejszego użytkownika
» 2014-09-14 16:36:08
C/C++
WindowClass();
Wywołuje domyślny konstruktor. Wiem że to działa (przynajmniej na GCC). W domyślnym konstruktorze ustalam początkowe wartości zmiennych by później nie mieć jakichś nieporozumień. Nie chciałem dwa razy tego powtarzać.
Co do:
C/C++
wndClass.lpszClassName =( char * ) sName.c_str();
Faktycznie, przyzwyczaiłem się tak pisać dlatego że GCC to toleruje :)
Zmienna reg jest domyślnie ustawiona na false, co z resztą możesz zobaczyć w domyślnych wartościach argumentów w konstruktorze (reg nie jest 'członkiem' klasy)

Wiem, że MSVC 8 jest stare, jednak jak wspomniałem miałem problemy. Chodzi o to, że wcześniej instalowałem wersje 2013 i nie umiałem się połapać, nie mogłem podpiąć tego kompilatora pod Code Blocks bo obsługuje tylko do wersji 2010.

Zaraz sprawdze czy działa.

Edit:

Kurcze, nie wiem jak to zrobić. Mam jakieś zaćmienie, pomożesz :P
P-116985
Monika90
» 2014-09-14 16:44:01
Przeoczyłam to, faktycznie reg jest równe false, czyli rejestracja klasy nastepuje po wyściu z konstruktora, wtedy lpszClassName jest nieważne, bo sName już nie istnieje.

Natomiast to
WindowClass();
 tworzy tymczasowy obiekt klasy, który zaraz potem jest niszczony. Nie ma to wpływu na obiekt którego konstrukcja aktualnie się odbywa.

P-116986
RazzorFlame
Temat założony przez niniejszego użytkownika
» 2014-09-14 16:46:16
Aha, okej. Tymczasem... DZIAŁA! Zmieniłem w konstruktorze string na const char* i zaczęło działać. Wielkie dzięki za szybką odpowiedź i za pomoc. Dzięki też za wytłumaczenie z tym konstruktorem.
P-116987
« 1 »
  Strona 1 z 1