unit main; //{$DEFINE DEBUG} interface uses Windows, Messages, SysUtils, Classes, Forms, Dialogs, Menus, Grids, StdCtrls, Controls, Buttons, ExtCtrls, uEdit; type TForm1 = class(TForm) MainMenu1: TMainMenu; mniFile: TMenuItem; mniFile_New: TMenuItem; mniFile_Open: TMenuItem; mniFile_Save: TMenuItem; mniFile_SaveAs: TMenuItem; mniFile_Line1: TMenuItem; mniHelp_FileVersion: TMenuItem; mniFile_Line2: TMenuItem; mniFile_Exit: TMenuItem; mniEdit: TMenuItem; mniEdit_Undo: TMenuItem; mniEdit_Redo: TMenuItem; mniEdit_Line1: TMenuItem; mniEdit_Cut: TMenuItem; mniEdit_Copy: TMenuItem; mniEdit_Paste: TMenuItem; mniEdit_Delete: TMenuItem; mniEdit_Line2: TMenuItem; mniEdit_SelectAll: TMenuItem; mniEdit_Line3: TMenuItem; mniEdit_FindBackward: TMenuItem; mniEdit_FindForward: TMenuItem; mniEdit_FindWord: TMenuItem; mniEdit_FindIgnoreCase: TMenuItem; mniEdit_Line4: TMenuItem; mniEdit_ReadOnly: TMenuItem; mniDisp: TMenuItem; mniDisp_WordWrap: TMenuItem; mniDisp_LineHeight: TMenuItem; mniDisp_Tab: TMenuItem; mniDisp_Tab_1: TMenuItem; mniDisp_Tab_2: TMenuItem; mniDisp_Tab_4: TMenuItem; mniDisp_Tab_8: TMenuItem; mniDisp_Line1: TMenuItem; mniDisp_Font: TMenuItem; PopupMenu1: TPopupMenu; mniPEdit_Undo: TMenuItem; mniPEdit_Redo: TMenuItem; mniPLine_1: TMenuItem; mniPEdit_Cut: TMenuItem; mniPEdit_Copy: TMenuItem; mniPEdit_Paste: TMenuItem; mniPEdit_Delete: TMenuItem; mniPLine_2: TMenuItem; mniPEdit_SelectAll: TMenuItem; mniPLine_3: TMenuItem; mniPEdit_SelFindForward: TMenuItem; mniPEdit_SelFindBackward: TMenuItem; mniPLine_4: TMenuItem; mniPEdit_Tab: TMenuItem; mniPEdit_CtrlTab: TMenuItem; mniPEdit_CtrlF: TMenuItem; pnlTop: TPanel; lblFind: TLabel; DrawGrid_FindEdit: TDrawGrid; btnEdit_FindForward: TSpeedButton; btnEdit_FindBackward: TSpeedButton; DrawGrid_Memo: TDrawGrid; FontDialog1: TFontDialog; procedure FormCreate (Sender: TObject); procedure FormDestroy(Sender: TObject); procedure FormClose (Sender: TObject; var Action: TCloseAction); procedure FormResize (Sender: TObject); procedure PopupMenu1Popup (Sender: TObject); procedure mniFile_NewClick (Sender: TObject); procedure mniFile_OpenClick (Sender: TObject); procedure mniFile_SaveAsClick (Sender: TObject); procedure mniFile_SaveClick (Sender: TObject); procedure mniFile_ExitClick (Sender: TObject); procedure mniEdit_UndoClick (Sender: TObject); procedure mniEdit_RedoClick (Sender: TObject); procedure mniEdit_CutClick (Sender: TObject); procedure mniEdit_CopyClick (Sender: TObject); procedure mniEdit_PasteClick (Sender: TObject); procedure mniEdit_DeleteClick (Sender: TObject); procedure mniEdit_SelectAllClick (Sender: TObject); procedure mniEdit_FindForwardClick (Sender: TObject); procedure mniEdit_FindWordClick (Sender: TObject); procedure mniEdit_FindIgnoreCaseClick (Sender: TObject); procedure mniEdit_ReadOnlyClick (Sender: TObject); procedure mniPEdit_TabClick (Sender: TObject); procedure mniPEdit_CtrlFClick (Sender: TObject); procedure mniDisp_WordWrapClick (Sender: TObject); procedure mniDisp_Tab_8Click (Sender: TObject); procedure mniDisp_LineHeightClick (Sender: TObject); procedure mniDisp_FontClick (Sender: TObject); procedure mniHelp_AboutClick (Sender: TObject); procedure mniPEdit_SelFindForwardClick(Sender: TObject); procedure mniPEdit_CtrlTabClick (Sender: TObject); procedure DrawGrid_MemoEnter (Sender: TObject); private { Private 宣言 } FMemo : TMyMemoControl; FEdit : TMyEditControl; FsFileName : WideString; function FGetFocusEdit: TMyCustomEditControl; function FConfirmSave: Boolean; procedure FOpenFile(sFile: WideString); procedure WMDropFiles (var Msg: TWMDropFiles); message WM_DROPFILES; procedure WMMouseActivate(var Msg: TWMMOUSEACTIVATE); message WM_MOUSEACTIVATE; protected procedure WndProc(var Msg: TMessage); override; public { Public 宣言 } end; var Form1: TForm1; //実行ファイル名 G_sAppExeName: WideString; implementation uses {$IFDEF DEBUG} myDebug, {$ENDIF} Clipbrd, RichEdit, ShellAPI, general; {$R *.dfm} //ドラッグアンドドロップ procedure TForm1.WMDropFiles(var Msg: TWMDropFiles); var li_Len: Integer; lp_Buff: PWideChar; begin DragAcceptFiles(Handle, False); li_Len := DragQueryFileW(Msg.Drop, 0, nil, 0); lp_Buff := AllocMem((li_Len + 1) * 2); try DragQueryFileW(Msg.Drop, 0, lp_Buff, li_Len + 1); FOpenFile(WideString(lp_Buff)); finally FreeMem(lp_Buff); end; DragFinish(Msg.Drop); //処理終了 DragAcceptFiles(Handle, True); end; procedure TForm1.WMMouseActivate(var Msg: TWMMOUSEACTIVATE); //マウスでエディットコントロールをクリックしてもVCLのTabStopのインデックスは変わらないことへの対処 var lpt_Pos: TPoint; lh_Wnd: HWND; begin //クリックしたのが作成したエディットコントロールであれば //まずDrawGridに(VCLの)SetFocusを行ってTabStopのインデックスを整える //そのあと作成したエディットコントロールにフォーカスを移す lpt_Pos := Point(0, 0); GetCursorPos(lpt_Pos); lh_Wnd := WindowFromPoint(lpt_Pos); if (lh_Wnd = FEdit.Handle) then begin DrawGrid_FindEdit.SetFocus; DrawGrid_MemoEnter(DrawGrid_FindEdit); end else if (lh_Wnd = FMemo.Handle) then begin DrawGrid_Memo.SetFocus; DrawGrid_MemoEnter(DrawGrid_Memo); end else begin DrawGrid_Memo.TabOrder end; end; //VCLのTabStopの調整 procedure TForm1.DrawGrid_MemoEnter(Sender: TObject); //http://d.hatena.ne.jp/senna_hpp/20060718/p2 begin if (Sender = DrawGrid_Memo) then begin FMemo.SetFocus; end else if (Sender = DrawGrid_FindEdit) then begin FEdit.SetFocus; // PostMessageW(F_Edit.Handle, EM_SETSEL, 0, -1); end; end; //============================================================================== procedure TForm1.FormCreate(Sender: TObject); function _ParamGet: WideString; //Unicode対応のコマンドライン引数の取得 var li_Count: Integer; lpp_Arg, lpp_Param: PPWideChar; begin Result := ''; lpp_Param := CommandLineToArgvW(GetCommandLineW, li_Count); try lpp_Arg := lpp_Param; G_sAppExeName := WideString(lpp_Arg^); //実行ファイル名 if (li_Count >= 2) then begin Inc(lpp_Arg); Result := WideString(lpp_Arg^); //最初の引数だけ取得 end; finally LocalFree(Cardinal(lpp_Param)); end; end; begin Application.Title := PAnsiChar(PWideChar(WideString('春香'))) + #$FF#0#0; DrawGrid_Memo.Align := alClient; FEdit := TMyEditControl.Create(DrawGrid_FindEdit); FEdit.SetBounds(0, 2, FEdit.Width, FEdit.Height -2); FMemo := TMyMemoControl.Create(DrawGrid_Memo); FMemo.HideSelection := False; FMemo.AutoFont := False; FMemo.SetFocus; FsFileName := _ParamGet; if (FsFileName <> '') then begin //ショートカットにドロップされたファイルの処理 FOpenFile(FsFileName); end; //ドラッグアンドドロップの受け入れ DragAcceptFiles(Handle, True); end; procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); begin if not(FConfirmSave) then begin Action := caNone; end; end; procedure TForm1.FormDestroy(Sender: TObject); begin //終了処理 FMemo.Free; FEdit.Free; end; procedure TForm1.FormResize(Sender: TObject); begin //メモのサイズをフォームのクライアントに合わせる FMemo.SetBounds(0, 0, DrawGrid_Memo.ClientWidth, DrawGrid_Memo.ClientHeight); end; function TForm1.FConfirmSave: Boolean; var li_Sel: Word; begin //文書が変更されていて、確認ダイアログでキャンセルを押さなければTrueを返す Result := True; if (FMemo.Modified) then begin Beep; li_Sel := MessageDlg('文書が変更されています。保存しますか', mtCustom, mbYesNoCancel, 0); Result := li_Sel <> mrCancel; if (li_Sel = mrYes) then begin mniFile_SaveAsClick(nil); end; end; end; procedure TForm1.FOpenFile(sFile: WideString); begin FsFileName := sFile; FMemo.LoadFromFile(FsFileName); FMemo.SetFocus; //フォームのタイトルバーにファイル名をセット Caption := gfnsFileNameGet(FsFileName); // Application.Title := ''; // Application.Title := PAnsiChar(gfnsFileNameGet(FsFileName)) + #0#0; // SetWindowTextW(Application.Handle, PWideChar(gfnsFileNameGet(FsFileName)); SetWindowTextA(Application.Handle, PAnsiChar(PWideChar(gfnsFileNameGet(FsFileName)))); end; //新規作成 procedure TForm1.mniFile_NewClick(Sender: TObject); begin if (FConfirmSave) then begin Form1.FsFileName := ''; Form1.FMemo.Text := ''; Caption := ''; end; end; //開く procedure TForm1.mniFile_OpenClick(Sender: TObject); var ls_File: WideString; begin if (FConfirmSave) then begin ls_File := ''; if (gfnbOpenFileDialog(ls_File)) then begin FsFileName := ls_File; FOpenFile(FsFileName); end; end; end; //上書き保存 procedure TForm1.mniFile_SaveClick(Sender: TObject); begin if (FsFileName = '') then begin //新規作成でファイル名がなければダイアログを出す mniFile_SaveAsClick(Sender); end else begin FMemo.SaveToFile(FsFileName); end; end; //名前をつけて保存 procedure TForm1.mniFile_SaveAsClick(Sender: TObject); var ls_File: WideString; begin ls_File := FsFileName; if (gfnbSaveFileDialog(ls_File)) then begin //保存 FsFileName := ls_File; mniFile_SaveClick(nil); end; end; //終了 procedure TForm1.mniFile_ExitClick(Sender: TObject); begin Close; end; // 編集 ------------------------------------------------------------------------ //現在フォーカスのあるエディットを返す function TForm1.FGetFocusEdit: TMyCustomEditControl; begin if (FEdit.Focused) then begin Result := FEdit; end else if (FMemo.Focused) then begin Result := FMemo; end else begin Result := FMemo; end; end; //メインメニュー //http://www2.big.or.jp/~osamu/Delphi/Tips/key.cgi?key=29#0066.txt procedure TForm1.WndProc(var Msg: TMessage); begin if (Msg.Msg = WM_INITMENU) and (Msg.WParam = WPARAM(Menu.Handle)) then begin PopupMenu1Popup(nil); end; inherited WndProc(Msg); end; //状況に応じたメニューの変更 procedure TForm1.PopupMenu1Popup(Sender: TObject); var l_Edit: TMyCustomEditControl; begin l_Edit := FGetFocusEdit; if (l_Edit = nil) then begin l_Edit := FMemo; //AIU end; mniEdit_Undo.Enabled := l_Edit.CanUndo; mniEdit_Redo.Enabled := l_Edit.CanRedo; if (l_Edit = FMemo) and (FMemo.ReadOnly) then begin mniEdit_Undo.Enabled := False; mniEdit_Redo.Enabled := False; end; mniPEdit_Undo.Enabled := mniEdit_Undo.Enabled; mniPEdit_Redo.Enabled := mniEdit_Redo.Enabled; //すべて選択 mniEdit_SelectAll.Enabled := SendMessageW(l_Edit.Handle, EM_GETLINECOUNT, 0, 0) > 0; mniPEdit_SelectAll.Enabled := mniEdit_SelectAll.Enabled; mniEdit_Copy.Enabled := l_Edit.Selected; mniPEdit_Copy.Enabled := mniEdit_Copy.Enabled; mniEdit_Cut.Enabled := l_Edit.Selected; if (l_Edit = FMemo) and (FMemo.ReadOnly) then begin mniEdit_Cut.Enabled := False; end; mniPEdit_Cut.Enabled := mniEdit_Cut.Enabled; mniEdit_Delete.Enabled := mniEdit_Cut.Enabled; mniPEdit_Delete.Enabled := mniEdit_Cut.Enabled; mniEdit_Paste.Enabled := SendMessageW(l_Edit.Handle, EM_CANPASTE, WPARAM(CF_TEXT), 0) <> 0; mniPEdit_Paste.Enabled := mniEdit_Paste.Enabled; mniEdit_FindForward.Enabled := (FEdit.Text <> '') or (FMemo.Selected); mniEdit_FindBackward.Enabled := mniEdit_FindForward.Enabled; mniPEdit_SelFindForward.Enabled := FMemo.Selected; mniPEdit_SelFindBackward.Enabled := mniPEdit_SelFindForward.Enabled; end; //元に戻す procedure TForm1.mniEdit_UndoClick(Sender: TObject); begin if (FGetFocusEdit <> nil) then begin FGetFocusEdit.Undo; end; end; //やり直し procedure TForm1.mniEdit_RedoClick(Sender: TObject); begin if (FGetFocusEdit <> nil) then begin FGetFocusEdit.Redo; end; end; //切り取り procedure TForm1.mniEdit_CutClick(Sender: TObject); begin if (FGetFocusEdit <> nil) then begin FGetFocusEdit.CutToClipboard; end; end; //コピー procedure TForm1.mniEdit_CopyClick(Sender: TObject); begin if (FGetFocusEdit <> nil) then begin FGetFocusEdit.CopyToClipboard; end; end; //貼り付け procedure TForm1.mniEdit_PasteClick(Sender: TObject); begin if (FGetFocusEdit <> nil) then begin FGetFocusEdit.PasteFromClipboard; end; end; //削除 procedure TForm1.mniEdit_DeleteClick(Sender: TObject); begin if (FGetFocusEdit <> nil) then begin FGetFocusEdit.ClearSelection; end; end; //全て選択 procedure TForm1.mniEdit_SelectAllClick(Sender: TObject); begin if (FGetFocusEdit <> nil) then begin FGetFocusEdit.SelectAll; end; end; //書込み禁止 procedure TForm1.mniEdit_ReadOnlyClick(Sender: TObject); begin FMemo.ReadOnly := mniEdit_ReadOnly.Checked; end; //検索 procedure TForm1.mniEdit_FindForwardClick(Sender: TObject); begin //FMemoのHideSelectionをFalseにした場合↓が必要 { if not(FMemo.Focused) then begin DrawGrid1Enter(DrawGrid1); end; } FMemo.FindForward := (Sender = mniEdit_FindForward) or (Sender = mniPEdit_SelFindForward) or (Sender = btnEdit_FindForward); if (FEdit.Text = '') and (FMemo.Selected) then begin FEdit.Text := FMemo.SelText; end; FMemo.Find(FEdit.Text); end; //選択範囲を検索 procedure TForm1.mniPEdit_SelFindForwardClick(Sender: TObject); begin FEdit.Text := FMemo.SelText; mniEdit_FindForwardClick(Sender); end; //単語検索オプション procedure TForm1.mniEdit_FindWordClick(Sender: TObject); begin FMemo.FindWholeWord := mniEdit_FindWord.Checked; end; //大小文字の区別 procedure TForm1.mniEdit_FindIgnoreCaseClick(Sender: TObject); begin FMemo.FindIgnoreCase := mniEdit_FindIgnoreCase.Checked; end; //Tabの入力 procedure TForm1.mniPEdit_TabClick(Sender: TObject); begin if (FGetFocusEdit <> nil) then begin FGetFocusEdit.Insert(#9); end; end; //コントロールの移動 procedure TForm1.mniPEdit_CtrlTabClick(Sender: TObject); begin if (FEdit.Focused) then begin FMemo.SetFocus; end else if (FMemo.Focused) then begin FEdit.SetFocus; end; end; //検索欄へフォーカス procedure TForm1.mniPEdit_CtrlFClick(Sender: TObject); begin if (FEdit.Focused) then begin FMemo.SetFocus; end else if (FMemo.Focused) then begin FEdit.SetFocus; end; end; //------------------------------------------------------------------------------ //表示 //右端で折り返す procedure TForm1.mniDisp_WordWrapClick(Sender: TObject); begin FMemo.WordWrap := mniDisp_WordWrap.Checked; // FormResize(nil); end; //行間を詰める procedure TForm1.mniDisp_LineHeightClick(Sender: TObject); begin FMemo.LineHeight := not(mniDisp_LineHeight.Checked); // FormResize(nil); end; //タブ間隔 procedure TForm1.mniDisp_Tab_8Click(Sender: TObject); begin FMemo.Tabs := TMenuItem(Sender).Tag; end; //フォント選択 procedure TForm1.mniDisp_FontClick(Sender: TObject); begin FontDialog1.Font := FMemo.Font; if (FontDialog1.Execute) then begin FMemo.Font := FontDialog1.Font; end; end; //ヘルプ procedure TForm1.mniHelp_AboutClick(Sender: TObject); begin gfniMessageBox(WideFormat('%s Ver:%s'#13#13'Ctrl+F:検索ボックスと本文とのフォーカス移動', [Application.Title, gfnsFileVersionGet]), 'バージョン情報', 0); end; end.