Skallierende Edit mit Skrollbalken



  • Moin, nochmal.
    Also, ich habe hier ein Hauptfenster mit einer
    Edit in der client area. Das mit dem Autoscroll
    (vertikal und horizontal) habe ich soweit schon
    selbst herausgefunden.

    Nun will ich aber eine vertikale und eine horizontale Scrollbar in
    mein Edit Control reinbringen. Außerdem soll sich das Edit Control
    der Breite und Höhe des Fensters anpassen.

    Wird das Fenster gestreckt, wird es auch das Edit Control.
    Windows erstellt ja soweit eine Nachricht zum Abholen mit GetMessage(),
    wenn das Fenster gesreckt wird. Dann lässt sich bestimt irgendwie
    die Breite des Fensters ermitteln und dieser Wert dem Edit
    Control als seinen Breitenwert setzen.

    Ich weiß leider aber nur, wie man mit CreateWindowEx ein Control
    setzt mit Angaben, wie es sein soll. Aber nicht, wie man seine
    "Eigenschaften" nachträglich ändern kann, womit so eine
    Skallierung möglich wäre.

    #include <windows.h>
    
    LPCSTR MainClassName = "Texteditor";
    
    // Zum Empfangen und Auswerten der messages
    LRESULT CALLBACK WndProc(HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam);
    
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
    {
    	// Generelle Fensterstruktur registrieren
    	WNDCLASSEX wc;
    	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(0));
    	wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    	wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
    	wc.lpszMenuName = MAKEINTRESOURCE(1);
    	wc.lpszClassName = MainClassName;
    	wc.hIconSm = (HICON)LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(0), IMAGE_ICON, 16, 16, 0);
    
    	if(!RegisterClassEx(&wc))
    	{
    		MessageBox(NULL, "Konnte das Hauptfenster nicht registrieren!", "Fehler!", MB_ICONEXCLAMATION | MB_OK);
    		return 0;
    	}
    
    	// Fenster erstellen
    	HWND hWnd = CreateWindowEx(
    		WS_EX_CLIENTEDGE,
    		MainClassName,
    		"Texteditor",
    		WS_OVERLAPPEDWINDOW,
    		CW_USEDEFAULT, CW_USEDEFAULT, 400, 300,
    		NULL,
    		NULL,
    		hInstance,
    		NULL
    	);
    
    	// Textbox ins Fenster setzen
    	HWND hCheck1 = CreateWindowEx(
    		NULL,
    		"EDIT",
    		"Gib was ein",
    		WS_CHILD | WS_VISIBLE | ES_MULTILINE | ES_AUTOHSCROLL | ES_AUTOVSCROLL,
    		0, 0, 400, 300,
    		hWnd,
    		NULL,
    		NULL,
    		NULL
    	);
    
    	// Fenster anzeigen
    	ShowWindow(hWnd, iCmdShow);
    
    	// Auf Messages reagieren
    	MSG wmsg;
    	while( GetMessage(&wmsg, NULL, 0, 0) )
    	{
    		switch (wmsg.message)
    		{
    			case WM_RBUTTONDOWN:
    				MessageBox(NULL, "Da ist nichts, was sich durch Rechtsklick öffnet!", "Entschuldige, aber...", MB_OK);
    			break;
    			default:
    				TranslateMessage(&wmsg);
    				DispatchMessage(&wmsg);
    		}
    	}
    
    	return wmsg.wParam;
    }
    
    LRESULT CALLBACK WndProc(HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
    {
    	char string[255];
    
    	switch (iMsg)
    	{
    		case WM_CLOSE:
    			DestroyWindow(hWnd);
    		break;
    		case WM_DESTROY:
    			PostQuitMessage(0);
    			return 0;
    		case WM_COMMAND:
    			switch(LOWORD(wParam))
    			{
    				case 11:
    					LoadString(GetModuleHandle(NULL), 21, string, sizeof(string));
    					MessageBox(hWnd, string, "Öffnen", MB_ICONINFORMATION);
    				break;
    				case 12:
    					LoadString(GetModuleHandle(NULL), 22, string, sizeof(string));
    					MessageBox(hWnd, string, "Speichern", MB_ICONINFORMATION);
    				break;
    				case 13:
    					DestroyWindow(hWnd);
    				break;
    			}
    		break;
    	}
    
    	// An Windows weitergeben und dessen Antwort als Rückgabewert zurück
    	return DefWindowProc(hWnd, iMsg, wParam, lParam);
    }
    

    Jetzt frage ich euch, wie das geht.
    Danke dann.



  • ganz einfach
    du faengst die nachricht "WM_SIZE" und in dieser hast du dann die neuen groessen X und Y als parameter, dann brauchst du nur dein edit nehmen unt mit MoveWindow neu skalieren
    feddich is
    fuer dauerhafte scroll elemente musste halt ma die edit styles durch schaun
    (parameter nachtraeglich aendern geht mit SetWindowLong wenn ich mich nicht irre)



  • thx. Nur gibt es keine style flags für scrollbars für das EDIT control,
    so wie ich bereits in der msdn rumrecharchiert habe.

    // Edit #1000

    #include <windows.h>
    
    LPCSTR MainClassName = "Texteditor";
    
    // Zum Empfangen und Auswerten der messages
    LRESULT CALLBACK WndProc(HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam);
    
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
    {
    	// Generelle Fensterstruktur registrieren
    	WNDCLASSEX wc;
    	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(0));
    	wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    	wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
    	wc.lpszMenuName = MAKEINTRESOURCE(1);
    	wc.lpszClassName = MainClassName;
    	wc.hIconSm = (HICON)LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(0), IMAGE_ICON, 16, 16, 0);
    
    	if(!RegisterClassEx(&wc))
    	{
    		MessageBox(NULL, "Konnte das Hauptfenster nicht registrieren!", "Fehler!", MB_ICONEXCLAMATION | MB_OK);
    		return 0;
    	}
    
    	// Fenster erstellen
    	HWND hWnd = CreateWindowEx(
    		WS_EX_CLIENTEDGE,
    		MainClassName,
    		"Texteditor",
    		WS_OVERLAPPEDWINDOW,
    		CW_USEDEFAULT, CW_USEDEFAULT, 400, 300,
    		NULL,
    		NULL,
    		hInstance,
    		NULL
    	);
    
    	// Textbox ins Fenster setzen
    	HWND hwndEdit = CreateWindowEx(
    		NULL,
    		"EDIT",
    		"Gib was ein",
    		WS_CHILD | WS_BORDER | WS_VISIBLE | ES_MULTILINE | ES_AUTOHSCROLL | ES_AUTOVSCROLL,
    		0, 0, 400, 300,
    		hWnd,
    		NULL,
    		NULL,
    		NULL
    	);
    
    	// Fenster anzeigen
    	ShowWindow(hWnd, iCmdShow);
    
    	// Auf Messages reagieren
    	MSG wmsg;
    	while( GetMessage(&wmsg, NULL, 0, 0) )
    	{
    		switch (wmsg.message)
    		{
    			/* Vergleichbar: Private Sub Form_Resize */
    			case WM_SIZE:
    				// EDIT Control skallieren
    				SetWindowPos(      
    					hwndEdit, hWnd,
    					0, 0, wmsg.wParam, wmsg.lParam,
    					NULL
    				);
    			break;
    			default:
    				TranslateMessage(&wmsg);
    				DispatchMessage(&wmsg);
    		}
    	}
    
    	return wmsg.wParam;
    }
    
    LRESULT CALLBACK WndProc(HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
    {
    	char string[255];
    
    	switch (iMsg)
    	{
    		case WM_CLOSE:
    			DestroyWindow(hWnd);
    		break;
    		case WM_DESTROY:
    			PostQuitMessage(0);
    			return 0;
    		case WM_COMMAND:
    			switch(LOWORD(wParam))
    			{
    				case 11:
    					LoadString(GetModuleHandle(NULL), 21, string, sizeof(string));
    					MessageBox(hWnd, string, "Öffnen", MB_ICONINFORMATION);
    				break;
    				case 12:
    					LoadString(GetModuleHandle(NULL), 22, string, sizeof(string));
    					MessageBox(hWnd, string, "Speichern", MB_ICONINFORMATION);
    				break;
    				case 13:
    					DestroyWindow(hWnd);
    				break;
    			}
    		break;
    	}
    
    	// An Windows weitergeben und dessen Antwort als Rückgabewert zurück
    	return DefWindowProc(hWnd, iMsg, wParam, lParam);
    }
    

    Üüüberhaupt keine Skallierung 😞


  • Mod

    Sicher gibt es diese. Lass die ES_AUTO... Flags weg, und setze bei Bedarf WS_HSCROLL und WS_VSCROLL!

    Ansonsten heißt Skalieren, dass Du WM_SIZE als nachtricht behandelts und das Fenster anpasst. Das wurde Dir aber schon gesagt!



  • Martin Richter schrieb:

    Ansonsten heißt Skalieren, dass Du WM_SIZE als nachtricht behandelts und das Fenster anpasst. Das wurde Dir aber schon gesagt!

    Das hab ich doch gemacht. Das EDIT Control wächst nicht mit.

    0, 0, wmsg.wParam, wmsg.lParam,
    

    Die neue Breite und Höhe ist ja scheinbar nicht wParam und lParam.
    Und innerhalb der Fensterprozedur ist das handle zum EDIT Control
    ja nicht mehr sichtbar.

    Überhaupt tritt diese Case nicht ein!
    Wie fresse ich mich in der Fensterprozedur dann zum control durch?

    #include <windows.h>
    
    LPCSTR MainClassName = "Texteditor";
    
    // Zum Empfangen und Auswerten der messages
    LRESULT CALLBACK WndProc(HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam);
    
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
    {
    	// Generelle Fensterstruktur registrieren
    	WNDCLASSEX wc;
    	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(0));
    	wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    	wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
    	wc.lpszMenuName = MAKEINTRESOURCE(1);
    	wc.lpszClassName = MainClassName;
    	wc.hIconSm = (HICON)LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(0), IMAGE_ICON, 16, 16, 0);
    
    	if(!RegisterClassEx(&wc))
    	{
    		MessageBox(NULL, "Konnte das Hauptfenster nicht registrieren!", "Fehler!", MB_ICONEXCLAMATION | MB_OK);
    		return 0;
    	}
    
    	// Fenster erstellen
    	HWND hWnd = CreateWindowEx(
    		WS_EX_CLIENTEDGE,
    		MainClassName,
    		"Texteditor",
    		WS_OVERLAPPEDWINDOW | WS_VSCROLL | WS_HSCROLL,
    		CW_USEDEFAULT, CW_USEDEFAULT, 400, 300,
    		NULL,
    		NULL,
    		hInstance,
    		NULL
    	);
    
    	// Textbox ins Fenster setzen
    	HWND hwndEdit = CreateWindowEx(
    		NULL,
    		"EDIT",
    		"Gib was ein",
    		WS_CHILD | WS_VISIBLE | ES_MULTILINE | ES_AUTOHSCROLL | ES_AUTOVSCROLL,
    		3, 3, 400, 300,
    		hWnd,
    		NULL,
    		NULL,
    		NULL
    	);
    
    	// Fenster anzeigen
    	ShowWindow(hWnd, iCmdShow);
    
    	// Auf Messages reagieren
    	MSG wmsg;
    	while( GetMessage(&wmsg, NULL, 0, 0) )
    	{
    		TranslateMessage(&wmsg);
    		DispatchMessage(&wmsg);
    	}
    
    	return wmsg.wParam;
    }
    
    LRESULT CALLBACK WndProc(HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
    {
    	char string[255];
    
    	switch (iMsg)
    	{
    		case WM_SIZE:
    			MessageBox(NULL, "soweit drin", "hallo", MB_OK);
    
    			// EDIT Control skallieren
    			// WIE?
    		break;
    		case WM_CLOSE:
    			DestroyWindow(hWnd);
    		break;
    		case WM_DESTROY:
    			PostQuitMessage(0);
    			return 0;
    		case WM_COMMAND:
    			switch(LOWORD(wParam))
    			{
    				case 11:
    					LoadString(GetModuleHandle(NULL), 21, string, sizeof(string));
    					MessageBox(hWnd, string, "Öffnen", MB_ICONINFORMATION);
    				break;
    				case 12:
    					LoadString(GetModuleHandle(NULL), 22, string, sizeof(string));
    					MessageBox(hWnd, string, "Speichern", MB_ICONINFORMATION);
    				break;
    				case 13:
    					DestroyWindow(hWnd);
    				break;
    			}
    		break;
    	}
    
    	// An Windows weitergeben und dessen Antwort als Rückgabewert zurück
    	return DefWindowProc(hWnd, iMsg, wParam, lParam);
    }
    

    Ersetze ich Zeieln 79 bis 82 mit

    HWND hEdit = GetWindow(hWnd, GW_OWNER);
    
    			SetWindowPos(      
    				hEdit, hWnd,
    				0, 0, wParan, wParam,
    				NULL
    			);
    

    krieg ich den compile error

    55 C:\Dokumente und Einstellungen\sjBlack\Desktop\filebrowser\main.cpp [Warning] passing NULL used for non-pointer converting 1 of `HWND__* CreateWindowExA(DWORD, const CHAR*, const CHAR*, DWORD, int, int, int, int, HWND__*, HMENU__*, HINSTANCE__*, void*)'
    

  • Mod

    Und wo passt Du die Größe des Edit Controls an. Oder wo rufst Du MoveWndow oder SetWindowPos auf?
    Breite und Höhe werden in den WM_SIZE wParam/lParam Werten mit gegeben. Du kannst auch GetCLientrect aufrufen um die Koordinaten zu bekoommen.

    Diese Nachricht kommt! Garantiert und immer!



  • Habe meinen vorigen post erweitert.
    Ich bekomme einen compile error am Arsch des sources,
    wenn ich code unter case WM_SIZE setze.

    Mit GetWindow versuche ich, ein handle zum EDIT Control
    innerhalb des Hauptfensters zu bekommen.

    Also hier der ganze neue code

    #include <windows.h>
    
    LPCSTR MainClassName = "Texteditor";
    
    // Zum Empfangen und Auswerten der messages
    LRESULT CALLBACK WndProc(HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam);
    
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
    {
    	// Generelle Fensterstruktur registrieren
    	WNDCLASSEX wc;
    	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(0));
    	wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    	wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
    	wc.lpszMenuName = MAKEINTRESOURCE(1);
    	wc.lpszClassName = MainClassName;
    	wc.hIconSm = (HICON)LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(0), IMAGE_ICON, 16, 16, 0);
    
    	if(!RegisterClassEx(&wc))
    	{
    		MessageBox(NULL, "Konnte das Hauptfenster nicht registrieren!", "Fehler!", MB_ICONEXCLAMATION | MB_OK);
    		return 0;
    	}
    
    	// Fenster erstellen
    	HWND hWnd = CreateWindowEx(
    		WS_EX_CLIENTEDGE,
    		MainClassName,
    		"Texteditor",
    		WS_OVERLAPPEDWINDOW | WS_VSCROLL | WS_HSCROLL,
    		CW_USEDEFAULT, CW_USEDEFAULT, 400, 300,
    		NULL,
    		NULL,
    		hInstance,
    		NULL
    	);
    
    	// Textbox ins Fenster setzen
    	HWND hwndEdit = CreateWindowEx(
    		NULL,
    		"EDIT",
    		"Gib was ein",
    		WS_CHILD | WS_VISIBLE | ES_MULTILINE | ES_AUTOHSCROLL | ES_AUTOVSCROLL,
    		3, 3, 400, 300,
    		hWnd,
    		NULL,
    		NULL,
    		NULL
    	);
    
    	// Fenster anzeigen
    	ShowWindow(hWnd, iCmdShow);
    
    	// Auf Messages reagieren
    	MSG wmsg;
    	while( GetMessage(&wmsg, NULL, 0, 0) )
    	{
    		TranslateMessage(&wmsg);
    		DispatchMessage(&wmsg);
    	}
    
    	return wmsg.wParam;
    }
    
    LRESULT CALLBACK WndProc(HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
    {
    	char string[255];
    
    	switch (iMsg)
    	{
    		case WM_SIZE:
    			HWND hEdit = GetWindow(hWnd, GW_CHILD);
    
    			SetWindowPos(      
    				hEdit, hWnd,
    				0, 0, wParam, wParam,
    				NULL
    			); 
    		break;
    		case WM_CLOSE:
    			DestroyWindow(hWnd);
    		break;
    		case WM_DESTROY:
    			PostQuitMessage(0);
    			return 0;
    		case WM_COMMAND:
    			switch(LOWORD(wParam))
    			{
    				case 11:
    					LoadString(GetModuleHandle(NULL), 21, string, sizeof(string));
    					MessageBox(hWnd, string, "Öffnen", MB_ICONINFORMATION);
    				break;
    				case 12:
    					LoadString(GetModuleHandle(NULL), 22, string, sizeof(string));
    					MessageBox(hWnd, string, "Speichern", MB_ICONINFORMATION);
    				break;
    				case 13:
    					DestroyWindow(hWnd);
    				break;
    			}
    		break;
    	}
    
    	// An Windows weitergeben und dessen Antwort als Rückgabewert zurück
    	return DefWindowProc(hWnd, iMsg, wParam, lParam);
    }
    

    Ohne den code unter case WS_SIZE compiliert es ohne Fehlermeldungen.


Anmelden zum Antworten