Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

В компоненте MHMonthCalendar не работает событие OnChange


Страницы:   1 2

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


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо