[C++/WinAPI] Jak zakończyć proces


(rozwalkompa) #1

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) #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.


(rozwalkompa) #3

Aha.

to znaczy jaką?

Dokąd ta funkcja zwraca identyfikator? Jakieś przypisanie w stylu Pascal'owego:

zmienna:=nazwa_funkcji(argumenty);

(Ryan) #4

Na pierwsze pytanie odpowie Ci dowolny tutorial, inny niż ten którego używasz. :wink: 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. :slight_smile:


(rozwalkompa) #5

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


(Fiołek) #6

A jak możesz definiować funkcje w pętli?

Przenieś kod WndProc poza funkcje WinMain, powinno działać.


(rozwalkompa) #7

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ę :smiley:


(Fiołek) #8

To też wywal!


(rozwalkompa) #9

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ę?


(Fiołek) #10

Do WndProc(do switcha) dodaj:

case WM_DESTROY:

PostQuitMessage(0);

return 0;

(rozwalkompa) #11

DZIAŁA!

To chyba będzie cud, jeśli się tego kiedyś nauczę :smiley: