OpenGL-Anwendung von Windowsfenster aus starten
-
Hallo.
Ich habe diese Semesterferien mal vor ein größeres Projekt zu machen.
Meine Idee:
Ein Windowsfenster, wo man die Funktionsgleichung eines 3D-Graphen eingeben kann, dann drückt man auf Start und der Graph wird mit OpenGL gezeichnet.An sich ist beides kein Problem, das dürfte ich mit meinen Kenntnissen hinbekommen. Allerdings fällt mir die Verknüpfung schwer. Wie würdet ihr sowas machen? Einfach 2 verschiedene Programme anlegen? Wichtig ist, dass für das OpenGL-Fenster einige Parameter übergeben werden müssen. Ich benutze VC++ 6 als Oberfläche und hatte damit schon immer Probleme alles richtig zu verlinken.
Das ganze ist bestimmt mit einem einzigen Befehl beantwortet, der nicht einmal was mit WinAPI zu tun hat ^^. Ein kleines Beispiel wäre natürlich Optimal (mit den Main-Funktionen beider Programme).
Bitte gebt mir einen kleinen Tip.
Vielen Dank schonmal.
Gruß
Max
-
Ein Beispiel kann ich dir nicht geben, aber du bräuchtest eigentlich nur ein Programm. Du erstellst 2 Fenster, eins für die Graphen und eins für die Eingabe. Dann eben noch für jedes seine eigene WinProc und dann sollte das auch funktionieren...
-
Mach's doch einfach so :
Du lässt dir erst dein Vollbild Modus ausrechnen und dann erstellst du ein Child-Window, da kannst du dann deine ganzen Buttons+Edit's usw. reinpacken.
-
Also Du kannst das theoretisch komplett in OpenGL lösen, da das Framework ja auch Steuerelemente zur Verfügung stellt. Falls Du bei Deiner Konzeption bleiben willst, gehe so vor (schematisch -> Pseudo-Code):
WinMain { 2 mal RegisterClassEx - einmal mit 'WndProc1' und einmal mit 'WndProc2' (in der WNDCLASSEX-Struktur) 2 mal CreateWindowEx - eins stellt das 'WinAPI'-Fenster dar (mit WndProc1), das andere das 'OpenGL-Fenster' (WndProc2) } WndProc1 { WinApi-Abhandlungen; } WndProc2 { OpenGL-Abhandlungen; }Die Kommunikation zwischen den Fenster kannst Du dann entweder mit globalen Variablen lösen (unschön^^!!). Oder Du sendest Nachrichten zwischen den Fenstern (siehe WM_USER in der MSDN). Alternativ kannst Du nach den Aufrufen von CreateWindowEx auch mit SetWindowLongPtr und GWL_USERDATA arbeiten.
Musst halt schaun, was am besten passt
.
-
Das war ja das, was ich vorgeschlagen habe

Aber vllt wirds jetzt klarer durch deine Veranschaulichung...^^
-
Das wird glaub ich etwas zu kompliziert für mich, da die WinMain-Funktionen eigentlich komplett verschieden sind. Ich habs erstmal so gehandhabt, dass ich 2 unterschiedliche Programme erstellt habe, wobei die 1. alle wichtigen Sachen in eine temporäre Datei schreibt, welches das 2. dann ausliest. Ich schickmal die Windowprozedur und die Winmain von beiden Dateien. So richtig bekomm ich das mit der erklärung nicht hin... Also:
Windowsfenster:
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { char input[255]; static HWND hEdit, hEditXmin, hEditYmin, hEditXmax, hEditYmax; float xMin, xMax, yMin, yMax; HWND hButtonStart, hCheckGrid; HDC hDc; PAINTSTRUCT ps; switch(message) { case WM_COMMAND: if(LOWORD(wParam) == 1 && HIWORD(wParam) == BN_CLICKED) { GetWindowText(hEditXmin, input, 255); xMin = atof(input); GetWindowText(hEditXmax, input, 255); xMax = atof(input); GetWindowText(hEditYmin, input, 255); yMin = atof(input); GetWindowText(hEditYmax, input, 255); yMax = atof(input); if(!CreateLogFile(xMin, xMax, yMin, yMax)) MessageBox(NULL, TEXT("Fehler beim schreiben der temporären Datei"), szAppName, MB_ICONERROR); }; break; case WM_CREATE: hButtonStart = CreateWindow (TEXT("button"), TEXT("Plot !"), WS_CHILD | WS_VISIBLE, 20, 140, 100, 50, hwnd, (HMENU) 1, ((LPCREATESTRUCT) lParam)->hInstance, NULL); hEdit = CreateWindow (TEXT("edit"), NULL, WS_CHILD | WS_BORDER | WS_VISIBLE, 70, 100, 170, 22, hwnd, NULL, ((LPCREATESTRUCT) lParam)->hInstance, NULL); hCheckGrid = CreateWindow (TEXT("button"), TEXT("Show Grid"), WS_CHILD | WS_VISIBLE | BS_CHECKBOX, 150, 140, 100, 22, hwnd, NULL, ((LPCREATESTRUCT) lParam)->hInstance, NULL); hEditXmin = CreateWindow (TEXT("edit"), NULL, WS_CHILD | WS_VISIBLE | WS_BORDER, 100, 20, 50, 22, hwnd, NULL, ((LPCREATESTRUCT) lParam)->hInstance, NULL); hEditXmax = CreateWindow (TEXT("edit"), NULL, WS_CHILD | WS_VISIBLE | WS_BORDER, 190, 20, 50, 22, hwnd, NULL, ((LPCREATESTRUCT) lParam)->hInstance, NULL); hEditYmin = CreateWindow (TEXT("edit"), NULL, WS_CHILD | WS_VISIBLE | WS_BORDER, 100, 50, 50, 22, hwnd, NULL, ((LPCREATESTRUCT) lParam)->hInstance, NULL); hEditYmax = CreateWindow (TEXT("edit"), NULL, WS_CHILD | WS_VISIBLE | WS_BORDER, 190, 50, 50, 22, hwnd, NULL, ((LPCREATESTRUCT) lParam)->hInstance, NULL); break; case WM_PAINT: hDc = BeginPaint (hwnd, &ps); TextOut (hDc, 15, 103, TEXT("f(x,y) = "),9); TextOut (hDc, 15, 23, TEXT("X - Range:"), 10); TextOut (hDc, 15, 53, TEXT("Y - Range:"), 10); TextOut (hDc, 168, 23, TEXT("-"), 1); TextOut (hDc, 168, 53, TEXT("-"), 1); EndPaint(hwnd, &ps); break; case WM_DESTROY: PostQuitMessage(0); break; }; return DefWindowProc(hwnd, message, wParam, lParam); } int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int iCmdShow) { WNDCLASS wndclass; HWND hwnd; MSG msg; wndclass.style = CS_HREDRAW | CS_VREDRAW; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.lpfnWndProc = WndProc; wndclass.hInstance = hInstance; wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); wndclass.lpszMenuName = (NULL); wndclass.lpszClassName = szAppName; wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH); if(!RegisterClass(&wndclass)) { MessageBox(NULL, TEXT("Fehler beim Registrieren der Fensterklasse"), szAppName, MB_ICONERROR); return 0; }; hwnd = CreateWindow (szAppName, szAppName, WS_CAPTION | WS_THICKFRAME | WS_OVERLAPPED | WS_MINIMIZEBOX | WS_SYSMENU, 100, 100, 500, 300, NULL, NULL, hInstance, NULL); ShowWindow(hwnd, iCmdShow); UpdateWindow(hwnd); while(GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); }; return msg.wParam; }Und jetzt das OpenGL-Programm:
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch(uMsg) { case WM_ACTIVATE: if(!HIWORD(wParam)) { active=TRUE; } else { active=FALSE; } return 0; case WM_SYSCOMMAND: switch(wParam) { case SC_SCREENSAVE: case SC_MONITORPOWER: return 0; } return 0; case WM_CLOSE: PostQuitMessage(0); return 0; case WM_KEYDOWN: keys[wParam]=TRUE; return 0; case WM_KEYUP: keys[wParam]=FALSE; return 0; case WM_SIZE: ReSizeGLScene(LOWORD(lParam), HIWORD(lParam)); return 0; } return DefWindowProc(hWnd, uMsg, wParam, lParam); } int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { MSG msg; BOOL done=FALSE; if(MessageBox(NULL, "Soll im Vollbildmodus gestartet werden?", "OpenGL", MB_ICONEXCLAMATION | MB_YESNO)==IDNO) { fullscreen=FALSE; } if(!CreateGLWindow("OpenGL", 640, 480, 16, fullscreen)) { return 0; } LoadData(); while(!done) { if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { if(msg.message==WM_QUIT) { done=TRUE; } else { TranslateMessage(&msg); DispatchMessage(&msg); } } else { if(active) { if(keys[VK_ESCAPE]) { done=TRUE; } else { DrawGLScene(); SwapBuffers(hDc); } } if(keys[VK_F1]) { keys[VK_F1]=FALSE; KillGLWindow(); fullscreen=!fullscreen; if(!CreateGLWindow("OpenGL", 640, 480, 16, fullscreen)) { return 0; } } } } KillGLWindow(); return(msg.wParam); }Der Kenner sieht vielleicht, dass das WindowsFenster a la Petzold und der OpenGL-Teil a la NeHe programmiert wurde ^^.
Ich weiß nicht so richtig, wie ich die WinMain-Funktion jetzt schreiben soll, da im OpenGL-Prog dort noch diese Abfragen nach der ESC-, und F1-Taste drin vorkommen. Wäre nett wenn ihr mir noch ein kleines bisschen helfen könntet.Schöne Grüße
Max