monthcal.c

来自「一个类似windows」· C语言 代码 · 共 2,069 行 · 第 1/5 页

C
2,069
字号
  int prev = -1;

  TRACE("%d: color %08lx\n", wParam, lParam);

  switch((int)wParam) {
    case MCSC_BACKGROUND:
      prev = infoPtr->bk;
      infoPtr->bk = (COLORREF)lParam;
      break;
    case MCSC_TEXT:
      prev = infoPtr->txt;
      infoPtr->txt = (COLORREF)lParam;
      break;
    case MCSC_TITLEBK:
      prev = infoPtr->titlebk;
      infoPtr->titlebk = (COLORREF)lParam;
      break;
    case MCSC_TITLETEXT:
      prev=infoPtr->titletxt;
      infoPtr->titletxt = (COLORREF)lParam;
      break;
    case MCSC_MONTHBK:
      prev = infoPtr->monthbk;
      infoPtr->monthbk = (COLORREF)lParam;
      break;
    case MCSC_TRAILINGTEXT:
      prev = infoPtr->trailingtxt;
      infoPtr->trailingtxt = (COLORREF)lParam;
      break;
  }

  InvalidateRect(infoPtr->hwndSelf, NULL, FALSE);
  return prev;
}


static LRESULT
MONTHCAL_GetMonthDelta(MONTHCAL_INFO *infoPtr)
{
  TRACE("\n");

  if(infoPtr->delta)
    return infoPtr->delta;
  else
    return infoPtr->visible;
}


static LRESULT
MONTHCAL_SetMonthDelta(MONTHCAL_INFO *infoPtr, WPARAM wParam)
{
  int prev = infoPtr->delta;

  TRACE("delta %d\n", wParam);

  infoPtr->delta = (int)wParam;
  return prev;
}


static LRESULT
MONTHCAL_GetFirstDayOfWeek(MONTHCAL_INFO *infoPtr)
{
  return infoPtr->firstDay;
}


/* sets the first day of the week that will appear in the control */
/* 0 == Sunday, 6 == Saturday */
/* FIXME: this needs to be implemented properly in MONTHCAL_Refresh() */
/* FIXME: we need more error checking here */
static LRESULT
MONTHCAL_SetFirstDayOfWeek(MONTHCAL_INFO *infoPtr, LPARAM lParam)
{
  int prev = infoPtr->firstDay;
  WCHAR buf[40];

  TRACE("day %ld\n", lParam);

  if((lParam >= 0) && (lParam < 7)) {
    infoPtr->firstDay = (int)lParam;
  }
  else
    {
      GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_IFIRSTDAYOFWEEK, buf, countof(buf));
      TRACE("%s %d\n", debugstr_w(buf), strlenW(buf));
      infoPtr->firstDay = (atoiW(buf)+1)%7;
    }
  return prev;
}


static LRESULT
MONTHCAL_GetMonthRange(MONTHCAL_INFO *infoPtr)
{
  TRACE("\n");

  return infoPtr->monthRange;
}


static LRESULT
MONTHCAL_GetMaxTodayWidth(MONTHCAL_INFO *infoPtr)
{
  return(infoPtr->todayrect.right - infoPtr->todayrect.left);
}


/* FIXME: are validated times taken from current date/time or simply
 * copied?
 * FIXME:    check whether MCM_GETMONTHRANGE shows correct result after
 *            adjusting range with MCM_SETRANGE
 */

static LRESULT
MONTHCAL_SetRange(MONTHCAL_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
{
  SYSTEMTIME *lprgSysTimeArray=(SYSTEMTIME *)lParam;
  int prev;

  TRACE("%x %lx\n", wParam, lParam);

  if(wParam & GDTR_MAX) {
    if(MONTHCAL_ValidateTime(lprgSysTimeArray[1])){
      MONTHCAL_CopyTime(&lprgSysTimeArray[1], &infoPtr->maxDate);
      infoPtr->rangeValid|=GDTR_MAX;
    } else  {
      GetSystemTime(&infoPtr->todaysDate);
      MONTHCAL_CopyTime(&infoPtr->todaysDate, &infoPtr->maxDate);
    }
  }
  if(wParam & GDTR_MIN) {
    if(MONTHCAL_ValidateTime(lprgSysTimeArray[0])) {
      MONTHCAL_CopyTime(&lprgSysTimeArray[0], &infoPtr->minDate);
      infoPtr->rangeValid|=GDTR_MIN;
    } else {
      GetSystemTime(&infoPtr->todaysDate);
      MONTHCAL_CopyTime(&infoPtr->todaysDate, &infoPtr->minDate);
    }
  }

  prev = infoPtr->monthRange;
  infoPtr->monthRange = infoPtr->maxDate.wMonth - infoPtr->minDate.wMonth;

  if(infoPtr->monthRange!=prev) {
	infoPtr->monthdayState = ReAlloc(infoPtr->monthdayState,
                                                  infoPtr->monthRange * sizeof(MONTHDAYSTATE));
  }

  return 1;
}


static LRESULT
MONTHCAL_GetRange(HWND hwnd, WPARAM wParam, LPARAM lParam)
{
  MONTHCAL_INFO *infoPtr = MONTHCAL_GetInfoPtr(hwnd);
  SYSTEMTIME *lprgSysTimeArray = (SYSTEMTIME *)lParam;

  /* validate parameters */

  if((infoPtr==NULL) || (lprgSysTimeArray==NULL)) return FALSE;

  MONTHCAL_CopyTime(&infoPtr->maxDate, &lprgSysTimeArray[1]);
  MONTHCAL_CopyTime(&infoPtr->minDate, &lprgSysTimeArray[0]);

  return infoPtr->rangeValid;
}


static LRESULT
MONTHCAL_SetDayState(MONTHCAL_INFO *infoPtr, WPARAM wParam, LPARAM lParam)

{
  int i, iMonths = (int)wParam;
  MONTHDAYSTATE *dayStates = (LPMONTHDAYSTATE)lParam;

  TRACE("%x %lx\n", wParam, lParam);
  if(iMonths!=infoPtr->monthRange) return 0;

  for(i=0; i<iMonths; i++)
    infoPtr->monthdayState[i] = dayStates[i];
  return 1;
}

static LRESULT
MONTHCAL_GetCurSel(MONTHCAL_INFO *infoPtr, LPARAM lParam)
{
  SYSTEMTIME *lpSel = (SYSTEMTIME *) lParam;

  TRACE("%lx\n", lParam);
  if((infoPtr==NULL) ||(lpSel==NULL)) return FALSE;
  if(GetWindowLongW(infoPtr->hwndSelf, GWL_STYLE) & MCS_MULTISELECT) return FALSE;

  MONTHCAL_CopyTime(&infoPtr->minSel, lpSel);
  TRACE("%d/%d/%d\n", lpSel->wYear, lpSel->wMonth, lpSel->wDay);
  return TRUE;
}

/* FIXME: if the specified date is not visible, make it visible */
/* FIXME: redraw? */
static LRESULT
MONTHCAL_SetCurSel(MONTHCAL_INFO *infoPtr, LPARAM lParam)
{
  SYSTEMTIME *lpSel = (SYSTEMTIME *)lParam;

  TRACE("%lx\n", lParam);
  if((infoPtr==NULL) ||(lpSel==NULL)) return FALSE;
  if(GetWindowLongW(infoPtr->hwndSelf, GWL_STYLE) & MCS_MULTISELECT) return FALSE;

  infoPtr->currentMonth=lpSel->wMonth;
  infoPtr->currentYear=lpSel->wYear;

  MONTHCAL_CopyTime(lpSel, &infoPtr->minSel);
  MONTHCAL_CopyTime(lpSel, &infoPtr->maxSel);

  InvalidateRect(infoPtr->hwndSelf, NULL, FALSE);

  return TRUE;
}


static LRESULT
MONTHCAL_GetMaxSelCount(MONTHCAL_INFO *infoPtr)
{
  return infoPtr->maxSelCount;
}


static LRESULT
MONTHCAL_SetMaxSelCount(MONTHCAL_INFO *infoPtr, WPARAM wParam)
{
  TRACE("%x\n", wParam);

  if(GetWindowLongW(infoPtr->hwndSelf, GWL_STYLE) & MCS_MULTISELECT)  {
    infoPtr->maxSelCount = wParam;
  }

  return TRUE;
}


static LRESULT
MONTHCAL_GetSelRange(MONTHCAL_INFO *infoPtr, LPARAM lParam)
{
  SYSTEMTIME *lprgSysTimeArray = (SYSTEMTIME *) lParam;

  TRACE("%lx\n", lParam);

  /* validate parameters */

  if((infoPtr==NULL) ||(lprgSysTimeArray==NULL)) return FALSE;

  if(GetWindowLongW(infoPtr->hwndSelf, GWL_STYLE) & MCS_MULTISELECT)
  {
    MONTHCAL_CopyTime(&infoPtr->maxSel, &lprgSysTimeArray[1]);
    MONTHCAL_CopyTime(&infoPtr->minSel, &lprgSysTimeArray[0]);
    TRACE("[min,max]=[%d %d]\n", infoPtr->minSel.wDay, infoPtr->maxSel.wDay);
    return TRUE;
  }

  return FALSE;
}


static LRESULT
MONTHCAL_SetSelRange(MONTHCAL_INFO *infoPtr, LPARAM lParam)
{
  SYSTEMTIME *lprgSysTimeArray = (SYSTEMTIME *) lParam;

  TRACE("%lx\n", lParam);

  /* validate parameters */

  if((infoPtr==NULL) ||(lprgSysTimeArray==NULL)) return FALSE;

  if(GetWindowLongW(infoPtr->hwndSelf, GWL_STYLE) & MCS_MULTISELECT)
  {
    MONTHCAL_CopyTime(&lprgSysTimeArray[1], &infoPtr->maxSel);
    MONTHCAL_CopyTime(&lprgSysTimeArray[0], &infoPtr->minSel);
    TRACE("[min,max]=[%d %d]\n", infoPtr->minSel.wDay, infoPtr->maxSel.wDay);
    return TRUE;
  }

  return FALSE;
}


static LRESULT
MONTHCAL_GetToday(MONTHCAL_INFO *infoPtr, LPARAM lParam)
{
  SYSTEMTIME *lpToday = (SYSTEMTIME *) lParam;

  TRACE("%lx\n", lParam);

  /* validate parameters */

  if((infoPtr==NULL) || (lpToday==NULL)) return FALSE;
  MONTHCAL_CopyTime(&infoPtr->todaysDate, lpToday);
  return TRUE;
}


static LRESULT
MONTHCAL_SetToday(MONTHCAL_INFO *infoPtr, LPARAM lParam)
{
  SYSTEMTIME *lpToday = (SYSTEMTIME *) lParam;

  TRACE("%lx\n", lParam);

  /* validate parameters */

  if((infoPtr==NULL) ||(lpToday==NULL)) return FALSE;
  MONTHCAL_CopyTime(lpToday, &infoPtr->todaysDate);
  InvalidateRect(infoPtr->hwndSelf, NULL, FALSE);
  return TRUE;
}


static LRESULT
MONTHCAL_HitTest(MONTHCAL_INFO *infoPtr, LPARAM lParam)
{
  PMCHITTESTINFO lpht = (PMCHITTESTINFO)lParam;
  UINT x,y;
  DWORD retval;
  int day,wday,wnum;


  x = lpht->pt.x;
  y = lpht->pt.y;
  retval = MCHT_NOWHERE;

  ZeroMemory(&lpht->st, sizeof(lpht->st));

  /* Comment in for debugging...
  TRACE("%d %d wd[%d %d %d %d] d[%d %d %d %d] t[%d %d %d %d] wn[%d %d %d %d]\n", x, y,
	infoPtr->wdays.left, infoPtr->wdays.right,
	infoPtr->wdays.top, infoPtr->wdays.bottom,
	infoPtr->days.left, infoPtr->days.right,
	infoPtr->days.top, infoPtr->days.bottom,
	infoPtr->todayrect.left, infoPtr->todayrect.right,
	infoPtr->todayrect.top, infoPtr->todayrect.bottom,
	infoPtr->weeknums.left, infoPtr->weeknums.right,
	infoPtr->weeknums.top, infoPtr->weeknums.bottom);
  */

  /* are we in the header? */

  if(PtInRect(&infoPtr->title, lpht->pt)) {
    if(PtInRect(&infoPtr->titlebtnprev, lpht->pt)) {
      retval = MCHT_TITLEBTNPREV;
      goto done;
    }
    if(PtInRect(&infoPtr->titlebtnnext, lpht->pt)) {
      retval = MCHT_TITLEBTNNEXT;
      goto done;
    }
    if(PtInRect(&infoPtr->titlemonth, lpht->pt)) {
      retval = MCHT_TITLEMONTH;
      goto done;
    }
    if(PtInRect(&infoPtr->titleyear, lpht->pt)) {
      retval = MCHT_TITLEYEAR;
      goto done;
    }

    retval = MCHT_TITLE;
    goto done;
  }

  day = MONTHCAL_CalcDayFromPos(infoPtr,x,y,&wday,&wnum);
  if(PtInRect(&infoPtr->wdays, lpht->pt)) {
    retval = MCHT_CALENDARDAY;
    lpht->st.wYear  = infoPtr->currentYear;
    lpht->st.wMonth = (day < 1)? infoPtr->currentMonth -1 : infoPtr->currentMonth;
    lpht->st.wDay   = (day < 1)?
      MONTHCAL_MonthLength(infoPtr->currentMonth-1,infoPtr->currentYear) -day : day;
    goto done;
  }
  if(PtInRect(&infoPtr->weeknums, lpht->pt)) {
    retval = MCHT_CALENDARWEEKNUM;
    lpht->st.wYear  = infoPtr->currentYear;
    lpht->st.wMonth = (day < 1) ? infoPtr->currentMonth -1 :
      (day > MONTHCAL_MonthLength(infoPtr->currentMonth,infoPtr->currentYear)) ?
      infoPtr->currentMonth +1 :infoPtr->currentMonth;
    lpht->st.wDay   = (day < 1 ) ?
      MONTHCAL_MonthLength(infoPtr->currentMonth-1,infoPtr->currentYear) -day :
      (day > MONTHCAL_MonthLength(infoPtr->currentMonth,infoPtr->currentYear)) ?
      day - MONTHCAL_MonthLength(infoPtr->currentMonth,infoPtr->currentYear) : day;
    goto done;
  }
  if(PtInRect(&infoPtr->days, lpht->pt))
    {
      lpht->st.wYear  = infoPtr->currentYear;
      if ( day < 1)
	{
	  retval = MCHT_CALENDARDATEPREV;
	  lpht->st.wMonth = infoPtr->currentMonth - 1;
	  if (lpht->st.wMonth <1)
	    {
	      lpht->st.wMonth = 12;
	      lpht->st.wYear--;
	    }
	  lpht->st.wDay   = MONTHCAL_MonthLength(lpht->st.wMonth,lpht->st.wYear) -day;
	}
      else if (day > MONTHCAL_MonthLength(infoPtr->currentMonth,infoPtr->currentYear))
	{
	  retval = MCHT_CALENDARDATENEXT;
	  lpht->st.wMonth = infoPtr->currentMonth + 1;
	  if (lpht->st.wMonth <12)
	    {
	      lpht->st.wMonth = 1;
	      lpht->st.wYear++;
	    }

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?