1 /*
2  * todayfw.c -- TODAY for Windows95/98/Me/NT4/2000/XP - Windows main
3  *
4  * Copyright (C) 1997-1999,2001,2002,2003 by Yoshifumi Mori
5  *
6  * tab:4
7  */
8 
9 #include "cdefs.h"
10 #include "extern.h"
11 #include "todayfw.rh"
12 
13 #define DEF_SPLASH_TIMEOUT	(2 * 1000)
14 #define MAXARGS				1000
15 #define MAX_EDIT_MENU		1	/* default max edit menu */
16 
17        char	*szAppName;
18 static char	*szAppNameMsg;
19 static char	*szAppNameMutex;
20 static char	*szAppNameLong;
21 static char	*szCopyright;
22 static char	*szVersion;
23 static char	*szComment;
24        char	*szHelpFile;
25        char	*szCalClass;
26 static char	*szCalCmd;
27 
28 int	splash_timeout = DEF_SPLASH_TIMEOUT;
29 
30 static HWND		hwndSplash;
31 static int	iSplashActiveTime;
32 static DWORD	dwSplashStartTime;
33 #define idSplashTimer	1
34 
35 static HINSTANCE	ghInstance;
36 static HANDLE	hMutex;
37 static HWND		hwndMain;
38 static HWND		hwndToolbar;
39 static HIMAGELIST	hImgList;
40 static HWND		hwndMsg;
41 static HWND		hwndError;
42 static HBRUSH	brushBg;
43 static HFONT	hDispFont;
44 static UINT		umsgToday;
45 static UINT		umsgCal;
46 static SIZE	sizeToolbar;
47 static SIZE	sizeChar;
48 static int	nCols;
49 static int	nRows;
50 static int	nVscrollPos;
51 static int	nVscrollMax;
52 static int	nHscrollPos;
53 static int	nHscrollMax;
54 static int	nTextWidthAve;
55 static int	nTextWidthMax;
56 static int	nTextLineMax;
57 
58 static int	argc;
59 static char	**argv;
60 static struct DATE_T input_ymd;
61 
62 #define NUMIMAGES		14
63 #define IMAGEWIDTH		16
64 #define IMAGEHEIGHT		16
65 #define IMAGEMASKRGB	RGB(0xC0, 0xC0, 0xC0)
66 
67 static const TBBUTTON	tbButton[] = {
68 	{  1, IDM_FILEOUT,    TBSTATE_ENABLED, TBSTYLE_BUTTON, { 0, 0 }, 0, 0 },
69 	{  2, IDM_COPY,       TBSTATE_ENABLED, TBSTYLE_BUTTON, { 0, 0 }, 0, 0 },
70 	{  0, 0,              TBSTATE_ENABLED, TBSTYLE_SEP,    { 0, 0 }, 0, 0 },
71 	{  4, IDM_DATESET,    TBSTATE_ENABLED, TBSTYLE_BUTTON, { 0, 0 }, 0, 0 },
72 	{  5, IDM_DATEOFFSET, TBSTATE_ENABLED, TBSTYLE_BUTTON, { 0, 0 }, 0, 0 },
73 	{  0, 0,              TBSTATE_ENABLED, TBSTYLE_SEP,    { 0, 0 }, 0, 0 },
74 	{  6, IDM_YYDOWN,     TBSTATE_ENABLED, TBSTYLE_BUTTON, { 0, 0 }, 0, 0 },
75 	{  7, IDM_MMDOWN,     TBSTATE_ENABLED, TBSTYLE_BUTTON, { 0, 0 }, 0, 0 },
76 	{  8, IDM_DDDOWN,     TBSTATE_ENABLED, TBSTYLE_BUTTON, { 0, 0 }, 0, 0 },
77 	{  3, IDM_DATENOW,    TBSTATE_ENABLED, TBSTYLE_BUTTON, { 0, 0 }, 0, 0 },
78 	{  9, IDM_DDUP,       TBSTATE_ENABLED, TBSTYLE_BUTTON, { 0, 0 }, 0, 0 },
79 	{ 10, IDM_MMUP,       TBSTATE_ENABLED, TBSTYLE_BUTTON, { 0, 0 }, 0, 0 },
80 	{ 11, IDM_YYUP,       TBSTATE_ENABLED, TBSTYLE_BUTTON, { 0, 0 }, 0, 0 },
81 //	{  0, 0,              TBSTATE_ENABLED, TBSTYLE_SEP,    { 0, 0 }, 0, 0 },
82 //	{ 12, IDM_ABOUT,      TBSTATE_ENABLED, TBSTYLE_BUTTON, { 0, 0 }, 0, 0 },
83 //	{ 13, IDM_HELP,       TBSTATE_ENABLED, TBSTYLE_BUTTON, { 0, 0 }, 0, 0 },
84 };
85 
86 static const char	Copyright[] = "TODAY for Windows95/98/Me/NT4/2000/XP  Copyright (C) 1997,1998,1999,2001,2002,2003 by Yoshifumi Mori";
87 
88 void DestroySplashWindow(BOOL bForce);
89 
90 /* ------------------------------------------------------------------------- */
91 
92 #define PACKVERSION(major,minor)	MAKELONG(minor,major)
93 
GetDllVersion(LPCTSTR lpszDllName)94 DWORD GetDllVersion(LPCTSTR lpszDllName)
95 {
96 	HINSTANCE	hinstDll;
97 	DWORD	dwVersion = 0;
98 
99 	hinstDll = LoadLibrary(lpszDllName);
100 	if (hinstDll) {
101 		DLLGETVERSIONPROC	pDllGetVersion;
102 
103 		pDllGetVersion = (DLLGETVERSIONPROC)GetProcAddress(hinstDll, "DllGetVersion");
104 		/*
105 		 * Because some DLLs might not implement this function, you
106 		 * must test for it explicitly. Depending on the particular
107 		 * DLL, the lack of a DllGetVersion function can be a useful
108 		 * indicator of the version.
109 		 */
110 		if (pDllGetVersion) {
111 			DLLVERSIONINFO	dvi;
112 			HRESULT	hr;
113 
114 			ZeroMemory(&dvi, sizeof(dvi));
115 			dvi.cbSize = sizeof(dvi);
116 
117 			hr = (*pDllGetVersion)(&dvi);
118 			if (SUCCEEDED(hr)) {
119 				dwVersion = PACKVERSION(dvi.dwMajorVersion, dvi.dwMinorVersion);
120 			}
121 		}
122 
123 		FreeLibrary(hinstDll);
124 	}
125 	return (dwVersion);
126 }
127 
128 static
CenterWindow(HWND hwndMove,HWND hwndAltOwner)129 BOOL CenterWindow(HWND hwndMove, HWND hwndAltOwner)
130 {
131 	RECT	rcMove;
132 	RECT	rcAlt;
133 	POINT	ptNew;
134 
135 	if (!IsWindow(hwndMove)) {
136 		goto Error_Exit;
137 	}
138 	if (hwndAltOwner && !IsWindow(hwndAltOwner)) {
139 		goto Error_Exit;
140 	}
141 
142 	GetWindowRect(hwndMove, &rcMove);
143 
144 	if (!hwndAltOwner) {
145 		SystemParametersInfo(SPI_GETWORKAREA, 0, &rcAlt, 0);
146 	} else {
147 		GetWindowRect(hwndAltOwner, &rcAlt);
148 	}
149 
150 	ptNew.x = rcAlt.left + ((rcAlt.right  - rcAlt.left) - (rcMove.right  - rcMove.left)) / 2;
151 	ptNew.y = rcAlt.top  + ((rcAlt.bottom - rcAlt.top ) - (rcMove.bottom - rcMove.top )) / 2;
152 
153 	SetWindowPos(hwndMove, NULL, ptNew.x, ptNew.y, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
154 
155 	return (TRUE);
156 
157 Error_Exit:
158 	return (FALSE);
159 }
160 
161 /* ------------------------------------------------------------------------- */
162 
163 /*
164  * ���ꥨ�顼����
165  */
memerr(const char * func)166 void memerr(const char *func)
167 {
168 	char	szTitle[256];
169 	char	szText[256];
170 
171 	wsprintf(szTitle, "%s ���顼���� - %s", szAppName, func);
172 	wsprintf(szText, "�ؿ�: %s �ǥ��꡼����ݤǤ��ޤ���Ǥ���\n�ץ�����λ���ޤ�.", func);
173 
174 	DestroySplashWindow(TRUE);
175 
176 	MessageBox(hwndMain, szText, szTitle, MB_ICONEXCLAMATION | MB_OK);
177 
178 	pager_clean(FALSE);
179 	exit(1);
180 }
181 
182 /*
183  * ���顼����ե�����˽��Ϥ���
184  */
185 static
saveErrorLog(HWND hwnd)186 void saveErrorLog(HWND hwnd)
187 {
188 	OPENFILENAME	ofn;
189 	char	szFileName[MAX_PATH + 1];
190 	char	msgbuf[MAX_PATH + 1 + 64];
191 	FILE	*ofp;
192 	int	textlen;
193 	char	*text;
194 
195 	memset(szFileName, 0, sizeof(szFileName));
196 	memset(&ofn, 0, sizeof(ofn));
197 	ofn.lStructSize = sizeof(OPENFILENAME);
198 	ofn.hwndOwner = hwnd;
199 	ofn.lpstrFilter = "Text files {*.txt}\0*.txt\0Log files {*.log}\0*.log\0nAll files {*.*}\0*.*\0\0";
200 	ofn.lpstrFile = szFileName;
201 	ofn.nMaxFile = MAX_PATH;
202 	ofn.lpstrDefExt = "txt";
203 	if (GetSaveFileName(&ofn) != TRUE) {
204 		return ;
205 	}
206 
207 	ofp = fopen(szFileName, "w");
208 	if (ofp == NULL) {
209 		wsprintf(msgbuf, "%s: %s", szFileName, strerror(errno));
210 		MessageBox(hwnd, msgbuf, szAppName, MB_ICONEXCLAMATION | MB_OK);
211 		return ;
212 	}
213 
214 	textlen = SendDlgItemMessage(hwnd, IDC_ERREDIT, WM_GETTEXTLENGTH, 0, 0L);
215 	text = malloc(textlen + 1);
216 	if (text != NULL) {
217 		SendDlgItemMessage(hwnd, IDC_ERREDIT, WM_GETTEXT, textlen + 1, (LPARAM)text);
218 		fprintf(ofp, "%s\n", text);
219 		free(text);
220 	}
221 
222 	fclose(ofp);
223 }
224 
225 /*
226  * ���顼������ɥ�
227  * �ᥤ�����
228  */
ErrorDlgProc(HWND hDlg,UINT iMessage,WPARAM wParam,LPARAM lParam)229 INT_PTR CALLBACK ErrorDlgProc(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam)
230 {
231 	switch (iMessage) {
232 	case WM_INITDIALOG:
233 		SetClassLong(hDlg, GCL_HICON, (LONG)LoadIcon(ghInstance, MAKEINTRESOURCE(IDI_ICON1)));
234 		CenterWindow(hDlg, NULL);
235 		return (TRUE);
236 	case WM_COMMAND:
237 		switch (LOWORD(wParam)) {
238 		case IDOK:
239 		case IDCANCEL:
240 			DestroyWindow(hDlg);
241 			return (TRUE);
242 		case IDC_ERRSAVE:
243 			saveErrorLog(hDlg);
244 			return (TRUE);
245 		}
246 		break;
247 	case WM_CTLCOLORSTATIC:
248 		if ((HWND)lParam == GetDlgItem(hDlg, IDC_ERREDIT)) {
249 			return ((INT_PTR)GetSysColorBrush(COLOR_WINDOW));
250 		}
251 		break;
252 	case WM_DESTROY:
253 		hwndError = NULL;
254 		break;
255 	}
256 
257 	return (FALSE);
258 }
259 
260 /*
261  * ���顼������ɥ��κ���
262  */
CreateErrorWindow(const char * title,const char * errtext)263 void CreateErrorWindow(const char *title, const char *errtext)
264 {
265 	int	textlen;
266 	int	allocsize;
267 	char	*text;
268 
269 	if (hwndError == NULL) {
270 		hwndError = CreateDialog(ghInstance, MAKEINTRESOURCE(IDD_ERROR), NULL, ErrorDlgProc);
271 		if (hwndError == NULL) {
272 			return ;
273 		}
274 		ShowWindow(hwndError, SW_SHOW);
275 		SetWindowText(hwndError, title);
276 	}
277 
278 	textlen = SendDlgItemMessage(hwndError, IDC_ERREDIT, WM_GETTEXTLENGTH, 0, 0L);
279 	if (textlen == 0) {
280 		allocsize = strlen(errtext) + 1;
281 	} else {
282 		allocsize = textlen + strlen(errtext) + 2 + 1;
283 	}
284 	text = malloc(allocsize);
285 	if (text != NULL) {
286 		SendDlgItemMessage(hwndError, IDC_ERREDIT, WM_GETTEXT, textlen + 1, (LPARAM)text);
287 		if (textlen == 0) {
288 			strcpy(text, errtext);
289 		} else {
290 			strcat(text, "\r\n");
291 			strcat(text, errtext);
292 		}
293 		SendDlgItemMessage(hwndError, IDC_ERREDIT, WM_SETTEXT, 0, (LPARAM)text);
294 		free(text);
295 	}
296 }
297 
298 /*
299  * ���顼������ɥ��κ��
300  */
DestroyErrorWindow(void)301 void DestroyErrorWindow(void)
302 {
303 	if (hwndError != NULL) {
304 		DestroyWindow(hwndError);
305 	}
306 }
307 
308 /*
309  * �¹���Υ��顼ɽ��
310  *
311  * func:  �¹Դؿ�̾
312  * level: ���顼��٥� (information, warning, debug, error, panic)
313  * fmt:   ���顼��å�����
314  */
errprint(const char * func,int level,const char * fmt,...)315 void errprint(const char *func, int level, const char *fmt, ...)
316 {
317 	static const char	*statname[] = {
318 		"Warning", "Debug", "Error", "Panic",
319 	};
320 	char	szTitle[256];
321 	char	szText[256];
322 	va_list	ap;
323 
324 	sprintf(szTitle, "%s ���顼����", szAppName);
325 
326 	szText[0] = '\0';
327 	if (func != NULL) {
328 		sprintf(szText, "%s: ", func);
329 	}
330 	if (level != ERR_INFO) {
331 		sprintf(strlastp(szText), "%s: ", statname[level - ERR_WARN]);
332 	}
333 	va_start(ap, fmt);
334 	vsprintf(strlastp(szText), fmt, ap);
335 	va_end(ap);
336 
337 	DestroySplashWindow(TRUE);
338 
339 	if (level == ERR_PANIC) {
340 		MessageBox(hwndMain, szText, szTitle, MB_ICONEXCLAMATION | MB_OK);
341 	} else {
342 		CreateErrorWindow(szTitle, szText);
343 	}
344 }
345 
346 /* ------------------------------------------------------------------------- */
347 
348 /*
349  * ���ץ�å��奦����ɥ�
350  * �ᥤ�����
351  */
SplashDlgProc(HWND hDlg,UINT iMessage,WPARAM wParam,LPARAM lParam)352 BOOL CALLBACK SplashDlgProc(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam)
353 {
354 #define PAD_HEIGHT	2
355 	static HFONT	hFont;
356 	static HBITMAP	hBitmap;
357 	PAINTSTRUCT	ps;
358 	HDC	hdc;
359 	HDC	hMemDC;
360 	TEXTMETRIC	tm;
361 	BITMAP	bm;
362 	SIZE	winSz;
363 	SIZE	txtSz;
364 	char	msg[128];
365 
366 	switch (iMessage) {
367 	case WM_INITDIALOG:
368 		hFont = CreateFont(12, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, "Arial");
369 		hdc = GetDC(hDlg);
370 		SelectObject(hdc, hFont);
371 		GetTextMetrics(hdc, &tm);
372 		ReleaseDC(hDlg, hdc);
373 		hBitmap = (HBITMAP)LoadImage(ghInstance, MAKEINTRESOURCE(IDB_SPLASH), IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR | LR_DEFAULTSIZE | LR_LOADMAP3DCOLORS);
374 		GetObject(hBitmap, sizeof(BITMAP), &bm);
375 		winSz.cx = bm.bmWidth + GetSystemMetrics(SM_CXFIXEDFRAME) * 2;
376 		winSz.cy = bm.bmHeight + GetSystemMetrics(SM_CYFIXEDFRAME) * 2 + tm.tmHeight + tm.tmExternalLeading;
377 		/*
378 		 * Windows95/98 Bug? ����
379 		 * ���������꥽������ WS_EX_PALETTEWINDOW ����ꤷ�Ƥ�
380 		 * WS_EX_TOOLWINDOW �� WS_EX_TOPMOST �����ꤵ��Ƥ��ʤ���
381 		 * ���Τ��ᡢSetWindowLong() �� WS_EX_PALETTEWINDOW ������ꤷ
382 		 * �Ƥ��롣��������WS_EX_TOPMOST �����ꤵ��ʤ��Τ� SetWindowPos()
383 		 * �� WS_EX_TOPMOST �����ꤷ�Ƥ��롣
384 		 */
385 		SetWindowLong(hDlg, GWL_EXSTYLE, GetWindowLong(hDlg, GWL_EXSTYLE) | WS_EX_PALETTEWINDOW);
386 		SetWindowPos(hDlg, HWND_TOPMOST, 0, 0, winSz.cx, winSz.cy, SWP_NOMOVE);
387 		CenterWindow(hDlg, NULL);
388 		return (TRUE);
389 	case WM_PAINT:
390 		GetObject(hBitmap, sizeof(BITMAP), &bm);
391 		BeginPaint(hDlg, &ps);
392 		hMemDC = CreateCompatibleDC(ps.hdc);
393 		SelectObject(hMemDC, hBitmap);
394 		BitBlt(ps.hdc, 0, 0, bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY);
395 		DeleteDC(hMemDC);
396 		sprintf(msg, "%s %s", szComment, szVersion);
397 		SelectObject(ps.hdc, hFont);
398 		GetTextExtentPoint32(ps.hdc, msg, strlen(msg), &txtSz);
399 		SetBkMode(ps.hdc, TRANSPARENT);
400 		TextOut(ps.hdc, (bm.bmWidth - txtSz.cx) / 2, bm.bmHeight - PAD_HEIGHT, msg, strlen(msg));
401 		EndPaint(hDlg, &ps);
402 		return (TRUE);
403 	case WM_TIMER:
404 		KillTimer(hDlg, idSplashTimer);
405 		DestroyWindow(hDlg);
406 		return (TRUE);
407 	case WM_DESTROY:
408 		DeleteObject(hBitmap);
409 		DeleteObject(hFont);
410 		hwndSplash = NULL;
411 		break;
412 	}
413 
414 	return (FALSE);
415 }
416 
417 /*
418  * ���ץ�å��奦����ɥ��κ���
419  *
420  * in: iActiveTime - ���ץ�å��奦����ɥ�ɽ������(ms)
421  *                   0 �ǥ��ץ�å��奦����ɥ���̵��
422  * in: iDelayTime  - ���ץ�å��奦����ɥ�ñ��ɽ������(ms)
423  */
CreateSplashWindow(int iActiveTime,int iDelayTime)424 void CreateSplashWindow(int iActiveTime, int iDelayTime)
425 {
426 	if (iActiveTime > 0) {
427 		hwndSplash = CreateDialog(ghInstance, MAKEINTRESOURCE(IDD_SPLASH), NULL, SplashDlgProc);
428 		if (hwndSplash != NULL) {
429 			ShowWindow(hwndSplash, SW_SHOW);
430 			iSplashActiveTime = iActiveTime;
431 			dwSplashStartTime = GetTickCount();
432 			if (iDelayTime > 0) {
433 				Sleep(iDelayTime);
434 			}
435 		}
436 	}
437 }
438 
439 /*
440  * ���ץ�å��奦����ɥ��κ��
441  *
442  * in: bForce - TRUE:  �������
443  *              FALSE: ������ɥ�ɽ�����֤��ĤäƤ�����ϡ�
444  *                     �ĤäƤ�����֤��Ԥäƺ��
445  */
DestroySplashWindow(BOOL bForce)446 void DestroySplashWindow(BOOL bForce)
447 {
448 	int	progressTime;
449 
450 	if (hwndSplash != NULL) {
451 		progressTime = (int)(GetTickCount() - dwSplashStartTime);
452 		if (bForce != FALSE || progressTime >= iSplashActiveTime) {
453 			DestroyWindow(hwndSplash);
454 		} else {
455 			SetTimer(hwndSplash, idSplashTimer, iSplashActiveTime - progressTime, NULL);
456 			SetWindowPos(hwndSplash, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
457 		}
458 	}
459 }
460 
461 /* ------------------------------------------------------------------------- */
462 
463 /*
464  * �ƥ����Ȥ�ɽ��
465  */
466 static
drawScreen(HWND hWnd)467 void drawScreen(HWND hWnd)
468 {
469 	PAINTSTRUCT	ps;
470 	HFONT	oldFont;
471 	int		i;
472 	int		j;
473 	int		x;
474 	int		dispx;
475 	int		y;
476 	RECT	rcClient;
477 	RECT	rcRect;
478 	struct ESC_TOKEN_T	*et;
479 	SIZE	dispTextSize;
480 
481 	BeginPaint(hWnd, &ps);
482 	GetClientRect(hWnd, &rcClient);
483 	if (hDispFont == NULL) {
484 		oldFont = SelectObject(ps.hdc, GetStockObject(SYSTEM_FIXED_FONT));
485 	} else {
486 		oldFont = SelectObject(ps.hdc, hDispFont);
487 	}
488 
489 	x = -(sizeChar.cx * nHscrollPos);
490 	for (i = 0, j = nVscrollPos, y = 0; i <= nRows; i++, j++, y += sizeChar.cy) {
491 		if (j >= nTextLineMax) {
492 			SetRect(&rcRect, 0, y, rcClient.right, rcClient.bottom);
493 			FillRect(ps.hdc, &rcRect, brushBg);
494 			break;
495 		}
496 		SetRect(&rcRect, 0, y, rcClient.right, y + sizeChar.cy);
497 		if (RectVisible(ps.hdc, &rcRect)) {
498 			dispx = x;
499 			et = separate_escstring(textBuf[j]);
500 			while (et != NULL) {
501 				SetTextColor(ps.hdc, RGB2PALETTERGB(win_colormap[MASK_COL_FG(et->attr)]));
502 				SetBkColor(ps.hdc, RGB2PALETTERGB(win_colormap[MASK_COL_BG(et->attr)]));
503 				GetTextExtentPoint32(ps.hdc, et->msg, et->len, &dispTextSize);
504 				TextOut(ps.hdc, dispx, y, et->msg, et->len);
505 				dispx += dispTextSize.cx;
506 				free(et->msg);
507 				et = separate_escstring(NULL);
508 			}
509 			if (dispx < rcClient.right) {
510 				SetRect(&rcRect, dispx, y, rcClient.right, y + sizeChar.cy);
511 				FillRect(ps.hdc, &rcRect, brushBg);
512 			}
513 		}
514 	}
515 
516 	SelectObject(ps.hdc, oldFont);
517 	EndPaint(hWnd, &ps);
518 }
519 
520 /*
521  * ��ľ������������
522  */
523 static
ctrlVScroll(HWND hWnd,WPARAM wParam,int step)524 void ctrlVScroll(HWND hWnd, WPARAM wParam, int step)
525 {
526 	int		nVscrollNew;
527 	int		nVscrollDif;
528 	RECT	rcClient;
529 	SCROLLINFO	si;
530 
531 	nVscrollNew = nVscrollPos;
532 	switch (LOWORD(wParam)) {
533 	case SB_TOP:
534 		nVscrollNew = 0;
535 		break;
536 	case SB_BOTTOM:
537 		nVscrollNew = nVscrollMax;
538 		break;
539 	case SB_LINEUP:
540 		if (nVscrollPos > 0) {
541 			nVscrollNew--;
542 		}
543 		break;
544 	case SB_LINEDOWN:
545 		if (nVscrollPos < nVscrollMax) {
546 			nVscrollNew++;
547 		}
548 		break;
549 	case SB_PAGEUP:
550 		if ((nVscrollPos - nRows) >= 0) {
551 			nVscrollNew -= nRows;
552 		} else {
553 			nVscrollNew = 0;
554 		}
555 		break;
556 	case SB_PAGEDOWN:
557 		if ((nVscrollPos + nRows) <= nVscrollMax) {
558 			nVscrollNew += nRows;
559 		} else {
560 			nVscrollNew = nVscrollMax;
561 		}
562 		break;
563 	case SB_THUMBTRACK:
564 		nVscrollNew = HIWORD(wParam);
565 		break;
566 	case (WORD)-1:
567 		nVscrollNew += step;
568 		if (nVscrollNew < 0) {
569 			nVscrollNew = 0;
570 		} else if (nVscrollNew > nVscrollMax) {
571 			nVscrollNew = nVscrollMax;
572 		}
573 		break;
574 	}
575 	nVscrollDif = nVscrollPos - nVscrollNew;
576 	if (nVscrollDif != 0) {
577 		nVscrollPos = nVscrollNew;
578 		GetClientRect(hWnd, &rcClient);
579 		ScrollWindowEx(hWnd, 0, sizeChar.cy * nVscrollDif, NULL, &rcClient, NULL, NULL, SW_INVALIDATE);
580 		si.cbSize = sizeof(SCROLLINFO);
581 		si.fMask  = SIF_POS;
582 		si.nPos   = nVscrollPos;
583 		SetScrollInfo(hWnd, SB_VERT, &si, TRUE);
584 	}
585 }
586 
587 /*
588  * ��ʿ�������������
589  */
590 static
ctrlHScroll(HWND hWnd,WPARAM wParam)591 void ctrlHScroll(HWND hWnd, WPARAM wParam)
592 {
593 	int		nHscrollNew;
594 	int		nHscrollDif;
595 	RECT	rcClient;
596 	SCROLLINFO	si;
597 
598 	nHscrollNew = nHscrollPos;
599 	switch (LOWORD(wParam)) {
600 	case SB_LINELEFT:
601 		if (nHscrollPos > 0) {
602 			nHscrollNew--;
603 		}
604 		break;
605 	case SB_LINERIGHT:
606 		if (nHscrollPos < nHscrollMax) {
607 			nHscrollNew++;
608 		}
609 		break;
610 	case SB_PAGELEFT:
611 		if ((nHscrollPos - 8) >= 0) {
612 			nHscrollNew -= 8;
613 		} else {
614 			nHscrollNew = 0;
615 		}
616 		break;
617 	case SB_PAGERIGHT:
618 		if ((nHscrollPos + 8) <= nHscrollMax) {
619 			nHscrollNew += 8;
620 		} else {
621 			nHscrollNew = nHscrollMax;
622 		}
623 		break;
624 	case SB_THUMBTRACK:
625 		nHscrollNew = HIWORD(wParam);
626 		break;
627 	}
628 	nHscrollDif = nHscrollPos - nHscrollNew;
629 	if (nHscrollDif != 0) {
630 		nHscrollPos = nHscrollNew;
631 		GetClientRect(hWnd, &rcClient);
632 		ScrollWindowEx(hWnd, sizeChar.cx * nHscrollDif, 0, NULL, &rcClient, NULL, NULL, SW_INVALIDATE);
633 		si.cbSize = sizeof(SCROLLINFO);
634 		si.fMask  = SIF_POS;
635 		si.nPos   = nHscrollPos;
636 		SetScrollInfo(hWnd, SB_HORZ, &si, TRUE);
637 	}
638 }
639 
640 /*
641  * ��ʿ����ľ��������С�������
642  */
643 static
setupScrollInfo(HWND hWnd)644 void setupScrollInfo(HWND hWnd)
645 {
646 	SCROLLINFO	si;
647 
648 	nTextLineMax  = textLines;
649 	nTextWidthMax = max(nTextWidthAve, screen_max_columns);
650 
651 	nVscrollMax = max(0, nTextLineMax - nRows);
652 	nVscrollPos = min(nVscrollPos, nVscrollMax);
653 	if (nVscrollMax == 0) {
654 		EnableScrollBar(hWnd, SB_VERT, ESB_DISABLE_BOTH);
655 	} else {
656 		si.cbSize = sizeof(SCROLLINFO);
657 		si.fMask  = SIF_RANGE | SIF_PAGE | SIF_POS;
658 		si.nMin   = 0;
659 		si.nMax   = nTextLineMax - 1;
660 		si.nPage  = nRows;
661 		si.nPos   = nVscrollPos;
662 		SetScrollInfo(hWnd, SB_VERT, &si, TRUE);
663 		EnableScrollBar(hWnd, SB_VERT, ESB_ENABLE_BOTH);
664 	}
665 
666 	nHscrollMax = max(0, nTextWidthMax - nCols);
667 	nHscrollPos = min(nHscrollPos, nHscrollMax);
668 	if (nHscrollMax == 0) {
669 		EnableScrollBar(hWnd, SB_HORZ, ESB_DISABLE_BOTH);
670 	} else {
671 		si.cbSize = sizeof(SCROLLINFO);
672 		si.fMask  = SIF_RANGE | SIF_PAGE | SIF_POS;
673 		si.nMin   = 0;
674 		si.nMax   = nTextWidthMax - 1;
675 		si.nPage  = nCols;
676 		si.nPos   = nHscrollPos;
677 		SetScrollInfo(hWnd, SB_HORZ, &si, TRUE);
678 		EnableScrollBar(hWnd, SB_HORZ, ESB_ENABLE_BOTH);
679 	}
680 }
681 
682 /*
683  * ɽ������ƥ����Ȥ���������ɽ����ɬ�פʷ�������
684  * ���������������ꤷ������ɽ��
685  */
setupDisplayText(HWND hwnd)686 void setupDisplayText(HWND hwnd)
687 {
688 	HDC	hdc;
689 	HFONT	oldFont;
690 	SIZE	textSz;
691 	char	*text;
692 	char	*s;
693 	int	i;
694 	int	len;
695 
696 	hdc = GetDC(hwnd);
697 	if (hDispFont == NULL) {
698 		oldFont = SelectObject(hdc, GetStockObject(SYSTEM_FIXED_FONT));
699 	} else {
700 		oldFont = SelectObject(hdc, hDispFont);
701 	}
702 
703 	nTextWidthAve = 0;
704 	for (i = 0; i < textLines; i++) {
705 		text = textBuf[i];
706 		len = getlength_escstring(text);
707 		s = gettext_escstring(text);
708 		if (s != NULL) {
709 			GetTextExtentPoint32(hdc, s, strlen(s), &textSz);
710 			len = (textSz.cx + sizeChar.cx - 1) / sizeChar.cx;
711 			free(s);
712 		}
713 		/*
714 		 * gettext_escstring() �� NULL ���֤�����硢getlength_escstring()
715 		 * �ǵ��äƤ���Ĺ������Ѥ���١����ΰ��֤ˤ���
716 		 */
717 		if (nTextWidthAve < len) {
718 			nTextWidthAve = len;
719 		}
720 	}
721 
722 	SelectObject(hdc, oldFont);
723 	ReleaseDC(hwnd, hdc);
724 
725 	nVscrollPos = 0;
726 	nHscrollPos = 0;
727 	setupScrollInfo(hwnd);
728 	InvalidateRect(hwnd, NULL, TRUE);
729 }
730 
MsgWndProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam)731 LRESULT CALLBACK MsgWndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam)
732 {
733 #if 0
734 	RECT	rcClient;
735 	POINT	mspoint;
736 #endif
737 	int	scrollLines;
738 
739 	switch (iMessage) {
740 	case WM_CREATE:
741 		nVscrollPos = 0;
742 		nHscrollPos = 0;
743 		break;
744 	case WM_KEYDOWN:
745 		switch (wParam) {
746 		case VK_HOME:
747 			SendMessage(hWnd, WM_VSCROLL, SB_TOP, 0L);
748 			break;
749 		case VK_END:
750 			SendMessage(hWnd, WM_VSCROLL, SB_BOTTOM, 0L);
751 			break;
752 		case VK_PRIOR:
753 		case VK_BACK:
754 			SendMessage(hWnd, WM_VSCROLL, SB_PAGEUP, 0L);
755 			break;
756 		case VK_NEXT:
757 		case VK_SPACE:
758 			SendMessage(hWnd, WM_VSCROLL, SB_PAGEDOWN, 0L);
759 			break;
760 		case VK_UP:
761 			SendMessage(hWnd, WM_VSCROLL, SB_LINEUP, 0L);
762 			break;
763 		case VK_DOWN:
764 			SendMessage(hWnd, WM_VSCROLL, SB_LINEDOWN, 0L);
765 			break;
766 		case VK_LEFT:
767 			SendMessage(hWnd, WM_HSCROLL, SB_LINELEFT, 0L);
768 			break;
769 		case VK_RIGHT:
770 			SendMessage(hWnd, WM_HSCROLL, SB_LINERIGHT, 0L);
771 			break;
772 		}
773 		break;
774 	case WM_VSCROLL:
775 		ctrlVScroll(hWnd, wParam, 0);
776 		break;
777 	case WM_HSCROLL:
778 		ctrlHScroll(hWnd, wParam);
779 		break;
780 	case WM_SIZE:
781 		nCols = LOWORD(lParam) / sizeChar.cx;
782 		nRows = HIWORD(lParam) / sizeChar.cy;
783 		setupScrollInfo(hWnd);
784 		break;
785 	case WM_PAINT:
786 		drawScreen(hWnd);
787 		break;
788 	case WM_MOUSEWHEEL:
789 #if 0
790 		GetClientRect(hWnd, &rcClient);
791 		mspoint.x = LOWORD(lParam);
792 		mspoint.y = HIWORD(lParam);
793 		ScreenToClient(hWnd, &mspoint);
794 		if (CHK_SYSFLAGS(SYSFLAGS_WHEELMOUSE) != FALSE &&
795 		    PtInRect(&rcClient, mspoint) != FALSE) {
796 #else
797 		if (CHK_SYSFLAGS(SYSFLAGS_WHEELMOUSE) != FALSE) {
798 #endif
799 			SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, &scrollLines, 0);
800 			scrollLines *= GET_WHEEL_DELTA_WPARAM(wParam) / WHEEL_DELTA;
801 			ctrlVScroll(hWnd, -1, -scrollLines);
802 		}
803 		break;
804 	default:
805 		return (DefWindowProc(hWnd, iMessage, wParam, lParam));
806 	}
807 
808 	return (0);
809 }
810 
811 /* ------------------------------------------------------------------------- */
812 
813 BOOL CALLBACK AboutDlgProc(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam)
814 {
815 	char	msg[32];
816 	HICON	hIcon;
817 
818 	switch (iMessage) {
819 	case WM_INITDIALOG:
820 		SetClassLong(hDlg, GCL_HICON, (LONG)LoadIcon(ghInstance, MAKEINTRESOURCE(IDI_ICON1)));
821 		CenterWindow(hDlg, GetParent(hDlg));
822 		SetDlgItemText(hDlg, IDC_APPNAME, szAppNameLong);
823 		sprintf(msg, "Version %s  (" __DATE__ ")", szVersion);
824 		SetDlgItemText(hDlg, IDC_VERINFO, msg);
825 		SetDlgItemText(hDlg, IDC_COPYRIGHT, szCopyright);
826 		SetDlgItemText(hDlg, IDC_COMMENT, szComment);
827 		return (TRUE);
828 	case WM_DRAWITEM:
829 		if ((UINT)wParam == IDC_ICON1) {
830 			hIcon = LoadImage(ghInstance, MAKEINTRESOURCE(IDI_ICON1), IMAGE_ICON, 64, 64, LR_DEFAULTCOLOR);
831 			DrawIconEx(((LPDRAWITEMSTRUCT)lParam)->hDC, 0, 0, hIcon, 64, 64, 0, NULL, DI_NORMAL);
832 			return (TRUE);
833 		}
834 		break;
835 	case WM_COMMAND:
836 		switch (LOWORD(wParam)) {
837 		case IDOK:
838 		case IDCANCEL:
839 			EndDialog(hDlg, 0);
840 			return (TRUE);
841 		}
842 		break;
843 	case WM_CLOSE:
844 		EndDialog(hDlg, 0);
845 		return (TRUE);
846 	}
847 
848 	return (FALSE);
849 }
850 
851 /*
852  * ���դ��������
853  */
854 static
855 int dateControl(int type, int offset)
856 {
857 	switch (type) {
858 	case 0:	/* yy+1 */
859 		if (calendar.year < SUPPORT_MAX_YEAR) {
860 			calendar.year++;
861 		}
862 		break;
863 	case 1:	/* yy-1 */
864 		if (calendar.year > SUPPORT_MIN_YEAR) {
865 			calendar.year--;
866 		}
867 		break;
868 	case 2:	/* mm+1 */
869 		if (++calendar.month > 12) {
870 			if (calendar.year < SUPPORT_MAX_YEAR) {
871 				calendar.year++;
872 				calendar.month = 1;
873 			} else {
874 				calendar.month = 12;
875 			}
876 		}
877 		break;
878 	case 3:	/* mm-1 */
879 		if (--calendar.month < 1) {
880 			if (calendar.year > SUPPORT_MIN_YEAR) {
881 				calendar.year--;
882 				calendar.month = 12;
883 			} else {
884 				calendar.month = 1;
885 			}
886 		}
887 		break;
888 	case 4:	/* dd+1 */
889 		date_inc((struct DATE_T *)&calendar, 1);
890 		break;
891 	case 5:	/* dd-1 */
892 		date_inc((struct DATE_T *)&calendar, -1);
893 		break;
894 	case -1:	/* dd + offset */
895 		date_inc((struct DATE_T *)&calendar, offset);
896 		break;
897 	default:
898 		return (FALSE);
899 	}
900 
901 	if (calendar.year < SUPPORT_MIN_YEAR) {
902 		calendar.year = SUPPORT_MIN_YEAR;
903 		calendar.month = 1;
904 		calendar.day = 1;
905 	}
906 	if (calendar.year > SUPPORT_MAX_YEAR) {
907 		calendar.year = SUPPORT_MAX_YEAR;
908 		calendar.month = 12;
909 		calendar.day = GetDayofMonth(calendar.year, calendar.month);
910 	}
911 
912 	if (calendar.month == 2 && calendar.day == 29 && isleap(calendar.year) == 0) {
913 		calendar.month = 3;
914 		calendar.day = 1;
915 	}
916 
917 	return (TRUE);
918 }
919 
920 BOOL CALLBACK SetDateDlgProc(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam)
921 {
922 	BOOL	bFlag;
923 
924 	switch (iMessage) {
925 	case WM_INITDIALOG:
926 		SetClassLong(hDlg, GCL_HICON, (LONG)LoadIcon(ghInstance, MAKEINTRESOURCE(IDI_ICON1)));
927 		CenterWindow(hDlg, GetParent(hDlg));
928 		SetDlgItemInt(hDlg, IDC_EDIT_YY, calendar.year,  TRUE);
929 		SetDlgItemInt(hDlg, IDC_EDIT_MM, calendar.month, TRUE);
930 		SetDlgItemInt(hDlg, IDC_EDIT_DD, calendar.day,   TRUE);
931 		SendDlgItemMessage(hDlg, IDC_EDIT_YY, EM_LIMITTEXT, 4, 0L);
932 		SendDlgItemMessage(hDlg, IDC_EDIT_MM, EM_LIMITTEXT, 2, 0L);
933 		SendDlgItemMessage(hDlg, IDC_EDIT_DD, EM_LIMITTEXT, 2, 0L);
934 		return (TRUE);
935 	case WM_COMMAND:
936 		switch (LOWORD(wParam)) {
937 		case IDOK:
938 			input_ymd.year  = GetDlgItemInt(hDlg, IDC_EDIT_YY, &bFlag, TRUE);
939 			input_ymd.month = GetDlgItemInt(hDlg, IDC_EDIT_MM, &bFlag, TRUE);
940 			input_ymd.day   = GetDlgItemInt(hDlg, IDC_EDIT_DD, &bFlag, TRUE);
941 			if (isDate(input_ymd.year, input_ymd.month, input_ymd.day) == FALSE) {
942 				MessageBox(hDlg, "���դ�����������ޤ���", "��������", MB_ICONINFORMATION | MB_OK);
943 			} else {
944 				EndDialog(hDlg, 1);
945 			}
946 			return (TRUE);
947 		case IDCANCEL:
948 			EndDialog(hDlg, 0);
949 			return (TRUE);
950 		}
951 		break;
952 	case WM_CLOSE:
953 		EndDialog(hDlg, 0);
954 		return (TRUE);
955 	}
956 
957 	return (FALSE);
958 }
959 
960 BOOL CALLBACK DateOffsetDlgProc(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam)
961 {
962 	BOOL	bFlag;
963 	int		offset;
964 
965 	switch (iMessage) {
966 	case WM_INITDIALOG:
967 		SetClassLong(hDlg, GCL_HICON, (LONG)LoadIcon(ghInstance, MAKEINTRESOURCE(IDI_ICON1)));
968 		CenterWindow(hDlg, GetParent(hDlg));
969 		SetDlgItemInt(hDlg, IDC_EDIT_DDOFFSET, 0,  TRUE);
970 		SendDlgItemMessage(hDlg, IDC_EDIT_DDOFFSET, EM_LIMITTEXT, 5, 0L);
971 		return (TRUE);
972 	case WM_COMMAND:
973 		switch (LOWORD(wParam)) {
974 		case IDOK:
975 			offset = GetDlgItemInt(hDlg, IDC_EDIT_DDOFFSET, &bFlag, TRUE);
976 			if (bFlag == FALSE) {
977 				MessageBox(hDlg, "����������������ޤ���", "��������", MB_ICONINFORMATION | MB_OK);
978 			} else {
979 				dateControl(-1, offset);
980 				EndDialog(hDlg, 1);
981 			}
982 			return (TRUE);
983 		case IDCANCEL:
984 			EndDialog(hDlg, 0);
985 			return (TRUE);
986 		}
987 		break;
988 	case WM_CLOSE:
989 		EndDialog(hDlg, 0);
990 		return (TRUE);
991 	}
992 
993 	return (FALSE);
994 }
995 
996 /*
997  * CALfW �ε�ư
998  */
999 static
1000 void showCalendar(HWND hWnd)
1001 {
1002 	HWND	hwndCal;
1003 	STARTUPINFO	si;
1004 	PROCESS_INFORMATION	pi;
1005 	char	szCommandLine[256];
1006 	LPARAM	lParam;
1007 
1008 	hwndCal = FindWindow(szCalClass, NULL);
1009 	if (hwndCal == NULL) {
1010 		ZeroMemory(&si, sizeof(si));
1011 		ZeroMemory(&pi, sizeof(pi));
1012 		si.cb = sizeof(STARTUPINFO);
1013 		si.dwFlags = STARTF_USESHOWWINDOW;
1014 		si.wShowWindow = SW_SHOWNORMAL;
1015 		sprintf(szCommandLine, "%s %02d %04d", szCalCmd, calendar.month, calendar.year);
1016 		if (CreateProcess(NULL, szCommandLine, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi) == FALSE) {
1017 			sprintf(szCommandLine, "%s �����Ĥ���ޤ���", szCalCmd);
1018 			MessageBox(hWnd, szCommandLine, szAppName, MB_ICONEXCLAMATION | MB_OK);
1019 		} else {
1020 			CloseHandle(pi.hThread);
1021 			CloseHandle(pi.hProcess);
1022 		}
1023 	} else {
1024 		if (IsIconic(hwndCal)) {
1025 			ShowWindow(hwndCal, SW_RESTORE);
1026 		}
1027 		SetForegroundWindow(hwndCal);
1028 		lParam = (calendar.year << 9) | (calendar.month << 5);
1029 		SendMessage(hwndCal, umsgCal, 0, lParam);
1030 	}
1031 }
1032 
1033 /*
1034  * ɽ���ƥ����ȤΥե�����ؤν���
1035  */
1036 static
1037 void saveDisplayText(HWND hWnd)
1038 {
1039 	OPENFILENAME	ofn;
1040 	char	fileName[MAX_PATH+1];
1041 	FILE	*ofp;
1042 	int		i;
1043 
1044 	strcpy(fileName, make_filename(_T_OUTFILE_DEFAULT));
1045 
1046 	memset(&ofn, '\0', sizeof(ofn));
1047 	ofn.lStructSize = sizeof(OPENFILENAME);
1048 	ofn.hwndOwner = hWnd;
1049 	ofn.lpstrFile = fileName;
1050 	ofn.nMaxFile = MAX_PATH;
1051 	ofn.lpstrFileTitle = NULL;
1052 	ofn.lpstrTitle = "��̽�����";
1053 	ofn.lpstrDefExt = NULL;
1054 	ofn.Flags = OFN_HIDEREADONLY | OFN_NOREADONLYRETURN | OFN_OVERWRITEPROMPT;
1055 
1056 	if (GetSaveFileName(&ofn) != FALSE) {
1057 		ofp = fopen(fileName, "w");
1058 		if (ofp == NULL) {
1059 			errprint("��̽���", ERR_ERROR, "�ե����륪���ץ��顼: %s", fileName);
1060 		} else {
1061 			for (i = 0; i < textLines; i++) {
1062 				fprintf(ofp, "%s\n", textBuf[i]);
1063 			}
1064 			fclose(ofp);
1065 		}
1066 	}
1067 }
1068 
1069 /*
1070  * ɽ���ƥ����ȤΥ���åץܡ��ɤؤν���
1071  */
1072 static
1073 void copyClipboardDisplayText(HWND hWnd)
1074 {
1075 	int	i;
1076 	DWORD	memSize;
1077 	HGLOBAL	hData;
1078 	LPTSTR	pData;
1079 
1080 	memSize = 0;
1081 	for (i = 0; i < textLines; i++) {
1082 		memSize += strlen(textBuf[i]) + 2;	/* CR + LF */
1083 	}
1084 	memSize++;	/* \0 */
1085 
1086 	hData = GlobalAlloc(GHND | GMEM_DDESHARE, memSize);
1087 	if (hData == NULL) {
1088 		memerr("copyClipboardDisplayText[GlobalAlloc:GHND]");
1089 	}
1090 	pData = GlobalLock(hData);
1091 	if (pData == NULL) {
1092 		memerr("copyClipboardDisplayText[GlobalLock]");
1093 	}
1094 
1095 	for (i = 0; i < textLines; i++) {
1096 		sprintf(pData, "%s\r\n", textBuf[i]);
1097 		pData += strlen(pData);
1098 	}
1099 
1100 	GlobalUnlock(hData);
1101 
1102 	if (OpenClipboard(hWnd) == FALSE) {
1103 		GlobalFree(hData);
1104 	} else {
1105 		EmptyClipboard();
1106 		SetClipboardData(CF_TEXT, hData);
1107 		CloseClipboard();
1108 	}
1109 }
1110 
1111 /* ------------------------------------------------------------------------- */
1112 
1113 /*
1114  * ������ɥ��Υ����ȥ롢��˥塼���ġ���С���ͭ����̵������
1115  */
1116 static
1117 void updateWindowFrameStatus(HWND hWnd)
1118 {
1119 	char	mbuf[128];
1120 	HMENU	hMenu;
1121 
1122 	sprintf(mbuf, "%04d/%02d/%02d - %s", calendar.year, calendar.month, calendar.day, szAppNameLong);
1123 	SetWindowText(hWnd, mbuf);
1124 
1125 #define MENU_ENABLE(x)	((x) ? (MF_BYCOMMAND | MFS_ENABLED) : (MF_BYCOMMAND | MFS_GRAYED))
1126 	hMenu = GetMenu(hWnd);
1127 	EnableMenuItem(hMenu, IDM_FILEOUT, MENU_ENABLE(textLines > 0));
1128 	EnableMenuItem(hMenu, IDM_COPY, MENU_ENABLE(textLines > 0));
1129 #define BUTTON_ENABLE(x)	((x) ? TRUE : FALSE)
1130 	SendMessage(hwndToolbar, TB_ENABLEBUTTON, IDM_FILEOUT, BUTTON_ENABLE(textLines > 0));
1131 	SendMessage(hwndToolbar, TB_ENABLEBUTTON, IDM_COPY, BUTTON_ENABLE(textLines > 0));
1132 }
1133 
1134 /*
1135  * TODAY main �θƤӽФ����ƥ����Ȥ�ɽ��
1136  */
1137 static
1138 void CallTodayAndDisplayText(HWND hWnd, int type)
1139 {
1140 	execute_today(hWnd, type);
1141 	updateWindowFrameStatus(hWnd);
1142 	setupDisplayText(hwndMsg);
1143 }
1144 
1145 /*
1146  * ��ĥ�ݥåץ��åץ�˥塼������
1147  */
1148 static
1149 void initPopupMenu(HWND hWnd, WPARAM wParam, LPARAM lParam)
1150 {
1151 	HMENU	hSubMenu = GetSubMenu(GetMenu(hWnd), 1);
1152 	int		mcount;
1153 	char	szText[32];
1154 
1155 	if ((HMENU)wParam == hSubMenu) {
1156 		mcount = GetMenuItemCount(hSubMenu);
1157 		if (file_editor_cmd == NULL) {
1158 			if (mcount != MAX_EDIT_MENU) {
1159 				DeleteMenu(hSubMenu, MAX_EDIT_MENU + 1, MF_BYPOSITION);
1160 				DeleteMenu(hSubMenu, MAX_EDIT_MENU + 0, MF_BYPOSITION);
1161 			}
1162 		} else {
1163 			if (mcount == MAX_EDIT_MENU) {
1164 				LoadString(ghInstance, IDM_EXT_EDIT, szText, sizeof(szText));
1165 				AppendMenu(hSubMenu, MFT_SEPARATOR, 0, NULL);
1166 				AppendMenu(hSubMenu, MFT_STRING, IDM_EXT_EDIT, szText);
1167 			}
1168 		}
1169 	}
1170 }
1171 
1172 /*
1173  * �ġ�����åפΥƥ���������
1174  */
1175 static
1176 void notifyToolbar(LPTOOLTIPTEXT lpToolTipText)
1177 {
1178 	static char	szBuffer[64];
1179 
1180 	if (lpToolTipText->hdr.code == TTN_NEEDTEXT) {
1181 		LoadString(ghInstance, lpToolTipText->hdr.idFrom, szBuffer, sizeof(szBuffer));
1182 		lpToolTipText->lpszText = szBuffer;
1183 	}
1184 }
1185 
1186 /*
1187  * ɽ���ե���Ȥκ���
1188  */
1189 HFONT createDisplayFontObject(HWND hwnd, const char *fontname, int *fontsize)
1190 {
1191 	HDC	hDC;
1192 	HFONT	hFont;
1193 	int	fontSize;
1194 
1195 	if (fontname == NULL) {
1196 		hFont = NULL;
1197 	} else {
1198 		if (*fontsize < MIN_FONTSIZE) {
1199 			*fontsize = DEFAULT_FONTSIZE;
1200 		} else if (*fontsize > MAX_FONTSIZE) {
1201 			*fontsize = MAX_FONTSIZE;
1202 		}
1203 		hDC = GetDC(hwnd);
1204 		fontSize = -MulDiv(*fontsize, GetDeviceCaps(hDC, LOGPIXELSY), 72);
1205 		ReleaseDC(hwnd, hDC);
1206 		hFont = CreateFont(fontSize, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE,
1207 					SHIFTJIS_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
1208 					PROOF_QUALITY, DEFAULT_PITCH | FF_DONTCARE, fontname);
1209 	}
1210 
1211 	return (hFont);
1212 }
1213 
1214 /*
1215  * �ƥ�����ɽ���ѥ꥽�����κ���
1216  * ɽ���ե���ȡ��طʥ֥饷�κ���
1217  *
1218  * bStarting = TRUE:��ư��
1219  */
1220 static
1221 void createDisplayResource(HWND hWnd, BOOL bStarting)
1222 {
1223 	HDC	hdc;
1224 	TEXTMETRIC	tm;
1225 	HBRUSH	brushBgNew;
1226 
1227 	if (hDispFont != NULL) {
1228 		DeleteObject(hDispFont);
1229 	}
1230 
1231 	hDispFont = createDisplayFontObject(hWnd, disp_fontname, &disp_fontsize);
1232 	hdc = GetDC(hWnd);
1233 	if (hDispFont == NULL) {
1234 		SelectObject(hdc, GetStockObject(SYSTEM_FIXED_FONT));
1235 	} else {
1236 		SelectObject(hdc, hDispFont);
1237 	}
1238 	GetTextMetrics(hdc, &tm);
1239 	ReleaseDC(hWnd, hdc);
1240 	sizeChar.cx = tm.tmAveCharWidth;
1241 	sizeChar.cy = tm.tmHeight + tm.tmExternalLeading;
1242 
1243 	brushBgNew = CreateSolidBrush(RGB2PALETTERGB(win_colormap[MASK_COL_BG(win_default_color)]));
1244 	if (bStarting == FALSE) {
1245 		SetClassLong(hWnd, GCL_HBRBACKGROUND, (LONG)brushBgNew);
1246 		if (brushBg != NULL) {
1247 			DeleteObject(brushBg);
1248 		}
1249 	}
1250 	brushBg = brushBgNew;
1251 }
1252 
1253 /*
1254  * createDisplayResource() �Ǻ��������꥽�����β���
1255  */
1256 static
1257 void deleteDisplayResource(HWND hWnd)
1258 {
1259 	if (hDispFont != NULL) {
1260 		DeleteObject(hDispFont);
1261 		hDispFont = NULL;
1262 	}
1263 	if (brushBg != NULL) {
1264 		DeleteObject(brushBg);
1265 		brushBg = NULL;
1266 	}
1267 }
1268 
1269 /*
1270  * ������ɥ����ΤΥ�������Ĵ������
1271  *
1272  * �ġ���С������������ƤӽФ�����
1273  */
1274 static
1275 void setupWindowFrameSize(HWND hWnd)
1276 {
1277 	int		cx;
1278 	int		cy;
1279 	int		sx;
1280 	int		sy;
1281 	RECT	rcWindow;
1282 
1283 	cx = screen_max_columns * sizeChar.cx +
1284 	     GetSystemMetrics(SM_CXSIZEFRAME) * 2 +
1285 	     GetSystemMetrics(SM_CXEDGE) * 2 +
1286 	     GetSystemMetrics(SM_CXVSCROLL);
1287 	cy = screen_max_rows * sizeChar.cy +
1288 	     GetSystemMetrics(SM_CYSIZEFRAME) * 2 +
1289 	     GetSystemMetrics(SM_CYEDGE) * 2 +
1290 	     GetSystemMetrics(SM_CYCAPTION) +
1291 	     GetSystemMetrics(SM_CYMENU) +
1292 	     GetSystemMetrics(SM_CYHSCROLL) +
1293 	     sizeToolbar.cy;
1294 
1295 	SystemParametersInfo(SPI_GETWORKAREA, 0, &rcWindow, 0);
1296 	sx = rcWindow.right - rcWindow.left;
1297 	sy = rcWindow.bottom - rcWindow.top;
1298 
1299 	while (cx > sx) {
1300 		cx -= sizeChar.cx;
1301 	}
1302 	while (cy > sy) {
1303 		cy -= sizeChar.cy;
1304 	}
1305 
1306 	SetWindowPos(hWnd, HWND_TOP, 0, 0, cx, cy, SWP_NOMOVE);
1307 	CenterWindow(hWnd, NULL);
1308 }
1309 
1310 /*
1311  * �ġ���С����ƥ�����ɽ��������ɥ��κ���
1312  */
1313 static
1314 BOOL createWindowFrame(HWND hWnd)
1315 {
1316 	BOOL	bFlat;
1317 	DWORD	dStyle;
1318 	RECT	rcWindow;
1319 	WNDCLASS	wndclass;
1320 	char	szText[256];
1321 
1322 	InitCommonControls();
1323 
1324 	if (CHK_SYSFLAGS(SYSFLAGS_TOOLFLAT) != FALSE &&
1325 	    GetDllVersion("comctl32.dll") >= PACKVERSION(4,70)) {
1326 		bFlat = TRUE;
1327 	} else {
1328 		bFlat = FALSE;
1329 	}
1330 
1331 	hwndToolbar = CreateToolbarEx(hWnd, WS_CHILD | WS_VISIBLE | TBSTYLE_TOOLTIPS,
1332 		IDC_TOOLBAR, NUMIMAGES, ghInstance, bFlat ? IDB_TBFLAT : IDB_TBHOT,
1333 		tbButton, sizeof(tbButton) / sizeof(TBBUTTON), 0, 0, IMAGEWIDTH, IMAGEHEIGHT, sizeof(TBBUTTON));
1334 
1335 	if (hwndToolbar == NULL) {
1336 		MessageBox(hWnd, "�ġ���С��������Ǥ��ޤ���", szAppNameLong, MB_ICONEXCLAMATION | MB_OK);
1337 		DestroyWindow(hWnd);
1338 		return (FALSE);
1339 	}
1340 	if (bFlat != FALSE) {
1341 		dStyle = SendMessage(hwndToolbar, TB_GETSTYLE, 0, 0L);
1342 		SendMessage(hwndToolbar, TB_SETSTYLE,0, (dStyle | TBSTYLE_FLAT));
1343 		hImgList = ImageList_LoadBitmap(ghInstance, MAKEINTRESOURCE(IDB_TBHOT), IMAGEWIDTH, 1, IMAGEMASKRGB);
1344 		SendMessage(hwndToolbar, TB_SETHOTIMAGELIST, 0, (LPARAM)hImgList);
1345 //		ShowWindow(hwndToolbar, SW_HIDE);
1346 //		ShowWindow(hwndToolbar, SW_SHOW);
1347 	}
1348 
1349 	GetWindowRect(hwndToolbar, &rcWindow);
1350 	sizeToolbar.cx = rcWindow.right - rcWindow.left;
1351 	sizeToolbar.cy = rcWindow.bottom - rcWindow.top;
1352 
1353 	setupWindowFrameSize(hWnd);
1354 
1355 	wndclass.style         = 0;
1356 	wndclass.lpfnWndProc   = (WNDPROC)MsgWndProc;
1357 	wndclass.cbClsExtra    = 0;
1358 	wndclass.cbWndExtra    = 0;
1359 	wndclass.hInstance     = ghInstance;
1360 	wndclass.hIcon         = NULL;
1361 	wndclass.hCursor       = LoadCursor(NULL, IDC_ARROW);
1362 	wndclass.hbrBackground = brushBg;
1363 	wndclass.lpszMenuName  = NULL;
1364 	wndclass.lpszClassName = szAppNameMsg;
1365 
1366 	if (!RegisterClass(&wndclass)) {
1367 		DestroyWindow(hWnd);
1368 		return (FALSE);
1369 	}
1370 
1371 	hwndMsg = CreateWindowEx(WS_EX_CLIENTEDGE, szAppNameMsg, NULL,
1372 				WS_CHILD | WS_VISIBLE | WS_HSCROLL | WS_VSCROLL,
1373 				0, 0, 0, 0,
1374 				hWnd, (HMENU)IDC_MSGWIN, ghInstance, NULL);
1375 
1376 	if (hwndMsg == NULL) {
1377 		DestroyWindow(hWnd);
1378 		return (FALSE);
1379 	}
1380 	SetFocus(hwndMsg);
1381 
1382 	sprintf(szText, "%s Control Message", szAppName);
1383 	umsgToday = RegisterWindowMessage(szText);
1384 	sprintf(szText, "%s Control Message", szCalClass);
1385 	umsgCal = RegisterWindowMessage(szText);
1386 
1387 	return (TRUE);
1388 }
1389 
1390 /*
1391  * createWindowFrame() �Ǻ��������꥽�����β���
1392  */
1393 static
1394 void deleteWindowFrame(HWND hWnd)
1395 {
1396 	if (hImgList != NULL) {
1397 		ImageList_Destroy(hImgList);
1398 		hImgList = NULL;
1399 	}
1400 }
1401 
1402 LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam)
1403 {
1404 	PAINTSTRUCT	ps;
1405 	struct DATE_T	nowDate;
1406 	BOOL	bChangeDisplay;
1407 
1408 	if (iMessage == umsgToday) {
1409 		input_ymd.year  = (lParam >> 9) & 0x3FFF;
1410 		input_ymd.month = (lParam >> 5) & 0x000F;
1411 		input_ymd.day   = lParam & 0x001F;
1412 		if (isDate(input_ymd.year, input_ymd.month, input_ymd.day) == TRUE) {
1413 			calendar.year  = input_ymd.year;
1414 			calendar.month = input_ymd.month;
1415 			calendar.day   = input_ymd.day;
1416 			CallTodayAndDisplayText(hWnd, T_CALL_DATECHANGE);
1417 		}
1418 		return (0);
1419 	}
1420 
1421 	switch (iMessage) {
1422 	case WM_CREATE:
1423 		createDisplayResource(hWnd, TRUE);
1424 		if (createWindowFrame(hWnd) == TRUE) {
1425 			CallTodayAndDisplayText(hWnd, T_CALL_FIRST);
1426 		}
1427 		break;
1428 	case WM_COMMAND:
1429 		switch (LOWORD(wParam)) {
1430 		case IDM_SETUP:
1431 			if (setupPropertyProc(hWnd, ghInstance, &bChangeDisplay) == TRUE) {
1432 				if (MessageBox(hWnd, "�ѹ����Ƥ�ե�����(TODAY.CNF)\n����¸���ޤ���?", "�ץ�ѥƥ�", MB_ICONINFORMATION | MB_YESNO) == IDYES) {
1433 					preserveConfig(hWnd);
1434 				}
1435 				if (bChangeDisplay == TRUE) {
1436 					createDisplayResource(hWnd, FALSE);
1437 					setupWindowFrameSize(hWnd);
1438 				}
1439 				CallTodayAndDisplayText(hWnd, T_CALL_DATENOW);
1440 			}
1441 			break;
1442 		case IDM_EXIT:
1443 			DestroyWindow(hwndMsg);
1444 			DestroyWindow(hWnd);
1445 			break;
1446 		case IDM_FILEOUT:
1447 			saveDisplayText(hWnd);
1448 			break;
1449 		case IDM_COPY:
1450 			copyClipboardDisplayText(hWnd);
1451 			break;
1452 		case IDM_EXT_EDIT:
1453 			nowDate.year = calendar.year;
1454 			nowDate.month = calendar.month;
1455 			nowDate.day = calendar.day;
1456 			externalFileEdit(hWnd, ghInstance, nowDate);
1457 			break;
1458 		case IDM_FINDSTRING:
1459 			findString(hWnd, ghInstance);
1460 			break;
1461 		case IDM_DATENOW:
1462 			CallTodayAndDisplayText(hWnd, T_CALL_DATENOW);
1463 			break;
1464 		case IDM_DATESET:
1465 			if (DialogBox(ghInstance, MAKEINTRESOURCE(IDD_SETDATE1), hWnd, (DLGPROC)SetDateDlgProc) == 1) {
1466 				calendar.year  = input_ymd.year;
1467 				calendar.month = input_ymd.month;
1468 				calendar.day   = input_ymd.day;
1469 				CallTodayAndDisplayText(hWnd, T_CALL_DATECHANGE);
1470 			}
1471 			break;
1472 		case IDM_DATEOFFSET:
1473 			if (DialogBox(ghInstance, MAKEINTRESOURCE(IDD_SETDATE2), hWnd, (DLGPROC)DateOffsetDlgProc) == 1) {
1474 				CallTodayAndDisplayText(hWnd, T_CALL_DATECHANGE);
1475 			}
1476 			break;
1477 		case IDM_SHOWCAL:
1478 			showCalendar(hWnd);
1479 			break;
1480 		case IDM_HELP:
1481 			WinHelp(hWnd, szHelpFile, HELP_FINDER, 0L);
1482 			break;
1483 		case IDM_ABOUT:
1484 			DialogBox(ghInstance, MAKEINTRESOURCE(IDD_ABOUT), hWnd, (DLGPROC)AboutDlgProc);
1485 			break;
1486 		case IDM_YYUP:
1487 		case IDM_YYDOWN:
1488 		case IDM_MMUP:
1489 		case IDM_MMDOWN:
1490 		case IDM_DDUP:
1491 		case IDM_DDDOWN:
1492 			if (dateControl(LOWORD(wParam) - IDM_YYUP, 0) != FALSE) {
1493 				CallTodayAndDisplayText(hWnd, T_CALL_DATECHANGE);
1494 			}
1495 			break;
1496 		}
1497 		break;
1498 	case WM_INITMENUPOPUP:
1499 		initPopupMenu(hWnd, wParam, lParam);
1500 		break;
1501 	case WM_NOTIFY:
1502 		notifyToolbar((LPTOOLTIPTEXT)lParam);
1503 		break;
1504 	case WM_SETFOCUS:
1505 		SetFocus(hwndMsg);
1506 		break;
1507 	case WM_SIZE:
1508 		SendMessage(hwndToolbar, WM_SIZE, wParam, lParam);
1509 		if (wParam != SIZE_MINIMIZED) {
1510 			MoveWindow(hwndMsg, 0, sizeToolbar.cy, LOWORD(lParam), HIWORD(lParam) - sizeToolbar.cy, TRUE);
1511 			if (wParam == SIZE_MAXIMIZED) {
1512 				InvalidateRect(hwndMsg, NULL, FALSE);
1513 			}
1514 		}
1515 		break;
1516 	case WM_PAINT:
1517 		SendMessage(hwndToolbar, WM_PAINT, wParam, lParam);
1518 		SendMessage(hwndMsg, WM_PAINT, wParam, lParam);
1519 		BeginPaint(hWnd, &ps);
1520 		EndPaint(hWnd, &ps);
1521 		break;
1522 	case WM_EXITSIZEMOVE:
1523 		InvalidateRect(hwndMsg, NULL, TRUE);
1524 		break;
1525 	case WM_DESTROY:
1526 		terminate_today(hWnd);
1527 		deleteWindowFrame(hWnd);
1528 		deleteDisplayResource(hWnd);
1529 		WinHelp(hWnd, szHelpFile, HELP_QUIT, 0L);
1530 		externalFileEditCleanup();
1531 		PostQuitMessage(0);
1532 		break;
1533 	case WM_QUERYENDSESSION:
1534 		DestroyWindow(hwndMsg);
1535 		DestroyWindow(hWnd);
1536 		return (TRUE);
1537 	default:
1538 		return (DefWindowProc(hWnd, iMessage, wParam, lParam));
1539 	}
1540 
1541 	return (0);
1542 }
1543 
1544 /* ------------------------------------------------------------------------- */
1545 
1546 static
1547 void setupResource(void)
1548 {
1549 	DWORD	dwSize;
1550 	DWORD	dwReserved;
1551 	LPVOID	lpBuffer;
1552 	LPVOID	lpStr;
1553 	UINT	uLen;
1554 	char	buf[MAX_PATH+1];
1555 	char	*p;
1556 
1557 	dwSize = GetFileVersionInfoSize(argv[0], &dwReserved);
1558 	if (dwSize != 0) {
1559 		lpBuffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwSize);
1560 		if (lpBuffer && GetFileVersionInfo(argv[0], dwReserved, dwSize, lpBuffer)) {
1561 #define VERPATH	"\\StringFileInfo\\041103A4\\"
1562 			VerQueryValue(lpBuffer, VERPATH "InternalName", &lpStr, &uLen);
1563 			szAppName = xstrdup(lpStr);
1564 			sprintf(buf, "%s Message", szAppName);
1565 			szAppNameMsg = xstrdup(buf);
1566 			sprintf(buf, "%s Mutex", szAppName);
1567 			szAppNameMutex = xstrdup(buf);
1568 			VerQueryValue(lpBuffer, VERPATH "ProductName", &lpStr, &uLen);
1569 			szAppNameLong = xstrdup(lpStr);
1570 			VerQueryValue(lpBuffer, VERPATH "LegalCopyright", &lpStr, &uLen);
1571 			szCopyright = xstrdup(lpStr);
1572 			VerQueryValue(lpBuffer, VERPATH "ProductVersion", &lpStr, &uLen);
1573 			szVersion = xstrdup(lpStr);
1574 			VerQueryValue(lpBuffer, VERPATH "Comments", &lpStr, &uLen);
1575 			szComment = xstrdup(lpStr);
1576 			VerQueryValue(lpBuffer, VERPATH "OriginalFilename", &lpStr, &uLen);
1577 			memset(buf, '\0', sizeof(buf));
1578 			strncpy(buf, lpStr, sizeof(buf) - 1);
1579 			p = strstr(buf, ".exe");
1580 			if (p != NULL) {
1581 				strcpy(p, ".HLP");
1582 				szHelpFile = xstrdup(buf);
1583 			}
1584 		}
1585 		if (lpBuffer) {
1586 			HeapFree(GetProcessHeap(), 0, lpBuffer);
1587 		}
1588 	}
1589 
1590 	if (LoadString(ghInstance, IDS_CALCLASS, buf, sizeof(buf) - 1) != 0) {
1591 		szCalClass = xstrdup(buf);
1592 	}
1593 	if (LoadString(ghInstance, IDS_CALCMD, buf, sizeof(buf) - 1) != 0) {
1594 		szCalCmd = xstrdup(buf);
1595 	}
1596 }
1597 
1598 static
1599 void copychar(char **dst, char **src)
1600 {
1601 	if ((*src)[0] == '\\' && (*src)[1] == '"') {
1602 		**dst = '"';
1603 		*src += 2;
1604 	} else if (IsDBCSLeadByte((*src)[0]) && (*src)[1]) {
1605 		**dst = **src;
1606 		*src += 1;
1607 		*dst += 1;
1608 		**dst = **src;
1609 		*src += 1;
1610 	} else {
1611 		**dst = **src;
1612 		*src += 1;
1613 	}
1614 	*dst += 1;
1615 }
1616 
1617 #define is_space(x)	((x) == ' ' || (x) == '\t')
1618 
1619 static
1620 void setupArgParam(char *cmdline)
1621 {
1622 	char	szFullPath[MAX_PATH+1];
1623 	char	*arv[MAXARGS];
1624 	char	*bufp;
1625 	char	*src;
1626 	char	*dst;
1627 
1628 	GetModuleFileName(ghInstance, szFullPath, sizeof(szFullPath));
1629 	arv[0] = xstrdup(szFullPath);
1630 	argc = 1;
1631 
1632 	bufp = malloc(strlen(cmdline) + 1);
1633 	if (bufp == NULL) {
1634 		memerr("setupArgParam");
1635 	}
1636 
1637 	src = cmdline;
1638 	while (*src != '\0') {
1639 		while (is_space(*src)) {
1640 			src++;
1641 		}
1642 		if (*src == '\0') {
1643 			break;
1644 		}
1645 		dst = bufp;
1646 		while (is_space(*src) == 0 && *src != '\0') {
1647 			if (*src == '"') {
1648 				src++;
1649 				while (*src != '"' && *src != '\0') {
1650 					copychar(&dst, &src);
1651 				}
1652 				if (*src == '"') {
1653 					src++;
1654 				}
1655 			} else {
1656 				copychar(&dst, &src);
1657 			}
1658 		}
1659 		*dst = '\0';
1660 		if ((argc + 1) >= MAXARGS) {
1661 			break;
1662 		}
1663 		arv[argc++] = xstrdup(bufp);
1664 		if (*src == '\0') {
1665 			break;
1666 		}
1667 		src++;
1668 	}
1669 	arv[argc] = NULL;
1670 
1671 	free(bufp);
1672 
1673 	argv = malloc(sizeof(char *) * (argc + 1));
1674 	if (argv != NULL) {
1675 		memcpy(argv, arv, sizeof(char *) * (argc + 1));
1676 	} else {
1677 		memerr("setupArgParam");
1678 	}
1679 }
1680 
1681 static
1682 BOOL initInstance(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine)
1683 {
1684 	DWORD	rtc;
1685 	HWND	hwnd;
1686 
1687 	if (hPrevInstance) {
1688 		return (FALSE);
1689 	}
1690 
1691 	ghInstance = hInstance;
1692 
1693 	setupArgParam(lpCmdLine);
1694 	setupResource();
1695 
1696 	hMutex = CreateMutex(NULL, FALSE, szAppNameMutex);
1697 	if (hMutex == NULL) {
1698 		goto activewindow;
1699 	}
1700 	rtc = WaitForSingleObject(hMutex, 0);
1701 	if (rtc == WAIT_TIMEOUT || rtc == WAIT_FAILED) {
1702 		CloseHandle(hMutex);
1703 activewindow:
1704 		hwnd = FindWindow(szAppName, NULL);
1705 		if (hwnd != NULL) {
1706 			if (IsIconic(hwnd)) {
1707 				ShowWindow(hwnd, SW_RESTORE);
1708 			}
1709 			SetForegroundWindow(hwnd);
1710 		}
1711 		return (FALSE);
1712 	}
1713 
1714 	return (TRUE);
1715 }
1716 
1717 static
1718 void exitInstance(void)
1719 {
1720 	if (hMutex) {
1721 		CloseHandle(hMutex);
1722 	}
1723 }
1724 
1725 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
1726 {
1727 	WNDCLASSEX	wcex;
1728 	HWND	hWnd;
1729 	HACCEL	hAccel;
1730 	MSG		msg;
1731 
1732 	if (initInstance(hInstance, hPrevInstance, lpCmdLine) == FALSE) {
1733 		return (0);
1734 	}
1735 
1736 	if (configuration_today(argc, argv) == FALSE) {
1737 		msg.wParam = 0;
1738 		goto err_exit;
1739 	}
1740 
1741 	wcex.cbSize        = sizeof(WNDCLASSEX);
1742 	wcex.style         = 0;
1743 	wcex.lpfnWndProc   = (WNDPROC)WndProc;
1744 	wcex.cbClsExtra    = 0;
1745 	wcex.cbWndExtra    = 0;
1746 	wcex.hInstance     = hInstance;
1747 	wcex.hIcon         = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON1));
1748 	wcex.hCursor       = LoadCursor(NULL, IDC_IBEAM);
1749 	wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
1750 	wcex.lpszMenuName  = szAppName;
1751 	wcex.lpszClassName = szAppName;
1752 	wcex.hIconSm       = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON1));
1753 
1754 	if (!RegisterClassEx(&wcex)) {
1755 		msg.wParam = 0;
1756 		goto err_exit;
1757 	}
1758 
1759 	CreateSplashWindow(splash_timeout, 250);
1760 
1761 	hwndMain = hWnd = CreateWindowEx(0, szAppName, szAppNameLong,
1762 						WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
1763 						CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
1764 						NULL, NULL, hInstance, NULL);
1765 	if (hWnd == NULL) {
1766 		msg.wParam = 0;
1767 		goto err_exit;
1768 	}
1769 
1770 	ShowWindow(hWnd, nShowCmd);
1771 	UpdateWindow(hWnd);
1772 
1773 	DestroySplashWindow(FALSE);
1774 
1775 	hAccel = LoadAccelerators(hInstance, szAppName);
1776 
1777 	while (GetMessage(&msg, NULL, 0, 0)) {
1778 		if (!hAccel || !TranslateAccelerator(hWnd, hAccel, &msg)) {
1779 			TranslateMessage(&msg);
1780 			DispatchMessage(&msg);
1781 		}
1782 	}
1783 
1784 err_exit:
1785 	DestroyErrorWindow();
1786 	DestroySplashWindow(TRUE);
1787 	exitInstance();
1788 
1789 	return (msg.wParam);
1790 }
1791