340 likes | 396 Views
Ćwiczenie (1). Dostosuj poniższy program do swojego programy zaliczeniowego . (Plik z programem jest dostępny pod adresem http://mijprogramowania.w.interia.pl/18_01_2009.c) #include <stdio.h> #include <stdlib.h> typedef struct{ char imie[30]; char nazwisko[50]; int rokUrodzenia;
E N D
Ćwiczenie (1) Dostosuj poniższy program do swojego programy zaliczeniowego. (Plik z programem jest dostępny pod adresem http://mijprogramowania.w.interia.pl/18_01_2009.c) #include <stdio.h> #include <stdlib.h> typedef struct{ char imie[30]; char nazwisko[50]; int rokUrodzenia; char PESEL[20]; //data } klient; klient tKlienci[100]; //funkcje narzedziowe /////////////////////////////////////////////// char *substring(size_t start, size_t stop, const char *src, char *dst){ int count = stop - start; sprintf(dst, "%.*s", count, src + start); return dst; } char *strtoupper(char *str) { int i = 0; for(i = 0; str[i]; i++) str[i] = toupper(str[i]); return str; } ///////////////////////////////////////////////
Ćwiczenie (1) void wczytajKlientow(){ FILE *plik; char a[100], sciezka[100] = "C:\\temp\\abc.txt", linia[100], podciag[100] ; int i=0; if ((plik = fopen(sciezka, "r")) == NULL) { printf("Nie mozna otworzyc %s\n", sciezka); system("PAUSE"); exit(1); } while (fgets(linia, 100, plik)!= NULL){ if(strstr(linia, "PESEL:")){ substring(sizeof("PESEL:")/sizeof(char) - 1, strlen(linia)-1, linia, podciag); strcpy(tKlienci[i].PESEL, podciag); i++; } else if (strstr(linia, "Imie:")){ substring(sizeof("Imie:")/sizeof(char) - 1, strlen(linia)-1, linia, podciag); strcpy(tKlienci[i].imie, podciag); } else if (strstr(linia, "Nazwisko:")){ substring(sizeof("Nazwisko:")/sizeof(char) - 1, strlen(linia)-1, linia, podciag); strcpy(tKlienci[i].nazwisko, podciag); } else if (strstr(linia, "Rok urodzenia:")){ substring(sizeof("Rok urodzenia:")/sizeof(char) - 1, strlen(linia)-1, linia, podciag); tKlienci[i].rokUrodzenia = atoi(podciag); } } fclose(plik); };
Ćwiczenie (1) void wypiszKlienta(int i){ printf("%d. klient\n", i+1); printf("PESEL: %s\n", tKlienci[i].PESEL); printf("Imie: %s\n", tKlienci[i].imie); printf("Nazwisko: %s\n", tKlienci[i].nazwisko); printf("Rok urodzenia: %d\n\n", tKlienci[i].rokUrodzenia); } void wypiszKlientow(){ int i; system("cls"); for(i = 0; i < sizeof(tKlienci)/sizeof(klient); i++){ if (strlen(tKlienci[i].PESEL) > 0){ wypiszKlienta(i); } } system("PAUSE"); }
Ćwiczenie (1) void zapisz(klient pDoZapisu) { FILE *plik; char a[100], sciezka[100] = "C:\\temp\\abc.txt" ; if ((plik = fopen(sciezka, "a")) == NULL) { printf("Nie moznaotworzyc %s\n", sciezka); system("PAUSE"); exit(1); } fprintf(plik, "PESEL:%s\n", pDoZapisu.PESEL); fprintf(plik, "Imie:%s\n", pDoZapisu.imie); fprintf(plik, "Nazwisko:%s\n", pDoZapisu.nazwisko); fprintf(plik, "Rok urodzenia:%d\n", pDoZapisu.rokUrodzenia); fclose(plik); } voidtKlienciDodaj(klient nowy){ int i; for(i = 0; i < sizeof(tKlienci)/sizeof(klient); i++){ if (strlen(tKlienci[i].PESEL)==0){ tKlienci[i] = nowy; return; } } } void dodaj(){ klient nowy; printf("WprowadzPESEL:\n"); scanf("%s", &nowy.PESEL); printf("Wprowadzimie:\n"); scanf("%s", &nowy.imie); printf("Wprowadznazwisko:\n"); scanf("%s", &nowy.nazwisko); printf("Wprowadz rok urodzenia:\n"); scanf("%d", &nowy.rokUrodzenia); tKlienciDodaj(nowy); };
Ćwiczenie (1) void edytujNazwisko(int i){}; void edytujImie(int i){ wypiszKlienta(i); printf("Wprowadz nowe imie:"); scanf("%s", tKlienci[i].imie); }; void edytuj(){ int i, option; wypiszKlientow(); printf("Wprowadz numer klienta do edycji:"); scanf("%d", &i); do { printf("Wybierz opcję:\n1 - Edytuj imie\n2 - Edytuj nazwisko\n0 - powrot do menu\n"); scanf("%d", &option); switch(option){ case 0: break; case 1: edytujImie(i - 1); break; case 2: edytujNazwisko(i - 1); break; } } while (option != 0); }; void usun(){};
Ćwiczenie (1) int znajdzImie(char *szukane){ char imie2[30], imie1[30]; strcpy(imie2, strtoupper(szukane)); int i; for (i = 0; i < sizeof(tKlienci)/sizeof(klient); i++){ //if (strstr(toupper(tKlienci[i].imie), toupper(szukane)) != NULL) return i; strcpy(imie1, strtoupper(tKlienci[i].imie)); if (strstr(imie1, imie2) != NULL) return i; } return -1; } void wyszukajImie(){ char szukane[50]; int option, znalezione; printf("Imie: "); scanf("%s", szukane); znalezione = znajdzImie(szukane); if (znalezione != -1) wypiszKlienta(znalezione); else printf("Nie znaleziono klienta o imieniu %s\n", szukane); } void wyszukajNazwisko(){};
Ćwiczenie (1) void wyszukaj(){ int option; do { printf("Wybierz opcję:\n1 - Wyszukaj imie\n2 - Wyszukaj nazwisko\n0 - powrot do menu\n"); scanf("%d", &option); switch(option){ case 0: break; case 1: wyszukajImie(); break; case 2: wyszukajNazwisko(); break; } } while (option != 0); }; void zakoncz(){ int i; system("del c:\\temp\\abc.txt"); for(i = 0; i < sizeof(tKlienci)/sizeof(klient); i++){ if (strlen(tKlienci[i].PESEL) > 0) zapisz(tKlienci[i]); } };
Ćwiczenie (1) int main(int argc, char *argv[]){ wczytajKlientow(); int option; while(option!=0){ //system("cls"); printf("Wybierz opcję:\n1 - Dodaj kienta\n2 - Edytuj klienta\n3 - Usuń klienta\n"); printf("4 - Wyszukaj klienta\n5 - Wypisz klientow\n0 - Zakończ\n"); scanf("%d", &option); switch(option){ case 0: zakoncz(); break; case 1: dodaj(); break; case 2: edytuj(); break; case 3: usun(); break; case 4: wyszukaj(); break; case 5: wypiszKlientow(); break; } } system("PAUSE"); return 0; }
Zadanie 1) Popraw program tak, aby funkcja znajdzImie zwracała nie pierwszy znaleziony rekord, ale tablicę rekordów spełniających kryterium wyszukiwania. 2) Zmodyfikuj funkcję strtoupper tak, aby nie zmieniała wartości przekazywanej jako parametr.
Uruchamianie zewnętrznych aplikacji (1) • Plik nagłówkowy windows.h zawiera prototyp funkcji WinExec pozwalającej uruchomić zewnętrzną aplikację. Pierwszy parametr funkcji wskazuje uruchamiany plik, zaś drugi przyjmuje wartości: • SW_HIDE - okno aplikacji jest niewidoczne • SW_MINIMIZE - okno aplikacji jest zminimalizowane • SW_SHOWNORMAL - standardowe okno aplikacji • Zadanie: • 1) Przepisz i uruchom poniższy progran • #include <windows.h> • int main() • { • WinExec("NOTEPAD.exe", SW_SHOWNORMAL); • } • 2) Zmodyfikuj program tak, aby uruchomiony został Excel • 3) Zmodyfikuj program tak, by otwarta została wpisana przez użytkownika liczba okienek notatnika
Okna dialogowe (1) • Plik nagłówkowy windows.h zawiera prototyp funkcji MessageBox pozwalającej wyświetlać okna dialogowe. Funkcja ma postać: • int Message Box(hwndParent, lpszText, lpszTitle, Style) • Parametry: • HWND hwndParent - identyfikator macierzystego okna (głównego okna aplikacji), • LPCSTR lpszText - łańcuch tekstowy wewnątrz okienka, • LPCSTR lpszTitle - łańcuch tekstowy tytułu okienka komunikatu, • UINT Style - numer określający zawartość okienka (m. in. MB_OK, MB_OKCANCEL, MB_RETRYCANCEL, MB_ICONQUESTION, MB_ABORTRETRYIGNORE, MB_HELP, MB_YESNO, MB_YESNOCANCEL) • Funkcja zwraca identyfikator klawisza wybranego przez użytkownika
Okna dialogowe (2) • Zadanie: • 1) Przepisz i uruchom program: • #include <windows.h> • int main() • { • MessageBox(0,"Wystąpił nieoczekiwany błąd","Błąd programu", MB_OK); • } • 2) Zmień komunikat i tytuł okna dialogowego. • 3) Przetestuj inne style okna dialogowego.
Okna dialogowe (3) • Funkcja MessageBox() zwraca identyfikator klawisza wybranego przez użytkownika. Wartość ta może wpływać na dalszą pracę programu. • Zadanie: • 1) Przepisz i uruchom poniższy program: • # include <windows.h> • main() • { • if( MessageBox(0, "Jeszcze jedno okno?", "Tytuł", MB_OKCANCEL) == IDOK) • MessageBox(0, "Drugie okno", "Tytuł 2", MB_OK); • else • if( MessageBox(0, "Może jednak?", "Tytuł", MB_YESNO) == IDYES) • MessageBox(0, "Drugie okno", "Tytuł 2", MB_OK); • } • 2) Zmodyfikuj powyższy program tak, aby w zależności od wyboru użytkownika uruchamiany był notatnik lub Excel.
Tworzenie okna programu (1) 1) Utwórz nowy projekt wybierając opcję „Windows Application” 2) Skompiluj i uruchom utworzony program
Tworzenie okna programu (2) • Informacje o oknie przechowywane są w strukturze WNDCLASSEX. Struktura ta zawiera m. in. dane o Window Procedure kontrolującej działanie okna, ikonach, kursorze i tle. • Przykład: • wc.cbSize = sizeof(WNDCLASSEX); • wc.style = 0; • wc.lpfnWndProc = WndProc; • wc.cbClsExtra = 0; • wc.cbWndExtra = 0; • wc.hInstance = hInstance; • wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); • wc.hCursor = LoadCursor(NULL, IDC_ARROW); • wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); • wc.lpszMenuName = NULL; • wc.lpszClassName = g_szClassName; • wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
Tworzenie okna programu (3) • Pola struktury okna: • cbSize - rozmiar struktury, • style - styl klasy (CS_*), np. CS_BYTEALIGNCLIENT, CS_BYTEALIGNWINDOW, CS_KEYCVTWINDOW, CS_NOKEYCVT, CS_CLASSDC, CS_DBLCLKS, • lpfnWndProc - wskaźnik do Window Procedure danego okna, • cbClsExtra - ilość dodatkowej pamięci przydzielonej klasie, • cbWndExtra - ilość dodatkowej pamięci przydzielonej oknu, • hInstance - uchwyt do instancji aplikacji (przekazany w pierwszym parametrze WinMain), • hIcon - ikona (zazwyczaj 32x32) pokazywana przy naciśnięciu Alt+Tab, • hCursor - kursos wyświetlany w oknie • hbrBackground - kolor okna, • lpszMenuName - nazwa menu okna, • LpszClassName - nazwa klasy, • hIconSm - ikona (zazwyczaj 16x16) pokazywana w pasku zadań i w lewym górnym rogu okna.
Tworzenie okna programu (4) Zadanie: 1) Zmodyfikuj program utworzony przez Dev-C++ zmieniając kursor za pomocą stałych: IDC_HELP, IDC_WAIT, IDC_CROSS, IDC_HAND, IDC_NO, IDC_APPSTARTING, IDC_UPARROW, IDC_IBEAM, IDC_SIZEWE, IDC_SIZENS. 2) Zmodyfikuj parametr hIcon okna. Jako drugi parametr funkcji LoadIcon wstaw IDI_QUESTION, IDI_HAND, IDI_EXCLAMATION, IDI_ASTERISK, IDI_WINLOGO. Sprawdź działanie parametrów naciskając Alt+Tab po uruchomieniu programu.
Tworzenie okna programu (5) • Po ustaleniu wartości pól struktury okna należy je zarejestrować: • if(!RegisterClassEx(&wc)) • { • MessageBox(NULL, "Window Registration Failed!", "Error!", • MB_ICONEXCLAMATION | MB_OK); • return 0; • } • W kolejnym kroku można już utworzyć okno aplikacji: • hwnd = CreateWindowEx( • WS_EX_CLIENTEDGE, • g_szClassName, • "The title of my window", • WS_OVERLAPPEDWINDOW, • CW_USEDEFAULT, CW_USEDEFAULT, 240, 120, • NULL, NULL, hInstance, NULL);
Tworzenie okna programu (6) • Parametry funkcji CreateWindowEx; • styl obramowania okna, • nazwa klasy, • tytuł okna, • styl okna, • współrzędna x lewego górnego rogu okna, • współrzędna y lewego górnego rogu okna, • szerokość okna, • wysokość okna, • uchwyt macierzystego okna, • uchwyt menu, • uchwyt instancji aplikacji, • dodatkowe dane o oknie (rzadko używane).
Tworzenie okna programu (7) Zadanie: 1) Zmodyfikuj parametry położenia i wielkości tworzonego okna. 2) Zmodyfikuj program zmieniając kolejno wartości pierwszego parametru funkcji CreateWindowEx na WS_EX_LAYERED, WS_EX_WINDOWEDGE, WS_EX_PALETTEWINDOW. Zaobserwuj zmiany wyglądu okna w zależności od tego parametru.
Obsługa zdarzeń (1) • Każde zdarzenie ruchu myszy, naciśnięcia klawisza, kliknięcie na pozycję menu itp. generuje informację przechwytywaną przez aplikację i wstawianą do kolejki zdarzeń. Wywołanie GetMessage() powoduje pobranie z kolejki kolejnego zdarzenia w celu jego obsługi przez program. Jeśli kolejka jest pusta aplikacje oczekuje na kolejne zdarzenie. • Przykład: • while(GetMessage(&Msg, NULL, 0, 0) > 0) • { • TranslateMessage(&Msg); • DispatchMessage(&Msg); • } • return Msg.wParam;
Obsługa zdarzeń (2) • WndProc jest uruchamiany dla każdego zdarzenia. • Parametry: • hwnd - uchwyt okna - wiele okien może używać tej samej metody WndProc • msg - identyfikator zdarzenia • Przykład: • LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) • { • switch (message) /* handle the messages */ • { • case WM_DESTROY: • PostQuitMessage (0); /* send a WM_QUIT to the message queue */ • break; • default: /* for messages that we don't deal with */ • return DefWindowProc (hwnd, message, wParam, lParam); • } • return 0; • }
Obsługa zdarzeń (3) • Przykład: • Dodanie obsługi zdarzenia myszki. • LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) • { • switch (message) /* handle the messages */ • { • case WM_LBUTTONDOWN: • MessageBox(hwnd, "Obsłużono zdarzenie myszki", "Komunikat o zdarzeniu", MB_OK); • break; • case WM_DESTROY: • PostQuitMessage (0); /* send a WM_QUIT to the message queue */ • break; • default: /* for messages that we don't deal with */ • return DefWindowProc (hwnd, message, wParam, lParam); • } • return 0; • }
Obsługa zdarzeń (4) Zadanie: 1) Dodaj obsługę zdarzeń obrotu rolki myszki (WM_MOUSEWHEEL), utworzenia okna (WM_CREATE), naciśnięcia klawisza klawiatury (WM_KEYDOWN), przesunięcia okna (WM_MOVE), podwójnego kliknięcia lewego klawisza myszy (WM_LBUTTONDBLCLK), pojedynczego kliknięcia prawego klawisza myszy (WM_RBUTTONDOWN). Przy wystąpieniu każdego ze zdarzeń dodaj okno dialogowe z odpowiednim komunikatem.
Menu (1) • W celu utworzenia w okienku menu należy obsłużyć zdarzenie WM_CREATE wywołując w nim kolejno metody: • CreateMenu – tworzy menu • AppendMenu – dodaje element menu • SetMenu – przypisuje menu do okna • Przykład: • case WM_CREATE: • { • HMENU hMenu, hSubMenu; • HICON hIcon, hIconSm; • hMenu = CreateMenu(); • hSubMenu = CreatePopupMenu(); • AppendMenu(hSubMenu, MF_STRING, 9001, "E&xit"); • AppendMenu(hMenu, MF_STRING | MF_POPUP, (UINT)hSubMenu, "&File"); • hSubMenu = CreatePopupMenu(); • AppendMenu(hSubMenu, MF_STRING, 9002, "&Go"); • AppendMenu(hMenu, MF_STRING | MF_POPUP, (UINT)hSubMenu, "&Stuff"); • SetMenu(hwnd, hMenu); • }
Menu (2) Zadanie: 1) Skonstruuj okno z menu zawierającym funkcje dostępne w Twoim semestralnym programie zaliczeniowym. Aplikację zachowaj do wykorzystania w kolejnym ćwiczeniu.
Menu (3) • Obsługa zdarzeń menu • Wybór przez użytkownika opcji menu powinien powodować określone akcje. • Przykład: • case WM_COMMAND: • switch(LOWORD(wParam)) • { • case 9001: • MessageBox(hwnd, "Wyjście", "Komunikat o zdarzeniu", MB_OK); • break; • case 9002: • MessageBox(hwnd, "Przejdź do...", "Komunikat o zdarzeniu", MB_OK); • break; • } • break;
Menu (4) Zadanie: 1) Dodaj do utworzonej w poprzednim ćwiczeniu aplikacji obsługę zdarzeń wyboru pozycji z menu.
Standardowe kontrolki (1) • Pole edycyjne • Przykład: • case WM_CREATE: • { • HFONT hfDefault; • HWND hEdit; • hEdit = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "", • WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_HSCROLL | ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL, • 0, 0, 100, 100, hwnd, (HMENU)IDC_MAIN_EDIT, GetModuleHandle(NULL), NULL); • if(hEdit == NULL) • MessageBox(hwnd, "Could not create edit box.", "Error", MB_OK | MB_ICONERROR); • hfDefault = GetStockObject(DEFAULT_GUI_FONT); • SendMessage(hEdit, WM_SETFONT, (WPARAM)hfDefault, MAKELPARAM(FALSE, 0)); • } • Zadania: • 1) Sprawdź działanie programu po usunięciu wybranych flag związanych z trzecim parametrem funkcji CreateWindowEx (parametry o nazwach WS_*)
Standardowe kontrolki (2) • Lista • Przykład: • case WM_CREATE: • { • hLB = CreateWindowEx(WS_EX_CLIENTEDGE, "LISTBOX", "", • WS_CHILDWINDOW | WS_VISIBLE | WS_BORDER|LBS_SORT, • 10, 10, 200, 60, hwnd, (HMENU)9004, GetModuleHandle(NULL), NULL); • if(hLB == NULL) • MessageBox(hwnd, "Could not create list box.", "Error", MB_OK | MB_ICONERROR); • SendMessage (hLB, LB_INSERTSTRING, (WPARAM) -1, (LPARAM) "Opcja 1"); • SendMessage (hLB, LB_INSERTSTRING, (WPARAM) -1, (LPARAM) "Opcja 2"); • SendMessage (hLB, LB_INSERTSTRING, (WPARAM) -1, (LPARAM) "Opcja 3"); • hfDefault = GetStockObject(DEFAULT_GUI_FONT); • SendMessage(hLB, WM_SETFONT, (WPARAM)hfDefault, MAKELPARAM(FALSE, 0)); • break; • } • Zadanie • 1) Dodaj do aplikacji listę zawierającą opcje związane tematycznie z Twoim semestralnym programem zaliczeniowym.
Standardowe kontrolki (3) Lista combo Przykład: HWND hCombo; hCombo = CreateWindowEx(0, WC_COMBOBOXEX, 0, WS_CHILD | WS_VISIBLE | CBS_DROPDOWNLIST, 30, 210, 150, 150, hwnd, (HMENU)107, GetModuleHandle(NULL), 0); COMBOBOXEXITEM item; item.mask = CBEIF_TEXT | CBEIF_IMAGE | CBEIF_SELECTEDIMAGE; item.iItem = 0; item.iImage = 0; item.iSelectedImage = 1; item.cchTextMax = sizeof("Opcja 1"); item.pszText = "Opcja 1"; SendMessage(hCombo, CBEM_INSERTITEM, 0, (LPARAM)&item); break;
Standardowe kontrolki (4) • Przyciski • Przykład: • CreateWindow("button", "Przycisk", • WS_CHILD | WS_VISIBLE, 30,100,100,40, hwnd, (HMENU)101, • GetModuleHandle(NULL), NULL); • Przyciski radio • Przykład: • CreateWindow("button", "Przycisk", WS_CHILD | WS_VISIBLE | BS_RADIOBUTTON, 30,150,100,20, hwnd, (HMENU)105, GetModuleHandle(NULL), NULL); • Pasek przewijania • Przykład: • hScrollBar = CreateWindow("SCROLLBAR", NULL, WS_CHILD | WS_VISIBLE • | SBS_VERT, 0, 0, 15, 200, hwnd, (HMENU)100, GetModuleHandle(NULL), NULL);
Standardowe kontrolki (5) Zadania: 1) Dodaj do aplikacji kilka przycisków związanych tematycznie z semestralnym programem zaliczeniowym. 2) Dodaj grupę przycisków radio zawierającą opcję wyboru związaną z programem zaliczeniowym. 3) Dodaj pionowy pasek przewijania.
Pasek statusu (1) • Pole edycyjne • Przykład: • HWND hStatus; • int statwidths[] = {100, -1}; • hStatus = CreateWindowEx(0, STATUSCLASSNAME, NULL, • WS_CHILD | WS_VISIBLE | SBARS_SIZEGRIP , 0, 0, 0, 0, • hwnd, (HMENU)108, GetModuleHandle(NULL), NULL); • SendMessage(hStatus, SB_SETPARTS, sizeof(statwidths)/sizeof(int), (LPARAM)statwidths); • SendMessage(hStatus, SB_SETTEXT, 0, (LPARAM)"Tekst paska statusowego"); • Zadanie • 1) Dodaj pasek statusu do swojej aplikacji i wyświetl w nim aktualną datę i godzinę