- Add more code for NTP server selection.

- draw clock window from resource file to fix dialog unit / pixel anomaly ;)
- Do a bit of work on the NTP client. Still untested and may change to tcp.
All untested and I'm no where near finished yet, but there are a few bug fixes in here, and I'm running short on time ;)

svn path=/trunk/; revision=22486
This commit is contained in:
Ged Murphy 2006-06-21 19:57:58 +00:00
parent 25e24d88df
commit 4f99e0c714
8 changed files with 258 additions and 110 deletions

View file

@ -20,6 +20,8 @@ BEGIN
DTS_TIMEFORMAT | WS_CHILD | WS_VISIBLE | WS_TABSTOP,
144, 105, 90, 12
LTEXT "", IDC_TIMEZONE, 4, 136, 241, 8
CONTROL "", IDC_CLOCKWND, "ClockWndClass",
WS_CHILD | WS_VISIBLE, 138, 12, 102, 89
END

View file

@ -5,6 +5,7 @@
#define TWOPI (2 * 3.14159)
static const TCHAR szClockWndClass[] = TEXT("ClockWndClass");
static HBRUSH hGreyBrush = NULL;
static HPEN hGreyPen = NULL;
@ -101,7 +102,7 @@ DrawHands(HDC hdc, SYSTEMTIME * pst, BOOL fChange)
iAngle[1] = pst->wMinute * 6;
iAngle[2] = pst->wSecond * 6;
memcpy(ptTemp, pt, sizeof(pt));
CopyMemory(ptTemp, pt, sizeof(pt));
for(i = fChange ? 0 : 2; i < 3; i++)
{
@ -176,21 +177,25 @@ ClockWndProc(HWND hwnd,
}
BOOL
InitClockWindowClass(VOID)
RegisterClockControl(VOID)
{
WNDCLASSEX wc = {0};
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = ClockWndProc;
wc.hInstance = hApplet;
wc.hIcon = NULL;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
wc.lpszClassName = szClockWndClass;
wc.hIconSm = NULL;
return RegisterClassEx(&wc) != (ATOM)0;
}
VOID
UnregisterClockControl(VOID)
{
UnregisterClass(szClockWndClass,
hApplet);
}

View file

@ -163,7 +163,7 @@ MonthCalUpdate(IN PMONTHCALWND infoPtr)
NewCellSize.cy = infoPtr->ClientSize.cy / 7;
if (infoPtr->CellSize.cx != NewCellSize.cx ||
infoPtr->CellSize.cy != NewCellSize.cy);
infoPtr->CellSize.cy != NewCellSize.cy)
{
infoPtr->CellSize = NewCellSize;
RepaintHeader = TRUE;

View file

@ -3,7 +3,7 @@
SOCKET Sock;
SOCKADDR_IN myAddr, ntpAddr;
BOOL InitialiseConnection()
BOOL InitialiseConnection(CHAR *szIpAddr)
{
WSADATA wsaData;
INT Ret;
@ -13,7 +13,6 @@ BOOL InitialiseConnection()
if (Ret != 0)
return FALSE;
Sock = WSASocket(AF_INET,
SOCK_DGRAM,
IPPROTO_UDP,
@ -27,7 +26,7 @@ BOOL InitialiseConnection()
ZeroMemory(&myAddr, sizeof(myAddr));
myAddr.sin_family = AF_INET;
myAddr.sin_port = htons(IPPORT_TIMESERVER);
myAddr.sin_addr.s_addr = INADDR_ANY;
myAddr.sin_addr.s_addr = inet_addr(szIpAddr);
Ret = bind(Sock,
(SOCKADDR *)&myAddr,
@ -69,19 +68,22 @@ BOOL SendData()
}
BOOL RecieveData(CHAR *Buf)
ULONG RecieveData(ULONG ulTime)
{
INT Ret;
INT Size = sizeof(SOCKADDR_IN);
Ret = recvfrom(Sock,
Buf,
BUFSIZE,
(char *)&ulTime,
4,
0,
(SOCKADDR *)&ntpAddr,
&Size);
if (Ret == SOCKET_ERROR)
return FALSE;
if (Ret != SOCKET_ERROR)
ulTime = ntohl(ulTime);
else
ulTime = 0;
return TRUE;
return ulTime;
}

View file

@ -8,6 +8,7 @@
#define IDC_MONTHCB 101
#define IDC_YEAREDIT 102
#define IDC_MONTHCALENDAR 103
#define IDC_CLOCKWND 104
#define IDC_TIMEZONE 106
#define IDC_TIMEPICKER 107
#define IDC_YEAR 108

View file

@ -60,6 +60,25 @@ APPLET Applets[NUM_APPLETS] =
{IDC_CPLICON, IDS_CPLNAME, IDS_CPLDESCRIPTION, Applet}
};
VOID GetError(VOID)
{
LPVOID lpMsgBuf;
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpMsgBuf,
0,
NULL );
MessageBox(NULL, lpMsgBuf, _T("Error!"), MB_OK | MB_ICONERROR);
LocalFree(lpMsgBuf);
}
static BOOL
SystemSetLocalTime(LPSYSTEMTIME lpSystemTime)
{
@ -284,6 +303,8 @@ static VOID
AutoUpdateMonthCal(HWND hwndDlg,
PNMMCCAUTOUPDATE lpAutoUpdate)
{
UNREFERENCED_PARAMETER(lpAutoUpdate);
/* update the controls */
FillMonthsComboBox(GetDlgItem(hwndDlg,
IDC_MONTHCB));
@ -292,9 +313,9 @@ AutoUpdateMonthCal(HWND hwndDlg,
INT_PTR CALLBACK
DTPProc(HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam)
UINT uMsg,
WPARAM wParam,
LPARAM lParam)
{
switch (uMsg)
{
@ -302,11 +323,11 @@ DTPProc(HWND hwnd,
/* stop the timer when the user is about to change the time */
if ((wParam != VK_LEFT) & (wParam != VK_RIGHT))
KillTimer(GetParent(hwnd), ID_TIMER);
return CallWindowProc(pOldWndProc, hwnd, uMsg, wParam, lParam);
break;
default:
return CallWindowProc(pOldWndProc, hwnd, uMsg, wParam, lParam);
}
return CallWindowProc(pOldWndProc, hwnd, uMsg, wParam, lParam);
}
/* Property page dialog callback */
@ -331,18 +352,8 @@ DateTimePageProc(HWND hwndDlg,
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));
InitClockWindowClass();
CreateWindowExW(0,
L"ClockWndClass",
L"Clock",
WS_CHILD | WS_VISIBLE,
208, 14, 150, 150,
hwndDlg,
NULL,
hApplet,
NULL);
pOldWndProc = (WNDPROC) SetWindowLong(GetDlgItem(hwndDlg, IDC_TIMEPICKER), GWL_WNDPROC, (INT_PTR) DTPProc);
break;
case WM_TIMER:
@ -463,8 +474,6 @@ DateTimePageProc(HWND hwndDlg,
}
static PTIMEZONE_ENTRY
GetLargerTimeZoneEntry(DWORD Index)
{
@ -960,22 +969,23 @@ CreateNTPServerList(HWND hwnd)
}
VOID SetNTPServer(HWND hwnd)
/* Set the selected server in the registry */
static VOID
SetNTPServer(HWND hwnd)
{
HKEY hKey;
HWND hList;
INT Sel;
UINT Sel;
WCHAR szSel[4];
LONG Ret;
//DebugBreak();
hList = GetDlgItem(hwnd,
IDC_SERVERLIST);
Sel = (INT)SendMessage(hList,
CB_GETCURSEL,
0,
0);
Sel = (UINT)SendMessage(hList,
CB_GETCURSEL,
0,
0);
_itow(Sel, szSel, 10);
@ -985,7 +995,10 @@ VOID SetNTPServer(HWND hwnd)
KEY_SET_VALUE,
&hKey);
if (Ret != ERROR_SUCCESS)
{
GetError();
return;
}
Ret = RegSetValueExW(hKey,
L"",
@ -993,35 +1006,143 @@ VOID SetNTPServer(HWND hwnd)
REG_SZ,
(LPBYTE)szSel,
sizeof(szSel));
if (Ret == ERROR_SUCCESS)
MessageBoxW(NULL, szSel, NULL, 0);
else
{
WCHAR Buff[20];
_itow(Ret, Buff, 10);
//MessageBoxW(NULL, Buff, NULL, 0);
}
if (Ret != ERROR_SUCCESS)
GetError();
RegCloseKey(hKey);
}
VOID UpdateSystemTime(HWND hwndDlg)
/* get the dotted decimal address from the registry */
static BOOL
GetNTPServerAddress(CHAR *szIpAddr)
{
//SYSTEMTIME systime;
CHAR Buf[BUFSIZE];
HKEY hKey;
WCHAR szSel[4];
WCHAR buf[32];
DWORD dwSize;
LONG Ret;
Ret = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\DateTime\\Servers",
0,
KEY_QUERY_VALUE,
&hKey);
if (Ret != ERROR_SUCCESS)
{
GetError();
return FALSE;
}
dwSize = sizeof(szSel);
Ret = RegQueryValueExW(hKey,
L"",
NULL,
NULL,
(LPBYTE)szSel,
&dwSize);
if (Ret != ERROR_SUCCESS)
{
GetError();
return FALSE;
}
dwSize = sizeof(szSel);
Ret = RegQueryValueExW(hKey,
szSel,
NULL,
NULL,
(LPBYTE)buf,
&dwSize);
if (Ret != ERROR_SUCCESS)
{
GetError();
return FALSE;
}
if (WideCharToMultiByte(CP_ACP,
0,
buf,
sizeof(buf),
szIpAddr,
sizeof(szIpAddr),
NULL,
NULL) == 0)
{
GetError();
return FALSE;
}
/* safety check */
if (inet_addr(szIpAddr) == INADDR_NONE)
return FALSE;
return TRUE;
}
/* request the time from the current NTP server */
static ULONG
GetTimeFromServer(VOID)
{
CHAR szIpAddr[32];
ULONG ulTime = 0;
if (! GetNTPServerAddress(szIpAddr))
return 0;
if (InitialiseConnection(szIpAddr))
{
if (SendData())
{
RecieveData(ulTime);
}
}
InitialiseConnection();
SendData();
RecieveData(Buf);
DestroyConnection();
//DateTime_SetSystemtime(hwndDlg, 0, systime);
return ulTime;
}
/*
* NTP servers state the number of seconds passed since
* 1st Jan, 1900. The time returned from the server
* needs adding to that date to get the current Gregorian time
*/
static VOID
UpdateSystemTime(ULONG ulTime)
{
FILETIME ftNew;
LARGE_INTEGER li;
SYSTEMTIME stNew;
/* time at 1st Jan 1900 */
stNew.wYear = 1900;
stNew.wMonth = 1;
stNew.wDay = 1;
stNew.wHour = 0;
stNew.wMinute = 0;
stNew.wSecond = 0;
stNew.wMilliseconds = 0;
/* convert to a file time */
SystemTimeToFileTime(&stNew, &ftNew);
/* add on the time passed since 1st Jan 1900 */
li = *(LARGE_INTEGER *)&ftNew;
li.QuadPart += (LONGLONG)10000000 * ulTime;
ftNew = * (FILETIME *)&li;
/* convert back to a system time */
FileTimeToSystemTime(&ftNew, &stNew);
if (! SetSystemTime(&stNew))
GetError();
}
/* Property page dialog callback */
INT_PTR CALLBACK
InetTimePageProc(HWND hwndDlg,
@ -1040,36 +1161,46 @@ InetTimePageProc(HWND hwndDlg,
switch(LOWORD(wParam))
{
case IDC_UPDATEBUTTON:
{
ULONG ulTime;
SetNTPServer(hwndDlg);
//UpdateSystemTime(hwndDlg);
MessageBox(NULL, L"Not yet implemented", NULL, 0);
ulTime = GetTimeFromServer();
if (ulTime != 0)
UpdateSystemTime(ulTime);
}
break;
case IDC_SERVERLIST:
{
if (HIWORD(wParam) == CBN_SELCHANGE)
/* Enable the 'Apply' button */
PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
}
break;
case IDC_AUTOSYNC:
{
if (HIWORD(wParam) == BN_CLICKED)
{
BOOL bChecked;
HWND hCheck = GetDlgItem(hwndDlg, IDC_AUTOSYNC);
//HWND hSerText = GetDlgItem(hwndDlg, IDC_SERVERTEXT);
//HWND hSerList = GetDlgItem(hwndDlg, IDC_SERVERLIST);
//HWND hUpdateBut = GetDlgItem(hwndDlg, IDC_UPDATEBUTTON);
//HWND hSucSync = GetDlgItem(hwndDlg, IDC_SUCSYNC);
//HWND hNextSync = GetDlgItem(hwndDlg, IDC_NEXTSYNC);
UINT Check = (UINT)SendMessageW(hCheck, BM_GETCHECK, 0, 0);
INT Check = (INT)SendMessageW(hCheck, BM_GETCHECK, 0, 0);
if (Check)
;//show all data
else
;//hide all data
bChecked = (Check == BST_CHECKED) ? TRUE : FALSE;
EnableWindow(GetDlgItem(hwndDlg, IDC_SERVERTEXT), bChecked);
EnableWindow(GetDlgItem(hwndDlg, IDC_SERVERLIST), bChecked);
EnableWindow(GetDlgItem(hwndDlg, IDC_UPDATEBUTTON), bChecked);
EnableWindow(GetDlgItem(hwndDlg, IDC_SUCSYNC), bChecked);
EnableWindow(GetDlgItem(hwndDlg, IDC_NEXTSYNC), bChecked);
/* Enable the 'Apply' button */
PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
}
}
break;
}
break;
@ -1084,7 +1215,7 @@ InetTimePageProc(HWND hwndDlg,
switch (lpnm->code)
{
case PSN_APPLY:
//DebugBreak();
SetNTPServer(hwndDlg);
return TRUE;
@ -1120,7 +1251,8 @@ Applet(HWND hwnd, UINT uMsg, LONG wParam, LONG lParam)
TCHAR Caption[256];
LONG Ret = 0;
if (RegisterMonthCalControl(hApplet))
if (RegisterMonthCalControl(hApplet) &&
RegisterClockControl())
{
LoadString(hApplet, IDS_CPLNAME, Caption, sizeof(Caption) / sizeof(TCHAR));
@ -1142,6 +1274,7 @@ Applet(HWND hwnd, UINT uMsg, LONG wParam, LONG lParam)
Ret = (LONG)(PropertySheet(&psh) != -1);
UnregisterMonthCalControl(hApplet);
UnregisterClockControl();
}
return Ret;
@ -1193,16 +1326,16 @@ DllMain(HINSTANCE hinstDLL,
switch (dwReason)
{
case DLL_PROCESS_ATTACH:
{
INITCOMMONCONTROLSEX InitControls;
{
INITCOMMONCONTROLSEX InitControls;
InitControls.dwSize = sizeof(INITCOMMONCONTROLSEX);
InitControls.dwICC = ICC_DATE_CLASSES | ICC_PROGRESS_CLASS | ICC_UPDOWN_CLASS;
InitCommonControlsEx(&InitControls);
InitControls.dwSize = sizeof(INITCOMMONCONTROLSEX);
InitControls.dwICC = ICC_DATE_CLASSES | ICC_PROGRESS_CLASS | ICC_UPDOWN_CLASS;
InitCommonControlsEx(&InitControls);
hApplet = hinstDLL;
}
break;
hApplet = hinstDLL;
}
break;
}
return TRUE;

View file

@ -28,12 +28,18 @@ typedef struct
extern HINSTANCE hApplet;
BOOL InitClockWindowClass();
/* timedate.c */
VOID GetError(VOID);
BOOL InitialiseConnection(VOID);
/* clock.c */
BOOL RegisterClockControl(VOID);
VOID UnregisterClockControl(VOID);
/* ntpclient.c */
BOOL InitialiseConnection(CHAR *szIpAddr);
VOID DestroyConnection(VOID);
BOOL SendData(VOID);
BOOL RecieveData(CHAR *);
ULONG RecieveData(ULONG ulTime);
/* monthcal.c */
#define MCCM_SETDATE (WM_USER + 1)

View file

@ -13,7 +13,6 @@
<library>comctl32</library>
<library>ws2_32</library>
<library>iphlpapi</library>
<library>ntdll</library>
<file>clock.c</file>
<file>ntpclient.c</file>
<file>monthcal.c</file>