Версия для печати темы

Нажмите сюда для просмотра этой темы в обычном формате

Форум «Всё о Паскале» _ Делфи _ Изменение координат элементов (winapi)

Автор: Lio 8.01.2007 3:03

Здравствуйте,
Вообщем, пробую писать на чистом АПИ в Делфи. (Предупреждая вопрос "Зачем?" - "Надо, хочу научиться"=) )
Создаю окно, добавляю на него несколько различных элементов 'listbox', 'edit' и пр.
Как сделать так, чтобы расположение этих элементов зависело от размеров окна, которое изменяется в процессе работы. Т.е. увеличил я окно направо и кнопки сдвинулись туда же, вместе с размерами 'listbox'a и т.п.
Уверен, что это все связано со структурой TRect и функцией GetClientRect. Но вот как их для этого использовать я понять не могу =(? Перепробовал различные варианты. Need help.

Автор: volvo 8.01.2007 3:46

Создаешь контрол вот так:

  GetClientRect(hWindow, Rect);
hEditWnd := CreateWindow('Edit', nil,
ws_child or ws_visible or es_multiline or
ws_vscroll or ws_hscroll or es_autohscroll or es_autovscroll,
0, 0,
(rect.right - rect.left) - 50, { Чтобы не на все окно, а на 50 пикс. меньше по ширине }
(rect.bottom - rect.top),
hWindow,
0,
system.MainInstance, nil);


и обрабатываешь WM_SIZE (при изменении размеров родительского окна что еще можно обрабатывать? smile.gif ) в оконной функции:
    WM_SIZE:
Begin
MoveWindow(hEditWnd, 0, 0, loword(lparam) - 50, hiword(lparam), true);
// Второй и третий параметры - смещение по ширине/высоте относительно
// родительского окна, четвертый и пятый - новая ширина/высота контрола
Exit;
End;



(я сразу говорю, лень было запускать Дельфи, набросал на FPC, поэтому с синтаксисом могут быть накладки, но это работает)

Автор: Bokul 8.01.2007 7:20

А если контролов много EnumChildWindows?

Автор: Lio 8.01.2007 15:59

Не получается =(
Я попробовал, как во втором посте, только контрол был не 'Edit' а 'Listbox'
И другой вариант:


var
ListText:THandle;
Rect:TRECT;
...
WM_CREATE:
begin
ListText:=CreateWindow('LISTBOX',
nil,
WS_CHILD or WS_VISIBLE or LBS_STANDARD,
Rect.Left,
Rect.Bottom div 2,
Rect.Right,
Rect.Bottom,
hWnd, 0, hInstance, nil);

...
end;
WM_SIZE:
begin
GetClientRect(hWnd,Rect);
MoveWindow(ListText, Rect.Left,
Rect.Bottom div 2,
Rect.Right,
Rect.Bottom, true);
end;

Где я неправ?

Автор: volvo 8.01.2007 16:00

Полностью файл прикрепи...

Автор: Lio 8.01.2007 16:18

*.dpr файлик не дал прикрепить - сменил расширение на *.pas
Заранее спасибо за то, что помогаете разобраться smile.gif


Прикрепленные файлы
Прикрепленный файл  arch.pas ( 6.06 килобайт ) Кол-во скачиваний: 289

Автор: volvo 8.01.2007 16:42

var
ListFrom,ListTo,ListSubj,ListText:THandle;

Должны быть описаны глобально, а не локально в WinProc... Вынеси описание выше по тексту, и ListText начнет изменять размер...

Автор: Lio 8.01.2007 16:50

Сработало!!! smile.gif
Огромное спасибо smile.gif
Немного непонятно, почему глобальные переменные (все пишут, что это плохой стиль программирования. Что так нельзя и я даже не думал об их использовании...). Контрол вроде создается и изменяется в одной функции ... вообщем пока для меня мистика smile.gif. Буду разбираться ... еще раз спасибо.

Автор: volvo 8.01.2007 16:57

Цитата
Контрол вроде создается и изменяется в одной функции ...
Создается - да, а вот изменяется он - каждый раз, когда функции окна приходит сообщение WM_SIZE, так? А что будет с локальной переменной, когда WinProc неактивна, ты знаешь? Она прекратит существование, потому, как располагается в стеке. При следующей активизации WinProc переменная ListText (ну, и все остальные тоже) создастся заново, а вот что она будет содержать - это мусор, ничего общего с тем хендлом, что ты создавал...

Поэтому надо хранить хендлы глобально, чтобы они не менялись...

Автор: Lio 8.01.2007 17:09

Я понял. Спасибо. Буду осторожнее с переменными впредь ...