home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DOS/V Power Report 2002 December (Special)
/
DOSV2002_12.iso
/
utility
/
tcl230ja95.lzh
/
source.lzh
/
dll
/
tclock.c
< prev
next >
Wrap
C/C++ Source or Header
|
2001-02-18
|
26KB
|
1,028 lines
/*-----------------------------------------------------
tclock.c
customize the tray clock
KAZUBON 1997-2001
-------------------------------------------------------*/
#include "tcdll.h"
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
void InitClock(HWND hwnd);
void EndClock(void);
BOOL IsIE4(HWND hwnd);
void CreateTip(HWND hwnd);
void CreateClockDC(HWND hwnd);
void ReadData(HWND hwnd);
void InitSysInfo(HWND hwnd);
void OnTimer(HWND hwnd);
void DrawClockSub(HWND hwnd, HDC hdc, SYSTEMTIME* pt, int beat100);
LRESULT OnCalcRect(HWND hwnd);
void OnTooltipNeedText(UINT code, LPARAM lParam);
void OnCopy(HWND hwnd, LPARAM lParam);
void UpdateSysRes(HWND hwnd, BOOL bsysres, BOOL bbattery, BOOL bmem);
void InitDaylightTimeTransition(void);
BOOL CheckDaylightTimeTransition(SYSTEMTIME *lt);
/*------------------------------------------------
shared data among processes
--------------------------------------------------*/
#pragma data_seg(".MYDATA")
HHOOK hhook = 0;
HWND hwndTClockMain = NULL;
HWND hwndClock = NULL;
char szShareBuf[81] = { 0 };
#pragma data_seg()
/*------------------------------------------------
globals
--------------------------------------------------*/
HANDLE hmod = 0;
WNDPROC oldWndProc = NULL;
BOOL bTimer = FALSE;
BOOL bTimerTesting = FALSE;
HDC hdcClock = NULL;
HBITMAP hbmpClock = NULL;
HFONT hFon = NULL;
HWND hwndTip = NULL;
COLORREF colback, colback2, colfore;
char format[1024];
BOOL bHour12, bHourZero;
SYSTEMTIME LastTime;
int beatLast = -1;
int bDispSecond = FALSE;
int nDispBeat = 0;
BOOL bNoClock = FALSE;
int nBlink = 0;
BOOL bIE4 = FALSE, bWin95 = FALSE, bWin98 = FALSE,
bWinNT = FALSE, bWin2000 = FALSE;
int dwidth = 0, dheight = 0, dvpos = 0, dlineheight = 0;
int iClockWidth = -1;
BOOL bPlaying = FALSE;
BOOL bDispSysInfo = FALSE, bTimerSysInfo = FALSE;
BOOL bGetSysRes = FALSE, bGetBattery = FALSE;
BOOL bGetMem = 0;
int iFreeRes[3] = {0,0,0}, iCPUUsage = 0, iBatteryLife = 0;
char sAvailPhysK[11], sAvailPhysM[11];
extern HWND hwndStart;
extern HWND hwndStartMenu;
extern BOOL bStartMenuClock; // startbtn.c
extern BOOL bFillTray;
extern int codepage;
// XButton Messages
#define WM_XBUTTONDOWN 0x020B
#define WM_XBUTTONUP 0x020C
/*------------------------------------------------
initialize the clock
--------------------------------------------------*/
void InitClock(HWND hwnd)
{
BOOL b;
DWORD dw;
hwndClock = hwnd;
dw = GetVersion();
bWin95 = (dw & 0x80000000);
bWin98 = ((dw & 0x80000000) &&
LOBYTE(LOWORD(dw)) >= 4 && HIBYTE(LOWORD(dw)) >= 10);
bWinNT = !(dw & 0x80000000);
bWin2000 = (!(dw & 0x80000000) && LOBYTE(LOWORD(dw)) >= 5);
if(bWin2000) bWin98 = TRUE;
if(bWin95)
GetRegLong(HKEY_DYN_DATA, "PerfStats\\StartStat", "KERNEL\\CPUUsage", 0);
PostMessage(hwndTClockMain, WM_USER, 0, (LPARAM)hwnd);
//レジストリ読み込み
ReadData(hwndClock);
InitDaylightTimeTransition();
//サブクラス化
oldWndProc = (WNDPROC)GetWindowLong(hwndClock, GWL_WNDPROC);
SetWindowLong(hwndClock, GWL_WNDPROC, (LONG)WndProc);
//ダブルクリック受け付けない
SetClassLong(hwndClock, GCL_STYLE,
GetClassLong(hwndClock, GCL_STYLE) & ~CS_DBLCLKS);
//スタートボタンの初期化
SetStartButton(hwndClock);
//スタートメニューの初期化
SetStartMenu(hwndClock);
//ツールチップ作成
CreateTip(hwndClock);
b = GetMyRegLong(NULL, "DropFiles", FALSE);
DragAcceptFiles(hwnd, b);
bIE4 = IsIE4(hwndClock);
if(bIE4)
{
InitStartMenuIE4();
InitTaskSwitch(hwndClock);
}
InitTrayNotify(hwndClock);
if(bWin2000) SetLayeredTaskbar(hwndClock);
//タスクバーの更新
PostMessage(GetParent(GetParent(hwndClock)), WM_SIZE,
SIZE_RESTORED, 0);
InvalidateRect(GetParent(GetParent(hwndClock)), NULL, TRUE);
}
/*------------------------------------------------
ending process
--------------------------------------------------*/
void DeleteClockRes(void)
{
if(hFon) DeleteObject(hFon); hFon = NULL;
if(hdcClock) DeleteDC(hdcClock); hdcClock = NULL;
if(hbmpClock) DeleteObject(hbmpClock); hbmpClock = NULL;
}
void EndClock(void)
{
DragAcceptFiles(hwndClock, FALSE);
if(hwndTip) DestroyWindow(hwndTip); hwndTip = NULL;
EndTrayNotify();
EndTaskSwitch();
EndStartButton();
EndStartMenu();
ClearStartMenuIE4();
DeleteClockRes();
EndNewAPI(hwndClock);
EndSysres();
FreeBatteryLife();
if(bWin95)
GetRegLong(HKEY_DYN_DATA, "PerfStats\\StopStat", "KERNEL\\CPUUsage", 0);
if(hwndClock && IsWindow(hwndClock))
{
if(bTimer) KillTimer(hwndClock, 1); bTimer = FALSE;
if(bTimerSysInfo) KillTimer(hwndClock, 2);
SetWindowLong(hwndClock, GWL_WNDPROC, (LONG)oldWndProc);
oldWndProc = NULL;
}
//TClockウィンドウを終了させる
if(IsWindow(hwndTClockMain))
PostMessage(hwndTClockMain, WM_USER+2, 0, 0);
}
/*------------------------------------------------
IE 4 or later is installed ?
--------------------------------------------------*/
BOOL IsIE4(HWND hwnd)
{
char classname[80];
DWORD dw;
dw = GetRegLong(HKEY_CURRENT_USER,
"Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer",
"ClassicShell", 0);
if(dw) return TRUE;
hwnd = GetParent(GetParent(hwnd));
if(hwnd == NULL) return FALSE;
hwnd = GetWindow(hwnd, GW_CHILD);
while(hwnd)
{
GetClassName(hwnd, classname, 80);
if(lstrcmpi(classname, "ReBarWindow32") == 0)
return TRUE;
hwnd = GetWindow(hwnd, GW_HWNDNEXT);
}
return FALSE;
}
/*------------------------------------------------
subclass procedure of the clock
--------------------------------------------------*/
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch(message) // ツールチップ対応
{
case WM_LBUTTONDOWN:
case WM_RBUTTONDOWN:
case WM_MBUTTONDOWN:
case WM_LBUTTONUP:
case WM_RBUTTONUP:
case WM_MBUTTONUP:
case WM_MOUSEMOVE:
{
MSG msg;
msg.hwnd = hwnd;
msg.message = message;
msg.wParam = wParam;
msg.lParam = lParam;
msg.time = GetMessageTime();
msg.pt.x = LOWORD(GetMessagePos());
msg.pt.y = HIWORD(GetMessagePos());
if(hwndTip)
SendMessage(hwndTip, TTM_RELAYEVENT, 0, (LPARAM)&msg);
}
}
switch(message)
{
case WM_DESTROY:
DeleteClockRes();
break;
// 親ウィンドウから送られ、サイズを返すメッセージ
case (WM_USER+100):
if(bNoClock) break;
return OnCalcRect(hwnd);
// システムの設定を反映する
case WM_SYSCOLORCHANGE:
CreateClockDC(hwnd); //hdcClock作り直し
case WM_WININICHANGE:
case WM_TIMECHANGE:
// 親ウィンドウから送られる
case (WM_USER+101):
{
HDC hdc;
if(bNoClock) break;
hdc = GetDC(hwnd);
DrawClock(hwnd, hdc);
ReleaseDC(hwnd, hdc);
return 0;
}
case WM_SIZE:
CreateClockDC(hwnd); //hdcClock作り直し
break;
case WM_ERASEBKGND:
break;
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc;
if(bNoClock) break;
hdc = BeginPaint(hwnd, &ps);
DrawClock(hwnd, hdc);
EndPaint(hwnd, &ps);
return 0;
}
case WM_TIMER:
if(wParam == 1) OnTimer(hwnd);
else if(wParam == 2)
UpdateSysRes(hwnd, bGetSysRes, bGetBattery, bGetMem);
else
{
if(bNoClock) break;
}
return 0;
// マウスダウン
case WM_LBUTTONDOWN:
case WM_RBUTTONDOWN:
case WM_MBUTTONDOWN:
case WM_XBUTTONDOWN:
if(nBlink)
{
nBlink = 0; InvalidateRect(hwnd, NULL, TRUE);
}
if(message == WM_LBUTTONDOWN && bStartMenuClock &&
hwndStart && IsWindow(hwndStart))
{
SetWindowPos(hwndStart, NULL, 0, 0, 0, 0,
SWP_NOSIZE|SWP_NOZORDER|SWP_NOACTIVATE);
// スタートメニュー
PostMessage(hwndStart, WM_LBUTTONDOWN, 0, 0);
return 0;
}
PostMessage(hwndTClockMain, message, wParam, lParam);
return 0;
// マウスアップ
case WM_LBUTTONUP:
case WM_RBUTTONUP:
case WM_MBUTTONUP:
case WM_XBUTTONUP:
PostMessage(hwndTClockMain, message, wParam, lParam);
if(message == WM_RBUTTONUP) break;
return 0;
case WM_MOUSEMOVE:
return 0;
case WM_CONTEXTMENU: // 右クリックメニュー
PostMessage(hwndTClockMain, message, wParam, lParam);
return 0;
case WM_NCHITTEST: // oldWndProcに処理させない
return DefWindowProc(hwnd, message, wParam, lParam);
case WM_MOUSEACTIVATE:
return MA_ACTIVATE;
// ファイルのドロップ
case WM_DROPFILES:
PostMessage(hwndTClockMain, WM_DROPFILES, wParam, lParam);
return 0;
case WM_NOTIFY: //ツールチップのテキスト表示
{
UINT code;
code = ((LPNMHDR)lParam)->code;
if(code == TTN_NEEDTEXT || code == TTN_NEEDTEXTW)
{
OnTooltipNeedText(code, lParam);
return 0;
}
break;
}
case WM_COMMAND:
if(LOWORD(wParam) == 102) EndClock();
return 0;
case CLOCKM_REFRESHCLOCK: // refresh the clock
{
BOOL b;
ReadData(hwnd);
CreateClockDC(hwnd);
b = GetMyRegLong(NULL, "DropFiles", FALSE);
DragAcceptFiles(hwnd, b);
InvalidateRect(hwnd, NULL, FALSE);
InvalidateRect(GetParent(hwndClock), NULL, TRUE);
return 0;
}
case CLOCKM_REFRESHTASKBAR: // refresh other elements than clock
SetStartButton(hwnd);
SetStartMenu(hwnd);
InitTaskSwitch(hwnd);
InitTrayNotify(hwnd);
CreateClockDC(hwnd);
if(bWin2000) SetLayeredTaskbar(hwndClock);
PostMessage(GetParent(GetParent(hwnd)), WM_SIZE,
SIZE_RESTORED, 0);
InvalidateRect(GetParent(GetParent(hwndClock)), NULL, TRUE);
return 0;
case CLOCKM_BLINK: // blink the clock
if(wParam) { if(nBlink == 0) nBlink = 4; }
else nBlink = 2;
return 0;
case CLOCKM_COPY: // copy format to clipboard
OnCopy(hwnd, lParam);
return 0;
case WM_WINDOWPOSCHANGING: // サイズ調整
{
LPWINDOWPOS pwp;
if(bNoClock) break;
pwp = (LPWINDOWPOS)lParam;
if(IsWindowVisible(hwnd) && !(pwp->flags & SWP_NOSIZE))
{
int h;
h = (int)HIWORD(OnCalcRect(hwnd));
if(pwp->cy > h) pwp->cy = h;
}
break;
}
}
/*
{
char s[80];
wsprintf(s, "%X", message);
WriteDebug(s);
}
*/
return CallWindowProc(oldWndProc, hwnd, message, wParam, lParam);
}
/*------------------------------------------------
設定の読み込みとデータの初期化
--------------------------------------------------*/
void ReadData(HWND hwnd)
{
char fontname[80];
int fontsize;
LONG weight, italic;
SYSTEMTIME lt;
colfore = GetMyRegLong(NULL, "ForeColor",
0x80000000 | COLOR_BTNTEXT);
colback = GetMyRegLong(NULL, "BackColor",
0x80000000 | COLOR_3DFACE);
if(GetMyRegLong(NULL, "UseBackColor2", TRUE))
colback2 = GetMyRegLong(NULL, "BackColor2", colback);
else colback2 = colback;
GetMyRegStr(NULL, "Font", fontname, 80, "");
fontsize = GetMyRegLong(NULL, "FontSize", 9);
weight = GetMyRegLong(NULL, "Bold", 0);
if(weight) weight = FW_BOLD;
else weight = 0;
italic = GetMyRegLong(NULL, "Italic", 0);
if(hFon) DeleteObject(hFon);
hFon = CreateMyFont(fontname, fontsize, weight, italic);
dheight = (int)(short)GetMyRegLong(NULL, "ClockHeight", 0);
dwidth = (int)(short)GetMyRegLong(NULL, "ClockWidth", 0);
dvpos = (int)(short)GetMyRegLong(NULL, "VertPos", 0);
dlineheight = (int)(short)GetMyRegLong(NULL, "LineHeight", 0);
bNoClock = GetMyRegLong(NULL, "NoClock", FALSE);
if(!GetMyRegStr(NULL, "Format", format, 1024, "") || !format[0])
{
bNoClock = TRUE;
}
bDispSecond = IsDispSecond(format);
if(!bTimer) SetTimer(hwndClock, 1, 1000, NULL);
bTimer = TRUE;
nDispBeat = IsDispBeat(format);
bHour12 = GetMyRegLong(NULL, "Hour12", 0);
bHourZero = GetMyRegLong(NULL, "HourZero", 0);
GetLocalTime(<);
LastTime.wDay = lt.wDay;
InitFormat(<); // format.c
iClockWidth = -1;
InitSysInfo(hwnd);
}
void InitSysInfo(HWND hwnd)
{
char tip[1024];
GetMyRegStr("Tooltip", "Tooltip", tip, 1024, "");
if(bTimerSysInfo) KillTimer(hwndClock, 2);
bDispSysInfo = bTimerSysInfo = FALSE;
bGetSysRes = FALSE;
bGetBattery = FALSE;
bGetMem = 0;
sAvailPhysK[0] = sAvailPhysM[0] = 0;
if(bWin95)
{
if(IsDispSysInfo(format))
{
bGetSysRes = TRUE; bDispSysInfo = TRUE;
}
if(!bGetSysRes) bGetSysRes = IsDispSysInfo(tip);
if(bGetSysRes) bTimerSysInfo = TRUE;
}
if(bWin95 || bWin2000)
{
if(FindFormatStr(format, "BL"))
{
bGetBattery = TRUE; bDispSysInfo = TRUE;
}
if(!bGetBattery) bGetBattery = FindFormatStr(tip, "BL");
if(bGetBattery) bTimerSysInfo = TRUE;
}
if(FindFormatStr(format, "MK") || FindFormatStr(format, "MM"))
bGetMem = TRUE;
if(bGetMem) bDispSysInfo = TRUE;
if(!bGetMem)
bGetMem = (FindFormatStr(tip, "MK") || FindFormatStr(tip, "MM"));
if(bGetMem) bTimerSysInfo = TRUE;
if(bTimerSysInfo)
{
int interval;
UpdateSysRes(hwnd, bGetSysRes, bGetBattery, bGetMem);
interval = (int)GetMyRegLong(NULL, "IntervalSysInfo", 5);
if(interval <= 0 || 60 < interval) interval = 5;
SetTimer(hwndClock, 2, interval * 1000, NULL);
}
}
/*------------------------------------------------
ツールチップウィンドウの作成
--------------------------------------------------*/
void CreateTip(HWND hwnd)
{
TOOLINFO ti;
hwndTip = CreateWindow(TOOLTIPS_CLASS, (LPSTR)NULL,
TTS_ALWAYSTIP,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hmod, NULL);
if(!hwndTip) return;
ti.cbSize = sizeof(TOOLINFO);
ti.uFlags = 0;
ti.hwnd = hwnd;
ti.hinst = NULL;
ti.uId = 1;
ti.lpszText = LPSTR_TEXTCALLBACK;
ti.rect.left = 0;
ti.rect.top = 0;
ti.rect.right = 480;
ti.rect.bottom = 480;
SendMessage(hwndTip, TTM_ADDTOOL, 0, (LPARAM) (LPTOOLINFO)&ti);
SendMessage(hwndTip, TTM_ACTIVATE, TRUE, 0);
}
/*------------------------------------------------
描画用メモリDCの作成
--------------------------------------------------*/
void CreateClockDC(HWND hwnd)
{
RECT rc;
COLORREF col;
HDC hdc;
if(hdcClock) DeleteDC(hdcClock); hdcClock = NULL;
if(hbmpClock) DeleteObject(hbmpClock); hbmpClock = NULL;
if(bNoClock) return;
if(bFillTray) hwnd = GetParent(hwnd);
GetClientRect(hwnd, &rc);
hdc = GetDC(NULL);
hdcClock = CreateCompatibleDC(hdc);
if(!hdcClock)
{
ReleaseDC(NULL, hdc);
return;
}
hbmpClock = CreateCompatibleBitmap(hdc, rc.right, rc.bottom);
if(!hbmpClock)
{
DeleteDC(hdcClock); hdcClock = NULL;
ReleaseDC(NULL, hdc);
return;
}
SelectObject(hdcClock, hbmpClock);
SelectObject(hdcClock, hFon);
SetBkMode(hdcClock, TRANSPARENT);
SetTextAlign(hdcClock, TA_CENTER|TA_TOP);
col = colfore;
if(col & 0x80000000) col = GetSysColor(col & 0x00ffffff);
SetTextColor(hdcClock, col);
FillClock(hwnd, hdcClock, &rc, 0);
ReleaseDC(NULL, hdc);
}
/*------------------------------------------------
get date/time and beat to display
--------------------------------------------------*/
void GetDisplayTime(SYSTEMTIME* pt, int* beat100)
{
FILETIME ft, lft;
SYSTEMTIME lt;
GetSystemTimeAsFileTime(&ft);
if(beat100)
{
DWORDLONG dl;
SYSTEMTIME st;
int sec;
dl = *(DWORDLONG*)&ft + 36000000000;
FileTimeToSystemTime((FILETIME*)&dl, &st);
sec = st.wHour * 3600 + st.wMinute * 60 + st.wSecond;
*beat100 = (sec * 1000) / 864;
}
FileTimeToLocalFileTime(&ft, &lft);
FileTimeToSystemTime(&lft, <);
memcpy(pt, <, sizeof(lt));
}
/*------------------------------------------------
WM_TIMER の処理
--------------------------------------------------*/
void OnTimer(HWND hwnd)
{
SYSTEMTIME t;
int beat100;
HDC hdc;
BOOL bRedraw;
GetDisplayTime(&t, nDispBeat?(&beat100):NULL);
if(t.wMilliseconds > 200 || (bWinNT && t.wMilliseconds > 50))
{
KillTimer(hwnd, 1);
bTimerTesting = TRUE;
SetTimer(hwnd, 1, 1001 - t.wMilliseconds, NULL);
}
else if(bTimerTesting)
{
KillTimer(hwnd, 1);
bTimerTesting = FALSE;
SetTimer(hwnd, 1, 1000, NULL);
}
if(CheckDaylightTimeTransition(&t))
{
CallWindowProc(oldWndProc, hwnd, WM_TIMER, 0, 0);
GetDisplayTime(&t, nDispBeat?(&beat100):NULL);
}
bRedraw = FALSE;
if(nBlink > 0) bRedraw = TRUE;
else if(bDispSecond) bRedraw = TRUE;
else if(nDispBeat == 1 && beatLast != (beat100/100)) bRedraw = TRUE;
else if(nDispBeat == 2 && beatLast != beat100) bRedraw = TRUE;
else if(bDispSysInfo) bRedraw = TRUE;
else if(LastTime.wHour != (int)t.wHour
|| LastTime.wMinute != (int)t.wMinute) bRedraw = TRUE;
if(bNoClock) bRedraw = FALSE;
if(LastTime.wDay != t.wDay || LastTime.wMonth != t.wMonth ||
LastTime.wYear != t.wYear)
{
InitFormat(&t); // format.c
InitDaylightTimeTransition();
}
hdc = NULL;
if(bRedraw) hdc = GetDC(hwnd);
memcpy(&LastTime, &t, sizeof(t));
if(nDispBeat == 1) beatLast = beat100/100;
else if(nDispBeat > 1) beatLast = beat100;
if(nBlink >= 3 && t.wMinute == 1) nBlink = 0;
if(hdc)
{
DrawClockSub(hwnd, hdc, &t, beat100); //描画
ReleaseDC(hwnd, hdc);
}
if(nBlink)
{
if(nBlink % 2) nBlink++;
else nBlink--;
}
CheckCursorOnStartButton();
}
/*------------------------------------------------
時計の描画
--------------------------------------------------*/
void DrawClock(HWND hwnd, HDC hdc)
{
SYSTEMTIME t;
int beat100;
GetDisplayTime(&t, nDispBeat?(&beat100):NULL);
DrawClockSub(hwnd, hdc, &t, beat100);
}
/*------------------------------------------------
draw the clock
--------------------------------------------------*/
void DrawClockSub(HWND hwnd, HDC hdc, SYSTEMTIME* pt, int beat100)
{
BITMAP bmp;
RECT rcFill, rcClock;
TEXTMETRIC tm;
int hf, y, w;
char s[1024], *p, *sp;
SIZE sz;
int xclock, yclock, wclock, hclock, xsrc, ysrc, wsrc, hsrc;
int xcenter;
HRGN hRgn, hOldRgn;
if(!hdcClock) CreateClockDC(hwnd);
if(!hdcClock || !hbmpClock) return;
GetObject(hbmpClock, sizeof(BITMAP), (LPVOID)&bmp);
rcFill.left = rcFill.top = 0;
rcFill.right = bmp.bmWidth; rcFill.bottom = bmp.bmHeight;
FillClock(hwnd, hdcClock, &rcFill, nBlink);
MakeFormat(s, pt, beat100, format);
GetClientRect(hwndClock, &rcClock);
if(bFillTray)
{
POINT ptTray, ptClock;
ptTray.x = ptTray.y = 0;
ClientToScreen(GetParent(hwndClock), &ptTray);
ptClock.x = ptClock.y = 0;
ClientToScreen(hwndClock, &ptClock);
xclock = ptClock.x - ptTray.x;
yclock = ptClock.y - ptTray.y;
}
else
{
xclock = 0; yclock = 0;
}
wclock = rcClock.right; hclock = rcClock.bottom;
GetTextMetrics(hdcClock, &tm);
if(bFillTray)
{
hRgn = CreateRectRgn(xclock, yclock,
xclock + wclock, yclock + hclock);
hOldRgn = SelectObject(hdcClock, hRgn);
}
hf = tm.tmHeight - tm.tmInternalLeading;
p = s;
y = hf / 4 - tm.tmInternalLeading / 2;
if(bFillTray) y += yclock;
xcenter = wclock / 2;
if(bFillTray) xcenter += xclock;
w = 0;
while(*p)
{
sp = p;
while(*p && *p != 0x0d) p++;
if(*p == 0x0d) { *p = 0; p += 2; }
if(*p == 0 && sp == s)
{
y = (hclock - tm.tmHeight) / 2 - tm.tmInternalLeading / 4;
if(bFillTray) y += yclock;
}
TextOut(hdcClock, xcenter, y + dvpos, sp, strlen(sp));
if(GetTextExtentPoint32(hdcClock, sp, strlen(sp), &sz) == 0)
sz.cx = strlen(sp) * tm.tmAveCharWidth;
if(w < sz.cx) w = sz.cx;
y += hf; if(*p) y += 2 + dlineheight;
}
xsrc = 0; ysrc = 0; wsrc = rcFill.right; hsrc = rcFill.bottom;
if(bFillTray)
{
xsrc = xclock; ysrc = yclock;
wsrc = wclock; hsrc = hclock;
}
BitBlt(hdc, 0, 0, wsrc, hsrc, hdcClock, xsrc, ysrc, SRCCOPY);
if(bFillTray)
{
SelectObject(hdcClock, hOldRgn);
DeleteObject(hRgn);
}
w += tm.tmAveCharWidth * 2;
w += dwidth;
if(w > iClockWidth)
{
iClockWidth = w;
PostMessage(GetParent(GetParent(hwndClock)), WM_SIZE,
SIZE_RESTORED, 0);
}
}
/*------------------------------------------------
paint background of clock
--------------------------------------------------*/
void FillClock(HWND hwnd, HDC hdc, RECT *prc, int nblink)
{
HBRUSH hbr;
COLORREF col;
if(nblink == 0 || (nblink % 2)) col = colfore;
else col = colback;
if(col & 0x80000000) col = GetSysColor(col & 0x00ffffff);
SetTextColor(hdc, col);
if(nblink || colback == colback2 || !bWin98)
{
if(nblink == 0 || (nblink % 2)) col = colback;
else col = colfore;
if(col & 0x80000000) col = GetSysColor(col & 0x00ffffff);
hbr = CreateSolidBrush(col);
FillRect(hdc, prc, hbr);
DeleteObject(hbr);
}
else
{
COLORREF col2;
col = colback;
if(col & 0x80000000) col = GetSysColor(col & 0x00ffffff);
col2 = colback2;
if(col2 & 0x80000000) col2 = GetSysColor(col2 & 0x00ffffff);
GradientFillClock(hdc, prc, col, col2);
}
}
/*------------------------------------------------
時計に必要なサイズを返す
戻り値:上位WORD 高さ 下位WORD 幅
--------------------------------------------------*/
LRESULT OnCalcRect(HWND hwnd)
{
SYSTEMTIME t;
int beat100;
LRESULT w, h;
HDC hdc;
TEXTMETRIC tm;
char s[1024], *p, *sp;
SIZE sz;
int hf;
if(!(GetWindowLong(hwnd, GWL_STYLE)&WS_VISIBLE)) return 0;
hdc = GetDC(hwnd);
if(hFon) SelectObject(hdc, hFon);
GetTextMetrics(hdc, &tm);
GetDisplayTime(&t, nDispBeat?(&beat100):NULL);
MakeFormat(s, &t, beat100, format);
p = s; w = 0; h = 0;
hf = tm.tmHeight - tm.tmInternalLeading;
while(*p)
{
sp = p;
while(*p && *p != 0x0d) p++;
if(*p == 0x0d) { *p = 0; p += 2; }
if(GetTextExtentPoint32(hdc, sp, strlen(sp), &sz) == 0)
sz.cx = strlen(sp) * tm.tmAveCharWidth;
if(w < sz.cx) w = sz.cx;
h += hf; if(*p) h += 2 + dlineheight;
}
w += tm.tmAveCharWidth * 2;
if(iClockWidth < 0) iClockWidth = w;
else w = iClockWidth;
w += dwidth;
h += hf / 2 + dheight;
if(h < 4) h = 4;
ReleaseDC(hwnd, hdc);
return (h << 16) + w;
}
/*------------------------------------------------
ツールチップの表示
--------------------------------------------------*/
void OnTooltipNeedText(UINT code, LPARAM lParam)
{
SYSTEMTIME t;
int beat100;
char fmt[1024], s[1024];
GetMyRegStr("Tooltip", "Tooltip", fmt, 1024, "");
if(fmt[0] == 0) strcpy(fmt, "\"TClock\" LDATE");
GetDisplayTime(&t, &beat100);
MakeFormat(s, &t, beat100, fmt);
if(code == TTN_NEEDTEXT)
strcpy(((LPTOOLTIPTEXT)lParam)->szText, s);
else
MultiByteToWideChar(CP_ACP, 0, s, -1,
((LPTOOLTIPTEXTW)lParam)->szText, 80);
SetWindowPos(hwndTip, HWND_TOPMOST, 0, 0, 0, 0,
SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE);
}
/*------------------------------------------------
copy date/time text to clipboard
--------------------------------------------------*/
void OnCopy(HWND hwnd, LPARAM lParam)
{
SYSTEMTIME t;
int beat100;
char entry[20], fmt[256], s[1024], *pbuf;
HGLOBAL hg;
BOOL br, bb, bm;
GetDisplayTime(&t, &beat100);
wsprintf(entry, "%d%dClip",
(int)LOWORD(lParam), (int)HIWORD(lParam));
GetMyRegStr("Mouse", entry, fmt, 256, "");
if(fmt[0] == 0) strcpy(fmt, format);
br = IsDispSysInfo(fmt);
bb = FindFormatStr(fmt, "BL");
bm = (FindFormatStr(fmt, "MK") || FindFormatStr(fmt, "MM"));
if(br || bb || bm)
UpdateSysRes(hwnd, br, bb, bm);
MakeFormat(s, &t, beat100, fmt);
if(!OpenClipboard(hwnd)) return;
EmptyClipboard();
hg = GlobalAlloc(GMEM_DDESHARE, strlen(s) + 1);
pbuf = (char*)GlobalLock(hg);
strcpy(pbuf, s);
GlobalUnlock(hg);
SetClipboardData(CF_TEXT, hg);
CloseClipboard();
}
void UpdateSysRes(HWND hwnd, BOOL bsysres, BOOL bbattery, BOOL bmem)
{
int i;
if(bWin95 && bsysres)
{
// char s[10];
for(i = 0; i < 3; i++)
iFreeRes[i] = GetFreeSystemResources((WORD)i);
iCPUUsage = GetRegLong(HKEY_DYN_DATA, "PerfStats\\StatData",
"KERNEL\\CPUUsage", 0);
// wsprintf(s, "%d", iCPUUsage);
// WriteDebug(s);
}
if((bWin95 || bWin2000) && bbattery)
{
iBatteryLife = GetBatteryLifePercent();
}
if(bmem)
{
MEMORYSTATUS ms;
ms.dwLength = sizeof(ms);
GlobalMemoryStatus(&ms);
wsprintf(sAvailPhysK, "%d", ms.dwAvailPhys / 1024);
wsprintf(sAvailPhysM, "%d", ms.dwAvailPhys / (1024 * 1024));
}
}
int iHourTransition = -1, iMinuteTransition = -1;
/*------------------------------------------------
initialize time-zone information
--------------------------------------------------*/
void InitDaylightTimeTransition(void)
{
SYSTEMTIME lt, *plt;
TIME_ZONE_INFORMATION tzi;
DWORD dw;
BOOL b;
iHourTransition = iMinuteTransition = -1;
GetLocalTime(<);
b = FALSE;
memset(&tzi, 0, sizeof(tzi));
dw = GetTimeZoneInformation(&tzi);
if(dw == TIME_ZONE_ID_STANDARD
&& tzi.DaylightDate.wMonth == lt.wMonth
&& tzi.DaylightDate.wDayOfWeek == lt.wDayOfWeek)
{
b = TRUE; plt = &(tzi.DaylightDate);
}
if(dw == TIME_ZONE_ID_DAYLIGHT
&& tzi.StandardDate.wMonth == lt.wMonth
&& tzi.StandardDate.wDayOfWeek == lt.wDayOfWeek)
{
b = TRUE; plt = &(tzi.StandardDate);
}
if(b && plt->wDay < 5)
{
if(((lt.wDay - 1) / 7 + 1) == plt->wDay)
{
iHourTransition = plt->wHour;
iMinuteTransition = plt->wMinute;
}
}
else if(b && plt->wDay == 5)
{
FILETIME ft;
SystemTimeToFileTime(<, &ft);
*(DWORDLONG*)&ft += 6048000000000i64;
FileTimeToSystemTime(&ft, <);
if(lt.wDay < 8)
{
iHourTransition = plt->wHour;
iMinuteTransition = plt->wMinute;
}
}
}
BOOL CheckDaylightTimeTransition(SYSTEMTIME *plt)
{
if((int)plt->wHour == iHourTransition &&
(int)plt->wMinute >= iMinuteTransition)
{
iHourTransition = iMinuteTransition = -1;
return TRUE;
}
else return FALSE;
}