Текущий архив: 2016.02.28;
Скачать: CL | DM;
Вниз
Вывести пустой TDateTimePicker Найти похожие ветки
← →
Rouse_ © (2014-08-12 10:24) [40]
> С-К (12.08.14 09:08) [38]
> как реализовать выпадающий календарик?
Ну я ж тебе даже ссылку на пример дал :)
Ладно, пойдем более простым путем, на форму кидай кнопку и календарь, у календаря свойство Visible ставь в False, потом в обработчике кнопки пиши следующий код:procedure TForm1.Button1Click(Sender: TObject);
begin
MonthCalendar1.Left := Button1.Left;
MonthCalendar1.Top := Button1.Top + Button1.Height;
AnimateWindow(MonthCalendar1.Handle, 200, AW_SLIDE or AW_VER_POSITIVE);
MonthCalendar1.Visible := True;
end;
← →
С-К (2014-08-12 11:02) [41]Rouse_, крутяк вообще получилось все :) Спасибо!
← →
С-К (2014-08-12 11:41) [42]Не все крутяк.. (
Почему то по бокам у TMonthCalendar возникает серая полоска.
Картинка: http://bit.ly/1q66LKC
← →
С-К (2014-08-12 11:43) [43]Хм... Потому что когда создается TMonthCalendar - он почему то шире, чем нужно для отображения.
Его ширина: 191
Ширина, когда он "нормально" выглядит без серых полосок: 155
Могу ли я ему присвоить ширину 155 (допустим, при динамическом создании) - валидно ли это будет? Он всегда попиксельно одинаковый?
← →
С-К (2014-08-12 11:50) [44]И еще один баг...
Когда скрывать календарь, как определить момент выбора? Я сделал событие на OnClick, но бяда в том, что OnClick возникает и тогда, когда пользователь нажимает стрелочки влево, вправо для смены месяца. Происходит OnClick и мой календарь неожиданно исчезает ((
Я ж говорю - не все так просто - написать свой компонент.
← →
Rouse_ © (2014-08-12 12:05) [45]
> Я ж говорю - не все так просто - написать свой компонент.
Все там просто, если немножко подумать.TForm1 = class(TForm)
Button1: TButton;
MonthCalendar1: TMonthCalendar;
procedure Button1Click(Sender: TObject);
private
FOldCalendarWndProc: TWndMethod;
procedure CalendarWndProc(var Message: TMessage);
end;
..
uses
CommCtrl;
procedure TForm1.Button1Click(Sender: TObject);
var
R: TRect;
begin
// получаем минимальные размеры календаря
MonthCalendar1.Left := -1000;
MonthCalendar1.Top := -1000;
MonthCalendar1.Visible := True;
MonthCalendar1.Perform(MCM_GETMINREQRECT, 0, R);
with R do
begin
MonthCalendar1.Width := Right - Left;
MonthCalendar1.Height := Bottom - Top;
end;
MonthCalendar1.Visible := False;
// указываем еу позицию
MonthCalendar1.Left := Button1.Left;
MonthCalendar1.Top := Button1.Top + Button1.Height;
// делаем анимацию
AnimateWindow(MonthCalendar1.Handle, 200, AW_SLIDE or AW_VER_POSITIVE);
MonthCalendar1.Visible := True;
// ставим фокус и перекрываем оконную процедуру
MonthCalendar1.SetFocus;
FOldCalendarWndProc := MonthCalendar1.WindowProc;
MonthCalendar1.WindowProc := CalendarWndProc;
end;
procedure TForm1.CalendarWndProc(var Message: TMessage);
begin
// а в оконной процедуре реагируем на потерю фокуса
if Message.Msg = WM_KILLFOCUS then
begin
// где скрываем календарь
MonthCalendar1.Visible := False;
// и снимаем перехват
MonthCalendar1.WindowProc := FOldCalendarWndProc;
end;
// не забываем все сообщения передать старой оконной процедуре
FOldCalendarWndProc(Message);
end;
← →
Rouse_ © (2014-08-12 12:07) [46]там же в оконной процедуре реагируй на выбор даты мышкой (раз стрелочки не устраивают)
← →
brother © (2014-08-12 12:08) [47]> Я ж говорю - не все так просто - написать свой компонент.
конечно, когда знаний не хватает на элементарное...
зы. а что это розыч так расщедрился на код?)
← →
Rouse_ © (2014-08-12 12:09) [48]
> brother © (12.08.14 12:08) [47]
> зы. а что это розыч так расщедрился на код?)
Да там кода-то :)
← →
С-К (2014-08-12 12:14) [49]
> там же в оконной процедуре реагируй на выбор даты мышкой
> (раз стрелочки не устраивают)
не понял фразы.
Вопрос вот в чем - как отличить выбор даты от выбора даты стрелочками (которые листают месяцы и при этом не нужно скрывать календарь).
← →
Rouse_ © (2014-08-12 12:30) [50]
> Вопрос вот в чем - как отличить выбор даты от выбора даты
> стрелочками (которые листают месяцы и при этом не нужно
> скрывать календарь).
На, последний раз подсказываю, дальше сам, не буду же я за тебя весь код писать?procedure TForm1.CalendarWndProc(var Message: TMessage);
procedure Hide;
begin
// где скрываем календарь
MonthCalendar1.Visible := False;
// и снимаем перехват
MonthCalendar1.WindowProc := FOldCalendarWndProc;
end;
procedure SetNewValue;
begin
Hide;
ShowMessage(DateToStr(MonthCalendar1.Date));
end;
begin
case Message.Msg of
// а в оконной процедуре реагируем на потерю фокуса
WM_KILLFOCUS, WM_CANCELMODE: Hide;
// реагируем на выбор мышкой
WM_LBUTTONUP: SetNewValue;
WM_CHAR:
begin
case Message.WParam of
// реагируем на выбор клавишей Enter
VK_RETURN: SetNewValue;
// закрываем по ESC
VK_ESCAPE: Hide;
end;
end;
end;
// не забываем все сообщения передать старой оконной процедуре
FOldCalendarWndProc(Message);
end;
← →
junglecat (2014-08-12 12:35) [51]Ну вот, Розыч практически написал сторонний компонент. А по правилам его юзать нельзя o)
← →
С-К (2014-08-12 12:37) [52]
> На
я не понял по коду как отличить то в результате? И то и другое является кликом. Но клик по стрелочкам не должен скрывать календарь.
← →
junglecat (2014-08-12 12:44) [53]скрывать календарь можно кликом по форме либо по кнопке раскрытия. Определить можно по координатам
← →
Rouse_ © (2014-08-12 12:46) [54]
> И то и другое является кликом. Но клик по стрелочкам не
> должен скрывать календарь.
А, ну да, с этим ты не разберешся, тогда вот так :)))procedure TForm1.CalendarWndProc(var Message: TMessage);
procedure Hide;
begin
// где скрываем календарь
MonthCalendar1.Visible := False;
// и снимаем перехват
MonthCalendar1.WindowProc := FOldCalendarWndProc;
end;
procedure SetNewValue;
begin
Hide;
ShowMessage(DateToStr(MonthCalendar1.Date));
end;
function NeedCloseUp(X, Y: Integer): Boolean;
const
MCM_GETCURRENTVIEW = (MCM_FIRST + 22);
var
MCHitTest: TMCHitTestInfo;
begin
Result := False;
ZeroMemory(@MCHitTest, SizeOf(TMCHitTestInfo));
MCHitTest.cbSize := SizeOf(TMCHitTestInfo);
MCHitTest.pt := Point(X, Y);
MonthCal_HitTest(MonthCalendar1.Handle, MCHitTest);
if MCHitTest.uHit and MCHT_CALENDARDATE = MCHT_CALENDARDATE then
Result := SendMessage(MonthCalendar1.Handle, MCM_GETCURRENTVIEW, 0, 0) = 0
else
if MCHitTest.uHit and MCHT_TODAYLINK = MCHT_TODAYLINK then
Result := True;
end;
begin
case Message.Msg of
// а в оконной процедуре реагируем на потерю фокуса
WM_KILLFOCUS, WM_CANCELMODE: Hide;
// реагируем на выбор мышкой
WM_LBUTTONUP:
if NeedCloseUp(TWMMouse(Message).XPos, TWMMouse(Message).YPos) then
begin
FOldCalendarWndProc(Message);
SetNewValue;
Exit;
end;
WM_CHAR:
begin
case Message.WParam of
// реагируем на выбор клавишей Enter
VK_RETURN: SetNewValue;
// закрываем по ESC
VK_ESCAPE: Hide;
end;
end;
end;
// не забываем все сообщения передать старой оконной процедуре
FOldCalendarWndProc(Message);
end;
← →
brother © (2014-08-12 13:13) [55]Эээ, а это по-феншую?)
> MonthCalendar1.Left := -1000;
> MonthCalendar1.Top := -1000;
← →
С-К (2014-08-12 13:13) [56]Что-то не работает.
У меня при вызове:
> MonthCal_HitTest(MonthCalendar.Handle, MCHitTest);
MCHitTest.uHit - всегда равен нулю (
Правда, я не перехватывал сообщения. Просто проверил это на обработке OnClick.
← →
С-К (2014-08-12 13:14) [57]Ну и соответственно вместо:
>(TWMMouse(Message).XPos, TWMMouse(Message).YPos
Я передаю Mouse.Cursor.X и .Y
← →
junglecat (2014-08-12 13:20) [58]WM_LBUTTONUP - х и у относительно календаря. Mouse.Cursor.X и .Y - относительно десктопа
← →
Rouse_ © (2014-08-12 13:20) [59]
> brother © (12.08.14 13:13) [55]
> Эээ, а это по-феншую?)
Это по быстрому ;)
> Правда, я не перехватывал сообщения. Просто проверил это
> на обработке OnClick.
А это не правильно.
← →
brother © (2014-08-12 13:22) [60]Ну, что Вы ему мастер-класс по перехвату сообщений даете? Видно же, что он код ждет и не понимает как это все работает...
Давайте уж тогда с основ...
← →
brother © (2014-08-12 13:23) [61]а то, он же обозначил задачу)
← →
С-К (2014-08-12 13:41) [62]
> WM_LBUTTONUP - х и у относительно календаря. Mouse.Cursor.
> X и .Y - относительно десктопа
спасибо! Все заработало.
Rouse_, спасибо большое!
← →
С-К (2014-08-12 13:44) [63]Остался маленький глючок, конечно. Если кликнуть на область обозначений дней недели - то это засчитывается за клик-выбор даты.
На картинку обозначил проблемную область: http://bit.ly/1rlxKDT
Но это, конечно, мелочи. Спасибо за помощь.
← →
Rouse_ © (2014-08-12 14:01) [64]То что на картинке соответствует MCHT_CALENDARDAY при вызове MonthCal_HitTest, стало быть NeedCloseUp это должна учитывать, хотя судя по картинке у тебя какая-то старая ОС, вполне возможно что там не возвращалась эта константа.
← →
С-К (2014-08-12 14:05) [65]
> судя по картинке у тебя какая-то старая ОС
Windows Server 2003 R2
← →
С-К (2014-08-12 14:12) [66]
> Windows Server 2003 R2
на Windows 7 абсолютно аналогично.
Еще нашел глюк. Если перейти к отображению календаря по месяцам: http://bit.ly/1pM7cfF
то клик на месяц тоже приводит к выбору даты и календарь закрывается ((
При этом в режиме отображения годов - этого не происходит. Интересно.
← →
Rouse_ © (2014-08-12 14:29) [67]
> на Windows 7 абсолютно аналогично.
У меня Windows 7 все работает штатно, что-то значит опять не так сделал: http://rouse.drkb.ru/tmp/mct.zip
← →
С-К (2014-08-12 14:42) [68]У тебя в таком случае uHit = 131074
А у меня, если MonthCal_HitTest делать при OnClick: 33685505
Видимо, есть какая-то разница в состоянии компонента в разное время. Хотя и не понимаю какая.. Сделаю тогда тоже на перехвате сообщения.
← →
Германн © (2014-08-13 01:40) [69]
> С-К (12.08.14 09:08) [38]
>
>
> > пишется за 15 минут
>
> как реализовать выпадающий календарик?
>
>
> > Ещё раз повторю TDateEdit от RxLib.
>
> еще раз повторю:
>
>
> > А сейчас требование работать на стандартных компонентах
>
Неужели трудно прежде чем прежде чем выпрашивать код здесь скачать из Инета RxLibrary(ссылок дофига) и посмотреть код упоминаемого мною компонента.
Лень матушка.
Страницы: 1 2 вся ветка
Текущий архив: 2016.02.28;
Скачать: CL | DM;
Память: 0.61 MB
Время: 0.007 c