rtoss - Blame information for rev 124

Subversion Repositories:
Rev:
Rev Author Line No. Line
89 roytam 1 #include "stdafx.h"
2 #include "rsrc/resource.h"
3 #include "GpMain.h"
4 using namespace ki;
5 using namespace editwing;
6  
7  
8  
9 //-------------------------------------------------------------------------
10 // 新規プロセス起動
11 //-------------------------------------------------------------------------
12  
13 void BootNewProcess( const TCHAR* cmd = TEXT("") )
14 {
15         STARTUPINFO         sti;
16         PROCESS_INFORMATION psi;
17         ::GetStartupInfo( &sti );
18  
19         String fcmd = Path(Path::ExeName).BeShortStyle();
20         fcmd += ' ';
21         fcmd += cmd;
22  
23         if( ::CreateProcess( NULL, const_cast<TCHAR*>(fcmd.c_str()),
24                         NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL,
25                         &sti, &psi ) )
26         {
27                 ::CloseHandle( psi.hThread );
28                 ::CloseHandle( psi.hProcess );
29         }
30 }
31  
32  
33  
34 //-------------------------------------------------------------------------
35 // ステ[タスバ[制御
36 //-------------------------------------------------------------------------
37  
38 inline GpStBar::GpStBar()
39         : str_(NULL)
40         , lb_(2)
41 {
42 }
43  
44 inline void GpStBar::SetCsText( const TCHAR* str )
45 {
46         // 文字コ[ド表示領域にSetTextする
47         SetText( str_=str, 1 );
48 }
49  
50 inline void GpStBar::SetLbText( int lb )
51 {
52         // 改行コ[ド表示領域にSetTextする
53         static const TCHAR* const lbstr[] = {TEXT("CR"),TEXT("LF"),TEXT("CRLF")};
54         SetText( lbstr[lb_=lb], 2 );
55 }
56  
57 int GpStBar::AutoResize( bool maximized )
58 {
59         // 文字コ[ド表示領域を確保しつつリサイズ
60         int h = StatusBar::AutoResize( maximized );
61         int w[] = { width()-5, width()-5, width()-5 };
62  
63         HDC dc = ::GetDC( hwnd() );
64         SIZE s;
65         if( ::GetTextExtentPoint32( dc, TEXT("BBBBM"), 5, &s ) )
66                 w[1] = w[2] - s.cx;
90 roytam 67         if( ::GetTextExtentPoint32( dc, TEXT("BBBWW"), 5, &s ) )
89 roytam 68                 w[0] = w[1] - s.cx;
69         ::ReleaseDC( hwnd(), dc );
70  
71         SetParts( countof(w), w );
72         SetCsText( str_ );
73         SetLbText( lb_ );
74         return h;
75 }
76  
77  
78  
79 //-------------------------------------------------------------------------
80 // ディスパッチャ
81 //-------------------------------------------------------------------------
82  
83 LRESULT GreenPadWnd::on_message( UINT msg, WPARAM wp, LPARAM lp )
84 {
85         switch( msg )
86         {
87         // アクティブ化。EditCtrlにフォ[カスを。
88         case WM_ACTIVATE:
89                 if( LOWORD(wp) != WA_INACTIVE )
90                         edit_.SetFocus();
91                 break;
92  
93         // サイズ変更。子窓を適当に移動。
94         case WM_SIZE:
95                 if( wp==SIZE_MAXIMIZED || wp==SIZE_RESTORED )
96                 {
97                         int ht = stb_.AutoResize( wp==SIZE_MAXIMIZED );
98                         edit_.MoveTo( 0, 0, LOWORD(lp), HIWORD(lp)-ht );
99                         cfg_.RememberWnd(this);
100                 }
101                 break;
102  
103         // ウインドウ移動
104         case WM_MOVE:
105                 {
106                         RECT rc;
107                         getPos(&rc);
108                         cfg_.RememberWnd(this);
109                 }
110                 break;
111  
112         // システムコマンド。終了ボタンとか。
113         case WM_SYSCOMMAND:
114                 if( wp==SC_CLOSE || wp==SC_DEFAULT )
115                         on_exit();
116                 else
117                         return WndImpl::on_message( msg, wp, lp );
118                 break;
119  
120         // 右クリックメニュ[
121         case WM_CONTEXTMENU:
122                 if( reinterpret_cast<HWND>(wp) == edit_.hwnd() )
123                         ::TrackPopupMenu(
124                                 ::GetSubMenu( ::GetMenu(hwnd()), 1 ), // 編集メニュ[表示
125                                 TPM_LEFTALIGN|TPM_TOPALIGN|TPM_LEFTBUTTON|TPM_RIGHTBUTTON,
95 roytam 126                                 static_cast<SHORT>(LOWORD(lp)), static_cast<SHORT>(HIWORD(lp)), 0, hwnd(), NULL );
89 roytam 127                 else
128                         return WndImpl::on_message( msg, wp, lp );
129                 break;
130  
131         // メニュ[のグレ[アウト処理
132         case WM_INITMENU:
133         case WM_INITMENUPOPUP:
134                 on_initmenu( reinterpret_cast<HMENU>(wp), msg==WM_INITMENUPOPUP );
135                 break;
136  
137         // D&D
138         case WM_DROPFILES:
139                 on_drop( reinterpret_cast<HDROP>(wp) );
140                 break;
141  
142         // MRU
143         case GPM_MRUCHANGED:
144                 SetupMRUMenu();
145                 break;
146  
90 roytam 147         // NOTIFY
148         case WM_NOTIFY:
149                 if( ((NMHDR*)lp)->code == NM_DBLCLK )
150                         if( wp == 1787 ) // Status Bar ID
151                                 on_reopenfile();
152                 break;
153  
89 roytam 154         // その他
155         default:
156                 return WndImpl::on_message( msg, wp, lp );
157         }
158  
159         return 0;
160 }
161  
162 bool GreenPadWnd::on_command( UINT id, HWND ctrl )
163 {
164         switch( id )
165         {
166         // Window
167         case ID_CMD_NEXTWINDOW: on_nextwnd(); break;
168         case ID_CMD_PREVWINDOW: on_prevwnd(); break;
169  
170         // File
171         case ID_CMD_NEWFILE:    on_newfile();   break;
172         case ID_CMD_OPENFILE:   on_openfile();  break;
173         case ID_CMD_REOPENFILE: on_reopenfile();break;
174         case ID_CMD_SAVEFILE:   on_savefile();  break;
175         case ID_CMD_SAVEFILEAS: on_savefileas();break;
176         case ID_CMD_EXIT:       on_exit();      break;
177  
178         // Edit
179         case ID_CMD_UNDO:       edit_.getDoc().Undo();              break;
180         case ID_CMD_REDO:       edit_.getDoc().Redo();              break;
181         case ID_CMD_CUT:        edit_.getCursor().Cut();            break;
182         case ID_CMD_COPY:       edit_.getCursor().Copy();           break;
183         case ID_CMD_PASTE:      edit_.getCursor().Paste();          break;
184         case ID_CMD_DELETE: if( edit_.getCursor().isSelected() )
185                                 edit_.getCursor().Del();            break;
186         case ID_CMD_SELECTALL:  edit_.getCursor().Home(true,false);
187                                 edit_.getCursor().End(true,true);   break;
188         case ID_CMD_DATETIME:   on_datetime();                      break;
189  
190         // Search
191         case ID_CMD_FIND:       search_.ShowDlg();  break;
192         case ID_CMD_FINDNEXT:   search_.FindNext(); break;
193         case ID_CMD_FINDPREV:   search_.FindPrev(); break;
194         case ID_CMD_JUMP:       on_jump(); break;
195         case ID_CMD_GREP:       on_grep();break;
196  
197         // View
198         case ID_CMD_NOWRAP:     edit_.getView().SetWrapType( wrap_=-1 ); break;
199         case ID_CMD_WRAPWIDTH:  edit_.getView().SetWrapType( wrap_=cfg_.wrapWidth() ); break;
200         case ID_CMD_WRAPWINDOW: edit_.getView().SetWrapType( wrap_=0 ); break;
201         case ID_CMD_CONFIG:     on_config();    break;
202         case ID_CMD_STATUSBAR:  on_statusBar(); break;
203  
204         // DocType
205         default: if( ID_CMD_DOCTYPE <= id ) {
206                         on_doctype( id - ID_CMD_DOCTYPE );
207                         break;
208                 } else if( ID_CMD_MRU <= id ) {
209                         on_mru( id - ID_CMD_MRU );
210                         break;
211                 }
212  
213         // Default
214                 return false;
215         }
216         return true;
217 }
218  
219 bool GreenPadWnd::PreTranslateMessage( MSG* msg )
220 {
221         // 苦肉の策^^;
222         if( search_.TrapMsg(msg) )
223                 return true;
224         // キ[ボ[ドショ[トカット処理
225         return 0 != ::TranslateAccelerator( hwnd(), accel_, msg );
226 }
227  
228  
229  
230 //-------------------------------------------------------------------------
231 // コマンド処理
232 //-------------------------------------------------------------------------
233  
234 void GreenPadWnd::on_dirtyflag_change( bool )
235 {
236         UpdateWindowName();
237 }
238  
239 void GreenPadWnd::on_newfile()
240 {
241         BootNewProcess();
242 }
243  
244 void GreenPadWnd::on_openfile()
245 {
246         Path fn;
247         int  cs;
248         if( ShowOpenDlg( &fn, &cs ) )
249                 Open( fn, cs );
250 }
251  
252 void GreenPadWnd::on_reopenfile()
253 {
254         if( !isUntitled() )
255         {
256                 ReopenDlg dlg( charSets_, csi_ );
257                 dlg.GoModal( hwnd() );
258                 if( dlg.endcode()==IDOK && AskToSave() )
259                         OpenByMyself( filename_, charSets_[dlg.csi()].ID, false );
260         }
261 }
262  
263 void GreenPadWnd::on_savefile()
264 {
265         Save_showDlgIfNeeded();
266 }
267  
268 void GreenPadWnd::on_savefileas()
269 {
270         if( ShowSaveDlg() )
271         {
272                 Save();
273                 ReloadConfig(); // 文書タイプに応じて表示を更新
274         }
275 }
276  
277 void GreenPadWnd::on_exit()
278 {
279         search_.SaveToINI( cfg_.getImpl() );
280         if( AskToSave() )
281                 Destroy();
282 }
283  
284 void GreenPadWnd::on_initmenu( HMENU menu, bool editmenu_only )
285 {
124 roytam 286 #if !defined(TARGET_VER) || (defined(TARGET_VER) && TARGET_VER>310)
89 roytam 287         LOGGER("GreenPadWnd::ReloadConfig on_initmenu begin");
122 roytam 288         if(app().isNewShell())
289         {
290                 MENUITEMINFO mi = { sizeof(MENUITEMINFO), MIIM_STATE };
89 roytam 291  
122 roytam 292                 mi.fState =
293                         (edit_.getCursor().isSelected() ? MFS_ENABLED : MFS_DISABLED);
294                 ::SetMenuItemInfo( menu, ID_CMD_CUT, FALSE, &mi );
295                 ::SetMenuItemInfo( menu, ID_CMD_COPY, FALSE, &mi );
296                 ::SetMenuItemInfo( menu, ID_CMD_DELETE, FALSE, &mi );
89 roytam 297  
122 roytam 298                 mi.fState =
299                         (edit_.getDoc().isUndoAble() ? MFS_ENABLED : MFS_DISABLED);
300                 ::SetMenuItemInfo( menu, ID_CMD_UNDO, FALSE, &mi );
89 roytam 301  
122 roytam 302                 mi.fState =
303                         (edit_.getDoc().isRedoAble() ? MFS_ENABLED : MFS_DISABLED);
304                 ::SetMenuItemInfo( menu, ID_CMD_REDO, FALSE, &mi );
89 roytam 305  
122 roytam 306                 if( editmenu_only )
307                 {
308                         LOGGER("GreenPadWnd::ReloadConfig on_initmenu end");
309                         return;
310                 }
311  
312                 mi.fState = (isUntitled() || edit_.getDoc().isModified()
313                         ? MFS_ENABLED : MFS_DISABLED);
314                 ::SetMenuItemInfo( menu, ID_CMD_SAVEFILE, FALSE, &mi );
315  
316                 mi.fState =
317                         (!isUntitled() ? MFS_ENABLED : MFS_DISABLED);
318                 ::SetMenuItemInfo( menu, ID_CMD_REOPENFILE, FALSE, &mi );
319  
320                 mi.fState =
321                         (cfg_.grepExe().len()>0 ? MFS_ENABLED : MFS_DISABLED);
322                 ::SetMenuItemInfo( menu, ID_CMD_GREP, FALSE, &mi );
323  
324                 UINT id = (wrap_==-1 ? ID_CMD_NOWRAP
325                         : (wrap_>0 ? ID_CMD_WRAPWIDTH : ID_CMD_WRAPWINDOW));
326                 ::CheckMenuRadioItem(
327                         menu, ID_CMD_NOWRAP, ID_CMD_WRAPWINDOW, id, MF_BYCOMMAND );
328         }
329         else
124 roytam 330 #endif
89 roytam 331         {
122 roytam 332                 ::EnableMenuItem( menu, ID_CMD_CUT, MF_BYCOMMAND|(edit_.getCursor().isSelected() ? MF_ENABLED : MF_GRAYED) );
333                 ::EnableMenuItem( menu, ID_CMD_COPY, MF_BYCOMMAND|(edit_.getCursor().isSelected() ? MF_ENABLED : MF_GRAYED) );
334                 ::EnableMenuItem( menu, ID_CMD_DELETE, MF_BYCOMMAND|(edit_.getCursor().isSelected() ? MF_ENABLED : MF_GRAYED) );
335                 ::EnableMenuItem( menu, ID_CMD_UNDO, MF_BYCOMMAND|(edit_.getDoc().isUndoAble() ? MF_ENABLED : MF_GRAYED) );
336                 ::EnableMenuItem( menu, ID_CMD_REDO, MF_BYCOMMAND|(edit_.getDoc().isRedoAble() ? MF_ENABLED : MF_GRAYED) );
89 roytam 337  
122 roytam 338                 if( editmenu_only )
339                 {
340                         LOGGER("GreenPadWnd::ReloadConfig on_initmenu end");
341                         return;
342                 }
89 roytam 343  
122 roytam 344                 ::EnableMenuItem( menu, ID_CMD_SAVEFILE, MF_BYCOMMAND|(isUntitled() || edit_.getDoc().isModified() ? MF_ENABLED : MF_GRAYED) );
345                 ::EnableMenuItem( menu, ID_CMD_REOPENFILE, MF_BYCOMMAND|(!isUntitled() ? MF_ENABLED : MF_GRAYED) );
346                 ::EnableMenuItem( menu, ID_CMD_GREP, MF_BYCOMMAND|(cfg_.grepExe().len()>0 ? MF_ENABLED : MF_GRAYED) );
89 roytam 347  
122 roytam 348                 ::CheckMenuItem( menu, ID_CMD_NOWRAP, MF_BYCOMMAND|(wrap_==-1?MF_CHECKED:MF_UNCHECKED));
349                 ::CheckMenuItem( menu, ID_CMD_WRAPWIDTH, MF_BYCOMMAND|(wrap_>0?MF_CHECKED:MF_UNCHECKED));
350                 ::CheckMenuItem( menu, ID_CMD_WRAPWINDOW, MF_BYCOMMAND|(wrap_==0?MF_CHECKED:MF_UNCHECKED));
351         }
89 roytam 352  
124 roytam 353 #if defined(TARGET_VER) && TARGET_VER==310
354         ::EnableMenuItem( menu, ID_CMD_STATUSBAR, MF_BYCOMMAND|MF_GRAYED );
355 #else
89 roytam 356         ::CheckMenuItem( menu, ID_CMD_STATUSBAR,
122 roytam 357                 cfg_.showStatusBar()?MF_CHECKED:MF_UNCHECKED );
124 roytam 358 #endif
89 roytam 359         LOGGER("GreenPadWnd::ReloadConfig on_initmenu end");
360 }
361  
362 void GreenPadWnd::on_drop( HDROP hd )
363 {
364         UINT iMax = ::DragQueryFile( hd, 0xffffffff, NULL, 0 );
365         for( UINT i=0; i<iMax; ++i )
366         {
367                 TCHAR str[MAX_PATH];
368                 ::DragQueryFile( hd, i, str, countof(str) );
369                 Open( str, AutoDetect );
370         }
371         ::DragFinish( hd );
372 }
373  
374 void GreenPadWnd::on_jump()
375 {
376         struct JumpDlg : public DlgImpl {
377                 JumpDlg(HWND w) : DlgImpl(IDD_JUMP), w_(w) { GoModal(w); }
378                 void on_init() {
379                         SetCenter(hwnd(),w_); ::SetFocus(item(IDC_LINEBOX)); }
380                 bool on_ok() {
381                         TCHAR str[100];
382                         ::GetWindowText( item(IDC_LINEBOX), str, countof(str) );
383                         LineNo = String(str).GetInt();
384                         return true;
385                 }
386                 int LineNo; HWND w_;
387         } dlg(hwnd());
388  
389         if( IDOK == dlg.endcode() )
390                 JumpToLine( dlg.LineNo );
391 }
392  
393 void GreenPadWnd::on_grep()
394 {
395         Path g = cfg_.grepExe();
396         if( g.len() != 0 )
397         {
398                 Path d;
399                 if( filename_.len() )
400                         (d = filename_).BeDirOnly().BeBackSlash(false);
401                 else
402                         d = Path(Path::Cur);
403  
404                 String fcmd;
405                 for( int i=0, e=g.len(); i<e; ++i )
406                         if( g[i]==TEXT('%') )
407                         {
408                                 if( g[i+1]==TEXT('1') || g[i+1]==TEXT('D') ) // '1' for bkwd compat
409                                         ++i, fcmd += d;
410                                 else if( g[i+1]==TEXT('F') )
411                                         ++i, fcmd += filename_;
412                                 else if( g[i+1]==TEXT('N') )
413                                         ++i, fcmd += filename_.name();
414                         }
415                         else
416                                 fcmd += g[i];
417  
418                 PROCESS_INFORMATION psi;
419                 STARTUPINFO         sti = {sizeof(STARTUPINFO)};
420                 //sti.dwFlags = STARTF_USESHOWWINDOW;
421                 //sti.wShowWindow = SW_SHOWNORMAL;
422                 if( ::CreateProcess( NULL, const_cast<TCHAR*>(fcmd.c_str()),
423                                 NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL,
424                                 &sti, &psi ) )
425                 {
426                         ::CloseHandle( psi.hThread );
427                         ::CloseHandle( psi.hProcess );
428                 }
429         }
430 }
431  
432 void GreenPadWnd::on_datetime()
433 {
94 roytam 434         String g = cfg_.dateFormat();
89 roytam 435         TCHAR buf[255], tmp[255];
436         ::GetTimeFormat
94 roytam 437                 ( LOCALE_USER_DEFAULT, 0, NULL, g.len()?const_cast<TCHAR*>(g.c_str()):TEXT("HH:mm yyyy/MM/dd"), buf, countof(buf));
89 roytam 438         ::GetDateFormat
94 roytam 439                 ( LOCALE_USER_DEFAULT, 0, NULL, buf, tmp,countof(tmp));
440         edit_.getCursor().Input( tmp, ::lstrlen(tmp) );
89 roytam 441 }
442  
443 void GreenPadWnd::on_doctype( int no )
444 {
445         if( HMENU m = ::GetSubMenu( ::GetSubMenu(::GetMenu(hwnd()),3),4 ) )
446         {
447                 cfg_.SetDocTypeByMenu( no, m );
448                 ReloadConfig( true );
449         }
450 }
451  
452 void GreenPadWnd::on_config()
453 {
454         if( cfg_.DoDialog(*this) )
455         {
456                 SetupSubMenu();
457                 SetupMRUMenu();
458                 ReloadConfig(false);
459         }
460 }
461  
462 static inline void MyShowWnd( HWND wnd )
463 {
464         if( ::IsIconic(wnd) )
465                 ::ShowWindow( wnd, SW_RESTORE );
466         ::BringWindowToTop( wnd );
467 }
468  
469 void GreenPadWnd::on_nextwnd()
470 {
124 roytam 471 #if !defined(TARGET_VER) || (defined(TARGET_VER) && TARGET_VER>310)
89 roytam 472         if( HWND next = ::FindWindowEx( NULL, hwnd(), className_, NULL ) )
473         {
474                 HWND last=next, pos;
475                 while( last != NULL )
476                         last = ::FindWindowEx( NULL, pos=last, className_, NULL );
477                 if( pos != next )
478                         ::SetWindowPos( hwnd(), pos,
479                                 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_SHOWWINDOW );
480                 MyShowWnd( next );
481         }
124 roytam 482 #endif
89 roytam 483 }
484  
485 void GreenPadWnd::on_prevwnd()
486 {
124 roytam 487 #if !defined(TARGET_VER) || (defined(TARGET_VER) && TARGET_VER>310)
89 roytam 488         HWND pos=NULL, next=::FindWindowEx( NULL,NULL,className_,NULL );
489         if( next==hwnd() )
490         {
491                 while( next != NULL )
492                         next = ::FindWindowEx( NULL,pos=next,className_,NULL );
493                 if( pos!=hwnd())
494                         MyShowWnd( pos );
495         }
496         else
497         {
498                 while( next!=hwnd() && next!=NULL )
499                         next = ::FindWindowEx( NULL,pos=next,className_,NULL );
500                 if( next!=NULL )
501                         MyShowWnd( pos );
502         }
124 roytam 503 #endif
89 roytam 504 }
505  
506 void GreenPadWnd::on_statusBar()
507 {
508         stb_.SetStatusBarVisible( !stb_.isStatusBarVisible() );
509         cfg_.ShowStatusBarSwitch();
510  
511         WINDOWPLACEMENT wp = {sizeof(wp)};
512         ::GetWindowPlacement( hwnd(), &wp );
513         if( wp.showCmd != SW_MINIMIZE )
514         {
515                 const int ht = stb_.AutoResize( wp.showCmd == SW_MAXIMIZE );
516                 RECT rc;
517                 getClientRect(&rc);
518                 edit_.MoveTo( 0, 0, rc.right, rc.bottom-ht );
519         }
520 }
521  
522 void GreenPadWnd::on_move( const DPos& c, const DPos& s )
523 {
524         static int busy_cnt = 0;
525         if( edit_.getDoc().isBusy() && ((++busy_cnt)&0xff) )
526                 return;
527  
528         ulong cad = c.ad;
529         if( ! cfg_.countByUnicode() )
530         {
531                 // ShiftJIS風のByte数カウント
532                 const unicode* cu = edit_.getDoc().tl(c.tl);
533                 const ulong tab = cfg_.vConfig().tabstep;
534                 cad = 0;
535                 for( ulong i=0; i<c.ad; ++i )
536                         if( cu[i] == L'\t' )
537                                 cad = (cad/tab+1)*tab;
538                         else if( cu[i]<0x80 || 0xff60<=cu[i] && cu[i]<=0xff9f )
539                                 cad = cad + 1;
540                         else
541                                 cad = cad + 2;
542         }
543  
544         String str;
545         str += TEXT('(');
546         str += String().SetInt(c.tl+1);
547         str += TEXT(',');
548         str += String().SetInt(cad+1);
549         str += TEXT(')');
550         if( c != s )
551         {
552                 ulong sad = s.ad;
553                 if( ! cfg_.countByUnicode() )
554                 {
555                         // ShiftJIS風のByte数カウント
556                         const unicode* su = edit_.getDoc().tl(s.tl);
557                         sad = 0;
558                         for( ulong i=0; i<s.ad; ++i )
559                                 sad += (su[i]<0x80 || 0xff60<=su[i] && su[i]<=0xff9f ? 1 : 2);
560                 }
561                 str += TEXT(" - (");
562                 str += String().SetInt(s.tl+1);
563                 str += TEXT(',');
564                 str += String().SetInt(sad+1);
565                 str += TEXT(')');
566         }
567         stb_.SetText( str.c_str() );
568 }
569  
570  
571  
572 //-------------------------------------------------------------------------
573 // ユ[ティリティ[
574 //-------------------------------------------------------------------------
575  
576 void GreenPadWnd::JumpToLine( ulong ln )
577 {
578         edit_.getCursor().MoveCur( DPos(ln-1,0), false );
579 }
580  
581 void GreenPadWnd::SetupSubMenu()
582 {
583         if( HMENU m = ::GetSubMenu( ::GetSubMenu(::GetMenu(hwnd()),3),4 ) )
584         {
585                 cfg_.SetDocTypeMenu( m, ID_CMD_DOCTYPE );
586                 ::DrawMenuBar( hwnd() );
587         }
588 }
589  
590 void GreenPadWnd::UpdateWindowName()
591 {
592         // タイトルバ[に表示される文字列の調整
593         // [FileName *] - GreenPad
594         String name;
595         name += TEXT('[');
596         name += isUntitled() ? TEXT("untitled") : filename_.name();
597         if( edit_.getDoc().isModified() ) name += TEXT(" *");
598         name += TEXT("] - ");
599         name += String(IDS_APPNAME).c_str();
600  
601         SetText( name.c_str() );
104 roytam 602         stb_.SetCsText( csi_==0xffffffff?TEXT("UNKN"):charSets_[csi_].shortName );
89 roytam 603         stb_.SetLbText( lb_ );
604 }
605  
606 void GreenPadWnd::SetupMRUMenu()
607 {
608         if( HMENU m = ::GetSubMenu( ::GetSubMenu(::GetMenu(hwnd()),0),8 ) )
609         {
610                 cfg_.SetUpMRUMenu( m, ID_CMD_MRU );
611                 ::DrawMenuBar( hwnd() );
612         }
613 }
614  
615 void GreenPadWnd::on_mru( int no )
616 {
617         Path fn = cfg_.GetMRU(no);
618         if( fn.len() != 0 )
619                 Open( fn, AutoDetect );
620 }
621  
622  
623  
624 //-------------------------------------------------------------------------
625 // 設定更新処理
626 //-------------------------------------------------------------------------
627  
628 void GreenPadWnd::ReloadConfig( bool noSetDocType )
629 {
630         // 文書タイプロ[ド
631         if( !noSetDocType )
632         {
633                 int t = cfg_.SetDocType( filename_ );
634                 if( HMENU m = ::GetSubMenu( ::GetSubMenu(::GetMenu(hwnd()),3),4 ) )
635                         cfg_.CheckMenu( m, t );
636         }
637         LOGGER("GreenPadWnd::ReloadConfig DocTypeLoaded");
638  
639         // Undo回数制限
640         edit_.getDoc().SetUndoLimit( cfg_.undoLimit() );
641  
642         // 行番号
643         bool ln = cfg_.showLN();
644         edit_.getView().ShowLineNo( ln );
645  
646         // 折り返し方式
647         wrap_ = cfg_.wrapType();
648         edit_.getView().SetWrapType( wrap_ );
649  
650         // 色・フォント
651         VConfig vc = cfg_.vConfig();
652         edit_.getView().SetFont( vc );
653         LOGGER("GreenPadWnd::ReloadConfig ViewConfigLoaded");
654  
655         // キ[ワ[ドファイル
656         Path kwd = cfg_.kwdFile();
657         FileR fp;
658         if( kwd.len()!=0 && fp.Open(kwd.c_str()) )
659                 edit_.getDoc().SetKeyword((const unicode*)fp.base(),fp.size()/2);
660         else
661                 edit_.getDoc().SetKeyword(NULL,0);
662         LOGGER("GreenPadWnd::ReloadConfig KeywordLoaded");
663 }
664  
665  
666  
667 //-------------------------------------------------------------------------
668 // 開く処理
669 //-------------------------------------------------------------------------
670  
671 bool GreenPadWnd::ShowOpenDlg( Path* fn, int* cs )
672 {
673         // [Open][Cancel] 開くファイル名指定ダイアログを表示
674         String flst[] = {
675                 String(IDS_TXTFILES),
676                 String(cfg_.txtFileFilter()),
677                 String(IDS_ALLFILES),
678                 String(TEXT("*.*"))
679         };
680         aarr<TCHAR> filt = OpenFileDlg::ConnectWithNull(flst,countof(flst));
681  
682         OpenFileDlg ofd( charSets_ );
683         bool ok = ofd.DoModal( hwnd(), filt.get(), filename_.c_str() );
684         if( ok )
685         {
686                 *fn = ofd.filename();
687                 *cs = charSets_[ofd.csi()].ID;
688         }
689  
690         return ok;
691 }
692  
693 bool GreenPadWnd::Open( const ki::Path& fn, int cs )
694 {
695         if( isUntitled() && !edit_.getDoc().isModified() )
696         {
697                 // 無題で無変更だったら自分で開く
698                 return OpenByMyself( fn, cs );
699         }
700         else
701         {
702                 // 同じ窓で開くモ[ドならそうする
703                 if( cfg_.openSame() )
704                         return ( AskToSave() ? OpenByMyself( fn, cs ) : true );
705  
706                 // そうでなければ他へ回す
707                 String
708                         cmd  = TEXT("-c");
709                         cmd += String().SetInt( cs );
710                         cmd += TEXT(" \"");
711                         cmd += fn;
712                         cmd += TEXT('\"');
713                 BootNewProcess( cmd.c_str() );
714                 return true;
715         }
716 }
717  
718 bool GreenPadWnd::OpenByMyself( const ki::Path& fn, int cs, bool needReConf )
719 {
720         // ファイルを開けなかったらそこでおしまい。
721         aptr<TextFileR> tf( new TextFileR(cs) );
722         if( !tf->Open( fn.c_str() ) )
723         {
724                 // ERROR!
725                 MsgBox( String(IDS_OPENERROR).c_str() );
726                 return false;
727         }
728  
729         // 自分内部の管理情報を更新
730         if( fn[0]==TEXT('\\') || fn[1]==TEXT(':') )
731                 filename_ = fn;
732         else
733                 filename_ = Path( Path::Cur ) + fn;
734         if( tf->size() )
735         {
736                 csi_      = charSets_.findCsi( tf->codepage() );
737                 if( tf->nolb_found() )
738                         lb_       = cfg_.GetNewfileLB();
739                 else
740                         lb_       = tf->linebreak();
741         }
742         else
743         { // 空ファイルの場合は新規作成と同じ扱い
744                 csi_      = cfg_.GetNewfileCsi();
745                 lb_       = cfg_.GetNewfileLB();
746         }
747         filename_.BeShortLongStyle();
748  
749         // カレントディレクトリを、ファイルのある位置以外にしておく
750         // (こうしないと、開いているファイルのあるディレクトリが削除できない)
751         ::SetCurrentDirectory( Path(filename_).BeDriveOnly().c_str() );
752  
753         // 文書タイプに応じて表示を更新
754         if( needReConf )
755                 ReloadConfig();
756  
757         // 開く
758         edit_.getDoc().ClearAll();
759         edit_.getDoc().OpenFile( tf );
760  
761         // タイトルバ[更新
762         UpdateWindowName();
763  
764         // [最近使ったファイル]へ追加
765         cfg_.AddMRU( filename_ );
766         HWND wnd = NULL;
124 roytam 767 #if !defined(TARGET_VER) || (defined(TARGET_VER) && TARGET_VER>310)
89 roytam 768         while( NULL!=(wnd=::FindWindowEx( NULL, wnd, className_, NULL )) )
769                 SendMessage( wnd, GPM_MRUCHANGED, 0, 0 );
124 roytam 770 #endif
89 roytam 771  
772         return true;
773 }
774  
775  
776  
777 //-------------------------------------------------------------------------
778 // 保存処理
779 //-------------------------------------------------------------------------
780  
781 bool GreenPadWnd::ShowSaveDlg()
782 {
783         // [Save][Cancel] 保存先ファイル名指定ダイアログを表示
784  
785         String flst[] = {
786                 String(IDS_ALLFILES),
787                 String(TEXT("*.*"))
788         };
789         aarr<TCHAR> filt = SaveFileDlg::ConnectWithNull( flst, countof(flst) );
790  
791         SaveFileDlg sfd( charSets_, csi_, lb_ );
792         if( !sfd.DoModal( hwnd(), filt.get(), filename_.c_str() ) )
793                 return false;
794  
795         filename_ = sfd.filename();
796         csi_      = sfd.csi();
797         lb_       = sfd.lb();
798  
799         return true;
800 }
801  
802 bool GreenPadWnd::Save_showDlgIfNeeded()
803 {
804         bool wasUntitled = isUntitled();
805  
806         // [Save][Cancel] ファイル名未定ならダイアログ表示
807         if( isUntitled() )
808                 if( !ShowSaveDlg() )
809                         return false;
810         if( Save() )
811         {
812                 if( wasUntitled )
813                         ReloadConfig(); // 文書タイプに応じて表示を更新
814                 return true;
815         }
816         return false;
817 }
818  
819 bool GreenPadWnd::AskToSave()
820 {
821         // 変更されていたら、
822         // [Yes][No][Cancel] 保存するかどうか尋ねる。
823         // 保存するなら
824         // [Save][Cancel]    ファイル名未定ならダイアログ表示
825  
826         if( edit_.getDoc().isModified() )
827         {
828                 int answer = MsgBox(
829                         String(IDS_ASKTOSAVE).c_str(),
830                         String(IDS_APPNAME).c_str(),
831                         MB_YESNOCANCEL|MB_ICONQUESTION
832                 );
833                 if( answer == IDYES )    return Save_showDlgIfNeeded();
834                 if( answer == IDCANCEL ) return false;
835         }
836         return true;
837 }
838  
839 bool GreenPadWnd::Save()
840 {
841         TextFileW tf( charSets_[csi_].ID, lb_ );
842         if( tf.Open( filename_.c_str() ) )
843         {
844                 // 無事ファイルに保存できた場合
845                 edit_.getDoc().SaveFile( tf );
846                 UpdateWindowName();
847                 // [最近使ったファイル]更新
848                 cfg_.AddMRU( filename_ );
849                 HWND wnd = NULL;
124 roytam 850 #if !defined(TARGET_VER) || (defined(TARGET_VER) && TARGET_VER>310)
89 roytam 851                 while( NULL!=(wnd=::FindWindowEx( NULL, wnd, className_, NULL )) )
852                         SendMessage( wnd, GPM_MRUCHANGED, 0, 0 );
124 roytam 853 #endif
89 roytam 854                 return true;
855         }
856  
857         // Error!
858         MsgBox( String(IDS_SAVEERROR).c_str() );
859         return false;
860 }
861  
862  
863  
864 //-------------------------------------------------------------------------
865 // メインウインドウの初期化
866 //-------------------------------------------------------------------------
867  
868 GreenPadWnd::ClsName GreenPadWnd::className_ = TEXT("GreenPad MainWnd");
869  
870 GreenPadWnd::GreenPadWnd()
871         : WndImpl  ( className_, WS_OVERLAPPEDWINDOW, WS_EX_ACCEPTFILES )
872         , charSets_( cfg_.GetCharSetList() )
873         , csi_     ( cfg_.GetNewfileCsi() )
874         , lb_      ( cfg_.GetNewfileLB() )
875         , search_  ( *this, edit_ )
876 {
877         LOGGER( "GreenPadWnd::Construct begin" );
878  
123 roytam 879 #if !defined(TARGET_VER) || TARGET_VER>350
89 roytam 880         static WNDCLASSEX wc;
123 roytam 881 #else
882         static WNDCLASS wc;
883 #endif
89 roytam 884         wc.hIcon         = app().LoadIcon( IDR_MAIN );
885         wc.hCursor       = app().LoadOemCursor( IDC_ARROW );
886         wc.lpszMenuName  = MAKEINTRESOURCE( IDR_MAIN );
887         wc.lpszClassName = className_;
888         WndImpl::Register( &wc );
889  
890         ime().EnableGlobalIME( true );
891  
892         LOGGER( "GreenPadWnd::Construct end" );
893 }
894  
895 void GreenPadWnd::on_create( CREATESTRUCT* cs )
896 {
897         LOGGER("GreenPadWnd::on_create begin");
898  
899         accel_ = app().LoadAccel( IDR_MAIN );
900         stb_.Create( hwnd() );
901         edit_.Create( NULL, hwnd(), 0, 0, 100, 100 );
902         LOGGER("GreenPadWnd::on_create edit created");
903         edit_.getDoc().AddHandler( this );
904         edit_.getCursor().AddHandler( this );
124 roytam 905 #if !defined(TARGET_VER) || (defined(TARGET_VER) && TARGET_VER>310)
89 roytam 906         stb_.SetStatusBarVisible( cfg_.showStatusBar() );
124 roytam 907 #elif defined(TARGET_VER) && TARGET_VER==310
908         stb_.SetStatusBarVisible( false );
909 #endif
89 roytam 910  
911         LOGGER("GreenPadWnd::on_create halfway");
912  
913         search_.LoadFromINI( cfg_.getImpl() );
914         SetupSubMenu();
915         SetupMRUMenu();
916  
917         LOGGER("GreenPadWnd::on_create menu");
918 }
919  
920 bool GreenPadWnd::StartUp( const Path& fn, int cs, int ln )
921 {
922         LOGGER( "GreenPadWnd::StartUp begin" );
923         Create( 0, 0, cfg_.GetWndX(), cfg_.GetWndY(), cfg_.GetWndW(), cfg_.GetWndH(), 0 );
924         LOGGER( "GreenPadWnd::Created" );
925         if( fn.len()==0 || !OpenByMyself( fn, cs ) )
926         {
927                 LOGGER( "for new file..." );
928  
929                 // ファイルを開か(け)なかった場合
930                 ReloadConfig( fn.len()==0 );
931                 LOGGER( "GreenPadWnd::StartUp reloadconfig end" );
932                 UpdateWindowName();
933                 LOGGER( "GreenPadWnd::StartUp updatewindowname end" );
934         }
935  
936         // 指定の行へジャンプ
937         if( ln != -1 )
938                 JumpToLine( ln );
939  
940         LOGGER( "GreenPadWnd::StartUp end" );
941         return true;
942 }
943  
944 void GreenPadWnd::ShowUp2()
945 {
946         Window::ShowUp( cfg_.GetWndM() ? SW_MAXIMIZE : SW_SHOW );
947 }
948  
949  
950 //-------------------------------------------------------------------------
951 // スタ[トアップル[チン
952 //      コマンドラインの解析を行う
953 //-------------------------------------------------------------------------
954  
955 int kmain()
956 {
957         LOGGER( "kmain() begin" );
958  
959         Argv  arg;
960         ulong   i;
961  
962         LOGGER( "argv processed" );
963  
964   //-- まずオプションスイッチを処理
965  
966         int optL = -1;
967         int optC = 0;
968  
969         for( i=1; i<arg.size() && arg[i][0]==TEXT('-'); ++i )
970                 switch( arg[i][1] )
971                 {
972                 case TEXT('c'):
973                         optC = String::GetInt( arg[i]+2 );
974                         break;
975                 case TEXT('l'):
976                         optL = String::GetInt( arg[i]+2 );
977                         break;
978                 }
979  
980         LOGGER( "option processed" );
981  
982   //-- 次にファイル名
983  
984         Path file;
985  
986         if( i < arg.size() )
987         {
988                 file = arg[i];
989                 if( !file.isFile() )
990                 {
991                         ulong j; // ""無しで半スペ入りでもそれなりに対処
992                         for( j=i+1; j<arg.size(); ++j )
993                         {
994                                 file += ' ';
995                                 file += arg[j];
996                                 if( file.isFile() )
997                                         break;
998                         }
999  
1000                         if( j==arg.size() )
1001                                 file = arg[i];
1002                         else
1003                                 i=j;
1004                 }
1005         }
1006  
1007         LOGGER( "filename processed" );
1008  
1009   //-- ]ってる引数があれば、それで新規プロセス起動
1010  
1011         if( ++i < arg.size() )
1012         {
1013                 String cmd;
1014                 for( ; i<arg.size(); ++i )
1015                 {
1016                         cmd += TEXT('\"');
1017                         cmd += arg[i];
1018                         cmd += TEXT("\" ");
1019                 }
1020                 ::BootNewProcess( cmd.c_str() );
1021         }
1022  
1023         LOGGER( "newprocess booted" );
1024  
1025   //-- メインウインドウ発進
1026  
1027         GreenPadWnd wnd;
1028         if( !wnd.StartUp(file,optC,optL) )
1029                 return -1;
1030  
1031         LOGGER( "kmain() startup ok" );
1032  
1033   //-- メインル[プ
1034  
1035         wnd.ShowUp2();
1036         LOGGER( "showup!" );
1037         wnd.MsgLoop();
1038  
1039         LOGGER( "fin" );
1040         return 0;
1041 }