Ver Mensaje Individual
  #7  
Antiguo Hace 3 Horas
Avatar de escafandra
[escafandra] escafandra is offline
Miembro Premium
 
Registrado: nov 2007
Posts: 2.211
Reputación: 22
escafandra Tiene un aura espectacularescafandra Tiene un aura espectacular
No había visto este tema hasta ahora.
Para que el marcado de días sea consistente hay que crearse un componente o hacer un subclassing del TDateTimePicker. Si trabajasemos sobre un TMonthCalendar, bastaría con interceptar en el Formulario los mensajes WM_NOTIFY. Esto es debido a que un control windows envia las notificaciones a su parent, en el caso de TMonthCalendar las envía al Formulario pero en el caso de TDateTimePicker, lleva un MonthCalendar desplegable que notifica al DateTimePicker.

Se debe gestionar la notificación MCN_GETDAYSTATE de esta manera:
Código:
void __fastcall TForm1::SubClassTimePickerProc(TMessage& Message)
{
  if(Message.Msg == WM_NOTIFY){
    LPNMDAYSTATE PNMD = (LPNMDAYSTATE)Message.LParam;
    if(PNMD->nmhdr.code == MCN_GETDAYSTATE){
      // Poner en negrita del dia 1 al 25 del mes
      for(int i = 0; i < PNMD->cDayState; i++){
        DayStates[i] = 0;
        for(int d = 1; d <= 25; d ++){
          DayStates[i] |= (1 << (d - 1));
        }
      }
      PNMD->prgDayState = DayStates;
      Message.Result = 0;
    }
  }

  OldTimePickerProc(Message);
}
He preparado un ejemplo con un TTimePicker y un TMonthCalendar para ver las diferencias. Ambor marcan del dia 1 al 25 de cada mes.
Código:
//---------------------------------------------------------------------------

#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <ComCtrls.hpp>
//---------------------------------------------------------------------------

typedef void __fastcall(__closure *PWndProc)(Messages::TMessage &Message);


class TForm1 : public TForm
{
  __published:	// IDE-managed Components
  TDateTimePicker *DateTimePicker1;
  TMonthCalendar *MonthCalendar1;

  private:	// User declarations
  PWndProc OldTimePickerProc;

  MONTHDAYSTATE DayStates[12]; // debe vivir mientras el popup esté abierto
  void __fastcall WMNotify(TMessage &Message);
  void __fastcall SubClassTimePickerProc(TMessage& Message);

  public:		// User declarations
  __fastcall TForm1(TComponent* Owner);

BEGIN_MESSAGE_MAP
  MESSAGE_HANDLER(WM_NOTIFY, TMessage, WMNotify)
END_MESSAGE_MAP(TForm)
};

//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif
Código:
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"

#define  DTM_GETMCSTYLE (DTM_FIRST + 12)
#define  DTM_SETMCSTYLE (DTM_FIRST + 11)

TForm1 *Form1;

//---------------------------------------------------------------------------
void __fastcall SetSubCass(TWinControl *WC, PWndProc newProc, PWndProc *oldProc)
{
  *oldProc = WC->WindowProc;
  WC->WindowProc = newProc;
}
//---------------------------------------------------------------------------

//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
  : TForm(Owner)
{
  DWORD style = SendMessage(DateTimePicker1->Handle, DTM_GETMCSTYLE, 0, 0);
  SendMessage(DateTimePicker1->Handle, DTM_SETMCSTYLE, 0, style | MCS_DAYSTATE);
  SendMessage(MonthCalendar1->Handle, DTM_SETMCSTYLE, 0, style | MCS_DAYSTATE);
  SetSubCass(DateTimePicker1, SubClassTimePickerProc, &OldTimePickerProc);
}
//---------------------------------------------------------------------------

void __fastcall TForm1::WMNotify(TMessage &Message)
{
  LPNMDAYSTATE PNMD = (LPNMDAYSTATE)Message.LParam;
  if(PNMD->nmhdr.code == MCN_GETDAYSTATE){
    for(int i = 0; i < PNMD->cDayState; i++){
      DayStates[i] = 0;
      // Poner en negrita del dia 1 al 25 del mes
      for(int d = 1; d <= 25; d ++){
        DayStates[i] |= (1 << (d - 1));
      }
    }
    PNMD->prgDayState = DayStates;
    Message.Result = 0;
  }
  else{
    // Deja que VCL procese el resto de notificaciones normalmente
    TForm::Dispatch(&Message);
  }
}
//---------------------------------------------------------------------------

void __fastcall TForm1::SubClassTimePickerProc(TMessage& Message)
{
  if(Message.Msg == WM_NOTIFY){
    LPNMDAYSTATE PNMD = (LPNMDAYSTATE)Message.LParam;
    if(PNMD->nmhdr.code == MCN_GETDAYSTATE){
      // Poner en negrita del dia 1 al 25 del mes
      for(int i = 0; i < PNMD->cDayState; i++){
        DayStates[i] = 0;
        for(int d = 1; d <= 25; d ++){
          DayStates[i] |= (1 << (d - 1));
        }
      }
      PNMD->prgDayState = DayStates;
      Message.Result = 0;
    }
  }

  OldTimePickerProc(Message);
}
Saludos.
Responder Con Cita