CYFROWY BARON • PROGRAMOWANIE • Zobacz wątek - TMonthCalendar - BoldDay - Odświeżanie

TMonthCalendar - BoldDay - Odświeżanie

dział ogólny

TMonthCalendar - BoldDay - Odświeżanie

Nowy postprzez mckri » czwartek, 26 stycznia 2012, 21:35

Witam
Robię mały programik, którego zadaniem jest zapisywanie notatek na wybrany dzień. Używam komponentów TMonthCalendar i RichEdit.
Jednym z założeń jest wyróżnienie dni w kalendarzu, które zawierają notatkę.

Kod: Zaznacz cały
TStringList *Lista=new TStringList; //deklaracja obiektu 'Lista'.

....
Kod: Zaznacz cały
Lista->Add("20110110");  //lista dni tworzona dynamicznie, głównie w momencie utworzenia nowej notatki.
Lista->Add("20110112");
Lista->Add("20110118");
Lista->Add("20110128");
...


W zdarzeniu OnGetMonthInfo można umieścić kod, który będzie wyróżniał poprzez pogrubienie zadane dni.

Kod: Zaznacz cały
TDateTime date[366];
for(int x=0;x<Lista-> Count;x++)
{
   date[x]=EncodeDate(Lista->Strings[x].SubString(1,4).ToInt(),Lista->Strings[x].SubString(5,2).ToInt(),Lista->Strings[x].SubString(7,2).ToInt());
}

WORD day,month,year;

int j = 0;
for (int i = 0; i < Lista->Count; i++)   
{
      DecodeDate(date[i],year,month,day);
      unsigned bolddays[31];

      if (Month==month  )
      {
       bolddays[j] = day;
       Calendar1->BoldDays(bolddays,j, (unsigned&)MonthBoldInfo);
       j++;
      }
}


Zadane dni ładnie i pieknie się wyróżniają, ale są 2 główne problemy.
1. Kod wyróżnia prawidłowo tylko wg miesiąca i dnia danego miesiąca. Rok nie jest brany pod uwagę. Tzn, notatka zapisana dnia 11.01.2012 będzie również wyróżniona w innych latach 11.01.2011, 2010, 2009, itd.

2. Dodanie nowej notatki powoduje dodanie do obiektu 'Lista' odpowiednio nowej daty. Jak automatycznie odświeżyć w TMonthCalendar dzień utworzenia tej notatki? Odświeżenie działa obecnie tylko przy nawigacji między miesiącami.

Chyba przekopałem już cały internet w tym temacie i natknąłem się na ciekawe rozwiązania wykorzystujące bezpośrednio API.
https://forums.embarcadero.com/thread.jspa?threadID=63457
Niestety program czasami się sypie - StackOverflow.

Może ktoś pomoże?
Avatar użytkownika
mckri
Intelektryk
Intelektryk
 
Posty: 160
Dołączył(a): piątek, 15 sierpnia 2008, 13:48
Podziękował : 10
Otrzymał podziękowań: 2
System operacyjny: Windows Vista SP2
Kompilator: BCB 5/2007/2009
    Windows VistaOpera

Re: TMonthCalendar - BoldDay - Odświeżanie

Nowy postprzez Cyfrowy Baron » czwartek, 26 stycznia 2012, 23:48

mckri napisał(a): Kod wyróżnia prawidłowo tylko wg miesiąca i dnia danego miesiąca. Rok nie jest brany pod uwagę.
KOD cpp:     UKRYJ  
if (Month==month  )


Skoro instrukcja warunkowa sprawdza tylko miesiąc bez roku to czego oczekujesz?! Dodaj do warunku jeszcze sprawdzanie czy rok się zgadza:

KOD cpp:     UKRYJ  
if (Month == month  && Year == year) /.../






mckri napisał(a):2. Dodanie nowej notatki powoduje dodanie do obiektu 'Lista' odpowiednio nowej daty. Jak automatycznie odświeżyć w TMonthCalendar dzień utworzenia tej notatki? Odświeżenie działa obecnie tylko przy nawigacji między miesiącami.


Po dodaniu notatki wywołaj funkcję Refresh dla obiektu:

KOD cpp:     UKRYJ  
 MonthCalendar1->Refresh()
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: TMonthCalendar - BoldDay - Odświeżanie

Nowy postprzez mckri » piątek, 27 stycznia 2012, 00:21

Z całym szacunkiem, ale chyba nie orientujesz się w czym problem.

Skoro instrukcja warunkowa sprawdza tylko miesiąc bez roku to czego oczekujesz?! Dodaj do warunku jeszcze sprawdzanie czy rok się zgadza:

Nie jest to możliwe w tym zdarzeniu.

Po dodaniu notatki wywołaj funkcję Refresh dla obiektu:

Gdyby to było takie proste nie pisałbym na forum :)
Avatar użytkownika
mckri
Intelektryk
Intelektryk
 
Posty: 160
Dołączył(a): piątek, 15 sierpnia 2008, 13:48
Podziękował : 10
Otrzymał podziękowań: 2
System operacyjny: Windows Vista SP2
Kompilator: BCB 5/2007/2009
    Windows VistaOpera

Re: TMonthCalendar - BoldDay - Odświeżanie

Nowy postprzez Cyfrowy Baron » piątek, 27 stycznia 2012, 00:44

Rok możesz pobrać bezpośrednio z kalendarza, a nie z ciała funkcji.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: TMonthCalendar - BoldDay - Odświeżanie

Nowy postprzez mckri » piątek, 27 stycznia 2012, 01:02

NIby moge pobrać, standardowo przez Calendar1->Date.FormatString("yyyy") ale zdarzenie OnGetMonthInfo jest dość specyficzne, bo pobiera wartość 3 miesiący. Komponent kelandarza prezentuje oprócz bieżacego miesiąca, również częsciowo koniec poprzedniego i początek kolejnego. I tutaj pojawia się problem z właściwym rozpoznaniem roku.
Avatar użytkownika
mckri
Intelektryk
Intelektryk
 
Posty: 160
Dołączył(a): piątek, 15 sierpnia 2008, 13:48
Podziękował : 10
Otrzymał podziękowań: 2
System operacyjny: Windows Vista SP2
Kompilator: BCB 5/2007/2009
    Windows VistaOpera

Re: TMonthCalendar - BoldDay - Odświeżanie

Nowy postprzez Cyfrowy Baron » piątek, 27 stycznia 2012, 01:16

Warunek musi zawierać rok, w przeciwnym razie będzie działał dla wszystkich lat. TMontCalendar to prosty kalendarz i nie został przewidziany do tworzenia terminarzy. Idealnym rozwiązaniem byłby komponent TPlanerCalendar z pakietu TMS Component Pack.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: TMonthCalendar - BoldDay - Odświeżanie

Nowy postprzez Corvis » piątek, 27 stycznia 2012, 09:16

Napisz swój kalendarz wtedy będziesz mógł robić co chcesz. Mam gdzieś taki nawet napisany przy użyciu StringGrida. Jak znajdę to wrzucę źródła.
"Sukcesy trwają, dopóki ich ktoś nie spieprzy. Porażki są wieczne"

Dr Gregory House
Avatar użytkownika
Corvis
Programista I
Programista I
 
Posty: 880
Dołączył(a): sobota, 26 lipca 2008, 00:31
Podziękował : 80
Otrzymał podziękowań: 30
System operacyjny: WINDOWS 7 64-bity
Kompilator: Praca - C++ Builder XE2 ENTERPRISE - Update 4, Dom - C++ Builder XE4 - Uddate 1
Gadu Gadu: 0
    Windows 7Chrome

Re: TMonthCalendar - BoldDay - Odświeżanie

Nowy postprzez Cyfrowy Baron » piątek, 27 stycznia 2012, 10:43

mckri napisał(a):NIby moge pobrać, standardowo przez Calendar1->Date.FormatString("yyyy")


Wcale nie, wystarczy tak:

KOD cpp:     UKRYJ  
WORD day, month, year;
  WORD tmp1, tmp2, Year;
  DecodeDate( Calendar1->Date, Year, tmp1, tmp2);


  int j = 0;
  for (int i = 0; i < Lista->Items->Count; i++)
  {
          DecodeDate(date[i], year, month, day);

          unsigned bolddays[31];

          if( Month == month  && Year == year)
      {
       bolddays[j] = day;
           Calendar1->BoldDays(bolddays, j, (unsigned&)MonthBoldInfo);
           j++;
      }
  }




mckri napisał(a):ale zdarzenie OnGetMonthInfo jest dość specyficzne, bo pobiera wartość 3 miesiący.


No nie jest tak do końca. Problem występuje tylko przy przechodzeniu np. z grudnia 2012 do stycznia 2013, ale przejście z lutego 2013 do stycznia 2013 już działa prawidłowo, czyli problem dotyczy zmiany roku. Niestety nie widzę sposobu na obejście tego problemu.

Co do odświeżania, to wypróbowałem kilka sposobów i żaden nie dział. Jest oczywiste, że jakakolwiek to będzie metoda, musi zostać wywołane zdarzenie OnGetMonthInfo, jednak próba ręcznego sterowania tym zdarzeniem niczego nie daje.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: TMonthCalendar - BoldDay - Odświeżanie

Nowy postprzez mckri » niedziela, 29 stycznia 2012, 15:11

Udało mi się w końcu rozwiązać oba problemy w tym wątku. Może nie są to rozwiązania zachwycające, ale działają :)
1.
Trzeba było w zdarzeniu OnGetMonthInfo pobierać wartość roku a przy okazji ilość prezentowanych szczątkowych miesiący (koniec poprzedniego i początek kolejnego) w dla danego miesiąca. Ja mam zawsze jeden kalendarz dla bieżacego miesiąca.

KOD cpp:     UKRYJ  
WORD Year;
SYSTEMTIME st[2]={0};
int num_month=SNDMSG(Calendar1->Handle, MCM_GETMONTHRANGE,GMR_DAYSTATE, reinterpret_cast<LPARAM>(&st));
Year=st->wYear; //struktura st zawsze zawiera informacje o dacie z pierwszego szczątkowego miesiąca
//zdarzenie OnGetMonthInfo wykonuje się tyle razy ile widać miesiący w jednym kalendarzu.
if(MCount==1 && Month==1)
         Year++;  //odpowiednio dodaje +1 do roku z miesiąca szczątkowego
 if(MCount==2 && Month==2)
         Year++;
 if(MCount==2 && Month==1)
         Year++;

...

MCount++;
 if(MCount==num_month)   MCount=0; //resetuje wartosc globalnej, gdy wykonało się sprawdzenie wszystkich miesiący z kalendarza.




2.
Żeby odświeżyć dni w kalendarzu bez zbędnego "męczenia się" wystarczy cofnąć chwilowo bieżacy widok o miesiąc, następnie przywrócić, np:

KOD cpp:     UKRYJ  
TDateTime datatmp=Calendar1->Date;  
Calendar1->Date=datatmp-31;
Calendar1->Date=datatmp;


Taka operacja wywołuje zdarzenie OnGetMonthInfo i spowoduje, że dzień dla którego zapisano notatkę zostanie wyróżniony.
Avatar użytkownika
mckri
Intelektryk
Intelektryk
 
Posty: 160
Dołączył(a): piątek, 15 sierpnia 2008, 13:48
Podziękował : 10
Otrzymał podziękowań: 2
System operacyjny: Windows Vista SP2
Kompilator: BCB 5/2007/2009
    Windows VistaOpera

Re: TMonthCalendar - BoldDay - Odświeżanie

Nowy postprzez Cyfrowy Baron » niedziela, 29 stycznia 2012, 17:13

mckri napisał(a):Żeby odświeżyć dni w kalendarzu bez zbędnego "męczenia się" wystarczy cofnąć chwilowo bieżacy widok o miesiąc, następnie przywrócić,


Próbowałem tego u siebie i u mnie to nie działa. To znaczy data się cofa, ale zdarzenie nie jest wywoływane.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: TMonthCalendar - BoldDay - Odświeżanie

Nowy postprzez mckri » poniedziałek, 30 stycznia 2012, 22:46

A skąd wiesz, że zdarzenie OnGetMonthInfo nie jest wywoływane podczas tricku cofnięcia/przywrócenia daty?. Masz obecnie w tym zdarzeniu jakiś kod?
Avatar użytkownika
mckri
Intelektryk
Intelektryk
 
Posty: 160
Dołączył(a): piątek, 15 sierpnia 2008, 13:48
Podziękował : 10
Otrzymał podziękowań: 2
System operacyjny: Windows Vista SP2
Kompilator: BCB 5/2007/2009
    Windows VistaOpera

Re: TMonthCalendar - BoldDay - Odświeżanie

Nowy postprzez Cyfrowy Baron » wtorek, 31 stycznia 2012, 05:53

Oczywiście, że mam tam Twój kod. To jaki mam tam kod jest o tyle nieistotne, że wiem jak sprawdzić czy zdarzenie zostało wywołane czy nie.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: TMonthCalendar - BoldDay - Odświeżanie

Nowy postprzez mckri » wtorek, 31 stycznia 2012, 18:17

Kod jaki mam w OnGetMonthInfo wygląda jak poniżej. Jest tam wykorzystana zmienna globalna MCount zajmująca sie obsługą prezentacji roku z miesiacy szczątkowych oraz ListaBold, która zawiera listę dat w formacie yyyyMMdd - do listy dodawana jest nowa data w momencie zapisania notatki w wybranym dniu.

KOD cpp:     UKRYJ  
TDateTime date[366];
 for(int x=0;x<ListaBold->Count;x++)
 {
   date[x]=EncodeDate(ListaBold->Strings[x].SubString(1,4).ToInt(),ListaBold->Strings[x].SubString(5,2).ToInt(),ListaBold->Strings[x].SubString(7,2).ToInt());
 }
 WORD day,month,year;

 WORD Year;
 SYSTEMTIME st[2]={0};
 int num_month=SNDMSG(Calendar1->Handle, MCM_GETMONTHRANGE,GMR_DAYSTATE, reinterpret_cast<LPARAM>(&st));
 Year=st->wYear;
 if(MCount==1 && Month==1)
         Year++;
 if(MCount==2 && Month==2)
         Year++;
 if(MCount==2 && Month==1)
         Year++;

 int j = 0;
 for (int i = 0; i < ListaBold->Count; i++)  
 {
           DecodeDate(date[i],year,month,day);
           unsigned bolddays[31];

           if (Month==month && Year==year)
           {
                 bolddays[j] = day;
                 Calendar1->BoldDays(bolddays,j, (unsigned&)MonthBoldInfo);
                 j++;
           }
 }
 MCount++;
 if(MCount==num_month)   MCount=0;
 


Dla mnie wątek jest zakończony.
Avatar użytkownika
mckri
Intelektryk
Intelektryk
 
Posty: 160
Dołączył(a): piątek, 15 sierpnia 2008, 13:48
Podziękował : 10
Otrzymał podziękowań: 2
System operacyjny: Windows Vista SP2
Kompilator: BCB 5/2007/2009
    Windows VistaOpera


  • Podobne tematy
    Odpowiedzi
    Wyświetlone
    Ostatni post

Powrót do Ogólne problemy z programowaniem

Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zalogowanych użytkowników i 3 gości