Ĺadny brzuch
Sprawa przedstawia się następująco:
Chce zrobić w winAPI okno menu z 3 przyciskami (każde do rysowania wykresu) i chce żeby dla każdego przycisku otwierało się osobne okno na ktorym bedzie wyrysowany wykres i tutaj pojawia się problem, wiec zwracam się do was z zapytaniem jak to najlepiej zrobić.
Osobiście myślałem nad tym aby:
- to menu z przyciskami zrobić jako okno dialogowe z przyciskami i w zależności od wybranego przycisku rysować w głównym oknie wykres (tylko ze jest to jedno okno a chciałbym w osobnych a nie wiem jak to zrealizować).
- i druga opcja to odwrotna czyli w głównym oknie zrobić to menu z przyciskami a w oknach dialogowych rysować (o ile można w nim tak po prostu rysować jak w zwykłym oknie).
Z góry dzięki za udzieloną pomoc i porady.
oczywiście mile widziane są jakieś przykłady kodu, ale nie są wymagane. :)
P.S. aby zaoszczędzić Wam i mnie samemu czasu proszę nie zamieszczać tekstów z rodziny: "poszukaj sobie w google tam wszystko jest". Przeczytałem kilka różnych kursów do winAPI i szukałem po różnych forach ale nigdzie nie mogłem znaleźć przykłądu w którym ktoś tworzyłby okno potomne do okna rodzica niebędące kontrolką czy też oknem dialogowym.
Poszukaj w dokumentacji, bo tam wszystko jest ładnie opisane ;)
CreateWindow - paramert HWND hWndParent pozwala na określenie, które okno ma być rodzicem. Tworzysz główne okno (parametr hWndParent przyjmuje wartość NULL) z trzema przyciskami. Po naciśnięciu przycisku tworzysz okno potomne (jako parametr hWndParent przekazujesz uchwyt głównego okna).
OK. Dzięki :)
Mam taki kod:
#include <windows.h> #include <commctrl.h> #define CS_DROPSHADOW 0x00020000 HWND hButton,HWrodzic,HWpotomek1,HWpotomek2,HWpotomek3,HWpotomek4; CHAR szClassName[]="OknoRodzica"; HINSTANCE* hInst; LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM); INT WINAPI WinMain(HINSTANCE hInstance,HINSTANCE,LPSTR lStart,INT nShow) { hInst=&hInstance; WNDCLASSEX wc; wc.hInstance=*hInst; wc.lpszClassName=szClassName; wc.lpfnWndProc=WndProc; wc.style=0; wc.cbSize=sizeof(WNDCLASSEX); wc.hIcon=LoadIcon(0,IDI_APPLICATION); wc.hIconSm=LoadIcon(0,IDI_APPLICATION); wc.hCursor=LoadCursor(0,IDC_ARROW); wc.lpszMenuName="menu"; wc.cbClsExtra=0; wc.cbWndExtra=0; wc.hbrBackground=CreateHatchBrush(HS_DIAGCROSS,RGB(10,150,230)); if(!RegisterClassEx(&wc)) return 0; HWrodzic=CreateWindowEx(0,szClassName,"rodzic",WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX,20,20,600, 300,0,0,*hInst,0); ShowWindow(HWrodzic,nShow); //UpdateWindow(hWnd); HWpotomek1=CreateWindowEx(0,szClassName,"Potomek1",WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX,20, 20,600,300,HWrodzic,0,*hInst,0); HWpotomek2=CreateWindowEx(0,szClassName,"Potomek2",WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX,20, 20,600,300,HWrodzic,0,*hInst,0); HWpotomek3=CreateWindowEx(0,szClassName,"Potomek3",WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX,20, 20,600,300,HWrodzic,0,*hInst,0); HWpotomek4=CreateWindowEx(0,szClassName,"Potomek4",WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX,20, 20,600,300,HWrodzic,0,*hInst,0); UpdateWindow(HWpotomek1); UpdateWindow(HWpotomek2); UpdateWindow(HWpotomek3); UpdateWindow(HWpotomek4); MSG msgs; while(GetMessage(&msgs,0,0,0)) { TranslateMessage(&msgs); DispatchMessage(&msgs); } return msgs.wParam; } LRESULT CALLBACK WndProc(HWND hwnd,UINT msg,WPARAM wPar,LPARAM lPar) { HBRUSH kolor=CreateSolidBrush(RGB(255,70,70)); HBRUSH kolor2=CreateSolidBrush(RGB(0,255,0)); HFONT hFont=CreateFont(20,0,0,0,0,0,0,0,0,0,0,0,0,"Courier"); HDC HDCrodzic,HDCpotomek; PAINTSTRUCT ps; switch(msg) { case WM_PAINT: //rodzic HDCrodzic=BeginPaint(HWrodzic,&ps); DeleteObject(SelectObject(HDCrodzic,kolor)); RoundRect(HDCrodzic,20,10,580,80,15,15); DeleteObject(SelectObject(HDCrodzic, hFont)); SetBkMode(HDCrodzic, TRANSPARENT); SetTextAlign(HDCrodzic,TA_LEFT); TextOut(HDCrodzic,35,20,"przykladowy tekst 1.",20); TextOut(HDCrodzic,35,45,"przykladowy tekst 2.",20); EndPaint(HWrodzic,&ps); ReleaseDC(HWrodzic,HDCrodzic); //potomek1 HDCpotomek=BeginPaint(HWpotomek1,&ps); DeleteObject(SelectObject(HDCpotomek,kolor2)); RoundRect(HDCpotomek,20,10,580,80,15,15); EndPaint(HWpotomek1,&ps); ReleaseDC(HWpotomek1,HDCpotomek); //potomek2 HDCpotomek=BeginPaint(HWpotomek2,&ps); DeleteObject(SelectObject(HDCpotomek,kolor)); RoundRect(HDCpotomek,20,10,580,80,15,15); EndPaint(HWpotomek2,&ps); ReleaseDC(HWpotomek2,HDCpotomek); //potomek3 HDCpotomek=BeginPaint(HWpotomek3,&ps); RoundRect(HDCpotomek,20,10,580,80,15,15); EndPaint(HWpotomek3,&ps); ReleaseDC(HWpotomek3,HDCpotomek); //potomek4 HDCpotomek=BeginPaint(HWpotomek4,&ps); RoundRect(HDCpotomek,20,10,580,80,15,15); EndPaint(HWpotomek4,&ps); ReleaseDC(HWpotomek4,HDCpotomek); break; case WM_CREATE: hButton=CreateWindowEx(0,WC_BUTTON,"Przycisk1",WS_CHILD|WS_VISIBLE,480,90,100,30,HWrodzic,(HMENU)1, *hInst,0); hButton=CreateWindowEx(0,WC_BUTTON,"Przycisk2",WS_CHILD|WS_VISIBLE,480,130,100,30,HWrodzic, (HMENU)2,*hInst,0); hButton=CreateWindowEx(0,WC_BUTTON,"Przycisk3",WS_CHILD|WS_VISIBLE,480,170,100,30,HWrodzic, (HMENU)3,*hInst,0); hButton=CreateWindowEx(0,WC_BUTTON,"Przycisk4",WS_CHILD|WS_VISIBLE,480,210,100,30,HWrodzic, (HMENU)4,*hInst,0); break; case WM_COMMAND: if(wPar==1) { ShowWindow(HWpotomek1,SW_SHOW); } if(wPar==2) { ShowWindow(HWpotomek2,SW_SHOW); } if(wPar==3) { ShowWindow(HWpotomek3,SW_SHOW); } if(wPar==4) { ShowWindow(HWpotomek4,SW_SHOW); } break; case WM_CLOSE: if(hwnd==HWpotomek1) { SendMessage(HWpotomek1,WM_CLOSE,0,0); } if(hwnd==HWpotomek2) { ShowWindow(HWpotomek2,SW_HIDE); } if(hwnd==HWpotomek3) { ShowWindow(HWpotomek3,SW_HIDE); } if(hwnd==HWpotomek4) { ShowWindow(HWpotomek4,SW_HIDE); } if(hwnd==HWrodzic) { DestroyWindow(hButton); PostQuitMessage(0); } break; default: return DefWindowProc(hwnd,msg,wPar,lPar); } return 0; }
1. Po pierwsze czy da się jakoś inaczej zrobić to zamykanie konkretnego okna.
2. I druga kwestia to, że jak przesuwam którekolwiek z okien to wszystko ładnie działa ale przez parę pierwszych przesunięć czy to czasu a później się dzieją różne dziwne rzeczy związane z wyświetlaniem okien na pulpicie. Wie ktoś może jak to rozwiązać ? (mile widziany kod) :).
1. Ten kod:
case WM_CLOSE: if(hwnd==HWpotomek1) { SendMessage(HWpotomek1,WM_CLOSE,0,0); }
powoduje, że program się zapętla. Jeśli okno otrzyma WM_CLOSE, to wysyła do siebie WM_CLOSE ;)
2. "DestroyWindow(hButton);" - nie musisz usuwać przycisków. Zwłaszcza, że ten kod usunie tylko ostatni z nich (uchwyt każdego przycisku przypisujesz do tej samej zmiennej).
3. Zawartość WM_CREATE tworzy 4 przyciski. Procedura jest jedna dla wszystkich okien, więc utworzenie okien potomnych również wywoła ten kod. Rozwiązanie niżej.
4. Zrób osobną procedurę dla głównego okna i okien potomnych. W procedurze głównego okna w WM_CLOSE wstaw "PostQuitMessage(0);", a do procedury okien potomnych wstaw "ShowWindow(hwnd, SW_HIDE);".
Dzięki. Zgodnie z twoją poradą utworzyłem procedurę dla okna potomka:
LRESULT CALLBACK WNDpotomek(HWND HWpotomek1,UINT msg,WPARAM wPar,LPARAM lPar) { HBRUSH kolor=CreateSolidBrush(RGB(255,70,70)); HBRUSH kolor2=CreateSolidBrush(RGB(0,255,0)); HFONT hFont=CreateFont(20,0,0,0,0,0,0,0,0,0,0,0,0,"Courier"); HDC HDCpotomek; PAINTSTRUCT ps; switch(msg) { case WM_PAINT: //potomek1 HDCpotomek=BeginPaint(HWpotomek1,&ps); DeleteObject(SelectObject(HDCpotomek,kolor2)); RoundRect(HDCpotomek,20,10,580,80,15,15); EndPaint(HWpotomek1,&ps); ReleaseDC(HWpotomek1,HDCpotomek); break; case WM_CREATE: ShowWindow(HWpotomek1,SW_SHOW); break; case WM_COMMAND: break; case WM_CLOSE: ShowWindow(HWpotomek1,SW_HIDE); break; default: return DefWindowProc(HWpotomek1,msg,wPar,lPar); } return 0; }
tylko jak przekazać teraz wiadomość z procedury dla okna rodzica do procedury dla okna potomka? Tzn jak zrobić aby po przyciśnięciu przycisku w procedurze dla okna rodzica została wywołana odpowiednia akcja tworząca okno potomka w procedurze dla tego właśnie okna potomka.
Użytkownik gregussss edytował ten post 08 kwiecień 2009, 20:53
Np. SendMessage(uchwyt_okna_potomnego, WM_CLOSE, 0, 0);. Podaj jakiś przykład, bo nie jestem pewien czy dobrze rozumiem.
Ok. Mam taki kod:
#include <windows.h> #include <commctrl.h> #include <stdlib.h> #define CS_DROPSHADOW 0x00020000 HWND hButton,HWrodzic,HWpotomek1,HWpotomek2,HWpotomek3,HWpotomek4; CHAR szClassName[]="OknoRodzica"; CHAR szClassNamep[]="OknoPotomka"; HINSTANCE* hInst; LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM); LRESULT CALLBACK WNDpotomek(HWND,UINT,WPARAM,LPARAM); INT WINAPI WinMain(HINSTANCE hInstance,HINSTANCE,LPSTR lStart,INT nShow) { hInst=&hInstance; WNDCLASSEX wc; wc.hInstance=*hInst; wc.lpszClassName=szClassName; wc.lpfnWndProc=WndProc; wc.style=0; wc.cbSize=sizeof(WNDCLASSEX); wc.hIcon=LoadIcon(0,IDI_APPLICATION); wc.hIconSm=LoadIcon(0,IDI_APPLICATION); wc.hCursor=LoadCursor(0,IDC_ARROW); wc.lpszMenuName="menu"; wc.cbClsExtra=0; wc.cbWndExtra=0; wc.hbrBackground=CreateHatchBrush(HS_DIAGCROSS,RGB(10,150,230)); if(!RegisterClassEx(&wc)) return 0; WNDCLASSEX wcp; wcp.hInstance=*hInst; wcp.lpszClassName=szClassNamep; wcp.lpfnWndProc=WNDpotomek; wcp.style=0; wcp.cbSize=sizeof(WNDCLASSEX); wcp.hIcon=LoadIcon(0,IDI_APPLICATION); wcp.hIconSm=LoadIcon(0,IDI_APPLICATION); wcp.hCursor=LoadCursor(0,IDC_ARROW); wcp.lpszMenuName=0; wcp.cbClsExtra=0; wcp.cbWndExtra=0; wcp.hbrBackground=CreateHatchBrush(HS_DIAGCROSS,RGB(10,150,230)); if(!RegisterClassEx(&wcp)) return 0; HWrodzic=CreateWindowEx(0,szClassName,"rodzic",WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX,20,20,600, 300,0,0,*hInst,0); ShowWindow(HWrodzic,nShow); UpdateWindow(hWnd); HWpotomek1=CreateWindowEx(0,szClassNamep,"Potomek1",WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX,20, 20,600,300,HWrodzic,0,*hInst,0); HWpotomek2=CreateWindowEx(0,szClassName,"Potomek2",WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX,20, 20,600,300,HWrodzic,0,*hInst,0); HWpotomek3=CreateWindowEx(0,szClassName,"Potomek3",WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX,20, 20,600,300,HWrodzic,0,*hInst,0); HWpotomek4=CreateWindowEx(0,szClassName,"Potomek4",WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX,20, 20,600,300,HWrodzic,0,*hInst,0); UpdateWindow(HWpotomek1); UpdateWindow(HWpotomek2); UpdateWindow(HWpotomek3); UpdateWindow(HWpotomek4); MSG msgs; while(GetMessage(&msgs,0,0,0)) { TranslateMessage(&msgs); DispatchMessage(&msgs); } return msgs.wParam; } LRESULT CALLBACK WndProc(HWND hwnd,UINT msg,WPARAM wPar,LPARAM lPar) { HBRUSH kolor=CreateSolidBrush(RGB(255,70,70)); HBRUSH kolor2=CreateSolidBrush(RGB(0,255,0)); HFONT hFont=CreateFont(20,0,0,0,0,0,0,0,0,0,0,0,0,"Courier"); HDC HDCrodzic,HDCpotomek; PAINTSTRUCT ps; switch(msg) { case WM_PAINT: //rodzic HDCrodzic=BeginPaint(HWrodzic,&ps); DeleteObject(SelectObject(HDCrodzic,kolor)); RoundRect(HDCrodzic,20,10,580,80,15,15); DeleteObject(SelectObject(HDCrodzic, hFont)); SetBkMode(HDCrodzic, TRANSPARENT); SetTextAlign(HDCrodzic,TA_LEFT); TextOut(HDCrodzic,35,20,"przykladowy tekst 1.",20); TextOut(HDCrodzic,35,45,"przykladowy tekst 2.",20); EndPaint(HWrodzic,&ps); ReleaseDC(HWrodzic,HDCrodzic); //potomek2 HDCpotomek=BeginPaint(HWpotomek2,&ps); DeleteObject(SelectObject(HDCpotomek,kolor)); RoundRect(HDCpotomek,20,10,580,80,15,15); EndPaint(HWpotomek2,&ps); ReleaseDC(HWpotomek2,HDCpotomek); //potomek3 HDCpotomek=BeginPaint(HWpotomek3,&ps); RoundRect(HDCpotomek,20,10,580,80,15,15); EndPaint(HWpotomek3,&ps); ReleaseDC(HWpotomek3,HDCpotomek); //potomek4 HDCpotomek=BeginPaint(HWpotomek4,&ps); RoundRect(HDCpotomek,20,10,580,80,15,15); EndPaint(HWpotomek4,&ps); ReleaseDC(HWpotomek4,HDCpotomek); break; case WM_CREATE: hButton=CreateWindowEx(0,WC_BUTTON,"Przycisk1",WS_CHILD|WS_VISIBLE,480,90,100,30,HWrodzic,(HMENU)1, *hInst,0); hButton=CreateWindowEx(0,WC_BUTTON,"Przycisk2",WS_CHILD|WS_VISIBLE,480,130,100,30,HWrodzic, (HMENU)2,*hInst,0); hButton=CreateWindowEx(0,WC_BUTTON,"Przycisk3",WS_CHILD|WS_VISIBLE,480,170,100,30,HWrodzic, (HMENU)3,*hInst,0); hButton=CreateWindowEx(0,WC_BUTTON,"Przycisk4",WS_CHILD|WS_VISIBLE,480,210,100,30,HWrodzic, (HMENU)4,*hInst,0); break; case WM_COMMAND: if(wPar==1) { ShowWindow(HWpotomek1,SW_SHOW); } if(wPar==2) { ShowWindow(HWpotomek2,SW_SHOW); } if(wPar==3) { ShowWindow(HWpotomek3,SW_SHOW); } if(wPar==4) { ShowWindow(HWpotomek4,SW_SHOW); } break; case WM_CLOSE: if(hwnd==HWpotomek2) { ShowWindow(HWpotomek2,SW_HIDE); } if(hwnd==HWpotomek3) { ShowWindow(HWpotomek3,SW_HIDE); } if(hwnd==HWpotomek4) { ShowWindow(HWpotomek4,SW_HIDE); } if(hwnd==HWrodzic) { DestroyWindow(hButton); PostQuitMessage(0); } break; default: return DefWindowProc(hwnd,msg,wPar,lPar); } return 0; } LRESULT CALLBACK WNDpotomek(HWND HWpotomek1,UINT msg,WPARAM wPar,LPARAM lPar) { HBRUSH kolor=CreateSolidBrush(RGB(255,70,70)); HBRUSH kolor2=CreateSolidBrush(RGB(0,255,0)); HFONT hFont=CreateFont(20,0,0,0,0,0,0,0,0,0,0,0,0,"Courier"); HDC HDCpotomek; PAINTSTRUCT ps; switch(msg) { case WM_PAINT: //potomek1 HDCpotomek=BeginPaint(HWpotomek1,&ps); DeleteObject(SelectObject(HDCpotomek,kolor2)); SetPixel(HDCpotomek,20, 20,RGB(10,580,80)); MoveToEx(HDCpotomek,10,100,0); LineTo(HDCpotomek,100,100); EndPaint(HWpotomek1,&ps); ReleaseDC(HWpotomek1,HDCpotomek); break; case WM_CLOSE: ShowWindow(HWpotomek1,SW_HIDE); break; default: return DefWindowProc(HWpotomek1,msg,wPar,lPar); } return 0; }
1. Problem jest w tym, ze jak przemieszczam to okna po pulpicie to po pewnym czasie zaczyna się wszystko sypać i dziwne rzeczy pokazują się na ekranie (np. tło okna rozciąga się na cały ekran, znika górny pasek(ten z minimalizacja i krzyżykiem do zamykania okna itp itd)) i nie wiem jak temu zaradzić.
2. Nie wiem czemu nie działa komenda:
SetPixel(HDCpotomek,20, 20,RGB(10,580,80));
zanotowane.pl doc.pisz.pl pdf.pisz.pl zsf.htw.pl
Chce zrobić w winAPI okno menu z 3 przyciskami (każde do rysowania wykresu) i chce żeby dla każdego przycisku otwierało się osobne okno na ktorym bedzie wyrysowany wykres i tutaj pojawia się problem, wiec zwracam się do was z zapytaniem jak to najlepiej zrobić.
Osobiście myślałem nad tym aby:
- to menu z przyciskami zrobić jako okno dialogowe z przyciskami i w zależności od wybranego przycisku rysować w głównym oknie wykres (tylko ze jest to jedno okno a chciałbym w osobnych a nie wiem jak to zrealizować).
- i druga opcja to odwrotna czyli w głównym oknie zrobić to menu z przyciskami a w oknach dialogowych rysować (o ile można w nim tak po prostu rysować jak w zwykłym oknie).
Z góry dzięki za udzieloną pomoc i porady.
oczywiście mile widziane są jakieś przykłady kodu, ale nie są wymagane. :)
P.S. aby zaoszczędzić Wam i mnie samemu czasu proszę nie zamieszczać tekstów z rodziny: "poszukaj sobie w google tam wszystko jest". Przeczytałem kilka różnych kursów do winAPI i szukałem po różnych forach ale nigdzie nie mogłem znaleźć przykłądu w którym ktoś tworzyłby okno potomne do okna rodzica niebędące kontrolką czy też oknem dialogowym.
Poszukaj w dokumentacji, bo tam wszystko jest ładnie opisane ;)
CreateWindow - paramert HWND hWndParent pozwala na określenie, które okno ma być rodzicem. Tworzysz główne okno (parametr hWndParent przyjmuje wartość NULL) z trzema przyciskami. Po naciśnięciu przycisku tworzysz okno potomne (jako parametr hWndParent przekazujesz uchwyt głównego okna).
OK. Dzięki :)
Mam taki kod:
#include <windows.h> #include <commctrl.h> #define CS_DROPSHADOW 0x00020000 HWND hButton,HWrodzic,HWpotomek1,HWpotomek2,HWpotomek3,HWpotomek4; CHAR szClassName[]="OknoRodzica"; HINSTANCE* hInst; LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM); INT WINAPI WinMain(HINSTANCE hInstance,HINSTANCE,LPSTR lStart,INT nShow) { hInst=&hInstance; WNDCLASSEX wc; wc.hInstance=*hInst; wc.lpszClassName=szClassName; wc.lpfnWndProc=WndProc; wc.style=0; wc.cbSize=sizeof(WNDCLASSEX); wc.hIcon=LoadIcon(0,IDI_APPLICATION); wc.hIconSm=LoadIcon(0,IDI_APPLICATION); wc.hCursor=LoadCursor(0,IDC_ARROW); wc.lpszMenuName="menu"; wc.cbClsExtra=0; wc.cbWndExtra=0; wc.hbrBackground=CreateHatchBrush(HS_DIAGCROSS,RGB(10,150,230)); if(!RegisterClassEx(&wc)) return 0; HWrodzic=CreateWindowEx(0,szClassName,"rodzic",WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX,20,20,600, 300,0,0,*hInst,0); ShowWindow(HWrodzic,nShow); //UpdateWindow(hWnd); HWpotomek1=CreateWindowEx(0,szClassName,"Potomek1",WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX,20, 20,600,300,HWrodzic,0,*hInst,0); HWpotomek2=CreateWindowEx(0,szClassName,"Potomek2",WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX,20, 20,600,300,HWrodzic,0,*hInst,0); HWpotomek3=CreateWindowEx(0,szClassName,"Potomek3",WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX,20, 20,600,300,HWrodzic,0,*hInst,0); HWpotomek4=CreateWindowEx(0,szClassName,"Potomek4",WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX,20, 20,600,300,HWrodzic,0,*hInst,0); UpdateWindow(HWpotomek1); UpdateWindow(HWpotomek2); UpdateWindow(HWpotomek3); UpdateWindow(HWpotomek4); MSG msgs; while(GetMessage(&msgs,0,0,0)) { TranslateMessage(&msgs); DispatchMessage(&msgs); } return msgs.wParam; } LRESULT CALLBACK WndProc(HWND hwnd,UINT msg,WPARAM wPar,LPARAM lPar) { HBRUSH kolor=CreateSolidBrush(RGB(255,70,70)); HBRUSH kolor2=CreateSolidBrush(RGB(0,255,0)); HFONT hFont=CreateFont(20,0,0,0,0,0,0,0,0,0,0,0,0,"Courier"); HDC HDCrodzic,HDCpotomek; PAINTSTRUCT ps; switch(msg) { case WM_PAINT: //rodzic HDCrodzic=BeginPaint(HWrodzic,&ps); DeleteObject(SelectObject(HDCrodzic,kolor)); RoundRect(HDCrodzic,20,10,580,80,15,15); DeleteObject(SelectObject(HDCrodzic, hFont)); SetBkMode(HDCrodzic, TRANSPARENT); SetTextAlign(HDCrodzic,TA_LEFT); TextOut(HDCrodzic,35,20,"przykladowy tekst 1.",20); TextOut(HDCrodzic,35,45,"przykladowy tekst 2.",20); EndPaint(HWrodzic,&ps); ReleaseDC(HWrodzic,HDCrodzic); //potomek1 HDCpotomek=BeginPaint(HWpotomek1,&ps); DeleteObject(SelectObject(HDCpotomek,kolor2)); RoundRect(HDCpotomek,20,10,580,80,15,15); EndPaint(HWpotomek1,&ps); ReleaseDC(HWpotomek1,HDCpotomek); //potomek2 HDCpotomek=BeginPaint(HWpotomek2,&ps); DeleteObject(SelectObject(HDCpotomek,kolor)); RoundRect(HDCpotomek,20,10,580,80,15,15); EndPaint(HWpotomek2,&ps); ReleaseDC(HWpotomek2,HDCpotomek); //potomek3 HDCpotomek=BeginPaint(HWpotomek3,&ps); RoundRect(HDCpotomek,20,10,580,80,15,15); EndPaint(HWpotomek3,&ps); ReleaseDC(HWpotomek3,HDCpotomek); //potomek4 HDCpotomek=BeginPaint(HWpotomek4,&ps); RoundRect(HDCpotomek,20,10,580,80,15,15); EndPaint(HWpotomek4,&ps); ReleaseDC(HWpotomek4,HDCpotomek); break; case WM_CREATE: hButton=CreateWindowEx(0,WC_BUTTON,"Przycisk1",WS_CHILD|WS_VISIBLE,480,90,100,30,HWrodzic,(HMENU)1, *hInst,0); hButton=CreateWindowEx(0,WC_BUTTON,"Przycisk2",WS_CHILD|WS_VISIBLE,480,130,100,30,HWrodzic, (HMENU)2,*hInst,0); hButton=CreateWindowEx(0,WC_BUTTON,"Przycisk3",WS_CHILD|WS_VISIBLE,480,170,100,30,HWrodzic, (HMENU)3,*hInst,0); hButton=CreateWindowEx(0,WC_BUTTON,"Przycisk4",WS_CHILD|WS_VISIBLE,480,210,100,30,HWrodzic, (HMENU)4,*hInst,0); break; case WM_COMMAND: if(wPar==1) { ShowWindow(HWpotomek1,SW_SHOW); } if(wPar==2) { ShowWindow(HWpotomek2,SW_SHOW); } if(wPar==3) { ShowWindow(HWpotomek3,SW_SHOW); } if(wPar==4) { ShowWindow(HWpotomek4,SW_SHOW); } break; case WM_CLOSE: if(hwnd==HWpotomek1) { SendMessage(HWpotomek1,WM_CLOSE,0,0); } if(hwnd==HWpotomek2) { ShowWindow(HWpotomek2,SW_HIDE); } if(hwnd==HWpotomek3) { ShowWindow(HWpotomek3,SW_HIDE); } if(hwnd==HWpotomek4) { ShowWindow(HWpotomek4,SW_HIDE); } if(hwnd==HWrodzic) { DestroyWindow(hButton); PostQuitMessage(0); } break; default: return DefWindowProc(hwnd,msg,wPar,lPar); } return 0; }
1. Po pierwsze czy da się jakoś inaczej zrobić to zamykanie konkretnego okna.
2. I druga kwestia to, że jak przesuwam którekolwiek z okien to wszystko ładnie działa ale przez parę pierwszych przesunięć czy to czasu a później się dzieją różne dziwne rzeczy związane z wyświetlaniem okien na pulpicie. Wie ktoś może jak to rozwiązać ? (mile widziany kod) :).
1. Ten kod:
case WM_CLOSE: if(hwnd==HWpotomek1) { SendMessage(HWpotomek1,WM_CLOSE,0,0); }
powoduje, że program się zapętla. Jeśli okno otrzyma WM_CLOSE, to wysyła do siebie WM_CLOSE ;)
2. "DestroyWindow(hButton);" - nie musisz usuwać przycisków. Zwłaszcza, że ten kod usunie tylko ostatni z nich (uchwyt każdego przycisku przypisujesz do tej samej zmiennej).
3. Zawartość WM_CREATE tworzy 4 przyciski. Procedura jest jedna dla wszystkich okien, więc utworzenie okien potomnych również wywoła ten kod. Rozwiązanie niżej.
4. Zrób osobną procedurę dla głównego okna i okien potomnych. W procedurze głównego okna w WM_CLOSE wstaw "PostQuitMessage(0);", a do procedury okien potomnych wstaw "ShowWindow(hwnd, SW_HIDE);".
Dzięki. Zgodnie z twoją poradą utworzyłem procedurę dla okna potomka:
LRESULT CALLBACK WNDpotomek(HWND HWpotomek1,UINT msg,WPARAM wPar,LPARAM lPar) { HBRUSH kolor=CreateSolidBrush(RGB(255,70,70)); HBRUSH kolor2=CreateSolidBrush(RGB(0,255,0)); HFONT hFont=CreateFont(20,0,0,0,0,0,0,0,0,0,0,0,0,"Courier"); HDC HDCpotomek; PAINTSTRUCT ps; switch(msg) { case WM_PAINT: //potomek1 HDCpotomek=BeginPaint(HWpotomek1,&ps); DeleteObject(SelectObject(HDCpotomek,kolor2)); RoundRect(HDCpotomek,20,10,580,80,15,15); EndPaint(HWpotomek1,&ps); ReleaseDC(HWpotomek1,HDCpotomek); break; case WM_CREATE: ShowWindow(HWpotomek1,SW_SHOW); break; case WM_COMMAND: break; case WM_CLOSE: ShowWindow(HWpotomek1,SW_HIDE); break; default: return DefWindowProc(HWpotomek1,msg,wPar,lPar); } return 0; }
tylko jak przekazać teraz wiadomość z procedury dla okna rodzica do procedury dla okna potomka? Tzn jak zrobić aby po przyciśnięciu przycisku w procedurze dla okna rodzica została wywołana odpowiednia akcja tworząca okno potomka w procedurze dla tego właśnie okna potomka.
Użytkownik gregussss edytował ten post 08 kwiecień 2009, 20:53
Np. SendMessage(uchwyt_okna_potomnego, WM_CLOSE, 0, 0);. Podaj jakiś przykład, bo nie jestem pewien czy dobrze rozumiem.
Ok. Mam taki kod:
#include <windows.h> #include <commctrl.h> #include <stdlib.h> #define CS_DROPSHADOW 0x00020000 HWND hButton,HWrodzic,HWpotomek1,HWpotomek2,HWpotomek3,HWpotomek4; CHAR szClassName[]="OknoRodzica"; CHAR szClassNamep[]="OknoPotomka"; HINSTANCE* hInst; LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM); LRESULT CALLBACK WNDpotomek(HWND,UINT,WPARAM,LPARAM); INT WINAPI WinMain(HINSTANCE hInstance,HINSTANCE,LPSTR lStart,INT nShow) { hInst=&hInstance; WNDCLASSEX wc; wc.hInstance=*hInst; wc.lpszClassName=szClassName; wc.lpfnWndProc=WndProc; wc.style=0; wc.cbSize=sizeof(WNDCLASSEX); wc.hIcon=LoadIcon(0,IDI_APPLICATION); wc.hIconSm=LoadIcon(0,IDI_APPLICATION); wc.hCursor=LoadCursor(0,IDC_ARROW); wc.lpszMenuName="menu"; wc.cbClsExtra=0; wc.cbWndExtra=0; wc.hbrBackground=CreateHatchBrush(HS_DIAGCROSS,RGB(10,150,230)); if(!RegisterClassEx(&wc)) return 0; WNDCLASSEX wcp; wcp.hInstance=*hInst; wcp.lpszClassName=szClassNamep; wcp.lpfnWndProc=WNDpotomek; wcp.style=0; wcp.cbSize=sizeof(WNDCLASSEX); wcp.hIcon=LoadIcon(0,IDI_APPLICATION); wcp.hIconSm=LoadIcon(0,IDI_APPLICATION); wcp.hCursor=LoadCursor(0,IDC_ARROW); wcp.lpszMenuName=0; wcp.cbClsExtra=0; wcp.cbWndExtra=0; wcp.hbrBackground=CreateHatchBrush(HS_DIAGCROSS,RGB(10,150,230)); if(!RegisterClassEx(&wcp)) return 0; HWrodzic=CreateWindowEx(0,szClassName,"rodzic",WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX,20,20,600, 300,0,0,*hInst,0); ShowWindow(HWrodzic,nShow); UpdateWindow(hWnd); HWpotomek1=CreateWindowEx(0,szClassNamep,"Potomek1",WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX,20, 20,600,300,HWrodzic,0,*hInst,0); HWpotomek2=CreateWindowEx(0,szClassName,"Potomek2",WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX,20, 20,600,300,HWrodzic,0,*hInst,0); HWpotomek3=CreateWindowEx(0,szClassName,"Potomek3",WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX,20, 20,600,300,HWrodzic,0,*hInst,0); HWpotomek4=CreateWindowEx(0,szClassName,"Potomek4",WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX,20, 20,600,300,HWrodzic,0,*hInst,0); UpdateWindow(HWpotomek1); UpdateWindow(HWpotomek2); UpdateWindow(HWpotomek3); UpdateWindow(HWpotomek4); MSG msgs; while(GetMessage(&msgs,0,0,0)) { TranslateMessage(&msgs); DispatchMessage(&msgs); } return msgs.wParam; } LRESULT CALLBACK WndProc(HWND hwnd,UINT msg,WPARAM wPar,LPARAM lPar) { HBRUSH kolor=CreateSolidBrush(RGB(255,70,70)); HBRUSH kolor2=CreateSolidBrush(RGB(0,255,0)); HFONT hFont=CreateFont(20,0,0,0,0,0,0,0,0,0,0,0,0,"Courier"); HDC HDCrodzic,HDCpotomek; PAINTSTRUCT ps; switch(msg) { case WM_PAINT: //rodzic HDCrodzic=BeginPaint(HWrodzic,&ps); DeleteObject(SelectObject(HDCrodzic,kolor)); RoundRect(HDCrodzic,20,10,580,80,15,15); DeleteObject(SelectObject(HDCrodzic, hFont)); SetBkMode(HDCrodzic, TRANSPARENT); SetTextAlign(HDCrodzic,TA_LEFT); TextOut(HDCrodzic,35,20,"przykladowy tekst 1.",20); TextOut(HDCrodzic,35,45,"przykladowy tekst 2.",20); EndPaint(HWrodzic,&ps); ReleaseDC(HWrodzic,HDCrodzic); //potomek2 HDCpotomek=BeginPaint(HWpotomek2,&ps); DeleteObject(SelectObject(HDCpotomek,kolor)); RoundRect(HDCpotomek,20,10,580,80,15,15); EndPaint(HWpotomek2,&ps); ReleaseDC(HWpotomek2,HDCpotomek); //potomek3 HDCpotomek=BeginPaint(HWpotomek3,&ps); RoundRect(HDCpotomek,20,10,580,80,15,15); EndPaint(HWpotomek3,&ps); ReleaseDC(HWpotomek3,HDCpotomek); //potomek4 HDCpotomek=BeginPaint(HWpotomek4,&ps); RoundRect(HDCpotomek,20,10,580,80,15,15); EndPaint(HWpotomek4,&ps); ReleaseDC(HWpotomek4,HDCpotomek); break; case WM_CREATE: hButton=CreateWindowEx(0,WC_BUTTON,"Przycisk1",WS_CHILD|WS_VISIBLE,480,90,100,30,HWrodzic,(HMENU)1, *hInst,0); hButton=CreateWindowEx(0,WC_BUTTON,"Przycisk2",WS_CHILD|WS_VISIBLE,480,130,100,30,HWrodzic, (HMENU)2,*hInst,0); hButton=CreateWindowEx(0,WC_BUTTON,"Przycisk3",WS_CHILD|WS_VISIBLE,480,170,100,30,HWrodzic, (HMENU)3,*hInst,0); hButton=CreateWindowEx(0,WC_BUTTON,"Przycisk4",WS_CHILD|WS_VISIBLE,480,210,100,30,HWrodzic, (HMENU)4,*hInst,0); break; case WM_COMMAND: if(wPar==1) { ShowWindow(HWpotomek1,SW_SHOW); } if(wPar==2) { ShowWindow(HWpotomek2,SW_SHOW); } if(wPar==3) { ShowWindow(HWpotomek3,SW_SHOW); } if(wPar==4) { ShowWindow(HWpotomek4,SW_SHOW); } break; case WM_CLOSE: if(hwnd==HWpotomek2) { ShowWindow(HWpotomek2,SW_HIDE); } if(hwnd==HWpotomek3) { ShowWindow(HWpotomek3,SW_HIDE); } if(hwnd==HWpotomek4) { ShowWindow(HWpotomek4,SW_HIDE); } if(hwnd==HWrodzic) { DestroyWindow(hButton); PostQuitMessage(0); } break; default: return DefWindowProc(hwnd,msg,wPar,lPar); } return 0; } LRESULT CALLBACK WNDpotomek(HWND HWpotomek1,UINT msg,WPARAM wPar,LPARAM lPar) { HBRUSH kolor=CreateSolidBrush(RGB(255,70,70)); HBRUSH kolor2=CreateSolidBrush(RGB(0,255,0)); HFONT hFont=CreateFont(20,0,0,0,0,0,0,0,0,0,0,0,0,"Courier"); HDC HDCpotomek; PAINTSTRUCT ps; switch(msg) { case WM_PAINT: //potomek1 HDCpotomek=BeginPaint(HWpotomek1,&ps); DeleteObject(SelectObject(HDCpotomek,kolor2)); SetPixel(HDCpotomek,20, 20,RGB(10,580,80)); MoveToEx(HDCpotomek,10,100,0); LineTo(HDCpotomek,100,100); EndPaint(HWpotomek1,&ps); ReleaseDC(HWpotomek1,HDCpotomek); break; case WM_CLOSE: ShowWindow(HWpotomek1,SW_HIDE); break; default: return DefWindowProc(HWpotomek1,msg,wPar,lPar); } return 0; }
1. Problem jest w tym, ze jak przemieszczam to okna po pulpicie to po pewnym czasie zaczyna się wszystko sypać i dziwne rzeczy pokazują się na ekranie (np. tło okna rozciąga się na cały ekran, znika górny pasek(ten z minimalizacja i krzyżykiem do zamykania okna itp itd)) i nie wiem jak temu zaradzić.
2. Nie wiem czemu nie działa komenda:
SetPixel(HDCpotomek,20, 20,RGB(10,580,80));