#include "stdafx.h"
#include "rsrc/resource.h"
#include "GpMain.h"
using namespace ki;
using namespace editwing;
//-------------------------------------------------------------------------
// 新規プロセス起動
//-------------------------------------------------------------------------
void BootNewProcess( const TCHAR* cmd = TEXT("") )
{
STARTUPINFO sti;
PROCESS_INFORMATION psi;
::GetStartupInfo( &sti );
String fcmd = Path(Path::ExeName).BeShortStyle();
fcmd += ' ';
fcmd += cmd;
if( ::CreateProcess( NULL, const_cast<TCHAR*>(fcmd.c_str()),
NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL,
&sti, &psi ) )
{
::CloseHandle( psi.hThread );
::CloseHandle( psi.hProcess );
}
}
//-------------------------------------------------------------------------
// ステータスバー制御
//-------------------------------------------------------------------------
inline GpStBar::GpStBar()
: str_(NULL)
, lb_(2)
{
}
inline void GpStBar::SetCsText( const TCHAR* str )
{
// 文字コード表示領域にSetTextする
SetText( str_=str, 1 );
}
inline void GpStBar::SetLbText( int lb )
{
// 改行コード表示領域にSetTextする
static const TCHAR* const lbstr[] = {TEXT("CR"),TEXT("LF"),TEXT("CRLF")};
SetText( lbstr[lb_=lb], 2 );
}
int GpStBar::AutoResize( bool maximized )
{
// 文字コード表示領域を確保しつつリサイズ
int h = StatusBar::AutoResize( maximized );
int w[] = { width()-5, width()-5, width()-5 };
HDC dc = ::GetDC( hwnd() );
SIZE s;
if( ::GetTextExtentPoint32( dc, TEXT("BBBBM"), 5, &s ) )
w[1] = w[2] - s.cx;
if( ::GetTextExtentPoint32( dc, TEXT("BBBBB"), 5, &s ) )
w[0] = w[1] - s.cx;
::ReleaseDC( hwnd(), dc );
SetParts( countof(w), w );
SetCsText( str_ );
SetLbText( lb_ );
return h;
}
//-------------------------------------------------------------------------
// ディスパッチャ
//-------------------------------------------------------------------------
LRESULT GreenPadWnd::on_message( UINT msg, WPARAM wp, LPARAM lp )
{
switch( msg )
{
// アクティブ化。EditCtrlにフォーカスを。
case WM_ACTIVATE:
if( LOWORD(wp) != WA_INACTIVE )
edit_.SetFocus();
break;
// サイズ変更。子窓を適当に移動。
case WM_SIZE:
if( wp==SIZE_MAXIMIZED || wp==SIZE_RESTORED )
{
int ht = stb_.AutoResize( wp==SIZE_MAXIMIZED );
edit_.MoveTo( 0, 0, LOWORD(lp), HIWORD(lp)-ht );
cfg_.RememberWnd(this);
}
break;
// ウインドウ移動
case WM_MOVE:
{
RECT rc;
getPos(&rc);
cfg_.RememberWnd(this);
}
break;
// システムコマンド。終了ボタンとか。
case WM_SYSCOMMAND:
if( wp==SC_CLOSE || wp==SC_DEFAULT )
on_exit();
else
return WndImpl::on_message( msg, wp, lp );
break;
// 右クリックメニュー
case WM_CONTEXTMENU:
if( reinterpret_cast<HWND>(wp) == edit_.hwnd() )
::TrackPopupMenu(
::GetSubMenu( ::GetMenu(hwnd()), 1 ), // 編集メニュー表示
TPM_LEFTALIGN|TPM_TOPALIGN|TPM_LEFTBUTTON|TPM_RIGHTBUTTON,
LOWORD(lp), HIWORD(lp), 0, hwnd(), NULL );
else
return WndImpl::on_message( msg, wp, lp );
break;
// メニューのグレーアウト処理
case WM_INITMENU:
case WM_INITMENUPOPUP:
on_initmenu( reinterpret_cast<HMENU>(wp), msg==WM_INITMENUPOPUP );
break;
// D&D
case WM_DROPFILES:
on_drop( reinterpret_cast<HDROP>(wp) );
break;
// MRU
case GPM_MRUCHANGED:
SetupMRUMenu();
break;
// その他
default:
return WndImpl::on_message( msg, wp, lp );
}
return 0;
}
bool GreenPadWnd::on_command( UINT id, HWND ctrl )
{
switch( id )
{
// Window
case ID_CMD_NEXTWINDOW: on_nextwnd(); break;
case ID_CMD_PREVWINDOW: on_prevwnd(); break;
// File
case ID_CMD_NEWFILE: on_newfile(); break;
case ID_CMD_OPENFILE: on_openfile(); break;
case ID_CMD_REOPENFILE: on_reopenfile();break;
case ID_CMD_SAVEFILE: on_savefile(); break;
case ID_CMD_SAVEFILEAS: on_savefileas();break;
case ID_CMD_EXIT: on_exit(); break;
// Edit
case ID_CMD_UNDO: edit_.getDoc().Undo(); break;
case ID_CMD_REDO: edit_.getDoc().Redo(); break;
case ID_CMD_CUT: edit_.getCursor().Cut(); break;
case ID_CMD_COPY: edit_.getCursor().Copy(); break;
case ID_CMD_PASTE: edit_.getCursor().Paste(); break;
case ID_CMD_DELETE: if( edit_.getCursor().isSelected() )
edit_.getCursor().Del(); break;
case ID_CMD_SELECTALL: edit_.getCursor().Home(true,false);
edit_.getCursor().End(true,true); break;
case ID_CMD_DATETIME: on_datetime(); break;
// Search
case ID_CMD_FIND: search_.ShowDlg(); break;
case ID_CMD_FINDNEXT: search_.FindNext(); break;
case ID_CMD_FINDPREV: search_.FindPrev(); break;
case ID_CMD_JUMP: on_jump(); break;
case ID_CMD_GREP: on_grep();break;
// View
case ID_CMD_NOWRAP: edit_.getView().SetWrapType( wrap_=-1 ); break;
case ID_CMD_WRAPWIDTH: edit_.getView().SetWrapType( wrap_=cfg_.wrapWidth() ); break;
case ID_CMD_WRAPWINDOW: edit_.getView().SetWrapType( wrap_=0 ); break;
case ID_CMD_CONFIG: on_config(); break;
case ID_CMD_STATUSBAR: on_statusBar(); break;
// DocType
default: if( ID_CMD_DOCTYPE <= id ) {
on_doctype( id - ID_CMD_DOCTYPE );
break;
} else if( ID_CMD_MRU <= id ) {
on_mru( id - ID_CMD_MRU );
break;
}
// Default
return false;
}
return true;
}
bool GreenPadWnd::PreTranslateMessage( MSG* msg )
{
// 苦肉の策^^;
if( search_.TrapMsg(msg) )
return true;
// キーボードショートカット処理
return 0 != ::TranslateAccelerator( hwnd(), accel_, msg );
}
//-------------------------------------------------------------------------
// コマンド処理
//-------------------------------------------------------------------------
void GreenPadWnd::on_dirtyflag_change( bool )
{
UpdateWindowName();
}
void GreenPadWnd::on_newfile()
{
BootNewProcess();
}
void GreenPadWnd::on_openfile()
{
Path fn;
int cs;
if( ShowOpenDlg( &fn, &cs ) )
Open( fn, cs );
}
void GreenPadWnd::on_reopenfile()
{
if( !isUntitled() )
{
ReopenDlg dlg( charSets_, csi_ );
dlg.GoModal( hwnd() );
if( dlg.endcode()==IDOK && AskToSave() )
OpenByMyself( filename_, charSets_[dlg.csi()].ID, false );
}
}
void GreenPadWnd::on_savefile()
{
Save_showDlgIfNeeded();
}
void GreenPadWnd::on_savefileas()
{
if( ShowSaveDlg() )
{
Save();
ReloadConfig(); // 文書タイプに応じて表示を更新
}
}
void GreenPadWnd::on_exit()
{
search_.SaveToINI( cfg_.getImpl() );
if( AskToSave() )
Destroy();
}
void GreenPadWnd::on_initmenu( HMENU menu, bool editmenu_only )
{
LOGGER("GreenPadWnd::ReloadConfig on_initmenu begin");
MENUITEMINFO mi = { sizeof(MENUITEMINFO), MIIM_STATE };
mi.fState =
(edit_.getCursor().isSelected() ? MFS_ENABLED : MFS_DISABLED);
SetMenuItemInfo( menu, ID_CMD_CUT, FALSE, &mi );
SetMenuItemInfo( menu, ID_CMD_COPY, FALSE, &mi );
SetMenuItemInfo( menu, ID_CMD_DELETE, FALSE, &mi );
mi.fState =
(edit_.getDoc().isUndoAble() ? MFS_ENABLED : MFS_DISABLED);
SetMenuItemInfo( menu, ID_CMD_UNDO, FALSE, &mi );
mi.fState =
(edit_.getDoc().isRedoAble() ? MFS_ENABLED : MFS_DISABLED);
SetMenuItemInfo( menu, ID_CMD_REDO, FALSE, &mi );
if( editmenu_only )
{
LOGGER("GreenPadWnd::ReloadConfig on_initmenu end");
return;
}
mi.fState = (isUntitled() || edit_.getDoc().isModified()
? MFS_ENABLED : MFS_DISABLED);
SetMenuItemInfo( menu, ID_CMD_SAVEFILE, FALSE, &mi );
mi.fState =
(!isUntitled() ? MFS_ENABLED : MFS_DISABLED);
SetMenuItemInfo( menu, ID_CMD_REOPENFILE, FALSE, &mi );
mi.fState =
(cfg_.grepExe().len()>0 ? MFS_ENABLED : MFS_DISABLED);
SetMenuItemInfo( menu, ID_CMD_GREP, FALSE, &mi );
UINT id = (wrap_==-1 ? ID_CMD_NOWRAP
: (wrap_>0 ? ID_CMD_WRAPWIDTH : ID_CMD_WRAPWINDOW));
::CheckMenuRadioItem(
menu, ID_CMD_NOWRAP, ID_CMD_WRAPWINDOW, id, MF_BYCOMMAND );
::CheckMenuItem( menu, ID_CMD_STATUSBAR,
cfg_.showStatusBar()?MFS_CHECKED:MFS_UNCHECKED );
LOGGER("GreenPadWnd::ReloadConfig on_initmenu end");
}
void GreenPadWnd::on_drop( HDROP hd )
{
UINT iMax = ::DragQueryFile( hd, 0xffffffff, NULL, 0 );
for( UINT i=0; i<iMax; ++i )
{
TCHAR str[MAX_PATH];
::DragQueryFile( hd, i, str, countof(str) );
Open( str, AutoDetect );
}
::DragFinish( hd );
}
void GreenPadWnd::on_jump()
{
struct JumpDlg : public DlgImpl {
JumpDlg(HWND w) : DlgImpl(IDD_JUMP), w_(w) { GoModal(w); }
void on_init() {
SetCenter(hwnd(),w_); ::SetFocus(item(IDC_LINEBOX)); }
bool on_ok() {
TCHAR str[100];
::GetWindowText( item(IDC_LINEBOX), str, countof(str) );
LineNo = String(str).GetInt();
return true;
}
int LineNo; HWND w_;
} dlg(hwnd());
if( IDOK == dlg.endcode() )
JumpToLine( dlg.LineNo );
}
void GreenPadWnd::on_grep()
{
Path g = cfg_.grepExe();
if( g.len() != 0 )
{
Path d;
if( filename_.len() )
(d = filename_).BeDirOnly().BeBackSlash(false);
else
d = Path(Path::Cur);
String fcmd;
for( int i=0, e=g.len(); i<e; ++i )
if( g[i]==TEXT('%') )
{
if( g[i+1]==TEXT('1') || g[i+1]==TEXT('D') ) // '1' for bkwd compat
++i, fcmd += d;
else if( g[i+1]==TEXT('F') )
++i, fcmd += filename_;
else if( g[i+1]==TEXT('N') )
++i, fcmd += filename_.name();
}
else
fcmd += g[i];
PROCESS_INFORMATION psi;
STARTUPINFO sti = {sizeof(STARTUPINFO)};
//sti.dwFlags = STARTF_USESHOWWINDOW;
//sti.wShowWindow = SW_SHOWNORMAL;
if( ::CreateProcess( NULL, const_cast<TCHAR*>(fcmd.c_str()),
NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL,
&sti, &psi ) )
{
::CloseHandle( psi.hThread );
::CloseHandle( psi.hProcess );
}
}
}
void GreenPadWnd::on_datetime()
{
TCHAR buf[255], tmp[255];
::GetTimeFormat
( LOCALE_USER_DEFAULT, 0, NULL, TEXT("HH:mm "), buf, countof(buf));
::GetDateFormat
( LOCALE_USER_DEFAULT, 0, NULL, TEXT("yy/MM/dd"),tmp,countof(tmp));
::lstrcat( buf, tmp );
edit_.getCursor().Input( buf, ::lstrlen(buf) );
}
void GreenPadWnd::on_doctype( int no )
{
if( HMENU m = ::GetSubMenu( ::GetSubMenu(::GetMenu(hwnd()),3),4 ) )
{
cfg_.SetDocTypeByMenu( no, m );
ReloadConfig( true );
}
}
void GreenPadWnd::on_config()
{
if( cfg_.DoDialog(*this) )
{
SetupSubMenu();
SetupMRUMenu();
ReloadConfig(false);
}
}
static inline void MyShowWnd( HWND wnd )
{
if( ::IsIconic(wnd) )
::ShowWindow( wnd, SW_RESTORE );
::BringWindowToTop( wnd );
}
void GreenPadWnd::on_nextwnd()
{
if( HWND next = ::FindWindowEx( NULL, hwnd(), className_, NULL ) )
{
HWND last=next, pos;
while( last != NULL )
last = ::FindWindowEx( NULL, pos=last, className_, NULL );
if( pos != next )
::SetWindowPos( hwnd(), pos,
0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_SHOWWINDOW );
MyShowWnd( next );
}
}
void GreenPadWnd::on_prevwnd()
{
HWND pos=NULL, next=::FindWindowEx( NULL,NULL,className_,NULL );
if( next==hwnd() )
{
while( next != NULL )
next = ::FindWindowEx( NULL,pos=next,className_,NULL );
if( pos!=hwnd())
MyShowWnd( pos );
}
else
{
while( next!=hwnd() && next!=NULL )
next = ::FindWindowEx( NULL,pos=next,className_,NULL );
if( next!=NULL )
MyShowWnd( pos );
}
}
void GreenPadWnd::on_statusBar()
{
stb_.SetStatusBarVisible( !stb_.isStatusBarVisible() );
cfg_.ShowStatusBarSwitch();
WINDOWPLACEMENT wp = {sizeof(wp)};
::GetWindowPlacement( hwnd(), &wp );
if( wp.showCmd != SW_MINIMIZE )
{
const int ht = stb_.AutoResize( wp.showCmd == SW_MAXIMIZE );
RECT rc;
getClientRect(&rc);
edit_.MoveTo( 0, 0, rc.right, rc.bottom-ht );
}
}
void GreenPadWnd::on_move( const DPos& c, const DPos& s )
{
static int busy_cnt = 0;
if( edit_.getDoc().isBusy() && ((++busy_cnt)&0xff) )
return;
ulong cad = c.ad;
if( ! cfg_.countByUnicode() )
{
// ShiftJIS風のByte数カウント
const unicode* cu = edit_.getDoc().tl(c.tl);
const ulong tab = cfg_.vConfig().tabstep;
cad = 0;
for( ulong i=0; i<c.ad; ++i )
if( cu[i] == L'\t' )
cad = (cad/tab+1)*tab;
else if( cu[i]<0x80 || 0xff60<=cu[i] && cu[i]<=0xff9f )
cad = cad + 1;
else
cad = cad + 2;
}
String str;
str += TEXT('(');
str += String().SetInt(c.tl+1);
str += TEXT(',');
str += String().SetInt(cad+1);
str += TEXT(')');
if( c != s )
{
ulong sad = s.ad;
if( ! cfg_.countByUnicode() )
{
// ShiftJIS風のByte数カウント
const unicode* su = edit_.getDoc().tl(s.tl);
sad = 0;
for( ulong i=0; i<s.ad; ++i )
sad += (su[i]<0x80 || 0xff60<=su[i] && su[i]<=0xff9f ? 1 : 2);
}
str += TEXT(" - (");
str += String().SetInt(s.tl+1);
str += TEXT(',');
str += String().SetInt(sad+1);
str += TEXT(')');
}
stb_.SetText( str.c_str() );
}
//-------------------------------------------------------------------------
// ユーティリティー
//-------------------------------------------------------------------------
void GreenPadWnd::JumpToLine( ulong ln )
{
edit_.getCursor().MoveCur( DPos(ln-1,0), false );
}
void GreenPadWnd::SetupSubMenu()
{
if( HMENU m = ::GetSubMenu( ::GetSubMenu(::GetMenu(hwnd()),3),4 ) )
{
cfg_.SetDocTypeMenu( m, ID_CMD_DOCTYPE );
::DrawMenuBar( hwnd() );
}
}
void GreenPadWnd::UpdateWindowName()
{
// タイトルバーに表示される文字列の調整
// [FileName *] - GreenPad
String name;
name += TEXT('[');
name += isUntitled() ? TEXT("untitled") : filename_.name();
if( edit_.getDoc().isModified() ) name += TEXT(" *");
name += TEXT("] - ");
name += String(IDS_APPNAME).c_str();
SetText( name.c_str() );
stb_.SetCsText( charSets_[csi_].shortName );
stb_.SetLbText( lb_ );
}
void GreenPadWnd::SetupMRUMenu()
{
if( HMENU m = ::GetSubMenu( ::GetSubMenu(::GetMenu(hwnd()),0),8 ) )
{
cfg_.SetUpMRUMenu( m, ID_CMD_MRU );
::DrawMenuBar( hwnd() );
}
}
void GreenPadWnd::on_mru( int no )
{
Path fn = cfg_.GetMRU(no);
if( fn.len() != 0 )
Open( fn, AutoDetect );
}
//-------------------------------------------------------------------------
// 設定更新処理
//-------------------------------------------------------------------------
void GreenPadWnd::ReloadConfig( bool noSetDocType )
{
// 文書タイプロード
if( !noSetDocType )
{
int t = cfg_.SetDocType( filename_ );
if( HMENU m = ::GetSubMenu( ::GetSubMenu(::GetMenu(hwnd()),3),4 ) )
cfg_.CheckMenu( m, t );
}
LOGGER("GreenPadWnd::ReloadConfig DocTypeLoaded");
// Undo回数制限
edit_.getDoc().SetUndoLimit( cfg_.undoLimit() );
// 行番号
bool ln = cfg_.showLN();
edit_.getView().ShowLineNo( ln );
// 折り返し方式
wrap_ = cfg_.wrapType();
edit_.getView().SetWrapType( wrap_ );
// 色・フォント
VConfig vc = cfg_.vConfig();
edit_.getView().SetFont( vc );
LOGGER("GreenPadWnd::ReloadConfig ViewConfigLoaded");
// キーワードファイル
Path kwd = cfg_.kwdFile();
FileR fp;
if( kwd.len()!=0 && fp.Open(kwd.c_str()) )
edit_.getDoc().SetKeyword((const unicode*)fp.base(),fp.size()/2);
else
edit_.getDoc().SetKeyword(NULL,0);
LOGGER("GreenPadWnd::ReloadConfig KeywordLoaded");
}
//-------------------------------------------------------------------------
// 開く処理
//-------------------------------------------------------------------------
bool GreenPadWnd::ShowOpenDlg( Path* fn, int* cs )
{
// [Open][Cancel] 開くファイル名指定ダイアログを表示
String flst[] = {
String(IDS_TXTFILES),
String(cfg_.txtFileFilter()),
String(IDS_ALLFILES),
String(TEXT("*.*"))
};
aarr<TCHAR> filt = OpenFileDlg::ConnectWithNull(flst,countof(flst));
OpenFileDlg ofd( charSets_ );
bool ok = ofd.DoModal( hwnd(), filt.get(), filename_.c_str() );
if( ok )
{
*fn = ofd.filename();
*cs = charSets_[ofd.csi()].ID;
}
return ok;
}
bool GreenPadWnd::Open( const ki::Path& fn, int cs )
{
if( isUntitled() && !edit_.getDoc().isModified() )
{
// 無題で無変更だったら自分で開く
return OpenByMyself( fn, cs );
}
else
{
// 同じ窓で開くモードならそうする
if( cfg_.openSame() )
return ( AskToSave() ? OpenByMyself( fn, cs ) : true );
// そうでなければ他へ回す
String
cmd = TEXT("-c");
cmd += String().SetInt( cs );
cmd += TEXT(" \"");
cmd += fn;
cmd += TEXT('\"');
BootNewProcess( cmd.c_str() );
return true;
}
}
bool GreenPadWnd::OpenByMyself( const ki::Path& fn, int cs, bool needReConf )
{
// ファイルを開けなかったらそこでおしまい。
aptr<TextFileR> tf( new TextFileR(cs) );
if( !tf->Open( fn.c_str() ) )
{
// ERROR!
MsgBox( String(IDS_OPENERROR).c_str() );
return false;
}
// 自分内部の管理情報を更新
if( fn[0]==TEXT('\\') || fn[1]==TEXT(':') )
filename_ = fn;
else
filename_ = Path( Path::Cur ) + fn;
if( tf->size() )
{
csi_ = charSets_.findCsi( tf->codepage() );
if( tf->nolb_found() )
lb_ = cfg_.GetNewfileLB();
else
lb_ = tf->linebreak();
}
else
{ // 空ファイルの場合は新規作成と同じ扱い
csi_ = cfg_.GetNewfileCsi();
lb_ = cfg_.GetNewfileLB();
}
filename_.BeShortLongStyle();
// カレントディレクトリを、ファイルのある位置以外にしておく
// (こうしないと、開いているファイルのあるディレクトリが削除できない)
::SetCurrentDirectory( Path(filename_).BeDriveOnly().c_str() );
// 文書タイプに応じて表示を更新
if( needReConf )
ReloadConfig();
// 開く
edit_.getDoc().ClearAll();
edit_.getDoc().OpenFile( tf );
// タイトルバー更新
UpdateWindowName();
// [最近使ったファイル]へ追加
cfg_.AddMRU( filename_ );
HWND wnd = NULL;
while( NULL!=(wnd=::FindWindowEx( NULL, wnd, className_, NULL )) )
SendMessage( wnd, GPM_MRUCHANGED, 0, 0 );
return true;
}
//-------------------------------------------------------------------------
// 保存処理
//-------------------------------------------------------------------------
bool GreenPadWnd::ShowSaveDlg()
{
// [Save][Cancel] 保存先ファイル名指定ダイアログを表示
String flst[] = {
String(IDS_ALLFILES),
String(TEXT("*.*"))
};
aarr<TCHAR> filt = SaveFileDlg::ConnectWithNull( flst, countof(flst) );
SaveFileDlg sfd( charSets_, csi_, lb_ );
if( !sfd.DoModal( hwnd(), filt.get(), filename_.c_str() ) )
return false;
filename_ = sfd.filename();
csi_ = sfd.csi();
lb_ = sfd.lb();
return true;
}
bool GreenPadWnd::Save_showDlgIfNeeded()
{
bool wasUntitled = isUntitled();
// [Save][Cancel] ファイル名未定ならダイアログ表示
if( isUntitled() )
if( !ShowSaveDlg() )
return false;
if( Save() )
{
if( wasUntitled )
ReloadConfig(); // 文書タイプに応じて表示を更新
return true;
}
return false;
}
bool GreenPadWnd::AskToSave()
{
// 変更されていたら、
// [Yes][No][Cancel] 保存するかどうか尋ねる。
// 保存するなら
// [Save][Cancel] ファイル名未定ならダイアログ表示
if( edit_.getDoc().isModified() )
{
int answer = MsgBox(
String(IDS_ASKTOSAVE).c_str(),
String(IDS_APPNAME).c_str(),
MB_YESNOCANCEL|MB_ICONQUESTION
);
if( answer == IDYES ) return Save_showDlgIfNeeded();
if( answer == IDCANCEL ) return false;
}
return true;
}
bool GreenPadWnd::Save()
{
TextFileW tf( charSets_[csi_].ID, lb_ );
if( tf.Open( filename_.c_str() ) )
{
// 無事ファイルに保存できた場合
edit_.getDoc().SaveFile( tf );
UpdateWindowName();
// [最近使ったファイル]更新
cfg_.AddMRU( filename_ );
HWND wnd = NULL;
while( NULL!=(wnd=::FindWindowEx( NULL, wnd, className_, NULL )) )
SendMessage( wnd, GPM_MRUCHANGED, 0, 0 );
return true;
}
// Error!
MsgBox( String(IDS_SAVEERROR).c_str() );
return false;
}
//-------------------------------------------------------------------------
// メインウインドウの初期化
//-------------------------------------------------------------------------
GreenPadWnd::ClsName GreenPadWnd::className_ = TEXT("GreenPad MainWnd");
GreenPadWnd::GreenPadWnd()
: WndImpl ( className_, WS_OVERLAPPEDWINDOW, WS_EX_ACCEPTFILES )
, charSets_( cfg_.GetCharSetList() )
, csi_ ( cfg_.GetNewfileCsi() )
, lb_ ( cfg_.GetNewfileLB() )
, search_ ( *this, edit_ )
{
LOGGER( "GreenPadWnd::Construct begin" );
static WNDCLASSEX wc;
wc.hIcon = app().LoadIcon( IDR_MAIN );
wc.hCursor = app().LoadOemCursor( IDC_ARROW );
wc.lpszMenuName = MAKEINTRESOURCE( IDR_MAIN );
wc.lpszClassName = className_;
WndImpl::Register( &wc );
ime().EnableGlobalIME( true );
LOGGER( "GreenPadWnd::Construct end" );
}
void GreenPadWnd::on_create( CREATESTRUCT* cs )
{
LOGGER("GreenPadWnd::on_create begin");
accel_ = app().LoadAccel( IDR_MAIN );
stb_.Create( hwnd() );
edit_.Create( NULL, hwnd(), 0, 0, 100, 100 );
LOGGER("GreenPadWnd::on_create edit created");
edit_.getDoc().AddHandler( this );
edit_.getCursor().AddHandler( this );
stb_.SetStatusBarVisible( cfg_.showStatusBar() );
LOGGER("GreenPadWnd::on_create halfway");
search_.LoadFromINI( cfg_.getImpl() );
SetupSubMenu();
SetupMRUMenu();
LOGGER("GreenPadWnd::on_create menu");
}
bool GreenPadWnd::StartUp( const Path& fn, int cs, int ln )
{
LOGGER( "GreenPadWnd::StartUp begin" );
Create( 0, 0, cfg_.GetWndX(), cfg_.GetWndY(), cfg_.GetWndW(), cfg_.GetWndH(), 0 );
LOGGER( "GreenPadWnd::Created" );
if( fn.len()==0 || !OpenByMyself( fn, cs ) )
{
LOGGER( "for new file..." );
// ファイルを開か(け)なかった場合
ReloadConfig( fn.len()==0 );
LOGGER( "GreenPadWnd::StartUp reloadconfig end" );
UpdateWindowName();
LOGGER( "GreenPadWnd::StartUp updatewindowname end" );
}
// 指定の行へジャンプ
if( ln != -1 )
JumpToLine( ln );
LOGGER( "GreenPadWnd::StartUp end" );
return true;
}
void GreenPadWnd::ShowUp2()
{
Window::ShowUp( cfg_.GetWndM() ? SW_MAXIMIZE : SW_SHOW );
}
//-------------------------------------------------------------------------
// スタートアップルーチン
// コマンドラインの解析を行う
//-------------------------------------------------------------------------
int kmain()
{
LOGGER( "kmain() begin" );
Argv arg;
ulong i;
LOGGER( "argv processed" );
//-- まずオプションスイッチを処理
int optL = -1;
int optC = 0;
for( i=1; i<arg.size() && arg[i][0]==TEXT('-'); ++i )
switch( arg[i][1] )
{
case TEXT('c'):
optC = String::GetInt( arg[i]+2 );
break;
case TEXT('l'):
optL = String::GetInt( arg[i]+2 );
break;
}
LOGGER( "option processed" );
//-- 次にファイル名
Path file;
if( i < arg.size() )
{
file = arg[i];
if( !file.isFile() )
{
ulong j; // ""無しで半スペ入りでもそれなりに対処
for( j=i+1; j<arg.size(); ++j )
{
file += ' ';
file += arg[j];
if( file.isFile() )
break;
}
if( j==arg.size() )
file = arg[i];
else
i=j;
}
}
LOGGER( "filename processed" );
//-- 余ってる引数があれば、それで新規プロセス起動
if( ++i < arg.size() )
{
String cmd;
for( ; i<arg.size(); ++i )
{
cmd += TEXT('\"');
cmd += arg[i];
cmd += TEXT("\" ");
}
::BootNewProcess( cmd.c_str() );
}
LOGGER( "newprocess booted" );
//-- メインウインドウ発進
GreenPadWnd wnd;
if( !wnd.StartUp(file,optC,optL) )
return -1;
LOGGER( "kmain() startup ok" );
//-- メインループ
wnd.ShowUp2();
LOGGER( "showup!" );
wnd.MsgLoop();
LOGGER( "fin" );
return 0;
}