C - win32 Api - createWindowEx
-
Guten Abend,
ich bräuchte Hilfe zu der Funktion createWindowEx. Ich lasse in einem C-Script 3 Fenster erstellen:
- Hauptfenster
- Listbox (im Hauptfenster)
- Editbox (im Hauptfenster)
Der Code:
hWnd = CreateWindowEx(WS_EX_CLIENTEDGE, MainClassName, "Foobar", WS_OVERLAPPEDWINDOW | WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, // width CW_USEDEFAULT, // height NULL, NULL, hInstance, NULL); foo = CreateWindowEx(WS_EX_CLIENTEDGE, "LISTBOX", "Bar", WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_HSCROLL | LBS_DISABLENOSCROLL | LBS_NOINTEGRALHEIGHT | LBS_SORT, 0, 20, 200, // width 600, // height hWnd, NULL, hInstance, NULL); bar = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "Foo", WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_HSCROLL | ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL, 220, 20, 500, // width 600, // height hWnd, NULL, hInstance, NULL);
Das erstellen der Fenster läuft reibungslos ab. Nun möchte ich aber erreichen, dass die beiden Kindfenster sich in der Höhe an das Hauptfenster anpassen. Gibt es da eine Funktion die mir die maximale height des Hauptfensters liefert? Wird das Hauptfester minimiert bzw. maximiert sollen die beiden Kindfenster ebenfalls minimiert bzw. maximiert werden - wie kann man das bewerkstelligen?
Mit freundlichen Grüßen,
Nico
-
In der WndProc des Hauptfensters wird dir eine Nachricht gesandt (WM_SIZE), die Größe anschließend per GetClientRect einholen und die Childs per MoveWindow verschieben.
case WM_SIZE: { RECT client; GetClientRect(hwnd, &client); MoveWindow(foo, ....); MoveWindow(bar, ....); break; }
Du solltest dir aber eines merken: Linux-Fragen werden hier anscheinend geduldet, bei WinAPI-Fragen kann es schon mal schärfere Kommentare geben
-
Dieser Thread wurde von Moderator/in SeppJ aus dem Forum C (C89 und C99) in das Forum WinAPI verschoben.
Im Zweifelsfall bitte auch folgende Hinweise beachten:
C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?Dieses Posting wurde automatisch erzeugt.
-
@Hmmh: danke, habs ausprobiert. Allerdings weiß ich derzeit nicht, wie ich auf die height und width des Hauptfensters zugreifen kann?
Achja, nochwas. Wenn ich den Zeiger RECT mainWindow im case WM_SIZE erst definiere, meldet der Debugger, dass der Zeiger mainWindow nicht deklariert wurde. Wenn ich der Zeiger außerhalb jeder Funktion definiere, scheint das in Ordnung zu gehen. Nur wieso kann ich den Pointer nicht im case definieren?
Hier übrigens der Code, den ich nun in die WndProc Funktion reingeschrieben habe:
case WM_SIZE: GetClientRect(hWnd, &mainWindow); MoveWindow(foo, 0, 0, 200, mainWindow, FALSE ); MoveWindow(bar, 220, 0, 200, mainWindow, FALSE ); break; }
Der 5. Parameter ist fehlerhaft. Was muss ich da ändern?
-
RECT ist eine Struktur mit 4 ints (linkere obere Ecke sowie die rechte untere). Beim "Client-Rect" ist oben links (0,0) (left=top=0).
Um Variablen im case-Zweig zu deklarieren, musst du einen neuen Scope aufmachen.case WM_SIZE: { RECT mainWindow; GetClientRect(hWnd, &mainWindow); MoveWindow(foo, 0, 0, 200, mainWindow.bottom, FALSE ); MoveWindow(bar, 220, 0, 200, mainWindow.bottom, FALSE ); break; }
Übrigens ist mainWindow natürlich kein Zeiger, das würde auch gar nicht funktionieren.
-
@hmmh: erstmal vielen danke für deine Hilfe. Beim Maximieren bzw. Minimieren wachsen jetzt immerhin schon die Kindfester mit
Das Ergebnis ist nun schon beinahe genau so, wie ich es mir vorgestellt habe. Nur fehlen die Scollbars bzw. werden sie teilweise versteckt. Die Propertionen der Kindfenster scheinen noch nicht komplett zu passen.
Der gesamte Code:
#include <windows.h> #include <stdio.h> #include <string.h> #include <dir.h> #include "resource.h" LPCSTR MainClassName = "Foobar"; HINSTANCE hInst; LRESULT CALLBACK WndProc(HWND hWnd,UINT iMsg, WPARAM wParam, LPARAM lParam); HWND clientsCol, clientDatas; int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) { WNDCLASSEX wc; MSG wmsg; HWND hWnd; wc.cbSize = sizeof(WNDCLASSEX); wc.style = 0; wc.lpfnWndProc = WndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.hIcon = LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(ID_ICON)); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+2); wc.lpszMenuName = MAKEINTRESOURCE(IDR_MENU1); wc.lpszClassName = MainClassName; wc.hIconSm = (HICON)LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(ID_ICON), IMAGE_ICON, 16, 16, 0); if(!RegisterClassEx(&wc)) { MessageBox(NULL, "Windows Registrations Fehler", "Error!", MB_ICONEXCLAMATION | MB_OK); return 0; } hWnd = CreateWindowEx(WS_EX_CLIENTEDGE, MainClassName, "Foobar", WS_OVERLAPPEDWINDOW | WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, // width CW_USEDEFAULT, // height NULL, NULL, hInstance, NULL); RECT mainWindow; GetWindowRect(hWnd, &mainWindow); clientsCol = CreateWindowEx(WS_EX_CLIENTEDGE, "LISTBOX", "foo", WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_HSCROLL | LBS_DISABLENOSCROLL | LBS_SORT, 0, // x 0, // y 200, // width mainWindow.bottom, // height hWnd, NULL, hInstance, NULL ); clientDatas = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "bar", WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_HSCROLL | ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL, 220, // x 0, //y mainWindow.right - 220 - GetSystemMetrics(SM_CXHSCROLL), // width mainWindow.bottom, // height hWnd, NULL, hInstance, NULL ); if (hWnd == NULL) { MessageBox(NULL, "Fehler beim Erstellen des Fensters!", "Error!", MB_ICONEXCLAMATION | MB_OK); return 0; } while (GetMessage(&wmsg,NULL,0,0)) { TranslateMessage(&wmsg); DispatchMessage(&wmsg); } return wmsg.wParam; } LRESULT CALLBACK WndProc(HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam) { switch (iMsg) { case WM_CLOSE: DestroyWindow(hWnd); break; case WM_DESTROY: PostQuitMessage(0); return 0; case WM_SIZE: { RECT mainWindow; GetWindowRect(hWnd, &mainWindow); MoveWindow(foo, 0, 0, 200, (mainWindow.bottom - GetSystemMetrics(SM_CYVSCROLL) - GetSystemMetrics(SM_CYMENU)), FALSE ); MoveWindow(bar, 220, 0, mainWindow.right - 220 - GetSystemMetrics(SM_CXHSCROLL), mainWindow.bottom - 50, FALSE ); break; } } return DefWindowProc(hWnd,iMsg,wParam,lParam); }
Mit der GetSystemMetrics Funktion habe ich versucht die Propertionen der Kindfenster genauer hinzubekommen. Aber passen tut das Ganze noch nicht so wirklich. Hier ein Screenshot wenn das Fenster maximiert ist: http://www.imgbox.de/users/public/images/ke5MqWz6mB.jpg
Wie man sieht, hat die Editbox, also das rechte Kindfenster einen minimalen Abstand nach rechts (sollte eig. nicht sein). Der Listbox, sprich dem linken Kindfenster, fehlt ein Teil des horizontalen Scrollbalken.
Und solang das Hauptfenster nicht maximiert ist, fehlen überhaupt die beiden horizontalen Scrollbalken der Kindfenster - zudem auch der vertikale Scrollbalken des rechten Kindfensters.Was muss ich noch alles beachten bzw. von welchen Fensterelementen muss ich die height und width noch abziehen?
Grüße
-
Da die Fenster im Clientbereich des Hauptfensters angezeigt werden sollen müsste es eigentlich so aussehen:
RECT mainWindow; GetClientRect(hWnd, &mainWindow); clientsCol = CreateWindowEx( WS_EX_CLIENTEDGE, L"LISTBOX", L"foo", WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_HSCROLL | LBS_DISABLENOSCROLL | LBS_SORT, 0, // x 0, // y 200, // width mainWindow.bottom-mainWindow.top, // height hWnd, NULL, hInstance, NULL ); clientDatas = CreateWindowEx( WS_EX_CLIENTEDGE, L"EDIT", L"bar", WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_HSCROLL | ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL, 210, // x 0, //y mainWindow.right - mainWindow.left - 210, // width mainWindow.bottom-mainWindow.top, // height hWnd, NULL, hInstance, NULL );