OSDN Git Service

Change icon.ico. And fix icon bug, write ChangeLog.txt.
[ckw/ckw.git] / main.cpp
1 /*-----------------------------------------------------------------------------
2  * File: main.cpp
3  *-----------------------------------------------------------------------------
4  * Copyright (c) 2005       Kazuo Ishii <k-ishii@wb4.so-net.ne.jp>
5  *                              - original version
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
20  *---------------------------------------------------------------------------*/
21 #include "ckw.h"
22 #include "ime_wrap.h"
23 #include "rsrc.h"
24
25 /*****************************************************************************/
26
27 HANDLE  gStdIn = NULL;  /* console */
28 HANDLE  gStdOut = NULL;
29 HANDLE  gStdErr = NULL;
30 HWND    gConWnd = NULL;
31
32 HANDLE  gChild = NULL;  /* child process */
33
34 LOGFONT gFontLog;       /* font IME */
35 HFONT   gFont;          /* font */
36 DWORD   gFontW;         /* char width */
37 DWORD   gFontH;         /* char height */
38
39 DWORD   gWinW;          /* window columns */
40 DWORD   gWinH;          /* window rows */
41
42 RECT    gFrame;         /* window frame size */
43 HBITMAP gBgBmp = NULL;  /* background image */
44 HBRUSH  gBgBrush = NULL;/* background brush */
45 DWORD   gBorderSize = 0;/* internal border */
46 DWORD   gLineSpace = 0; /* line space */
47 BOOL    gVScrollHide = FALSE;
48
49 BOOL    gImeOn = FALSE; /* IME-status */
50
51 /* screen buffer - copy */
52 CONSOLE_SCREEN_BUFFER_INFO* gCSI = NULL;
53 CHAR_INFO*      gScreen = NULL;
54 wchar_t*        gTitle = NULL;
55
56 /* setConsoleFont */
57 #define MAX_FONTS 128
58
59 typedef struct _CONSOLE_FONT {
60   DWORD index;
61   COORD dim;
62 } CONSOLE_FONT, *PCONSOLE_FONT;
63
64 typedef BOOL  (WINAPI *GetConsoleFontInfoT)( HANDLE,BOOL,DWORD,PCONSOLE_FONT );
65 typedef DWORD (WINAPI *GetNumberOfConsoleFontsT)( VOID );
66 typedef BOOL  (WINAPI *SetConsoleFontT)( HANDLE, DWORD );
67
68 GetConsoleFontInfoT             GetConsoleFontInfo;
69 GetNumberOfConsoleFontsT        GetNumberOfConsoleFonts;
70 SetConsoleFontT                 SetConsoleFont;
71
72 /* index color */
73 enum {
74         kColor0 = 0,
75                   kColor1,  kColor2,  kColor3,
76         kColor4,  kColor5,  kColor6,  kColor7,
77         kColor8,  kColor9,  kColor10, kColor11,
78         kColor12, kColor13, kColor14, kColor15,
79         kColorCursorFg,
80         kColorCursorBg,
81         kColorCursorImeFg,
82         kColorCursorImeBg,
83         /**/
84         kColorMax,
85 };
86 COLORREF gColorTable[ kColorMax ];
87
88
89 /*****************************************************************************/
90
91 #if 0
92 #include <stdio.h>
93 void trace(const char *msg)
94 {
95         fputs(msg, stdout);
96         fflush(stdout);
97 }
98 #else
99 #define trace(msg)
100 #endif
101
102 /*****************************************************************************/
103
104 BOOL WINAPI ReadConsoleOutput_Unicode(HANDLE con, CHAR_INFO* buffer,
105                                       COORD size, COORD pos, SMALL_RECT *sr)
106 {
107         if(!ReadConsoleOutputA(con, buffer, size, pos, sr))
108                 return(FALSE);
109
110         CHAR_INFO* s = buffer;
111         CHAR_INFO* e = buffer + (size.X * size.Y);
112         DWORD   codepage = GetConsoleOutputCP();
113         BYTE    ch[2];
114         WCHAR   wch;
115
116         while(s < e) {
117                 ch[0] = s->Char.AsciiChar;
118
119                 if(s->Attributes & COMMON_LVB_LEADING_BYTE) {
120                         if((s+1) < e && ((s+1)->Attributes & COMMON_LVB_TRAILING_BYTE)) {
121                                 ch[1] = (s+1)->Char.AsciiChar;
122                                 if(MultiByteToWideChar(codepage, 0, (LPCSTR)ch, 2, &wch, 1)) {
123                                         s->Char.UnicodeChar = wch;
124                                         s++;
125                                         s->Char.UnicodeChar = wch;
126                                         s++;
127                                         continue;
128                                 }
129                         }
130                 }
131
132                 if(MultiByteToWideChar(codepage, 0, (LPCSTR)ch, 1, &wch, 1)) {
133                         s->Char.UnicodeChar = wch;
134                 }
135                 s->Attributes &= ~(COMMON_LVB_LEADING_BYTE | COMMON_LVB_TRAILING_BYTE);
136                 s++;
137         }
138         return(TRUE);
139 }
140
141 /*****************************************************************************/
142
143 /*----------*/
144 inline void __draw_invert_char_rect(HDC hDC, RECT& rc)
145 {
146         rc.right++;
147         rc.bottom++;
148         rc.left   *= gFontW;
149         rc.right  *= gFontW;
150         rc.top    *= gFontH;
151         rc.bottom *= gFontH;
152         BitBlt(hDC, rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top, NULL,0,0, DSTINVERT);
153 }
154
155 /*----------*/
156 static void __draw_selection(HDC hDC)
157 {
158         SMALL_RECT sel;
159         if(!selectionGetArea(sel))
160                 return;
161
162         if(gCSI->srWindow.Top <= sel.Top && sel.Top <= gCSI->srWindow.Bottom)
163                 ;
164         else if(gCSI->srWindow.Top <= sel.Bottom && sel.Bottom <= gCSI->srWindow.Bottom)
165                 ;
166         else if(sel.Top < gCSI->srWindow.Top && gCSI->srWindow.Bottom < sel.Bottom)
167                 ;
168         else
169                 return;
170
171         RECT    rc;
172
173         if(sel.Top == sel.Bottom) {
174                 /* single line */
175                 rc.left  = sel.Left - gCSI->srWindow.Left;
176                 rc.right = sel.Right-1 - gCSI->srWindow.Left;
177                 rc.top   = \
178                 rc.bottom = sel.Top - gCSI->srWindow.Top;
179                 __draw_invert_char_rect(hDC, rc);
180                 return;
181         }
182
183         /* multi line */
184         if(gCSI->srWindow.Top <= sel.Top && sel.Top <= gCSI->srWindow.Bottom) {
185                 /* top */
186                 rc.left = sel.Left - gCSI->srWindow.Left;
187                 rc.right = gCSI->srWindow.Right - gCSI->srWindow.Left;
188                 rc.top = \
189                 rc.bottom = sel.Top - gCSI->srWindow.Top;
190                 __draw_invert_char_rect(hDC, rc);
191         }
192         if(sel.Top+1 <= sel.Bottom-1) {
193                 /* center */
194                 rc.left = 0;
195                 rc.right = gCSI->srWindow.Right - gCSI->srWindow.Left;
196
197                 if(gCSI->srWindow.Top <= sel.Top+1)
198                         rc.top = sel.Top+1 - gCSI->srWindow.Top;
199                 else
200                         rc.top = 0;
201
202                 if(gCSI->srWindow.Bottom >= sel.Bottom-1)
203                         rc.bottom = sel.Bottom-1 - gCSI->srWindow.Top;
204                 else
205                         rc.bottom = gCSI->srWindow.Bottom - gCSI->srWindow.Top;
206                 __draw_invert_char_rect(hDC, rc);
207         }
208         if(gCSI->srWindow.Top <= sel.Bottom && sel.Bottom <= gCSI->srWindow.Bottom) {
209                 /* bottom */
210                 rc.left = 0;
211                 rc.right = sel.Right-1 - gCSI->srWindow.Left;
212                 rc.top = \
213                 rc.bottom = sel.Bottom - gCSI->srWindow.Top;
214                 __draw_invert_char_rect(hDC, rc);
215         }
216 }
217
218 /*----------*/
219 static void __draw_screen(HDC hDC)
220 {
221         int     pntX, pntY;
222         int     x, y;
223         int     color_fg;
224         int     color_bg;
225         CHAR_INFO* ptr = gScreen;
226         int      work_color_fg = -1;
227         int      work_color_bg = -1;
228         wchar_t* work_text = new wchar_t[ CSI_WndCols(gCSI) ];
229         wchar_t* work_text_ptr;
230         INT*     work_width = new INT[ CSI_WndCols(gCSI) ];
231         INT*     work_width_ptr;
232         int      work_pntX;
233
234         pntY = 0;
235         for(y = gCSI->srWindow.Top ; y <= gCSI->srWindow.Bottom ; y++) {
236                 pntX = 0;
237                 work_pntX = 0;
238                 work_text_ptr = work_text;
239                 work_width_ptr = work_width;
240                 for(x = gCSI->srWindow.Left ; x <= gCSI->srWindow.Right ; x++) {
241
242                         if(ptr->Attributes & COMMON_LVB_TRAILING_BYTE) {
243                                 pntX += gFontW;
244                                 ptr++;
245                                 continue;
246                         }
247
248                         color_fg = ptr->Attributes & 0xF;
249                         color_bg = (ptr->Attributes>>4) & 0xF;
250
251                         if(color_fg != work_color_fg ||
252                            color_bg != work_color_bg) {
253                                 if(work_text_ptr > work_text) {
254                                         ExtTextOut(hDC, work_pntX, pntY, 0, NULL,
255                                                    (LPCWSTR)work_text,
256                                                    (UINT)(work_text_ptr - work_text),
257                                                    work_width);
258                                 }
259                                 work_text_ptr = work_text;
260                                 work_width_ptr = work_width;
261                                 work_pntX = pntX;
262                                 work_color_fg = color_fg;
263                                 work_color_bg = color_bg;
264                                 SetTextColor(hDC, gColorTable[work_color_fg]);
265                                 SetBkColor(  hDC, gColorTable[work_color_bg]);
266                                 SetBkMode(hDC, (work_color_bg) ? OPAQUE : TRANSPARENT);
267                         }
268
269                         if(ptr->Attributes & COMMON_LVB_LEADING_BYTE) {
270                                 *work_text_ptr++ = ptr->Char.UnicodeChar;
271                                 *work_width_ptr++ = gFontW * 2;
272                         }
273                         else {
274                                 *work_text_ptr++ = ptr->Char.UnicodeChar;
275                                 *work_width_ptr++ = gFontW;
276                         }
277                         pntX += gFontW;
278                         ptr++;
279                 }
280
281                 if(work_text_ptr > work_text) {
282                         ExtTextOut(hDC, work_pntX, pntY, 0, NULL,
283                                    (LPCWSTR)work_text,
284                                    (UINT)(work_text_ptr - work_text),
285                                    work_width);
286                 }
287
288                 pntY += gFontH;
289         }
290
291         /* draw selection */
292         __draw_selection(hDC);
293
294         /* draw cursor */
295         if(gCSI->srWindow.Top    <= gCSI->dwCursorPosition.Y &&
296            gCSI->srWindow.Bottom >= gCSI->dwCursorPosition.Y &&
297            gCSI->srWindow.Left   <= gCSI->dwCursorPosition.X &&
298            gCSI->srWindow.Right  >= gCSI->dwCursorPosition.X) {
299                 color_fg = (gImeOn) ? kColorCursorImeFg : kColorCursorFg;
300                 color_bg = (gImeOn) ? kColorCursorImeBg : kColorCursorBg;
301                 SetTextColor(hDC, gColorTable[ color_fg ]);
302                 SetBkColor(  hDC, gColorTable[ color_bg ]);
303                 SetBkMode(hDC, OPAQUE);
304                 pntX = gCSI->dwCursorPosition.X - gCSI->srWindow.Left;
305                 pntY = gCSI->dwCursorPosition.Y - gCSI->srWindow.Top;
306                 ptr = gScreen + CSI_WndCols(gCSI) * pntY + pntX;
307                 pntX *= gFontW;
308                 pntY *= gFontH;
309                 *work_width = (ptr->Attributes & COMMON_LVB_LEADING_BYTE) ? gFontW*2 : gFontW;
310                 ExtTextOut(hDC, pntX, pntY, 0, NULL,
311                            &ptr->Char.UnicodeChar, 1, work_width);
312         }
313
314         delete [] work_width;
315         delete [] work_text;
316 }
317
318 /*----------*/
319 void    onPaint(HWND hWnd)
320 {
321         PAINTSTRUCT ps;
322         HDC     hDC = BeginPaint(hWnd, &ps);
323         RECT    rc;
324         GetClientRect(hWnd, &rc);
325
326         HDC     hMemDC = CreateCompatibleDC(hDC);
327         HBITMAP hBmp = CreateCompatibleBitmap(hDC, rc.right-rc.left, rc.bottom-rc.top);
328         HGDIOBJ oldfont = SelectObject(hMemDC, gFont);
329         HGDIOBJ oldbmp  = SelectObject(hMemDC, hBmp);
330
331         FillRect(hMemDC, &rc, gBgBrush);
332
333         if(gScreen && gCSI) {
334                 SetWindowOrgEx(hMemDC, -(int)gBorderSize, -(int)gBorderSize, NULL);
335                 __draw_screen(hMemDC);
336                 SetWindowOrgEx(hMemDC, 0, 0, NULL);
337         }
338
339         BitBlt(hDC,rc.left,rc.top, rc.right-rc.left, rc.bottom-rc.top, hMemDC,0,0, SRCCOPY);
340
341         SelectObject(hMemDC, oldfont);
342         SelectObject(hMemDC, oldbmp);
343         DeleteObject(hBmp);
344         DeleteDC(hMemDC);
345
346         EndPaint(hWnd, &ps);
347 }
348
349 /*----------*/
350 static void __set_console_window_size(LONG cols, LONG rows)
351 {
352         CONSOLE_SCREEN_BUFFER_INFO csi;
353         GetConsoleScreenBufferInfo(gStdOut, &csi);
354
355         gWinW = cols;
356         gWinH = rows;
357
358         if(cols == CSI_WndCols(&csi) && rows == CSI_WndRows(&csi))
359                 return;
360
361         //SMALL_RECT tmp = { 0,0,0,0 };
362         //SetConsoleWindowInfo(gStdOut, TRUE, &tmp);
363
364         csi.dwSize.X = (SHORT)cols;
365         csi.srWindow.Left = 0;
366         csi.srWindow.Right = (SHORT)(cols -1);
367
368         if(csi.dwSize.Y < rows || csi.dwSize.Y == CSI_WndRows(&csi))
369                 csi.dwSize.Y = (SHORT)rows;
370
371         csi.srWindow.Bottom += (SHORT)(rows - CSI_WndRows(&csi));
372         if(csi.dwSize.Y <= csi.srWindow.Bottom) {
373                 csi.srWindow.Top -= csi.srWindow.Bottom - csi.dwSize.Y +1;
374                 csi.srWindow.Bottom = csi.dwSize.Y -1;
375         }
376
377         SetConsoleScreenBufferSize(gStdOut, csi.dwSize);
378         SetConsoleWindowInfo(gStdOut, TRUE, &csi.srWindow);
379 }
380
381 /*----------*/
382 void    onSizing(HWND hWnd, DWORD side, LPRECT rc)
383 {
384         trace("onSizing\n");
385         LONG fw = (gFrame.right - gFrame.left) + (gBorderSize * 2);
386         LONG fh = (gFrame.bottom - gFrame.top) + (gBorderSize * 2);
387         LONG width  = rc->right - rc->left;
388         LONG height = rc->bottom - rc->top;
389
390         width  -= fw;
391         width  -= width  % gFontW;
392         width  += fw;
393
394         height -= fh;
395         height -= height % gFontH;
396         height += fh;
397
398         if(side==WMSZ_LEFT || side==WMSZ_TOPLEFT || side==WMSZ_BOTTOMLEFT)
399                 rc->left = rc->right - width;
400         else
401                 rc->right = rc->left + width;
402
403         if(side==WMSZ_TOP || side==WMSZ_TOPLEFT || side==WMSZ_TOPRIGHT)
404                 rc->top = rc->bottom - height;
405         else
406                 rc->bottom = rc->top + height;
407 }
408
409 /*----------*/
410 void    onWindowPosChange(HWND hWnd, WINDOWPOS* wndpos)
411 {
412         trace("onWindowPosChange\n");
413         if(!(wndpos->flags & SWP_NOSIZE) && !IsIconic(hWnd)) {
414                 LONG fw = (gFrame.right - gFrame.left) + (gBorderSize * 2);
415                 LONG fh = (gFrame.bottom - gFrame.top) + (gBorderSize * 2);
416                 LONG width  = wndpos->cx;
417                 LONG height = wndpos->cy;
418                 width  = (width - fw) / gFontW;
419                 height = (height - fh) / gFontH;
420
421                 __set_console_window_size(width, height);
422
423                 wndpos->cx = width  * gFontW + fw;
424                 wndpos->cy = height * gFontH + fh;
425         }
426 }
427
428 static void __set_ime_position(HWND hWnd)
429 {
430         if(!gImeOn || !gCSI) return;
431         HIMC imc = ImmGetContext(hWnd);
432         LONG px = gCSI->dwCursorPosition.X - gCSI->srWindow.Left;
433         LONG py = gCSI->dwCursorPosition.Y - gCSI->srWindow.Top;
434         COMPOSITIONFORM cf;
435         cf.dwStyle = CFS_POINT;
436         cf.ptCurrentPos.x = px * gFontW + gBorderSize;
437         cf.ptCurrentPos.y = py * gFontH + gBorderSize;
438         ImmSetCompositionWindow(imc, &cf);
439         ImmReleaseContext(hWnd, imc);
440 }
441
442 /*----------*/
443 void    onTimer(HWND hWnd)
444 {
445         if(WaitForSingleObject(gChild, 0) != WAIT_TIMEOUT) {
446                 PostMessage(hWnd, WM_CLOSE, 0,0);
447                 return;
448         }
449
450         /* refresh handle */
451         if(gStdOut) CloseHandle(gStdOut);
452         gStdOut = CreateFile(L"CONOUT$", GENERIC_READ|GENERIC_WRITE,
453                              FILE_SHARE_READ|FILE_SHARE_WRITE,
454                              NULL, OPEN_EXISTING, 0, NULL);
455
456         /* title update */
457         static int timer_count = 0;
458         if((++timer_count & 0xF) == 1) {
459                 wchar_t *str = new wchar_t[256];
460                 GetConsoleTitle(str, 256);
461                 if(gTitle && !wcscmp(gTitle, str)) {
462                         delete [] str;
463                 }
464                 else {
465                         delete [] gTitle;
466                         gTitle = str;
467                         SetWindowText(hWnd, gTitle);
468                 }
469         }
470
471         CONSOLE_SCREEN_BUFFER_INFO* csi = new CONSOLE_SCREEN_BUFFER_INFO;
472         COORD   size;
473
474         GetConsoleScreenBufferInfo(gStdOut, csi);
475         size.X = CSI_WndCols(csi);
476         size.Y = CSI_WndRows(csi);
477
478         /* copy screen buffer */
479         DWORD      nb = size.X * size.Y;
480         CHAR_INFO* buffer = new CHAR_INFO[nb];
481         CHAR_INFO* ptr = buffer;
482         SMALL_RECT sr;
483         COORD      pos = { 0, 0 };
484
485         /* ReadConsoleOuput - maximum read size 64kByte?? */
486         size.Y = 0x8000 / sizeof(CHAR_INFO) / size.X;
487         sr.Left  = csi->srWindow.Left;
488         sr.Right = csi->srWindow.Right;
489         sr.Top   = csi->srWindow.Top;
490         do {
491                 sr.Bottom = sr.Top + size.Y -1;
492                 if(sr.Bottom > csi->srWindow.Bottom) {
493                         sr.Bottom = csi->srWindow.Bottom;
494                         size.Y = sr.Bottom - sr.Top +1;
495                 }
496                 ReadConsoleOutput_Unicode(gStdOut, ptr, size, pos, &sr);
497                 ptr += size.X * size.Y;
498                 sr.Top = sr.Bottom +1;
499         } while(sr.Top <= csi->srWindow.Bottom);
500
501         /* compare */
502         if(gScreen && gCSI &&
503            !memcmp(csi, gCSI, sizeof(CONSOLE_SCREEN_BUFFER_INFO)) &&
504            !memcmp(buffer, gScreen, sizeof(CHAR_INFO) * nb)) {
505                 /* no modified */
506                 delete [] buffer;
507                 delete csi;
508                 return;
509         }
510
511         /* swap buffer */
512         if(gScreen) delete [] gScreen;
513         if(gCSI) delete gCSI;
514         gScreen = buffer;
515         gCSI = csi;
516
517         /* redraw request */
518         InvalidateRect(hWnd, NULL, TRUE);
519
520         /* set vertical scrollbar status */
521         if(!gVScrollHide) {
522                 SCROLLINFO si;
523                 si.cbSize = sizeof(si);
524                 si.fMask = SIF_DISABLENOSCROLL | SIF_POS | SIF_PAGE | SIF_RANGE;
525                 si.nPos = gCSI->srWindow.Top;
526                 si.nPage = CSI_WndRows(gCSI);
527                 si.nMin = 0;
528                 si.nMax = gCSI->dwSize.Y-1;
529                 SetScrollInfo(hWnd, SB_VERT, &si, TRUE);
530         }
531
532         if(gImeOn) {
533                 __set_ime_position(hWnd);
534         }
535
536         int w = CSI_WndCols(gCSI);
537         int h = CSI_WndRows(gCSI);
538         if(gWinW != w || gWinH != h) {
539                 w = (w * gFontW) + (gBorderSize * 2) + (gFrame.right - gFrame.left);
540                 h = (h * gFontH) + (gBorderSize * 2) + (gFrame.bottom - gFrame.top);
541                 SetWindowPos(hWnd, NULL, 0,0,w,h, SWP_NOMOVE|SWP_NOZORDER);
542         }
543 }
544
545 /*****************************************************************************/
546
547 LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
548 {
549         switch(msg) {
550         case WM_CREATE:
551                 {
552                         HIMC imc = ImmGetContext(hWnd);
553                         ImmSetCompositionFontW(imc, &gFontLog);
554                         ImmReleaseContext(hWnd, imc);
555                 }
556                 SetTimer(hWnd, 0x3571, 10, NULL);
557                 break;
558         case WM_DESTROY:
559                 KillTimer(hWnd, 0x3571);
560                 PostQuitMessage(0);
561                 if(WaitForSingleObject(gChild, 0) == WAIT_TIMEOUT)
562                         TerminateProcess(gChild, 0);
563                 break;
564         case WM_TIMER:
565                 onTimer(hWnd);
566                 break;
567
568         case WM_ERASEBKGND:
569                 break;
570         case WM_PAINT:
571                 onPaint(hWnd);
572                 break;
573
574         case WM_SIZING:
575                 onSizing(hWnd, (DWORD)wp, (LPRECT)lp);
576                 break;
577         case WM_WINDOWPOSCHANGING:
578         case WM_WINDOWPOSCHANGED:
579                 onWindowPosChange(hWnd, (WINDOWPOS*)lp);
580                 selectionClear(hWnd);
581                 break;
582         case WM_LBUTTONDOWN:
583                 onLBtnDown(hWnd, (short)LOWORD(lp), (short)HIWORD(lp));
584                 break;
585         case WM_LBUTTONUP:
586                 onLBtnUp(hWnd, (short)LOWORD(lp), (short)HIWORD(lp));
587                 break;
588         case WM_MOUSEMOVE:
589                 onMouseMove(hWnd, (short)LOWORD(lp),(short)HIWORD(lp));
590                 // scroll when mouse is outside (craftware)
591                 {
592                         short x = (short)LOWORD(lp);
593                         short y = (short)HIWORD(lp);
594
595                         RECT rc;
596                         GetClientRect(hWnd, &rc);
597
598                         if( y<0 ) {
599                                 PostMessage(gConWnd, WM_MOUSEWHEEL, WHEEL_DELTA<<16, y<<16|x );
600                         }
601                         else if(y>=rc.bottom) {
602                                 PostMessage(gConWnd, WM_MOUSEWHEEL, -WHEEL_DELTA<<16, y<<16|x );
603                         }
604                 }
605                 break;
606         case WM_MBUTTONDOWN:
607         case WM_RBUTTONDOWN:
608                 onPasteFromClipboard(hWnd);
609                 break;
610         case WM_DROPFILES:
611                 onDropFile((HDROP)wp);
612                 break;
613
614         case WM_IME_STARTCOMPOSITION:
615                 __set_ime_position(hWnd);
616                 return( DefWindowProc(hWnd, msg, wp, lp) );
617         case WM_IME_NOTIFY:
618                 if(wp == IMN_SETOPENSTATUS) {
619                         HIMC imc = ImmGetContext(hWnd);
620                         gImeOn = ImmGetOpenStatus(imc);
621                         ImmReleaseContext(hWnd, imc);
622                         InvalidateRect(hWnd, NULL, TRUE);
623                 }
624                 return( DefWindowProc(hWnd, msg, wp, lp) );
625
626         case WM_SYSCOMMAND:
627                 if(!onSysCommand(hWnd, (DWORD)wp))
628                         return( DefWindowProc(hWnd, msg, wp, lp) );
629                 break;
630         case WM_VSCROLL:
631         case WM_MOUSEWHEEL:
632                 /* throw console window */
633                 PostMessage(gConWnd, msg, wp, lp);
634                 break;
635
636         case WM_IME_CHAR:
637                 PostMessage(gConWnd, msg, wp, lp);
638                 /* break */
639         case WM_CHAR:
640                 selectionClear(hWnd);
641                 break;
642
643         case WM_SYSKEYDOWN:
644         case WM_SYSKEYUP:
645                 if(wp != VK_RETURN) /* alt+enter */
646                         PostMessage(gConWnd, msg, wp, lp);
647                 break;
648         case WM_KEYDOWN:
649         case WM_KEYUP:
650                 if((wp == VK_NEXT || wp == VK_PRIOR ||
651                     wp == VK_HOME || wp == VK_END) &&
652                    (GetKeyState(VK_SHIFT) & 0x8000)) {
653                         if(msg == WM_KEYDOWN) {
654                                 WPARAM  sb = SB_PAGEDOWN;
655                                 if(wp == VK_PRIOR)     sb = SB_PAGEUP;
656                                 else if(wp == VK_HOME) sb = SB_TOP;
657                                 else if(wp == VK_END)  sb = SB_BOTTOM;
658                                 PostMessage(gConWnd, WM_VSCROLL, sb, 0);
659                         }
660                 }
661                 else if(wp == VK_INSERT &&
662                         (GetKeyState(VK_SHIFT) & 0x8000)) {
663                         if(msg == WM_KEYDOWN)
664                                 onPasteFromClipboard(hWnd);
665                 }
666                 else {
667                         PostMessage(gConWnd, msg, wp, lp);
668                 }
669                 break;
670         default:
671                 return( DefWindowProc(hWnd, msg, wp, lp) );
672         }
673         return(1);
674 }
675
676 /*****************************************************************************/
677 #include "option.h"
678
679 /*----------*/
680 static BOOL create_window(ckOpt& opt)
681 {
682         trace("create_window\n");
683
684         HINSTANCE hInstance = GetModuleHandle(NULL);
685         LPWSTR  className = L"CkwWindowClass";
686         const char*     conf_title;
687         LPWSTR  title;
688         WNDCLASSEX wc;
689         DWORD   style = WS_OVERLAPPEDWINDOW;
690         DWORD   exstyle = WS_EX_ACCEPTFILES;
691         LONG    width, height;
692         LONG    posx, posy;
693
694         if(opt.isTranspColor() ||
695            (0 < opt.getTransp() && opt.getTransp() < 255))
696                 exstyle |= WS_EX_LAYERED;
697
698         if(opt.isScrollRight())
699                 exstyle |= WS_EX_RIGHTSCROLLBAR;
700         else
701                 exstyle |= WS_EX_LEFTSCROLLBAR;
702
703         if(opt.isTopMost())
704                 exstyle |= WS_EX_TOPMOST;
705
706         if(opt.isScrollHide() || opt.getSaveLines() < 1)
707                 gVScrollHide = TRUE;
708         else
709                 style |= WS_VSCROLL;
710
711         if(opt.isIconic())
712                 style |= WS_MINIMIZE;
713
714         conf_title = opt.getTitle();
715         if(!conf_title || !conf_title[0]){
716           title = L"ckw";
717         }else{
718           title = new wchar_t[ strlen(conf_title)+1 ];
719           ZeroMemory(title, sizeof(wchar_t) * (strlen(conf_title)+1));
720           MultiByteToWideChar(CP_ACP, 0, conf_title, (int)strlen(conf_title), title, (int)(sizeof(wchar_t) * (strlen(conf_title)+1)) );
721         }
722
723         /* calc window size */
724         CONSOLE_SCREEN_BUFFER_INFO csi;
725         GetConsoleScreenBufferInfo(gStdOut, &csi);
726
727         AdjustWindowRectEx(&gFrame, style, FALSE, exstyle);
728         if(!gVScrollHide)
729                 gFrame.right += GetSystemMetrics(SM_CXVSCROLL);
730
731         gWinW = width  = csi.srWindow.Right  - csi.srWindow.Left + 1;
732         gWinH = height = csi.srWindow.Bottom - csi.srWindow.Top  + 1;
733         width  *= gFontW;
734         height *= gFontH;
735         width  += gBorderSize * 2;
736         height += gBorderSize * 2;
737         width  += gFrame.right  - gFrame.left;
738         height += gFrame.bottom - gFrame.top;
739
740         if(opt.isWinPos()) {
741                 RECT    rc;
742                 SystemParametersInfo(SPI_GETWORKAREA,0,(LPVOID)&rc,0);
743                 posx = opt.getWinPosX();
744                 if(posx < 0) posx = rc.right - (width - posx -1);
745                 else         posx += rc.left;
746                 if(posx < rc.left) posx = rc.left;
747                 if(posx > rc.right-5) posx = rc.right -5;
748                 posy = opt.getWinPosY();
749                 if(posy < 0) posy = rc.bottom - (height - posy -1);
750                 else         posy += rc.top;
751                 if(posy < rc.top) posy = rc.top;
752                 if(posy > rc.bottom-5) posy = rc.bottom -5;
753         }
754         else {
755                 posx = CW_USEDEFAULT;
756                 posy = CW_USEDEFAULT;
757         }
758
759         /**/
760         memset(&wc, 0, sizeof(wc));
761         wc.cbSize = sizeof(wc);
762         wc.style = 0;
763         wc.lpfnWndProc = WndProc;
764         wc.cbClsExtra = 0;
765         wc.cbWndExtra = 0;
766         wc.hInstance = hInstance;
767         wc.hIcon = LoadIcon(hInstance, (LPCTSTR)IDR_ICON);
768         wc.hCursor = LoadCursor(NULL, IDC_ARROW);
769         wc.hbrBackground = CreateSolidBrush(gColorTable[0]);
770         wc.lpszMenuName = NULL;
771         wc.lpszClassName = className;
772         wc.hIconSm = NULL;
773         if(! RegisterClassEx(&wc))
774                 return(FALSE);
775
776         HWND hWnd = CreateWindowEx(exstyle, className, title, style,
777                                    posx, posy, width, height,
778                                    NULL, NULL, hInstance, NULL);
779         if(!hWnd){
780                 delete [] title;
781                 return(FALSE);
782         }
783
784         sysmenu_init(hWnd);
785
786         if(0 < opt.getTransp() && opt.getTransp() < 255)
787                 SetLayeredWindowAttributes(hWnd, 0, opt.getTransp(), LWA_ALPHA);
788         else if(opt.isTranspColor())
789                 SetLayeredWindowAttributes(hWnd, opt.getTranspColor(), 255, LWA_COLORKEY);
790
791         ShowWindow(hWnd, SW_SHOW);
792         return(TRUE);
793 }
794
795 /*----------*/
796 static BOOL create_child_process(const char* cmd, const char* curdir)
797 {
798         trace("create_child_process\n");
799
800         char* buf = NULL;
801
802         if(!cmd || !cmd[0]) {
803                 buf = new char[32768];
804                 buf[0] = 0;
805                 if(!GetEnvironmentVariableA("COMSPEC", buf, 32768))
806                         strcpy(buf, "cmd.exe");
807         }
808         else {
809                 buf = new char[ strlen(cmd)+1 ];
810                 strcpy(buf, cmd);
811         }
812
813         PROCESS_INFORMATION pi;
814         STARTUPINFOA si;
815         memset(&si, 0, sizeof(si));
816         si.cb = sizeof(si);
817         si.dwFlags = STARTF_USESTDHANDLES;
818         si.hStdInput  = gStdIn;
819         si.hStdOutput = gStdOut;
820         si.hStdError  = gStdErr;
821
822         if (curdir)
823                 if (char *p = strstr((char*)curdir, ":\""))
824                         *(p+1) = '\\';
825
826         if(! CreateProcessA(NULL, buf, NULL, NULL, TRUE,
827                             0, NULL, curdir, &si, &pi)) {
828                 delete [] buf;
829                 return(FALSE);
830         }
831         delete [] buf;
832         CloseHandle(pi.hThread);
833         gChild = pi.hProcess;
834         return(TRUE);
835 }
836
837 /*----------*/
838 static BOOL create_font(const char* name, int height)
839 {
840         trace("create_font\n");
841
842         memset(&gFontLog, 0, sizeof(gFontLog));
843         gFontLog.lfHeight = -height;
844         gFontLog.lfWidth = 0;
845         gFontLog.lfEscapement = 0;
846         gFontLog.lfOrientation = 0;
847         gFontLog.lfWeight = FW_NORMAL;
848         gFontLog.lfItalic = 0;
849         gFontLog.lfUnderline = 0;
850         gFontLog.lfStrikeOut = 0;
851         gFontLog.lfCharSet = DEFAULT_CHARSET;
852         gFontLog.lfOutPrecision = OUT_DEFAULT_PRECIS;
853         gFontLog.lfClipPrecision = CLIP_DEFAULT_PRECIS;
854         gFontLog.lfQuality = DEFAULT_QUALITY;
855         gFontLog.lfPitchAndFamily = FIXED_PITCH | FF_DONTCARE;
856         if(name) {
857                 MultiByteToWideChar(CP_ACP,0, name, -1, gFontLog.lfFaceName, LF_FACESIZE);
858         }
859
860         gFont = CreateFontIndirect(&gFontLog);
861
862         /* calc font size */
863         HDC     hDC = GetDC(NULL);
864         HGDIOBJ oldfont = SelectObject(hDC, gFont);
865         TEXTMETRIC met;
866         INT     width1[26], width2[26], width = 0;
867
868         GetTextMetrics(hDC, &met);
869         GetCharWidth32(hDC, 0x41, 0x5A, width1);
870         GetCharWidth32(hDC, 0x61, 0x7A, width2);
871         SelectObject(hDC, oldfont);
872         ReleaseDC(NULL, hDC);
873
874         for(int i = 0 ; i < 26 ; i++) {
875                 width += width1[i];
876                 width += width2[i];
877         }
878         width /= 26 * 2;
879         gFontW = width; /* met.tmAveCharWidth; */
880         gFontH = met.tmHeight + gLineSpace;
881
882         return(TRUE);
883 }
884
885 // for Windows SDK v7.0 \83G\83\89\81[\82ª\94­\90\82·\82é\8fê\8d\87\82Í\83R\83\81\83\93\83g\83A\83E\83g\81B
886 #ifdef _MSC_VER
887 #include <winternl.h>
888 #endif
889
890 /*----------*/
891 static void __hide_alloc_console()
892 {
893         bool bResult = false;
894
895         /*
896          * Open Console Window
897          * hack StartupInfo.wShowWindow flag
898          */
899
900 #ifdef _MSC_VER
901 #ifdef _WIN64
902         INT_PTR peb = *(INT_PTR*)((INT_PTR)NtCurrentTeb() + 0x60);
903         INT_PTR param = *(INT_PTR*) (peb + 0x20);
904         DWORD* pflags = (DWORD*) (param + 0xa4);
905         WORD* pshow = (WORD*) (param + 0xa8); 
906 #else
907 #ifndef _WINTERNL_
908         INT_PTR peb = *(INT_PTR*)((INT_PTR)NtCurrentTeb() + 0x30);
909         INT_PTR param = *(INT_PTR*) (peb + 0x10);
910 #else
911         // for Windows SDK v7.0
912         PPEB peb = *(PPEB*)((INT_PTR)NtCurrentTeb() + 0x30);
913         PRTL_USER_PROCESS_PARAMETERS param = peb->ProcessParameters;
914 #endif // _WINTERNL_
915
916         DWORD* pflags = (DWORD*)((INT_PTR)param + 0x68);
917         WORD* pshow = (WORD*)((INT_PTR)param + 0x6C);
918 #endif // _WIN64
919 #else
920         // for gcc
921         INT_PTR peb = *(INT_PTR*)((INT_PTR)NtCurrentTeb() + 0x30);
922     PRTL_USER_PROCESS_PARAMETERS param = *(PRTL_USER_PROCESS_PARAMETERS*)(peb + 0x10);
923         DWORD* pflags = (DWORD*)&(param->dwFlags);
924         WORD* pshow = (WORD*)&(param->wShowWindow); 
925 #endif // _MSC_VER
926
927         DWORD   backup_flags = *pflags;
928         WORD    backup_show  = *pshow;
929
930         STARTUPINFO si;
931         GetStartupInfo(&si);
932
933         /* check */
934         if(si.dwFlags == backup_flags && si.wShowWindow == backup_show) {
935                 // \8fÚ\8d×\82Í\95s\96¾\82¾\82ªSTARTF_TITLEISLINKNAME\82ª\97§\82Á\82Ä\82¢\82é\82Æ\81A
936                 // Console\91\8b\89B\82µ\82É\8e¸\94s\82·\82é\82Ì\82Å\8f\9c\8b\8e(Win7-64bit)
937                 if (*pflags & STARTF_TITLEISLINKNAME) {
938                         *pflags &= ~STARTF_TITLEISLINKNAME;
939                 }
940                 *pflags |= STARTF_USESHOWWINDOW;
941                 *pshow  = SW_HIDE;
942                 bResult = true;
943         }
944
945         AllocConsole();
946
947         /* restore */
948         *pflags = backup_flags;
949         *pshow  = backup_show;
950
951         while((gConWnd = GetConsoleWindow()) == NULL) {
952                 Sleep(10);
953         }
954
955         if (!bResult){
956                 while (!IsWindowVisible(gConWnd)) {
957                         Sleep(10);
958                 }
959                 while(IsWindowVisible(gConWnd)) {
960                         ShowWindow(gConWnd, SW_HIDE);
961                         Sleep(10);
962                 }
963         }
964 }
965
966 /*----------*/
967 BOOL WINAPI sig_handler(DWORD n)
968 {
969         return(TRUE);
970 }
971
972 static BOOL create_console(ckOpt& opt)
973 {
974         const char*     conf_title;
975         LPWSTR  title;
976
977         conf_title = opt.getTitle();
978         if(!conf_title || !conf_title[0]){
979                 title = L"ckw";
980         }else{
981                 title = new wchar_t[ strlen(conf_title)+1 ];
982                 ZeroMemory(title, sizeof(wchar_t) * (strlen(conf_title)+1));
983                 MultiByteToWideChar(CP_ACP, 0, conf_title, (int)strlen(conf_title), title, (int)(sizeof(wchar_t) * (strlen(conf_title)+1)) );
984         }
985
986         __hide_alloc_console();
987
988         SetConsoleTitle(title);
989
990         SetConsoleCtrlHandler(sig_handler, TRUE);
991
992         SECURITY_ATTRIBUTES sa;
993         sa.nLength = sizeof(sa);
994         sa.lpSecurityDescriptor = NULL;
995         sa.bInheritHandle = TRUE;
996
997         gStdIn  = CreateFile(L"CONIN$",  GENERIC_READ|GENERIC_WRITE,
998                              FILE_SHARE_READ|FILE_SHARE_WRITE,
999                              &sa, OPEN_EXISTING, 0, NULL);
1000         gStdOut = CreateFile(L"CONOUT$",  GENERIC_READ|GENERIC_WRITE,
1001                              FILE_SHARE_READ|FILE_SHARE_WRITE,
1002                              &sa, OPEN_EXISTING, 0, NULL);
1003         gStdErr = CreateFile(L"CONOUT$",  GENERIC_READ|GENERIC_WRITE,
1004                              FILE_SHARE_READ|FILE_SHARE_WRITE,
1005                              &sa, OPEN_EXISTING, 0, NULL);
1006
1007         if(!gConWnd || !gStdIn || !gStdOut || !gStdErr)
1008                 return(FALSE);
1009
1010         HINSTANCE hLib;
1011         hLib = LoadLibraryW( L"KERNEL32.DLL" );
1012         if (hLib == NULL)
1013                 goto done;
1014
1015         #define GetProc( proc ) \
1016         do { \
1017                 proc = (proc##T)GetProcAddress( hLib, #proc ); \
1018                 if (proc == NULL) \
1019                         goto freelib; \
1020         } while (0)
1021         GetProc( GetConsoleFontInfo );
1022         GetProc( GetNumberOfConsoleFonts );
1023         GetProc( SetConsoleFont );
1024         #undef GetProc
1025
1026         {
1027                 CONSOLE_FONT font[MAX_FONTS];
1028                 DWORD fonts;
1029                 fonts = GetNumberOfConsoleFonts();
1030                 if (fonts > MAX_FONTS)
1031                         fonts = MAX_FONTS;
1032         
1033                 GetConsoleFontInfo(gStdOut, 0, fonts, font);
1034                 CONSOLE_FONT minimalFont = { 0, {0, 0}};
1035                 for(DWORD i=0;i<fonts;i++){
1036                         if(minimalFont.dim.X < font[i].dim.X && minimalFont.dim.Y < font[i].dim.Y)
1037                                 minimalFont = font[i];
1038                 }
1039                 SetConsoleFont(gStdOut, minimalFont.index);
1040         }
1041         freelib:
1042                 FreeLibrary( hLib );
1043         done:
1044
1045         /* set buffer & window size */
1046         COORD size;
1047         SMALL_RECT sr = {0,0,0,0};
1048         SetConsoleWindowInfo(gStdOut, TRUE, &sr);
1049         size.X = opt.getWinCharW();
1050         size.Y = opt.getWinCharH() + opt.getSaveLines();
1051         SetConsoleScreenBufferSize(gStdOut, size);
1052         sr.Left = 0;
1053         sr.Right = opt.getWinCharW()-1;
1054         sr.Top = size.Y - opt.getWinCharH();
1055         sr.Bottom = size.Y-1;
1056         SetConsoleWindowInfo(gStdOut, TRUE, &sr);
1057         size.X = sr.Left;
1058         size.Y = sr.Top;
1059         SetConsoleCursorPosition(gStdOut, size);
1060         return(TRUE);
1061 }
1062
1063 /*----------*/
1064 BOOL init_options(ckOpt& opt)
1065 {
1066         /* create argv */
1067         int     i, argc;
1068         LPWSTR* wargv = CommandLineToArgvW(GetCommandLineW(), &argc);
1069         char**  argv = new char*[argc+1];
1070         argv[argc] = 0;
1071         for(i = 0 ; i < argc ; i++) {
1072                 DWORD wlen = (DWORD) wcslen(wargv[i]);
1073                 DWORD alen = wlen * 2 + 16;
1074                 argv[i] = new char[alen];
1075                 alen = WideCharToMultiByte(CP_ACP, 0, wargv[i],wlen, argv[i],alen,NULL,NULL);
1076                 argv[i][alen] = 0;
1077         }
1078
1079         opt.loadXdefaults();
1080         bool result = opt.set(argc, argv);
1081
1082         for(i = 0 ; i < argc ; i++)
1083                 delete [] argv[i];
1084         delete [] argv;
1085
1086         if(!result) return(FALSE);
1087
1088         /* set */
1089         for(i = kColor0 ; i <= kColor15 ; i++)
1090                 gColorTable[i] = opt.getColor(i);
1091         gColorTable[kColor7] = opt.getColorFg();
1092         gColorTable[kColor0] = opt.getColorBg();
1093
1094         gColorTable[kColorCursorBg] = opt.getColorCursor();
1095         gColorTable[kColorCursorFg] = ~gColorTable[kColorCursorBg] & 0xFFFFFF;
1096         gColorTable[kColorCursorImeBg] = opt.getColorCursorIme();
1097         gColorTable[kColorCursorImeFg] = ~gColorTable[kColorCursorImeBg] & 0xFFFFFF;
1098
1099         gBorderSize = opt.getBorderSize();
1100         gLineSpace = opt.getLineSpace();
1101
1102         if(opt.getBgBmp()) {
1103                 gBgBmp = (HBITMAP)LoadImageA(NULL, opt.getBgBmp(),
1104                                 IMAGE_BITMAP, 0,0, LR_LOADFROMFILE);
1105         }
1106         if(gBgBmp)    gBgBrush = CreatePatternBrush(gBgBmp);
1107         if(!gBgBrush) gBgBrush = CreateSolidBrush(gColorTable[0]);
1108
1109         return(TRUE);
1110 }
1111
1112 /*----------*/
1113 static BOOL initialize()
1114 {
1115         ckOpt opt;
1116
1117         if(! ime_wrap_init()) {
1118                 trace("ime_wrap_init failed\n");
1119         }
1120
1121         if(! init_options(opt)) {
1122                 return(FALSE);
1123         }
1124         if(! create_console(opt)) {
1125                 trace("create_console failed\n");
1126                 return(FALSE);
1127         }
1128         if(! create_font(opt.getFont(), opt.getFontSize())) {
1129                 trace("create_font failed\n");
1130                 return(FALSE);
1131         }
1132         if(! create_child_process(opt.getCmd(), opt.getCurDir())) {
1133                 trace("create_child_process failed\n");
1134                 return(FALSE);
1135         }
1136         if(! create_window(opt)) {
1137                 trace("create_window failed\n");
1138                 return(FALSE);
1139         }
1140
1141         /*
1142         wchar_t path[MAX_PATH+1];
1143         GetSystemDirectory(path, MAX_PATH);
1144         SetCurrentDirectory(path);
1145         */
1146         return(TRUE);
1147 }
1148
1149 #define SAFE_CloseHandle(handle) \
1150         if(handle) { CloseHandle(handle); handle = NULL; }
1151
1152 #define SAFE_DeleteObject(handle) \
1153         if(handle) { DeleteObject(handle); handle = NULL; }
1154
1155 /*----------*/
1156 static void _terminate()
1157 {
1158         if(gTitle) {
1159                 delete [] gTitle;
1160                 gTitle = NULL;
1161         }
1162         if(gScreen) {
1163                 delete [] gScreen;
1164                 gScreen = NULL;
1165         }
1166         if(gCSI) {
1167                 delete gCSI;
1168                 gCSI = NULL;
1169         }
1170         gConWnd = NULL;
1171         SAFE_CloseHandle(gStdIn);
1172         SAFE_CloseHandle(gStdOut);
1173         SAFE_CloseHandle(gStdErr);
1174         SAFE_CloseHandle(gChild);
1175         SAFE_DeleteObject(gFont);
1176         SAFE_DeleteObject(gBgBrush);
1177         SAFE_DeleteObject(gBgBmp);
1178         ime_wrap_term();
1179 }
1180
1181 #ifdef _DEBUG
1182 #include <crtdbg.h>
1183 #endif
1184
1185 /*----------*/
1186 int APIENTRY wWinMain(HINSTANCE hInst, HINSTANCE hPrev, LPWSTR lpCmdLine, int nCmdShow)
1187 {
1188 #ifdef _DEBUG
1189         char *a = new char[1];
1190         *a = 0x22;
1191         _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF |
1192                        _CRTDBG_LEAK_CHECK_DF |
1193                        /*_CRTDBG_CHECK_ALWAYS_DF |*/
1194                        _CRTDBG_DELAY_FREE_MEM_DF);
1195         _CrtSetReportMode( _CRT_ASSERT, _CRTDBG_MODE_FILE );
1196         _CrtSetReportMode( _CRT_WARN,   _CRTDBG_MODE_FILE );
1197         _CrtSetReportMode( _CRT_ERROR,  _CRTDBG_MODE_FILE );
1198         _CrtSetReportFile( _CRT_ASSERT, _CRTDBG_FILE_STDERR );
1199         _CrtSetReportFile( _CRT_WARN,   _CRTDBG_FILE_STDERR );
1200         _CrtSetReportFile( _CRT_ERROR,  _CRTDBG_FILE_STDERR );
1201 #endif
1202
1203         if(initialize()) {
1204                 MSG msg;
1205                 while(GetMessage(&msg, NULL, 0,0)) {
1206                         TranslateMessage(&msg);
1207                         DispatchMessage(&msg);
1208                 }
1209         }
1210         _terminate();
1211         return(0);
1212 }
1213
1214 /* \90V\8bK\83E\83C\83\93\83h\83E\82Ì\8dì\90¬ */
1215 void makeNewWindow()
1216 {
1217         LPWSTR cd = new TCHAR[MAX_PATH+1];
1218         GetCurrentDirectory(MAX_PATH, cd);
1219
1220         STARTUPINFO si;
1221         ZeroMemory(&si, sizeof(si));
1222         si.cb = sizeof(si);
1223
1224         PROCESS_INFORMATION pi;
1225         ZeroMemory(&pi, sizeof(pi));
1226         if(CreateProcess(NULL, GetCommandLine(), NULL, NULL, FALSE, 0,
1227                                            NULL, NULL, &si, &pi)){
1228                 // \8eg\97p\82µ\82È\82¢\82Ì\82Å\81C\82·\82®\82É\83N\83\8d\81[\83Y\82µ\82Ä\82æ\82¢
1229                 CloseHandle(pi.hProcess);
1230                 CloseHandle(pi.hThread);
1231         }
1232 }
1233
1234 /* EOF */