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: 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: #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: 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 ) );
|
|
Monika90 |
» 2014-09-14 16:25:46 ta linia kodu wewnątrz konstuktora nie wygląda na sensowną co chciałeś w ten sposób uzyskać? wndClass.lpszClassName =( char * ) sName.c_str();
po wyjściu z konstruktora wskaźnik lpszClassName będzie nieważny 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. |
|
RazzorFlame Temat założony przez niniejszego użytkownika |
» 2014-09-14 16:36:08 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: 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 |
|
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. |
|
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. |
|
« 1 » |