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