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

📄 dst.cpp

📁 该代码压缩包只为需要研究CE下的任务管理器的实现而提供的。某些通用的头文件没有包含在其中
💻 CPP
📖 第 1 页 / 共 2 页
字号:
    switch (g_dwTime)
    {
        case TIME_ZONE_ID_DAYLIGHT :
            DEBUGMSG(ZONE_DST, ( _T("DST:  Currently in Daylight Time")));
            notificationTime = tzi.StandardDate;
        break;

        case TIME_ZONE_ID_STANDARD :
            DEBUGMSG(ZONE_DST, ( _T("DST:  Currently in Standard Time")));
            notificationTime = tzi.DaylightDate;
        break;

        default :
            DEBUGMSG(ZONE_DST, (_T("DST:  Unknown TimeZone")));
            ASSERT(TIME_ZONE_ID_UNKNOWN == dwTZ);    //otherwise GetTZInfo is busted
            return NULL;
    }

    if (0 == notificationTime.wYear) //no specific date set - do the math
        DST_DetermineChangeDate(&notificationTime);

    //only set events that are in the future
    VERIFY(SystemTimeToFileTime(&notificationTime, (FILETIME *)&llNotification));
    GetLocalTime(&curTime);
    VERIFY(SystemTimeToFileTime(&curTime, (FILETIME *)&llNow));
    if (llNotification > llNow)
    {
        hEvent = CreateEvent(NULL, FALSE, FALSE, DSTEVENT);
        if (hEvent != INVALID_HANDLE_VALUE)
        {
            if (!CeRunAppAtTime(DSTNOTIFICATION, &notificationTime))
            {
               CloseHandle(hEvent);
               hEvent = NULL;
            }
        }

        DEBUGMSG(ZONE_DST, (_T("DST:  Set TimeChange Event for %d/%d/%02d at %d:%02d"), 
                 notificationTime.wMonth, notificationTime.wDay, notificationTime.wYear,
                 notificationTime.wHour, notificationTime.wMinute));
    }

    return hEvent;
}


/*++
Routine Description:
    waits for DST event to be signaled, and optionally re-sets the
    time as appropriate.
    
Arguments:
    hEvent - handle to DST event
    
Return Value:
    none
    
--*/
void DST_WaitForEvents(LPHANDLE DST_handles)
{
    // The last event can be NULL if we so check before we give the number of handles
    DWORD dwEvent = WaitForMultipleObjects(DST_handles[NUMDSTEVENTS-1] ? NUMDSTEVENTS : NUMDSTEVENTS-1,
                                           DST_handles, FALSE, INFINITE);

    // returning from this function causes DST_Init to reset all of our events
    // so we need to turn everything off
    CeRunAppAtEvent(DSTTIMEZONENOTIFICATION, NOTIFICATION_EVENT_NONE);
    CeRunAppAtEvent(DSTTIMENOTIFICATION, NOTIFICATION_EVENT_NONE);
    CeRunAppAtTime(DSTNOTIFICATION, 0);

    // and ditch the handles
    for (int i = 0; i < NUMDSTEVENTS; i++)
    {
        if (NULL != DST_handles[i])
        {
            CloseHandle(DST_handles[i]);
            DST_handles[i] = NULL;
        }
    }

    switch (dwEvent - WAIT_OBJECT_0)
    {
        case TZCHANGEEVENT :
        case TIMECHANGEEVENT :
        {
            // need to redetermine whether we are in daylight or standard time
            DEBUGMSG(ZONE_DST, (_T("Resetting DST event due to Time, Date, or TZ change")));
            DST_SetDaylightOrStandardTime();
        }
        break;

        case DSTCHANGEEVENT :
        {
            if (DST_Auto())
            {
                SYSTEMTIME stOld, stNew;
                LONGLONG llOld, llNew;

#ifndef TASKMANDSTSAMPLE                
                TCHAR msg[MAX_DSTMSGLEN];
                TCHAR title[MAX_DSTTITLELEN];
#endif //TASKMANDSTSAMPLE

                GetLocalTime(&stOld); 
                SystemTimeToFileTime(&stOld, (FILETIME *)&llOld);

                /*
                    Check the time zone information.  It's possible that this information has
                    changed since the GetTimeZoneInformation call in DST_SetEvent, and
                    this action needs to be based on the current timezone.
                */
                TIME_ZONE_INFORMATION tzi = {0};
                GetTimeZoneInformation(&tzi);

                /*
                    If we're going from Daylight to Standard, we need to move the 
                    clock BACK by g_tzDSTBias (60 minutes usually).  If we're going 
                    from Standard to Daylight we need to move it forward even though
                    g_tzDSTBias is 0.
                */ 
                if (TIME_ZONE_ID_DAYLIGHT == g_dwTime) // clock needs to go back - so we add (g_tzDSTBias is always negative)
                {
                    llNew = llOld + (LONGLONG)((LONGLONG)tzi.DaylightBias * FILETIME_TO_MINUTES);
                    // now flip the time flag  because we're just about to change
                    g_dwTime = TIME_ZONE_ID_STANDARD;
                    SetDaylightTime(FALSE);
                }
                else // clock needs to go forward - so we subtract (see above)
                {
                    llNew = llOld - (LONGLONG)((LONGLONG)tzi.DaylightBias * FILETIME_TO_MINUTES);
                    // now flip the time flag  because we're just about to change
                    g_dwTime = TIME_ZONE_ID_DAYLIGHT;
                    SetDaylightTime(TRUE);
                }

                FileTimeToSystemTime((FILETIME *)&llNew, &stNew);

                
                DEBUGMSG(ZONE_DST, (L"TZ Change: Updating clock. Old Time =%d:%02d, New Time =%d:%02d\r\n", 
                                stOld.wHour, stOld.wMinute, stNew.wHour, stNew.wMinute));

                SetLocalTime(&stNew);

#ifndef TASKMANDSTSAMPLE                    
                if (DST_ShowMessage())
                {
                    if (LoadString(hInst, IDS_DSTCHANGED, msg, MAX_DSTMSGLEN) &&
                       LoadString(hInst, IDS_DSTTIMEINFO, title, MAX_DSTTITLELEN))
                    {
                       MessageBox(GetForegroundWindow(), msg, title, MB_OK);
                    }
                }
#endif // TASKMANDSTSAMPLE
            }
        }
        break;
        default :
        {
            DEBUGMSG(ZONE_DST, (_T("unexpected value returned from WaitForMultipleObjects")));
            DEBUGCHK(0);
        }
    }
}   


/*++
Routine Description:
    Determines real date that DST starts based on
    systemtime struct returned from GetTimeZoneInfo
    
Arguments:
    pointer to SYSTEMTIME structure
    
Return Value:
    TRUE if successful
    
--*/
BOOL DST_DetermineChangeDate(LPSYSTEMTIME pst)
{
    static BOOL bReEntered = FALSE;
    BOOL bRetval = FALSE;
    ASSERT(pst);
    if (NULL == pst)
        return bRetval;

    LONGLONG  llChangeDate = 0, llNow = 0;

    //  yes - February can have 29 days, but as of 6/01, no country changes dst in Feb, 
    //  and certainly no one would change on the last day of February
    static const int lastDayOfMonth[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };

    SYSTEMTIME st;
    GetLocalTime(&st);

    // build up the new structure
    if (pst->wYear == 0)
        pst->wYear = st.wYear;

    //look for daylight date
    switch (pst->wDay)
    {
        bRetval = TRUE;
        case FIRST_OF_MONTH :
        {
            //Day
            pst->wDay = 1;  //
            int day = DowFromDate(pst);
            if (day)
            {
                 pst->wDay = (8 - day) ;
            }
            //else the first is xxxday - nothing to do since wDay is already 1
            break;
        }
      
        case LAST_OF_MONTH :
        {
            //Day
            pst->wDay = lastDayOfMonth[pst->wMonth + 1];
            int day = DowFromDate(pst);
            pst->wDay = (pst->wDay - day) +pst->wDayOfWeek;
            break;
        }
        default :
            DEBUGCHK(_T("Unknown DST Format"));
            bRetval = FALSE;
    }

     // Need to determine if the next occurrance of this date is THIS year or NEXT year
    VERIFY(SystemTimeToFileTime(pst, (FILETIME *)&llChangeDate));
    VERIFY(SystemTimeToFileTime(&st, (FILETIME *)&llNow));

    //do we switch after Jan 1?
    if (!bReEntered && (llChangeDate < llNow))
    {
        bReEntered = TRUE;
        //need to redetermine the date for next year
        pst->wYear++;
        DST_DetermineChangeDate(pst);
    }
    bReEntered = FALSE;
    return bRetval;    
}




/*++
Routine Description:
    Find the day of the week the indicated month begins on
    
Arguments:
    yr        year, must be > 0
    mo        month, number 1-12
    
Return Value:
    day of the week (0-6) on which the month begins
         (0 = Sunday, 1 = Monday etc.)
    
--*/
int GetStartDowForMonth(int yr, int mo)
{
    int dow;

    // we want monday = 0, sunday = 6
    // dow = 6 + (yr - 1) + ((yr - 1) >> 2);
    dow = 5 + (yr - 1) + ((yr - 1) >> 2);
    if (yr > 1752)
        dow += ((yr - 1) - 1600) / 400 - ((yr - 1) - 1700) / 100 - 11;
    else if (yr == 1752 && mo > 9)
        dow -= 11;
    dow += AccumDaysByMonth[mo - 1];
    if (mo > 2 && (yr & 03) == 0 && (yr <= 1750 || yr % 100 != 0 || yr % 400 == 0))
        dow++;
    dow %= 7;

    return dow;
}


/*++
Routine Description:
    determines the day of week based on information in a SYSTEMTIME struct
    
Arguments:
    pointer to a SYSTEMTIME  struct
    
Return Value:
    0 based day of week based on systemtime struct
    
--*/
int DowFromDate(SYSTEMTIME *pst)
{
    int dow;

    ASSERT(pst);
    dow = GetStartDowForMonth(pst->wYear, pst->wMonth);
    dow = (dow + pst->wDay) % 7;

    return dow;
}

/*++
Routine Description:
    determines if the current locale supports DST based on
    information in a TIME_ZONE_INFORMATION struct
    
Arguments:
    pointer to a TIME_ZONE_INFORMATION  struct
    
Return Value:
    TRUE if the locale supports DST, FALSE otherwise
    
--*/
BOOL LocaleSupportsDST(TIME_ZONE_INFORMATION *ptzi)
{
    ASSERT(ptzi);

    // If the month value is zero then this locale does not change for DST
    // it should never be the case that we have a DST date but not a SDT date
    ASSERT(((0 != ptzi->StandardDate.wMonth) && (0 != ptzi->DaylightDate.wMonth)) ||
           ((0 == ptzi->StandardDate.wMonth) && (0 == ptzi->DaylightDate.wMonth)));

    if ((0 != ptzi->StandardDate.wMonth) && (0 != ptzi->DaylightDate.wMonth))
        return TRUE;
    else
        return FALSE;
}

#endif  //NODSTSAMPLE

⌨️ 快捷键说明

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