Autor podstrony: Krzysztof Zajączkowski

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

Wstęp

W systemie Windows stosowane są pewne podstawowe typy zarejestrowanych klas okien, które można utworzyć korzystając z znanej już funkcji CreateWindow. W funkcji tej pierwszy parametr przyjmuje łańcuch znaków opisujący nazwę klasy zarejestrowanego już wcześniej okna. Oto lista podstawowych nazw klas okien, z których można korzystać:

Każde z wyżej wymienionych nazw klas okien ma swoje własne dodatkowe style, które mogą być użyte wraz z standardowymi stylami okna zawierającymi przedrostek . Na tej stronie omówię nieco sposób tworzenia i podstawę obsługi tylko niektórych z powyższych klas okien.

Podczas tworzenia uchwytu okna danej klasy (które najczęściej jest oknem potomnym) należy zamiast parametru HMENU podać unikalny identyfikator okna, który będzie przekazywany w komunikacie WM_COMMAND jako niższe słowo parametru wParam użytego w funkcji obsługi komunikatów okna rodzica.

Kontrolka klasy "BUTTON"

Flagi stylów kontrolki

Przyciski należą do jednych z najprostszych okien, ich zadanie jest również proste: reakcja na kliknięcie lub zmiana jakiegoś tanu ustawienia. Co ciekawe w zależności od użytego stylu wewnętrznego tej kontrolki można uzyskać zupełnie inne jej wersje i funkcjonalności. Oto kilka przykładowych flag stylów, które wpływają w ten sposób na wygląd tej kontrolki:

Zgrupowanie kontrolek typu radiobutton sprawia, że tylko jedno pole wyboru jest możliwe do zaznaczenia.

Możliwe do wysłania komunikaty

Kontrolka przycisku przetwarza pewne komunikaty, które można do niej wysłać ręcznie za pomocą funkcji SendMessage uzyskując możliwość pozyskiwania lub ustawiania pewnych właściwości tej kontrolki w trakcie działania programu, oto lista niektórych z nich:

Wysyłane notyfikacje do okna rodzica

No i pytanie, co to są te notyfikacje? Są to obowiązkowe powiadomienia, jakie dane okno potomne jest zobowiązane wysłać do okna rodzica w celu przekazania pewnej konkretnej informacji. A jaka to może być ta konkretna informacja? A no na przykład w przypadku przycisku to chciałoby się otrzymać jakąś informację, że ten przycisk został wciśnięty. Teraz pozostaje pytanie jaki komunikat i w jaki sposób przesyłać te notyfikacje? Tym komunikatem jest komunikat WM_COMMAND, który jako parametr lParam otrzymuje uchwyt kontrolki, od której notyfikacja przychodzi, natomiast sam identyfikator informujący o zajściu tak podniosłego zdarzenia jakim jest wciśnięcie przycisku jest zawarty w wyższym słowie parametru wParam. Pozostało oczywiście jeszcze wyższe słowo tegoż parametru, które zawiera identyfikator kontrolki.

Oto lista notyfikacji, jakie wysyła kontrolka przycisku do okna rodzica:

I na koniec notyfikacja, która jest tak naprawdę komunikatem otrzymywanym przez okno rodzica:

Kontrolka klasy "COMBOBOX"

Flagi stylów kontrolki

Okno typu combobox jest to okno wyboru (pojedynczego), które wyposażone jest w rozwijaną listę wyboru. Poniżej zamieszczam niektóre flagi dostępnych stylów tego okna:

Możliwe do wysłania komunikaty

Oto lista flag komunikatów, jakie można wysyłać do okna typu combobox w celu pozyskiwania lub zmiany ustawień okna za pomocą funkcji SendMessage:

Wysyłane notyfikacje do okna rodzica

Oto lista notyfikacji wysyłanych do okna rodzica kontrolki w komunikacie WM_COMMAND:

Lista komunikatów wysyłanych bezpośrednio do okna rodzica:

Konstrolka typu "EDIT"

Flagi stylów kontrolki

Okno typu edit było już użyte w projekcie prostego i dość ubogiego w funkcjonalność notatnika, jednakże nie omówiłem tam szczegółów dotyczących możliwych stylów tego typu okna, co też i tutaj z najdzikszą wręcz rozkoszą czynię:

Możliwe do wysłania komunikaty

Dostępna jest następująca lista komunikatów, jakie można wysłać do tego typu okna za pomocą funkcji SendMessage:

Wysyłane notyfikacje do okna rodzica

Oto lista notyfikacji, które są wysyłane do okna rodzica w komunikacie WM_COMMAND:

Komunikat wysyłany bezpośrednio do okna rodzica:

Kontrolka klasy "LISTBOX"

Flagi stylów kontrolki

Lista stylów kontrolki typu list box, które użyte w funkcji CreateWindow wpływają na wygląd bądź funkcjonalność kontrolki:

Możliwe do wysłania komunikaty

Oto lista komunikatów, jakie można wysłać do okna w celu zmiany jego zachowania, wyglądu lub pozyskania informacji o nim:

Wysyłane notyfikacje do okna rodzica

Lista notyfikacji wysyłanych do okna rodzica w komunikacie WM_COMMAND:

Kontrolka klasy "SCROLLBAR"

Flagi stylów kontrolki

Lista flag stylów, jakie kontrolka może użyć w funkcji CreateWindow by wpłynąć na swój wygląd lub zachowanie:

Możliwe do wysłania komunikaty

Oto lista komunikatów, które można wysłać do kontrolki za pomocą funkcji SendMessage w celu uzyskania informacji o kontrolce lub ich ustawieniu:

Notyfikacje wysyłane do okna rodzica:

Oto lista notyfikacji wysyłanych przez kontrolkę bezpośrednio do okna rodzica:

Kontrolka klasy "STATIC"

Flagi stylów kontrolki

Lista flag stylów, jakie kontrolka może użyć w funkcji CreateWindow by wpłynąć na swój wygląd lub zachowanie:

Możliwe do wysłania komunikaty

Oto lista komunikatów, które można wysłać do kontrolki za pomocą funkcji SendMessage w celu uzyskania informacji o kontrolce lub ich ustawieniu:

Notyfikacje wysyłane do okna rodzica:

Oto lista notyfikacji wysyłanych przez kontrolkę w komunikacie WM_COMMAND do okna rodzica:

Funkcje tworzące nowe okno danej klasy

Funkcja CreateWindow

Funkcja CreateWindow umożliwia tworzenie nie tylko kontrolek wyżej wymienionych nazw klas okien, ale (jak już wcześniej było to mówione i wykorzystywane w projektach) również tworzenie egzemplarzy dowolnych zarejestrowanych nazw okien. Omówię tutaj parametry tejże funkcji, w której można ustawić własne dodatkowe style okna:

HWND CreateWindow( LPCTSTR lpClassName, // nazwa klasy okna LPCTSTR lpWindowName, // tekst zawarty w oknie (np. belce tytułowej, wewnątrz przycisku, kontrolki edycji, kontrolki statycznej DWORD dwStyle, // style własne i te podstawowe okna int x, // położenie na x-sie (można użyć CW_USEDEFAULT żeby system sam domyślnie ustawił) int y, // położenie na y-ku (można użyć CW_USEDEFAULT żeby system sam domyślnie ustawił) int nWidth, // szerokość (można użyć CW_USEDEFAULT żeby system sam domyślnie ustawił) int nHeight, // wysokość (można użyć CW_USEDEFAULT żeby system sam domyślnie ustawił) HWND hWndParent, // uchwyt okna rodzica (czasami nie ma i wtedy jest NULL) HMENU hMenu, // uchwyt menu, ale w przypadku kontrolki to raczej identyfikator okna potomnego HINSTANCE hInstance, // uchwyt instancji LPVOID lpParam // dodatkowe dane dla okna );

W przypadku kontrolek pole lpClassName powinno zawierać nazwę klasy kontrolki (mp. "EDIT"). Kolejny parametr, na który warto zwrócić uwagę to dwStyle, ten parametr przyjmuje kombinację stylów ogólnych oraz własnych, czyli takich, które są powiązane ściśle z danym typem klasy okna. Ogólne dostępne style okna to:

Funkcja CreateWindowEx

Zasadniczo, funkcja ta różni się od funkcji CreateWindowEx tylko jednym parametrem, dzięki któremu można nadawać oknom dodatkowe style. Oto nagłówek tej funkcji:

HWND CreateWindowEx( DWORD dwExStyle, // dodatkowe style okna LPCTSTR lpClassName, // nazwa klasy okna LPCTSTR lpWindowName, // tekst zawarty w oknie (np. belce tytułowej, wewnątrz przycisku, kontrolki edycji, kontrolki statycznej DWORD dwStyle, // style własne i te podstawowe okna int x, // położenie na x-sie (można użyć CW_USEDEFAULT żeby system sam domyślnie ustawił) int y, // położenie na y-ku (można użyć CW_USEDEFAULT żeby system sam domyślnie ustawił) int nWidth, // szerokość (można użyć CW_USEDEFAULT żeby system sam domyślnie ustawił) int nHeight, // wysokość (można użyć CW_USEDEFAULT żeby system sam domyślnie ustawił) HWND hWndParent, // uchwyt okna rodzica (czasami nie ma i wtedy jest NULL) HMENU hMenu, // uchwyt menu, ale w przypadku kontrolki to raczej identyfikator okna potomnego HINSTANCE hInstance, // uchwyt instancji LPVOID lpParam // dodatkowe dane dla okna );

Parametr dwExStyle funkcji CreateWindoEx umożliwia nadanie oknom następujących stylów:

Przykładowa implementacja programu z kontrolkami

Poniżej zamieszczam dość przydługawy kod, w którym w komentarzach postarałem się opisać sposób tworzenia i podstawowej obsługi kontrolek:

#include <windows.h> #include <Commctrl.h> //#################################### obliczeniow.com.pl/Programowanie%20Cpp_WinApi%20Podstawowe_klasy_okien_systemu_Windows ################################## // ################################### IDENTYFIKATORY KONTROLEK ##################################### #define ID_BUTTON_OK 100 #define ID_BUTTON_CHECKBOX 101 #define ID_BUTTON_RADIOBUTTON 102 #define ID_BUTTON_COMMANDLINK 103 #define ID_BUTTON_GROUPBOX 104 #define ID_BUTTON_RADIOBUTTON2 105 #define ID_COMBOBOX 106 #define ID_COMBOBOX2 107 #define ID_LISTBOX 108 #define ID_STATIC 108 // ################################### UCHWYTY KONTROLEK ############################################ HWND hWnd; HWND hButtonGroupbox; HWND hButtonOK; HWND hButtonCheckbox; HWND hButtonRadiobutton; HWND hButtonRadiobutton2; HWND hComboBox; HWND hComboBox2; HWND hListBox; HWND hStatic; LRESULT CALLBACK hwndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam){ static RECT wndSize; // zmienna statyczna przechowująca informacje o wymiarach okna switch(msg){ case WM_CREATE: // ten komunikat będzie obsłużony zawsze jako pierwszy { } break; case WM_DESTROY: // ten komunikat będzie obsłużony, gdy wciśniesz przycisk zamknięcia programu { PostQuitMessage(0); // kończy program } break; //############################################## OBSŁUGA KONTROLKI PASKA PRZEWIJANIA POZIOMEGO ############################################## case WM_HSCROLL: { if(lParam == NULL){ // gdy lParam jest równe NULL to komunikat przychodzi od kontrolki pionowego paska przewijania automatycznie dodanego do okna za pomocą stylu WS_HSCROLL SCROLLINFO si; // struktura opisująca stan paska przewijania ZeroMemory(&si, sizeof(si)); // zerowanie pól struktury si.cbSize = sizeof(si); // rozmiar struktury w bajtach si.fMask = SIF_ALL; // maska infromująca, że pobierane będą wszystkie parametry kontrolki GetScrollInfo(hWnd, SB_HORZ, &si); // pobieranie informacji o kontrolce switch(LOWORD(wParam)){ case SB_LINELEFT: // przewijanie w lewo { si.nPos -= 1; } break; case SB_LINERIGHT: // przewijanie w prawo { si.nPos += 1; } break; case SB_PAGELEFT: // przewijanie w lewo o zadaną wartość { si.nPos -= 10; } break; case SB_PAGERIGHT: // przewijanie w lewo o zadaną wartość { si.nPos += 10; } break; case SB_THUMBPOSITION: // przewijanie paska poprzez przesuwanie i opuszczenie lewego przycisku myszy { si.nPos = si.nTrackPos; } break; //case SB_THUMBTRACK: // { // si.nPos = si.nTrackPos; // } // break; } si.fMask = SIF_POS; // tym razem ustawione zostanie tylko położenie SetScrollInfo(hWnd, SB_HORZ, &si, true); // wprowadzanie zmian wraz z odświerzaniem kontrolki } } break; //############################# OBSŁUGA PASKA PRZEWIJANIA PIONOWEGO #################################### case WM_VSCROLL: { if(lParam == NULL){ SCROLLINFO si; ZeroMemory(&si, sizeof(si)); si.cbSize = sizeof(si); si.fMask = SIF_ALL; GetScrollInfo(hWnd, SB_VERT, &si); switch(LOWORD(wParam)){ case SB_LINELEFT: { si.nPos -= 1; } break; case SB_LINERIGHT: { si.nPos += 1; } break; case SB_PAGELEFT: { si.nPos -= 10; } break; case SB_PAGERIGHT: { si.nPos += 10; } break; case SB_THUMBPOSITION: { si.nPos = si.nTrackPos; } break; //case SB_THUMBTRACK: // { // si.nPos = si.nTrackPos; // } // break; } si.fMask = SIF_POS; SetScrollInfo(hWnd, SB_VERT, &si, true); } } break; case WM_COMMAND: { // ############################# OBSŁUGA KOMUNIKATÓW KONSTROLEK ################################# if(lParam){ switch(LOWORD(wParam)){ case ID_BUTTON_OK: // przycisk ok { switch(HIWORD(wParam)){ case BN_CLICKED: // kliknięty { MessageBox(hWnd, L"O! Kliknąłeś przycisk OK!",L"Informacja",MB_OK); } break; } } break; case ID_BUTTON_CHECKBOX: // przycisk checkbox { switch(HIWORD(wParam)){ case BN_CLICKED: // kliknięty { UINT c = SendMessage(HWND(lParam), BM_GETCHECK, 0, 0); SendMessage(HWND(lParam), BM_SETCHECK, (SendMessage(HWND(lParam), BM_GETCHECK, 0, 0) == BST_CHECKED) ? BST_UNCHECKED : BST_CHECKED, 0); } break; } } break; case ID_BUTTON_RADIOBUTTON: // pierwszy przycisk radiobutton { switch(HIWORD(wParam)){ case BN_CLICKED: // kliknięty { SendMessage(HWND(lParam), BM_SETCHECK, BST_CHECKED, 0); SendMessage(hButtonRadiobutton2, BM_SETCHECK, BST_UNCHECKED, 0); } break; } } break; case ID_BUTTON_RADIOBUTTON2: // drugi przycisk radiobutton { switch(HIWORD(wParam)){ case BN_CLICKED: // kliknięty { SendMessage(HWND(lParam), BM_SETCHECK, BST_CHECKED, 0); SendMessage(hButtonRadiobutton, BM_SETCHECK, BST_UNCHECKED, 0); } break; } } break; case ID_COMBOBOX: // COMBOBOX { switch(HIWORD(wParam)){ case CBN_SELCHANGE: // zmieniono zaznaczenie { MessageBox(hWnd, L"Zmieniono zaznaczenie", L"Informacja",MB_OK); } break; } } break; case ID_COMBOBOX2: // COMBOBOX2 { switch(HIWORD(wParam)){ case CBN_SELCHANGE: // zmieniono zaznaczenie { MessageBox(hWnd, L"Zmieniono zaznaczenie", L"Informacja",MB_OK); } break; } } break; case ID_LISTBOX: // LISTBOX { switch(HIWORD(wParam)){ case LBN_SELCHANGE: // zmieniono zaznaczenie { MessageBox(hWnd, L"Zmieniono zaznaczenie", L"Informacja",MB_OK); } break; } } break; } } } break; case WM_SIZE: { SetRect(&wndSize,0,0,LOWORD(lParam),HIWORD(lParam)); // ustawia strukturę wndSize tak, aby przechowywała szerokość i wysokość okna } break; } return DefWindowProc(hWnd, msg, wParam, lParam); } int WINAPI WinMain(HINSTANCE hInst, HINSTANCE , LPSTR str, int ){ WNDCLASS wnd; wchar_t wndClassName[] = L"KontrolkiWindows"; wnd.cbClsExtra = NULL; // ten parametr powinien być ustawiony na null (powinien on zawierać informacje o rozmiarze dodatkowych danych jakie będą przechowywane dla danej klasy okna) wnd.cbWndExtra = NULL; // ten parametr powinien być ustawiony na null (powinien on zawierać informacje o rozmiarze dodatkowych danych jakie będą przechowywane dla danego egzemplarza okna) wnd.hbrBackground = CreateSolidBrush(GetSysColor(COLOR_BTNFACE)); // to będzie tło okna wnd.hCursor = LoadCursor(NULL, IDC_ARROW); // ładowanie standardowego kursora wnd.hIcon = LoadIcon(NULL, IDI_APPLICATION); // ładowanie standardowej ikonki aplikacji wnd.hInstance = hInst; // uchwyt instancji programu wnd.lpfnWndProc = hwndProc; // wskaźnik do funkcji będącej procedurą okna wnd.lpszClassName = wndClassName; // nazwa klasy okna wnd.lpszMenuName = NULL; // tutaj powinno być menu, ale tym razem nie będzie żadnego menu więc NULL wnd.style = CS_VREDRAW|CS_HREDRAW; // opcje wyświetlania okna CS_VREDRAW i CS_HREDRAW oznaczają odświerzanie okna w poziomie i pionie if(!RegisterClass(&wnd)){ // jeżeli nie udało się zarejestrować klassy okna MessageBox(NULL,L"Wzięło się i nie zarejestrowało", L"Błąd", MB_OK); // to płacz, że coś się stało return 0; // i zwracaj zero } //######################################## TWORZENIE OKNA GŁÓWNEGO ###################################### hWnd = CreateWindow(wndClassName, // nazwa klasy okna wndClassName, // tekst belki tytułowej okna WS_OVERLAPPEDWINDOW|WS_VSCROLL|WS_HSCROLL, // styl okna (ten oznacza z belką tytułową, przyciskami minimalizacji, maksymalizacji i zwijania oraz z ramką, oraz style poziomego i pionowego paska przewijania CW_USEDEFAULT, // pozycja x (CS_USEDEFAULT oznacza domyślne) CW_USEDEFAULT, // pozycja y (CS_USEDEFAULT oznacza domyślne) CW_USEDEFAULT, // szerokość (CS_USEDEFAULT oznacza domyślne) CW_USEDEFAULT, // wysokość (CS_USEDEFAULT oznacza domyślne) NULL, // okno rodzica (tutaj nie będzie takiego więc NULL) NULL, // wskaźnik do menu (też nie będzie więc NULL) hInst, // uchwyt instancji programu NULL // wskaźnik do dodatkowych danych ); //######################################### OKNA KONTROLEK ############################################### //######################################### PRZYCISKI ##################################################### hButtonGroupbox = CreateWindow(L"BUTTON", // nazwa klasy kontrolki L"GroupBox", // tekst wyświetlany w kontrolce WS_VISIBLE|WS_CHILD|BS_GROUPBOX , // flagi podstawowe: widoczność; okno potomne; wciskany przycisk 10, 0, 140, 160, // położenie i wymiary hWnd, // okno rodzic (HMENU)ID_BUTTON_GROUPBOX, // identyfikator okna hInst, // uchwyt instancji programu NULL // to pole powinno być ustawione na NULL ); hButtonOK = CreateWindow(L"BUTTON", // nazwa klasy kontrolki L"OK", // tekst wyświetlany w kontrolce WS_VISIBLE|WS_CHILD|BS_PUSHBUTTON, // flagi podstawowe: widoczność; okno potomne; wciskany przycisk 20, 20, 120, 30, // położenie i wymiary hWnd, // okno rodzic (HMENU)ID_BUTTON_OK, // identyfikator okna hInst, // uchwyt instancji programu NULL // to pole powinno być ustawione na NULL ); hButtonCheckbox = CreateWindow(L"BUTTON", L"Checkbox", WS_VISIBLE|WS_CHILD|BS_CHECKBOX, // ostatni styl wyświetla pole wielokrotnego wyboru checbox 20, 50, 120, 30, hWnd, (HMENU)ID_BUTTON_CHECKBOX, // identyfikator okna hInst, NULL); hButtonRadiobutton = CreateWindow(L"BUTTON", L"Radiobutton", WS_VISIBLE|WS_CHILD|BS_RADIOBUTTON|WS_GROUP, // przycisk radio dla jednokrotnego wyboru 20, 90, 120, 30, hWnd, (HMENU)ID_BUTTON_RADIOBUTTON, // identyfikator przycisku hInst, NULL); hButtonRadiobutton2 = CreateWindow(L"BUTTON", L"Radiobutton2", WS_VISIBLE|WS_CHILD|BS_RADIOBUTTON|WS_GROUP, // przycisk radio dla jednokrotnego wyboru 20, 120, 120, 30, hWnd, (HMENU)ID_BUTTON_RADIOBUTTON2, // identyfikator przycisku hInst, NULL); //################################################ COMBO BOX-y ############################################################## hComboBox = CreateWindow(L"COMBOBOX", L"", WS_VISIBLE|WS_CHILD|WS_VSCROLL|CBS_AUTOHSCROLL|CBS_DROPDOWNLIST |CBS_DISABLENOSCROLL|CBS_SORT|CBS_NOINTEGRALHEIGHT , 160,10,120,100, hWnd, (HMENU)ID_COMBOBOX, hInst, NULL); SendMessage(hComboBox, CB_ADDSTRING, 0, (LPARAM) L"Polska"); SendMessage(hComboBox, CB_ADDSTRING, 0, (LPARAM) L"Francja"); SendMessage(hComboBox, CB_ADDSTRING, 0, (LPARAM) L"Dania"); SendMessage(hComboBox, CB_ADDSTRING, 0, (LPARAM) L"Słowacja"); SendMessage(hComboBox, CB_ADDSTRING, 0, (LPARAM) L"Czechy"); SendMessage(hComboBox, CB_ADDSTRING, 0, (LPARAM) L"Niemcy"); SendMessage(hComboBox, CB_ADDSTRING, 0, (LPARAM) L"Bułgaria"); SendMessage(hComboBox, CB_ADDSTRING, 0, (LPARAM) L"Szwecja"); SendMessage(hComboBox, CB_ADDSTRING, 0, (LPARAM) L"Włochy"); hComboBox2 = CreateWindow(L"COMBOBOX", L"", WS_VISIBLE|WS_CHILD|CBS_AUTOHSCROLL|WS_VSCROLL|CBS_DISABLENOSCROLL|CBS_SORT, 300,10,120,100, hWnd, (HMENU)ID_COMBOBOX2, hInst, NULL); SendMessage(hComboBox2, CB_ADDSTRING, 0, (LPARAM) L"Polska"); SendMessage(hComboBox2, CB_ADDSTRING, 0, (LPARAM) L"Francja"); SendMessage(hComboBox2, CB_ADDSTRING, 0, (LPARAM) L"Dania"); SendMessage(hComboBox2, CB_ADDSTRING, 0, (LPARAM) L"Słowacja"); SendMessage(hComboBox2, CB_ADDSTRING, 0, (LPARAM) L"Czechy"); SendMessage(hComboBox2, CB_ADDSTRING, 0, (LPARAM) L"Niemcy"); SendMessage(hComboBox2, CB_ADDSTRING, 0, (LPARAM) L"Bułgaria"); SendMessage(hComboBox2, CB_ADDSTRING, 0, (LPARAM) L"Szwecja"); SendMessage(hComboBox2, CB_ADDSTRING, 0, (LPARAM) L"Włochy"); //######################################## LISTBOX ######################################### hListBox = CreateWindow(L"LISTBOX", L"", WS_VISIBLE|WS_CHILD|WS_VSCROLL|LBS_SORT|LBS_HASSTRINGS|LBS_NOTIFY, 430,10,120,100, hWnd, (HMENU)ID_LISTBOX, hInst, NULL); SendMessage(hListBox, LB_ADDSTRING, 0, (LPARAM) L"Polska"); SendMessage(hListBox, LB_ADDSTRING, 0, (LPARAM) L"Francja"); SendMessage(hListBox, LB_ADDSTRING, 0, (LPARAM) L"Dania"); SendMessage(hListBox, LB_ADDSTRING, 0, (LPARAM) L"Słowacja"); SendMessage(hListBox, LB_ADDSTRING, 0, (LPARAM) L"Czechy"); SendMessage(hListBox, LB_ADDSTRING, 0, (LPARAM) L"Niemcy"); SendMessage(hListBox, LB_ADDSTRING, 0, (LPARAM) L"Bułgaria"); SendMessage(hListBox, LB_ADDSTRING, 0, (LPARAM) L"Szwecja"); SendMessage(hListBox, LB_ADDSTRING, 0, (LPARAM) L"Włochy"); SendMessage(hListBox, LB_ADDSTRING, 0, (LPARAM) L"Portugalia"); SendMessage(hListBox, LB_ADDSTRING, 0, (LPARAM) L"Hiszpania"); hListBox = CreateWindow(L"STATIC", L"Kontrolka Static", WS_VISIBLE|WS_CHILD, 560,10,120,30, hWnd, (HMENU)ID_STATIC, hInst, NULL); //######################################## KONIEC TWORZENIA KONTROLEK ########################################### ShowWindow(hWnd, SW_NORMAL); // wyświetlania okna i jego tryb UpdateWindow(hWnd); // wymuszenie pierwszego odświerzenia okna MSG msg; // struktura komunikatów while(GetMessage(&msg, 0,0,0)){ // dopóki nie otrzymano komunikatu == 0 TranslateMessage(&msg); // tłumacz komunikat DispatchMessage(&msg); // rozpakuj komunikat } return 0; }