Obsługa WM_SIZE,skalowanie kontrolek

0

Witam, przedstawię problem krótko i na temat. Program który stworzyłem sortuje liczby w polach edit oraz dodaje lub usuwa je.
Problem jest następujący po naciśnięciu dowolnego przycisku ww 3 przyciski znikają. Sądzę ze wartości wParam oraz lParam dla komunikatu zmieniają swa wartość po wymuszeniu SendMessage i dlatego kontrolki znikają, proszę o treściwe wyjaśnienie. Dziękuję za każdą pomoc.


#include "stdafx.h"
#include <vector>
#include <string>
#include <windows.h>
using namespace std;
int x,y;
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
                    PSTR  szCmdLine, int iCmdShow)
{
     static TCHAR szAppName[] = TEXT ("Checker1") ;
     HWND         hwnd ;
     MSG          msg ;
     WNDCLASS     wndclass ;
     
     wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
     wndclass.lpfnWndProc   = WndProc ;
     wndclass.cbClsExtra    = 0 ;
     wndclass.cbWndExtra    = 0 ;
     wndclass.hInstance     = hInstance ;
     wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
     wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
     wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
     wndclass.lpszMenuName  = NULL ;
     wndclass.lpszClassName = szAppName ;
     
     if (!RegisterClass (&wndclass))
     {
          MessageBox (NULL, TEXT ("Program requires Windows NT!"), 
                      szAppName, MB_ICONERROR) ;
          return 0 ;
     }
     
     hwnd = CreateWindow (szAppName, TEXT ("Checker1 Mouse Hit-Test Demo"),
                          WS_OVERLAPPEDWINDOW,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          NULL, NULL, hInstance, NULL) ;
     ShowWindow (hwnd, iCmdShow) ;
     UpdateWindow (hwnd) ;
     
     while (GetMessage (&msg, NULL, 0, 0))
     {
          TranslateMessage (&msg) ;
          DispatchMessage (&msg) ;
     }
     return msg.wParam ;
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	int wmId, wmEvent;
	static int cxChar,cyChar,iLength,cxClient,cyClient,i=0,s=5;
	PAINTSTRUCT ps;
	HDC hdc;
	TCHAR buffer[100];
	static vector<HWND> pola;
	static HWND sortuj,dodaj,usun,traf;
	static vector<int>liczby;
	switch (message)
	{
	case WM_CREATE:
		cxChar=LOWORD(GetDialogBaseUnits());
		cyChar=HIWORD(GetDialogBaseUnits());
		for (i=0;i<5;i++)
		{
			liczby.push_back(rand()%100+1);
			wsprintf(buffer,L"%d",liczby[i]);
			pola.push_back(CreateWindowEx(0,TEXT("edit"),buffer,WS_CHILD|WS_VISIBLE|WS_BORDER|ES_LEFT
				|ES_MULTILINE,cxChar*(1+20*i),cyChar*(3),20*cxChar,7*cyChar/4,hWnd,(HMENU) i,((LPCREATESTRUCT)lParam)->hInstance,NULL));

		}
		SendMessage(hWnd,WM_SIZE,wParam,lParam);
		sortuj=CreateWindowEx(0,TEXT("button"),TEXT("Sortuj"),WS_CHILD|WS_VISIBLE|WS_BORDER
			,0,0,100,30,hWnd,(HMENU) 99,((LPCREATESTRUCT)lParam)->hInstance,NULL);
		dodaj=CreateWindowEx(0,TEXT("button"),TEXT("Dodaj"),WS_CHILD|WS_VISIBLE|WS_BORDER
			,100,0,100,30,hWnd,(HMENU) 100,((LPCREATESTRUCT)lParam)->hInstance,NULL);
		usun=CreateWindowEx(0,TEXT("button"),TEXT("Usun"),WS_CHILD|WS_VISIBLE|WS_BORDER
			,200,0,100,30,hWnd,(HMENU) 101,((LPCREATESTRUCT)lParam)->hInstance,NULL);
		return 0;

		case WM_SIZE:
		cxClient=LOWORD(lParam);
		cyClient=HIWORD(lParam);
		x=cxClient/s;
		y=cyClient/s;
		MoveWindow(sortuj,0,0,cxClient/6,cyClient/12,true);
		MoveWindow(dodaj,cxClient/2-(cxClient/12),0,cxClient/6,cyClient/12,true);
		MoveWindow(usun,cxClient-(cxClient/6),0,cxClient/6,cyClient/12,true);
		for(int w=0;w<s;w++)
		{
			MoveWindow(pola[w],0+(x*w),100,x,50,true);
		}
	return 0;
	case WM_PAINT:
		hdc = BeginPaint(hWnd, &ps);
		// TODO: Add any drawing code here...
		EndPaint(hWnd, &ps);
		break;
	case WM_DESTROY:
		PostQuitMessage(0);
		break;

		case WM_COMMAND:
		wmId    = LOWORD(wParam);
		wmEvent = HIWORD(wParam);
		// Parse the menu selections:
		switch (wmId)
		{
		case 99:			//SORTOWANIE
			i=s;
	for (int w=0;w<i-1;w++)
		{
				for (int j=0;j<i-1;j++)
			{
				if(liczby[j]>liczby[j+1])
				{
					swap(liczby[j],liczby[j+1]);
				}		
		    }
	
		}
			for (int w=0;w<i;w++)
		{
			iLength=wsprintf(buffer,TEXT("%d"),liczby[w]);
			SetWindowText(pola[w],buffer);
		}
			break;
		case 100:				//DODOWANIE
			++s;
			liczby.push_back(rand()%100+1);
			wsprintf(buffer,TEXT("%i"),liczby[s-1]);
		pola.push_back(CreateWindowEx(0,TEXT("edit"),buffer,WS_CHILD|WS_VISIBLE|WS_BORDER|ES_LEFT
				|ES_MULTILINE,0,0,0,0,hWnd,(HMENU) s,((LPCREATESTRUCT)lParam)->hInstance,NULL));
	SendMessage(hWnd,WM_SIZE,wParam,lParam);
			break;
		case 101:
			if (liczby.size()>0 && pola.size()>0)
			{
		liczby.pop_back();
		DestroyWindow(pola[pola.size()-1]);
		pola.pop_back();
			--s;
			SendMessage(hWnd,WM_SIZE,wParam,lParam);
			}
		return 0;
		default:
			SendMessage(hWnd,WM_SIZE,wParam,lParam);
			return DefWindowProc(hWnd, message, wParam, lParam);
		}
	default:
		return DefWindowProc(hWnd, message, wParam, lParam);
	}
	return 0;
}
 
0

Po co wysyłasz WM_SIZE? Jeśli chcesz zmienić rozmiar okna to użyj funkcji MoveWindow.

0

WM_SIZE jest wywolywany pozniej niz WM_CREATE przez co nie moge posluzyc sie rozmiarami okna przechowywanymi w cxClient oraz cyClient

0

Nie rozumiem.
W każdym razie, tak jak pisałem, aby zmienić rozmiar okna użyj MoveWindow. Nie wysyłaj WM_SIZE, nie wolno. WM_SIZE to komunikat który ma przyjść PO zmianie rozmiaru okna. MoveWindow wyśle go automatycznie. Aktualny rozmiar okna odczytasz funkcją GetWindowSize. Jest jeszcze funkcja SetWindowPos którą możesz użyć do zmiany rozmiaru okna. Podając flagę SWP_NOMOVE nie musisz podawać nowego położenia a tylko rozmiar, położenie zostanie bez zmian.

0

Ok poszedlem za Twoja rada. Jednak mam jeszcze jeden problem. Otoz "losowo" wywala mi blad przy wsprintf w case (dodaj), otoz kiedy nacisne przycisk dodaj wyskakuje powiadomienie: "Unhandled exception at 0x76ed15ee in przyciski.exe: 0x00000000: Operacja ukończona pomyślnie."
Potem skompiluje ponownie i bledu nie ma .Nie mam pojecia o co kaman.
Tamten problem rozwiazalem mniejwiecej tak:

 
case 100:				//DODOWANIE	
			s++;
			x=cxClient/s;
		y=cyClient/s;
			liczby.push_back(rand()%100+1);
			iLength=wsprintf(buffer2,TEXT("%d"),liczby[s-1]);
		pola.push_back(CreateWindowEx(0,TEXT("edit"),buffer2,WS_CHILD|WS_VISIBLE|WS_BORDER|ES_LEFT
				|ES_MULTILINE,0,0,0,0,hWnd,(HMENU) (s-1),((LPCREATESTRUCT)lParam)->hInstance,NULL));
		for(int w=0;w<s;w++)
		{
			MoveWindow(pola[w],0+(x*w),100,x,50,true);
		}

i

GetClientRect(hWnd, &r);
		MoveWindow(sortuj,0,0,(r.right/3),30,true);
		MoveWindow(dodaj,(r.right/3),0,(r.right/3),30,true);
		MoveWindow(usun,(r.right/3)*2,0,(r.right/3),30,true);
 
0

Pokaż kod. Możesz całość zamieścić na Pastebin

0

wywala mi blad przy wsprintf

Jeśli to Visual, użyj swprintf_s, a błąd dostaniesz przy kompilacji a nie uruchomieniu - i prędzej się dowiesz, co jest nie tak.

1 użytkowników online, w tym zalogowanych: 0, gości: 1