OSDN Git Service

Change icon.ico. And fix icon bug, write ChangeLog.txt.
[ckw/ckw.git] / misc.cpp
1 /*-----------------------------------------------------------------------------
2  * File: misc.cpp
3  *-----------------------------------------------------------------------------
4  * Copyright (c) 2004-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
22 #include <string>
23
24 #include "ckw.h"
25 #include "rsrc.h"
26 #include "option.h"
27
28 BOOL init_options(ckOpt& opt);
29
30 static void __write_console_input(LPCWSTR str, DWORD length)
31 {
32         if(!str || !length) return;
33
34         INPUT_RECORD *p, *buf;
35         DWORD   i = 0;
36         p = buf = new INPUT_RECORD[ length ];
37
38         for( ; i < length ; i++, p++) {
39                 p->EventType = KEY_EVENT;
40                 p->Event.KeyEvent.bKeyDown = TRUE;
41                 p->Event.KeyEvent.wRepeatCount = 1;
42                 p->Event.KeyEvent.wVirtualKeyCode = 0;
43                 p->Event.KeyEvent.wVirtualScanCode = 0;
44                 p->Event.KeyEvent.uChar.UnicodeChar = 0;
45                 p->Event.KeyEvent.dwControlKeyState = 0;
46                 if(*str == '\r') {
47                         str++;
48                         length--;
49                 }
50                 if(*str == '\n') {
51                         p->Event.KeyEvent.wVirtualKeyCode = VK_RETURN;
52                         str++;
53                 } else {
54                         p->Event.KeyEvent.uChar.UnicodeChar = *str++;
55                 }
56         }
57
58         WriteConsoleInput(gStdIn, buf, length, &length);
59         delete [] buf;
60 }
61
62 /*----------*/
63 void copyChar(wchar_t*& p, CHAR_INFO* src, SHORT start, SHORT end, bool ret)
64 {
65         CHAR_INFO* pend = src + end;
66         CHAR_INFO* test = src + start;
67         CHAR_INFO* last = test-1;
68
69         /* search last char */
70         for( ; test <= pend ; test++) {
71                 if(test->Char.UnicodeChar > 0x20)
72                         last = test;
73         }
74         /* copy */
75         for(test = src+start ; test <= last ; test++) {
76                 if(!(test->Attributes & COMMON_LVB_TRAILING_BYTE))
77                         *p++ = test->Char.UnicodeChar;
78         }
79         if(ret && last < pend) {
80                 *p++ = L'\r';
81                 *p++ = L'\n';
82         }
83         *p = 0;
84 }
85
86 /*----------*/
87 void    onPasteFromClipboard(HWND hWnd)
88 {
89         bool    result = true;
90         HANDLE  hMem;
91         wchar_t *ptr;
92
93         if(! IsClipboardFormatAvailable(CF_UNICODETEXT))
94                 return;
95         if(!OpenClipboard(hWnd)) {
96                 Sleep(10);
97                 if(!OpenClipboard(hWnd))
98                         return;
99         }
100         hMem = GetClipboardData(CF_UNICODETEXT);
101         if(!hMem)
102                 result = false;
103         if(result && !(ptr = (wchar_t*)GlobalLock(hMem)))
104                 result = false;
105         if(result) {
106                 __write_console_input(ptr, (DWORD)wcslen(ptr));
107                 GlobalUnlock(hMem);
108         }
109         CloseClipboard();
110 }
111
112 /*----------*/
113 /* (craftware) */
114 void copyStringToClipboard( HWND hWnd, const wchar_t * str )
115 {
116         size_t length = wcslen(str) +1;
117         HANDLE hMem;
118         wchar_t* ptr;
119         bool    result = true;
120
121         hMem = GlobalAlloc(GMEM_MOVEABLE, sizeof(wchar_t) * length);
122         if(!hMem) result = false;
123
124         if(result && !(ptr = (wchar_t*) GlobalLock(hMem))) {
125                 result = false;
126         }
127         if(result) {
128                 memcpy(ptr, str, sizeof(wchar_t) * length);
129                 GlobalUnlock(hMem);
130         }
131         if(result && !OpenClipboard(hWnd)) {
132                 Sleep(10);
133                 if(!OpenClipboard(hWnd))
134                         result = false;
135         }
136         if(result) {
137                 if(!EmptyClipboard() ||
138                    !SetClipboardData(CF_UNICODETEXT, hMem))
139                         result = false;
140                 CloseClipboard();
141         }
142         if(!result && hMem) {
143                 GlobalFree(hMem);
144         }
145 }
146
147 /*----------*/
148 /* (craftware) */
149 wchar_t * getAllString()
150 {
151         int nb;
152
153         nb = gCSI->dwSize.X * gCSI->dwSize.Y;
154
155         COORD      size = { gCSI->dwSize.X, 1 };
156         CHAR_INFO* work = new CHAR_INFO[ gCSI->dwSize.X ];
157         wchar_t*   buffer = new wchar_t[ nb ];
158         wchar_t*   wp = buffer;
159         COORD      pos = { 0,0 };
160         SMALL_RECT sr = { 0, 0, gCSI->dwSize.X-1, 0 };
161
162         *wp = 0;
163
164         for( int y=0 ; y<gCSI->dwSize.Y ; ++y )
165         {
166                 sr.Top = sr.Bottom = y;
167                 ReadConsoleOutput_Unicode(gStdOut, work, size, pos, &sr);
168                 copyChar( wp, work, 0, gCSI->dwSize.X-1 );
169         }
170
171         delete [] work;
172
173         return(buffer);
174 }
175
176 /*----------*/
177 /* (craftware) */
178 void copyAllStringToClipboard(HWND hWnd)
179 {
180         wchar_t* str = getAllString();
181         if(!str) return;
182         
183         std::wstring s = str;
184
185         // skip empty line
186         size_t begin = s.find_first_not_of(L"\r\n");
187         size_t end = s.find_last_not_of(L"\r\n");
188         if(begin!=s.npos && end!=s.npos)
189         {
190                 s = s.substr( begin, end+1-begin );
191         }
192
193         copyStringToClipboard( hWnd, s.c_str() );
194
195         delete [] str;
196 }
197
198 /*----------*/
199 void    onDropFile(HDROP hDrop)
200 {
201         DWORD   i, nb, len;
202         wchar_t wbuf[MAX_PATH+32];
203         wchar_t* wp;
204
205         nb = DragQueryFile(hDrop, (DWORD)-1, NULL, 0);
206         for(i = 0 ; i < nb ; i++) {
207                 len = DragQueryFile(hDrop, i, NULL, 0);
208                 if(len < 1 || len > MAX_PATH)
209                         continue;
210                 wp = wbuf + 1;
211                 if(! DragQueryFile(hDrop, i, wp, MAX_PATH))
212                         continue;
213                 wp[len] = 0;
214                 while(*wp > 0x20) wp++;
215                 if(*wp) {
216                         wp = wbuf;
217                         len++;
218                         wp[0] = wp[len++] = L'\"';
219                 }
220                 else {
221                         wp = wbuf + 1;
222                 }
223                 wp[len++] = L' ';
224
225                 __write_console_input(wp, len);
226         }
227         DragFinish(hDrop);
228 }
229
230 /*----------*/
231 INT_PTR CALLBACK AboutDlgProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
232 {
233         switch(msg) {
234         case WM_INITDIALOG:
235                 {
236                         HWND hEdit = GetDlgItem(hWnd, IDC_EDIT1);
237                         SetWindowText(hEdit,
238 L"This program is free software; you can redistribute it and/or\r\n"
239 L"modify it under the terms of the GNU General Public License\r\n"
240 L"as published by the Free Software Foundation; either version 2\r\n"
241 L"of the License, or (at your option) any later version.\r\n"
242 L"\r\n"
243 L"This program is distributed in the hope that it will be useful,\r\n"
244 L"but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n"
245 L"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\r\n"
246 L"See the GNU General Public License for more details.\r\n"
247 L"\r\n"
248 L"You should have received a copy of the GNU General Public License\r\n"
249 L"along with this program; if not, write to the Free Software Foundation, Inc.,\r\n"
250 L" 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA."
251                         );
252                 }
253                 return(TRUE);
254         case WM_COMMAND:
255                 switch(LOWORD(wp)) {
256                 case IDOK:
257                 case IDCANCEL:
258                         EndDialog(hWnd, 0);
259                         return(TRUE);
260                 }
261         }
262         return(FALSE);
263 }
264
265 /*----------*/
266 void    sysmenu_init_topmost(HWND hWnd, HMENU hMenu);
267 void    sysmenu_init_subconfig(HWND hWnd, HMENU hMenu);
268 void    changeStateTopMostMenu(HWND hWnd, HMENU hMenu);
269
270 void    sysmenu_init(HWND hWnd)
271 {
272         MENUITEMINFO mii;
273         HMENU hMenu = GetSystemMenu(hWnd, FALSE);
274
275         memset(&mii, 0, sizeof(mii));
276         mii.cbSize = sizeof(mii);
277         mii.fMask = MIIM_TYPE | MIIM_ID;
278
279         mii.fType = MFT_STRING;
280         mii.wID = IDM_COPYALL;
281         mii.dwTypeData = L"Copy All(&C)";
282         mii.cch = (UINT) wcslen(mii.dwTypeData);
283         InsertMenuItem(hMenu, SC_CLOSE, FALSE, &mii);
284
285         mii.fType = MFT_STRING;
286         mii.wID = IDM_NEW;
287         mii.dwTypeData = L"New (&N)";
288         mii.cch = (UINT) wcslen(mii.dwTypeData);
289         InsertMenuItem(hMenu, SC_CLOSE, FALSE, &mii);
290
291         sysmenu_init_topmost(hWnd, hMenu);
292
293     // sysmenu_init_subconfig(hWnd, hMenu);
294
295         mii.fType = MFT_SEPARATOR;
296         mii.wID = 0;
297         mii.dwTypeData = 0;
298         mii.cch = 0;
299         InsertMenuItem(hMenu, SC_CLOSE, FALSE, &mii);
300
301         mii.fType = MFT_STRING;
302         mii.wID = IDM_ABOUT;
303         mii.dwTypeData = L"About (&A)";
304         mii.cch = (UINT) wcslen(mii.dwTypeData);
305         InsertMenuItem(hMenu, SC_CLOSE, FALSE, &mii);
306
307         mii.fType = MFT_SEPARATOR;
308         mii.wID = 0;
309         mii.dwTypeData = 0;
310         mii.cch = 0;
311         InsertMenuItem(hMenu, SC_CLOSE, FALSE, &mii);
312 }
313
314 void    get_directory_path(wchar_t *path)
315 {
316         wchar_t *c;
317         GetModuleFileName(NULL, path, MAX_PATH);
318         c = wcsrchr(path, L'\\');
319         if(c) *c = 0;
320 }
321
322 void    sysmenu_init_topmost(HWND hWnd, HMENU hMenu)
323 {
324         MENUITEMINFO mii;
325
326         memset(&mii, 0, sizeof(mii));
327         mii.cbSize = sizeof(mii);
328         mii.fMask = MIIM_TYPE | MIIM_ID | MIIM_CHECKMARKS;
329
330         mii.fType = MFT_STRING;
331         mii.wID = IDM_TOPMOST;
332         mii.dwTypeData = L"TopMost (&T)";
333         mii.cch = (UINT) wcslen(mii.dwTypeData);
334
335         InsertMenuItem(hMenu, SC_CLOSE, FALSE, &mii);
336
337         changeStateTopMostMenu(hWnd,hMenu);
338 }
339
340 void    sysmenu_init_subconfig(HWND hWnd, HMENU hMenu)
341 {
342         MENUITEMINFO mii;
343     HMENU hSubMenu = CreatePopupMenu();
344
345         memset(&mii, 0, sizeof(mii));
346         mii.cbSize = sizeof(mii);
347         mii.fMask = MIIM_TYPE | MIIM_ID;
348
349         wchar_t path[MAX_PATH+1];
350     get_directory_path(path);
351     wcscat_s(path, L"\\*.cfg");
352
353     WIN32_FIND_DATA fd;
354         memset(&fd, 0, sizeof(fd));
355     HANDLE hFile = FindFirstFile(path, &fd);
356     //MessageBox(hWnd, path, L"", MB_OK);
357
358     if (hFile != INVALID_HANDLE_VALUE)
359     {
360         for(int i = 0;;i++)
361         {
362             mii.fType = MFT_STRING;
363             mii.wID = IDM_CONFIG_SELECT_1 + i;
364             mii.dwTypeData = fd.cFileName;
365             mii.cch = (UINT) wcslen(mii.dwTypeData);
366             InsertMenuItem(hSubMenu, 0, TRUE, &mii);
367             if(FindNextFile(hFile, &fd) == 0) { break; }
368         }
369         FindClose(hFile);
370     }
371
372         mii.fMask |= MIIM_SUBMENU;
373         mii.fType = MFT_STRING;
374         mii.wID = IDM_CONFIG_SELECT;
375         mii.hSubMenu = hSubMenu;
376         mii.dwTypeData = L"Config (&O)";
377         mii.cch = (UINT) wcslen(mii.dwTypeData);
378         InsertMenuItem(hMenu, SC_CLOSE, FALSE, &mii);
379 }
380
381 void reloadConfig(wchar_t *path)
382 {
383         char filepath[MAX_PATH+1];
384         wcstombs(filepath, path, MAX_PATH);
385
386         ckOpt opt;
387         opt.setFile(filepath);
388     init_options(opt);
389 }
390
391 BOOL    onConfigMenuCommand(HWND hWnd, DWORD id)
392 {
393         wchar_t path[MAX_PATH+1];
394     get_directory_path(path);
395
396         MENUITEMINFO mii;
397         memset(&mii, 0, sizeof(mii));
398         mii.cbSize = sizeof(mii);
399         mii.fMask = MIIM_TYPE | MIIM_ID;
400     mii.fType = MFT_STRING;
401
402         HMENU hMenu = GetSystemMenu(hWnd, FALSE);
403     if (GetMenuItemInfo(hMenu, id, 0, &mii))
404     {
405         wchar_t sz[MAX_PATH+1], filepath[MAX_PATH+1];
406         mii.dwTypeData = sz;
407         mii.cch++;
408         GetMenuItemInfo(hMenu, id, 0, &mii);
409         wsprintf(filepath, L"%s\\%s", path, sz);
410         /* need to open file and update config here */
411         MessageBox(hWnd, filepath, L"", MB_OK);
412                 reloadConfig(filepath);
413     }
414
415     return(TRUE);
416 }
417
418 BOOL    onTopMostMenuCommand(HWND hWnd)
419 {
420         HMENU hMenu = GetSystemMenu(hWnd, FALSE);
421
422         UINT uState = GetMenuState( hMenu, IDM_TOPMOST, MF_BYCOMMAND);
423         DWORD dwExStyle = GetWindowLong(hWnd,GWL_EXSTYLE);
424         if( uState & MFS_CHECKED )
425         {
426                 SetWindowPos(hWnd, HWND_NOTOPMOST,NULL,NULL,NULL,NULL,SWP_NOMOVE | SWP_NOSIZE); 
427         }else{
428                 SetWindowPos(hWnd, HWND_TOPMOST,NULL,NULL,NULL,NULL,SWP_NOMOVE | SWP_NOSIZE); 
429         }
430
431         changeStateTopMostMenu(hWnd, hMenu);
432
433         return(TRUE);
434 }
435
436 void    changeStateTopMostMenu(HWND hWnd,HMENU hMenu)
437 {
438         DWORD dwExStyle = GetWindowLong(hWnd,GWL_EXSTYLE);
439
440         if ((dwExStyle & WS_EX_TOPMOST) == 0) {
441                 CheckMenuItem(hMenu, IDM_TOPMOST, MF_BYCOMMAND | MFS_UNCHECKED);
442         } else {
443                 CheckMenuItem(hMenu, IDM_TOPMOST, MF_BYCOMMAND | MFS_CHECKED);
444         }
445 }
446
447 /*----------*/
448 BOOL    onSysCommand(HWND hWnd, DWORD id)
449 {
450         switch(id) {
451         case IDM_COPYALL:
452                 copyAllStringToClipboard(hWnd);
453                 return(TRUE);
454         case IDM_ABOUT:
455                 DialogBox(GetModuleHandle(NULL),
456                           MAKEINTRESOURCE(IDD_DIALOG1),
457                           hWnd,
458                           AboutDlgProc);
459                 return(TRUE);
460         case IDM_NEW:
461                 makeNewWindow();
462                 return(TRUE);
463         case IDM_TOPMOST:
464                 return onTopMostMenuCommand(hWnd);
465         }
466     if(IDM_CONFIG_SELECT < id && id <= IDM_CONFIG_SELECT_MAX) {
467         return onConfigMenuCommand(hWnd, id);
468     }
469         return(FALSE);
470 }
471
472 /* EOF */