09. juli 2005 - 21:57
Der er
10 kommentarer og 1 løsning
styring af 2 vinduer
Jeg har lavet et lille script der åbner to vinduer og man kan så lukke dem igen (JIR!! lidt simpelt men man skal jo starte et sted). Mir problem er at for at gøre så de ikke begge lukker når jeg lukker det ene, har jeg lavet på callbacks, mit spørgsmål er om der ikke er en måde jeg kan afgøre hvilket vindue msg kommer fra så jeg slipper for to af dem. Ved ikke helt hvordan måkse noget med at lave to forskellige hwnd når jeg "creater" mine vinduer. Håber mit spørgsmål giver mening. Her er min kode: // INCLUDES ///////////////////////////////////////////////// #define WIN32_LEAN_AND_MEAN // STOP MFC #include <windows.h> #include <windowsx.h> #include <stdio.h> #include <math.h> // DEFINES ////////////////////////////////////////////////// #define WINDOW_CLASS_NAME "WINCLASS!" // GLOBALS ////////////////////////////////////////////////// bool stop = FALSE; // FUNCTIONS //////////////////////////////////////////////// LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { // main message handler PAINTSTRUCT ps; // used in WM_PAINT HDC hdc; // handle to device context switch(msg) { case WM_CREATE: { return 0; } break; case WM_PAINT: { hdc = BeginPaint(hwnd,&ps); EndPaint(hwnd,&ps); return 0; } break; case WM_DESTROY: { if (stop = TRUE) { PostQuitMessage(0); } else { stop = TRUE; } return 0; } break; default:break; } // end switch // hvis der kommer en message vi ikke har med return (DefWindowProc(hwnd, msg, wparam, lparam)); } // end WinProc // 2 LRESULT CALLBACK WindowProc2(HWND hwnd2, UINT msg2, WPARAM wparam2, LPARAM lparam2) { // main message handler PAINTSTRUCT ps2; // used in WM_PAINT HDC hdc2; // handle to device context switch(msg2) { case WM_CREATE: { return 0; } break; case WM_PAINT: { hdc2 = BeginPaint(hwnd2,&ps2); EndPaint(hwnd2,&ps2); return 0; } break; case WM_DESTROY: { if (stop = TRUE) { PostQuitMessage(0); } else { stop = TRUE; } return 0; } break; default:break; } // end switch // hvis der kommer en message vi ikke har med return (DefWindowProc(hwnd2, msg2, wparam2, lparam2)); } // end WinProc2 // WINMAIN ////////////////////////////////////////////////// int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hprevinstance, LPSTR lpcmdline, int ncmdshow) { // Winclass WNDCLASSEX winclass; HWND hwnd; MSG msg; winclass.cbSize = sizeof(WNDCLASSEX); winclass.style = CS_DBLCLKS | CS_OWNDC | CS_HREDRAW | CS_VREDRAW; winclass.lpfnWndProc = WindowProc; winclass.cbClsExtra = 0; winclass.cbWndExtra = 0; winclass.hInstance = hinstance; winclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); winclass.hCursor = LoadCursor(NULL, IDC_ARROW); winclass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); winclass.lpszMenuName = NULL; winclass.lpszClassName = "WINCLASS"; winclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION); if (!RegisterClassEx(&winclass)) return 0; if (!(hwnd =CreateWindowEx(NULL, "WINCLASS", "1", WS_OVERLAPPEDWINDOW | WS_VISIBLE, 100,100, 400,400, NULL, NULL, hinstance, NULL))) return(0); // Winclass2 HWND hwnd2; MSG msg2; winclass.cbSize = sizeof(WNDCLASSEX); winclass.style = CS_DBLCLKS | CS_OWNDC | CS_HREDRAW | CS_VREDRAW; winclass.lpfnWndProc = WindowProc2; winclass.cbClsExtra = 0; winclass.cbWndExtra = 0; winclass.hInstance = hinstance; winclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); winclass.hCursor = LoadCursor(NULL, IDC_ARROW); winclass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); winclass.lpszMenuName = NULL; winclass.lpszClassName = "WINCLASS2"; winclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION); if (!RegisterClassEx(&winclass)) return 0; if (!(hwnd2 =CreateWindowEx(NULL, "WINCLASS2", "2", WS_OVERLAPPEDWINDOW | WS_VISIBLE, 500,100, 400,200, NULL, NULL, hinstance, NULL))) return(0); // main loop while(TRUE) { if (PeekMessage(&msg,NULL,0,0,PM_REMOVE) | PeekMessage(&msg2,NULL,0,0,PM_REMOVE)) { if (msg.message == WM_QUIT) { break; } TranslateMessage(&msg); DispatchMessage(&msg); TranslateMessage(&msg2); DispatchMessage(&msg2); // main game here } // end if } // end while } // end WinMain
Annonceindlæg fra Computerworld
Gefion skaber fremtidens AI
Supercomputeren Gefion er Danmarks nye AI-kraftværk og skal sikre, at både forskning og virksomheder kan være med i den teknologiske front.
14. august 2025
Du burde kunne bruge samme WindowProc til begge vinduer, første parameter i kaldet fortæller netop hvilket vindue beskeden er for. Denne linie er sansynlig vis forkert (begge tilfælde): if (stop = TRUE) Du bør kunne bruge GetMessage i din message loop, som det er nu vil dit program æde alt cpu tid.
mener du at i min hwnd er der hvilket vidue beskeden er fra ? Hvis ja hvordan får jeg så den ene switch til at dele det op i de beskeder der kommer fra det ene og dem fra det andede?
Hvis du laver HWND hwnd; og HWND hwnd2; fra WinMain om til globale variable, og kalder dem hwnd1 og hwnd2, kan du i din WindowProc lave: if(hwnd == hwnd1) { // It's the first window } else if(hwnd == hwnd2) { // It's the second window } else { // What } Din message loop kunne se sådan ud: MSG Msg; while(GetMessage(&Msg, 0, 0, 0xFFFF) > 0) { TranslateMessage(&Msg); DispatchMessage(&Msg); }
smart, tror det virker, leger lige lidt med det og vender så tilbage. Tror bare jeg har lidt problemer med hvordan parametrerne bliver sendt rundt, er lige startet på c++.
Jeg lavede lige et eksempel. Det skulle gerne lave et vindue (1) med rød baggrund og et andet (2) med grøn baggrund: // INCLUDES ///////////////////////////////////////////////// #define WIN32_LEAN_AND_MEAN // STOP MFC #include <windows.h> #include <windowsx.h> #include <stdio.h> #include <math.h> // DEFINES ////////////////////////////////////////////////// #define WINDOW_CLASS_NAME "WINCLASS!" // GLOBALS ////////////////////////////////////////////////// bool stop = false; HWND hwnd1; HWND hwnd2; // FUNCTIONS //////////////////////////////////////////////// LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { // main message handler PAINTSTRUCT ps; // used in WM_PAINT HDC hdc; // handle to device context switch(msg) { case WM_CREATE: { return 0; } break; case WM_PAINT: { hdc = BeginPaint(hwnd,&ps); RECT R; GetClientRect(hwnd, &R); if(hwnd == hwnd1) { FillRect(hdc, &R, CreateSolidBrush(RGB(255, 0, 0))); } else if(hwnd == hwnd2) { FillRect(hdc, &R, CreateSolidBrush(RGB(0, 255, 0))); } else { MessageBox(hwnd, "Ups, wrong window!", "Whatever", MB_OK); } EndPaint(hwnd,&ps); return 0; } break; case WM_DESTROY: { if (stop) { PostQuitMessage(0); } else { stop = true; } return 0; } break; default:break; } // end switch // hvis der kommer en message vi ikke har med return (DefWindowProc(hwnd, msg, wparam, lparam)); } // end WinProc // WINMAIN ////////////////////////////////////////////////// int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hprevinstance, LPSTR lpcmdline, int ncmdshow) { // Winclass WNDCLASSEX winclass; winclass.cbSize = sizeof(WNDCLASSEX); winclass.style = CS_DBLCLKS | CS_OWNDC | CS_HREDRAW | CS_VREDRAW; winclass.lpfnWndProc = WindowProc; winclass.cbClsExtra = 0; winclass.cbWndExtra = 0; winclass.hInstance = hinstance; winclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); winclass.hCursor = LoadCursor(NULL, IDC_ARROW); winclass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); winclass.lpszMenuName = NULL; winclass.lpszClassName = "WINCLASS"; winclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION); if (!RegisterClassEx(&winclass)) return 0; if (!(hwnd1 =CreateWindowEx(NULL, "WINCLASS", "1", WS_OVERLAPPEDWINDOW | WS_VISIBLE, 100,100, 400,400, NULL, NULL, hinstance, NULL))) return(0); // Winclass2 winclass.cbSize = sizeof(WNDCLASSEX); winclass.style = CS_DBLCLKS | CS_OWNDC | CS_HREDRAW | CS_VREDRAW; winclass.lpfnWndProc = WindowProc; winclass.cbClsExtra = 0; winclass.cbWndExtra = 0; winclass.hInstance = hinstance; winclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); winclass.hCursor = LoadCursor(NULL, IDC_ARROW); winclass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); winclass.lpszMenuName = NULL; winclass.lpszClassName = "WINCLASS2"; winclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION); if (!RegisterClassEx(&winclass)) return 0; if (!(hwnd2 =CreateWindowEx(NULL, "WINCLASS2", "2", WS_OVERLAPPEDWINDOW | WS_VISIBLE, 500,100, 400,200, NULL, NULL, hinstance, NULL))) return(0); MSG Msg; while(GetMessage(&Msg, 0, 0, 0xFFFF) > 0) { TranslateMessage(&Msg); DispatchMessage(&Msg); } return 0; } // end WinMain
tak skal du ha'. Jeg har også lige lavet lidt, det er sikkert ikke så pænt (man er jo en newb), men det kan jo være nogen kan få glæde af det: // INCLUDES ///////////////////////////////////////////////// #define WIN32_LEAN_AND_MEAN // STOP MFC #include <windows.h> #include <windowsx.h> #include <stdio.h> #include <math.h> // DEFINES ////////////////////////////////////////////////// #define WINDOW_CLASS_NAME "WINCLASS!" // GLOBALS ////////////////////////////////////////////////// HWND hwnd1; HWND hwnd2; // FUNCTIONS //////////////////////////////////////////////// LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { // main message handler PAINTSTRUCT ps; // used in WM_PAINT HDC hdc; // handle to device context switch(msg) { case WM_CREATE: { return 0; } break; case WM_PAINT: { hdc = BeginPaint(hwnd,&ps); EndPaint(hwnd,&ps); return 0; } break; case WM_DESTROY: { if (hwnd == hwnd1) { hwnd1 = NULL; } else if (hwnd == hwnd2) { hwnd2 = NULL; } if (hwnd1 == NULL && hwnd2 == NULL) { PostQuitMessage(0); } return 0; } break; default:break; } // end switch // hvis der kommer en message vi ikke har med return (DefWindowProc(hwnd, msg, wparam, lparam)); } // end WinProc // WINMAIN ////////////////////////////////////////////////// int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hprevinstance, LPSTR lpcmdline, int ncmdshow) { // Winclass WNDCLASSEX winclass; MSG msg; winclass.cbSize = sizeof(WNDCLASSEX); winclass.style = CS_DBLCLKS | CS_OWNDC | CS_HREDRAW | CS_VREDRAW; winclass.lpfnWndProc = WindowProc; winclass.cbClsExtra = 0; winclass.cbWndExtra = 0; winclass.hInstance = hinstance; winclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); winclass.hCursor = LoadCursor(NULL, IDC_ARROW); winclass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); winclass.lpszMenuName = NULL; winclass.lpszClassName = "WINCLASS"; winclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION); if (!RegisterClassEx(&winclass)) return 0; if (!(hwnd1 =CreateWindowEx(NULL, "WINCLASS", "1", WS_OVERLAPPEDWINDOW | WS_VISIBLE, 100,100, 400,400, NULL, NULL, hinstance, NULL))) return(0); if (!(hwnd2 =CreateWindowEx(NULL, "WINCLASS", "2", WS_OVERLAPPEDWINDOW | WS_VISIBLE, 500,100, 400,200, NULL, NULL, hinstance, NULL))) return(0); // main loop while(TRUE) { if (PeekMessage(&msg,NULL,0,0,PM_REMOVE)) { if (msg.message == WM_QUIT) { break; } TranslateMessage(&msg); DispatchMessage(&msg); // main game here } // end if } // end while } // end WinMain Grunden til jeg bruger PeekMessage er fordi det stod i en bog, den startede med GetMessage, men skiftede så til PeekMessage, det var noget med den skulle være mere "live". Men smid et svar, det var en stor hjælp.
Prøv at starte taskmanageren/joblisten når dit program kører, så kan du se at dit program bruger ca 100% cpu tid. Man bruger normalt kun PeekMessage hvis man vil checke om der er noget i køen, men ikke ønsker at vente hvis der ikke ligger nogen besked klar. I dit eksempel spørger du igen og igen og igen. Jeg samler ikke på point.
ja jeg har lagt mærke til den bruger 99 %, men der må da være en grund til at bogen siger man skal bruge den istedet for getmessage, bogen handler egentlig om at lave spil kan det have noget med sagen at gøre ?
Ja, det kan godt have noget med sagen at gøre. I et spil vil man typisk lave en masse grafik og fra tid til anden checke om der er nye beskeder og så fortsætte med grafikken. I spil ønsker man ikke at vente på beskeder, men vil fortsætte med noget andet, hvis der ikke er bekeder der skal håndteres. I dit eksempel laves der ikke andet end at vente på besker, og så er der ingen grund til at bruge PeekMessage.
10. juli 2005 - 00:44
#10
ja ok, men regner med at der bliver bygget videre på dette eksempel så det er vigtigt at jeg beholder peekmeassage, men tak for rådet det er meget rart at vide når jeg engang skal prøve at lave noget andet.
10. juli 2005 - 15:10
#11
jeg lukker det. Endnu en gang tak for hjælpen
Kurser inden for grundlæggende programmering