Usuwanie dynamicznie utworzonych obiektów

Stronę tą wyświetlono już: 340 razy

Wstęp

Skoro zrealizowane zostało dodawanie obiektów oraz ich zaznaczanie najwyższa pora nadeszła aby zacząć coś robić z tymi zaznaczonymi obiektami. Pierwszą taką operacją będzie usuwanie obiektów. Realizację tego zadania przekażemy w "ręce" klasy select_obj, gdyż ta przechowuje wewnątrz pewne informacje, które powinny zostać odpowiednio ustawione w przypadku usuwania obiektów. Oczywiście usuwanie obiektów powinno zostać podpięte pod przycisk delete klawiatury, a co za tym idzie do projektu konieczne będzie dodanie akceleratorów.

Dodawanie akceleratorów do zasobów programu

Na razie dodany zostanie tylko jeden akcelerator tak jak na poniższym rysunku zostało to pokazane.

Widok dodanego akceleratora do projektu programu Rysowanie
Rys. 1
Projekt programu rysowanie - widok dodanego akceleratora związanego z usuwaniem obiektów

Akcelerator należy oczywiście podpiąć do projektu w sposób już wcześniej omawiany na stronie Programowanie → C++ WinApi → Dodawanie menu, akceleratora, ikony i kursora do programu, toteż ja skupię się jedynie na obsłudze komunikatu przychodzącego od akceleratora do okna rysowanie:

Listing 1
  1. case WM_COMMAND:
  2. {
  3. if((HWND)lParam == toolbar){
  4. UINT n = LOWORD(wParam);
  5. if(n != ID_SELECT && st == state::sel){
  6. SelObjAct.Clear();
  7. InvalidateRect(hWndDraw, NULL, true);
  8. }
  9. switch(n){
  10. case ID_LINE: // komunikat przychodzący od przycisku toolbar-a o identyfikatorze ID_LINE
  11. {
  12. st = dr_line;
  13. SendMessage(statusbar, SB_SETTEXT, 2, (LPARAM)L"Rysowanie linii"); // ustawienie tekstu w ostatnim polu statusbar-u
  14. }
  15. break;
  16. case ID_CIRCLE: // to samo co poprzednio, tylko dla ID_CIRCLE
  17. {
  18. st = dr_circle;
  19. SendMessage(statusbar, SB_SETTEXT, 2, (LPARAM)L"Rysowanie okręgu"); // ustawienie tekstu w ostatnim polu statusbar-u
  20. }
  21. break;
  22. case ID_RECTANGLE: // to samo co poprzednio, tylko dla ID_RECTANGLE
  23. {
  24. st = dr_rect;
  25. SendMessage(statusbar, SB_SETTEXT, 2, (LPARAM)L"Rysowanie prostokąta"); // ustawienie tekstu w ostatnim polu statusbar-u
  26. }
  27. break;
  28. case ID_SELECT: // to samo co poprzednio, tylko dla ID_SELECT
  29. {
  30. st = sel;
  31. SendMessage(statusbar, SB_SETTEXT, 2, (LPARAM)L"Rysowanie edycja"); // ustawienie tekstu w ostatnim polu statusbar-u
  32. }
  33. break;
  34. }
  35. }else if(HIWORD(wParam) == 1){ // obsługa akceleratora
  36. switch(LOWORD(wParam)){ // id akceleratora
  37. case ID_ACCELERATOR_DELETE: // usuwanie obiektów
  38. {
  39. switch(st){
  40. case state::sel:
  41. {
  42. SelObjAct.Delete(hWndDraw, tObj); // wywołanie metody klasy SelObjAct, która usunie obiekty zaznaczone
  43. }
  44. break;
  45. }
  46. }
  47. break;
  48. }
  49. }
  50. }
  51. break;

Powyżej został wstawiony cały kod związany z komunikatem WM_COMMAND obsługiwanym wewnątrz funkcji procedury okna WndDrawingProc.

Metoda Delete klasy select_obj

Pozostało już tylko dodanie do klasy select_obj nowej metody o nazwie Delete, która będzie wyglądała następująco:

Listing 2
  1. void Delete(HWND hWndDraw, std::vector<i_dr_obj*> &tObj){
  2. if(!tSelObj.empty()){ // jak coś jest zaznaczone to
  3. if(objundercursor && objundercursor->Selected()){ // jeżeli obiekt pod kursorem jest już zaznaczony
  4. objundercursor = NULL; // to trzeba ustawić NULL bo ten obiekt zostanie usunięty
  5. }
  6. for(int i = 0; i < tObj.size(); i++){ // iterowanie po tablicy interfejsów graficznych obiektów
  7. if(tObj[i]->Selected()){ // jak zaznaczony
  8. delete tObj[i]; // zwalniam dynamicznie przypisaną pamięć
  9. tObj.erase(tObj.begin() + i); // usuwam obiekt
  10. i --; // muszę przesunąć ideks w dół bo jeden już usunąłem
  11. }
  12. }
  13. SetRectEmpty(&selrect); // prostokąt zaznaczenia powinien być pusty
  14. tSelObj.clear(); // czyszczę tablicę zaznaczonych obiektów
  15. InvalidateRect(hWndDraw, NULL, false); // i odświerzam jagby nigdy nic się nie stało okno
  16. }
  17. }

Po serii tych jakże wyczerpujących operacji można się cieszyć programem, który nie tylko dodaje, rysuje i zaznacza obiekty, ale również umożliwia ich usuwanie!

Załączniki:

Wersja programu Rysowanie z strony tutaj

Komentarze