Mam oto taki kod (ze strony: http://guidecpp.x12.pl/winapi-window.php )
#include
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nMode)
{
HWND hOkno;
MSG message;
WNDCLASS okno;
okno.hInstance = hInstance;
okno.lpszClassName = "klasa1";
okno.lpfnWndProc = DefWindowProc;
okno.lpszMenuName = NULL;
okno.style = 0;
okno.hIcon = LoadIcon (NULL,IDI_WINLOGO);
okno.hCursor = LoadCursor (NULL,IDC_ARROW);
okno.hbrBackground = (HBRUSH) GetStockObject (BLACK_BRUSH);
okno.cbClsExtra = 0;
okno.cbWndExtra = 0;
if (!RegisterClass (& okno)) return 0;
hOkno = CreateWindow (
"klasa1", //nazwa klasy okna
"NoName", //tytuł okna
WS_OVERLAPPEDWINDOW, //styl - WS_OVERLAPPEDWINDOW to standardowe okienko
300, 400, //współrzędne i..
800, 600, //..wymiary okna
NULL, //brak okna nadrzędnego, właścicielem jest pulpit
NULL, //brak menu
hInstance, //uchwyt instancji
NULL //brak dodatkowych danych
);
ShowWindow (hOkno, SW_SHOW);
while (GetMessage (&message, NULL, 0, 0))
{
DispatchMessage (&message);
}
}
Po zamknięciu okna, w procesach (w XP: [Ctrl]+[shift]+[Esc] -> Procesy) nadal istnieje proces NoName.exe
Jest jakiś kod, żeby zamknąć ten proces?
Ryan
(Ryan)
16 Sierpień 2007 19:10
#2
Po zamknięciu okna w aplikacjach proces nadal istnieje. Zabicie procesu kończy aplikację. Chyba to chciałeś powiedzieć.
W każdym razie - DefWindowProc nie zareaguje na WM_CLOSE ani WM_DESTROY w wyniku czego Twoja pętla nigdy się nie zakońcy (GetMessage nie zwróci FALSE). Poprawnie napisany program musi mieć funkcję obsługi wiadomości okna inną niż DefWindowProc.
Aha.
to znaczy jaką?
Dokąd ta funkcja zwraca identyfikator? Jakieś przypisanie w stylu Pascal’owego:
zmienna:=nazwa_funkcji(argumenty);
Ryan
(Ryan)
17 Sierpień 2007 12:43
#4
Na pierwsze pytanie odpowie Ci dowolny tutorial, inny niż ten którego używasz. Z pamięci (mogą być błędy):
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_DESTROY:
PostQuitMessage(0);
return 0; //?
case WM_CLOSE:
DestroyWindow(hwnd);
break; //?
}
return DefWindowProc(hwnd, msg, wParam, lParam);
}
Staje się to Twoim callbackiem dla okno.lpfnWndProc. Ponadto przed DispatchMessage potrzebujesz TranslateMessage. Nie pamiętam czy ma być w obu return, w obu break czy w różnych różnie. Pokombinuj.
Poszukałem, poczytałem i doszedłem do takiego kodu:
#include
LRESULT CALLBACK WndProc(HWND hOkno, UINT msg, WPARAM wParam, LPARAM lParam);
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nMode)
{
HWND hOkno;
MSG message;
WNDCLASS okno;
okno.hInstance = hInstance;
okno.lpszClassName = "klasa1";
okno.lpfnWndProc = WndProc;
okno.lpszMenuName = NULL;
okno.style = 0;
okno.hIcon = LoadIcon (NULL,IDI_WINLOGO);
okno.hCursor = LoadCursor (NULL,IDC_ARROW);
okno.hbrBackground = (HBRUSH) GetStockObject (BLACK_BRUSH);
okno.cbClsExtra = 0;
okno.cbWndExtra = 0;
if (!RegisterClass (& okno)) return 0;
hOkno = CreateWindow (
"klasa1", //nazwa klasy okna
"NoName", //tytuł okna
WS_OVERLAPPEDWINDOW, //styl - WS_OVERLAPPEDWINDOW to standardowe okienko
100, 300, //współrzędne i..
800, 600, //..wymiary okna
NULL, //brak okna nadrzędnego, właścicielem jest pulpit
NULL, //brak menu
hInstance, //uchwyt instancji
NULL //brak dodatkowych danych
);
ShowWindow (hOkno, SW_SHOW);
while (GetMessage (&message, NULL, 0, 0))
{
TranslateMessage (&message);
LRESULT CALLBACK WndProc(HWND hOkno, UINT msg, WPARAM wParam, LPARAM lParam)
{ //TUTAJ JEST BŁĄD?
switch (msg)
{
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_CLOSE:
DestroyWindow(hwnd);
break;
}
return WndProc(hOkno, msg, wParam, lParam);
}
DispatchMessage (&message);
}
return 0;
}
Jednak kompilator zwraca błąd
39 a function-definition is not allowed here before '{' token
w zaznaczonej linijce
Fiolek
(Fiołek)
17 Sierpień 2007 18:31
#6
A jak możesz definiować funkcje w pętli?
Przenieś kod WndProc poza funkcje WinMain, powinno działać.
Google, to potęga! Dzięki nim znalazłem taką oto stronę http://stud.wsi.edu.pl/~sistudem/Podstawy/WINProcOkna.html i wszystko ładnie się kompiluje i DZIAŁA!
Dziękuję za dotychczasową pomoc, jak coś, to jeszcze napiszę
Poprawiłem
(...)
ShowWindow (hOkno, SW_SHOW);
while (GetMessage (&message, NULL, 0, 0))
{
TranslateMessage (&message);
DispatchMessage (&message);
}
return 0;
}
LRESULT CALLBACK WndProc(HWND hOkno, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_CLOSE:
if (MessageBox(hOkno,"Czy chcesz zamknąć?","info",MB_YESNO) == IDYES)
DestroyWindow(hOkno);
break;
}
return DefWindowProc(hOkno,msg,wParam,lParam);
}
i ten sam problem co w temacie, jak zakończyć pętlę?
Fiolek
(Fiołek)
18 Sierpień 2007 11:11
#10
Do WndProc(do switcha) dodaj:
case WM_DESTROY:
PostQuitMessage(0);
return 0;
DZIAŁA!
To chyba będzie cud, jeśli się tego kiedyś nauczę