Annotation of OpenXM_contrib2/windows/asir32gui/asir32guiview.cpp, Revision 1.9
1.1 noro 1: // asir32guiView.cpp : CAsir32guiView クラスの動作の定義を行います。
2: //
3:
4: #include "stdafx.h"
5:
6: #include "asir32gui.h"
7: #include "asir32guiDoc.h"
8: #include "asir32guiView.h"
9: #include "FatalDialog.h"
1.3 noro 10: #include <direct.h>
1.6 noro 11: #include <io.h>
1.1 noro 12:
13: #ifdef _DEBUG
14: #define new DEBUG_NEW
15: #undef THIS_FILE
16: static char THIS_FILE[] = __FILE__;
17: #endif
18:
1.5 noro 19: // const TextBufferSize = 32768;
20: const TextBufferSize = 16384;
1.1 noro 21:
22: CAsir32guiView *theView;
23:
24: extern "C"
25: {
26: char *prev_hist(void), *next_hist(void), *search_hist(char *p);
27: void read_input_history(),write_input_history();
28: void init_input_history();
29: void add_hist(char *p), reset_traverse(void);
30: void asir_terminate(void);
31: void Main(int,char*[]);
32: void loadfile(char *);
33: void put_line(char *);
34: void send_intr(void);
35: void insert_to_theView(char *);
36: void get_rootdir(char *,int,char *);
37: extern int bigfloat, prtime, prresult;
38: extern char *asir_libdir;
1.2 noro 39: extern int asirgui_kind;
1.1 noro 40:
41: void insert_to_theView(char *str)
42: {
43: (void)theView->Insert(str);
44: }
45: void flush_log()
46: {
47: if ( theView->Logging )
48: theView->OnFileLog();
49: }
50: }
51:
52: /////////////////////////////////////////////////////////////////////////////
53: // CAsir32guiView
54:
55: IMPLEMENT_DYNCREATE(CAsir32guiView, CEditView)
56:
57: BEGIN_MESSAGE_MAP(CAsir32guiView, CEditView)
58: //{{AFX_MSG_MAP(CAsir32guiView)
59: ON_WM_KEYDOWN()
60: ON_WM_CHAR()
61: ON_WM_LBUTTONUP()
62: ON_WM_RBUTTONDOWN()
63: ON_COMMAND(ID_FILE_OPEN, OnFileOpen)
64: ON_COMMAND(ID_FILE_LOG, OnFileLog)
65: ON_COMMAND(ID_ASIRHELP, OnAsirhelp)
66: ON_UPDATE_COMMAND_UI(ID_FILE_LOG, OnUpdateFileLog)
67: ON_COMMAND(ID_EDIT_PASTE, OnEditPaste)
1.3 noro 68: ON_COMMAND(IDR_FONT, OnFont)
69: ON_WM_CREATE()
1.6 noro 70: ON_COMMAND(ID_CONTRIBHELP, OnContribhelp)
71: ON_UPDATE_COMMAND_UI(ID_CONTRIBHELP, OnUpdateContribhelp)
1.9 ! noro 72: ON_WM_SIZE()
1.1 noro 73: //}}AFX_MSG_MAP
74: // 標準印刷コマンド
75: // ON_COMMAND(ID_FILE_PRINT, CEditView::OnFilePrint)
76: // ON_COMMAND(ID_FILE_PRINT_DIRECT, CEditView::OnFilePrint)
77: // ON_COMMAND(ID_FILE_PRINT_PREVIEW, CEditView::OnFilePrintPreview)
78: END_MESSAGE_MAP()
79:
80: /////////////////////////////////////////////////////////////////////////////
81: // CAsir32guiView クラスの構築/消滅
82:
83: CAsir32guiView::CAsir32guiView()
84: {
85: // TODO: この場所に構築用のコードを追加してください。
86: static int tmpView_created = 0;
87: char errmsg[BUFSIZ];
88:
89: init_input_history();
90: read_input_history();
91: DebugMode = 0;
92: DebugInMain = 0;
1.9 ! noro 93: // MaxLineLength = 80;
1.1 noro 94: LogStart = 0;
95: Logging = 0;
96: Logfp = NULL;
97: ResetIndex();
98: theView = this;
99: }
100:
101: CAsir32guiView::~CAsir32guiView()
102: {
103: write_input_history();
104: }
105:
106: BOOL CAsir32guiView::PreCreateWindow(CREATESTRUCT& cs)
107: {
108: // TODO: この位置で CREATESTRUCT cs を修正して Window クラスまたはスタイルを
109: // 修正してください。
110:
111: m_dwDefaultStyle = dwStyleDefault & ~ES_AUTOHSCROLL ;
112: m_dwDefaultStyle &= ~WS_HSCROLL;
113: return CCtrlView::PreCreateWindow(cs);
114: }
115:
116: /////////////////////////////////////////////////////////////////////////////
117: // CAsir32guiView クラスの描画
118:
119: void CAsir32guiView::OnDraw(CDC* pDC)
120: {
121: CAsir32guiDoc* pDoc = GetDocument();
122: ASSERT_VALID(pDoc);
123:
124: // TODO: この場所にネイティブ データ用の描画コードを追加します。
125: }
126:
127: /////////////////////////////////////////////////////////////////////////////
128: // CAsir32guiView クラスの印刷
129:
130: BOOL CAsir32guiView::OnPreparePrinting(CPrintInfo* pInfo)
131: {
132: // デフォルトの印刷準備
133: return DoPreparePrinting(pInfo);
134: }
135:
136: void CAsir32guiView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
137: {
138: // TODO: 印刷前の特別な初期化処理を追加してください。
139: }
140:
141: void CAsir32guiView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
142: {
143: // TODO: 印刷後の後処理を追加してください。
144: }
145:
146: /////////////////////////////////////////////////////////////////////////////
147: // CAsir32guiView クラスの診断
148:
149: #ifdef _DEBUG
150: void CAsir32guiView::AssertValid() const
151: {
152: CEditView::AssertValid();
153: }
154:
155: void CAsir32guiView::Dump(CDumpContext& dc) const
156: {
157: CEditView::Dump(dc);
158: }
159:
160: CAsir32guiDoc* CAsir32guiView::GetDocument() // 非デバッグ バージョンはインラインです。
161: {
162: ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CAsir32guiDoc)));
163: return (CAsir32guiDoc*)m_pDocument;
164: }
165: #endif //_DEBUG
166:
167: /////////////////////////////////////////////////////////////////////////////
168: // CAsir32guiView クラスのメッセージ ハンドラ
169:
170: void CAsir32guiView::PutChar(int c)
171: {
1.8 noro 172: int i,len;
1.1 noro 173: char buf[2];
174:
1.8 noro 175: if ( EndPos >= sizeof(Buffer)-1 ) {
176: Beep(); return;
177: }
1.1 noro 178: for ( i = EndPos-1; i >= CurrentPos; i-- )
1.8 noro 179: Buffer[i+1] = Buffer[i];
1.1 noro 180: Buffer[CurrentPos] = (char)c;
1.8 noro 181: // buf[0] = (char)c; buf[1] = 0;
182: // Insert(buf,FALSE);
183: len = GetWindowTextLength();
184: if ( len+1 >= TextBufferSize )
185: DeleteTop();
186: CEditView::OnChar(c, 1, 0);
1.1 noro 187: CurrentPos++;
188: EndPos++;
189: }
190:
191: void CAsir32guiView::DeleteChar(int count) {
192: int i,s,e;
193: char null = 0;
194:
195: if ( count > (EndPos-CurrentPos) )
196: count = EndPos - CurrentPos;
197: if ( count == 0 )
198: Beep();
199: else {
200: EndPos -= count;
201: for ( i = CurrentPos; i < EndPos; i++ )
202: Buffer[i] = Buffer[i+count];
203: GetEditCtrl().GetSel(s,e);
204: GetEditCtrl().SetSel(s,s+count);
205: GetEditCtrl().ReplaceSel(&null);
206: }
207: }
208:
209: void CAsir32guiView::Insert(char *buf,BOOL wrap)
210: {
211: char t[BUFSIZ*4];
212: char *p,*q,c;
213: int len;
214: int i;
215:
216: if ( wrap ) {
217: i = GetEditCtrl().LineLength(-1);
218: for ( p = t, q = buf; (c = *p++ = *q++) != 0; )
219: if ( c == '\r' ) {
220: *p++ = *q++; i = 0;
221: } else if ( (*q != '\r') && (++i == MaxLineLength) ) {
222: *p++ = '\r'; *p++ = '\r'; *p++ = '\n'; i = 0;
223: }
224: p = t;
225: } else
226: p = buf;
227: len = GetWindowTextLength();
228: if ( strlen(p) + len >= TextBufferSize )
229: DeleteTop();
230: GetEditCtrl().ReplaceSel(p);
231: }
232:
233: void CAsir32guiView::DeleteTop()
234: {
235: const char *p,*q;
236: const char *buf;
237: char null = 0;
238: int len,len0,len1;
239:
240: buf = LockBuffer();
241: len0 = len = strlen(buf);
242: for ( p = buf; len >= TextBufferSize/2; ) {
243: q = strchr(p,'\n');
244: if ( !q ) {
245: len = 0; break;
246: } else {
247: q++; len -= (q-p); p = q;
248: }
249: }
250: if ( Logging ) {
1.4 noro 251: if ( len < LogStart )
252: LogStart -= len;
253: else {
254: fwrite(buf+LogStart,1,len-LogStart,Logfp);
255: LogStart = 0;
256: }
1.1 noro 257: }
258: UnlockBuffer();
259: if ( q ) {
260: GetEditCtrl().SetSel(0,len);
261: GetEditCtrl().ReplaceSel(&null);
262: }
263: UpdateCursor(EndPos);
264: }
265:
266: void CAsir32guiView::UpdateCursor(int pos)
267: {
268: int s;
269: int len;
270:
271: if ( pos < 0 || pos > EndPos )
272: Beep();
273: else {
274: len = GetWindowTextLength();
275: CurrentPos = pos;
276: s = len-EndPos+CurrentPos;
277: GetEditCtrl().SetSel(s,s);
278: }
279: }
280:
281: void CAsir32guiView::ReplaceString(char *str)
282: {
283: UpdateCursor(0); DeleteChar(EndPos);
284: Insert(str,FALSE);
285: strcpy(Buffer,str);
286: EndPos = CurrentPos = strlen(str);
287: }
288:
289: void CAsir32guiView::Beep(void) {
290: ::MessageBeep(0xffffffff);
291: }
292:
293: void CAsir32guiView::Paste(void) {
1.8 noro 294: char buf[2*BUFSIZ];
295: const char *src;
296: char c;
297: int i,j,l;
298: HGLOBAL hClip;
299:
300: if ( asirgui_kind == ASIRGUI_MESSAGE ) {
301: Beep(); return;
302: }
1.2 noro 303:
1.8 noro 304: if ( OpenClipboard() == FALSE ) {
305: Beep(); return;
1.1 noro 306: }
307: hClip = GetClipboardData(CF_TEXT);
308: src = (const char *)::GlobalLock(hClip);
1.8 noro 309: if ( !src || (l = strlen(src)) >= sizeof(Buffer) ) {
1.1 noro 310: ::CloseClipboard();
311: Beep(); return;
312: }
1.8 noro 313: for ( i = j = 0; i < l; i++ )
314: if ( (c = src[i]) != '\n' && c != '\r' )
315: buf[j++] = c;
316: buf[j] = 0;
1.1 noro 317: ::GlobalUnlock(hClip);
318: ::CloseClipboard();
1.8 noro 319: if ( EndPos+j >= sizeof(Buffer)-1 ) {
320: Beep(); return;
321: }
1.1 noro 322: GetEditCtrl().ReplaceSel(buf);
1.8 noro 323: strncpy(Buffer+EndPos,buf,j);
324: EndPos += j; CurrentPos = EndPos;
1.1 noro 325: }
326:
327: #define CTRL(c) (c)&0x1f
328:
329: void CAsir32guiView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
330: {
331: // TODO: この位置にメッセージ ハンドラ用のコードを追加するかまたはデフォルトの処理を呼び出してください
332: char *exp_result;
333:
334: switch ( nChar ) {
335: case VK_LEFT:
336: UpdateCursor(CurrentPos-1); return;
337: case VK_RIGHT:
338: UpdateCursor(CurrentPos+1); return;
339: case VK_DELETE:
340: DeleteChar(1); return;
341: case VK_UP:
342: if ( (exp_result = prev_hist()) != 0 )
343: ReplaceString(exp_result);
344: else
345: Beep();
346: return;
347: case VK_DOWN:
348: if ( (exp_result = next_hist()) != 0 )
349: ReplaceString(exp_result);
350: else
351: Beep();
352: return;
353: default:
354: break;
355: }
356: CEditView::OnKeyDown(nChar, nRepCnt, nFlags);
357: }
358:
359: void CAsir32guiView::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
360: {
361: // TODO: この位置にメッセージ ハンドラ用のコードを追加するかまたはデフォルトの処理を呼び出してください
362: char *exp_result;
363:
1.2 noro 364: if ( asirgui_kind == ASIRGUI_MESSAGE ) {
365: Beep(); return;
366: }
367:
1.1 noro 368: switch ( nChar ) {
369: case CTRL('M'): case CTRL('J'):
370: UpdateCursor(EndPos);
371: Buffer[EndPos] = 0;
372: reset_traverse();
373: if ( Buffer[0] == '!' ) {
374: exp_result = search_hist(Buffer+1);
375: if ( exp_result )
376: ReplaceString(exp_result);
377: else {
378: UpdateCursor(0); DeleteChar(EndPos); Beep();
379: }
380: return;
381: } else {
382: add_hist(Buffer);
383: put_line(Buffer);
384: ResetIndex();
385: nChar = CTRL('M');
386: }
387: break;
388: case CTRL('N'):
389: if ( (exp_result = next_hist()) != 0 )
390: ReplaceString(exp_result);
391: else
392: Beep();
393: return;
394: case CTRL('P'):
395: if ( (exp_result = prev_hist()) != 0 )
396: ReplaceString(exp_result);
397: else
398: Beep();
399: return;
400: case CTRL('A'):
401: UpdateCursor(0); return;
402: case CTRL('E'):
403: UpdateCursor(EndPos); return;
404: case CTRL('F'):
405: UpdateCursor(CurrentPos+1); return;
406: case CTRL('B'):
407: UpdateCursor(CurrentPos-1); return;
408: case CTRL('K'):
409: DeleteChar(EndPos-CurrentPos); return;
410: case CTRL('U'):
411: UpdateCursor(0); DeleteChar(EndPos); return;
412: case CTRL('D'):
413: DeleteChar(1); return;
414: case CTRL('H'):
415: if ( CurrentPos > 0 ) {
416: UpdateCursor(CurrentPos-1); DeleteChar(1);
417: } else
418: Beep();
419: return;
420: case CTRL('C'):
421: send_intr();
422: /* wake up the engine */
423: put_line("");
424: return;
425: default :
426: if ( nChar >= 0x20 && nChar < 0x7f )
427: PutChar(nChar);
428: else
429: Beep();
430: return;
431: }
432: CEditView::OnChar(nChar, nRepCnt, nFlags);
433: }
434:
435: void CAsir32guiView::OnLButtonUp(UINT nFlags, CPoint point)
436: {
437: // TODO: この位置にメッセージ ハンドラ用のコードを追加するかまたはデフォルトの処理を呼び出してください
438: GetEditCtrl().Copy(); UpdateCursor(EndPos);
439: CEditView::OnLButtonUp(nFlags, point);
440: }
441:
442: void CAsir32guiView::OnRButtonDown(UINT nFlags, CPoint point)
443: {
444: // TODO: この位置にメッセージ ハンドラ用のコードを追加するかまたはデフォルトの処理を呼び出してください
445: Paste();
446:
447: // CEditView::OnRButtonDown(nFlags, point);
448: }
449:
450: void CAsir32guiView::OnFileOpen()
451: {
452: // TODO: この位置にコマンド ハンドラ用のコードを追加してください
453: char cmd[BUFSIZ*2]; // XXX
454: char *p;
1.3 noro 455: static char errmsg[BUFSIZ];
456: static char prevdir[BUFSIZ];
1.1 noro 457:
1.3 noro 458: if ( !prevdir[0] ) {
459: get_rootdir(prevdir,sizeof(prevdir),errmsg);
460: strcat(prevdir,"\\lib");
461: }
462:
463: _chdir(prevdir);
1.1 noro 464: CFileDialog fileDialog(TRUE);
465: if ( fileDialog.DoModal() == IDOK ) {
466: CString pathName = fileDialog.GetPathName();
467: sprintf(cmd,"load(\"%s\");",pathName);
468: for ( p = cmd; *p; p++ )
469: if ( *p == '\\' )
470: *p = '/';
471: put_line(cmd);
1.3 noro 472: p = strrchr(pathName,'\\');
473: if ( p ) {
474: *p = 0;
475: strcpy(prevdir,pathName);
476: }
1.1 noro 477: }
478: }
479:
480: void CAsir32guiView::OnAsirhelp()
481: {
482: // TODO: この位置にコマンド ハンドラ用のコードを追加してください
483: char root[BUFSIZ],errmsg[BUFSIZ],helpfile[BUFSIZ];
484:
485: get_rootdir(root,sizeof(root),errmsg);
486: sprintf(helpfile,"%s\\bin\\asirhelp.chm",root);
487: HtmlHelp(NULL, helpfile, HH_DISPLAY_TOPIC, 0);
488: }
489:
490: void CAsir32guiView::OnFileLog()
491: {
492: // TODO: この位置にコマンド ハンドラ用のコードを追加してください
493: if ( !Logging ) {
494: CFileDialog fileDialog(TRUE);
495: if ( fileDialog.DoModal() == IDOK ) {
496: CString logfile = fileDialog.GetPathName();
497: Logfp = fopen(logfile,"ab");
498: if ( Logfp ) {
499: LogStart = GetWindowTextLength();
500: Logging = 1;
501: }
502: }
503: } else {
504: const char *buf;
505: buf = LockBuffer();
506: fwrite(buf+LogStart,1,strlen(buf)-LogStart,Logfp);
507: UnlockBuffer();
508: fclose(Logfp);
509: Logging = 0;
510: }
511: }
512:
513: void CAsir32guiView::OnUpdateFileLog(CCmdUI* pCmdUI)
514: {
515: // TODO: この位置に command update UI ハンドラ用のコードを追加してください
516: if ( Logging )
517: pCmdUI->SetCheck(1);
518: else
519: pCmdUI->SetCheck(0);
520: }
521:
522: void CAsir32guiView::OnEditPaste()
523: {
524: // TODO: この位置にコマンド ハンドラ用のコードを追加してください
525: Paste();
1.3 noro 526: }
527:
1.9 ! noro 528: void CAsir32guiView::UpdateMetrics()
! 529: {
! 530: TEXTMETRIC tm;
! 531: RECT r;
! 532:
! 533: GetEditCtrl().GetRect(&r);
! 534: CDC *pDC = GetDC();
! 535: pDC->SelectObject(GetFont());
! 536: pDC->GetTextMetrics(&tm);
! 537: MaxLineLength = (r.right-r.left)/tm.tmAveCharWidth-1;
! 538: }
! 539:
1.3 noro 540: void CAsir32guiView::OnFont()
541: {
542: // TODO: この位置にコマンド ハンドラ用のコードを追加してください
543: int ret;
1.9 ! noro 544: LOGFONT lf;
! 545:
! 546: GetFont()->GetLogFont(&lf);
! 547: CFontDialog fd(&lf,CF_EFFECTS | CF_SCREENFONTS | CF_FIXEDPITCHONLY);
1.3 noro 548: static CFont *f = 0;
549:
550: ret = fd.DoModal();
551: if ( ret == IDOK ) {
552: fd.GetCurrentFont(&lf);
553: if ( f )
554: delete f;
555: f = new CFont;
556: f->CreateFontIndirect(&lf);
557: SetFont(f);
1.9 ! noro 558: UpdateMetrics();
1.3 noro 559: }
560: }
561:
562: int CAsir32guiView::OnCreate(LPCREATESTRUCT lpCreateStruct)
563: {
564: if (CEditView::OnCreate(lpCreateStruct) == -1)
565: return -1;
566:
567: // TODO: この位置に固有の作成用コードを追加してください
1.9 ! noro 568:
1.3 noro 569: LOGFONT logFont; memset(&logFont, 0, sizeof(LOGFONT));
570: logFont.lfHeight = 20;
571: logFont.lfCharSet = DEFAULT_CHARSET;
572: strcpy(logFont.lfFaceName, "Terminal");
573: CFont *f = new CFont;
574: f->CreateFontIndirect(&logFont);
575: SetFont(f);
1.9 ! noro 576: UpdateMetrics();
1.3 noro 577: GetEditCtrl().LimitText(nMaxSize);
1.9 ! noro 578: GetEditCtrl().SetTabStops(m_nTabStops);
1.3 noro 579:
580: return 0;
1.6 noro 581: }
582:
583: void CAsir32guiView::OnContribhelp()
584: {
585: // TODO: この位置にコマンド ハンドラ用のコードを追加してください
586: char root[BUFSIZ],errmsg[BUFSIZ],helpfile[BUFSIZ];
587:
588: get_rootdir(root,sizeof(root),errmsg);
589: sprintf(helpfile,"%s\\bin\\cmanhelp.chm",root);
590: HtmlHelp(NULL, helpfile, HH_DISPLAY_TOPIC, 0);
591: }
592:
593: void CAsir32guiView::OnUpdateContribhelp(CCmdUI* pCmdUI)
594: {
595: // TODO: この位置に command update UI ハンドラ用のコードを追加してください
596: char root[BUFSIZ],errmsg[BUFSIZ],helpfile[BUFSIZ];
597:
1.7 noro 598: if ( getenv("OpenXM_WIN_ROOT") ) {
599: get_rootdir(root,sizeof(root),errmsg);
600: sprintf(helpfile,"%s\\bin\\cmanhelp.chm",root);
601: if ( _access(helpfile,04) != -1 ) {
602: pCmdUI->Enable( TRUE );
603: return;
604: }
605: }
606: pCmdUI->Enable( FALSE );
1.9 ! noro 607: }
! 608:
! 609: void CAsir32guiView::OnSize(UINT nType, int cx, int cy)
! 610: {
! 611: CEditView::OnSize(nType, cx, cy);
! 612:
! 613: // TODO: この位置にメッセージ ハンドラ用のコードを追加してください
! 614: UpdateMetrics();
1.1 noro 615: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>