wintime.cpp
上传用户:center1979
上传日期:2022-07-26
资源大小:50633k
文件大小:9k
源码类别:

OpenGL

开发平台:

Visual C++

  1. // wintime.cpp
  2. //
  3. // Copyright (C) 2005, Chris Laurel <claurel@shatters.net>
  4. //
  5. // Win32 set time dialog box for Celestia
  6. //
  7. // This program is free software; you can redistribute it and/or
  8. // modify it under the terms of the GNU General Public License
  9. // as published by the Free Software Foundation; either version 2
  10. // of the License, or (at your option) any later version.
  11. #include "wintime.h"
  12. #include <windows.h>
  13. #include <winuser.h>
  14. #include <commctrl.h>
  15. #include <time.h>
  16. #include "res/resource.h"
  17. #include <celengine/astro.h>
  18. #include "celutil/util.h"
  19. #include "celutil/winutil.h"
  20. class SetTimeDialog
  21. {
  22. public:
  23.     SetTimeDialog(CelestiaCore*);
  24.     ~SetTimeDialog();
  25.     void init(HWND _hDlg);
  26.     double getTime() const;
  27.     void setTime(const double _tdb);
  28.     
  29.     void updateControls();
  30.     
  31.     LRESULT command(WPARAM wParam, LPARAM lParam);
  32.     LRESULT notify(int id, const NMHDR& nmhdr);
  33.     
  34. private:
  35.     HWND hDlg;
  36.     CelestiaCore* appCore;
  37.     double tdb;
  38.     bool useLocalTime;
  39.     bool useUTCOffset;
  40.     int localTimeZoneBiasInSeconds;
  41.     
  42.     void getLocalTimeZoneInfo();
  43. };
  44. SetTimeDialog::SetTimeDialog(CelestiaCore* _appCore) :
  45.     hDlg(0),
  46.     appCore(_appCore),
  47.     tdb(astro::J2000),
  48.     useLocalTime(false),
  49.     useUTCOffset(false),
  50.     localTimeZoneBiasInSeconds(0)
  51. {
  52. }
  53. SetTimeDialog::~SetTimeDialog()
  54. {
  55. }
  56. static void acronymify(char* words, int length)
  57. {
  58.     int n = 0;
  59.     char lastChar = ' ';
  60.     for (int i = 0; i < length; i++)
  61.     {
  62.         if (lastChar == ' ')
  63.             words[n++] = words[i];
  64.         lastChar = words[i];
  65.     }
  66.     words[n] = '';
  67. }
  68. void
  69. SetTimeDialog::init(HWND _hDlg)
  70. {
  71.     hDlg = _hDlg;
  72.     
  73.     SetWindowLong(hDlg, DWL_USER, reinterpret_cast<LPARAM>(this));
  74.     getLocalTimeZoneInfo();
  75.     tdb = appCore->getSimulation()->getTime();
  76.     useLocalTime = appCore->getTimeZoneBias() != 0;
  77.     useUTCOffset = appCore->getDateFormat() == 2;
  78.     bind_textdomain_codeset("celestia", CurrentCP());
  79.     SendDlgItemMessage(hDlg, IDC_COMBOBOX_TIMEZONE, CB_ADDSTRING, 0, (LPARAM) _("Universal Time"));
  80.     SendDlgItemMessage(hDlg, IDC_COMBOBOX_TIMEZONE, CB_ADDSTRING, 0, (LPARAM) _("Local Time"));
  81.     SendDlgItemMessage(hDlg, IDC_COMBOBOX_DATE_FORMAT, CB_ADDSTRING, 0, (LPARAM) _("Time Zone Name"));
  82.     SendDlgItemMessage(hDlg, IDC_COMBOBOX_DATE_FORMAT, CB_ADDSTRING, 0, (LPARAM) _("UTC Offset"));
  83.     bind_textdomain_codeset("celestia", "UTF8");
  84.     
  85.     SendDlgItemMessage(hDlg, IDC_COMBOBOX_TIMEZONE, CB_SETCURSEL, useLocalTime ? 1 : 0, 0);
  86.     SendDlgItemMessage(hDlg, IDC_COMBOBOX_DATE_FORMAT, CB_SETCURSEL, useUTCOffset ? 1 : 0, 0);
  87.     EnableWindow (GetDlgItem (hDlg, IDC_COMBOBOX_DATE_FORMAT), useLocalTime);
  88.     updateControls();
  89. }
  90. void
  91. SetTimeDialog::getLocalTimeZoneInfo()
  92. {
  93.     TIME_ZONE_INFORMATION tzi;
  94.     DWORD dst = GetTimeZoneInformation(&tzi);
  95.     if (dst != TIME_ZONE_ID_INVALID)
  96.     {
  97.         WCHAR* tzName = NULL;
  98.         LONG dstBias = 0;
  99.         if (dst == TIME_ZONE_ID_STANDARD)
  100.         {
  101.             dstBias = tzi.StandardBias;
  102.             tzName = tzi.StandardName;
  103.         }
  104.         else if (dst == TIME_ZONE_ID_DAYLIGHT)
  105.         {
  106.             dstBias = tzi.DaylightBias;
  107.             tzName = tzi.DaylightName;
  108.         }
  109.         localTimeZoneBiasInSeconds = (tzi.Bias + dstBias) * -60;
  110.     }
  111. }
  112. double
  113. SetTimeDialog::getTime() const
  114. {
  115.     return tdb;
  116. }
  117. void
  118. SetTimeDialog::setTime(double _tdb)
  119. {
  120.     tdb = _tdb;
  121. }
  122. void
  123. SetTimeDialog::updateControls()
  124. {
  125.     HWND timeItem = NULL;
  126.     HWND dateItem = NULL;
  127.     HWND jdItem = NULL;
  128.     SYSTEMTIME sysTime;
  129.     double tztdb = tdb;
  130.     if (useLocalTime)
  131.         tztdb += localTimeZoneBiasInSeconds / 86400.0;
  132.         
  133.     astro::Date newTime = astro::TDBtoUTC(tztdb);
  134.     
  135.     sysTime.wYear = newTime.year;
  136.     sysTime.wMonth = newTime.month;
  137.     sysTime.wDay = newTime.day;
  138.     sysTime.wDayOfWeek = ((int) ((double) newTime + 0.5) + 1) % 7;
  139.     sysTime.wHour = newTime.hour;
  140.     sysTime.wMinute = newTime.minute;
  141.     sysTime.wSecond = (int) newTime.seconds;
  142.     sysTime.wMilliseconds = 0;
  143.     dateItem = GetDlgItem(hDlg, IDC_DATEPICKER);
  144.     if (dateItem != NULL)
  145.     {
  146.         DateTime_SetFormat(dateItem, "dd' 'MMM' 'yyy");
  147.         DateTime_SetSystemtime(dateItem, GDT_VALID, &sysTime);
  148.     }
  149.     timeItem = GetDlgItem(hDlg, IDC_TIMEPICKER);
  150.     if (timeItem != NULL)
  151.     {
  152.         char timeFormat[256];
  153.         sprintf(timeFormat, "HH':'mm':'ss");
  154.         DateTime_SetFormat(timeItem, timeFormat);
  155.         DateTime_SetSystemtime(timeItem, GDT_VALID, &sysTime);
  156.     }
  157.     jdItem = GetDlgItem(hDlg, IDC_JDPICKER);
  158.     if (jdItem != NULL)
  159.     {
  160.         char jd[16];
  161.         sprintf(jd, "%0.5f", astro::TAItoJDUTC(astro::TTtoTAI(astro::TDBtoTT(tdb))));
  162.         SetWindowText(GetDlgItem(hDlg, IDC_JDPICKER), jd);
  163.     }
  164. }
  165. LRESULT
  166. SetTimeDialog::command(WPARAM wParam, LPARAM lParam)
  167. {
  168.     switch (LOWORD(wParam))
  169.     {
  170.         case IDOK:
  171.             appCore->tick();
  172.             appCore->getSimulation()->setTime(tdb);
  173.             appCore->setTimeZoneBias(useLocalTime ? 1 : 0);
  174.             appCore->setDateFormat((astro::Date::Format) (useLocalTime && useUTCOffset ? 2 : 1));
  175.             EndDialog(hDlg, 0);
  176.             return TRUE;
  177.             
  178.         case IDCANCEL:
  179.             EndDialog(hDlg, 0);
  180.             return TRUE;
  181.     
  182.         case IDC_SETCURRENTTIME:
  183.             // Set time to the current system time
  184.             setTime(astro::UTCtoTDB((double) time(NULL) / 86400.0 + (double) astro::Date(1970, 1, 1)));
  185.             updateControls();
  186.             return TRUE;
  187.             
  188.         case IDC_COMBOBOX_TIMEZONE:
  189.             if (HIWORD(wParam) == CBN_SELCHANGE)
  190.             {
  191.                 LRESULT selection = SendMessage((HWND) lParam, CB_GETCURSEL, 0, 0);
  192.                 useLocalTime = (selection == 1);
  193.                 EnableWindow (GetDlgItem (hDlg, IDC_COMBOBOX_DATE_FORMAT), useLocalTime);
  194.                 updateControls();
  195.             }
  196.             return TRUE;          
  197.         case IDC_COMBOBOX_DATE_FORMAT:
  198.             if (HIWORD(wParam) == CBN_SELCHANGE)
  199.             {
  200.                 LRESULT selection = SendMessage((HWND) lParam, CB_GETCURSEL, 0, 0);
  201.                 useUTCOffset = (selection == 1);
  202.                 updateControls();
  203.             }
  204.             return TRUE;  
  205.         case IDC_JDPICKER:
  206.             if (HIWORD(wParam) == EN_KILLFOCUS)
  207.             {
  208.                 char jd[16];
  209.                 GetWindowText(GetDlgItem(hDlg, IDC_JDPICKER), jd, sizeof(jd));
  210.                 tdb = astro::TTtoTDB(astro::TAItoTT(astro::JDUTCtoTAI(atof(jd))));
  211.                 updateControls();
  212.             }
  213.             return TRUE;
  214.         default:
  215.             return FALSE;
  216.     }
  217. }
  218. LRESULT
  219. SetTimeDialog::notify(int id, const NMHDR& hdr)
  220. {
  221.     astro::Date newTime(tdb);
  222.     
  223.     if (hdr.code == DTN_DATETIMECHANGE)
  224.     {
  225.         LPNMDATETIMECHANGE change = (LPNMDATETIMECHANGE) &hdr;
  226.         if (change->dwFlags == GDT_VALID)
  227.         {
  228.             if (id == IDC_DATEPICKER || id == IDC_TIMEPICKER)
  229.             {
  230.                 SYSTEMTIME sysTime;
  231.                 SYSTEMTIME sysDate;
  232.                 DateTime_GetSystemtime(GetDlgItem(hDlg, IDC_TIMEPICKER), &sysTime);
  233.                 DateTime_GetSystemtime(GetDlgItem(hDlg, IDC_DATEPICKER), &sysDate);
  234.                 newTime.year = (int16) sysDate.wYear;
  235.                 newTime.month = sysDate.wMonth;
  236.                 newTime.day = sysDate.wDay;
  237.                 newTime.hour = sysTime.wHour;
  238.                 newTime.minute = sysTime.wMinute;
  239.                 newTime.seconds = sysTime.wSecond + (double) sysTime.wMilliseconds / 1000.0;
  240.                 
  241.                 tdb = astro::UTCtoTDB(newTime);
  242.                 if (useLocalTime)
  243.                     tdb -= localTimeZoneBiasInSeconds / 86400.0;
  244.                 updateControls();
  245.             }
  246.         }
  247.     }
  248.         
  249.     return TRUE;
  250. }
  251. static BOOL APIENTRY 
  252. SetTimeProc(HWND hDlg,
  253.             UINT message,
  254.             UINT wParam,
  255.             LONG lParam)
  256. {
  257.     SetTimeDialog* timeDialog = reinterpret_cast<SetTimeDialog*>(GetWindowLong(hDlg, DWL_USER));
  258.     switch (message)
  259.     {
  260.     case WM_INITDIALOG:
  261.         {
  262.             timeDialog = reinterpret_cast<SetTimeDialog*>(lParam);
  263.             if (timeDialog == NULL)
  264.                 return EndDialog(hDlg, 0);
  265.             timeDialog->init(hDlg);
  266.         }
  267.         return TRUE;
  268.     case WM_COMMAND:
  269.         return timeDialog->command(wParam, lParam);
  270.         
  271.     case WM_NOTIFY:
  272.         return timeDialog->notify((int) wParam, *reinterpret_cast<NMHDR*>(lParam));
  273.     }
  274.     return FALSE;
  275. }
  276. void
  277. ShowSetTimeDialog(HINSTANCE appInstance,
  278.                   HWND appWindow,
  279.                   CelestiaCore* appCore)
  280. {
  281.     SetTimeDialog* timeDialog = new SetTimeDialog(appCore);
  282.     
  283.     DialogBoxParam(appInstance, MAKEINTRESOURCE(IDD_SETTIME), appWindow, SetTimeProc, reinterpret_cast<LPARAM>(timeDialog));
  284.     
  285.     delete timeDialog;
  286. }