![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
В компоненте MHMonthCalendar не работает событие OnChange
ElDev © (2006-02-12 19:34:00)Народ помогите в MHMonthCalendar не работает OnChange, а в аналогичном MHDateTimePicker всё нормально.
пр.
Calendar.OnChange := TOnEvent(MakeMethod(Calendar, @OnChange));
ecm (2006-03-01 12:06:00) [1]годится... :)
avs (2006-03-01 10:54:00) [2]Приношу свои извинения. Напутал с версиями. Предлагаю такой вариант:
function WndProcCalSelChange(Sender : PControl; var Msg:TMsg; var Rslt:Integer):Boolean;
var
NMSC:PNMSelChange;
SelRange: TDateRange;
MCD: PMonthCalData;
SS,SE: Cardinal;
begin
result:=false;
if Msg.message=WM_NOTIFY then
begin
Result:=true;
NMSC := PNMSelChange(Msg.lParam);
MCD := PMonthCalData(Sender.CustomData);
with NMSC^,MCD^ do begin
Case nmhdr.code of
MCN_SELCHANGE: begin
SystemTime2DateTime(stSelStart, SelRange.MinDate);
SystemTime2DateTime(stSelEnd, SelRange.MaxDate);
SS := Trunc(SelRange.MinDate); SE := Trunc(SelRange.MaxDate);
if (SS <> fSelStart) or (SE <> fSelEnd) then begin
fSelStart := SS; fSelEnd := SE;
if Assigned(fOnSelChange) then fOnSelChange(Sender,SelRange.MinDate,SelRange.MaxDate);
end;
end;
MCN_SELECT: if Assigned(Sender.OnChange) then Sender.OnChange(Sender);
else result:=false;
end;
end;
end;
end;
ecm (2006-03-01 09:28:00) [3]Вы неправы - всё есть, только вкралась очепятка, правда на логику работы это не повлияло (торопился - было мало времени, и не закоментировал лишню проверку - скопированной строки if). Вот код из 0.05:
function WndProcCalSelChange(Sender : PControl; var Msg:TMsg; var Rslt:Integer):Boolean;
var
NMSC:PNMSelChange;
SelRange: TDateRange;
MCD: PMonthCalData;
SS,SE: Cardinal;
begin
Result := False;
if Msg.message=WM_NOTIFY then
begin
NMSC := PNMSelChange(Msg.lParam);
MCD := PMonthCalData(Sender.CustomData);
with NMSC^,MCD^ do begin
if {(nmhdr.code = MCN_SELECT) or }(nmhdr.code = MCN_SELCHANGE) then begin
SystemTime2DateTime(stSelStart, SelRange.MinDate);
SystemTime2DateTime(stSelEnd, SelRange.MaxDate);
SS := Trunc(SelRange.MinDate); SE := Trunc(SelRange.MaxDate);
if (SS <> fSelStart) or (SE <> fSelEnd) then begin
fSelStart := SS; fSelEnd := SE;
if Assigned(fOnSelChange) then fOnSelChange(Sender,SelRange.MinDate,SelRange.MaxDate);
end;
Result := TRUE;
end else if (nmhdr.code = MCN_SELECT) or (nmhdr.code = MCN_SELCHANGE) then begin
if Assigned(Sender.OnChange) then Sender.OnChange(Sender);
end;
end;
end;
end;
В первом IF закоменнтирован MCN_SELECT, во втором надо было закоментировать MCN_SELCHANGE (я это поправлю) - но на логику это никак не повлияет - только уменьшит кол-во проверок и размер кода.
avs (2006-03-01 08:52:00) [4]Пардон, действительно не переустановил.
Но OnChange - реакция на MCN_SELECTнету.
Более того, я заглянул в исходники и следов OnChange не обнаружил....
Нашел реакцию на MCN_SELCHANGE или MCN_SELECT, отдельно MCN_SELECT не обрабатывается.
ecm (2006-02-28 17:45:00) [5]Всё правильно - Вы не переустановили пакет.
1) Требуется переустановка пакета.
2) Откореектируйте объявление MonthCalendar1SelChange вручную (см. описание типа TOnSelChange) либо - переименуйте и создайте обработчик заново...
:)
avs (2006-02-28 16:58:00) [6]Докладаю результаты испытания версии (0.05):
1. OnChange не видно в Object inspector
2. При компиляции имеем ругательство:
Result.MonthCalendar1.OnSelChange := Result.MonthCalendar1SelChange;
[Error] Unk1_1.inc(809): Incompatible types: 'PControl' and 'PObj'
ECM (2006-02-28 16:29:00) [7]
> Пользователю захотелось полистать месяцы, годы и т.д. и
> отслеживать это до тех пор, пока ему что-то не понравидось,
> по-моему, смысла нет.
Разумно... согласен...
Переделанная версия (0.05) лежит там же.. :)
Теперь OnSelChange - это реакция на MCN_SELCHANGE
Sent by a month calendar control when the currently selected date or range of dates changes.
OnChange - реакция на MCN_SELECT
Sent by a month calendar control when the user makes an explicit date selection within a month calendar control. This notification message is similar to MCN_SELCHANGE, but it is sent only in response to a user's explicit date selections.
avs (2006-02-28 09:03:00) [8]Cмысл сего действа смысл сего действа в следующем:
Пользователю захотелось полистать месяцы, годы и т.д. и отслеживать это до тех пор, пока ему что-то не понравидось, по-моему, смысла нет.
А вот, когда он выбрал конкретную дату, нужно ее считать. Так работает
DateTimePicker и так работает
-746:if Assigned(MHMonthCalendarNow.OnChange) then MHMonthCalendarNow.OnChange
Может быть, есть смысл организовать OnChange по MCN_SELECT ?
ECM (2006-02-27 16:41:00) [9]
> не работает событие onMouseDblClk
Поправил - см новую версию..
http://www.delphimaster.ru/cgi-bin/forum.pl?id=1140886672&n=10
> чтобы событие OnSelChange не отрабатывалось при изменении
> года и месяца
Я думаю - это делать в самом компоненте - не нужно. Событие генерируется системой (кстати в VCL пользовательская обработка этого события отсутствует) - повлиять на то когда генерировать когда нет - это к дяде Билли... :)
Можно конечно поставить анализ на изменение даты... Но кто мешает Вам поставить такой анализ у себя в обработчике OnSelChange?
И смысл сего действа мне не совсем ясен...
avs (2006-02-27 12:36:00) [10]Уважаемый Евгений! Еще одно замечание. Хотелось бы, чтобы событие OnSelChange не отрабатывалось при изменении года и месяца.
avs (2006-02-27 11:43:00) [11]Уважаемый Евгений! Утановил версию от 23.02.2006 (кстати, с прошедшим Вас праздником). Все бы хорошо, но не работает событие onMouseDblClk
ECM (2006-02-24 14:41:00) [12]
> не факт что размер календаря установленный визуально в MCK
> будет совпадать с реальным, в разных версиях Windows
Вот есть такой недостаток... называется, кажется, - "косноязычие"
Думал про одно - а сказал про другое...:(
(Завидую Владимиру - у него кроме таланта к программированию еще и литературный талант есть ... физик и лирик в одном лице - прямо как братья АБС :)) )
Тут я имел ввиду что размер календаря подобранный визуально в МСК в определенной версии Windows, может не подойти для других - он в рамки заданые SetSize может просто не поместиться полностью...
:))
GMax (2006-02-23 22:08:00) [13]спасибо, на этот раз вроде всё нормально.
ECM (2006-02-23 21:55:00) [14]
> Хорошо бы еще сообразить рамку по границе окна
Кстати тут есть тонкость - в разных версиях Windows календарь рисуется немного поразному (в W2K он шире чем в XP/W2K) поэтому рамку (при помощи BackColor) надо создавать примерно следующим образом :
procedure TForm1.KOLForm1FormCreate(Sender: PObj);
begin
...
MonthCalendar1.AdjustSize;
MonthCalendar1.SetSize(MonthCalendar1.Width+4,MonthCalendar1.Height+4);
end;
здесь будет создана рамка толщиной в 2 пикселя
т.е. есть неоднозначность - не факт что размер календаря установленный визуально в MCK будет совпадать с реальным, в разных версиях Windows
(но AdjustSize - работает везде)
ECM (2006-02-23 14:34:00) [15]Исправил ситуацию с w2k и размерами после бросания на форму
версия 0.03 лежит там же:
http://www.kolnmck.ru/files/components/controls/kolmonthcalendar.zip
ECM (2006-02-21 19:43:00) [16]
> таки что с W2k ?
Эффект имеет место быть ... разбираюсь. Проблема - негде поставить w2k.
:(
GMax (2006-02-21 19:39:00) [17]таки что с W2k ?
попробовал на другой машине, там вроде error in user32.dll не проявился, но изображения всё равно нет
ECM (2006-02-21 16:39:00) [18]Поправьте у себя в KOLMonthCalendar.pas
function TMonthCalendar.GetDateVal(const Index: Integer): TDateTime;
const
Msg_Val: Array[0..1] of DWORD = (
MCM_GETCURSEL,
MCM_GETTODAY
);
var
ST: TSystemTime;
begin
Perform(Msg_Val[Index],0,Integer(@ST));
FillChar(ST.wHour,SizeOf(Word)*4,0);
SystemTime2DateTime(ST,Result);
end;
Я вечером выложу исправление...
По поводу размера - для AutoSize = false после бросания на форму
измените размеры мышкой - что бы в inc-файле появилась установка
размера (тоже поправлю)
Рамку можно сделать уже сейчас - просто поставьте нужный цвет рамки
в BackColor и поиграйте размерами - сами увидите...
avs (2006-02-21 16:21:00) [19]MultiSelect=False
SelStart,SelEnd тоже пользовал. Результат тот же.
Кроме того, если autosize=false, при запуске программы видна часть календарика в маленьком квадратике.
Видимо, с разбегу не получилось, но штука очень нужная.Хорошо бы еще сообразить рамку по границе окна.
ECM (2006-02-21 15:29:00) [20]Наверное у вас MultiSelect=TRUE
Почитайте коментарии:
property Date: TDateTime index 0 read GetDateVal write SetDateVal;
{* Sets the currently selected date for a month calendar control.
If the specified date is not in view, the control updates the display
to bring it into view. Apply to a month calendar control that NOT uses
the MCS_MULTISELECT style}
Используйте в этом случае SelStart,SelEnd