Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 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.54 MB
Время: 0.021 c
11-1057509228
=Sniper=
2003-07-06 20:33
2004.03.28
Поскажите замену для KOLследующим выражениям!!!!


4-1074492106
DeScriptor
2004-01-19 09:01
2004.03.28
Как добыть текст из окна типа MessageBox?


14-1077780780
d10
2004-02-26 10:33
2004.03.28
Математика v0.5, полезная прога для студентов


6-1073645802
vivk
2004-01-09 13:56
2004.03.28
Узнать IP клиента


1-1078393979
Builder
2004-03-04 12:52
2004.03.28
Печать Excel