⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 timedate.c

📁 一个类似windows
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 * PROJECT:     ReactOS Timedate Control Panel
 * LICENSE:     GPL - See COPYING in the top level directory
 * FILE:        lib/cpl/timedate/timedate.c
 * PURPOSE:     ReactOS Timedate Control Panel
 * COPYRIGHT:   Copyright 2004-2005 Eric Kohl
 *              Copyright 2006 Ged Murphy <gedmurphy@gmail.com>
 *              Copyright 2006 Christoph v. Wittich <Christoph@ActiveVB.de>
 *
 */

#include <timedate.h>

typedef struct _TZ_INFO
{
  LONG Bias;
  LONG StandardBias;
  LONG DaylightBias;
  SYSTEMTIME StandardDate;
  SYSTEMTIME DaylightDate;
} TZ_INFO, *PTZ_INFO;

typedef struct _TIMEZONE_ENTRY
{
  struct _TIMEZONE_ENTRY *Prev;
  struct _TIMEZONE_ENTRY *Next;
  WCHAR Description[64];   /* 'Display' */
  WCHAR StandardName[33];  /* 'Std' */
  WCHAR DaylightName[33];  /* 'Dlt' */
  TZ_INFO TimezoneInfo;    /* 'TZI' */
  ULONG Index;             /* 'Index ' */
} TIMEZONE_ENTRY, *PTIMEZONE_ENTRY;

typedef struct _SERVERS
{
    CHAR *Address;
    WCHAR *Name;
} SERVERS;


#define NUM_APPLETS    (1)

LONG APIENTRY
Applet(HWND hwnd, UINT uMsg, LONG wParam, LONG lParam);


HINSTANCE hApplet = 0;
BOOL bSynced = FALSE;

PTIMEZONE_ENTRY TimeZoneListHead = NULL;
PTIMEZONE_ENTRY TimeZoneListTail = NULL;


/* Applets */
APPLET Applets[NUM_APPLETS] =
{
  {IDC_CPLICON, IDS_CPLNAME, IDS_CPLDESCRIPTION, Applet}
};

static BOOL
SystemSetLocalTime(LPSYSTEMTIME lpSystemTime)
{
    HANDLE hToken;
    DWORD PrevSize;
    TOKEN_PRIVILEGES priv, previouspriv;
    BOOL Ret = FALSE;

    /*
     * Enable the SeSystemtimePrivilege privilege
     */

    if (OpenProcessToken(GetCurrentProcess(),
                         TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
                         &hToken))
    {
        priv.PrivilegeCount = 1;
        priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

        if (LookupPrivilegeValue(NULL,
                                 SE_SYSTEMTIME_NAME,
                                 &priv.Privileges[0].Luid))
        {
            if (AdjustTokenPrivileges(hToken,
                                      FALSE,
                                      &priv,
                                      sizeof(previouspriv),
                                      &previouspriv,
                                      &PrevSize) &&
                GetLastError() == ERROR_SUCCESS)
            {
                /*
                 * We successfully enabled it, we're permitted to change the system time
                 * Call SetLocalTime twice to ensure correct results
                 */
                Ret = SetLocalTime(lpSystemTime) &&
                      SetLocalTime(lpSystemTime);

                /*
                 * For the sake of security, restore the previous status again
                 */
                if (previouspriv.PrivilegeCount > 0)
                {
                    AdjustTokenPrivileges(hToken,
                                          FALSE,
                                          &previouspriv,
                                          0,
                                          NULL,
                                          0);
                }
            }
        }
        CloseHandle(hToken);
    }

    return Ret;
}


static VOID
SetLocalSystemTime(HWND hwnd)
{
    SYSTEMTIME Time;

    if (DateTime_GetSystemTime(GetDlgItem(hwnd,
                                          IDC_TIMEPICKER),
                               &Time) == GDT_VALID &&
        SendMessage(GetDlgItem(hwnd,
                               IDC_MONTHCALENDAR),
                    MCCM_GETDATE,
                    (WPARAM)&Time,
                    0))
    {
        SystemSetLocalTime(&Time);

        SetWindowLong(hwnd,
                      DWL_MSGRESULT,
                      PSNRET_NOERROR);

        SendMessage(GetDlgItem(hwnd,
                               IDC_MONTHCALENDAR),
                    MCCM_RESET,
                    (WPARAM)&Time,
                    0);

        /* broadcast the time change message */
        SendMessage(HWND_BROADCAST,
                    WM_TIMECHANGE,
                    0,
                    0);
    }
}


static VOID
SetTimeZoneName(HWND hwnd)
{
  TIME_ZONE_INFORMATION TimeZoneInfo;
  WCHAR TimeZoneString[128];
  WCHAR TimeZoneText[128];
  WCHAR TimeZoneName[128];
  DWORD TimeZoneId;

  TimeZoneId = GetTimeZoneInformation(&TimeZoneInfo);

  LoadStringW(hApplet, IDS_TIMEZONETEXT, TimeZoneText, 128);

  switch (TimeZoneId)
  {
    case TIME_ZONE_ID_STANDARD:
      wcscpy(TimeZoneName, TimeZoneInfo.StandardName);
      break;

    case TIME_ZONE_ID_DAYLIGHT:
      wcscpy(TimeZoneName, TimeZoneInfo.DaylightName);
      break;

    case TIME_ZONE_ID_UNKNOWN:
      LoadStringW(hApplet, IDS_TIMEZONEUNKNOWN, TimeZoneName, 128);
      break;

    case TIME_ZONE_ID_INVALID:
    default:
      LoadStringW(hApplet, IDS_TIMEZONEINVALID, TimeZoneName, 128);
      break;
  }

  wsprintfW(TimeZoneString, TimeZoneText, TimeZoneName);
  SendDlgItemMessageW(hwnd, IDC_TIMEZONE, WM_SETTEXT, 0, (LPARAM)TimeZoneString);
}


static VOID
FillMonthsComboBox(HWND hCombo)
{
    SYSTEMTIME LocalDate = {0};
    WCHAR szBuf[64];
    INT i;
    UINT Month;

    GetLocalTime(&LocalDate);

    SendMessage(hCombo,
                CB_RESETCONTENT,
                0,
                0);

    for (Month = 1;
         Month <= 13;
         Month++)
    {
        i = GetLocaleInfoW(LOCALE_USER_DEFAULT,
                           ((Month < 13) ? LOCALE_SMONTHNAME1 + Month - 1 : LOCALE_SMONTHNAME13),
                           szBuf,
                           sizeof(szBuf) / sizeof(szBuf[0]));
        if (i > 1)
        {
            i = (INT)SendMessage(hCombo,
                                 CB_ADDSTRING,
                                 0,
                                 (LPARAM)szBuf);
            if (i != CB_ERR)
            {
                SendMessage(hCombo,
                            CB_SETITEMDATA,
                            (WPARAM)i,
                            Month);

                if (Month == (UINT)LocalDate.wMonth)
                {
                    SendMessage(hCombo,
                                CB_SETCURSEL,
                                (WPARAM)i,
                                0);
                }
            }
        }
    }
}


static WORD
GetCBSelectedMonth(HWND hCombo)
{
    INT i;
    WORD Ret = (WORD)-1;

    i = (INT)SendMessage(hCombo,
                         CB_GETCURSEL,
                         0,
                         0);
    if (i != CB_ERR)
    {
        i = (INT)SendMessage(hCombo,
                             CB_GETITEMDATA,
                             (WPARAM)i,
                             0);

        if (i >= 1 && i <= 13)
            Ret = (WORD)i;
    }

    return Ret;
}


static VOID
ChangeMonthCalDate(HWND hMonthCal,
                   WORD Day,
                   WORD Month,
                   WORD Year)
{
    SendMessage(hMonthCal,
                MCCM_SETDATE,
                MAKEWPARAM(Day,
                           Month),
                MAKELPARAM(Year,
                           0));
}

static VOID
AutoUpdateMonthCal(HWND hwndDlg,
                   PNMMCCAUTOUPDATE lpAutoUpdate)
{
    /* update the controls */
    FillMonthsComboBox(GetDlgItem(hwndDlg,
                                  IDC_MONTHCB));
}


/* Property page dialog callback */
INT_PTR CALLBACK
DateTimePageProc(HWND hwndDlg,
         UINT uMsg,
         WPARAM wParam,
         LPARAM lParam)
{
  SYSTEMTIME st;
  GetLocalTime(&st);

  switch (uMsg)
  {
    case WM_INITDIALOG:
        FillMonthsComboBox(GetDlgItem(hwndDlg,
                                      IDC_MONTHCB));

        SetTimer(hwndDlg, ID_TIMER, 1000, NULL);

        /* set range and current year */
        SendMessage(GetDlgItem(hwndDlg, IDC_YEAR), UDM_SETRANGE, 0, MAKELONG ((short) 9999, (short) 1900));
        SendMessage(GetDlgItem(hwndDlg, IDC_YEAR), UDM_SETPOS, 0, MAKELONG( (short) st.wYear, 0));
#if 0
        InitClockWindowClass();
        CreateWindowExW(0,
                       L"ClockWndClass",
                       L"Clock",
                       WS_CHILD | WS_VISIBLE,
                       208, 14, 150, 150,
                       hwndDlg,
                       NULL,
                       hApplet,
                       NULL);
#endif
    break;

    case WM_TIMER:
    {
        SendMessage(GetDlgItem(hwndDlg, IDC_TIMEPICKER), DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM) &st); 
        break;
    }
    case WM_COMMAND:
    {
        switch (LOWORD(wParam))
        {
            case IDC_MONTHCB:
            {
                if (HIWORD(wParam) == CBN_SELCHANGE)
                {
                    ChangeMonthCalDate(GetDlgItem(hwndDlg,
                                                  IDC_MONTHCALENDAR),
                                       -1,
                                       GetCBSelectedMonth((HWND)lParam),
                                       -1);
                }
                break;
            }
        }
        break;
    }
    case WM_CTLCOLORSTATIC:
    {
        if ((HWND) lParam == GetDlgItem(hwndDlg, IDC_YEARTEXT))
            return (int) GetSysColorBrush(COLOR_WINDOW);
        break;
    }
    case WM_NOTIFY:
      {
          LPNMHDR lpnm = (LPNMHDR)lParam;

          switch (lpnm->idFrom)
          {
              case IDC_YEAR:
                  switch (lpnm->code)
                  {
				      case UDN_DELTAPOS:
                      {
                         short wYear;
                         LPNMUPDOWN updown = (LPNMUPDOWN) lpnm; 
                         wYear = SendMessage(GetDlgItem(hwndDlg, IDC_YEAR), UDM_GETPOS, 0, 0);
                          /* Enable the 'Apply' button */
                         PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
                         ChangeMonthCalDate(GetDlgItem(hwndDlg,
                                       IDC_MONTHCALENDAR),
                                       -1,
                                       -1,
                                       wYear + updown->iDelta);
                          break;
                      }
                  }
                  break;
              case IDC_TIMEPICKER:
                  switch (lpnm->code)
                  {
                      case DTN_DATETIMECHANGE:
                          /* Enable the 'Apply' button */
                          PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
                          break;
                  }
                  break;

              case IDC_MONTHCALENDAR:
                  switch (lpnm->code)
                  {
                      case MCCN_SELCHANGE:
                          /* Enable the 'Apply' button */
                          PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
                          break;

                      case MCCN_AUTOUPDATE:
                          AutoUpdateMonthCal(hwndDlg,
                                             (PNMMCCAUTOUPDATE)lpnm);
                          break;
                  }
                  break;

              default:
                  switch (lpnm->code)
                  {
                      case PSN_SETACTIVE:
                          SetTimeZoneName(hwndDlg);
                          break;

                      case PSN_APPLY:
                          SetLocalSystemTime(hwndDlg);
                          return TRUE;
                  }
          }
      }
      break;

    case WM_TIMECHANGE:
    {
        /* FIXME - we don't get this message as we're not a top-level window... */
        SendMessage(GetDlgItem(hwndDlg,
                               IDC_MONTHCALENDAR),
                    MCCM_RESET,
                    0,
                    0);
        break;
    }
    case WM_DESTROY:
    {
        KillTimer(hwndDlg, ID_TIMER);
        break;
    }
  }

  return FALSE;
}




static PTIMEZONE_ENTRY
GetLargerTimeZoneEntry(DWORD Index)
{
  PTIMEZONE_ENTRY Entry;

  Entry = TimeZoneListHead;
  while (Entry != NULL)
    {
      if (Entry->Index >= Index)
    return Entry;

      Entry = Entry->Next;
    }

  return NULL;
}


static VOID
CreateTimeZoneList(VOID)
{
  WCHAR szKeyName[256];
  DWORD dwIndex;
  DWORD dwNameSize;
  DWORD dwValueSize;
  LONG lError;
  HKEY hZonesKey;
  HKEY hZoneKey;

  PTIMEZONE_ENTRY Entry;
  PTIMEZONE_ENTRY Current;

  if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
            L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones",
            0,
            KEY_ENUMERATE_SUB_KEYS,
            &hZonesKey))
    return;

  dwIndex = 0;
  while (TRUE)
    {
      dwNameSize = 256;
      lError = RegEnumKeyExW(hZonesKey,
                 dwIndex,
                 szKeyName,
                 &dwNameSize,
                 NULL,
                 NULL,
                 NULL,
                 NULL);
      if (lError != ERROR_SUCCESS && lError != ERROR_MORE_DATA)
    break;

      if (RegOpenKeyExW(hZonesKey,
            szKeyName,
            0,
            KEY_QUERY_VALUE,
            &hZoneKey))
    break;

      Entry = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(TIMEZONE_ENTRY));
      if (Entry == NULL)
      {
      RegCloseKey(hZoneKey);
      break;
    }

      dwValueSize = 64 * sizeof(WCHAR);
      if (RegQueryValueExW(hZoneKey,
               L"Display",
               NULL,
               NULL,
               (LPBYTE)&Entry->Description,
               &dwValueSize))
    {
      RegCloseKey(hZoneKey);
      break;
    }

      dwValueSize = 33 * sizeof(WCHAR);
      if (RegQueryValueExW(hZoneKey,
               L"Std",
               NULL,
               NULL,
               (LPBYTE)&Entry->StandardName,
               &dwValueSize))
    {
      RegCloseKey(hZoneKey);
      break;
    }

      dwValueSize = 33 * sizeof(WCHAR);
      if (RegQueryValueExW(hZoneKey,
               L"Dlt",
               NULL,
               NULL,
               (LPBYTE)&Entry->DaylightName,
               &dwValueSize))
    {
      RegCloseKey(hZoneKey);
      break;
    }

      dwValueSize = sizeof(DWORD);
      if (RegQueryValueExW(hZoneKey,
               L"Index",
               NULL,
               NULL,
               (LPBYTE)&Entry->Index,
               &dwValueSize))
    {
      RegCloseKey(hZoneKey);
      break;
    }

      dwValueSize = sizeof(TZ_INFO);
      if (RegQueryValueExW(hZoneKey,
               L"TZI",
               NULL,
               NULL,
               (LPBYTE)&Entry->TimezoneInfo,
               &dwValueSize))
    {
      RegCloseKey(hZoneKey);
      break;
    }

      RegCloseKey(hZoneKey);

      if (TimeZoneListHead == NULL &&
      TimeZoneListTail == NULL)
    {
      Entry->Prev = NULL;
      Entry->Next = NULL;
      TimeZoneListHead = Entry;

⌨️ 快捷键说明

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