Ĺadny brzuch
Mam problem z natury technicznej. Tworze sobie gierkę w Dev-Cpp, korzystam z trybu graficznego winbgim. Otóż chcę stworzyć obsługę klawiszy. Posłużyłem się tym przykładem [link]. I tu występuje problem, że ta procedura w moim programie nie przechwytuje klawiszy. Dodam jeszcze, że ja tworze dodatkowe okno i w nim wszystkie operacje przeprowadzam.
Może zrobiłem jakiś podstawowy błąd? Próbowałem wiele razy, ale na nic. Może pomożecie :) .
Schemat mojego programu:
//include itp... MSG msg; WNDCLASS wndclass; HWND hWnd; LRESULT CALLBACK MainWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_KEYDOWN: switch (wParam) { case VK_ESCAPE: cout << " esc " ; break; case 0x41: cout << " a " ; break; } break; default: return (DefWindowProc(hWnd, uMsg, wParam, lParam)); } return(0L); } int main(int argc, char *argv[]) { //okienko utwórz initwindow(320,240); //zmienne mojego programu /* jakiś tam kod */ //glowna petla while (1){ /* jakiś tam kod */ while(GetMessage(&msg, NULL, 0, 0)); { TranslateMessage(&msg); DispatchMessage(&msg); } } closegraph(); system("PAUSE"); return EXIT_SUCCESS; }
Użytkownik Maciek J. edytował ten post 02 czerwiec 2006, 11:39
while (1){ /* jakiś tam kod */ while(GetMessage(&msg, NULL, 0, 0)); { TranslateMessage(&msg); DispatchMessage(&msg); } }
Czy to nie tu tkwi problem? Wydaje mi się, że jak w amin wywołasz pętlę z warunkiem 1, to program nie ma szans przejść do pętli obsługi komunikatów, a tym samym nic nie wykona. Sprawdź, czy zakończenie tej pętli wcześniej nie zmieni sytuacji.
W czasie wykonywania głównej pętli chce obsługe klawiszy, więc nie moge jej zamknąć wcześniej.
Myśle, że problem tkwi w chwytaniu tych klawiszy, a nie umieszczeniu pętel. Nie wiem czy to poprawnie wpisałem.
Użytkownik Maciek J. edytował ten post 03 czerwiec 2006, 12:35
Przecież obsługę klawiszy masz w MainWndProc. Zeby sięta funkcja wywołała musi się wywołać ta pętla:
while(GetMessage(&msg, NULL, 0, 0))
No i jeszcze zauważyłem, że tam masz średnik na końcu linii, a nie powinno go być, więc może zacznij do usunięcia tego średnika. A jak to nie pomoże, to zrób taki warunek w poprzedniej pętli, który pozwoli się jej skończyć, zamiast while(1).
Jak SPRAWDZISZ, że to nie zadziała, to wtedy napisz, że nie działa.
Jeżeli robie warunek
int a=0; //gdzieś przed pętlą while (a==10){ /* jakiś tam kod */ while(GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } a++; }
to mi dochodzi do tego momentu
closegraph(); (Jeżeli coś tu wstawie np. cout << "cos tam"; to mi to wyświetli i zakończy program)
Możesz dać cały kod, razem z includami i wszystkim, żeby można było wkleić i skompilować? Bo teraz to już się sam pogubiłem, dlatego wolałbym to zobaczyć po skompilowaniu u siebie.
kod na któym aktualnie pracuje (copyright oczywiście ;) )#include <cstdlib> #include <iostream> #include <winbgim.h> #include <windows.h> using namespace std; void rysuj(int x, int y); /**//**//**//**/ //______________ MSG msg; WNDCLASS wndclass; HWND hWnd; short int kierunek=1; LRESULT CALLBACK MainWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_CREATE: break; case WM_DESTROY: PostQuitMessage(0); break; case WM_KEYDOWN: switch (wParam) { case VK_ESCAPE: cout << " esc "; //kod do wykonania jeśli zostanie wciśnięty klawisz escape break; case 0x41: cout << " a "; // kod do wykonania jeśli wciśnięty klawisz "A" break; } break; default: return (DefWindowProc(hWnd, uMsg, wParam, lParam)); } return(0L); } //^^^^^^^^^^^^^^ /**//**//**//**/ int main(int argc, char *argv[]) { //okienko utwórz initwindow(320,240); setfillstyle(SOLID_FILL, 0); bar (0,0,getmaxx(),getmaxy()); setfillstyle(SOLID_FILL, WHITE); //zmienne int dlg=4; int waz[50][2]/*={5,5,5,4,5,3,5,2,5,1,5,0}*/; for (int i=0;i<=dlg;i++){ for (int j=dlg;j>0;j--){ waz[i][0]=5; waz[i][1]=j; } } //narysuj weza setfillstyle(SOLID_FILL, WHITE); for (int j=0;j<dlg;j++){ rysuj(waz[j][0],waz[j][1]); } int a=0; //glowna petla while (a==10){ //rysuj nowa glowe setfillstyle(SOLID_FILL, WHITE); rysuj(waz[0][0],waz[0][1]); //zamaluj tyl setfillstyle(SOLID_FILL, BLACK); rysuj(waz[0+dlg][0],waz[0+dlg][1]); //zaktualizowanie przesuniecia weza for(int i=(dlg+1);i>0;i--){ waz[i][0]=waz[i-1][0]; waz[i][1]=waz[i-1][1]; } delay(300); switch (kierunek){ case 1: waz[0][0]+=1; break; case 2: waz[0][1]+=1; break; case -1: waz[0][0]-=1; break; case -2: waz[0][1]-=1; break; } /* if (waz[0][0]==(getmaxx())/10)kierunek=-kierunek; if (waz[0][0]==0)kierunek=-kierunek;*/ //obsługa klawiszy cout <<", przed get"; while(GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } cout <<", po get" ; a++; } while(!kbhit()); closegraph(); system("PAUSE"); return EXIT_SUCCESS; } void rysuj(int x, int y){ bar(x*10,y*10,x*10+10,y*10+10); //grubość punktu - 10 pixel'i }
Użytkownik Maciek J. edytował ten post 03 czerwiec 2006, 15:08
int a=0; //gdzieś przed pętlą
while (a==10){...
Warunke jest taki, że ta pętla się nie wykona, powinno być raczej a<10. Ale kodu, który zamieściłeś nie udało mi się skompilować, linker coś tam wywalił.
Powiem tak ogólnie: na pewno ten błąd, co wyżej mówiłem. Poza tym w przykładzie, do którego dałeś linka główna pętla programu jest na końcu funkcji main (WinMain) i powiem, że nie widziałem programu, żeby to było inaczej zrobione (ale mało widziałem programów w WinAPI napisanych :P ). Tozadziała tak, że jak program będzie miał się zakończyć, bo okno otrzyma komunikat zamknięcia, to wtedy dopiero zacznie coś robić. Może i ma to szanse zadziałać, ale przemyśl tą konstrukcję i przeczytaj więcej o pisaniu z użyciem WinAPI.
int a=0; //gdzieś przed pętlą
while (a==10){...
Warunke jest taki, że ta pętla się nie wykona, powinno być raczej a<10. klasyczny błąd :D
Ale kodu, który zamieściłeś nie udało mi się skompilować, linker coś tam wywalił. bo nie masz w folderze include plików winbgim.h i winbgim.cpp (więcej o tej bibliotece [link])
PS: A tak poza tym, to ja nie chciałem się uczyć WinAPI, tylko na razie samego języka w celu poznania go. A ta gra troche mi namiesza w głowie <_<.
Każda pomoc mile widziana :) .
//edit
A może ja źle deklaruje uchwyt okna, i mi zbiera komunikaty z innego okna?
//edit2
@down: ale ja nie chce się go uczyć :excl:
Użytkownik Maciek J. edytował ten post 03 czerwiec 2006, 18:55
Jeżeli uczysz się języka na WinAPI to ja współczuje.
Jeżeli piszesz gierke to powinieneś sie zainteresować funkcją PickMessage, ale wątpie, żeby ci to coś powiedziało...
zanotowane.pl doc.pisz.pl pdf.pisz.pl zsf.htw.pl
Może zrobiłem jakiś podstawowy błąd? Próbowałem wiele razy, ale na nic. Może pomożecie :) .
Schemat mojego programu:
//include itp... MSG msg; WNDCLASS wndclass; HWND hWnd; LRESULT CALLBACK MainWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_KEYDOWN: switch (wParam) { case VK_ESCAPE: cout << " esc " ; break; case 0x41: cout << " a " ; break; } break; default: return (DefWindowProc(hWnd, uMsg, wParam, lParam)); } return(0L); } int main(int argc, char *argv[]) { //okienko utwórz initwindow(320,240); //zmienne mojego programu /* jakiś tam kod */ //glowna petla while (1){ /* jakiś tam kod */ while(GetMessage(&msg, NULL, 0, 0)); { TranslateMessage(&msg); DispatchMessage(&msg); } } closegraph(); system("PAUSE"); return EXIT_SUCCESS; }
Użytkownik Maciek J. edytował ten post 02 czerwiec 2006, 11:39
while (1){ /* jakiś tam kod */ while(GetMessage(&msg, NULL, 0, 0)); { TranslateMessage(&msg); DispatchMessage(&msg); } }
Czy to nie tu tkwi problem? Wydaje mi się, że jak w amin wywołasz pętlę z warunkiem 1, to program nie ma szans przejść do pętli obsługi komunikatów, a tym samym nic nie wykona. Sprawdź, czy zakończenie tej pętli wcześniej nie zmieni sytuacji.
W czasie wykonywania głównej pętli chce obsługe klawiszy, więc nie moge jej zamknąć wcześniej.
Myśle, że problem tkwi w chwytaniu tych klawiszy, a nie umieszczeniu pętel. Nie wiem czy to poprawnie wpisałem.
Użytkownik Maciek J. edytował ten post 03 czerwiec 2006, 12:35
Przecież obsługę klawiszy masz w MainWndProc. Zeby sięta funkcja wywołała musi się wywołać ta pętla:
while(GetMessage(&msg, NULL, 0, 0))
No i jeszcze zauważyłem, że tam masz średnik na końcu linii, a nie powinno go być, więc może zacznij do usunięcia tego średnika. A jak to nie pomoże, to zrób taki warunek w poprzedniej pętli, który pozwoli się jej skończyć, zamiast while(1).
Jak SPRAWDZISZ, że to nie zadziała, to wtedy napisz, że nie działa.
Jeżeli robie warunek
int a=0; //gdzieś przed pętlą while (a==10){ /* jakiś tam kod */ while(GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } a++; }
to mi dochodzi do tego momentu
closegraph(); (Jeżeli coś tu wstawie np. cout << "cos tam"; to mi to wyświetli i zakończy program)
Możesz dać cały kod, razem z includami i wszystkim, żeby można było wkleić i skompilować? Bo teraz to już się sam pogubiłem, dlatego wolałbym to zobaczyć po skompilowaniu u siebie.
kod na któym aktualnie pracuje (copyright oczywiście ;) )#include <cstdlib> #include <iostream> #include <winbgim.h> #include <windows.h> using namespace std; void rysuj(int x, int y); /**//**//**//**/ //______________ MSG msg; WNDCLASS wndclass; HWND hWnd; short int kierunek=1; LRESULT CALLBACK MainWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_CREATE: break; case WM_DESTROY: PostQuitMessage(0); break; case WM_KEYDOWN: switch (wParam) { case VK_ESCAPE: cout << " esc "; //kod do wykonania jeśli zostanie wciśnięty klawisz escape break; case 0x41: cout << " a "; // kod do wykonania jeśli wciśnięty klawisz "A" break; } break; default: return (DefWindowProc(hWnd, uMsg, wParam, lParam)); } return(0L); } //^^^^^^^^^^^^^^ /**//**//**//**/ int main(int argc, char *argv[]) { //okienko utwórz initwindow(320,240); setfillstyle(SOLID_FILL, 0); bar (0,0,getmaxx(),getmaxy()); setfillstyle(SOLID_FILL, WHITE); //zmienne int dlg=4; int waz[50][2]/*={5,5,5,4,5,3,5,2,5,1,5,0}*/; for (int i=0;i<=dlg;i++){ for (int j=dlg;j>0;j--){ waz[i][0]=5; waz[i][1]=j; } } //narysuj weza setfillstyle(SOLID_FILL, WHITE); for (int j=0;j<dlg;j++){ rysuj(waz[j][0],waz[j][1]); } int a=0; //glowna petla while (a==10){ //rysuj nowa glowe setfillstyle(SOLID_FILL, WHITE); rysuj(waz[0][0],waz[0][1]); //zamaluj tyl setfillstyle(SOLID_FILL, BLACK); rysuj(waz[0+dlg][0],waz[0+dlg][1]); //zaktualizowanie przesuniecia weza for(int i=(dlg+1);i>0;i--){ waz[i][0]=waz[i-1][0]; waz[i][1]=waz[i-1][1]; } delay(300); switch (kierunek){ case 1: waz[0][0]+=1; break; case 2: waz[0][1]+=1; break; case -1: waz[0][0]-=1; break; case -2: waz[0][1]-=1; break; } /* if (waz[0][0]==(getmaxx())/10)kierunek=-kierunek; if (waz[0][0]==0)kierunek=-kierunek;*/ //obsługa klawiszy cout <<", przed get"; while(GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } cout <<", po get" ; a++; } while(!kbhit()); closegraph(); system("PAUSE"); return EXIT_SUCCESS; } void rysuj(int x, int y){ bar(x*10,y*10,x*10+10,y*10+10); //grubość punktu - 10 pixel'i }
Użytkownik Maciek J. edytował ten post 03 czerwiec 2006, 15:08
int a=0; //gdzieś przed pętlą
while (a==10){...
Warunke jest taki, że ta pętla się nie wykona, powinno być raczej a<10. Ale kodu, który zamieściłeś nie udało mi się skompilować, linker coś tam wywalił.
Powiem tak ogólnie: na pewno ten błąd, co wyżej mówiłem. Poza tym w przykładzie, do którego dałeś linka główna pętla programu jest na końcu funkcji main (WinMain) i powiem, że nie widziałem programu, żeby to było inaczej zrobione (ale mało widziałem programów w WinAPI napisanych :P ). Tozadziała tak, że jak program będzie miał się zakończyć, bo okno otrzyma komunikat zamknięcia, to wtedy dopiero zacznie coś robić. Może i ma to szanse zadziałać, ale przemyśl tą konstrukcję i przeczytaj więcej o pisaniu z użyciem WinAPI.
int a=0; //gdzieś przed pętlą
while (a==10){...
Warunke jest taki, że ta pętla się nie wykona, powinno być raczej a<10. klasyczny błąd :D
Ale kodu, który zamieściłeś nie udało mi się skompilować, linker coś tam wywalił. bo nie masz w folderze include plików winbgim.h i winbgim.cpp (więcej o tej bibliotece [link])
PS: A tak poza tym, to ja nie chciałem się uczyć WinAPI, tylko na razie samego języka w celu poznania go. A ta gra troche mi namiesza w głowie <_<.
Każda pomoc mile widziana :) .
//edit
A może ja źle deklaruje uchwyt okna, i mi zbiera komunikaty z innego okna?
//edit2
@down: ale ja nie chce się go uczyć :excl:
Użytkownik Maciek J. edytował ten post 03 czerwiec 2006, 18:55
Jeżeli uczysz się języka na WinAPI to ja współczuje.
Jeżeli piszesz gierke to powinieneś sie zainteresować funkcją PickMessage, ale wątpie, żeby ci to coś powiedziało...