Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

341 lines
9.4 KiB

//---------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation 1991-1992
//
// Put a clock in a window.
//---------------------------------------------------------------------------
#include "cabinet.h"
#include "trayclok.h"
extern HFONT g_hfontCapNormal;
extern TRAYSTUFF g_ts;
TCHAR g_szTimeFmt[20]=TEXT(""); // The format string to pass to GetFormatTime
TCHAR g_szCurTime[20]=TEXT(""); // The current string.
int g_cchCurTime=0;
WORD g_wLastHour = (WORD)-1; // wHour from local time of last timer message
#if 0
// use CS_VREDRAW | CS_HREDRAW instead
//---------------------------------------------------------------------------
LRESULT ClockCtl_HandleSize(HWND hWnd)
{
InvalidateRect(hWnd, NULL, TRUE); // Make sure everything redraws!
return (LRESULT)0;
}
#endif
//--------------------------------------------------------------------------
LRESULT ClockCtl_HandleCreate(HWND hwnd)
{
SYSTEMTIME st;
// presumably initcab already tried refreshing so init g_wLastHour
GetLocalTime(&st);
g_wLastHour = st.wHour;
// Set up a one second timer.
if (!g_ts.fRudeApp && !(g_ts.uAutoHide & AH_HIDING))
PostMessage(hwnd, WM_TIMER, 0, 0L);
else
SetTimer(hwnd, 0, 60*1000, NULL);
return 1;
}
//---------------------------------------------------------------------------
LRESULT ClockCtl_HandleDestroy(HWND hwnd)
{
KillTimer(hwnd, 0);
return 1;
}
//---------------------------------------------------------------------------
LRESULT ClockCtl_DoPaint(HWND hwnd, BOOL fPaint)
{
HDC hdc;
PAINTSTRUCT ps;
RECT rcClient;
HFONT hfontOld;
SIZE size;
if (fPaint)
hdc = BeginPaint(hwnd, &ps);
else {
hdc = GetDC(hwnd);
}
if (GetClipBox(hdc, &rcClient) != NULLREGION) {
GetClientRect(hwnd, &rcClient);
SetBkColor(hdc, GetSysColor(COLOR_3DFACE));
SetTextColor(hdc, GetSysColor(COLOR_BTNTEXT));
if (g_hfontCapNormal)
hfontOld = SelectObject(hdc, g_hfontCapNormal);
GetTextExtentPoint(hdc, g_szCurTime, g_cchCurTime, &size);
// Now lets setup to draw the text for time. It is implied that
// g_cchCurTime DOES NOT include the terminating NULL character,
// if there is one.
ExtTextOut(hdc, (rcClient.right - size.cx)/2,
(rcClient.bottom - size.cy)/2, ETO_OPAQUE,
&rcClient, g_szCurTime, g_cchCurTime, NULL);
if (g_hfontCapNormal)
SelectObject(hdc, hfontOld);
}
if (fPaint)
EndPaint(hwnd, &ps);
else
ReleaseDC(hwnd, hdc);
return 0;
}
//--------------------------------------------------------------------------
LRESULT ClockCtl_HandleTimer(HWND hwnd)
{
// DebugMsg(DM_TRACE, "c.ccht: Clock ticked or was set.");
SYSTEMTIME st;
GetLocalTime(&st);
// Get time string for the current time...
g_cchCurTime = GetTimeFormat(LOCALE_USER_DEFAULT, TIME_NOSECONDS, NULL,
g_szTimeFmt, g_szCurTime, ARRAYSIZE(g_szCurTime));
// decrement g_cchCurTime so as not to include the null terminator
if (g_cchCurTime > 0)
g_cchCurTime--;
// Make our next timer come at the top of the next minute
SetTimer(hwnd, 0, (60-st.wSecond)*1000, NULL);
ClockCtl_DoPaint(hwnd, FALSE);
// do our timezone check about once an hour
if (st.wHour != g_wLastHour)
PostMessage(hwnd, TCM_TIMEZONEHACK, 0, 0L);
g_wLastHour = st.wHour;
return 1;
}
//--------------------------------------------------------------------------
LRESULT ClockCtl_HandleTimeChange(HWND hwnd)
{
SYSTEMTIME st;
// grab the new time so we don't try to refresh the timezone information
GetLocalTime(&st);
g_wLastHour = st.wHour;
// repaint using new settings
ClockCtl_HandleTimer(hwnd);
return 1;
}
//---------------------------------------------------------------------------
LRESULT ClockCtl_CalcMinSize(HWND hWnd)
{
RECT rc;
HDC hdc;
HFONT hfontOld;
SYSTEMTIME st={0}; // Initialize to 0...
SIZE sizeAM;
SIZE sizePM;
TCHAR szTime[20];
int cch;
if (!(GetWindowLong(hWnd, GWL_STYLE) & WS_VISIBLE))
return 0L;
if (g_szTimeFmt[0] == TEXT('\0'))
{
if (GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_STIMEFORMAT,
g_szTimeFmt, ARRAYSIZE(g_szTimeFmt)) == 0)
{
#ifdef DEBUG
int dwError = GetLastError();
DebugMsg(DM_TRACE, TEXT("c.ccms: GetLocalInfo Failed %d."), dwError);
#endif
}
}
hdc = GetDC(hWnd);
if (!hdc)
return(0L);
if (g_hfontCapNormal)
hfontOld = SelectObject(hdc, g_hfontCapNormal);
// We need to get the AM and the PM sizes...
// We append Two 0s and end to add slop into size
st.wHour=11;
cch = GetTimeFormat(LOCALE_USER_DEFAULT, TIME_NOSECONDS, &st,
g_szTimeFmt, szTime, ARRAYSIZE(szTime));
lstrcat(szTime, TEXT("00"));
GetTextExtentPoint(hdc, szTime, cch+2, &sizeAM);
st.wHour=23;
cch = GetTimeFormat(LOCALE_USER_DEFAULT, TIME_NOSECONDS, &st,
g_szTimeFmt, szTime, ARRAYSIZE(szTime));
lstrcat(szTime, TEXT("00"));
GetTextExtentPoint(hdc, szTime, cch+2, &sizePM);
if (g_hfontCapNormal)
SelectObject(hdc, hfontOld);
ReleaseDC(hWnd, hdc);
// Now lets setup our rectangle...
// The width is 6 digits (a digit slop on both ends + size of
// : or sep and max AM or PM string...)
SetRect(&rc, 0, 0, max(sizeAM.cx, sizePM.cx),
max(sizeAM.cy, sizePM.cy) + 4 * g_cyBorder);
AdjustWindowRectEx(&rc, GetWindowLong(hWnd, GWL_STYLE), FALSE,
GetWindowLong(hWnd, GWL_EXSTYLE));
// make sure we're at least the size of other buttons:
if (rc.bottom - rc.top < g_cySize + g_cyEdge)
rc.bottom = rc.top + g_cySize + g_cyEdge;
return MAKELRESULT((rc.right - rc.left),
(rc.bottom - rc.top));
}
//---------------------------------------------------------------------------
LRESULT ClockCtl_HandleIniChange(HWND hWnd, WPARAM wParam, LPTSTR pszSection)
{
// Only process certain sections...
if ((pszSection == NULL) || (lstrcmpi(pszSection, TEXT("intl")) == 0) ||
(wParam == SPI_SETICONTITLELOGFONT))
{
TOOLINFO ti;
g_szTimeFmt[0] = TEXT('\0'); // Go reread the format.
// And make sure we have it recalc...
ClockCtl_CalcMinSize(hWnd);
ti.cbSize = SIZEOF(ti);
ti.uFlags = 0;
ti.hwnd = v_hwndTray;
ti.uId = (UINT)hWnd;
ti.lpszText = LPSTR_TEXTCALLBACK;
SendMessage(g_ts.hwndTrayTips, TTM_UPDATETIPTEXT, 0, (LPARAM)&ti);
}
ClockCtl_HandleTimer(hWnd);
return (LRESULT)0;
}
//---------------------------------------------------------------------------
LRESULT CALLBACK ClockCtl_WndProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam)
{
switch (wMsg)
{
case WM_CALCMINSIZE:
return ClockCtl_CalcMinSize(hWnd);
case WM_CREATE:
return ClockCtl_HandleCreate(hWnd);
case WM_DESTROY:
return ClockCtl_HandleDestroy(hWnd);
case WM_PAINT:
return ClockCtl_DoPaint(hWnd, TRUE);
#if 0
case WM_SIZE:
return ClockCtl_HandleSize(hWnd);
#endif
// InvalidateRect(hWnd, NULL, TRUE);
case WM_WININICHANGE:
return ClockCtl_HandleIniChange(hWnd, wParam, (LPTSTR)lParam);
case WM_TIMECHANGE:
return ClockCtl_HandleTimeChange(hWnd);
case WM_TIMER:
return ClockCtl_HandleTimer(hWnd);
case WM_NCHITTEST:
return(HTTRANSPARENT);
case TCM_TIMEZONEHACK:
Cabinet_DoDaylightCheck(FALSE);
break;
/*
* Called by the tray to inform us we are hiding/showing the tray so that we.
* can disable/enable the clock for perf optimizations...
*/
case TCM_TRAYHIDE:
if (lParam)
{
// not paging us in every minute helps WinStone scores
KillTimer(hWnd, 0);
break;
}
//fall through
case TCM_KICKSTART:
// our timer handler restarts the timer and paints
ClockCtl_HandleTimer(hWnd);
break;
default:
return (DefWindowProc(hWnd, wMsg, wParam, lParam));
}
return 0;
}
//---------------------------------------------------------------------------
// Register the clock class.
BOOL ClockCtl_Class(HINSTANCE hinst)
{
WNDCLASS wc;
wc.lpszClassName = WC_TRAYCLOCK;
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = (WNDPROC)ClockCtl_WndProc;
wc.hInstance = hinst;
wc.hIcon = NULL;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_3DFACE+1);
wc.lpszMenuName = NULL;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
return RegisterClass(&wc);
}
/*
** ClockCtl_Create
*
* PARAMETERS:
*
* DESCRIPTION:
*
* RETURNS:
*
*/
HWND ClockCtl_Create(HWND hwndParent, UINT uID, HINSTANCE hInst)
{
return(CreateWindow(WC_TRAYCLOCK,
NULL, WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE, 0, 0, 0, 0,
hwndParent, (HMENU)uID, hInst, NULL));
}