1 /*
2  * calfw.c -- Calendar for Windows95/98/Me/NT4/2000/XP
3  *
4  * Copyright (C) 1997,1998,1999,2001,2003 by Yoshifumi Mori
5  *
6  * tab:4
7  */
8 
9 #include "cdefs.h"
10 #include "extern.h"
11 #include "calfw.rh"
12 
13 #define MAXARGS				1000
14 #define MAX_TOPMENU			4		/* default max top menu */
15 #define MAX_SHEET			3
16 #define MAXLINE				6
17 #define MAXWEEK				7
18 #define MAXDAYTBL			(MAXLINE * MAXWEEK)
19 #define CAL_CENTERMONTH		(CAL_MAXMONTH / 2)
20 #define SHOW_MAXMONTH		(CAL_MAXMONTH - 2)
21 #define SHOW_CENTERMONTH	(SHOW_MAXMONTH / 2)
22 #define POP_SKIP_X			5
23 #define POP_SKIP_Y			5
24 #define POP_SHADOW_X		6
25 #define POP_SHADOW_Y		6
26 #define BLK_XGAP			(3 * 2)
27 #define CLICK_TIMER			1
28 
29 #define FONT_ANK	"Comic Sans MS"
30 //#define FONT_ANK	"Microsoft Sans Serif"
31 #define FONT_KNJ	"�ͣ� �����å�"
32 
33 #define SHOW_FIRST		0
34 #define SHOW_TODAY		1
35 #define SHOW_SETDATE	2
36 
37 const char	*fmt_sep1 = "/\t ";
38 const char	*fmt_sep2 = ",\t ";
39 const char	*fmt_sep3 = "\t ";
40 const char	*fmt_sep4 = "";
41 
42 const char	*todaycnf_file = "today.cnf";
43 
44 #define ATTR_HOLIDAY	001	/* ���������� */
45 #define ATTR_TRANSHOL	002	/* ���ص��� */
46 #define ATTR_TODAY		004	/* ���� */
47 #define ATTR_LUNARCAL	010	/* ϻ��ͭ�� */
48 #define ATTR_SCHEDULE	020	/* �������塼�뤢�� */
49 #define ATTR_GRAYEDDAY	040	/* ���������� */
50 
51 typedef struct DAY_T {
52 	struct DATE_T	date;
53 	int	attr;
54 	int	holiday;
55 	struct LUNAR_CALENDAR	lc;
56 } *PDAYINFO, DAYINFO;
57 
58 typedef struct CAL_NAMETBL_T {
59 	int	year;
60 	int	month;
61 	const char	*name;
62 } CALNAME;
63 
64 struct POPMSG_T {
65 	int	cy;
66 	int	len;
67 	char	*msg;
68 };
69 
70 struct PROP_TBL {
71 	int		iResID;
72 	DLGPROC	DlgProc;
73 };
74 
75 struct CALTBL	caltbl[CAL_MAXMONTH];
76 
77 static CALNAME	tblCalName[SHOW_MAXMONTH];
78 static PDAYINFO	tblCalDay[SHOW_MAXMONTH][MAXDAYTBL];
79 static DAYINFO	tblDayInfo[CAL_MAXMONTH * MAX_DAYOFMONTH];
80 static struct CALENDAR	nowdate;
81 static struct DATE_T	curdate;
82 static struct DATE_T	input_ymd;
83 static DAYINFO	*popinfo;
84 
85 static int	argc;
86 static char	**argv;
87 static char	cmdpathbuf[_T_MAXPATHNAME];
88 
89        char	*szAppName;
90 static char	*szAppNameMsg;
91 static char	*szAppNameMutex;
92 static char	*szAppNameLong;
93 static char	*szCopyright;
94 static char	*szVersion;
95 static char	*szComment;
96        char	*szHelpFile;
97        char	*szTodayClass;
98 static char	*szTodayCmd;
99 
100 static HINSTANCE	ghInstance;
101 static HANDLE	hMutex;
102 static HWND		hwndMain;
103 static HWND		hwndToolbar;
104 static HIMAGELIST	hImgList;
105 static HWND		hwndMsg;
106 static UINT		umsgToday;
107 static UINT		umsgCal;
108 static HFONT	hfontA;
109 static HFONT	hfontK;
110 static SIZE		sizeToolbar;
111 static SIZE		sizeChar;
112 static SIZE		sizeKChar;
113 static SIZE		sizeBlk;
114 static BOOL		bChangeProp;
115 static BOOL		bChangeFont;
116 
117 #define NUMIMAGES		13
118 #define IMAGEWIDTH		16
119 #define IMAGEHEIGHT		16
120 #define IMAGEMASKRGB	RGB(0xC0, 0xC0, 0xC0)
121 
122 static const TBBUTTON	tbButton[] = {
123 	{  2, IDM_DATESET, TBSTATE_ENABLED, TBSTYLE_BUTTON,     { 0, 0 }, 0, 0 },
124 	{  0, 0,           TBSTATE_ENABLED, TBSTYLE_SEP,        { 0, 0 }, 0, 0 },
125 	{  4, IDM_YYDOWN,  TBSTATE_ENABLED, TBSTYLE_BUTTON,     { 0, 0 }, 0, 0 },
126 	{  5, IDM_MMDOWN,  TBSTATE_ENABLED, TBSTYLE_BUTTON,     { 0, 0 }, 0, 0 },
127 	{  1, IDM_DATENOW, TBSTATE_ENABLED, TBSTYLE_BUTTON,     { 0, 0 }, 0, 0 },
128 	{  6, IDM_MMUP,    TBSTATE_ENABLED, TBSTYLE_BUTTON,     { 0, 0 }, 0, 0 },
129 	{  7, IDM_YYUP,    TBSTATE_ENABLED, TBSTYLE_BUTTON,     { 0, 0 }, 0, 0 },
130 	{  0, 0,           TBSTATE_ENABLED, TBSTYLE_SEP,        { 0, 0 }, 0, 0 },
131 	{  8, IDM_MONTH1,  TBSTATE_ENABLED, TBSTYLE_CHECKGROUP, { 0, 0 }, 0, 0 },
132 	{  9, IDM_MONTH3,  TBSTATE_ENABLED, TBSTYLE_CHECKGROUP, { 0, 0 }, 0, 0 },
133 	{  0, 0,           TBSTATE_ENABLED, TBSTYLE_SEP,        { 0, 0 }, 0, 0 },
134 	{ 12, IDM_ROKUYOU, TBSTATE_ENABLED, TBSTYLE_CHECK,      { 0, 0 }, 0, 0 },
135 //	{  0, 0,           TBSTATE_ENABLED, TBSTYLE_SEP,        { 0, 0 }, 0, 0 },
136 //	{ 10, IDM_ABOUT,   TBSTATE_ENABLED, TBSTYLE_BUTTON,     { 0, 0 }, 0, 0 },
137 //	{ 11, IDM_HELP,    TBSTATE_ENABLED, TBSTYLE_BUTTON,     { 0, 0 }, 0, 0 },
138 };
139 
140 static const DWORD	propHelpID[] = {
141 // ɽ��
142 	IDC_DISP_CHK_01,		1101,
143 	IDC_DISP_CHK_02,		1102,
144 	IDC_DISP_CHK_03,		1103,
145 	IDC_DISP_CHK_04,		1104,
146 	IDC_DISP_CHK_05,		1105,
147 	IDC_DISP_CHK_06,		1106,
148 	IDC_DISP_CHK_07,		1107,
149 	IDC_DISP_CHK_08,		1108,
150 	IDC_DISP_CHK_09,		1109,
151 	IDC_DISP_CHK_10,		1112,	/* add */
152 	IDC_DISP_RBTN_1,		1110,
153 	IDC_DISP_RBTN_2,		1111,
154 // ��
155 	IDC_COL_EDIT_00,		1201,
156 	IDC_COL_EDIT_01,		1202,
157 	IDC_COL_EDIT_02,		1203,
158 	IDC_COL_EDIT_03,		1204,
159 	IDC_COL_EDIT_04,		1205,
160 	IDC_COL_EDIT_05,		1206,
161 	IDC_COL_EDIT_06,		1207,
162 	IDC_COL_EDIT_07,		1208,
163 	IDC_COL_EDIT_08,		1209,
164 	IDC_COL_EDIT_09,		1210,
165 	IDC_COL_EDIT_10,		1211,
166 	IDC_COL_EDIT_11,		1212,
167 	IDC_COL_EDIT_12,		1213,
168 	IDC_COL_EDIT_13,		1215,	/* add */
169 	IDC_COL_DRAW_S00,		1214,
170 	IDC_COL_DRAW_S01,		1214,
171 	IDC_COL_DRAW_S02,		1214,
172 	IDC_COL_DRAW_S03,		1214,
173 	IDC_COL_DRAW_S04,		1214,
174 	IDC_COL_DRAW_S05,		1214,
175 	IDC_COL_DRAW_S06,		1214,
176 	IDC_COL_DRAW_S07,		1214,
177 	IDC_COL_DRAW_S08,		1214,
178 	IDC_COL_DRAW_S09,		1214,
179 	IDC_COL_DRAW_S10,		1214,
180 	IDC_COL_DRAW_S11,		1214,
181 	IDC_COL_DRAW_S12,		1214,
182 	IDC_COL_DRAW_S13,		1214,
183 	IDC_COL_DRAW_S14,		1214,
184 	IDC_COL_DRAW_S15,		1214,
185 	IDC_COL_DRAW_00,		1240,	/* add */
186 	IDC_COL_DRAW_01,		1241,	/* add */
187 	IDC_COL_DRAW_02,		1242,	/* add */
188 	IDC_COL_DRAW_03,		1243,	/* add */
189 	IDC_COL_DRAW_04,		1244,	/* add */
190 	IDC_COL_DRAW_05,		1245,	/* add */
191 	IDC_COL_DRAW_06,		1246,	/* add */
192 	IDC_COL_DRAW_07,		1247,	/* add */
193 	IDC_COL_DRAW_08,		1248,	/* add */
194 	IDC_COL_DRAW_09,		1249,	/* add */
195 	IDC_COL_DRAW_10,		1250,	/* add */
196 	IDC_COL_DRAW_11,		1251,	/* add */
197 	IDC_COL_DRAW_12,		1252,	/* add */
198 	IDC_COL_DRAW_13,		1253,	/* add */
199 // �ե�����
200 	IDC_FILE_EDIT_SCHEDULE,	1301,
201 	IDC_FILE_EDIT_TABLE,	1302,
202 //
203 	0,						0
204 };
205 
206 static const char	*rokuyou_name[6] = {
207 	"�辡", "ͧ��", "����", "ʩ��", "���", "�ָ�"
208 };
209 static const char	*week_name[MAXWEEK] = {
210 	"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
211 };
212 static const int	week_index[2][MAXWEEK] = {
213 	{ 0, 1, 2, 3, 4, 5, 6 },	/* �������������� */
214 	{ 6, 0, 1, 2, 3, 4, 5 },	/* �������������� */
215 };
216 
217 #define COL_MAX			14		/* ���顼�ơ��֥�� */
218 #define COL_WEEKDAY		0		/* ʿ�� */
219 #define COL_SUNDAY		1		/* ���� */
220 #define COL_SATDAY		2		/* ���� */
221 #define COL_HOLIDAY		3		/* ����/���� */
222 #define COL_ROKUYOU		4		/* ϻ�� +0 -- +5 */
223 #define COL_SCHEDULE	10		/* �������塼�� */
224 #define COL_TITLE		11		/* �����ȥ� */
225 #define COL_FRAME		12		/* �� */
226 #define COL_GRAYDAY		13		/* ���쥤���� */
227 
228 static int	calcolor[COL_MAX];
229 
230 #define MAX_COLORMAP	16
231 
232 static int	colormap[MAX_COLORMAP] = {
233 	0x000000, 0x0000AA, 0x00AA00, 0x0055AA, 0xAA0000, 0xAA00AA, 0xAAAA00, 0xAAAAAA,
234 	0x555555, 0x5555FF, 0x55FF55, 0x55FFFF, 0xFF5555, 0xFF55FF, 0xFFFF55, 0xFFFFFF,
235 };
236 
237 static int	bigfont_flag = TRUE;
238 static int	cal3_flag = TRUE;
239 static int	rokuyou_flag = TRUE;
240 static int	rokuyou_item[6];		/* 0:ɽ�����ʤ�ϻ�� */
241 static int	schedule_flag;
242 
243 #define CHK_SYSFLAGS(flags)			CHK_BITFLAGS(sysflags,flags)
244 #define CHG_SYSFLAGS(flags)			CHG_BITFLAGS(sysflags,flags)
245 #define SET_SYSFLAGS(flags,state)	SET_BITFLAGS(sysflags,flags,state)
246 
247 #define SYSFLAGS_TOOLFLAT	0x00000001	/* Toolbar FLAT */
248 #define SYSFLAGS_WHEELMOUSE	0x00000002	/* wheel mouse */
249 static int	sysflags = 0;
250 
251 #define CHK_EXTFLAGS(flags)			CHK_BITFLAGS(extflags,flags)
252 #define CHG_EXTFLAGS(flags)			CHG_BITFLAGS(extflags,flags)
253 #define SET_EXTFLAGS(flags,state)	SET_BITFLAGS(extflags,flags,state)
254 
255 #define EXTFLAGS_GRAYEDDAY	0x00000001	/* Grayed day */
256 #define EXTFLAGS_WEEKTYPE	0x00000002	/* 0:sun-sat, 1:mon-sun */
257 #define EXTFLAGS_OLDCALSIZE	0x80000000	/* version 1.0 �ߴ������� */
258 static int	extflags = EXTFLAGS_GRAYEDDAY;
259 
260 static const struct OPERAND_TABLE	op_yesno[] = {
261 	{ "yes", TRUE  },
262 	{ "no",  FALSE },
263 	{ NULL,  0     },
264 };
265 
266 static struct CONFIG_VARIABLE_TABLE	conf_tbl[] = {
267 	{ "bigfont",         VAR_OP,     { op_yesno                }, { &bigfont_flag    } },
268 	{ "calcolor",        VAR_DIMINT, { (void *)COL_MAX         }, { calcolor         } },
269 	{ "colormap",        VAR_DIMINT, { (void *)MAX_COLORMAP    }, { colormap         }, 0x61 },
270 	{ "file_editor",     VAR_STR,    { NULL                    }, { &file_editor_cmd } },
271 	{ "find_editor",     VAR_STR,    { NULL                    }, { &find_editor_cmd } },
272 	{ "kyureki",         VAR_OP,     { op_yesno                }, { &rokuyou_flag    } },
273 	{ "replace_pathenv", VAR_OP,     { op_yesno                }, { &replace_pathenv } },
274 	{ "rokuyou",         VAR_DIMINT, { (void *)6               }, { rokuyou_item     } },
275 	{ "schedule",        VAR_OP,     { op_yesno                }, { &schedule_flag   } },
276 	{ "schedule_file",   VAR_DIMSTR, { (void *)MAXSCHEDULEFILE }, { schedule_filetbl } },
277 	{ "table_path",      VAR_STR,    { NULL                    }, { &search_path     } },
278 	{ "three_months",    VAR_OP,     { op_yesno                }, { &cal3_flag       } },
279 	{ "sysflags",        VAR_INT,    { NULL                    }, { &sysflags        }, 0x81 },
280 	{ "extflags",        VAR_INT,    { NULL                    }, { &extflags        }, 0x81 },
281 	{ NULL,              VAR_NONE,   { NULL                    }, { NULL             } },
282 };
283 
284 static const char	*readblock[] = { "wincal", "common", "windows", NULL };
285 
286 static const char	Copyright[] = "Calendar for Windows95/98/Me/NT4/2000/XP  Copyright (C) 1997,1998,1999,2001,2003 by Yoshifumi Mori";
287 
288 /* ------------------------------------------------------------------------- */
289 
290 #define PACKVERSION(major,minor)	MAKELONG(minor,major)
291 
GetDllVersion(LPCTSTR lpszDllName)292 DWORD GetDllVersion(LPCTSTR lpszDllName)
293 {
294 	HINSTANCE	hinstDll;
295 	DWORD	dwVersion = 0;
296 
297 	hinstDll = LoadLibrary(lpszDllName);
298 	if (hinstDll) {
299 		DLLGETVERSIONPROC	pDllGetVersion;
300 
301 		pDllGetVersion = (DLLGETVERSIONPROC)GetProcAddress(hinstDll, "DllGetVersion");
302 		/*
303 		 * Because some DLLs might not implement this function, you
304 		 * must test for it explicitly. Depending on the particular
305 		 * DLL, the lack of a DllGetVersion function can be a useful
306 		 * indicator of the version.
307 		 */
308 		if (pDllGetVersion) {
309 			DLLVERSIONINFO	dvi;
310 			HRESULT	hr;
311 
312 			ZeroMemory(&dvi, sizeof(dvi));
313 			dvi.cbSize = sizeof(dvi);
314 
315 			hr = (*pDllGetVersion)(&dvi);
316 			if (SUCCEEDED(hr)) {
317 				dwVersion = PACKVERSION(dvi.dwMajorVersion, dvi.dwMinorVersion);
318 			}
319 		}
320 
321 		FreeLibrary(hinstDll);
322 	}
323 	return (dwVersion);
324 }
325 
326 /* ------------------------------------------------------------------------- */
327 
328 /*
329  * ���ꥨ�顼����
330  */
memerr(const char * func)331 void memerr(const char *func)
332 {
333 	char	szTitle[256];
334 	char	szText[256];
335 	int		errcode;
336 
337 	errcode = GetLastError();
338 	sprintf(szTitle, "%s ���顼���� - %s", szAppName, func);
339 	sprintf(szText, "�ؿ�: %s �ǥ��꡼����ݤǤ��ޤ���Ǥ���\n�ץ�����λ���ޤ�. ErrCode = %d", func, errcode);
340 	MessageBox(hwndMain, szText, szTitle, MB_ICONEXCLAMATION | MB_OK);
341 	exit(errcode);
342 }
343 
344 /*
345  * �¹���Υ��顼ɽ��
346  *
347  * func:  �¹Դؿ�̾
348  * level: ���顼��٥� (information, warning, debug, error, panic)
349  * fmt:   ���顼��å�����
350  */
errprint(const char * func,int level,const char * fmt,...)351 void errprint(const char *func, int level, const char *fmt, ...)
352 {
353 	static const char	*statname[] = {
354 		"Warning", "Debug", "Error", "Panic",
355 	};
356 	char	szTitle[256];
357 	char	szText[256];
358 	va_list	ap;
359 
360 	sprintf(szTitle, "%s ���顼����", szAppName);
361 	if (func != NULL) {
362 		sprintf(strlastp(szTitle), " - %s", func);
363 	}
364 
365 	szText[0] = '\0';
366 	if (func != NULL) {
367 		sprintf(szText, "%s: ", func);
368 	}
369 	if (level != ERR_INFO) {
370 		sprintf(strlastp(szText), "%s: ", statname[level - ERR_WARN]);
371 	}
372 	va_start(ap, fmt);
373 	vsprintf(strlastp(szText), fmt, ap);
374 	va_end(ap);
375 
376 	MessageBox(hwndMain, szText, szTitle, MB_ICONINFORMATION | MB_OK);
377 }
378 
379 /* ------------------------------------------------------------------------- */
380 
381 /*
382  * ������֤���¸
383  */
384 static
preserveConfig(HWND hWnd)385 void preserveConfig(HWND hWnd)
386 {
387 	if (writeConfig(todaycnf_file, &conf_tbl[0], &readblock[0]) == FALSE) {
388 		MessageBox(hWnd, "TODAY.CNF ��¸���˥��顼��ȯ�����ޤ���", "�ץ�ѥƥ�", MB_ICONEXCLAMATION | MB_OK);
389 	}
390 }
391 
392 /*
393  * ǯ���������Ƚ��
394  *
395  * return value:
396  *   TRUE  ����
397  *   FALSE ���顼����
398  */
399 static
isDateValid(int year,int month)400 int isDateValid(int year, int month)
401 {
402 	if (year < SUPPORT_MIN_YEAR || year > SUPPORT_MAX_YEAR) {
403 		return (FALSE);
404 	}
405 	if (month < 1 || month > 12) {
406 		return (FALSE);
407 	}
408 	return (TRUE);
409 }
410 
411 /*
412  * ���դ��������
413  */
414 static
dateControl(int type)415 void dateControl(int type)
416 {
417 	switch (type) {
418 	case 0:	/* yy+1 */
419 		if (curdate.year < SUPPORT_MAX_YEAR) {
420 			curdate.year++;
421 		}
422 		break;
423 	case 1:	/* yy-1 */
424 		if (curdate.year > SUPPORT_MIN_YEAR) {
425 			curdate.year--;
426 		}
427 		break;
428 	case 2:	/* mm+1 */
429 		if (++curdate.month > 12) {
430 			if (curdate.year < SUPPORT_MAX_YEAR) {
431 				curdate.year++;
432 				curdate.month = 1;
433 			} else {
434 				curdate.month = 12;
435 			}
436 		}
437 		break;
438 	case 3:	/* mm-1 */
439 		if (--curdate.month < 1) {
440 			if (curdate.year > SUPPORT_MIN_YEAR) {
441 				curdate.year--;
442 				curdate.month = 12;
443 			} else {
444 				curdate.month = 1;
445 			}
446 		}
447 		break;
448 	}
449 }
450 
451 /*
452  * �������������ơ��֥����
453  * ���եơ��֥����
454  */
455 static
makeCalTbl(void)456 void makeCalTbl(void)
457 {
458 	int	i;
459 	int	j;
460 	int	yy;
461 	int	mm;
462 	int	dd;
463 	int	dayofmonth;
464 	int	dayofweek;
465 	int	add_attr;
466 	int	freespace;
467 	int	*tblHoliday;
468 	int	weektype;
469 	int	week;
470 	int	total_days;
471 	long	jd;
472 	PDAYINFO	*tblCalPtr[MAX_DAYOFMONTH];
473 	PDAYINFO	**ptblCalPtr;
474 	DAYINFO		*pDayInfo;
475 	DAYINFO		*pDayInfoMonthTop;
476 	DAYINFO		*pDayInfoWork;
477 	const struct LUNAR_CALENDAR	*lc;
478 
479 	if (CHK_EXTFLAGS(EXTFLAGS_WEEKTYPE) == 0) {
480 		weektype = 0;
481 	} else {
482 		weektype = 1;
483 	}
484 
485 	ZeroMemory(tblCalDay, sizeof(tblCalDay));
486 	ZeroMemory(tblDayInfo, sizeof(tblDayInfo));
487 	pDayInfo = tblDayInfo;
488 
489 	for (i = 0; i < CAL_MAXMONTH; i++) {
490 		yy = curdate.year;
491 		mm = curdate.month + (i - CAL_CENTERMONTH);
492 		if (mm < 1) {
493 			yy--;
494 			mm += 12;
495 		}
496 		if (mm > 12) {
497 			yy++;
498 			mm -= 12;
499 		}
500 		dayofmonth = GetDayofMonth(yy, mm);
501 		caltbl[i].year = yy;
502 		caltbl[i].month = mm;
503 		caltbl[i].dayofmonth = dayofmonth;
504 		caltbl[i].first_dayofweek = GetDayofWeek(yy, mm, 1);
505 		caltbl[i].last_dayofweek = GetDayofWeek(yy, mm, dayofmonth);
506 		caltbl[i].monthname = GetNameofMonth(LANG_E, mm);
507 	}
508 
509 	if (schedule_flag == TRUE) {
510 		schedule_find();
511 	}
512 
513 	total_days = 0;
514 	for (i = 0; i < CAL_MAXMONTH; i++) {
515 		ZeroMemory(tblCalPtr, sizeof(tblCalPtr));
516 		yy = caltbl[i].year;
517 		mm = caltbl[i].month;
518 		dayofmonth = caltbl[i].dayofmonth;
519 		dayofweek = caltbl[i].first_dayofweek;
520 		add_attr = 0;
521 		total_days += dayofmonth;
522 
523 		if (i >= 1 && i < (SHOW_MAXMONTH + 1)) {
524 			tblCalName[i - 1].year = yy;
525 			tblCalName[i - 1].month = mm;
526 			tblCalName[i - 1].name = caltbl[i].monthname;
527 			week = week_index[weektype][dayofweek];
528 			for (j = 0; j < dayofmonth; j++) {
529 				tblCalPtr[j] = &tblCalDay[i - 1][week + j];
530 			}
531 		}
532 		if ((cal3_flag == FALSE && i != CAL_CENTERMONTH) ||
533 		    (cal3_flag != FALSE && (i < 1 || i >= (SHOW_MAXMONTH + 1)))) {
534 			add_attr = ATTR_GRAYEDDAY;
535 		}
536 		if (CHK_EXTFLAGS(EXTFLAGS_GRAYEDDAY) != FALSE) {
537 			if (cal3_flag == FALSE) {
538 				switch (i) {
539 				case CAL_CENTERMONTH-1:
540 					freespace = week_index[weektype][caltbl[CAL_CENTERMONTH].first_dayofweek];
541 					dd = dayofmonth - (freespace - 1);
542 					for (j = 0; j < freespace; j++) {
543 						tblCalPtr[j + dd - 1] = &tblCalDay[SHOW_CENTERMONTH][j];
544 					}
545 					break;
546 				case CAL_CENTERMONTH+1:
547 					dd = week_index[weektype][caltbl[i - 1].first_dayofweek] + caltbl[i - 1].dayofmonth;
548 					freespace = MAXDAYTBL - dd;
549 					for (j = 0; j < freespace; j++) {
550 						tblCalPtr[j] = &tblCalDay[SHOW_CENTERMONTH][j + dd];
551 					}
552 					break;
553 				}
554 			} else {
555 				switch (i) {
556 				case 0:
557 					freespace = week_index[weektype][caltbl[1].first_dayofweek];
558 					dd = dayofmonth - (freespace - 1);
559 					for (j = 0; j < freespace; j++) {
560 						tblCalPtr[j + dd - 1] = &tblCalDay[0][j];
561 					}
562 					break;
563 				case CAL_MAXMONTH-1:
564 					dd = week_index[weektype][caltbl[i - 1].first_dayofweek] + caltbl[i - 1].dayofmonth;
565 					freespace = MAXDAYTBL - dd;
566 					for (j = 0; j < freespace; j++) {
567 						tblCalPtr[j] = &tblCalDay[SHOW_MAXMONTH - 1][j + dd];
568 					}
569 					break;
570 				}
571 			}
572 		}
573 
574 		ptblCalPtr = tblCalPtr;
575 		pDayInfoMonthTop = pDayInfo;
576 		for (dd = 1; dd <= dayofmonth; dd++) {
577 			pDayInfo->date.year = yy;
578 			pDayInfo->date.month = mm;
579 			pDayInfo->date.day = dd;
580 			pDayInfo->date.dayofweek = dayofweek;
581 			dayofweek = (dayofweek + 1) % MAXWEEK;
582 			lc = GetLunarCalendar(yy, mm, dd);
583 			if (lc != NULL) {
584 				pDayInfo->lc = *lc;
585 				pDayInfo->attr |= ATTR_LUNARCAL;
586 			}
587 			pDayInfo->attr |= add_attr;
588 			if (schedule_flag == TRUE && schedule_daytbl[i][dd - 1] == SCHEDULE_EXIST) {
589 				pDayInfo->attr |= ATTR_SCHEDULE;
590 			}
591 			if (yy == nowdate.year && mm == nowdate.month && dd == nowdate.day) {
592 				pDayInfo->attr |= ATTR_TODAY;
593 			}
594 			if (*ptblCalPtr != NULL) {
595 				**ptblCalPtr = pDayInfo;
596 			}
597 			pDayInfo++;
598 			ptblCalPtr++;
599 		}
600 
601 		/* ���������������� */
602 		tblHoliday = GetHolidayTbl(yy, mm);
603 		if (tblHoliday != NULL) {
604 			pDayInfoWork = pDayInfoMonthTop;
605 			jd = Julian(pDayInfoWork->date.year, pDayInfoWork->date.month, pDayInfoWork->date.day);
606 			for (j = 0; j < MAX_DAYOFMONTH; j++) {
607 				if (tblHoliday[j] != 0) {
608 					pDayInfoWork->holiday = tblHoliday[j];	/* �����������ơ��֥�Υ���ǥå��� */
609 					pDayInfoWork->attr &= ~ATTR_TRANSHOL;
610 					pDayInfoWork->attr |= ATTR_HOLIDAY;
611 					if (pDayInfoWork->date.dayofweek == 0 &&
612 					    checkTransferHolidayJD(jd + 1) == TRUE) {
613 						pDayInfoWork[1].holiday = 0;
614 						pDayInfoWork[1].attr |= ATTR_TRANSHOL;	/* ���ص��� */
615 					}
616 				}
617 				jd++;
618 				pDayInfoWork++;
619 			}
620 			free(tblHoliday);
621 		}
622 	}
623 
624 	jd = Julian(tblDayInfo[0].date.year, tblDayInfo[0].date.month, tblDayInfo[0].date.day);
625 	pDayInfoWork = tblDayInfo;
626 	for (i = 0; i < total_days - 2; i++) {
627 		if ((pDayInfoWork[0].attr & ATTR_HOLIDAY) != 0 &&
628 		    (pDayInfoWork[2].attr & ATTR_HOLIDAY) != 0 &&
629 		    (pDayInfoWork[1].attr & (ATTR_HOLIDAY | ATTR_TRANSHOL)) == 0 &&
630 		    pDayInfoWork[1].date.dayofweek != 0 &&
631 		    checkNationalHolidayJD(jd + 1) == TRUE) {
632 			pDayInfoWork[1].attr |= ATTR_HOLIDAY;
633 			pDayInfoWork[1].holiday = 1;	/* ��̱�ε��� */
634 		}
635 		jd++;
636 		pDayInfoWork++;
637 	}
638 }
639 
640 /*
641  * ���ץ���������
642  */
643 static
usage(HWND hWnd)644 void usage(HWND hWnd)
645 {
646 	char	szMsg[256];
647 	char	szTitle[64];
648 
649 	sprintf(szMsg, "%s [options] [month [year]]\n\n"
650 		"options:"
651 		"\t-1 | -3\t\tɽ���������\n\t\t\t-1��1��ʬ\n"
652 		"\t-s | -S\t\t�������塼���ɽ������\n\t\t\t-s��ɽ��\n"
653 		"\t-@file\t\t���Ū�� %s(file) ���ɤ߹���\n"
654 		"\t-rvarname=value\t���Ū���ѿ����ѹ�", szAppName, todaycnf_file);
655 	sprintf(szTitle, "%s�Υ��ץ����", szAppName);
656 
657 	MessageBox(hWnd, szMsg, szTitle, MB_OK);
658 }
659 
660 /*
661  * ���������ɤ߹���
662  * ���ץ�������
663  *
664  * return value:
665  *   TRUE  ���ェλ
666  *   FALSE ���顼
667  */
668 static
Configuration(void)669 int Configuration(void)
670 {
671 	char	*p;
672 	int		year;
673 	int		month;
674 	int		c;
675 
676 	strncpy(cmdpathbuf, argv[0], sizeof(cmdpathbuf) - 1);
677 	p = strrchr(cmdpathbuf, _T_FS_CHR);
678 	if (p == NULL) {
679 		p = strrchr(cmdpathbuf, '/');
680 		if (p == NULL) {
681 			p = strrchr(cmdpathbuf, ':');
682 		}
683 	}
684 	if (p != NULL) {
685 		p[1] = '\0';
686 		search_cmdpath = cmdpathbuf;
687 	}
688 	search_envname = "TODAYTBL";
689 	replace_pathenv = TRUE;
690 
691 	config(todaycnf_file, &conf_tbl[0], &readblock[0]);
692 
693 	while ((c = getopt(argc, argv, "13@::Kkr::Ss?")) != EOF) {
694 		switch (c) {
695 		case '1':
696 			cal3_flag = FALSE;
697 			break;
698 		case '3':
699 			cal3_flag = TRUE;
700 			break;
701 		case 'k':
702 			rokuyou_flag = TRUE;
703 			break;
704 		case 'K':
705 			rokuyou_flag = FALSE;
706 			break;
707 		case 's':
708 			schedule_flag = TRUE;
709 			break;
710 		case 'S':
711 			schedule_flag = FALSE;
712 			break;
713 		case 'r':	/* ���Ū���ѿ������� */
714 			if (optarg != NULL) {
715 				config_oneline("cmdline", &conf_tbl[0], optarg);
716 			}
717 			break;
718 		case '@':	/* ���Ū�� TODAY.CNF ���ɤ߹��� */
719 			config(optarg, &conf_tbl[0], &readblock[0]);
720 			break;
721 		case '?':
722 			usage(NULL);
723 			return (FALSE);
724 		}
725 	}
726 
727 	rdcalendar(&nowdate);
728 	year = nowdate.year;
729 	month = nowdate.month;
730 
731 	argc -= optind;
732 	argv += optind;
733 
734 	switch (argc) {
735 	case 0:	/* no option */
736 		break;
737 	case 2:	/* month & year option */
738 		year = atoi(argv[1]);
739 		if (isDateValid(year, month) == FALSE) {
740 			errprint(NULL, ERR_ERROR, "����ǯ���ϰϳ��Ǥ�");
741 			year = nowdate.year;
742 		}
743 		/* no break */
744 	case 1:	/* month option */
745 		month = atoi(argv[0]);
746 		if (isDateValid(year, month) == FALSE) {
747 			errprint(NULL, ERR_ERROR, "�����ϰϳ��Ǥ�");
748 			month = nowdate.month;
749 		}
750 		break;
751 	}
752 
753 	if (Loading_GengoTbl() != LOAD_OK) {
754 		errprint(NULL, ERR_ERROR, "ǯ���Ѵ��ϤǤ��ޤ���");
755 	}
756 	if (Loading_HolidayTbl() != LOAD_OK) {
757 		errprint(NULL, ERR_ERROR, "������������ɽ���Ǥ��ޤ���");
758 	}
759 
760 	curdate.year = year;
761 	curdate.month = month;
762 
763 	return (TRUE);
764 }
765 
766 /* ------------------------------------------------------------------------- */
767 
768 static
setEditText(HWND hDlg,UINT ctrlID,char * text)769 void setEditText(HWND hDlg, UINT ctrlID, char *text)
770 {
771 	if (text == NULL) {
772 		text = "";
773 	}
774 	SetDlgItemText(hDlg, ctrlID, (LPCTSTR)text);
775 }
776 
777 static
setFileList(HWND hDlg,UINT ctrlID,char ** filetbl,int maxtbl)778 void setFileList(HWND hDlg, UINT ctrlID, char **filetbl, int maxtbl)
779 {
780 	int		i;
781 	int		textlen;
782 	char	*bufp;
783 	char	*p;
784 
785 	textlen = 0;
786 	for (i = 0; i < maxtbl; i++) {
787 		if (filetbl[i] != NULL && *(filetbl[i]) != '\0') {
788 			textlen += strlen(filetbl[i]) + 2;
789 		}
790 	}
791 	textlen++;
792 	bufp = malloc(textlen);
793 	if (bufp != NULL) {
794 		p = bufp;
795 		for (i = 0; i < maxtbl; i++) {
796 			if (filetbl[i] != NULL && *(filetbl[i]) != '\0') {
797 				sprintf(p, "%s\r\n", filetbl[i]);
798 				p = strchr(p, '\0');
799 			}
800 		}
801 		*p = '\0';
802 		SetDlgItemText(hDlg, ctrlID, (LPCTSTR)bufp);
803 		free(bufp);
804 	}
805 }
806 
807 static
updateCheckButton(HWND hDlg,UINT ctrlID,int * flag)808 int updateCheckButton(HWND hDlg, UINT ctrlID, int *flag)
809 {
810 	int	state;
811 
812 	state = IsDlgButtonChecked(hDlg, ctrlID);
813 	if (*flag != state) {
814 		*flag = state;
815 		bChangeProp = TRUE;
816 		return (TRUE);
817 	}
818 	return (FALSE);
819 }
820 
821 static
updateCheckEditText(HWND hDlg,UINT ctrlID,char ** bufp)822 void updateCheckEditText(HWND hDlg, UINT ctrlID, char **bufp)
823 {
824 	int		textlen;
825 	char	*text;
826 
827 	textlen = SendDlgItemMessage(hDlg, ctrlID, WM_GETTEXTLENGTH, 0, 0L) + 1;
828 	text = malloc(textlen);
829 	if (text != NULL) {
830 		SendDlgItemMessage(hDlg, ctrlID, WM_GETTEXT, textlen, (LPARAM)text);
831 		(void)strtok(text, "\r\n");	/* cut CR/LF */
832 		if (strlen(text) == 0) {	/* edit text is empty */
833 			if (*bufp != NULL) {
834 				free(*bufp);
835 				bChangeProp = TRUE;
836 			}
837 			*bufp = NULL;
838 		} else if (*bufp == NULL || strcmp(*bufp, text) != 0) {
839 			if (*bufp != NULL) {
840 				free(*bufp);
841 			}
842 			*bufp = xstrdup(text);
843 			bChangeProp = TRUE;
844 		}
845 		free(text);
846 	}
847 }
848 
849 static
updateCheckEditTextList(HWND hDlg,UINT ctrlID,char ** listp,int listcnt)850 void updateCheckEditTextList(HWND hDlg, UINT ctrlID, char **listp, int listcnt)
851 {
852 	int		i;
853 	int		cnt;
854 	int		textlen;
855 	char	*text;
856 	char	**bufp;
857 	char	*p;
858 	char	*lasts;
859 
860 	textlen = SendDlgItemMessage(hDlg, ctrlID, WM_GETTEXTLENGTH, 0, 0L) + 1;
861 	text = malloc(textlen);
862 	if (text != NULL) {
863 		SendDlgItemMessage(hDlg, ctrlID, WM_GETTEXT, textlen, (LPARAM)text);
864 
865 		bufp = malloc(sizeof(char *) * listcnt);
866 		if (bufp != NULL) {
867 			memset(bufp, '\0', sizeof(char *) * listcnt);
868 
869 			cnt = 0;
870 			lasts = NULL;
871 			p = strtok_r(text, "\r\n", &lasts);
872 			while (p != NULL) {
873 				bufp[cnt++] = p;
874 				if (cnt >= listcnt) {
875 					break;
876 				}
877 				p = strtok_r(NULL, "\r\n", &lasts);
878 			}
879 
880 			for (i = 0; i < listcnt; i++) {
881 				if (listp[i] == NULL) {
882 					if (bufp[i] != NULL) {
883 						listp[i] = xstrdup(bufp[i]);
884 						bChangeProp = TRUE;
885 					}
886 				} else if (bufp[i] == NULL || strcmp(listp[i], bufp[i]) != 0) {
887 					free(listp[i]);
888 					if (bufp[i] == NULL) {
889 						listp[i] = NULL;
890 					} else {
891 						listp[i] = xstrdup(bufp[i]);
892 					}
893 					bChangeProp = TRUE;
894 				}
895 			}
896 
897 			free(bufp);
898 		}
899 		free(text);
900 	}
901 }
902 
displayTabProc(HWND hDlg,UINT iMessage,WPARAM wParam,LPARAM lParam)903 LRESULT CALLBACK displayTabProc(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam)
904 {
905 	int	i;
906 	int	flag;
907 
908 	switch (iMessage) {
909 	case WM_INITDIALOG:
910 		CheckDlgButton(hDlg, IDC_DISP_CHK_01, cal3_flag);
911 		CheckDlgButton(hDlg, IDC_DISP_CHK_02, rokuyou_flag);
912 		CheckDlgButton(hDlg, IDC_DISP_CHK_03, schedule_flag);
913 		for (i = 0; i < 6; i++) {
914 			CheckDlgButton(hDlg, IDC_DISP_CHK_04 + i, rokuyou_item[i]);
915 			EnableWindow(GetDlgItem(hDlg, IDC_DISP_CHK_04 + i), rokuyou_flag);
916 		}
917 		CheckDlgButton(hDlg, IDC_DISP_CHK_10, CHK_EXTFLAGS(EXTFLAGS_GRAYEDDAY));
918 		CheckRadioButton(hDlg, IDC_DISP_RBTN_1, IDC_DISP_RBTN_2, bigfont_flag ? IDC_DISP_RBTN_2 : IDC_DISP_RBTN_1);
919 		return (TRUE);
920 	case WM_COMMAND:
921 		switch (HIWORD(wParam)) {
922 		case BN_CLICKED:
923 			if (LOWORD(wParam) == IDC_DISP_CHK_02) {
924 				flag = IsDlgButtonChecked(hDlg, IDC_DISP_CHK_02);
925 				for (i = 0; i < 6; i++) {
926 					EnableWindow(GetDlgItem(hDlg, IDC_DISP_CHK_04 + i), flag);
927 				}
928 				return (TRUE);
929 			}
930 			break;
931 		}
932 		break;
933 	case WM_NOTIFY:
934 		switch (((NMHDR *)lParam)->code) {
935 		case PSN_APPLY:
936 			updateCheckButton(hDlg, IDC_DISP_CHK_01, &cal3_flag);
937 			updateCheckButton(hDlg, IDC_DISP_CHK_02, &rokuyou_flag);
938 			updateCheckButton(hDlg, IDC_DISP_CHK_03, &schedule_flag);
939 			for (i = 0; i < 6; i++) {
940 				updateCheckButton(hDlg, IDC_DISP_CHK_04 + i, &rokuyou_item[i]);
941 			}
942 			updateCheckButton(hDlg, IDC_DISP_CHK_10, &flag);
943 			SET_EXTFLAGS(EXTFLAGS_GRAYEDDAY, flag);
944 			if (updateCheckButton(hDlg, IDC_DISP_RBTN_2, &bigfont_flag) != FALSE) {
945 				bChangeFont = TRUE;
946 			}
947 			return (TRUE);
948 		}
949 		break;
950 	case WM_HELP:
951 		commonHelpControl(propHelpID, (LPHELPINFO)lParam);
952 		return (TRUE);
953 	}
954 
955 	return (FALSE);
956 }
957 
colorTabProc(HWND hDlg,UINT iMessage,WPARAM wParam,LPARAM lParam)958 LRESULT CALLBACK colorTabProc(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam)
959 {
960 	int		i;
961 	int		col;
962 	BOOL	bErr;
963 	BOOL	bFlag;
964 	UINT	idCtrl;
965 	LPDRAWITEMSTRUCT	lpDIS;
966 	HBRUSH	hBrush;
967 	char	szText[32];
968 	char	msg[256];
969 
970 	switch (iMessage) {
971 	case WM_INITDIALOG:
972 		for (i = 0; i < COL_MAX; i++) {
973 			SetDlgItemInt(hDlg, IDC_COL_EDIT_00 + i, calcolor[i],  TRUE);
974 			SendDlgItemMessage(hDlg, IDC_COL_EDIT_00 + i, EM_LIMITTEXT, 2, 0L);
975 		}
976 		return (TRUE);
977 	case WM_COMMAND:
978 		idCtrl = LOWORD(wParam);
979 		switch (HIWORD(wParam)) {
980 		case EN_CHANGE:
981 			if (IDC_COL_EDIT_00 <= idCtrl && idCtrl < (IDC_COL_EDIT_00 + COL_MAX)) {
982 				InvalidateRect(GetDlgItem(hDlg, idCtrl - IDC_COL_EDIT_00 + IDC_COL_DRAW_00), NULL, FALSE);
983 				return (TRUE);
984 			}
985 			break;
986 		case STN_DBLCLK:
987 			if (IDC_COL_DRAW_00 <= idCtrl && idCtrl < (IDC_COL_DRAW_00 + COL_MAX)) {
988 				idCtrl = idCtrl - IDC_COL_DRAW_00 + IDC_COL_EDIT_00;
989 				col = GetDlgItemInt(hDlg, idCtrl, &bFlag, TRUE);
990 				if (bFlag == FALSE || col < 0 || col >= MAX_COLORMAP) {
991 					col = 0;
992 				}
993 				if (SelectColorMapNo(hDlg, ghInstance, &col, colormap, MAX_COLORMAP) == TRUE) {
994 					SetDlgItemInt(hDlg, idCtrl, col, TRUE);
995 					SetFocus(GetDlgItem(hDlg, idCtrl));
996 					SendDlgItemMessage(hDlg, idCtrl, EM_SETSEL, 0, -1);
997 					InvalidateRect((HWND)lParam, NULL, FALSE);
998 				}
999 				return (TRUE);
1000 			}
1001 			break;
1002 		}
1003 		break;
1004 	case WM_DRAWITEM:
1005 		idCtrl = (UINT)wParam;
1006 		lpDIS = (LPDRAWITEMSTRUCT)lParam;
1007 		if (idCtrl >= IDC_COL_DRAW_00 && idCtrl < (IDC_COL_DRAW_00 + COL_MAX)) {
1008 			col = GetDlgItemInt(hDlg, idCtrl - IDC_COL_DRAW_00 + IDC_COL_EDIT_00, &bFlag, TRUE);
1009 			if (bFlag == TRUE && col >= 0 && col < MAX_COLORMAP) {
1010 				hBrush = CreateSolidBrush(RGB2PALETTERGB(colormap[col]));
1011 				FillRect(lpDIS->hDC, &lpDIS->rcItem, hBrush);
1012 				DeleteObject(hBrush);
1013 				return (TRUE);
1014 			} else {
1015 				hBrush = (HBRUSH)SendMessage(hDlg, WM_CTLCOLORDLG, (WPARAM)lpDIS->hDC, (LPARAM)lpDIS->hwndItem);
1016 				FillRect(lpDIS->hDC, &lpDIS->rcItem, hBrush);
1017 				return (TRUE);
1018 			}
1019 		} else if (idCtrl >= IDC_COL_DRAW_S00 && idCtrl < (IDC_COL_DRAW_S00 + MAX_COLORMAP)) {
1020 			hBrush = CreateSolidBrush(RGB2PALETTERGB(colormap[idCtrl - IDC_COL_DRAW_S00]));
1021 			FillRect(lpDIS->hDC, &lpDIS->rcItem, hBrush);
1022 			DeleteObject(hBrush);
1023 			return (TRUE);
1024 		}
1025 		break;
1026 	case WM_NOTIFY:
1027 		switch (((NMHDR *)lParam)->code) {
1028 		case PSN_KILLACTIVE:
1029 			bErr = FALSE;
1030 			for (i = 0; i < COL_MAX; i++) {
1031 				col = GetDlgItemInt(hDlg, IDC_COL_EDIT_00 + i, &bFlag, TRUE);
1032 				if (bFlag == FALSE || col < 0 || col >= MAX_COLORMAP) {
1033 					bErr = TRUE;
1034 					break;
1035 				}
1036 			}
1037 			if (bErr == TRUE) {
1038 				LoadString(ghInstance, IDC_COL_EDIT_00 + i, szText, sizeof(szText));
1039 				sprintf(msg, "%s�ο��ֹ椬����������ޤ���", szText);
1040 				MessageBox(hDlg, msg, "���ֹ楨�顼", MB_ICONINFORMATION | MB_OK);
1041 			}
1042 			SetWindowLong(hDlg, DWL_MSGRESULT, bErr);
1043 			return (TRUE);
1044 		case PSN_APPLY:
1045 			for (i = 0; i < COL_MAX; i++) {
1046 				col = GetDlgItemInt(hDlg, IDC_COL_EDIT_00 + i, &bFlag, TRUE);
1047 				if (calcolor[i] != col) {
1048 					calcolor[i] = col;
1049 					bChangeProp = TRUE;
1050 				}
1051 			}
1052 			return (TRUE);
1053 		}
1054 		break;
1055 	case WM_HELP:
1056 		commonHelpControl(propHelpID, (LPHELPINFO)lParam);
1057 		return (TRUE);
1058 	}
1059 
1060 	return (FALSE);
1061 }
1062 
fileTabProc(HWND hDlg,UINT iMessage,WPARAM wParam,LPARAM lParam)1063 LRESULT CALLBACK fileTabProc(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam)
1064 {
1065 	switch (iMessage) {
1066 	case WM_INITDIALOG:
1067 		setFileList(hDlg, IDC_FILE_EDIT_SCHEDULE, schedule_filetbl, MAXSCHEDULEFILE);
1068 		setEditText(hDlg, IDC_FILE_EDIT_TABLE, search_path);
1069 		return (TRUE);
1070 	case WM_NOTIFY:
1071 		switch (((NMHDR *)lParam)->code) {
1072 		case PSN_APPLY:
1073 			updateCheckEditTextList(hDlg, IDC_FILE_EDIT_SCHEDULE, schedule_filetbl, MAXSCHEDULEFILE);
1074 			updateCheckEditText(hDlg, IDC_FILE_EDIT_TABLE, &search_path);
1075 			return (TRUE);
1076 		}
1077 		break;
1078 	case WM_HELP:
1079 		commonHelpControl(propHelpID, (LPHELPINFO)lParam);
1080 		return (TRUE);
1081 	}
1082 
1083 	return (FALSE);
1084 }
1085 
1086 static
setupPropertyProc(HWND hWnd)1087 BOOL setupPropertyProc(HWND hWnd)
1088 {
1089 	static const struct PROP_TBL	prop_tbl[MAX_SHEET] = {
1090 		{ IDD_TAB_DISPLAY, (DLGPROC)displayTabProc },
1091 		{ IDD_TAB_COLOR,   (DLGPROC)colorTabProc   },
1092 		{ IDD_TAB_FILE,    (DLGPROC)fileTabProc    },
1093 	};
1094 	PROPSHEETPAGE	psp[MAX_SHEET];
1095 	PROPSHEETHEADER	psh;
1096 	int	i;
1097 
1098 	memset(psp, '\0', sizeof(psp));
1099 
1100 	for (i = 0; i < MAX_SHEET; i++) {
1101 		psp[i].dwSize = sizeof(PROPSHEETPAGE);
1102 		psp[i].dwFlags = PSP_DEFAULT;
1103 		psp[i].hInstance = ghInstance;
1104 		psp[i].u.pszTemplate = MAKEINTRESOURCE(prop_tbl[i].iResID);
1105 		psp[i].pfnDlgProc = prop_tbl[i].DlgProc;
1106 	}
1107 
1108 	memset(&psh, '\0', sizeof(psh));
1109 	psh.dwSize = sizeof(PROPSHEETHEADER);
1110 	psh.dwFlags = PSH_PROPSHEETPAGE | PSH_PROPTITLE | PSH_NOAPPLYNOW;
1111 	psh.hwndParent = hWnd;
1112 	psh.hInstance = ghInstance;
1113 	psh.pszCaption = (LPSTR)szAppName;
1114 	psh.nPages = sizeof(psp) / sizeof(PROPSHEETPAGE);
1115 	psh.u3.ppsp = (LPCPROPSHEETPAGE)&psp;
1116 
1117 	bChangeProp = FALSE;
1118 	bChangeFont = FALSE;
1119 
1120 	return (PropertySheet(&psh));
1121 }
1122 
1123 static
CenterWindow(HWND hwndMove,HWND hwndAltOwner)1124 BOOL CenterWindow(HWND hwndMove, HWND hwndAltOwner)
1125 {
1126 	RECT	rcMove;
1127 	RECT	rcAlt;
1128 	POINT	ptNew;
1129 
1130 	if (!IsWindow(hwndMove)) {
1131 		goto Error_Exit;
1132 	}
1133 	if (hwndAltOwner && !IsWindow(hwndAltOwner)) {
1134 		goto Error_Exit;
1135 	}
1136 
1137 	GetWindowRect(hwndMove, &rcMove);
1138 
1139 	if (!hwndAltOwner) {
1140 		SystemParametersInfo(SPI_GETWORKAREA, 0, &rcAlt, 0);
1141 	} else {
1142 		GetWindowRect(hwndAltOwner, &rcAlt);
1143 	}
1144 
1145 	ptNew.x = rcAlt.left + ((rcAlt.right  - rcAlt.left) - (rcMove.right  - rcMove.left)) / 2;
1146 	ptNew.y = rcAlt.top  + ((rcAlt.bottom - rcAlt.top ) - (rcMove.bottom - rcMove.top )) / 2;
1147 
1148 	SetWindowPos(hwndMove, NULL, ptNew.x, ptNew.y, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
1149 
1150 	return (TRUE);
1151 
1152 Error_Exit:
1153 	return (FALSE);
1154 }
1155 
AboutDlgProc(HWND hDlg,UINT iMessage,WPARAM wParam,LPARAM lParam)1156 BOOL CALLBACK AboutDlgProc(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam)
1157 {
1158 	char	msg[32];
1159 	HICON	hIcon;
1160 
1161 	switch (iMessage) {
1162 	case WM_INITDIALOG:
1163 		CenterWindow(hDlg, GetParent(hDlg));
1164 		SetClassLong(hDlg, GCL_HICON, (LONG)LoadIcon(ghInstance, MAKEINTRESOURCE(IDI_ICON1)));
1165 		SetDlgItemText(hDlg, IDC_APPNAME, szAppNameLong);
1166 		sprintf(msg, "Version %s  (" __DATE__ ")", szVersion);
1167 		SetDlgItemText(hDlg, IDC_VERINFO, msg);
1168 		SetDlgItemText(hDlg, IDC_COPYRIGHT, szCopyright);
1169 		SetDlgItemText(hDlg, IDC_COMMENT, szComment);
1170 		return (TRUE);
1171 	case WM_DRAWITEM:
1172 		if ((UINT)wParam == IDC_ICON1) {
1173 			hIcon = LoadImage(ghInstance, MAKEINTRESOURCE(IDI_ICON1), IMAGE_ICON, 64, 64, LR_DEFAULTCOLOR);
1174 			DrawIconEx(((LPDRAWITEMSTRUCT)lParam)->hDC, 0, 0, hIcon, 64, 64, 0, NULL, DI_NORMAL);
1175 			return (TRUE);
1176 		}
1177 		break;
1178 	case WM_COMMAND:
1179 		switch (LOWORD(wParam)) {
1180 		case IDOK:
1181 		case IDCANCEL:
1182 			EndDialog(hDlg, 0);
1183 			return (TRUE);
1184 		}
1185 		break;
1186 	case WM_CLOSE:
1187 		EndDialog(hDlg, 0);
1188 		return (TRUE);
1189 	}
1190 
1191 	return (FALSE);
1192 }
1193 
SetDateDlgProc(HWND hDlg,UINT iMessage,WPARAM wParam,LPARAM lParam)1194 BOOL CALLBACK SetDateDlgProc(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam)
1195 {
1196 	BOOL	bFlag;
1197 
1198 	switch (iMessage) {
1199 	case WM_INITDIALOG:
1200 		CenterWindow(hDlg, GetParent(hDlg));
1201 		SetClassLong(hDlg, GCL_HICON, (LONG)LoadIcon(ghInstance, MAKEINTRESOURCE(IDI_ICON1)));
1202 		SetDlgItemInt(hDlg, IDC_EDIT_YY, curdate.year,  TRUE);
1203 		SetDlgItemInt(hDlg, IDC_EDIT_MM, curdate.month, TRUE);
1204 		SendDlgItemMessage(hDlg, IDC_EDIT_YY, EM_LIMITTEXT, 4, 0L);
1205 		SendDlgItemMessage(hDlg, IDC_EDIT_MM, EM_LIMITTEXT, 2, 0L);
1206 		return (TRUE);
1207 	case WM_COMMAND:
1208 		switch (LOWORD(wParam)) {
1209 		case IDOK:
1210 			input_ymd.year  = GetDlgItemInt(hDlg, IDC_EDIT_YY, &bFlag, TRUE);
1211 			input_ymd.month = GetDlgItemInt(hDlg, IDC_EDIT_MM, &bFlag, TRUE);
1212 			if (isDateValid(input_ymd.year, input_ymd.month) == FALSE) {
1213 				MessageBox(hDlg, "���դ�����������ޤ���", "��������", MB_ICONINFORMATION | MB_OK);
1214 			} else {
1215 				EndDialog(hDlg, 1);
1216 			}
1217 			return (TRUE);
1218 		case IDCANCEL:
1219 			EndDialog(hDlg, 0);
1220 			return (TRUE);
1221 		}
1222 		break;
1223 	case WM_CLOSE:
1224 		EndDialog(hDlg, 0);
1225 		return (TRUE);
1226 	}
1227 
1228 	return (FALSE);
1229 }
1230 
1231 static
showToday(HWND hWnd)1232 void showToday(HWND hWnd)
1233 {
1234 	HWND	hwndToday;
1235 	STARTUPINFO	si;
1236 	PROCESS_INFORMATION	pi;
1237 	char	szCommandLine[256];
1238 	LPARAM	lParam;
1239 
1240 	hwndToday = FindWindow(szTodayClass, NULL);
1241 	if (hwndToday == NULL) {
1242 		ZeroMemory(&si, sizeof(si));
1243 		ZeroMemory(&pi, sizeof(pi));
1244 		si.cb = sizeof(STARTUPINFO);
1245 		si.dwFlags = STARTF_USESHOWWINDOW;
1246 		si.wShowWindow = SW_SHOWNORMAL;
1247 		sprintf(szCommandLine, "%s %04d%02d%02d", szTodayCmd, popinfo->date.year, popinfo->date.month, popinfo->date.day);
1248 		if (CreateProcess(NULL, szCommandLine, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi) == FALSE) {
1249 			sprintf(szCommandLine, "%s �����Ĥ���ޤ���", szTodayCmd);
1250 			MessageBox(hWnd, szCommandLine, szAppName, MB_ICONEXCLAMATION | MB_OK);
1251 		} else {
1252 			CloseHandle(pi.hThread);
1253 			CloseHandle(pi.hProcess);
1254 		}
1255 	} else {
1256 		if (IsIconic(hwndToday)) {
1257 			ShowWindow(hwndToday, SW_RESTORE);
1258 		}
1259 		SetForegroundWindow(hwndToday);
1260 		lParam = (popinfo->date.year << 9) | (popinfo->date.month << 5) | popinfo->date.day;
1261 		SendMessage(hwndToday, umsgToday, 0, lParam);
1262 	}
1263 }
1264 
1265 static
drawPopupMessage(HWND hWnd,int pmcount,struct POPMSG_T * pm)1266 void drawPopupMessage(HWND hWnd, int pmcount, struct POPMSG_T *pm)
1267 {
1268 	PAINTSTRUCT	ps;
1269 	RECT	rcClient;
1270 	RECT	rcText;
1271 	HRGN	hRgn1;
1272 	HRGN	hRgn2;
1273 	HRGN	hRgn3;
1274 	HRGN	hRgn4;
1275 	HPEN	hPen1;
1276 	HPEN	hPen2;
1277 	HBITMAP	hBitmap;
1278 	BITMAP	bm;
1279 	HDC		hMemDC;
1280 	int		x, y;
1281 	int		i;
1282 	int		cy;
1283 	int		limitY;
1284 	char	msg[64];
1285 
1286 	GetClientRect(hWnd, &rcClient);
1287 	hRgn1 = CreateRectRgn(rcClient.left, rcClient.top, rcClient.right - POP_SHADOW_X, rcClient.bottom - POP_SHADOW_Y);
1288 	hRgn2 = CreateRectRgn(rcClient.left + POP_SHADOW_X, rcClient.top + POP_SHADOW_Y, rcClient.right, rcClient.bottom);
1289 	hRgn3 = CreateRectRgn(0, 0, 10, 10);
1290 	CombineRgn(hRgn3, hRgn2, hRgn1, RGN_DIFF);
1291 	hRgn4 = CreateRectRgn(rcClient.left + POP_SKIP_X, rcClient.top + POP_SKIP_Y, rcClient.right - POP_SHADOW_X - POP_SKIP_X, rcClient.bottom - POP_SHADOW_Y - POP_SKIP_Y);
1292 
1293 	BeginPaint(hWnd, &ps);
1294 // draw border
1295 	hPen1 = CreatePen(PS_SOLID, 0, GetSysColor(COLOR_WINDOWFRAME));
1296 	hPen2 = CreatePen(PS_SOLID, 0, GetSysColor(COLOR_3DLIGHT));
1297 	SelectObject(ps.hdc, hPen1);
1298 	SelectObject(ps.hdc, GetStockObject(NULL_BRUSH));
1299 	Rectangle(ps.hdc, rcClient.left, rcClient.top, rcClient.right - POP_SHADOW_X, rcClient.bottom - POP_SHADOW_Y);
1300 	SelectObject(ps.hdc, hPen2);
1301 #if 0
1302 	SelectObject(ps.hdc, GetStockObject(WHITE_BRUSH));
1303 #else
1304 	SelectObject(ps.hdc, GetSysColorBrush(COLOR_INFOBK));
1305 #endif
1306 	Rectangle(ps.hdc, rcClient.left + 1, rcClient.top + 1, rcClient.right - POP_SHADOW_X - 1, rcClient.bottom - POP_SHADOW_Y - 1);
1307 	SelectObject(ps.hdc, GetStockObject(BLACK_PEN));
1308 	DeleteObject(hPen2);
1309 	DeleteObject(hPen1);
1310 // draw shadow
1311 	SelectClipRgn(ps.hdc, hRgn3);
1312 	hBitmap = LoadBitmap(ghInstance, MAKEINTRESOURCE(IDB_SHADOW));
1313 	GetObject(hBitmap, sizeof(BITMAP), &bm);
1314 	hMemDC = CreateCompatibleDC(ps.hdc);
1315 	SelectObject(hMemDC, hBitmap);
1316 	for (y = rcClient.top + POP_SHADOW_Y; y < rcClient.bottom; y += bm.bmHeight) {
1317 		for (x = rcClient.left + POP_SHADOW_X; x < rcClient.right; x += bm.bmWidth) {
1318 			BitBlt(ps.hdc, x, y, bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCAND);
1319 		}
1320 	}
1321 	DeleteDC(hMemDC);
1322 	DeleteObject(hBitmap);
1323 // draw text
1324 	SelectClipRgn(ps.hdc, hRgn4);
1325 	SelectObject(ps.hdc, GetStockObject(SYSTEM_FIXED_FONT));
1326 	SetTextColor(ps.hdc, GetSysColor(COLOR_INFOTEXT));
1327 	SetBkMode(ps.hdc, TRANSPARENT);
1328 	cy = POP_SKIP_Y;
1329 	limitY = rcClient.bottom - POP_SHADOW_Y - POP_SKIP_Y;
1330 	for (i = 0; i < pmcount; i++) {
1331 		if (pm[i].msg != NULL) {
1332 			SetRect(&rcText, POP_SKIP_X, cy, rcClient.right - POP_SHADOW_X - POP_SKIP_X, cy + pm[i].cy);
1333 			if (cy + pm[i].cy >= limitY && (i + 1) != pmcount) {
1334 #define LEN_MSG_REMAIN	24
1335 				sprintf(msg, "����¾�� %d �濫��ޤ�.", pmcount - i);
1336 				DrawTextEx(ps.hdc, msg, -1, &rcText, DT_LEFT | DT_NOCLIP, NULL);
1337 				break;
1338 			} else {
1339 				DrawTextEx(ps.hdc, pm[i].msg, -1, &rcText, DT_LEFT | DT_NOCLIP | DT_NOPREFIX | DT_END_ELLIPSIS, NULL);
1340 			}
1341 		}
1342 		cy += pm[i].cy;
1343 	}
1344 	EndPaint(hWnd, &ps);
1345 
1346 	DeleteObject(hRgn4);
1347 	DeleteObject(hRgn3);
1348 	DeleteObject(hRgn2);
1349 	DeleteObject(hRgn1);
1350 }
1351 
1352 static
setupPopupMessageWindowSize(HWND hWnd,int pmcount,struct POPMSG_T * pm)1353 void setupPopupMessageWindowSize(HWND hWnd, int pmcount, struct POPMSG_T *pm)
1354 {
1355 	RECT	rcWindow;
1356 	TEXTMETRIC	tm;
1357 	POINT	winPos;
1358 	SIZE	winLimit;
1359 	SIZE	winSize;
1360 	SIZE	txtSize;
1361 	HDC		hdc;
1362 	int		i;
1363 
1364 	GetWindowRect(hWnd, &rcWindow);
1365 
1366 	winSize.cx = 0;
1367 	winSize.cy = 0;
1368 
1369 	hdc = GetDC(hWnd);
1370 	SelectObject(hdc, GetStockObject(SYSTEM_FIXED_FONT));
1371 
1372 	GetTextMetrics(hdc, &tm);
1373 	winLimit.cx = GetSystemMetrics(SM_CXSCREEN) * 2 / 3;
1374 	winLimit.cx -= winLimit.cx % tm.tmAveCharWidth;
1375 	if (rcWindow.top > (GetSystemMetrics(SM_CYSCREEN) - rcWindow.bottom)) {
1376 		winLimit.cy = rcWindow.top;
1377 	} else {
1378 		winLimit.cy = GetSystemMetrics(SM_CYSCREEN) - rcWindow.bottom;
1379 	}
1380 	winLimit.cy -= POP_SHADOW_Y + POP_SKIP_Y * 3;
1381 	winLimit.cy -= winLimit.cy % (tm.tmHeight + tm.tmExternalLeading);
1382 
1383 	for (i = 0; i < pmcount; i++) {
1384 		if (pm[i].msg != NULL) {
1385 			GetTextExtentPoint32(hdc, pm[i].msg, pm[i].len, &txtSize);
1386 			if (txtSize.cx > winSize.cx) {
1387 				winSize.cx = txtSize.cx;
1388 			}
1389 		} else {
1390 			txtSize.cy = POP_SKIP_Y;
1391 			winLimit.cy += txtSize.cy;
1392 		}
1393 		winSize.cy += txtSize.cy;
1394 		pm[i].cy = txtSize.cy;
1395 	}
1396 
1397 	ReleaseDC(hWnd, hdc);
1398 
1399 	if (winSize.cx > winLimit.cx) {
1400 		winSize.cx = winLimit.cx;
1401 	}
1402 	if (winSize.cy > winLimit.cy) {
1403 		winSize.cy = winLimit.cy;
1404 		/* ����ɽ���Ǥ��ʤ����ᡢ���ɽ�����뤿��κ�������ɬ�� */
1405 		i = LEN_MSG_REMAIN * tm.tmAveCharWidth;	/* �Ǿ�������ɥ����� */
1406 		if (winSize.cx < i) {
1407 			winSize.cx = i;
1408 		}
1409 	}
1410 	winSize.cx += POP_SKIP_X * 2 + POP_SHADOW_X;
1411 	winSize.cy += POP_SKIP_Y * 2 + POP_SHADOW_Y;
1412 
1413 	winPos.x = rcWindow.left;
1414 	winPos.y = rcWindow.bottom;
1415 
1416 	if ((winPos.x + winSize.cx) > GetSystemMetrics(SM_CXSCREEN)) {
1417 		winPos.x = GetSystemMetrics(SM_CXSCREEN) - winSize.cx;
1418 	}
1419 	if ((winPos.y + winSize.cy) >= GetSystemMetrics(SM_CYSCREEN)) {
1420 		winPos.y = rcWindow.top - winSize.cy;
1421 	}
1422 
1423 	SetWindowPos(hWnd, NULL, winPos.x, winPos.y, winSize.cx, winSize.cy, SWP_NOZORDER);
1424 }
1425 
1426 static
allocPopMsg(struct POPMSG_T * pm,int count)1427 struct POPMSG_T *allocPopMsg(struct POPMSG_T *pm, int count)
1428 {
1429 	struct POPMSG_T	*newpm;
1430 
1431 	newpm = realloc(pm, sizeof(struct POPMSG_T) * count);
1432 	if (newpm == NULL) {
1433 		memerr("allocPopMsg");
1434 	}
1435 	return (newpm);
1436 }
1437 
1438 static
createPopupMessage(int * pmcount)1439 struct POPMSG_T *createPopupMessage(int *pmcount)
1440 {
1441 	struct POPMSG_T	*pm;
1442 	int		cnt;
1443 	char	buf[256];
1444 	const char	*p;
1445 	int		msgcnt;
1446 	char	**msgtbl;
1447 	int		i;
1448 
1449 	pm = NULL;
1450 	cnt = 0;
1451 
1452 	sprintf(buf, "%d/%02d/%02d(%s)",
1453 		popinfo->date.year, popinfo->date.month, popinfo->date.day,
1454 		week_name[popinfo->date.dayofweek]);
1455 	if ((popinfo->attr & ATTR_LUNARCAL) != 0) {
1456 		sprintf(strlastp(buf), " [����%s%02d/%02d(%s)]",
1457 		popinfo->lc.leap ? "��" : "",
1458 		popinfo->lc.month, popinfo->lc.day,
1459 		rokuyou_name[popinfo->lc.dayofweek]);
1460 	}
1461 
1462 	pm = allocPopMsg(pm, cnt + 1);
1463 	pm[cnt].cy = 0;
1464 	pm[cnt].len = strlen(buf);
1465 	pm[cnt].msg = xstrdup(buf);
1466 	cnt++;
1467 
1468 	if (popinfo->holiday != 0 || popinfo->attr & ATTR_TRANSHOL) {
1469 		p = GetHolidayName(popinfo->holiday);
1470 		pm = allocPopMsg(pm, cnt + 1);
1471 		pm[cnt].cy = 0;
1472 		pm[cnt].len = strlen(p);
1473 		pm[cnt].msg = (char *)p;
1474 		cnt++;
1475 	}
1476 
1477 	p = GetSekkiName(popinfo->date.year, popinfo->date.month, popinfo->date.day, NULL);
1478 	if (p != NULL) {
1479 		pm = allocPopMsg(pm, cnt + 1);
1480 		pm[cnt].cy = 0;
1481 		pm[cnt].len = strlen(p);
1482 		pm[cnt].msg = xstrdup(p);
1483 		cnt++;
1484 	}
1485 
1486 	if (schedule_flag == TRUE && (popinfo->attr & ATTR_SCHEDULE) != 0) {
1487 		msgtbl = schedule_loadmsg(popinfo->date.year, popinfo->date.month, popinfo->date.day, &msgcnt);
1488 		if (msgtbl != NULL) {
1489 			pm = allocPopMsg(pm, cnt + msgcnt + 1);
1490 			pm[cnt].cy = 0;
1491 			pm[cnt].len = 0;
1492 			pm[cnt].msg = NULL;
1493 			cnt++;
1494 			for (i = 0; i < msgcnt; i++) {
1495 				pm[cnt + i].cy = 0;
1496 				pm[cnt + i].len = strlen(msgtbl[i]);
1497 				pm[cnt + i].msg = msgtbl[i];
1498 			}
1499 			cnt += msgcnt;
1500 			free(msgtbl);
1501 		}
1502 	}
1503 
1504 	*pmcount = cnt;
1505 	return (pm);
1506 }
1507 
PopupMsgWndProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam)1508 LRESULT CALLBACK PopupMsgWndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam)
1509 {
1510 	static int	pmcount = 0;
1511 	static struct POPMSG_T	*pm = NULL;
1512 	static BOOL	bSyskey;
1513 	int	i;
1514 
1515 	switch (iMessage) {
1516 	case WM_CREATE:
1517 		pm = createPopupMessage(&pmcount);
1518 		setupPopupMessageWindowSize(hWnd, pmcount, pm);
1519 		SetCapture(hWnd);
1520 		bSyskey = FALSE;
1521 		break;
1522 	case WM_PAINT:
1523 		drawPopupMessage(hWnd, pmcount, pm);
1524 		break;
1525 	case WM_ACTIVATE:
1526 		if (LOWORD(wParam) == WA_INACTIVE) {
1527 			PostMessage(hWnd, WM_CLOSE, 0, 0L);
1528 		}
1529 		break;
1530 	case WM_ACTIVATEAPP:
1531 		if (wParam == FALSE) {
1532 			PostMessage(hWnd, WM_CLOSE, 0, 0L);
1533 		}
1534 		break;
1535 	case WM_SYSKEYDOWN:
1536 		bSyskey = TRUE;
1537 		break;
1538 	case WM_SYSKEYUP:
1539 		bSyskey = FALSE;
1540 		break;
1541 	case WM_KEYUP:
1542 		switch (wParam) {
1543 //		case VK_TAB:
1544 		case VK_SNAPSHOT:
1545 		case VK_SHIFT:
1546 		case VK_CONTROL:
1547 		case VK_CAPITAL:
1548 			return (0);
1549 		}
1550 		/* no break */
1551 	case WM_CANCELMODE:
1552 		if (bSyskey == FALSE) {
1553 			PostMessage(hWnd, WM_CLOSE, 0, 0L);
1554 		} else if (iMessage == WM_KEYUP) {
1555 			bSyskey = FALSE;
1556 		}
1557 		break;
1558 	case WM_LBUTTONUP:
1559 	case WM_MBUTTONUP:
1560 	case WM_RBUTTONUP:
1561 //	case WM_XBUTTONUP:
1562 		PostMessage(hWnd, WM_CLOSE, 0, 0L);
1563 		break;
1564 	case WM_DESTROY:
1565 		ReleaseCapture();
1566 		hwndMsg = NULL;
1567 		/* delete message */
1568 		if (pm != NULL) {
1569 			for (i = 0; i < pmcount; i++) {
1570 				if (pm[i].msg != NULL) {
1571 					free(pm[i].msg);
1572 				}
1573 			}
1574 			free(pm);
1575 		}
1576 		pmcount = 0;
1577 		pm = NULL;
1578 		break;
1579 	default:
1580 		return (DefWindowProc(hWnd, iMessage, wParam, lParam));
1581 	}
1582 
1583 	return (0);
1584 }
1585 
1586 static
createPopupMessageWindow(HWND hWnd,int xpos,int ypos)1587 void createPopupMessageWindow(HWND hWnd, int xpos, int ypos)
1588 {
1589 	POINT	pt;
1590 
1591 	if (hwndMsg != NULL) {
1592 		DestroyWindow(hwndMsg);
1593 	}
1594 
1595 	pt.x = xpos - (xpos % sizeBlk.cx);
1596 	pt.y = ypos - ((ypos - sizeToolbar.cy - sizeChar.cy * 2) % sizeBlk.cy);
1597 	ClientToScreen(hWnd, &pt);
1598 	hwndMsg = CreateWindowEx(WS_EX_TOPMOST, szAppNameMsg, NULL,
1599 				WS_POPUP | WS_VISIBLE, pt.x, pt.y, sizeBlk.cx, sizeBlk.cy,
1600 				hWnd, NULL, ghInstance, NULL);
1601 }
1602 
checkClickWindowPosition(int kind,HWND hWnd,LPARAM mousePos[2])1603 void checkClickWindowPosition(int kind, HWND hWnd, LPARAM mousePos[2])
1604 {
1605 	POINT	pt1;
1606 	POINT	pt2;
1607 	int	current_month;
1608 	int	point_day;
1609 
1610 	pt1.x = LOWORD(mousePos[0]);
1611 	pt1.y = HIWORD(mousePos[0]);
1612 	pt2.x = LOWORD(mousePos[1]);
1613 	pt2.y = HIWORD(mousePos[1]);
1614 
1615 	if (kind != 1) {
1616 		if ((abs(pt1.x - pt2.x) > GetSystemMetrics(SM_CXDOUBLECLK)) ||
1617 		    (abs(pt1.y - pt2.y) > GetSystemMetrics(SM_CYDOUBLECLK))) {
1618 			return ;
1619 		}
1620 	}
1621 
1622 	pt2 = pt1;
1623 
1624 	pt2.y -= sizeToolbar.cy + sizeChar.cy * 2;
1625 	if (pt2.y < 0) {
1626 		return ;
1627 	}
1628 
1629 	pt2.x /= sizeBlk.cx;
1630 	point_day = (pt2.x % MAXWEEK) + (pt2.y / sizeBlk.cy) * MAXWEEK;
1631 
1632 	if (cal3_flag == FALSE) {
1633 		current_month = SHOW_CENTERMONTH;
1634 	} else {
1635 		current_month = pt2.x / MAXWEEK;
1636 	}
1637 
1638 	popinfo = tblCalDay[current_month][point_day];
1639 	if (popinfo == NULL) {
1640 		return ;
1641 	}
1642 
1643 	switch (kind) {
1644 	case 1:
1645 		createPopupMessageWindow(hWnd, pt1.x, pt1.y);
1646 		break;
1647 	case 2:
1648 		showToday(hWnd);
1649 		break;
1650 	}
1651 }
1652 
1653 #define TXCOL_DAY		0
1654 #define TXCOL_ROKUYOU	1
1655 #define TXCOL_SCHEDULE	2
1656 static
setTextColor(HDC hdc,int type,DAYINFO * di)1657 void setTextColor(HDC hdc, int type, DAYINFO *di)
1658 {
1659 	int	dayofweek;
1660 	int	cindex;
1661 
1662 	switch (type) {
1663 	case TXCOL_DAY:
1664 		dayofweek = (int)di;
1665 		if (dayofweek >= 0 && dayofweek <= 6) {
1666 			;
1667 		} else if ((di->attr & ATTR_GRAYEDDAY) != 0) {
1668 			cindex = COL_GRAYDAY;
1669 			break;
1670 		} else if ((di->attr & (ATTR_HOLIDAY | ATTR_TRANSHOL)) != 0) {
1671 			cindex = COL_HOLIDAY;
1672 			break;
1673 		} else {
1674 			dayofweek = di->date.dayofweek;
1675 		}
1676 		switch (dayofweek) {
1677 		case 0:	/* sunday */
1678 			cindex = COL_SUNDAY;
1679 			break;
1680 		case 6:	/* saturday */
1681 			cindex = COL_SATDAY;
1682 			break;
1683 		default:
1684 			cindex = COL_WEEKDAY;
1685 			break;
1686 		}
1687 		break;
1688 	case TXCOL_ROKUYOU:
1689 		if ((di->attr & ATTR_GRAYEDDAY) != 0) {
1690 			cindex = COL_GRAYDAY;
1691 		} else {
1692 			cindex = COL_ROKUYOU + di->lc.dayofweek;
1693 		}
1694 		break;
1695 	case TXCOL_SCHEDULE:
1696 		if ((di->attr & ATTR_GRAYEDDAY) != 0) {
1697 			cindex = COL_GRAYDAY;
1698 		} else {
1699 			cindex = COL_SCHEDULE;
1700 		}
1701 		break;
1702 	}
1703 
1704 	SetTextColor(hdc, RGB2PALETTERGB(colormap[calcolor[cindex]]));
1705 }
1706 
1707 static
drawCenterText(HDC hdc,const char * text,int x,int y,int width)1708 void drawCenterText(HDC hdc, const char *text, int x, int y, int width)
1709 {
1710 	SIZE	txtSize;
1711 	int	len = strlen(text);
1712 
1713 	GetTextExtentPoint32(hdc, text, len, &txtSize);
1714 	TextOut(hdc, x + (width - txtSize.cx) / 2, y, text, len);
1715 }
1716 
1717 static
drawScreen(HWND hWnd)1718 void drawScreen(HWND hWnd)
1719 {
1720 	PAINTSTRUCT	ps;
1721 	HPEN	hPen1;
1722 	HPEN	hPen2;
1723 	int		weektype;
1724 	int		current_month;
1725 	int		month_count;
1726 	int		bx;
1727 	int		i;
1728 	int		x;
1729 	int		y;
1730 	RECT	rcEdge;
1731 	char	buf[32];
1732 	PDAYINFO	*ppDayInfo;
1733 	DAYINFO	*pDayInfo;
1734 
1735 	if (CHK_EXTFLAGS(EXTFLAGS_WEEKTYPE) == 0) {
1736 		weektype = 0;
1737 	} else {
1738 		weektype = 1;
1739 	}
1740 
1741 	hPen1 = CreatePen(PS_SOLID, 0, RGB2PALETTERGB(colormap[calcolor[COL_FRAME]]));
1742 	hPen2 = CreatePen(PS_SOLID, 2, RGB2PALETTERGB(colormap[calcolor[COL_FRAME]]));
1743 
1744 	BeginPaint(hWnd, &ps);
1745 	SetViewportOrgEx(ps.hdc, 0, sizeToolbar.cy, NULL);
1746 
1747 	if (cal3_flag == FALSE) {
1748 		current_month = SHOW_CENTERMONTH;
1749 		month_count = 1;
1750 	} else {
1751 		current_month = 0;
1752 		month_count = SHOW_MAXMONTH;
1753 	}
1754 
1755 	/* rows line */
1756 	x = sizeBlk.cx * MAXWEEK * month_count;
1757 	SelectObject(ps.hdc, hPen1);
1758 	MoveToEx(ps.hdc, 0, sizeChar.cy, NULL);
1759 	LineTo(ps.hdc, x, sizeChar.cy);
1760 	for (y = sizeChar.cy * 2, i = 0; i < MAXLINE; y += sizeBlk.cy, i++) {
1761 		MoveToEx(ps.hdc, 0, y, NULL);
1762 		LineTo(ps.hdc, x, y);
1763 	}
1764 	/* columns line */
1765 	y = sizeChar.cy * 2 + sizeBlk.cy * MAXLINE;
1766 	for (x = 0, i = 1; i < MAXWEEK * month_count; i++) {
1767 		x += sizeBlk.cx;
1768 		if ((i % 7) == 0) {
1769 			SelectObject(ps.hdc, hPen2);
1770 			MoveToEx(ps.hdc, x, 0, NULL);
1771 		} else {
1772 			SelectObject(ps.hdc, hPen1);
1773 			MoveToEx(ps.hdc, x, sizeChar.cy, NULL);
1774 		}
1775 		LineTo(ps.hdc, x, y);
1776 	}
1777 
1778 	ppDayInfo = &tblCalDay[current_month][0];
1779 	SetBkMode(ps.hdc, TRANSPARENT);
1780 	SelectObject(ps.hdc, hfontA);
1781 	for (bx = 0; month_count > 0; bx += sizeBlk.cx * MAXWEEK, current_month++, month_count--) {
1782 		/* month name */
1783 		sprintf(buf, "%d %s", tblCalName[current_month].year, tblCalName[current_month].name);
1784 		SetTextColor(ps.hdc, RGB2PALETTERGB(colormap[calcolor[COL_TITLE]]));
1785 		drawCenterText(ps.hdc, buf, bx, 0, sizeBlk.cx * MAXWEEK);
1786 		/* week name */
1787 		for (i = 0; i < MAXWEEK; i++) {
1788 			x = bx + sizeBlk.cx * week_index[weektype][i];
1789 			setTextColor(ps.hdc, TXCOL_DAY, (DAYINFO *)i);
1790 			drawCenterText(ps.hdc, week_name[i], x, sizeChar.cy, sizeBlk.cx);
1791 		}
1792 		/* day */
1793 		for (i = 0; i < MAXDAYTBL; ppDayInfo++, i++) {
1794 			if (*ppDayInfo != NULL) {
1795 				pDayInfo = *ppDayInfo;
1796 				x = bx + sizeBlk.cx * (i % MAXWEEK);
1797 				y = sizeBlk.cy * (i / MAXWEEK) + sizeChar.cy * 2;
1798 				if (pDayInfo->attr & ATTR_TODAY) {
1799 					SetRect(&rcEdge, x, y, x + sizeBlk.cx + 1, y + sizeBlk.cy + 1);
1800 					InflateRect(&rcEdge, -1, -1);
1801 					DrawEdge(ps.hdc, &rcEdge, EDGE_SUNKEN, BF_RECT);
1802 				}
1803 				sprintf(buf, "%d", pDayInfo->date.day);
1804 				setTextColor(ps.hdc, TXCOL_DAY, pDayInfo);
1805 				drawCenterText(ps.hdc, buf, x, y, sizeBlk.cx);
1806 
1807 				if (rokuyou_flag == TRUE && (pDayInfo->attr & ATTR_LUNARCAL) != 0 && rokuyou_item[pDayInfo->lc.dayofweek] != 0) {
1808 					SelectObject(ps.hdc, hfontK);
1809 					setTextColor(ps.hdc, TXCOL_ROKUYOU, pDayInfo);
1810 					drawCenterText(ps.hdc, rokuyou_name[pDayInfo->lc.dayofweek], x, y + sizeChar.cy, sizeBlk.cx);
1811 					SelectObject(ps.hdc, hfontA);
1812 				}
1813 
1814 				if (schedule_flag == TRUE && (pDayInfo->attr & ATTR_SCHEDULE) != 0) {
1815 					SelectObject(ps.hdc, hfontK);
1816 					setTextColor(ps.hdc, TXCOL_SCHEDULE, pDayInfo);
1817 #if 1
1818 					TextOut(ps.hdc, x + sizeKChar.cx / 2, y, "*", 1);
1819 #else
1820 					TextOut(ps.hdc, x + sizeKChar.cx / 2, y + sizeChar.cy, "*", 1);
1821 #endif
1822 					SelectObject(ps.hdc, hfontA);
1823 				}
1824 			}
1825 		}
1826 	}
1827 
1828 	EndPaint(hWnd, &ps);
1829 
1830 	DeleteObject(hPen2);
1831 	DeleteObject(hPen1);
1832 }
1833 
1834 static
updateCalendar(HWND hWnd,int mode)1835 void updateCalendar(HWND hWnd, int mode)
1836 {
1837 	SIZE	client;
1838 	SIZE	wc;
1839 	SIZE	screen;
1840 	RECT	rcWindow;
1841 	RECT	rcClient;
1842 	RECT	rcButton;
1843 	HMENU	hMenu;
1844 	int		index;
1845 
1846 	if (mode != SHOW_FIRST) {
1847 		rdcalendar(&nowdate);
1848 	}
1849 
1850 	if (mode == SHOW_TODAY) {
1851 		curdate.year  = nowdate.year;
1852 		curdate.month = nowdate.month;
1853 	}
1854 
1855 	makeCalTbl();
1856 
1857 	if (cal3_flag == FALSE) {
1858 		client.cx = sizeBlk.cx * MAXWEEK;
1859 	} else {
1860 		client.cx = (sizeBlk.cx * MAXWEEK) * 3;
1861 	}
1862 	client.cy = sizeToolbar.cy + sizeChar.cy * 2 + sizeBlk.cy * MAXLINE;
1863 
1864 	wc.cx = client.cx + GetSystemMetrics(SM_CXFIXEDFRAME) * 2;
1865 	wc.cy = client.cy + GetSystemMetrics(SM_CYCAPTION) + GetSystemMetrics(SM_CYMENU) +
1866 			GetSystemMetrics(SM_CYFIXEDFRAME) * 2;
1867 
1868 	GetWindowRect(hWnd, &rcWindow);
1869 	if (mode == SHOW_FIRST) {
1870 		screen.cx = GetSystemMetrics(SM_CXSCREEN);
1871 		screen.cy = GetSystemMetrics(SM_CYSCREEN);
1872 		if (wc.cx <= screen.cx && (rcWindow.left + wc.cx) > screen.cx) {
1873 			rcWindow.left = (screen.cx - wc.cx) / 2;
1874 		}
1875 		if (wc.cy <= screen.cy && (rcWindow.top + wc.cy) > screen.cy) {
1876 			rcWindow.top = 0;
1877 		}
1878 	}
1879 
1880 	SetWindowPos(hWnd, NULL, rcWindow.left, rcWindow.top, wc.cx, wc.cy, SWP_NOZORDER | SWP_SHOWWINDOW);
1881 
1882 	GetClientRect(hWnd, &rcClient);
1883 	if (rcClient.right != client.cx || rcClient.bottom != client.cy) {
1884 		wc.cx += client.cx - rcClient.right;
1885 		wc.cy += client.cy - rcClient.bottom;
1886 		SetWindowPos(hWnd, NULL, 0, 0, wc.cx, wc.cy, SWP_NOZORDER | SWP_NOMOVE | SWP_SHOWWINDOW);
1887 	}
1888 
1889 	InvalidateRect(hWnd, NULL, TRUE);
1890 
1891 	GetClientRect(hWnd, &rcClient);
1892 	index = SendMessage(hwndToolbar, TB_COMMANDTOINDEX, IDM_ROKUYOU, 0);
1893 	SendMessage(hwndToolbar, TB_GETITEMRECT, index, (LPARAM)&rcButton);
1894 	if (rcButton.right < rcClient.right) {
1895 		SendMessage(hwndToolbar, TB_HIDEBUTTON, IDM_ROKUYOU, FALSE);
1896 //		SendMessage(hwndToolbar, TB_HIDEBUTTON, IDM_ABOUT, FALSE);
1897 //		SendMessage(hwndToolbar, TB_HIDEBUTTON, IDM_HELP, FALSE);
1898 	} else {
1899 		/* hide buttons */
1900 		SendMessage(hwndToolbar, TB_HIDEBUTTON, IDM_ROKUYOU, TRUE);
1901 //		SendMessage(hwndToolbar, TB_HIDEBUTTON, IDM_ABOUT, TRUE);
1902 //		SendMessage(hwndToolbar, TB_HIDEBUTTON, IDM_HELP, TRUE);
1903 	}
1904 
1905 	SendMessage(hwndToolbar, TB_CHECKBUTTON, (cal3_flag == FALSE) ? IDM_MONTH1 : IDM_MONTH3, TRUE);
1906 	SendMessage(hwndToolbar, TB_CHECKBUTTON, IDM_ROKUYOU, rokuyou_flag);
1907 
1908 #define MENU_CHECK(x)	((x) ? (MF_BYCOMMAND | MFS_CHECKED) : (MF_BYCOMMAND | MFS_UNCHECKED))
1909 	hMenu = GetMenu(hWnd);
1910 	CheckMenuItem(hMenu, IDM_MONTH1, MENU_CHECK(cal3_flag == FALSE));
1911 	CheckMenuItem(hMenu, IDM_MONTH3, MENU_CHECK(cal3_flag != FALSE));
1912 	CheckMenuItem(hMenu, IDM_ROKUYOU, MENU_CHECK(rokuyou_flag != FALSE));
1913 	CheckMenuItem(hMenu, IDM_SCHEDULE, MENU_CHECK(schedule_flag != FALSE));
1914 	CheckMenuItem(hMenu, IDM_GRAYDAY, MENU_CHECK(CHK_EXTFLAGS(EXTFLAGS_GRAYEDDAY)));
1915 }
1916 
1917 static
initMenu(HWND hWnd)1918 void initMenu(HWND hWnd)
1919 {
1920 	static HMENU	hPopMenuE = NULL;
1921 	HMENU	hMenu;
1922 	char	szText[32];
1923 
1924 	hMenu = GetMenu(hWnd);
1925 	if (file_editor_cmd == NULL) {
1926 		if (hPopMenuE != NULL) {
1927 			DeleteMenu(hMenu, 1, MF_BYPOSITION);
1928 			DrawMenuBar(hWnd);
1929 			DestroyMenu(hPopMenuE);
1930 			hPopMenuE = NULL;
1931 		}
1932 	} else {
1933 		if (hPopMenuE == NULL) {
1934 			hPopMenuE = CreatePopupMenu();
1935 			LoadString(ghInstance, IDM_EXT_EDIT, szText, sizeof(szText));
1936 			AppendMenu(hPopMenuE, MFT_STRING, IDM_EXT_EDIT, szText);
1937 			LoadString(ghInstance, IDS_EDIT_TOPMENU, szText, sizeof(szText));
1938 			InsertMenu(hMenu, 1, MF_POPUP | MF_BYPOSITION | MFT_STRING, (UINT)hPopMenuE, szText);
1939 			DrawMenuBar(hWnd);
1940 		}
1941 	}
1942 }
1943 
1944 static
notifyToolbar(LPTOOLTIPTEXT lpToolTipText)1945 void notifyToolbar(LPTOOLTIPTEXT lpToolTipText)
1946 {
1947 	static char	szBuffer[64];
1948 	int	id;
1949 
1950 	if (lpToolTipText->hdr.code == TTN_NEEDTEXT) {
1951 		id = lpToolTipText->hdr.idFrom;
1952 		if (id == IDM_ROKUYOU) {
1953 			if (rokuyou_flag == 0) {
1954 				id = IDM_ROKUYOU1;
1955 			} else {
1956 				id = IDM_ROKUYOU2;
1957 			}
1958 		}
1959 		LoadString(ghInstance, id, szBuffer, sizeof(szBuffer));
1960 		lpToolTipText->lpszText = szBuffer;
1961 	}
1962 }
1963 
1964 static
createFont(HWND hWnd)1965 void createFont(HWND hWnd)
1966 {
1967 	HDC	hdc;
1968 	TEXTMETRIC	tm;
1969 	SIZE	txtSize;
1970 	int	i;
1971 	int	xmax = 0;
1972 
1973 	if (hfontA != NULL) {
1974 		DeleteObject(hfontA);
1975 	}
1976 	hfontA = CreateFont(bigfont_flag ? 24 : 18, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, FONT_ANK);
1977 
1978 	if (hfontK != NULL) {
1979 		DeleteObject(hfontK);
1980 	}
1981 	hfontK = CreateFont(12, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, SHIFTJIS_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, FONT_KNJ);
1982 
1983 	hdc = GetDC(hWnd);
1984 	SelectObject(hdc, hfontA);
1985 	GetTextMetrics(hdc, &tm);
1986 	sizeChar.cx = tm.tmAveCharWidth;
1987 	sizeChar.cy = tm.tmHeight + tm.tmExternalLeading;
1988 	for (i = 0; i < MAXWEEK; i++) {
1989 		GetTextExtentPoint32(hdc, week_name[i], strlen(week_name[i]), &txtSize);
1990 		if (xmax < txtSize.cx) {
1991 			xmax = txtSize.cx;
1992 		}
1993 	}
1994 	SelectObject(hdc, hfontK);
1995 	GetTextMetrics(hdc, &tm);
1996 	sizeKChar.cx = tm.tmAveCharWidth;
1997 	sizeKChar.cy = tm.tmHeight + tm.tmExternalLeading;
1998 	ReleaseDC(hWnd, hdc);
1999 
2000 	sizeBlk.cx = sizeChar.cx * 5;
2001 	if (CHK_EXTFLAGS(EXTFLAGS_OLDCALSIZE) == FALSE) {
2002 		sizeBlk.cx = max(sizeBlk.cx, xmax + BLK_XGAP);
2003 	}
2004 	sizeBlk.cy = sizeChar.cy + sizeKChar.cy;
2005 }
2006 
2007 static
createWindowFrame(HWND hWnd)2008 int createWindowFrame(HWND hWnd)
2009 {
2010 	BOOL		bFlat;
2011 	DWORD		dStyle;
2012 	RECT		rcWindow;
2013 	WNDCLASS	wndclass;
2014 	char		szText[256];
2015 
2016 	InitCommonControls();
2017 	initMenu(hWnd);
2018 
2019 	if (CHK_SYSFLAGS(SYSFLAGS_TOOLFLAT) != FALSE &&
2020 	    GetDllVersion("comctl32.dll") >= PACKVERSION(4,70)) {
2021 		bFlat = TRUE;
2022 	} else {
2023 		bFlat = FALSE;
2024 	}
2025 
2026 	hwndToolbar = CreateToolbarEx(hWnd, WS_CHILD | WS_VISIBLE | TBSTYLE_TOOLTIPS,
2027 		IDC_TOOLBAR, NUMIMAGES, ghInstance, bFlat ? IDB_TBFLAT : IDB_TBHOT,
2028 		tbButton, sizeof(tbButton) / sizeof(TBBUTTON), 0, 0, IMAGEWIDTH, IMAGEHEIGHT, sizeof(TBBUTTON));
2029 
2030 	if (hwndToolbar == NULL) {
2031 		MessageBox(hWnd, "�ġ���С��������Ǥ��ޤ���", szAppNameLong, MB_ICONEXCLAMATION | MB_OK);
2032 		DestroyWindow(hWnd);
2033 		return (FALSE);
2034 	}
2035 	if (bFlat != FALSE) {
2036 		dStyle = SendMessage(hwndToolbar, TB_GETSTYLE, 0, 0L);
2037 		SendMessage(hwndToolbar, TB_SETSTYLE,0, (dStyle | TBSTYLE_FLAT));
2038 		hImgList = ImageList_LoadBitmap(ghInstance, MAKEINTRESOURCE(IDB_TBHOT), IMAGEWIDTH, 1, IMAGEMASKRGB);
2039 		SendMessage(hwndToolbar, TB_SETHOTIMAGELIST, 0, (LPARAM)hImgList);
2040 //		ShowWindow(hwndToolbar, SW_HIDE);
2041 //		ShowWindow(hwndToolbar, SW_SHOW);
2042 	}
2043 
2044 	GetWindowRect(hwndToolbar, &rcWindow);
2045 	sizeToolbar.cx = rcWindow.right - rcWindow.left;
2046 	sizeToolbar.cy = rcWindow.bottom - rcWindow.top;
2047 
2048 	createFont(hWnd);
2049 
2050 	wndclass.style         = 0;
2051 	wndclass.lpfnWndProc   = (WNDPROC)PopupMsgWndProc;
2052 	wndclass.cbClsExtra    = 0;
2053 	wndclass.cbWndExtra    = 0;
2054 	wndclass.hInstance     = ghInstance;
2055 	wndclass.hIcon         = NULL;
2056 	wndclass.hCursor       = LoadCursor(NULL, IDC_ARROW);
2057 	wndclass.hbrBackground = GetStockObject(NULL_BRUSH);
2058 	wndclass.lpszMenuName  = NULL;
2059 	wndclass.lpszClassName = szAppNameMsg;
2060 
2061 	if (!RegisterClass(&wndclass)) {
2062 		DestroyWindow(hWnd);
2063 		return (FALSE);
2064 	}
2065 
2066 	sprintf(szText, "%s Control Message", szTodayClass);
2067 	umsgToday = RegisterWindowMessage(szText);
2068 	sprintf(szText, "%s Control Message", szAppName);
2069 	umsgCal = RegisterWindowMessage(szText);
2070 
2071 	return (TRUE);
2072 }
2073 
WndProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam)2074 LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam)
2075 {
2076 	static BOOL	bTimer;
2077 	static int	nClick;
2078 	static LPARAM	mousePos[2];
2079 	struct DATE_T	nowDate;
2080 
2081 	if (iMessage == umsgCal) {
2082 		input_ymd.year  = (lParam >> 9) & 0x3FFF;
2083 		input_ymd.month = (lParam >> 5) & 0x000F;
2084 		if (isDateValid(input_ymd.year, input_ymd.month) == TRUE) {
2085 			curdate.year  = input_ymd.year;
2086 			curdate.month = input_ymd.month;
2087 			updateCalendar(hWnd, SHOW_SETDATE);
2088 		}
2089 		return (0);
2090 	}
2091 
2092 	switch (iMessage) {
2093 	case WM_CREATE:
2094 		if (createWindowFrame(hWnd) == TRUE) {
2095 			updateCalendar(hWnd, SHOW_FIRST);
2096 		}
2097 		bTimer = FALSE;
2098 		break;
2099 	case WM_COMMAND:
2100 		switch (LOWORD(wParam)) {
2101 		case IDM_EXIT:
2102 			DestroyWindow(hWnd);
2103 			break;
2104 		case IDM_SETUP:
2105 			setupPropertyProc(hWnd);
2106 			if (bChangeProp == TRUE) {
2107 				if (MessageBox(hWnd, "�ѹ����Ƥ�ե�����(TODAY.CNF)\n����¸���ޤ���?", "�ץ�ѥƥ�", MB_ICONINFORMATION | MB_YESNO) == IDYES) {
2108 					preserveConfig(hWnd);
2109 				}
2110 				if (bChangeFont == TRUE) {
2111 					createFont(hWnd);
2112 				}
2113 				initMenu(hWnd);
2114 				updateCalendar(hWnd, SHOW_SETDATE);
2115 			}
2116 			break;
2117 		case IDM_EXT_EDIT:
2118 			nowDate.year = curdate.year;
2119 			nowDate.month = curdate.month;
2120 			nowDate.day = 0;
2121 			externalFileEdit(hWnd, ghInstance, nowDate);
2122 			break;
2123 		case IDM_FINDSTRING:
2124 			findString(hWnd, ghInstance);
2125 			break;
2126 		case IDM_DATENOW:
2127 			updateCalendar(hWnd, SHOW_TODAY);
2128 			break;
2129 		case IDM_DATESET:
2130 			if (DialogBox(ghInstance, MAKEINTRESOURCE(IDD_DATESET1), hWnd, (DLGPROC)SetDateDlgProc) == 1) {
2131 				curdate.year  = input_ymd.year;
2132 				curdate.month = input_ymd.month;
2133 				updateCalendar(hWnd, SHOW_SETDATE);
2134 			}
2135 			break;
2136 		case IDM_YYUP:
2137 		case IDM_YYDOWN:
2138 		case IDM_MMUP:
2139 		case IDM_MMDOWN:
2140 			dateControl(LOWORD(wParam) - IDM_YYUP);
2141 			updateCalendar(hWnd, SHOW_SETDATE);
2142 			break;
2143 		case IDM_MONTH1:
2144 			if (cal3_flag == TRUE) {
2145 				cal3_flag = FALSE;
2146 				updateCalendar(hWnd, SHOW_SETDATE);
2147 			}
2148 			break;
2149 		case IDM_MONTH3:
2150 			if (cal3_flag == FALSE) {
2151 				cal3_flag = TRUE;
2152 				updateCalendar(hWnd, SHOW_SETDATE);
2153 			}
2154 			break;
2155 		case IDM_ROKUYOU:
2156 			rokuyou_flag = !rokuyou_flag;
2157 			updateCalendar(hWnd, SHOW_SETDATE);
2158 			break;
2159 		case IDM_SCHEDULE:
2160 			schedule_flag = !schedule_flag;
2161 			updateCalendar(hWnd, SHOW_SETDATE);
2162 			break;
2163 		case IDM_GRAYDAY:
2164 			CHG_EXTFLAGS(EXTFLAGS_GRAYEDDAY);
2165 			updateCalendar(hWnd, SHOW_SETDATE);
2166 			break;
2167 		case IDM_HELP:
2168 			WinHelp(hWnd, szHelpFile, HELP_FINDER, 0L);
2169 			break;
2170 		case IDM_ABOUT:
2171 			DialogBox(ghInstance, MAKEINTRESOURCE(IDD_ABOUT), hWnd, (DLGPROC)AboutDlgProc);
2172 			break;
2173 		}
2174 		break;
2175 	case WM_LBUTTONDOWN:
2176 		if (bTimer == FALSE) {
2177 			SetTimer(hWnd, CLICK_TIMER, GetDoubleClickTime(), NULL);
2178 			bTimer = TRUE;
2179 			nClick = 0;
2180 		} else {
2181 			KillTimer(hWnd, CLICK_TIMER);
2182 			bTimer = FALSE;
2183 		}
2184 		if (nClick < 2) {
2185 			mousePos[nClick] = lParam;
2186 		}
2187 		break;
2188 	case WM_LBUTTONUP:
2189 		nClick++;
2190 		if (bTimer == FALSE) {
2191 			checkClickWindowPosition(nClick, hWnd, mousePos);
2192 		}
2193 		break;
2194 	case WM_TIMER:
2195 		KillTimer(hWnd, CLICK_TIMER);
2196 		bTimer = FALSE;
2197 		if (nClick != 0) {
2198 			checkClickWindowPosition(1, hWnd, mousePos);
2199 		}
2200 		break;
2201 	case WM_NOTIFY:
2202 		notifyToolbar((LPTOOLTIPTEXT)lParam);
2203 		break;
2204 	case WM_SIZE:
2205 		SendMessage(hwndToolbar, WM_SIZE, wParam, lParam);
2206 		break;
2207 	case WM_PAINT:
2208 		drawScreen(hWnd);
2209 		break;
2210 	case WM_DESTROY:
2211 		if (hImgList != NULL) {
2212 			ImageList_Destroy(hImgList);
2213 		}
2214 		WinHelp(hWnd, szHelpFile, HELP_QUIT, 0L);
2215 		externalFileEditCleanup();
2216 		if (hwndMsg != NULL) {
2217 			DestroyWindow(hwndMsg);
2218 		}
2219 		PostQuitMessage(0);
2220 		break;
2221 	case WM_QUERYENDSESSION:
2222 		if (hwndMsg != NULL) {
2223 			DestroyWindow(hwndMsg);
2224 		}
2225 		DestroyWindow(hWnd);
2226 		return (TRUE);
2227 	default:
2228 		return (DefWindowProc(hWnd, iMessage, wParam, lParam));
2229 	}
2230 
2231 	return (0);
2232 }
2233 
2234 static
setupResource(void)2235 void setupResource(void)
2236 {
2237 	DWORD	dwSize;
2238 	DWORD	dwReserved;
2239 	LPVOID	lpBuffer;
2240 	LPVOID	lpStr;
2241 	UINT	uLen;
2242 	char	buf[MAX_PATH+1];
2243 	char	*p;
2244 
2245 	dwSize = GetFileVersionInfoSize(argv[0], &dwReserved);
2246 	if (dwSize != 0) {
2247 		lpBuffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwSize);
2248 		if (lpBuffer && GetFileVersionInfo(argv[0], dwReserved, dwSize, lpBuffer)) {
2249 #define VERPATH	"\\StringFileInfo\\041103A4\\"
2250 			VerQueryValue(lpBuffer, VERPATH "InternalName", &lpStr, &uLen);
2251 			szAppName = xstrdup(lpStr);
2252 			sprintf(buf, "%s Message", szAppName);
2253 			szAppNameMsg = xstrdup(buf);
2254 			sprintf(buf, "%s Mutex", szAppName);
2255 			szAppNameMutex = xstrdup(buf);
2256 			VerQueryValue(lpBuffer, VERPATH "ProductName", &lpStr, &uLen);
2257 			szAppNameLong = xstrdup(lpStr);
2258 			VerQueryValue(lpBuffer, VERPATH "LegalCopyright", &lpStr, &uLen);
2259 			szCopyright = xstrdup(lpStr);
2260 			VerQueryValue(lpBuffer, VERPATH "ProductVersion", &lpStr, &uLen);
2261 			szVersion = xstrdup(lpStr);
2262 			VerQueryValue(lpBuffer, VERPATH "Comments", &lpStr, &uLen);
2263 			szComment = xstrdup(lpStr);
2264 			VerQueryValue(lpBuffer, VERPATH "OriginalFilename", &lpStr, &uLen);
2265 			memset(buf, '\0', sizeof(buf));
2266 			strncpy(buf, lpStr, sizeof(buf) - 1);
2267 			p = strstr(buf, ".exe");
2268 			if (p != NULL) {
2269 				strcpy(p, ".HLP");
2270 				szHelpFile = xstrdup(buf);
2271 			}
2272 		}
2273 		if (lpBuffer) {
2274 			HeapFree(GetProcessHeap(), 0, lpBuffer);
2275 		}
2276 	}
2277 
2278 	if (LoadString(ghInstance, IDS_TODAYCLASS, buf, sizeof(buf) - 1) != 0) {
2279 		szTodayClass = xstrdup(buf);
2280 	}
2281 	if (LoadString(ghInstance, IDS_TODAYCMD, buf, sizeof(buf) - 1) != 0) {
2282 		szTodayCmd = xstrdup(buf);
2283 	}
2284 }
2285 
2286 static
copychar(char ** dst,char ** src)2287 void copychar(char **dst, char **src)
2288 {
2289 	if ((*src)[0] == '\\' && (*src)[1] == '"') {
2290 		**dst = '"';
2291 		*src += 2;
2292 	} else if (IsDBCSLeadByte((*src)[0]) && (*src)[1]) {
2293 		**dst = **src;
2294 		*src += 1;
2295 		*dst += 1;
2296 		**dst = **src;
2297 		*src += 1;
2298 	} else {
2299 		**dst = **src;
2300 		*src += 1;
2301 	}
2302 	*dst += 1;
2303 }
2304 
2305 #define is_space(x)	((x) == ' ' || (x) == '\t')
2306 
2307 static
setupArgParam(char * cmdline)2308 void setupArgParam(char *cmdline)
2309 {
2310 	char	szFullPath[MAX_PATH+1];
2311 	char	*arv[MAXARGS];
2312 	char	*bufp;
2313 	char	*src;
2314 	char	*dst;
2315 
2316 	GetModuleFileName(ghInstance, szFullPath, sizeof(szFullPath));
2317 	arv[0] = xstrdup(szFullPath);
2318 	argc = 1;
2319 
2320 	bufp = malloc(strlen(cmdline) + 1);
2321 	if (bufp == NULL) {
2322 		memerr("setupArgParam");
2323 	}
2324 
2325 	src = cmdline;
2326 	while (*src != '\0') {
2327 		while (is_space(*src)) {
2328 			src++;
2329 		}
2330 		if (*src == '\0') {
2331 			break;
2332 		}
2333 		dst = bufp;
2334 		while (is_space(*src) == 0 && *src != '\0') {
2335 			if (*src == '"') {
2336 				src++;
2337 				while (*src != '"' && *src != '\0') {
2338 					copychar(&dst, &src);
2339 				}
2340 				if (*src == '"') {
2341 					src++;
2342 				}
2343 			} else {
2344 				copychar(&dst, &src);
2345 			}
2346 		}
2347 		*dst = '\0';
2348 		if ((argc + 1) >= MAXARGS) {
2349 			break;
2350 		}
2351 		arv[argc++] = xstrdup(bufp);
2352 		if (*src == '\0') {
2353 			break;
2354 		}
2355 		src++;
2356 	}
2357 	arv[argc] = NULL;
2358 
2359 	free(bufp);
2360 
2361 	argv = malloc(sizeof(char *) * (argc + 1));
2362 	if (argv != NULL) {
2363 		memcpy(argv, arv, sizeof(char *) * (argc + 1));
2364 	} else {
2365 		memerr("setupArgParam");
2366 	}
2367 }
2368 
2369 static
initInstance(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine)2370 BOOL initInstance(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine)
2371 {
2372 	DWORD	rtc;
2373 	HWND	hwnd;
2374 
2375 	if (hPrevInstance) {
2376 		return (FALSE);
2377 	}
2378 
2379 	ghInstance = hInstance;
2380 
2381 	setupArgParam(lpCmdLine);
2382 	setupResource();
2383 
2384 	hMutex = CreateMutex(NULL, FALSE, szAppNameMutex);
2385 	if (hMutex == NULL) {
2386 		goto activewindow;
2387 	}
2388 	rtc = WaitForSingleObject(hMutex, 0);
2389 	if (rtc == WAIT_TIMEOUT || rtc == WAIT_FAILED) {
2390 		CloseHandle(hMutex);
2391 activewindow:
2392 		hwnd = FindWindow(szAppName, NULL);
2393 		if (hwnd != NULL) {
2394 			if (IsIconic(hwnd)) {
2395 				ShowWindow(hwnd, SW_RESTORE);
2396 			}
2397 			SetForegroundWindow(hwnd);
2398 		}
2399 		return (FALSE);
2400 	}
2401 
2402 	return (TRUE);
2403 }
2404 
2405 static
exitInstance(void)2406 void exitInstance(void)
2407 {
2408 	if (hMutex) {
2409 		CloseHandle(hMutex);
2410 	}
2411 }
2412 
WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd)2413 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
2414 {
2415 	WNDCLASS	wndclass;
2416 	HWND		hWnd;
2417 	HACCEL		hAccel;
2418 	MSG			msg;
2419 
2420 	if (initInstance(hInstance, hPrevInstance, lpCmdLine) == FALSE) {
2421 		return (0);
2422 	}
2423 
2424 	if (Configuration() == FALSE) {
2425 		msg.wParam = 0;
2426 		goto err_exit;
2427 	}
2428 
2429 	wndclass.style         = 0;
2430 	wndclass.lpfnWndProc   = (WNDPROC)WndProc;
2431 	wndclass.cbClsExtra    = 0;
2432 	wndclass.cbWndExtra    = 0;
2433 	wndclass.hInstance     = hInstance;
2434 	wndclass.hIcon         = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON1));
2435 	wndclass.hCursor       = LoadCursor(NULL, IDC_ARROW);
2436 	wndclass.hbrBackground = GetStockObject(WHITE_BRUSH);
2437 	wndclass.lpszMenuName  = szAppName;
2438 	wndclass.lpszClassName = szAppName;
2439 
2440 	if (!RegisterClass(&wndclass)) {
2441 		msg.wParam = 0;
2442 		goto err_exit;
2443 	}
2444 
2445 	hwndMain = hWnd = CreateWindowEx(0, szAppName, szAppNameLong,
2446 				WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_CLIPCHILDREN | WS_MINIMIZEBOX,
2447 				CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
2448 				NULL, NULL, hInstance, NULL);
2449 	if (hWnd == NULL) {
2450 		msg.wParam = 0;
2451 		goto err_exit;
2452 	}
2453 
2454 	ShowWindow(hWnd, nShowCmd);
2455 	UpdateWindow(hWnd);
2456 
2457 	hAccel = LoadAccelerators(hInstance, szAppName);
2458 
2459 	while (GetMessage(&msg, NULL, 0, 0)) {
2460 		if (!hAccel || !TranslateAccelerator(hWnd, hAccel, &msg)) {
2461 			TranslateMessage(&msg);
2462 			DispatchMessage(&msg);
2463 		}
2464 	}
2465 
2466 err_exit:
2467 	exitInstance();
2468 
2469 	return (msg.wParam);
2470 }
2471