· Начало · Отвђтить · Статистика · Поиск · FAQ · Правила · Установки · Язык · Выход · WASM.RU · Noir.Ru ·

 WASM Phorum —› WASM.WIN32 —› Постоянный размер клиентской области окна

Посл.отвђт Сообщенiе


Дата: Мар 13, 2004 09:23:49

Привет всем!
(может я плохо искал.. но ответ на форуме так и не нашел)

Нужны мне окошки примитивные до ужаса.
Но есть требование - постоянный размер клиентской области.
Причем размер этот не должен зависить от темы/стиля и т.п.
Раньше я делал это таким образом
(при обработке: WM_ACTIVATEAPP, WM_ACTIVATE, WM_PAINT - уже и сам не знаю, почему именно их ;-)
AjustWindow:
	invoke	GetClientRect, hWnd, ADDR ClientRect
	invoke	GetWindowRect, hWnd, ADDR WindowRect
	mov	EDX,	WindowRect.right
	sub	EDX,	WindowRect.left
	add	EDX,	VP_XMAX	;;  это требуемый размер
	sub	EDX,	ClientRect.right
	mov	ECX,	WindowRect.bottom
	sub	ECX,	WindowRect.top
	add	ECX,	VP_YMAX	;;  это требуемый размер
	sub	ECX,	ClientRect.bottom
	invoke	MoveWindow, hWnd, WindowRect.left, WindowRect.top, EDX, ECX, FALSE
	retn

Но сейчас мне это кажется как-то не Дзенно..
Столько вызовов API ради такой мелочи да еще когда попало..


Читаю MSDN (ох и не люблю я это..):
The system sends the WM_WINDOWPOSCHANGING message to a window whose size, position, position in the z-order, or show state is about to change. This message includes a pointer to a WINDOWPOS structure that specifies the window's new size, position, position in the z-order, and show state. By setting the members of WINDOWPOS, an application can affect the window's new size, position, and appearance.

Вот оно!!
Пробую так (тут FASM, но смысл простой):
proc	ConWindow.WM_WINDOWPOSCHANGING , hwnd,uMsg,wParam,lParam	
	mov	edx, [lParam]		;;  Pointer to a WINDOWPOS structure
	assume	edx, WINDOWPOS, .WINDOWPOS
	mov	[.WINDOWPOS.cx], 800
	mov	[.WINDOWPOS.cy], 600
	and	[.WINDOWPOS.flags],NOT SWP_NOSIZE


Это работает на ура. Размер окна постоянный, теперь модифицирую, дабы получить трубуемую клиентскую область:
proc	ConWindow.WM_WINDOWPOSCHANGING , hwnd,uMsg,wParam,lParam	
	. client, RECT
begin
	assume	EBX, SWnd		;;  assume .handle, etc = EBP+SWnd
	invoke	GetClientRect,[.handle], ESP	;;  ESP = ptr to [.client]
	mov	edx, [lParam]		;;  Pointer to a WINDOWPOS structure
	assume	edx, WINDOWPOS, .WINDOWPOS

	mov	eax, [.nWidth]	;;  здесь требуемый размер
	sub	eax, [.client.right]	
	add	[.WINDOWPOS.cx], eax
	
	mov	eax, [.nHeight]	;;  здесь требуемый размер
	sub	eax, [.client.bottom]	
	add	[.WINDOWPOS.cy], eax
	and	[.WINDOWPOS.flags],NOT SWP_NOSIZE
;	or	[.WINDOWPOS.flags],SWP_NOSENDCHANGING
	add	ESP, local_size		;;  release stack frame	
	jmp	ConWindow.def

Борода!! Работает фиг пойми как. То удваивает размер, то еще чего.
Смотрю в Olly - похоже вызывается рекурсивно эта штука время от времени, причем зависимость я так и не понял.
Структура WINDOWPOS содержит когда что.. :(
SWP_NOSENDCHANGING видимого эффекта не дает.. Помудрил я немного с условной обработкой WINDOWPOS.flags на входе, да и озадачился..


Прочитали? Спасибо :)
А теперь скажите плиз, забить мне на эту дурацкую идею и делать как раньше?
Но думаю есть какое-то нормальное решение, которое все юзают, кроме меня, темного.
Чего-то я упустил в этом (некогда гениальном?) наследии Ксерокса.
А вот чего?


Дата: Мар 13, 2004 17:35:56

Если я правильно понял, тебе нужно это:
.elseif eax == WM_GETMINMAXINFO
    mov ecx, lParam
    assume ecx:ptr MINMAXINFO
    mov [ecx].ptMinTrackSize.x, VP_XMAX
    mov [ecx].ptMaxTrackSize.x, VP_XMAX

    mrm [ecx].ptMinTrackSize.y, VP_YMAX
    mrm [ecx].ptMaxTrackSize.y, VP_YMAX
    assume ecx:nothing


Дата: Мар 14, 2004 03:17:14

Four-F
Спасибо, что заинтересовались моим вопросом..

Но похоже я не умею их задавать.
При создании окна, мы передаем естественно его размеры CreateWindow(Ex)
При этом какой будет размер его клиентской области - дзен его знает.
Это зависит от темы XP, размера шрифта в заголовке.. Да мало ли еще от чего.
Все что мне требуется - получить окна у которых именно клиенская область определена мной, а сам их размер с каемочкой и заголовком мне не сильно важен. (ну и кнопку MAXIMIZE можно и не создавать)
Причем пользователь может и поменять тему во время работы..

В первом примере я вычисляю разницу между требуемым размером кл. области и текущим, и прибавляю ее к размеру всего окна. Это работает, хотя наверное с сообщениями я перебрал..

Все же меня интересует более красивое решение, поэтому я и пытаю WM_WINDOWPOSCHANGING, уже нарыл какой-то недокум. WINDOWPOS.flags #8000, но похоже чего-то я не туда полез..


Дата: Мар 14, 2004 07:26:25

Хех.. после некоторой медитации все же нашел приемлемый вариант.
примерно так:
;;  обработчик WM_WINDOWPOSCHANGING
	mov	edx, [lParam]		;;  Pointer to a WINDOWPOS structure
	test	[edx+WINDOWPOS.flags], SWP_SHOWWINDOW
	jz @f
	sub	esp, sizeof.RECT	;;  local var
	invoke	GetClientRect,[.handle], ESP

	mov	edx, [lParam]		;;  Pointer to a WINDOWPOS structure
	mov	eax, [.nWidth]	;;  здесь требуемый размер
	add	eax, eax
	sub	eax, [ESP+RECT.right]
	mov	[edx+WINDOWPOS.cx], eax
	
	mov	eax, [.nHeight]	;;  здесь требуемый размер
	add	eax, eax
	sub	eax, [ESP+RECT.bottom]
	mov	[edx+WINDOWPOS.cy], eax
	and	[edx+WINDOWPOS.flags],NOT SWP_NOSIZE
	sub	esp, sizeof.RECT	;;  release stack
@@:


Ограничение здесь - при вызове CreateWindow(Ex) нужно передавать [.nHeight] и [.nWidth] в качестве размера окна. (В первом случае можно вообще хоть что)

Код отрабатывает только при создании окна и при сворачивании/разворачивании, так что не сильно нагружает gui :)

Все же как с точки зрения микрософта такие вещи надо делать я так и не понял.
По тупому, как у меня в начале?


Дата: Мар 14, 2004 21:29:00

[ S_T_A_S_: В первом примере я вычисляю разницу между требуемым размером кл. области и текущим, и прибавляю ее к размеру всего окна. ]

Но ведь можно сделать то же самое при обработке WM_GETMINMAXINFO. И дальше пусть система сама следит за размером. IMHO, это правильнее.


Дата: Мар 14, 2004 21:35:02

S_T_A_S_

А зачем тебе CreateWindowEx, что мешает юзать диалоговые шаблоны?


Дата: Мар 15, 2004 00:37:41

Four-F
WM_GETMINMAXINFO задаёт ограничение на размер всего окна, а S_T_A_S_ хочет ограничить размер клиентской области.

S_T_A_S_
Хех.. после некоторой медитации все же нашел приемлемый вариант.
Поддерживаю этот вариант.


Дата: Мар 15, 2004 04:33:32

Four-F
Но ведь можно сделать то же самое при обработке WM_GETMINMAXINFO. И дальше пусть система сама следит за размером.

Да, но если изменится размер каемочки и/или заголовка то будет не то что надо.
Собственно, после безуспешных попыток с WM_GETMINMAXINFO, я и пришел к решению ^^, проще не могу.


Asterix
А зачем тебе CreateWindowEx, что мешает юзать диалоговые шаблоны?

Я в окошке потом рисую DirectX. Если в полном экране, то до окошек мне совсем по-барабану, а вот в windowed mode..
Пришлось думать, т.к. в MSDN чего-то не нашел про это.


Quantum
Поддерживаю этот вариант.

Он тоже оказался не совсем дзенный. Так будет лучше:
test BYTE [edx+WINDOWPOS.flags], SWP_SHOWWINDOW


Дата: Мар 15, 2004 07:26:22 · Поправил: q_q

S_T_A_S_
При создании окна, мы передаем естественно его размеры CreateWindow(Ex)
При этом какой будет размер его клиентской области - дзен его знает.

Для определения размеров окна на основе размеров клиентской области, до вызова CreateWindows[Ex], воспользуйся AdjustWindowRect[Ex], а потом WM_GETMINMAXINFO.


Дата: Мар 15, 2004 10:56:26 · Поправил: S_T_A_S_

q_q
Вот это меня смущает:
(Из MSDN)
AdjustWindowRect(Ex) Function
.....
dwStyle
[in] Specifies the window style of the window whose required size is to be calculated. Note that you cannot specify the WS_OVERLAPPED style.

У меня как раз WS_OVERLAPPED окошки.


Дата: Мар 15, 2004 11:30:05

S_T_A_S_
У меня как раз WS_OVERLAPPED окошки
Не WS_OVERLAPPEDWINDOW, а ноль?


Дата: Мар 15, 2004 13:43:00

В данном конкретном случае: WS_MINIMIZEBOX or WS_SYSMENU
Хотя в будующем надеюсь будет 0. Пока я еще не могу от тех флагов избавиться.


Дата: Мар 15, 2004 14:27:45

Кстати, если в WS_OVERLAPPEDWINDOW заюзать WM_GETMINMAXINFO как показал Four-F, то у меня получается весьма забавный эффект при нажатии на MAXIMIZE. Не очень нужный, кстати..


Powered by miniBB 1.6 © 2001-2002
Время загрузки страницы (сек.): 0.041