Помогите защитить честь Delphi. Нужен компонент класса BitBtn с двумя Caption и чтобы у каждого был свой Font. Располагаться Caption-сы должны так: если разделить кнопку пополам по горизонтали то каждый Caption должен находится в средине своей половины, как по горизонтали, так и вертикали (тоже расположение, что и у Caption стандартного компонента). При длине текста, в Caption, больше чем ширина кнопки, текст должен переносится на вторую строку этого Caption, при этом весь текст должен центрироваться как и прежде. Нужна возможность программно, в динамике, влиять на размер, цвет, стиль Caption-ов. Необходима возможность выбора цвета кнопки, необходимо чтобы это был параметр, ну что-то типа ColorBut, в Инспекторе объектов на закладке Properties, который можно изменять как на этапе проектирования, так и во время работы программы, динамически то есть. Еще нужно свойство, в Инспекторе объектов, при установке которого при одном щелчке кнопка бы включала (нажималась), а при повторном нажатии бы возвращалась в исходное состояние, имелась бы возможность отследить текущее состояние кнопки. Данная кнопка должна поддерживать режим множественно выбора, когда помимо ее нажато еще несколько таких кнопок, при этом необходима возможность считывания состояния этих кнопок, было бы здорово считывать, в какой очередности они нажаты.
Также, необходима возможность динамически, во время выполнения программы, менять картинку кнопки.
Было бы совсем здорово, но я на это уж рассчитывать не буду и так много прошу, возможность располагать не только одну картинку, а четыре сразу. Пусть они все располагаются в левой части кнопки, как у стандартного компонента, в два ряда по две картинки, необходима возможность динамической замены каждой отдельной картинки во время выполнения программы. Но при этом оставалась бы возможность использования одной картинки вместо этих четырех, как у стандартного компонента.
Будет здорово если Вы подробно опишите процедуры и функции данного компонента, я никогда ранее не занимался созданием своих компонентов, как-то все стандартными обходился, а туту такое дело.
А дело заключается в следующем: встретил я тут одного прогера пишущего на ХХХХ (имя языка не указываю, дабы не дискредитировать нормальных прогеров пишущих на этом языке). Мы с ним разговорились о своем, о прогерском. Чувак оказался каким-то неправильным прогером, давай мне доказывать, что, мол, Delphi - это вчерашний день, что, мол, генерит он слишком тяжелый код, будущее, мол, за Веб технологиями, а Delphi вообще не актуальна. Я ему типа говорю, что, мол, каждый прогер выбирает себе язык программирования по себе, по стоящим перед ним задачам, каждый язык имеет свою спецификацию, по этому говорить, что один язык лучшее другого очень сложно и неправильно. А он заладил свое зараза, Delphi маздай мол и все тут. Ну, в общем, занозились мы неслабо на эту тему. И ладно бы просто занозились, но весь этот спор происходил на глазах третьей стороны, людей уважаемых, очень уважаемых, людей старшего возраста. Они нас слушали, слушали, а потом взяли да предложили, для того чтобы выяснить, чей язык программирования лучше, а кто из нас двоих трепло, написать программку на указанную ими тему.
Я прошу помочь мне, у меня осталось мало времени, я ранее никогда не писал компоненты и если я сейчас начну изучать эту тему, я все отведенное время потрачу только на создание вышеописанного компонента. Мне этот компонент нужен для того, чтобы все было в моей программе красиво, можно конечно что-то из стандартных компонентов наляпать, но получится не очень, а мне «не очень» нельзя.
Прошу, помогите защитить честь программиста, и честь, прекрасного языка программирования, Delphi.
Уважаемые авторы вопросов! Большая просьба сообщить о результатах решения проблемы на этой странице. Иначе, следящие за обсуждением, возможно имеющие аналогичные проблемы, не получают ясного представления об их решении. А авторы ответов не получают обратной связи. Что можно расценивать, как проявление неуважения к отвечающим от автора вопроса.
01-11-2008 06:32
Не знаю, в каком направлении вы двинулись и как обстоят дела на данном этапе, но всё-таки решил продемонстрировать своё предложение работающим кодом.
Итак, делаем фрейм, на него помещаем панель. Внизу оставляем место, чтобы было за что хвататься мышкой при перетаскивании. Anchors панели делаем по всем сторонам, чтобы при растягивании фрейма панель тоже растягивалась, сохраняя зазор. Фрейм можно помещать на форму как в дизайнтайм, так и в рантайм. 5 TImage в зависимости от ваших потребностей можно заполнять в любом удобном месте. Для тестов я загонял в них картинки из каталога Windows прямо во фрейм в дизайнтайм. Перед выкладыванием dfm сюда, я их, естественно, удалил. Код не везде оптимален, но демонстрирует некоторые подходы. При желании можете довести до нужной кондиции. Писалось всё это на скорую руку, поэтому, в частности, настройка фиксируемости кнопок и их группировка несколько тличается от TSpeedButton. Просто немного подзабыл, а в справку по TSpeedButton заглянул уже когда сделал. Скопируйте код в соответствующие файлы.
procedure TInfoButtonFrame.PanelResize(Sender: TObject); // Срабатывает по размерам в форме
begin
PrepareLabels;
Arrange;
end;
procedure TInfoButtonFrame.Arrange;
begin
pnlDivider.Top := (Panel.Height - pnlDivider.Height) div 2;
Label1.Top := ((Panel.Height - Panel.BorderWidth*2 - pnlDivider.Height)
div 2 - Label1.Height) div 2;
Label2.Top := ((Panel.Height - Panel.BorderWidth*2 - pnlDivider.Height)
div 2 - Label2.Height) div 2 +
(pnlDivider.Top + pnlDivider.Height div 2);
end;
function TInfoButtonFrame.GetCaption1: String;
begin
Result := Label1.Caption;
end;
function TInfoButtonFrame.GetCaption2: String;
begin
Result := Label2.Caption;
end;
function TInfoButtonFrame.GetChecked: Boolean;
begin
Result := (Panel.BevelOuter = bvLowered);
end;
function TInfoButtonFrame.GetSingleImage: Boolean;
begin
Result := Image0.Visible;
end;
procedure TInfoButtonFrame.SetCaption1(const Value: String);
begin
Label1.Caption := Value;
Arrange;
end;
procedure TInfoButtonFrame.SetCaption2(const Value: String);
begin
Label2.Caption := Value;
Arrange;
end;
procedure TInfoButtonFrame.SetChecked(const Value: Boolean);
var
OldVal: Boolean;
begin
OldVal := Checked;
if Value then
Panel.BevelOuter := bvLowered
else
Panel.BevelOuter := bvRaised;
if Value <> OldVal then
if Value then
begin
if Assigned(FOnCheck) then
FOnCheck(Self);
end
else
if Assigned(FOnUnCheck) then
FOnUnCheck(Self);
end;
procedure TInfoButtonFrame.SetFixed(const Value: Boolean);
begin
FFixed := Value;
if not FFixed then
Checked := False;
end;
procedure TInfoButtonFrame.SetSingleImage(const Value: Boolean);
begin
Image0.Visible := Value;
Image1.Visible := not Value;
Image2.Visible := not Value;
Image3.Visible := not Value;
Image4.Visible := not Value;
end;
procedure TInfoButtonFrame.AnyMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
var
i: Integer;
begin
Checked := not Checked;
if Group <> 0 then
for i:=0 to Owner.ComponentCount-1 do
if Owner.Components[i] is TInfoButtonFrame then
if TInfoButtonFrame(Owner.Components[i]).Group = FGroup then
if TInfoButtonFrame(Owner.Components[i]) <> Self then
TInfoButtonFrame(Owner.Components[i]).Checked := False;
end;
procedure TInfoButtonFrame.AnyMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if not FFixed then
Checked := False;
end;
end.
InfoButtonFrm.dfm
object InfoButtonFrame: TInfoButtonFrame
Left = 0
Top = 0
Width = 431
Height = 114
TabOrder = 0
TabStop = True
DesignSize = (
431
114)
object Panel: TPanel
Left = 0
Top = 0
Width = 431
Height = 105
Anchors = [akLeft, akTop, akRight, akBottom]
BevelWidth = 2
TabOrder = 0
OnMouseDown = AnyMouseDown
OnMouseUp = AnyMouseUp
OnResize = PanelResize
DesignSize = (
431
105)
object Image1: TImage
Left = 0
Top = 1
Width = 48
Height = 48
OnMouseDown = AnyMouseDown
OnMouseUp = AnyMouseUp
end
object Image2: TImage
Left = 54
Top = 0
Width = 48
Height = 48
OnMouseDown = AnyMouseDown
OnMouseUp = AnyMouseUp
end
object Image3: TImage
Left = 0
Top = 55
Width = 48
Height = 48
OnMouseDown = AnyMouseDown
OnMouseUp = AnyMouseUp
end
object Image4: TImage
Left = 54
Top = 54
Width = 48
Height = 48
OnMouseDown = AnyMouseDown
OnMouseUp = AnyMouseUp
end
object Image0: TImage
Left = 12
Top = 11
Width = 75
Height = 75
OnMouseDown = AnyMouseDown
OnMouseUp = AnyMouseUp
end
object Label1: TLabel
Left = 108
Top = 11
Width = 303
Height = 13
Alignment = taCenter
Anchors = [akLeft, akRight]
AutoSize = False
Caption = 'Label1'
OnMouseDown = AnyMouseDown
OnMouseUp = AnyMouseUp
ExplicitWidth = 250
end
object Label2: TLabel
Left = 108
Top = 57
Width = 303
Height = 13
Alignment = taCenter
Anchors = [akLeft, akRight]
AutoSize = False
Caption = 'Label2'
OnMouseDown = AnyMouseDown
OnMouseUp = AnyMouseUp
ExplicitTop = 59
ExplicitWidth = 250
end
object pnlDivider: TPanel
Left = 108
Top = 51
Width = 316
Height = 2
Anchors = [akLeft, akRight]
BevelOuter = bvLowered
Caption = 'pnlDivider'
TabOrder = 0
OnMouseDown = AnyMouseDown
OnMouseUp = AnyMouseUp
end
end
end
constructor TTestForm.Create(AOwner: TComponent);
procedure Prepare_4_5_6(Btn: TInfoButtonFrame); // Вложенная процедура
begin
with Btn do
begin
Fixed := True;
Group := 1;
SingleImage := True;
Caption1 := 'Зависимые фиксируемые';
OnCheck := Check_4_5_6;
OnUnCheck := UnCheck_4_5_6;
OnUnCheck(Btn);
end;
end;
begin
inherited;
{1}
InfoButtonFrame1.SingleImage := True;
InfoButtonFrame1.OnCheck := Check_1_2;
InfoButtonFrame1.OnUnCheck := UnCheck_1_2;
{2}
InfoButtonFrame2.SingleImage := True;
InfoButtonFrame2.OnCheck := Check_1_2;
InfoButtonFrame2.OnUnCheck := UnCheck_1_2;
InfoButtonFrame2.Fixed := True;
{3}
InfoButtonFrame3.SingleImage := False;
InfoButtonFrame3.OnCheck := Check_3;
InfoButtonFrame3.OnUnCheck := UnCheck_3;
InfoButtonFrame3.Fixed := True;
UnCheck_3(InfoButtonFrame3);
{4,5,6}
Prepare_4_5_6(InfoButtonFrame4);
Prepare_4_5_6(InfoButtonFrame5);
Prepare_4_5_6(InfoButtonFrame6);
{7}
with TInfoButtonFrame.Create(Self) do
begin
Parent := Self;
Label1.Font.Size := 12;
Label1.Font.Style := [fsBold];
Caption1 := 'Динамически созданная кнопка';
Caption2 := 'Обработчик не назначен';
SetBounds(10, 370, 500, 100);
end;
end;
procedure TTestForm.Check_1_2(Sender: TObject);
begin
with Sender as TInfoButtonFrame do
begin
Label2.Font.Color := clRed;
Caption2 := 'Нажата';
SingleImage := False;
end;
end;
procedure TTestForm.UnCheck_1_2(Sender: TObject);
begin
with Sender as TInfoButtonFrame do
begin
Label2.Font.Color := clGreen;
Caption2 := 'Отажата';
SingleImage := True;
end;
end;
procedure TTestForm.Check_3(Sender: TObject);
begin
with Sender as TInfoButtonFrame do
begin
Image1.Visible := False;
Image2.Visible := False;
Image3.Visible := True;
Image4.Visible := True;
Caption1 := 'Нажата';
Caption2 := 'Нижние картинки';
end;
end;
procedure TTestForm.UnCheck_3(Sender: TObject);
begin
with Sender as TInfoButtonFrame do
begin
Image1.Visible := True;
Image2.Visible := True;
Image3.Visible := False;
Image4.Visible := False;
Caption1 := 'Отжата';
Caption2 := 'Верхние картинки';
end;
end;
procedure TTestForm.Check_4_5_6(Sender: TObject);
begin
with Sender as TInfoButtonFrame do
begin
Image0.Visible := True;
Label2.Font.Color := clRed;
Label2.Font.Style := Label2.Font.Style + [fsBold, fsItalic, fsUnderline];
Caption2 := 'Нажата';
end;
end;
procedure TTestForm.UnCheck_4_5_6(Sender: TObject);
begin
with Sender as TInfoButtonFrame do
begin
Image0.Visible := False;
Label2.Font.Color := clGreen;
Label2.Font.Style := Label2.Font.Style - [fsBold, fsItalic, fsUnderline];
Caption2 := 'Отажата';
end;
end;
NavigatorNeba, вы, наверное, опять обидитесь, но ваше "точное" описание мне лично больше напоминает "как изменить цвет и фонт у кнопки". Вариантов много, но это так неинтересно.
Но чтобы не писать впустую, предложу такой самый простой начальный вариант: использовать в качестве основы нового компонента TPanel. У панели есть BevelOuter, меняя который можно визуализовать нажатие и отпускание кнопки. Надписи, вообще TLabel'ами реализовать. Лично я писал бы такой компонент не на основе TPanel, а как обертку над панелью и другими элементами с выводом в интерфейс только нужных полей.
ЗЫ. Нет смысла делать компонент для разового использования, да еще с чисто визуальными эффектами.
А, теперь понятно, Вас смутило четкое описание проблемы. Ну, наверное, есть что-то такое. Занимаясь электроникой, мне постоянно приходится делать описания чего-либо, а, чем точнее описание, тем понятней задача и проще в будущем. Кроме того, на вашем же сайте в правилах написания вопросов сказано:
Старайтесь последовательно изложить суть вопроса:
* опишите условия задачи; Что именно Вы хотите сделать? В чем конкретно заключается проблема?
Вот я и описал.
Я не рассчитывал на то, что кто-то за меня будет что-то писать, скажу честно, я рассчитывал на две вещи: во-первых я подумал, что вдруг у кого-то есть такой компонент просто он в Internet-е не выложен, меня просто время поджимает, поэтому, прочитав сообщение Антона Григорьева, я сразу же согласился, решив, что мне предлагают услуги по написанию компонента; и второе – я подумал, что, наверняка, у кого-нибудь за все время существования Delphi возникала подобная проблема, и я надеялся, что мне подскажут в каком направлении двигаться, может, опишут подводные камни, возникающие при написании компонентов.
Насчет Фленова: сколько людей столько и мнений, и в этом вся прелесть, в спорах рождается истина, если, конечно, Вы лично против него ничего не имеете. А то, что в его книгах много ошибок, то по моему опыту скажу, что примерно 85% технической литературы содержат ошибки, недочеты, неверные ссылки, опечатки, я в этом плане уже заколебался, что не книга, сидишь, блин, и как главный редактор все проверяешь, не знаю, вина ли это писателя, издателя или и тех, и других, но на это отвлекается столько сил и времени!
Рассказать более подробно о своей программе я не могу. Так как, если эти статьи увидит мой оппонент по спору, он сможет все представить так, будто программа полностью написана кем-то другим, а не мной, а программу я почти доделал, все упирается в этот компонент. Этот компонент идеально подходит для решения моей задачи. Пока в статьях отсутствуют ключевые моменты моей истории ее можно примерить на любого человека.
Надеюсь, что мы друг друга поняли, рассчитываю на вашу поддержку, начинаю изучать написание компонентов, эх, блин, по времени бы только уложиться!
Теперь насчет достоверности рассказа, я не малолетка, а вполне взрослый дядя, да будет Вам так угодно, и придумывать всякую БАЙДУ, для того чтобы что-то у кого-то попросить, не стану.
Просто вы "не знаете предысторию"...
Вообще-то, здесь присутствуют достаточно разные люди, от школьников до докторов наук... И не всегда одних можно сразу отличить от других...
>>> Да, опечален Я, недружественной реакцией моих «товарищей»
Я неоднократно наблюдал, как человек, пришедший в новый для него форум, сначала не находил общего языка и высказывал разнообразное недовольство, начиналось ломание копий, штакетника и проч. Через некоторое время всё устаканивалось...
>>> к сожалению, не знаю возраста своих оппонентов, это бы многое объяснило
У двух из четырёх ответивших вам людей год рождения указан в профиле. Ваш покорный слуга где-то рядом...
Мне все-таки хочется верить, что старшая часть программистов нашего прекрасного Виртуального мира все-таки обладает программерской Культурой.
И не только программерской... И не только старшая часть...
>>> Обратился я за помощью к сообществу программистов в первый раз, думал, сильна здесь взаимовыручка.
Вообще, вам ответили вполне корректно. Просто возникло некоторое недопонимание. Думаю, как раз из-за того, что это "в первый раз". Если вы здесь останетесь, вы это поймёте...
Уважаемый Антон Григорьев, я готов рассмотреть вариант покупки компонента, но честно, не знаю, как и в какой последовательности будет происходить оплата, напишите мне на электронку более подробно, метод оплаты и стоимость Ваших работ.
Не буду говорить за Антона, но думаю, что вы поняли его чересчур прямолинейно (пока писал, он уже ответил). Просто ваше сообщение очень похоже на техзадание. А написание программ на заказ выходит за пределы тематики данного форума. Если бы вы после "мне надо написать вот такое" далее вместо "расскажите мне всё от начала до конца", сказали "подкиньте идей как это лучше сделать", а потом - уточнения по конкретным местам, то реакция была бы другой.
И напоследок, давайте будем делать все для поднятия культурного уровня нашего брата- программиста, например, писать по существу, не можете помочь, так и напишите, без язв, а то получается, что Вы одни люди, а ВСЕ остальные маздаи.
Я пытался вам помочь, но вы обратили внимание только на первую часть моего сообщения. Обратите внимание на вторую. Расскажите более подробно назначение сей конструкции (если к этому нет противопоказаний). Возможно, вам подскажут более простой, но удовлетворяющий по функционалу вариант. Возможно, подскажут, как можно реализовать и в том виде, как вы описали.
Вариант 1:
Фрейм, на нём панель, на панели TImage, посередине панели - линия (TBevel), по бокам - два TStaticText с соответствующим выравниванием. Дальше возможны варианты. Пусть это будет отправной точкой.
Уважаемый Антон Григорьев, я готов рассмотреть вариант покупки компонента, но честно, не знаю, как и в какой последовательности будет происходить оплата, напишите мне на электронку более подробно, метод оплаты и стоимость Ваших работ.
Лично я не собираюсь брать заказы. Потому что свободного времени на вольное программирование у меня не так много, и я предпочитаю его тратить на то, что мне интересно, а ваш компонент меня не заинтересовал. Про деньги я писал потому, что знаю по опыту: вы не найдёте никого, кто согласился бы сделать вам такой компонент бесплатно. А вот за деньги шанс небольшой, но есть. Правда, это лучше искать на других сайтах, предназначенных именно для предложения частных заказов.
И ещё небольшой совет - лучше не упоминайте здесь Фленова. Потому что в книгах этого автора много ошибок, а там, где нет ошибок, преобладает очень поверхностный подход, который только уводит в сторону от основных проблем. На всех приличных форумах слово "Фленов" давно стало ругательным :)
Ну, во-первых, мне такая кнопка нужна не для красоты, она будет нести конкретную информационную и функциональную нагрузку, цвет кнопки, например, будет отражать состояние, в котором находится контролируемый объект, я написал, что нам предложили написать программу, но я ведь не писал, что эта программка уровня «Hello World», программа достаточно серьезная, и она у меня почти готова. Во-вторых, Delphi, очень мощный язык программирования, я не буду разводить здесь демагогию по этому поводу, просто, если Вам интересно, обратитесь к изданиям, например, Фленова М.Е.
Как Delphi конкурирует с Веб – технологиями: что имелось в виду, я и сам не знаю, я же написал, что программист, с которым я спорил, неправильный программист.
Теперь насчет «туту»: это называется ОПЕЧАТКА, я человек работающий, свободного времени мало, большая часть свободного времени - это кусок ночи, а ночью после 12-тичасового рабочего дня хочется спать, поэтому и ошибки бывают, так что ваши колкости здесь не уместны.
Теперь насчет достоверности рассказа, я не малолетка, а вполне взрослый дядя, да будет Вам так угодно, и придумывать всякую БАЙДУ, для того чтобы что-то у кого-то попросить, не стану.
Да, опечален Я, недружественной реакцией моих «товарищей», к сожалению, не знаю возраста своих оппонентов, это бы многое объяснило. Мне все-таки хочется верить, что старшая часть программистов нашего прекрасного Виртуального мира все-таки обладает программерской Культурой.
Обратился я за помощью к сообществу программистов в первый раз, думал, сильна здесь взаимовыручка. Лично Я на сайтах посвященных радио- и микро-электронике, делюсь своими разработками, ибо стараюсь сделать все, для того чтобы как можно больше людей занималось электроникой, в особенности, что касается подростков.
Уважаемый Антон Григорьев, я готов рассмотреть вариант покупки компонента, но честно, не знаю, как и в какой последовательности будет происходить оплата, напишите мне на электронку более подробно, метод оплаты и стоимость Ваших работ.
И напоследок, давайте будем делать все для поднятия культурного уровня нашего брата- программиста, например, писать по существу, не можете помочь, так и напишите, без язв, а то получается, что Вы одни люди, а ВСЕ остальные маздаи.
Я бы сказал, что прелесть Delphi это быстрая реализация алгоритмов для стандартного вида программы (интерфейс "Человек-машина") в Windows. Из условия видно, что Delphi способна отследить моменты нажатия кнопок, а вот дальше - расчёты, графика - этого нет. Для меня лично неожиданный вид кнопок - это не интересно (были, правда, небольшие исключения: использование иероглифов вместо текста и пиктограмм; отображение нажатия кнопки в виде лампочки).
>>> как-то все стандартными обходился, а туту такое дело.
Ой какая прелесть! Сразу вспомнил бесподобную фразу "туту бабам", встреченную в »вопрос КС №48697« , которая (наряду со всем остальным в этом вопросе) привела меня в неописуемый восторг...
Они нас слушали, слушали, а потом взяли да предложили, для того чтобы выяснить, чей язык программирования лучше, а кто из нас двоих трепло, написать программку на указанную ими тему.
Не касаясь достоверности рассказанной истории...
Вам предложили написать программу, а не компонент. Один и тот-же результат (в функциональном плане) можно достичь разными путями. Чёткое лаконичное решение обычно лучше разукрашенной "новогодней ёлки". Вот на это и направьте свои усилия. Если хотите, чтобы вам подсказали идею, подробнее опишите то, для чего вам это требуется. Возможно, простое и красивое решение "где-то рядом"...
Вряд ли вы найдёте здесь человека, который напишет вам готовый код. Начните, придите сюда с конкретными проблемами, и тогда есть шанс получить помощь. Или, если хотите всё-таки в готовом виде, называйте сумму.
Если вы заметили орфографическую ошибку на этой странице, просто выделите ошибку мышью и нажмите Ctrl+Enter. Функция может не работать в некоторых версиях броузеров.