Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 14.01.2013, 12:54   #1
x_Alex_x
Пользователь
 
Регистрация: 13.01.2013
Сообщений: 94
По умолчанию Затирание дочерних окон winapi

Здравствуйте! Столкнулся с такой проблемой: создал новый C++ Win32 проект в 2010 студии с уже готовым шаблоном приложения. В главном окне есть кнопка и эдит поле; по нажатии на кнопку создаётся дочернее окно с другим полем редактирования текста, в котором, в отличее от поля на главном окне, нельзя писать. К тому же, дочернее окно затирается элементами главного окна и такими же дочерними окнами:

Я думал, что не могу писать в полях дочерних окон т.к. на окнах нет "фокуса". Пытался его ставить вручную (SetFocus), но это не помогло. (

вот код главного окна:
Код:
case WM_CREATE:
		//кнопка
		button1 = CreateWindow(L"button", L"Дави", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
			120, 10, 121, 30, hWnd, (HMENU)BUTTON1, hInst, NULL);
		//Поле ввода текста
		Edit2=CreateWindow(L"edit", L"Текст", WS_CHILD|WS_BORDER|WS_VISIBLE|WS_CLIPSIBLINGS|
				WS_VSCROLL|             // Окну добавляется горизонтальная полоса прокрутки
				WS_HSCROLL|             // Окну добавляется горизонтальная полоса прокрутки
				ES_LEFT|                // Текст выровненный по левому краю окна
				ES_AUTOHSCROLL|         // Возможность выхода текста за границу окна и автоматической горизонтальной прокрутки
				ES_MULTILINE,
				10,130,100,80,hWnd,(HMENU)EDIT2, hInst, NULL);
	break;
...

case WM_COMMAND:
		wmId    = LOWORD(wParam);
		wmEvent = HIWORD(wParam);
		// Parse the menu selections:
		switch (wmId)
		{
		case BUTTON1://Если нажал кнопку
			WNDCLASS w;
			memset(&w,0,sizeof(WNDCLASS));

				w.lpfnWndProc = ChildProc;
				w.hInstance = hInst;
				w.hbrBackground = GetStockBrush(WHITE_BRUSH);
				w.lpszClassName = L"ChildWClass";
				w.hCursor=LoadCursor(NULL,IDC_CROSS); 
				RegisterClass(&w);
				HWND child;

				child=CreateWindowEx(0,L"ChildWClass",(LPCTSTR) L"Дочернее",
					WS_CHILD |WS_OVERLAPPEDWINDOW| WS_BORDER | WS_VISIBLE ,250,50,
					400,300,hWnd,(HMENU) 1,hInst,NULL);
				ShowWindow(child,SW_NORMAL);
				UpdateWindow(child);
				SetFocus(child);//////////////////////////////////////////////////////////////UpdateWindow(child);
			break;
...
вот дочернего:

Код:
case WM_CREATE:
			Edit1=CreateWindow(L"edit", L"Текст", WS_CHILD|WS_BORDER|WS_VISIBLE|WS_CLIPSIBLINGS|
				WS_VSCROLL|             // Окну добавляется горизонтальная полоса прокрутки
				WS_HSCROLL|             // Окну добавляется горизонтальная полоса прокрутки
				ES_LEFT|                // Текст выровненный по левому краю окна
				ES_AUTOHSCROLL|         // Возможность выхода текста за границу окна и автоматической горизонтальной прокрутки
				ES_MULTILINE,
				10,10,300,80,hWnd,(HMENU)EDIT1, hInst, NULL);
		break;
...
Подскажите кто что думает? В интернетах решения не нашёл(
x_Alex_x вне форума Ответить с цитированием
Старый 14.01.2013, 13:16   #2
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,331
По умолчанию

ChildProc вызывает DefWindowProc?
waleri вне форума Ответить с цитированием
Старый 14.01.2013, 13:39   #3
x_Alex_x
Пользователь
 
Регистрация: 13.01.2013
Сообщений: 94
По умолчанию

Я новичок и пишу исключительно по шаблонам, найденным в инете и ещё сам не понимаю большую часть кода. В примере, который я использовал для написания этого кода была такая же проблема с затиранием. Других примеров не нашёл(
x_Alex_x вне форума Ответить с цитированием
Старый 14.01.2013, 13:49   #4
x_Alex_x
Пользователь
 
Регистрация: 13.01.2013
Сообщений: 94
По умолчанию

Цитата:
Сообщение от waleri Посмотреть сообщение
ChildProc вызывает DefWindowProc?
единственное, что могу сказать - DefWindowProc встречается здесь:
Код:
switch (message)
{

...

default:
	return DefWindowProc(hWnd,Message,wparam,lparam);
}
break;
в функции главного и дочерних окон
x_Alex_x вне форума Ответить с цитированием
Старый 14.01.2013, 15:29   #5
EUGY
Форумчанин
 
Аватар для EUGY
 
Регистрация: 11.07.2010
Сообщений: 914
По умолчанию

Затирается из-за отсутствия стиля WS_CLIPSIBLINGS.
В примерах этот стиль не стоит, так как новые окна порождаются без родителя.
У Вас же новое окно имеет родителем главное и может отображаться только внутри него. Как будто это MDI приложение.
EUGY вне форума Ответить с цитированием
Старый 14.01.2013, 15:53   #6
x_Alex_x
Пользователь
 
Регистрация: 13.01.2013
Сообщений: 94
По умолчанию

EUGY, большое спасибо! одна проблема решена )) Но остались ещё минимум две:
1. Создаваемые кнопкой окна лежат в одном и том же порядке и никак не получается сделать одно из них активным и вынести на передний план.
2. Я всё ещё не могу писать в эдит полях дочерних окон.

Думаю и то и другое решается одним и тем же способом.?

А если не трудно, можете объяснить где нужно использовать этот WS_CLIPSIBLINGS стиль?
x_Alex_x вне форума Ответить с цитированием
Старый 14.01.2013, 16:00   #7
x_Alex_x
Пользователь
 
Регистрация: 13.01.2013
Сообщений: 94
По умолчанию

А вот и третья: кнопка, поле с текстом и эдит поле главного окна отрисовываются поверх дочерних окон.
ps: EUGY, по-идее и должно получится MDI приложение.
x_Alex_x вне форума Ответить с цитированием
Старый 14.01.2013, 16:14   #8
EUGY
Форумчанин
 
Аватар для EUGY
 
Регистрация: 11.07.2010
Сообщений: 914
По умолчанию

По первым пунктам советую сразу пересмотреть дизайн программы. И создать MDI приложение, а не изобретать велосипед. Хотя, конечно, интересно
Насчет clipsibling.
Вот есть главное окно. На нем расположены дочерние окна.
У окна есть графический контекст hDC. Чтобы дочернее окно было в области отсечения этого контекста, у родительского окна должен быть стиль WS_CLIPCHILDREN. А у дочерних окон, если они могут перекрывать друг друга - стиль WS_CLIPSIBLING.
Иначе при попытке рисовать по контексту родительского окна рисунок будет затирать дочерние.
PS. MDI приложение отличается тем, что дочерние окна имеют родителем специальное окно класса MDIClient, которое в свою очередь имеет родителем главное. И оконные процедуры имеют дефолтные вызовы DefMDIChildProc, DefFrameProc.

Последний раз редактировалось EUGY; 14.01.2013 в 16:18.
EUGY вне форума Ответить с цитированием
Старый 14.01.2013, 18:43   #9
x_Alex_x
Пользователь
 
Регистрация: 13.01.2013
Сообщений: 94
По умолчанию

Хм.. Так как мне запилить сразу MDI проект? В настройках при создании C++ Win32 проекта такой кнопки вроде нет. Или я не там смотрел?
Если это всё пишется ручками, то вряд ли осилю.
Можно примерчик?

Последний раз редактировалось x_Alex_x; 14.01.2013 в 18:55.
x_Alex_x вне форума Ответить с цитированием
Старый 14.01.2013, 19:20   #10
EUGY
Форумчанин
 
Аватар для EUGY
 
Регистрация: 11.07.2010
Сообщений: 914
По умолчанию

Ничего особенного.
Пустой проект. один cpp файл. юникод.

Код:
#include <windows.h>
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK CldProc(HWND, UINT, WPARAM, LPARAM);


ATOM RegisterMainClass(HINSTANCE hInstance)
{
	WNDCLASSEX wcex = {};

	wcex.cbSize = sizeof(WNDCLASSEX); 

	wcex.style			= CS_HREDRAW | CS_VREDRAW;
	wcex.lpfnWndProc	= (WNDPROC)WndProc;
	wcex.hInstance		= hInstance;
	wcex.hCursor		= LoadCursor(NULL, IDC_ARROW);
	wcex.lpszClassName	= L"MY_MAIN_MDI";
	return RegisterClassEx(&wcex);
}

ATOM RegisterChildClass(HINSTANCE hInstance)
{
	WNDCLASSEX wcex = {};

	wcex.cbSize = sizeof(WNDCLASSEX); 

	wcex.style			= CS_HREDRAW | CS_VREDRAW;
	wcex.lpfnWndProc	= (WNDPROC)CldProc;
	wcex.hInstance		= hInstance;
	wcex.hCursor		= LoadCursor(NULL, IDC_ARROW);
	wcex.hbrBackground	= (HBRUSH)GetStockObject(WHITE_BRUSH);
	wcex.lpszClassName	= L"MY_CHILD";
	return RegisterClassEx(&wcex);
}


int WINAPI  WinMain(HINSTANCE hInst, HINSTANCE , LPSTR ,  int)
{

	RegisterMainClass(hInst);
	RegisterChildClass(hInst);

	HMENU hmenu = CreateMenu();
	HWND hwndMain = CreateWindowEx(NULL, L"MY_MAIN_MDI", L"", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, hmenu, hInst, NULL);
	
	
	
	HWND hwndClient = FindWindowEx(hwndMain,NULL, L"MDICLIENT",NULL);
	
	ShowWindow(hwndMain,SW_SHOW);
	
	HWND hwndChild = CreateWindowEx(WS_EX_MDICHILD, L"MY_CHILD", L"", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, hwndClient, NULL, hInst, NULL);
	ShowWindow(hwndChild, SW_SHOW);
	
	MSG msg;
	while (GetMessage(&msg, NULL, 0, 0)) 
	{

			TranslateMessage(&msg);
			DispatchMessage(&msg);
	}
	return 0;
}

LRESULT CALLBACK CldProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	
	return DefMDIChildProc(hWnd,  message, wParam, lParam);
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{

	switch (message) 
	{
	
	case WM_CREATE:
		{
		CLIENTCREATESTRUCT ccs = {};
		CreateWindowEx(NULL, L"MDICLIENT",NULL,  WS_VISIBLE|WS_CHILD|WS_CLIPCHILDREN|WS_VSCROLL|WS_HSCROLL,0,0,0,0, hWnd,NULL,NULL,&ccs);
		}
		break;
	case WM_DESTROY:
		PostQuitMessage(0);
		break;

	}
	return DefFrameProc(hWnd, FindWindowEx(hWnd, NULL, L"MDICLIENT", NULL), message, wParam, lParam);
}
EUGY вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Затиание дочерних окон x_Alex_x Помощь студентам 0 13.01.2013 12:56
MDI - исключение дочерних окон из перехода по ctrl+tab andrew_jr20 C# (си шарп) 0 12.01.2012 22:52
Закрытие и открытие дочерних MDI окон приложения chandrasecar Общие вопросы Delphi 4 16.05.2011 13:41
Поведение дочерних окон maryan.vetrov C# (си шарп) 9 27.02.2011 18:09
SetWindowPos для дочерних окон и битмапов. Alex Cones Общие вопросы Delphi 4 02.02.2011 13:49