Текущий архив: 2004.03.28;
Скачать: CL | DM;
Вниз
Использование компонента TUpDown Найти похожие ветки
← →
YuRock © (2004-03-02 16:06) [0]Добрый день, уважаемые мастера! У меня, возможно, смешной вопрос, но это только с первого взгляда. Мне нужно связать TUpDown и TEdit.
На сколько я понял, это делается путем присвоения свойству Associate соответствующего Edit"а. Но не все так просто, как оказалось... Да, Edit начинает реагировать на изменения UpDown"а, но я хочу не только этого.
Итак, мне нужно, чтобы UpDown "лежал внутри Edit"а", как, например, в свойствах экрана (интервал заставки). Как этого добиться "стандартными дельфийскими" способами?
Пока что единственное, что помогло:
1. Создать Edit ч-з апи ч-з CreateWindow со стилями WS_CHILD, WS_VISIBLE, WS_BORDER, UDS_SETBUDDYINT, UDS_ALIGNRIGHT;
2. Создать UpDown ч-з CreateUpDownControl(WS_CHILD or WS_VISIBLE or WS_BORDER or UDS_SETBUDDYINT or UDS_ALIGNRIGHT), 0, 0, 0, 0, Handle, 0, 0, Edit.Handle, 30000, 1, 1);
3. Послать UpDown"у SendMessage(UpDown.Handle, UDM_SETBUDDY, Edit.Handle, 0);
Так работает. Но это же не "по Дельфински"! Что-то мне не верится, что этого нельзя сделать каким-нибудь одним присвоением.
Если кто знает, подскажите, как?
Спасибо всем!
P.S.1. Мне кажется, что проблема в Дельфевом TEdit - т.к. если сделать SendMessage(UpDown.Handle, UDM_SETBUDDY, Edit.Handle, 0); то это мало того, что не помогает, но и происходят всякие чудеса (размер уменьшается вдвое...);
P.S.2. TSpeenEdit из вкладки "Samples" не предлагать (это совсем другая история);
← →
Игорь Шевченко © (2004-03-02 16:29) [1]Метод, аналогичный созданию grid inplace-editor не сможет помочь ? В нем у edit меняется размер поля редактирования сообщением EM_SETRECTNP и встраиванием контрола в оставшееся место.
← →
YuRock © (2004-03-02 16:39) [2]Это имеется в виду что-то типа этого?:
SendMessage(Edit.Handle, EM_SETRECTNP, 0, Integer(@rc));
SetParent(UpDown.Handle, Edit.Handle);
UpDown.Top := 0;
UpDown.Left := rc.Right + 1;
Если да, то, по-моему, это еще хуже (менее красиво), чем ч-з апи Edit (а не TEdit!) создать, а потом спокойно, по научному, ч-з сообщение UDM_SETBUDDY встроить в него "стрелочки".
Я хотел узнать более легкий способ, ведь я уверен, что он есть.
← →
YuRock © (2004-03-02 16:39) [3]Это имеется в виду что-то типа этого?:
SendMessage(Edit.Handle, EM_SETRECTNP, 0, Integer(@rc));
SetParent(UpDown.Handle, Edit.Handle);
UpDown.Top := 0;
UpDown.Left := rc.Right + 1;
Если да, то, по-моему, это еще хуже (менее научно :)), чем ч-з апи Edit (а не TEdit!) создать, а потом спокойно, по научному, ч-з сообщение UDM_SETBUDDY встроить в него "стрелочки".
Я хотел узнать более легкий способ, ведь я уверен, что он есть.
← →
Игорь Шевченко © (2004-03-02 16:50) [4]
> по-моему, это еще хуже (менее научно :)),
Да вроде писать меньше :)
Другого способа я не знаю. Если есть, было бы интересно узнать
← →
YuRock © (2004-03-02 16:54) [5]Если узнаю - скажу
← →
Юрий Зотов © (2004-03-02 17:12) [6]Напишите потомок TEdit. Вот его примерный вариант.
type
TUpDownEdit = class(TEdit) // или TCustomEdit
private
FUpDown: TUpDown;
protected
procedure CreateParams(var Params: TCreateParams); override;
procedure CreateWnd; override;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
end;
constructor TUpDownEdit.Create(AOwner: TComponent);
begin
inherited;
FUpDown := TUpDown.Create(Self);
with FUpDown do
begin
Associate := Self;
Parent := Self;
Align := alRight
end
end;
destructor TUpDownEdit.Destroy;
begin
FUpDown.Free;
inherited
end;
procedure TUpDownEdit.CreateParams(var Params: TCreateParams);
begin
inherited;
Params.Style := Params.Style
or WS_CLIPCHILDREN or ES_MULTILINE
and not (ES_WANTRETURN or ES_AUTOVSCROL)
end;
procedure TUpDownEdit.CreateWnd;
var
R: TRect;
begin
inherited;
R := ClientRect;
Dec(R.Right, FUpDown.Width);
SendMessage(Handle, EM_SETRECT, 0, Integer(@R))
end;
← →
YuRock © (2004-03-04 10:52) [7]> Юрий Зотов
Спасибо за идею. Сделал примерно такой компонент, пользуюсь теперь...
Но только это не корректно. Для того, чтоб "засунуть" UpDown в Edit должно быть достаточно простого UDM_SETBUDDY, при этом UpDown не должен быть дочерним окном Edit"а (так в API задумано). Ну да ладно. Пользователь не отличит.
P.S. Кстати, не мог ответить в течении 2-х дней. Толи сервак этот висел, толи еще что...
← →
Юрий Зотов © (2004-03-04 12:46) [8]> YuRock © (04.03.04 10:52) [7]
> при этом UpDown не должен быть дочерним окном Edit"а (так в
> API задумано).
Загляните в VCL - все комбинированные компоненты так и строятся. IMHO, это потому, что и в API задумано именно так.
← →
YuRock © (2004-03-04 12:54) [9]> Загляните в VCL - все комбинированные компоненты так и строятся. IMHO, это потому, что и в API задумано именно так.
Да нет уж, извините... Советую запустить что-нибудь типа WinSighnt"a и посмотреть структуру виндовых диалогов, на к-рых есть UpDoun"ы...
Так что не надо вводить людей в заблуждение из-за того, что этот случай "не укладывается" в структуру VCL
← →
Юрий Зотов © (2004-03-04 14:46) [10]> YuRock
> Так что не надо вводить людей в заблуждение
Ах, извините великодушно. Только в чем же заблуждение-то? Приведите пример комбинированного компонента, построенного иначе. Не приведете.
И это именно потому что в API как раз такой ОБЩИЙ механизм и предусмотрен (что подтверждается хотя бы уже самим наличием таких стилей, как WS_CHILD и WS_CLIPCHILDREN).
> что этот случай "не укладывается" в структуру VCL
Как раз укладывается - в случае c UpDown VCL именно раз через UDM_SETBUDDY и работает (Associate). Оно и понятно, почему. Потому что MS задумала UpDown прирастающим к ЛЮБОМУ окну - и Borland сделала то же самое (иначе ей пришлось бы писать кучу отдельных компонентов).
=========================
Впрочем, если Вам не нравится - сделайте сами, как считаете правильным. Разве кто мешает?
← →
YuRock © (2004-03-04 15:13) [11]> Юрий Зотов © (04.03.04 14:46) [10]
> через UDM_SETBUDDY и работает (Associate)
Но не через Parent := !
> что подтверждается хотя бы уже самим наличием таких стилей, как WS_CHILD
Еще раз повторяю: UpDown не должен быть CHILD"ом Edit"a (в API)
> Приведите пример комбинированного компонента, построенного иначе. Не приведете.
И при чем здесь компоненты? Я же про апи говорю... На апи пожалуйста, вот пример:
program Test;
uses Windows, Messages, CommCtrl;
var
wc: TWndClassEx;
hMainWnd, hEditWnd, hUpDown: HWND;
Mes: TMSG;
function MainWndProc(Wnd: HWND; Msg: Cardinal; WP: WParam; LP: LParam): LResult; stdcall;
begin
case Msg of
WM_DESTROY: begin
PostQuitMessage(0);
Result:= 0; Exit;
end;
end;
Result := DefWindowProc(Wnd, Msg, WP, LP);
end;
begin // Тело программы
InitCommonControls;
wc.cbSize:= sizeof(wc);
wc.style:= CS_HREDRAW or CS_VREDRAW;
wc.lpfnWndProc:= @MainWndProc;
wc.cbClsExtra:= 0;
wc.cbWndExtra:= 0;
wc.hInstance:= HInstance;
wc.hIcon:= LoadIcon(0, IDI_APPLICATION);
wc.hCursor:= LoadCursor(0, IDC_ARROW);
wc.hbrBackground:= COLOR_BTNFACE+1;
wc.lpszMenuName:= nil;
wc.lpszClassName:= "TestClass";
RegisterClassEx(wc);
hMainWnd:= CreateWindow("TestClass", "Test", WS_OVERLAPPEDWINDOW or WS_VISIBLE,
100, 100, 200, 200, 0, 0, hInstance, nil);
hEditWnd := CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", nil, WS_CHILD or WS_VISIBLE,
10, 10, 100, 20, hMainWnd, 0, 0, nil);
hUpDown := CreateUpDownControl(WS_CHILD or WS_VISIBLE or WS_BORDER or UDS_SETBUDDYINT or UDS_ALIGNRIGHT,
0, 0, 0, 0, hMainWnd, 0, 0, 0, 100, 1, 1);
SendMessage(hUpDown, UDM_SETBUDDY, hEditWnd, 0);
while GetMessage(Mes, 0, 0, 0) do begin
TranslateMessage(Mes);
DispatchMessage(Mes);
end;
end.
И обратите внимание: UpDown не Child Edit"a, а Child главного окна!!!
← →
Юрий Зотов © (2004-03-04 15:29) [12]> YuRock © (04.03.04 15:13) [11]
Зачем повторять то, что известно еще со времен Win95?
И ПОЧЕМУ сделано именно так - тоже понятно.
Не нравится - делайте по-своему. Никто не мешает.
← →
TUser © (2004-03-04 16:18) [13]Надо поставить D7 - там уже есть такой компонент. Кажется, в D6 тоже есть, но точно не знаю.
← →
YuRock © (2004-03-04 16:30) [14]> Не нравится - делайте по-своему
Не по своему, а как придумали и делают программисты фирмы Microsoft. Вообще-то они определяют стандарты.
← →
YuRock © (2004-03-04 16:32) [15]> TUser © (04.03.04 16:18) [13]
см. вопрос темы (P.S.2.)
← →
Карл Маркс (2004-03-04 16:44) [16]> YuRock © (04.03.04 16:30) [14]
> Не по своему, а как придумали и делают программисты фирмы
> Microsoft. Вообще-то они определяют стандарты.
Именно так и сделан TUpDown в VCL. Почему же Вас это не устроило?
Странно как-то...
← →
YuRock © (2004-03-04 16:48) [17]> Карл Маркс (04.03.04 16:44) [16]
> Именно так и сделан TUpDown в VCL. Почему же Вас это не устроило?
Не устроило потому, что не работает как нужно (в Edit не "залазит"). Почему и вопрос в форуме задал.
← →
TUser © (2004-03-04 16:50) [18]
> см. вопрос темы (P.S.2.)
Не понял - в теме как раз речь идет о том, как сделать TSpinEdit.
← →
YuRock © (2004-03-04 16:56) [19]> TUser © (04.03.04 16:50) [18]
1. TSpinEdit выглядит совсем не так, как привычные пользователю UpDown в Edit"е;
2. У TSpinEdit возможностей намного больше, чем у UpDown + Edit;
3. Мне непонятно, как динамически ассоцировать UpDown из TSpinEdit другому эдиту;
...
← →
Юрий Зотов © (2004-03-04 17:02) [20]> YuRock © (04.03.04 16:48) [17]
А может, все-таки, залазит?
← →
YuRock © (2004-03-04 17:15) [21]> Юрий Зотов © (04.03.04 17:02) [20]
У меня не вышло сделать так, чтоб "залез". По-этому и вопрос задал (см. [0]).
← →
Юрий Зотов © (2004-03-04 17:41) [22]Бросьте на форму Edit и UpDown и сделайте вот такую программку.
procedure ShowBounds(Control: TWinControl);
begin
with Control.BoundsRect do
ShowMessage(Format("Left = %d"#13#10"Top = %d"#13#10"Right = %d"#13#10"Bottom = %d", [Left, Top, Right, Bottom]))
end;
procedure TForm1.FormClick(Sender: TObject); // OnClick
begin
ShowBounds(Edit1);
SendMessage(UpDown1.Handle, UDM_SETBUDDY, Edit1.Handle, 0);
ShowBounds(UpDown1)
end;
Теперь возвращаемся к исходному вопросу.
> если сделать
> SendMessage(UpDown.Handle, UDM_SETBUDDY, Edit.Handle, 0);
> то это мало того, что не помогает, но и происходят всякие
> чудеса (размер уменьшается вдвое...);
Запустите программу и кликните по форме. Как видите, влезает. То есть, именно SendMessage и помогает. И никаких чудес не происходит, и никакой размер вдвое не уменьшается.
> Как этого добиться "стандартными дельфийскими" способами?
Вот как раз так, как и было написано в самом начале - встроить окно в окно. Это и есть стандартный дельфийский способ. Именно дельфийский. И именно стандартный. То есть, точно соответствующий Вашему вопросу.
Что же еще-то нужно?
← →
YuRock © (2004-03-04 17:51) [23]> Запустите программу и кликните по форме. Как видите, влезает. То есть, именно SendMessage и помогает. И никаких чудес не происходит, и никакой размер вдвое не уменьшается.
Хоть убейте - у меня не залазит!!!! Только влево немного смещается.
Я не хочу спорить, ссориться с кем-то. За "дельфийский" способ я Вас еще в [7] поблагодарил. И ничего не имею против.
Вы просто говорили, что эта же концепция используется и в API, а так как это не так, я не мог не возразить. Ладно, не будем терять время на беспредметные споры.
Всего всем хорошего и всем спасибо.
Страницы: 1 вся ветка
Текущий архив: 2004.03.28;
Скачать: CL | DM;
Память: 0.52 MB
Время: 0.028 c