ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

timezone.c
Go to the documentation of this file.
00001 /*
00002  * PROJECT:     ReactOS Timedate Control Panel
00003  * LICENSE:     GPL - See COPYING in the top level directory
00004  * FILE:        dll/cpl/timedate/timezone.c
00005  * PURPOSE:     Time Zone property page
00006  * COPYRIGHT:   Copyright 2004-2005 Eric Kohl
00007  *              Copyright 2006 Ged Murphy <gedmurphy@gmail.com>
00008  *              Copyright 2006 Christoph v. Wittich <Christoph@ActiveVB.de>
00009  *
00010  */
00011 
00012 #include <timedate.h>
00013 
00014 typedef struct _TZ_INFO
00015 {
00016     LONG Bias;
00017     LONG StandardBias;
00018     LONG DaylightBias;
00019     SYSTEMTIME StandardDate;
00020     SYSTEMTIME DaylightDate;
00021 } TZ_INFO, *PTZ_INFO;
00022 
00023 typedef struct _TIMEZONE_ENTRY
00024 {
00025     struct _TIMEZONE_ENTRY *Prev;
00026     struct _TIMEZONE_ENTRY *Next;
00027     WCHAR Description[64];   /* 'Display' */
00028     WCHAR StandardName[33];  /* 'Std' */
00029     WCHAR DaylightName[33];  /* 'Dlt' */
00030     TZ_INFO TimezoneInfo;    /* 'TZI' */
00031     ULONG Index;             /* 'Index ' */
00032 } TIMEZONE_ENTRY, *PTIMEZONE_ENTRY;
00033 
00034 
00035 static HBITMAP hBitmap = NULL;
00036 static int cxSource, cySource;
00037 
00038 PTIMEZONE_ENTRY TimeZoneListHead = NULL;
00039 PTIMEZONE_ENTRY TimeZoneListTail = NULL;
00040 
00041 static PTIMEZONE_ENTRY
00042 GetLargerTimeZoneEntry(DWORD Index)
00043 {
00044     PTIMEZONE_ENTRY Entry;
00045 
00046     Entry = TimeZoneListHead;
00047     while (Entry != NULL)
00048     {
00049         if (Entry->Index >= Index)
00050             return Entry;
00051 
00052         Entry = Entry->Next;
00053     }
00054 
00055     return NULL;
00056 }
00057 
00058 
00059 static VOID
00060 CreateTimeZoneList(VOID)
00061 {
00062     WCHAR szKeyName[256];
00063     DWORD dwIndex;
00064     DWORD dwNameSize;
00065     DWORD dwValueSize;
00066     LONG lError;
00067     HKEY hZonesKey;
00068     HKEY hZoneKey;
00069 
00070     PTIMEZONE_ENTRY Entry;
00071     PTIMEZONE_ENTRY Current;
00072 
00073     if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
00074                       L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones",
00075                       0,
00076                       KEY_ENUMERATE_SUB_KEYS,
00077                       &hZonesKey))
00078         return;
00079 
00080     dwIndex = 0;
00081     while (TRUE)
00082     {
00083         dwNameSize = 256 * sizeof(WCHAR);
00084         lError = RegEnumKeyExW(hZonesKey,
00085                                dwIndex,
00086                                szKeyName,
00087                                &dwNameSize,
00088                                NULL,
00089                                NULL,
00090                                NULL,
00091                                NULL);
00092         if (lError == ERROR_NO_MORE_ITEMS)
00093             break;
00094 
00095         if (RegOpenKeyEx (hZonesKey,
00096                           szKeyName,
00097                           0,
00098                           KEY_QUERY_VALUE,
00099                           &hZoneKey))
00100             break;
00101 
00102         Entry = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(TIMEZONE_ENTRY));
00103         if (Entry == NULL)
00104         {
00105             RegCloseKey(hZoneKey);
00106             break;
00107         }
00108 
00109         dwValueSize = 64 * sizeof(WCHAR);
00110         lError = RegQueryValueExW(hZoneKey,
00111                              L"Display",
00112                              NULL,
00113                              NULL,
00114                              (LPBYTE)&Entry->Description,
00115                              &dwValueSize);
00116         if (lError != ERROR_SUCCESS)
00117         {
00118             RegCloseKey(hZoneKey);
00119             dwIndex++;
00120             HeapFree(GetProcessHeap(), 0, Entry);
00121             continue;
00122         }
00123 
00124         dwValueSize = 33 * sizeof(WCHAR);
00125         if (RegQueryValueExW(hZoneKey,
00126                              L"Std",
00127                              NULL,
00128                              NULL,
00129                              (LPBYTE)&Entry->StandardName,
00130                              &dwValueSize))
00131         {
00132             RegCloseKey(hZoneKey);
00133             break;
00134         }
00135 
00136         dwValueSize = 33 * sizeof(WCHAR);
00137         if (RegQueryValueExW(hZoneKey,
00138                              L"Dlt",
00139                              NULL,
00140                              NULL,
00141                              (LPBYTE)&Entry->DaylightName,
00142                              &dwValueSize))
00143         {
00144             RegCloseKey(hZoneKey);
00145             break;
00146         }
00147 
00148         dwValueSize = sizeof(DWORD);
00149         if (RegQueryValueExW(hZoneKey,
00150                              L"Index",
00151                              NULL,
00152                              NULL,
00153                              (LPBYTE)&Entry->Index,
00154                              &dwValueSize))
00155         {
00156             RegCloseKey(hZoneKey);
00157             break;
00158         }
00159 
00160         dwValueSize = sizeof(TZ_INFO);
00161         if (RegQueryValueExW(hZoneKey,
00162                              L"TZI",
00163                              NULL,
00164                              NULL,
00165                              (LPBYTE)&Entry->TimezoneInfo,
00166                              &dwValueSize))
00167         {
00168             RegCloseKey(hZoneKey);
00169             break;
00170         }
00171 
00172         RegCloseKey(hZoneKey);
00173 
00174         if (TimeZoneListHead == NULL &&
00175             TimeZoneListTail == NULL)
00176         {
00177             Entry->Prev = NULL;
00178             Entry->Next = NULL;
00179             TimeZoneListHead = Entry;
00180             TimeZoneListTail = Entry;
00181         }
00182         else
00183         {
00184             Current = GetLargerTimeZoneEntry(Entry->Index);
00185             if (Current != NULL)
00186             {
00187                 if (Current == TimeZoneListHead)
00188                 {
00189                     /* Prepend to head */
00190                     Entry->Prev = NULL;
00191                     Entry->Next = TimeZoneListHead;
00192                     TimeZoneListHead->Prev = Entry;
00193                     TimeZoneListHead = Entry;
00194                 }
00195                 else
00196                 {
00197                     /* Insert before current */
00198                     Entry->Prev = Current->Prev;
00199                     Entry->Next = Current;
00200                     Current->Prev->Next = Entry;
00201                     Current->Prev = Entry;
00202                 }
00203             }
00204             else
00205             {
00206                 /* Append to tail */
00207                 Entry->Prev = TimeZoneListTail;
00208                 Entry->Next = NULL;
00209                 TimeZoneListTail->Next = Entry;
00210                 TimeZoneListTail = Entry;
00211             }
00212         }
00213 
00214         dwIndex++;
00215     }
00216 
00217     RegCloseKey(hZonesKey);
00218 }
00219 
00220 
00221 static VOID
00222 DestroyTimeZoneList(VOID)
00223 {
00224     PTIMEZONE_ENTRY Entry;
00225 
00226     while (TimeZoneListHead != NULL)
00227     {
00228         Entry = TimeZoneListHead;
00229 
00230         TimeZoneListHead = Entry->Next;
00231         if (TimeZoneListHead != NULL)
00232         {
00233             TimeZoneListHead->Prev = NULL;
00234         }
00235 
00236         HeapFree(GetProcessHeap(), 0, Entry);
00237     }
00238 
00239     TimeZoneListTail = NULL;
00240 }
00241 
00242 
00243 static VOID
00244 ShowTimeZoneList(HWND hwnd)
00245 {
00246     TIME_ZONE_INFORMATION TimeZoneInfo;
00247     PTIMEZONE_ENTRY Entry;
00248     DWORD dwIndex;
00249     DWORD i;
00250 
00251     GetTimeZoneInformation(&TimeZoneInfo);
00252 
00253     dwIndex = 0;
00254     i = 0;
00255     Entry = TimeZoneListHead;
00256     while (Entry != NULL)
00257     {
00258         SendMessageW(hwnd,
00259                      CB_ADDSTRING,
00260                      0,
00261                      (LPARAM)Entry->Description);
00262 
00263         if (!wcscmp(Entry->StandardName, TimeZoneInfo.StandardName))
00264             dwIndex = i;
00265 
00266         i++;
00267         Entry = Entry->Next;
00268     }
00269 
00270     SendMessageW(hwnd,
00271                  CB_SETCURSEL,
00272                  (WPARAM)dwIndex,
00273                  0);
00274 }
00275 
00276 
00277 static VOID
00278 SetLocalTimeZone(HWND hwnd)
00279 {
00280     TIME_ZONE_INFORMATION TimeZoneInformation;
00281     PTIMEZONE_ENTRY Entry;
00282     DWORD dwIndex;
00283     DWORD i;
00284 
00285     dwIndex = (DWORD)SendMessageW(hwnd,
00286                                   CB_GETCURSEL,
00287                                   0,
00288                                   0);
00289 
00290     i = 0;
00291     Entry = TimeZoneListHead;
00292     while (i < dwIndex)
00293     {
00294         if (Entry == NULL)
00295             return;
00296 
00297         i++;
00298         Entry = Entry->Next;
00299     }
00300 
00301     wcscpy(TimeZoneInformation.StandardName,
00302             Entry->StandardName);
00303     wcscpy(TimeZoneInformation.DaylightName,
00304             Entry->DaylightName);
00305 
00306     TimeZoneInformation.Bias = Entry->TimezoneInfo.Bias;
00307     TimeZoneInformation.StandardBias = Entry->TimezoneInfo.StandardBias;
00308     TimeZoneInformation.DaylightBias = Entry->TimezoneInfo.DaylightBias;
00309 
00310     memcpy(&TimeZoneInformation.StandardDate,
00311            &Entry->TimezoneInfo.StandardDate,
00312            sizeof(SYSTEMTIME));
00313     memcpy(&TimeZoneInformation.DaylightDate,
00314            &Entry->TimezoneInfo.DaylightDate,
00315            sizeof(SYSTEMTIME));
00316 
00317     /* Set time zone information */
00318     SetTimeZoneInformation(&TimeZoneInformation);
00319 }
00320 
00321 
00322 static VOID
00323 GetAutoDaylightInfo(HWND hwnd)
00324 {
00325     HKEY hKey;
00326 
00327     if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
00328                       L"SYSTEM\\CurrentControlSet\\Control\\TimeZoneInformation",
00329                       0,
00330                       KEY_QUERY_VALUE,
00331                       &hKey))
00332         return;
00333 
00334     /* If the call fails (non zero), the reg value isn't available,
00335      * which means it shouldn't be disabled, so we should check the button.
00336      */
00337     if (RegQueryValueExW(hKey,
00338                          L"DisableAutoDaylightTimeSet",
00339                          NULL,
00340                          NULL,
00341                          NULL,
00342                          NULL))
00343     {
00344         SendMessageW(hwnd, BM_SETCHECK, (WPARAM)BST_CHECKED, 0);
00345     }
00346     else
00347     {
00348         SendMessageW(hwnd, BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0);
00349     }
00350 
00351     RegCloseKey(hKey);
00352 }
00353 
00354 
00355 static VOID
00356 SetAutoDaylightInfo(HWND hwnd)
00357 {
00358     HKEY hKey;
00359     DWORD dwValue = 1;
00360 
00361     if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
00362                       L"SYSTEM\\CurrentControlSet\\Control\\TimeZoneInformation",
00363                       0,
00364                       KEY_SET_VALUE,
00365                       &hKey))
00366         return;
00367 
00368     if (SendMessageW(hwnd, BM_GETCHECK, 0, 0) == BST_UNCHECKED)
00369     {
00370         RegSetValueExW(hKey,
00371                        L"DisableAutoDaylightTimeSet",
00372                        0,
00373                        REG_DWORD,
00374                        (LPBYTE)&dwValue,
00375                        sizeof(DWORD));
00376     }
00377     else
00378     {
00379         RegDeleteValueW(hKey,
00380                        L"DisableAutoDaylightTimeSet");
00381     }
00382 
00383     RegCloseKey(hKey);
00384 }
00385 
00386 
00387 /* Property page dialog callback */
00388 INT_PTR CALLBACK
00389 TimeZonePageProc(HWND hwndDlg,
00390                  UINT uMsg,
00391                  WPARAM wParam,
00392                  LPARAM lParam)
00393 {
00394     BITMAP bitmap;
00395 
00396     switch (uMsg)
00397     {
00398         case WM_INITDIALOG:
00399             CreateTimeZoneList();
00400             ShowTimeZoneList(GetDlgItem(hwndDlg, IDC_TIMEZONELIST));
00401             GetAutoDaylightInfo(GetDlgItem(hwndDlg, IDC_AUTODAYLIGHT));
00402             hBitmap = LoadImageW(hApplet, MAKEINTRESOURCEW(IDC_WORLD), IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR);
00403             if (hBitmap != NULL)
00404             {
00405                 GetObjectW(hBitmap, sizeof(BITMAP), &bitmap);
00406 
00407                 cxSource = bitmap.bmWidth;
00408                 cySource = bitmap.bmHeight;
00409             }
00410             break;
00411 
00412         case WM_DRAWITEM:
00413         {
00414             LPDRAWITEMSTRUCT lpDrawItem;
00415             lpDrawItem = (LPDRAWITEMSTRUCT) lParam;
00416             if(lpDrawItem->CtlID == IDC_WORLD_BACKGROUND)
00417             {
00418                 HDC hdcMem;
00419                 hdcMem = CreateCompatibleDC(lpDrawItem->hDC);
00420                 if (hdcMem != NULL)
00421                 {
00422                     SelectObject(hdcMem, hBitmap);
00423                     StretchBlt(lpDrawItem->hDC, lpDrawItem->rcItem.left, lpDrawItem->rcItem.top,
00424                                lpDrawItem->rcItem.right - lpDrawItem->rcItem.left,
00425                                lpDrawItem->rcItem.bottom - lpDrawItem->rcItem.top,
00426                                hdcMem, 0, 0, cxSource, cySource, SRCCOPY);
00427                     DeleteDC(hdcMem);
00428                 }
00429             }
00430         }
00431         break;
00432 
00433         case WM_COMMAND:
00434             if ((LOWORD(wParam) == IDC_TIMEZONELIST && HIWORD(wParam) == CBN_SELCHANGE) ||
00435                 (LOWORD(wParam) == IDC_AUTODAYLIGHT && HIWORD(wParam) == BN_CLICKED))
00436             {
00437                 /* Enable the 'Apply' button */
00438                 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
00439             }
00440             break;
00441 
00442         case WM_DESTROY:
00443             DestroyTimeZoneList();
00444             DeleteObject(hBitmap);
00445             break;
00446 
00447         case WM_NOTIFY:
00448         {
00449             LPNMHDR lpnm = (LPNMHDR)lParam;
00450 
00451             switch (lpnm->code)
00452             {
00453                 case PSN_APPLY:
00454                 {
00455                     SetAutoDaylightInfo(GetDlgItem(hwndDlg, IDC_AUTODAYLIGHT));
00456                     SetLocalTimeZone(GetDlgItem(hwndDlg, IDC_TIMEZONELIST));
00457                     SetWindowLongPtr(hwndDlg, DWL_MSGRESULT, PSNRET_NOERROR);
00458                     return TRUE;
00459                 }
00460 
00461                 default:
00462                     break;
00463             }
00464         }
00465         break;
00466     }
00467 
00468   return FALSE;
00469 }

Generated on Sat May 26 2012 04:19:48 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.