source: trunk/ab5.0/ablib/src/basic/prompt.sbp@ 691

Last change on this file since 691 was 691, checked in by イグトランス (egtra), 15 years ago

プロンプト画面のテキスト描画を、1文字ずつから、同じ色のテキストをまとめて書く方法へ変更。また、一部の制御コードに対応 (NUL, BEL, BS, HT, LF, FF, CR)。

File size: 26.3 KB
Line 
1'prompt.sbp
2
3
4#ifndef _INC_PROMPT
5#define _INC_PROMPT
6
7Namespace ActiveBasic
8Namespace Prompt
9Namespace Detail
10
11Function _PromptSys_GetTextExtentPoint32(hdc As HDC, psz As PCSTR, cb As Long, ByRef Size As SIZE) As Long
12 _PromptSys_GetTextExtentPoint32 = GetTextExtentPoint32A(hdc, psz, cb, Size)
13End Function
14
15Function _PromptSys_GetTextExtentPoint32(hdc As HDC, psz As PCWSTR, cb As Long, ByRef Size As SIZE) As Long
16 _PromptSys_GetTextExtentPoint32 = GetTextExtentPoint32W(hdc, psz, cb, Size)
17End Function
18
19Function _PromptSys_TextOut(hdc As HDC, x As Long, y As Long, psz As PCSTR, cb As Long) As Long
20 _PromptSys_TextOut = TextOutA(hdc, x, y, psz, cb)
21 If _PromptSys_TextOut = 0 Then Debug
22End Function
23
24Function _PromptSys_TextOut(hdc As HDC, x As Long, y As Long, psz As PCWSTR, cb As Long) As Long
25 _PromptSys_TextOut = TextOutW(hdc, x, y, psz, cb)
26End Function
27
28Function _PromptSys_ImmGetCompositionString(himc As HIMC, index As DWord, pBuf As PSTR, bufLen As DWord) As Long
29 _PromptSys_ImmGetCompositionString = ImmGetCompositionStringA(himc, index, pBuf, bufLen)
30End Function
31
32Function _PromptSys_ImmGetCompositionString(himc As HIMC, index As DWord, pBuf As PWSTR, bufLen As DWord) As Long
33 _PromptSys_ImmGetCompositionString = ImmGetCompositionStringW(himc, index, pBuf, bufLen)
34End Function
35
36Dim _PromptSys_hWnd As HWND
37Dim _PromptSys_dwThreadID As DWord
38Dim _PromptSys_hInitFinish As HANDLE
39
40'text
41Type _PromptSys_CharacterInformation
42 ForeColor As COLORREF
43 BackColor As COLORREF
44End Type
45
46Type _PromptSys_LineInformation
47 Length As Long
48 Text As *Char
49 CharInfo As *_PromptSys_CharacterInformation
50End Type
51
52Dim _PromptSys_hFont As HFONT
53Dim _PromptSys_FontSize As SIZE
54Dim _PromptSys_InputStr[255] As Char
55Dim _PromptSys_InputLen = -1 As Long
56Dim _PromptSys_KeyChar As Byte
57Dim _PromptSys_CurPos As POINTAPI
58Dim _PromptSys_TextLine[100] As _PromptSys_LineInformation
59Dim _PromptSys_NowTextColor As COLORREF
60Dim _PromptSys_NowBackColor As COLORREF
61Dim _PromptSys_SectionOfBufferAccess As CRITICAL_SECTION
62
63
64'graphic
65Dim _PromptSys_hBitmap As HBITMAP
66Dim _PromptSys_hMemDC As HDC
67Dim _PromptSys_ScreenSize As SIZE
68Dim _PromptSys_GlobalPos As POINTAPI
69
70Sub _PromptSys_Initialize()
71 _PromptSys_hInitFinish = CreateEvent(0, FALSE, FALSE, 0)
72 Dim _PromptSys_hThread = CreateThread(0, 0, AddressOf(PromptMain), 0, 0, _PromptSys_dwThreadID)
73 If _PromptSys_hThread = 0 Then
74 Debug
75 ExitProcess(1)
76 End If
77 WaitForSingleObject(_PromptSys_hInitFinish, INFINITE)
78End Sub
79
80Sub DrawTextBlock(hdc As HDC, len As Long, p As PCTSTR, ci As *_PromptSys_CharacterInformation)
81 If len = 0 Then
82 Exit Sub
83 End If
84
85 If ci[0].BackColor = -1 Then
86 SetBkMode(hdc, TRANSPARENT)
87 Else
88 SetBkMode(hdc, OPAQUE)
89 SetBkColor(hdc, ci[0].BackColor)
90 End If
91 SetTextColor(hdc, ci[0].ForeColor)
92
93 Dim i As Long
94 For i = 0 To ELM(len)
95 If ci[i].ForeColor <> ci[0].ForeColor Or ci[i].BackColor <> ci[0].BackColor Then
96 TextOut(hdc, 0, 0, p, i)
97 DrawTextBlock(hdc, len - 1, VarPtr(p[i]), VarPtr(ci[i]))
98 Exit Sub
99 End If
100 Next
101 TextOut(hdc, 0, 0, p, i)
102End Sub
103
104Sub DrawPromptBuffer(hDC As HDC, StartLine As Long, EndLine As Long)
105 Dim i As Long
106
107 Dim hOldFont = SelectObject(hDC, _PromptSys_hFont) As HFONT
108
109 'Scroll
110 Dim rc As RECT
111 GetClientRect(_PromptSys_hWnd, rc)
112 While (_PromptSys_CurPos.y+1) * _PromptSys_FontSize.cy > rc.bottom and _PromptSys_CurPos.y > 0
113 _System_free(_PromptSys_TextLine[0].Text)
114 _System_free(_PromptSys_TextLine[0].CharInfo)
115 For i = 0 To 100 - 1
116 _PromptSys_TextLine[i].Length = _PromptSys_TextLine[i+1].Length
117 _PromptSys_TextLine[i].Text = _PromptSys_TextLine[i+1].Text
118 _PromptSys_TextLine[i].CharInfo = _PromptSys_TextLine[i+1].CharInfo
119 Next
120 _PromptSys_TextLine[100].Length = 0
121 _PromptSys_TextLine[100].Text = _System_calloc(SizeOf (Char) * 255)
122 _PromptSys_TextLine[100].CharInfo = _System_calloc(SizeOf (_PromptSys_CharacterInformation) * 255)
123 _PromptSys_CurPos.y--
124
125 'Redraw
126 StartLine = -1
127 Wend
128
129 SetTextAlign(hDC, TA_LEFT Or TA_TOP Or TA_UPDATECP)
130 i = 0
131 While i * _PromptSys_FontSize.cy < rc.bottom And i <= 100
132 If StartLine = -1 Or (StartLine <= i And i <= EndLine) Then
133 With _PromptSys_TextLine[i]
134 BitBlt(hDC,_
135 0, i * _PromptSys_FontSize.cy, _
136 rc.right, _PromptSys_FontSize.cy, _
137 _PromptSys_hMemDC, 0, i * _PromptSys_FontSize.cy, SRCCOPY)
138 MoveToEx(hDC, 0, i * _PromptSys_FontSize.cy, ByVal 0)
139 DrawTextBlock(hDC, .Length, .Text, .CharInfo)
140 End With
141 End If
142 i++
143 Wend
144 SelectObject(hDC, hOldFont)
145End Sub
146
147Sub PRINT_ToPrompt(buf As String)
148 System.Diagnostics.Debug.WriteLine("PRINT_ToPrompt: " + buf)
149 PrintToPromptImpl(ToTCStr(buf), Len(buf))
150End Sub
151
152/*
153@brief PrintToPromptImplの内部関数
154@date 2009/03/16
155@author Egtra
156出力行が変わるときに呼ばれる。
157*/
158Sub SetLineLength()
159 _PromptSys_TextLine[_PromptSys_CurPos.y].Length = System.Math.Max(_PromptSys_TextLine[_PromptSys_CurPos.y].Length, _PromptSys_CurPos.x)
160End Sub
161
162/*
163@brief PrintToPromptImplの内部関数
164@date 2009/03/16
165@author Egtra
1661文字を出力するときに呼ばれる。
167*/
168Sub PutCharToPrompt(c As Char)
169 With _PromptSys_CurPos
170 Dim current = _PromptSys_TextLine[.y]
171 current.Text[.x] = c
172 current.CharInfo[.x].ForeColor = _PromptSys_NowTextColor
173 current.CharInfo[.x].BackColor = _PromptSys_NowBackColor
174 .x++
175 End With
176End Sub
177
178Sub PrintToPromptImpl(p As PCTSTR, len As Long)
179 EnterCriticalSection(_PromptSys_SectionOfBufferAccess)
180 Dim leadByte = False
181 'Addition
182 Dim i = 0 As Long
183 For i = 0 To ELM(len)
184 If leadByte Then
185 PutCharToPrompt(p[i])
186 Else
187 With _PromptSys_CurPos
188 Select Case p[i]
189 Case 13 'CR \r 復帰
190 SetLineLength()
191 .x = 0
192 Case 12 'FF フォームフィード
193 Cls 1
194 Case 10 'LF 改行
195 SetLineLength()
196 .y++
197 Case 9 'HT 水平タブ
198 Dim j As Long
199 For j = (.x And 7) To ELM(8)
200 PutCharToPrompt(&h20) '空白
201 Next
202 Case 8 'BS 後退
203 .x--
204 Case 7 'BEL ベル
205 MessageBeep(MB_ICONHAND) 'PuTTY由来のアイディア
206 Case 0 'NUL 空文字
207 Case Else
208 PutCharToPrompt(p[i])
209 If IsDBCSLeadByte(p[i]) Then
210 leadByte = True
211 End If
212 End Select
213 End With
214 End If
215 Next
216 SetLineLength()
217
218 LeaveCriticalSection(_PromptSys_SectionOfBufferAccess)
219
220 InvalidateRect(_PromptSys_hWnd, ByVal 0, TRUE)
221 UpdateWindow(_PromptSys_hWnd)
222End Sub
223
224Function PromptProc(hWnd As HWND, message As DWord, wParam As WPARAM, lParam As LPARAM) As LRESULT
225 Select Case message
226 Case WM_CREATE
227 Return _PromptWnd_OnCreate(hWnd, ByVal lParam As *CREATESTRUCT)
228 Case WM_PAINT
229 _PromptWnd_OnPaint(hWnd)
230 Case WM_SETFOCUS
231 _PromptWnd_OnSetFocus(hWnd, wParam As HWND)
232 Case WM_KILLFOCUS
233 _PromptWnd_OnKillForcus(hWnd, wParam As HWND)
234 Case WM_KEYDOWN
235 _PromptWnd_OnKeyDown(wParam As DWord, LOWORD(lParam) As DWord, HIWORD(lParam) As DWord)
236 Case WM_CHAR
237 _PromptWnd_OnChar(hWnd, wParam, lParam)
238 Case WM_IME_COMPOSITION
239 Return _PromptWnd_OnImeCompostion(hWnd, wParam, lParam)
240 Case WM_DESTROY
241 _PromptWnd_OnDestroy(hWnd)
242 Case Else
243 PromptProc = DefWindowProc(hWnd, message, wParam, lParam)
244 Exit Function
245 End Select
246 PromptProc = 0
247End Function
248
249Function _PromptWnd_OnCreate(hwnd As HWND, ByRef cs As CREATESTRUCT) As LRESULT
250 Dim hdc = GetDC(hwnd)
251 With _PromptSys_ScreenSize
252 _PromptSys_hBitmap = CreateCompatibleBitmap(hdc, .cx, .cy)
253 End With
254 _PromptSys_hMemDC = CreateCompatibleDC(hdc)
255 SelectObject(_PromptSys_hMemDC, _PromptSys_hBitmap)
256
257 'Initialize for Win9x
258 ClearGraphicsScreen()
259
260 Dim tm As TEXTMETRIC
261 Dim hOldFont = SelectObject(_PromptSys_hMemDC, _PromptSys_hFont) As HFONT
262 GetTextMetrics(_PromptSys_hMemDC, tm)
263 SelectObject(_PromptSys_hMemDC, hOldFont)
264 With _PromptSys_FontSize
265 .cx = tm.tmAveCharWidth
266 .cy = tm.tmHeight
267 End With
268
269 '_PromptSys_hFont initialize
270 Dim lf As LOGFONT
271 With lf
272 .lfHeight = -MulDiv(12, GetDeviceCaps(hdc, LOGPIXELSY), 72)
273 .lfWidth = 0
274 .lfEscapement = 0
275 .lfOrientation = 0
276 .lfWeight = 0
277 .lfItalic = 0
278 .lfUnderline = 0
279 .lfStrikeOut = 0
280 .lfCharSet = SHIFTJIS_CHARSET
281 .lfOutPrecision = OUT_DEFAULT_PRECIS
282 .lfClipPrecision = CLIP_DEFAULT_PRECIS
283 .lfQuality = DEFAULT_QUALITY
284 .lfPitchAndFamily = FIXED_PITCH
285 lstrcpy(.lfFaceName, ToTCStr("MS 明朝"))
286 End With
287
288 _PromptSys_hFont = CreateFontIndirect(lf)
289
290 ReleaseDC(hwnd, hdc)
291
292 _PromptWnd_OnCreate = 0
293End Function
294
295Sub _PromptWnd_OnPaint(hwnd As HWND)
296 Dim ps As PAINTSTRUCT
297 Dim hdc = BeginPaint(hwnd, ps)
298 With _PromptSys_ScreenSize
299 BitBlt(hdc, 0, 0, .cx, .cy, _PromptSys_hMemDC, 0, 0, SRCCOPY)
300' With ps.rcPaint
301' BitBlt(hdc, .left, .top, .right - .left, .bottom - .top, _PromptSys_hMemDC, .left, .top, SRCCOPY)
302 End With
303 DrawPromptBuffer(hdc, -1, 0)
304 EndPaint(hwnd, ps)
305End Sub
306
307Sub _PromptWnd_OnSetFocus(hwnd As HWND, hwndOldFocus As HWND)
308 If _PromptSys_InputLen <> -1 Then
309 Dim himc = ImmGetContext(hwnd)
310 If himc Then
311 Dim CompForm As COMPOSITIONFORM
312 With CompForm
313 .dwStyle = CFS_POINT
314 .ptCurrentPos.x = _PromptSys_CurPos.x * _PromptSys_FontSize.cx
315 .ptCurrentPos.y = _PromptSys_CurPos.y * _PromptSys_FontSize.cy
316 End With
317 ImmSetCompositionWindow(himc, CompForm)
318
319 Dim lf As LOGFONT
320 GetObject(_PromptSys_hFont, Len(lf), lf)
321 ImmSetCompositionFont(himc, lf)
322 End If
323 ImmReleaseContext(hwnd, himc)
324
325 CreateCaret(hwnd, 0, 9, 6)
326 With _PromptSys_CurPos
327 SetCaretPos(.x * _PromptSys_FontSize.cx, (.y + 1) * _PromptSys_FontSize.cy - 7)
328 End With
329 ShowCaret(hwnd)
330 End If
331End Sub
332
333Sub _PromptWnd_OnKillForcus(hwnd As HWND, hwndNewFocus As HWND)
334 HideCaret(hwnd)
335 DestroyCaret()
336End Sub
337
338Sub _PromptWnd_OnKeyDown(vk As DWord, repeat As DWord, flags As DWord)
339 If _PromptSys_InputLen = -1 Then
340 _PromptSys_KeyChar = vk As Byte
341 End If
342End Sub
343
344Sub _PromptWnd_OnDestroy(hwnd As HWND)
345 DeleteDC(_PromptSys_hMemDC)
346 DeleteObject(_PromptSys_hBitmap)
347
348 PostQuitMessage(0)
349End Sub
350
351Sub _PromptWnd_OnChar(hwnd As HWND, wParam As WPARAM, lParam As LPARAM)
352 Dim TempStr As String
353 If _PromptSys_InputLen <> -1 Then
354 If wParam = VK_BACK Then
355 If _PromptSys_InputLen Then
356 _PromptSys_InputLen--
357 _PromptSys_InputStr[_PromptSys_InputLen] = 0
358
359 _PromptSys_CurPos.x--
360 With _PromptSys_CurPos
361 _PromptSys_TextLine[.y].Text[.x] = 0
362 End With
363 End If
364 ElseIf wParam = VK_RETURN Then
365 _PromptSys_InputStr[_PromptSys_InputLen] = 0
366 _PromptSys_InputLen = -1
367 TempStr = Ex"\r\n"
368 ElseIf wParam = &H16 Then
369/*
370 'Paste Command(Use Clippboard)
371 OpenClipboard(hwnd)
372 Dim hGlobal = GetClipboardData(CF_TEXT) As HGLOBAL
373 If hGlobal = 0 Then Exit Sub
374 Dim pTemp = GlobalLock(hGlobal) As PCSTR
375#ifdef UNICODE 'A版ウィンドウプロシージャ用
376 Dim tempSizeA = lstrlenA(pTemp)
377 Dim tempSizeW = MultiByteToWideChar(CP_ACP, 0, pTemp, tempSizeA, 0, 0) + 1
378 TempStr = ZeroString(tempSizeW)
379 MultiByteToWideChar(CP_ACP, 0, pTemp, tempSizeA, StrPtr(TempStr), tempSizeW)
380#else
381 TempStr = ZeroString(lstrlen(pTemp) + 1)
382 lstrcpy(StrPtr(TempStr), pTemp)
383#endif
384 memcpy(VarPtr(_PromptSys_InputStr[_PromptSys_InputLen]), TempStr.Chars, SizeOf (Char) * TempStr.Length)
385 _PromptSys_InputLen += TempStr.Length
386
387 GlobalUnlock(hGlobal)
388 CloseClipboard()
389*/
390 Else
391 Dim t = wParam As TCHAR
392 TempStr = New String(VarPtr(t), 1)
393 _PromptSys_InputStr[_PromptSys_InputLen] = TempStr[0]
394 _PromptSys_InputLen++
395 End If
396
397 SendMessage(hwnd, WM_KILLFOCUS, 0, 0)
398 ActiveBasic.Prompt.Detail.PRINT_ToPrompt(TempStr)
399 SendMessage(hwnd, WM_SETFOCUS, 0, 0)
400 End If
401End Sub
402
403Function _PromptWnd_GetCompositionStringW(himc As HIMC, ByRef rpsz As PWSTR) As Long
404 Dim size = ImmGetCompositionStringW(himc, GCS_RESULTSTR, 0, 0) 'sizeはバイト単位
405 rpsz = GC_malloc(size) As PWSTR
406 If rpsz = 0 Then
407 'Debug
408 Return 0
409 End If
410 Return ImmGetCompositionStringW(himc, GCS_RESULTSTR, rpsz, size)
411End Function
412
413Function _PromptWnd_GetCompositionStringA(himc As HIMC, ByRef rpsz As PSTR) As Long
414 Dim size = ImmGetCompositionStringA(himc, GCS_RESULTSTR, 0, 0) 'sizeはバイト単位
415 rpsz = GC_malloc(size) As PSTR
416 If rpsz = 0 Then
417 'Debug
418 Return 0
419 End If
420 Return ImmGetCompositionStringA(himc, GCS_RESULTSTR, rpsz, size)
421End Function
422
423Function _PromptWnd_OnImeCompostion(hwnd As HWND, wp As WPARAM, lp As LPARAM) As LRESULT
424 If (lp And GCS_RESULTSTR) <> 0 Then
425 Dim himc = ImmGetContext(hwnd)
426 If himc = 0 Then
427 'Debug
428 Return 0
429 End If
430 Dim tempStr = Nothing As String
431 Dim str As *Char
432#ifdef UNICODE
433 Dim osver = System.Environment.OSVersion
434 With osver
435 ' GetCompositionStringW is not implimented in Windows 95
436 If .Version.Major = 4 And .Version.Minor = 0 And .Platform = System.PlatformID.Win32Windows Then
437 Dim strA As PCSTR
438 Dim sizeA = _PromptWnd_GetCompositionStringA(himc, strA)
439 tempStr = New String(strA, sizeA As Long)
440 Else
441 Dim size = _PromptWnd_GetCompositionStringW(himc, str)
442 tempStr = New String(str, (size \ SizeOf (WCHAR)) As Long)
443 End If
444 End With
445#else
446 Dim size = _PromptWnd_GetCompositionStringA(himc, str)
447 tempStr = New String(str, size As Long)
448#endif
449 ImmReleaseContext(hwnd, himc)
450
451 ActiveBasic.Strings.ChrCopy(VarPtr(_PromptSys_InputStr[_PromptSys_InputLen]), tempStr.StrPtr, tempStr.Length As SIZE_T)
452 _PromptSys_InputLen += tempStr.Length
453
454 SendMessage(hwnd, WM_KILLFOCUS, 0, 0)
455 ActiveBasic.Prompt.Detail.PRINT_ToPrompt(tempStr)
456 SendMessage(hwnd, WM_SETFOCUS, 0, 0)
457
458 _PromptWnd_OnImeCompostion = 0
459 Else
460 _PromptWnd_OnImeCompostion = DefWindowProc(hwnd, WM_IME_COMPOSITION, wp, lp)
461 End If
462End Function
463
464Function PromptMain(data As VoidPtr) As DWord
465 Dim i As Long
466 'Allocate
467 For i = 0 To 100
468 With _PromptSys_TextLine[i]
469 .Length = 0
470 .Text = _System_calloc(SizeOf (Char) * 255)
471 .CharInfo = _System_calloc(SizeOf (_PromptSys_CharacterInformation) * 255)
472 End With
473 Next
474
475 'Current Colors initialize
476 _PromptSys_NowTextColor = RGB(255, 255, 255)
477 _PromptSys_NowBackColor = RGB(0, 0, 0)
478
479 'Setup
480 With _PromptSys_ScreenSize
481 .cx = GetSystemMetrics(SM_CXSCREEN)
482 .cy = GetSystemMetrics(SM_CYSCREEN)
483 End With
484
485 'Critical Section
486 InitializeCriticalSection(_PromptSys_SectionOfBufferAccess)
487
488 'Regist Prompt Class
489 Dim wcl As WNDCLASSEX
490 ZeroMemory(VarPtr(wcl), Len(wcl))
491 With wcl
492 .cbSize = Len(wcl)
493 .hInstance = GetModuleHandle(0)
494 .style = CS_HREDRAW Or CS_VREDRAW' or CS_DBLCLKS
495 .hIcon = LoadImage(0, MAKEINTRESOURCE(IDI_APPLICATION), IMAGE_ICON, 0, 0, LR_DEFAULTSIZE Or LR_SHARED) As HICON
496 .hIconSm = LoadImage(0, MAKEINTRESOURCE(IDI_WINLOGO), IMAGE_ICON, 0, 0, LR_DEFAULTSIZE Or LR_SHARED) As HICON
497 .hCursor = LoadImage(0, MAKEINTRESOURCE(IDC_ARROW), IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE Or LR_SHARED) As HCURSOR
498 .lpszClassName = ToTCStr("PROMPT")
499 .lpfnWndProc = AddressOf(PromptProc)
500 .hbrBackground = GetStockObject(BLACK_BRUSH)
501 End With
502 Dim atom = RegisterClassEx(wcl)
503
504 'Create Prompt Window
505 _PromptSys_hWnd = CreateWindowEx(WS_EX_CLIENTEDGE, atom As ULONG_PTR As LPCTSTR, ToTCStr("BASIC PROMPT"), _
506 WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, _
507 0, 0, wcl.hInstance, 0)
508 ShowWindow(_PromptSys_hWnd, SW_SHOW)
509 UpdateWindow(_PromptSys_hWnd)
510 SetEvent(_PromptSys_hInitFinish)
511 Dim msg As MSG
512 Do
513 Dim iResult = GetMessage(msg, 0, 0, 0)
514 If iResult = 0 Then
515 System.Environment.ExitCode = msg.wParam As Long
516 Exit Do
517 ElseIf iResult = -1 Then
518 Exit Do
519 End If
520 TranslateMessage(msg)
521 DispatchMessage(msg)
522 Loop
523
524 '強制的に終了する
525 End
526
527 EnterCriticalSection(_PromptSys_SectionOfBufferAccess)
528
529 For i = 0 to 100
530 _System_free(_PromptSys_TextLine[i].Text)
531 _System_free(_PromptSys_TextLine[i].CharInfo)
532 Next
533
534 LeaveCriticalSection(_PromptSys_SectionOfBufferAccess)
535
536 DeleteCriticalSection(_PromptSys_SectionOfBufferAccess)
537
538 End
539End Function
540
541Sub ClearGraphicsScreen()
542 Dim rc As RECT
543 With rc
544 .left = 0
545 .top = 0
546 .right = _PromptSys_ScreenSize.cx
547 .bottom = _PromptSys_ScreenSize.cy
548 End With
549 SetBkColor(_PromptSys_hMemDC, 0)
550 ExtTextOut(_PromptSys_hMemDC, 0, 0, ETO_OPAQUE, rc, "", 0, 0) '矩形塗り潰しはExtTextOutが速いらしい
551End Sub
552
553'Prompt text command functoins
554
555Sub Cls(n As Long)
556 Dim i As Long
557
558 'When parameter was omitted, num is set to 1
559 If n = 0 Then n = 1
560
561 If n = 1 Or n = 3 Then
562 'Clear the text screen
563 For i = 0 To 100
564 With _PromptSys_TextLine[i]
565 .Text[0] = 0 '_System_FillChar(_PromptSys_TextLine[i].Text, -1 As Char, 0)
566 .Length = 0
567 End With
568 Next
569 With _PromptSys_CurPos
570 .x = 0
571 .y = 0
572 End With
573 End If
574
575 If n = 2 Or n = 3 Then
576 'Clear the graphics screen
577 ClearGraphicsScreen()
578 End If
579
580 'Redraw
581 InvalidateRect(_PromptSys_hWnd, ByVal 0, 0)
582End Sub
583
584Sub Color(textColorCode As Long, backColorCode As Long)
585 _PromptSys_NowTextColor = GetBasicColor(textColorCode)
586 If backColorCode = -1 Then
587 _PromptSys_NowBackColor = -1
588 Else
589 _PromptSys_NowBackColor = GetBasicColor(backColorCode)
590 End If
591End Sub
592
593Sub INPUT_FromPrompt(showStr As String)
594*InputReStart
595
596 ActiveBasic.Prompt.Detail.PRINT_ToPrompt(showStr)
597
598 'Input by keyboard
599 _PromptSys_InputLen = 0
600 SendMessage(_PromptSys_hWnd, WM_SETFOCUS, 0, 0)
601 While _PromptSys_InputLen <> -1
602 Sleep(10)
603 Wend
604 SendMessage(_PromptSys_hWnd, WM_KILLFOCUS, 0, 0)
605
606 'Set value to variable
607 Const comma = &h2c As Char 'Asc(",")
608 Dim broken = ActiveBasic.Strings.Detail.Split(New String(_PromptSys_InputStr), comma)
609 Dim i As Long
610 For i = 0 To ELM(broken.Count)
611 If _System_InputDataPtr[i] = 0 Then
612 ActiveBasic.Prompt.Detail.PRINT_ToPrompt(Ex"入力データの個数が多すぎます\r\n")
613 Goto *InputReStart
614 End If
615 _System_Input_SetArgument(_System_InputDataPtr[i], _System_InputDataType[i], broken.Item[i])
616 Next
617
618 If _System_InputDataPtr[i]<>0 Then
619 ActiveBasic.Prompt.Detail.PRINT_ToPrompt(Ex"入力データの個数が足りません\r\n")
620 Goto *InputReStart
621 End If
622End Sub
623
624Sub Locate(x As Long, y As Long)
625 If x < 0 Then x = 0
626 If y < 0 Then y = 0
627 If y > 100 Then y = 100
628 With _PromptSys_CurPos
629 .x = x
630 .y = y
631 End With
632
633 Dim i = _PromptSys_TextLine[y].Length
634 If i < x Then
635 ActiveBasic.Strings.ChrFill(VarPtr(_PromptSys_TextLine[y].Text[i]), x - i, &h20 As Char) 'Asc(" ")
636 Dim i2 As Long
637 For i2 = i To ELM(x)
638 _PromptSys_TextLine[y].CharInfo[i2].BackColor = -1
639 Next
640 _PromptSys_TextLine[y].Length = x
641 End If
642End Sub
643
644'Prompt graphic command functions
645
646Sub Circle(x As Double, y As Double, radius As Double, ColorCode As Long, StartPos As Double, EndPos As Double, Aspect As Double, bFill As Long, BrushColor As Long)
647 Dim hPen = CreatePen(PS_SOLID, 1, GetBasicColor(ColorCode))
648 Dim hBrush As HBRUSH
649 If bFill Then
650 hBrush = CreateSolidBrush(GetBasicColor(BrushColor))
651 Else
652 hBrush = GetStockObject(NULL_BRUSH)
653 End If
654
655 Dim hdc = GetDC(_PromptSys_hWnd)
656 Dim hOldPenDC = SelectObject(hdc, hPen)
657 Dim hOldBrushDC = SelectObject(hdc, hBrush)
658 Dim hOldPen = SelectObject(_PromptSys_hMemDC, hPen)
659 Dim hOldBrush = SelectObject(_PromptSys_hMemDC, hBrush)
660
661 Dim yRadius As Double
662 Dim xRadius As Double
663 If Aspect = 1 Then
664 yRadius = radius
665 xRadius = radius
666 ElseIf Aspect < 1 Then
667 yRadius = radius * Aspect
668 xRadius = radius
669 Else
670 yRadius = radius
671 xRadius = radius / Aspect
672 End If
673
674 Dim x1 = (x - xRadius) As Long
675 Dim x2 = (x + xRadius) As Long
676 Dim y1 = (y - yRadius) As Long
677 Dim y2 = (y + yRadius) As Long
678
679 If StartPos = 0 And EndPos = 0 Then
680 Ellipse(hdc, x1, y1, x2, y2)
681 Ellipse(_PromptSys_hMemDC, x1, y1, x2, y2)
682 Else
683 Dim isPie As Boolean
684 If StartPos < 0 Or EndPos < 0 Then
685 isPie = True
686 StartPos = Math.Abs(StartPos)
687 EndPos = Math.Abs(EndPos)
688 Else
689 isPie = False
690 End If
691
692 Dim scaleRadial = (x + y) * 0.5
693 Dim startX = (x + ActiveBasic.Math.Cos(StartPos) * scaleRadial) As Long
694 Dim startY = (y - ActiveBasic.Math.Sin(StartPos) * scaleRadial) As Long
695 Dim endX = (x + ActiveBasic.Math.Cos(EndPos) * scaleRadial) As Long
696 Dim endY = (y - ActiveBasic.Math.Sin(EndPos) * scaleRadial) As Long
697
698 If isPie Then
699 Pie(hdc, x1, y1, x2, y2, startX, startY, endX, endY)
700 Pie(_PromptSys_hMemDC, x1, y1, x2, y2, startX, startY, endX, endY)
701 Else
702 Arc(hdc, x1, y1, x2, y2, startX, startY, endX, endY)
703 Arc(_PromptSys_hMemDC, x1, y1, x2, y2, startX, startY, endX, endY)
704 End If
705 End If
706
707 SelectObject(hdc, hOldPenDC)
708 SelectObject(hdc, hOldBrushDC)
709 ReleaseDC(_PromptSys_hWnd, hdc)
710 SelectObject(_PromptSys_hMemDC, hOldPen)
711 SelectObject(_PromptSys_hMemDC, hOldBrush)
712 DeleteObject(hPen)
713 If bFill Then DeleteObject(hBrush)
714End Sub
715
716Sub Line(sx As Long, sy As Long, bStep As Long, ex As Long, ey As Long, ColorCode As Long, fType As Long, BrushColor As Long)
717 Dim temp As Long
718
719 If sx = &H80000000 And sy = &H80000000 Then
720 With _PromptSys_GlobalPos
721 sx = .x
722 sy = .y
723 End With
724 End If
725
726 If bStep Then
727 ex += sx
728 ey += sy
729 Else
730 If fType Then
731 'ラインの場合(四角形でない場合)
732 If sx>ex Then
733 temp=ex
734 ex=sx
735 sx=temp
736 End If
737 If sy>ey Then
738 temp=ey
739 ey=sy
740 sy=temp
741 End If
742 End If
743 End If
744
745 Dim hdc = GetDC(_PromptSys_hWnd)
746 Dim hPen = CreatePen(PS_SOLID, 1, GetBasicColor(ColorCode))
747 Dim hBrush As HBRUSH
748 If fType=2 Then
749 hBrush = CreateSolidBrush(GetBasicColor(BrushColor))
750 Else
751 hBrush = GetStockObject(NULL_BRUSH)
752 End If
753
754 SelectObject(hdc, hPen)
755 SelectObject(hdc, hBrush)
756 Dim hOldPen = SelectObject(_PromptSys_hMemDC, hPen)
757 Dim hOldBrush = SelectObject(_PromptSys_hMemDC, hBrush)
758
759 Select Case fType
760 Case 0
761 'line
762 MoveToEx(_PromptSys_hMemDC,sx,sy,ByVal NULL)
763 LineTo(_PromptSys_hMemDC,ex,ey)
764 SetPixel(_PromptSys_hMemDC,ex,ey,GetBasicColor(ColorCode))
765 MoveToEx(hdc,sx,sy,ByVal NULL)
766 LineTo(hdc,ex,ey)
767 SetPixel(hdc,ex,ey,GetBasicColor(ColorCode))
768 Case Else
769 'Rectangle
770 Rectangle(hdc,sx,sy,ex+1,ey+1)
771 Rectangle(_PromptSys_hMemDC,sx,sy,ex+1,ey+1)
772 End Select
773
774 ReleaseDC(_PromptSys_hWnd,hdc)
775 SelectObject(_PromptSys_hMemDC,hOldPen)
776 SelectObject(_PromptSys_hMemDC,hOldBrush)
777 DeleteObject(hPen)
778 If fType = 2 Then DeleteObject(hBrush)
779 With _PromptSys_GlobalPos
780 .x = ex
781 .y = ey
782 End With
783End Sub
784
785Sub PSet(x As Long, y As Long, ColorCode As Long)
786 Dim hdc = GetDC(_PromptSys_hWnd)
787 SetPixel(hdc, x, y, GetBasicColor(ColorCode))
788 SetPixel(_PromptSys_hMemDC, x, y, GetBasicColor(ColorCode))
789 ReleaseDC(_PromptSys_hWnd, hdc)
790 With _PromptSys_GlobalPos
791 .x = x
792 .y = y
793 End With
794End Sub
795
796Sub Paint(x As Long, y As Long, BrushColor As Long, LineColor As Long)
797 Dim hbr = CreateSolidBrush(GetBasicColor(BrushColor))
798
799 Dim hdc = GetDC(_PromptSys_hWnd)
800 Dim hbrOld = SelectObject(_PromptSys_hMemDC, hbr)
801 Dim hbrOldWndDC = SelectObject(hdc, hbr)
802
803 ExtFloodFill(hdc, x, y, GetBasicColor(LineColor), FLOODFILLBORDER)
804 ExtFloodFill(_PromptSys_hMemDC, x, y, GetBasicColor(LineColor), FLOODFILLBORDER)
805
806 ReleaseDC(_PromptSys_hWnd, hdc)
807 SelectObject(_PromptSys_hMemDC, hbrOld)
808 SelectObject(hdc, hbrOldWndDC)
809 DeleteObject(hbr)
810End Sub
811
812Function Inkey$() As String
813 If _PromptSys_KeyChar=0 Then
814 Inkey$=""
815 Else
816 Inkey$=Chr$(_PromptSys_KeyChar)
817 End If
818 _PromptSys_KeyChar=0
819End Function
820
821Function Input$(length As Long) As String
822 Dim i = 0 As Long
823
824 If length<=0 Then
825 Input$=""
826 Exit Function
827 End If
828
829 While 1
830 If _PromptSys_KeyChar Then
831 Input$=Input$+Chr$(_PromptSys_KeyChar)
832 _PromptSys_KeyChar=0
833 i++
834 If i >= length Then
835 Exit While
836 End If
837 End If
838 Sleep(1)
839 Wend
840End Function
841
842End Namespace 'Detail
843
844Function OwnerWnd() As HWND
845 Return Detail._PromptSys_hWnd
846End Function
847
848End Namespace 'Prompt
849End Namespace 'ActiveBasic
850
851'----------------------
852' Prompt text Commands
853'----------------------
854
855Sub PRINT_ToPrompt(s As String)
856 ActiveBasic.Prompt.Detail.PRINT_ToPrompt(s)
857End Sub
858
859Macro CLS()(num As Long)
860 ActiveBasic.Prompt.Detail.Cls(num)
861End Macro
862
863Macro COLOR(TextColorCode As Long)(BackColorCode As Long)
864 ActiveBasic.Prompt.Detail.Color(TextColorCode, BackColorCode)
865End Macro
866
867'---------- Defined in "command.sbp" ----------
868'Dim _System_InputDataPtr[_System_MAX_PARMSNUM] As VoidPtr
869'Dim _System_InputDataType[_System_MAX_PARMSNUM] As DWord
870'----------------------------------------------
871Sub INPUT_FromPrompt(ShowStr As String)
872 ActiveBasic.Prompt.Detail.INPUT_FromPrompt(ShowStr)
873End Sub
874
875/* TODO: _System_GetUsingFormatを用意して実装する
876Sub PRINTUSING_ToPrompt(UsingStr As String)
877 ActiveBasic.Prompt.Detail.PRINT_ToPrompt(_System_GetUsingFormat(UsingStr))
878End Sub
879*/
880
881Macro LOCATE(x As Double, y As Double)
882 ActiveBasic.Prompt.Detail.Locate(x As Long, y As Long)
883End Macro
884
885
886'-------------------
887' Graphics Commands
888'-------------------
889
890Macro CIRCLE(x As Double , y As Double, radius As Double)(ColorCode As Long, StartPos As Double, EndPos As Double, Aspect As Double, bFill As Long, BrushColor As Long)
891 '呼び出し方法は以下のようになります(コンパイラがパラメータの並びを最適化します)
892 'Circle (x, y), radius [, color] [, start] [, end] [, aspect] [, f] [, color2]
893 ActiveBasic.Prompt.Detail.Circle(x, y, radius, ColorCode, StartPos, EndPos, Aspect, bFill, BrushColor)
894End Macro
895
896Macro LINE(sx As Double, sy As Double, bStep As Long, ex As Double, ey As Double)(ColorCode As Long, fType As Long, BrushColor As Long)
897 '呼び出し方法は以下のようになります(コンパイラがパラメータの並びを最適化します)
898 'Line (sx,sy)-[STEP](ex,ey),[ColorCode],[B/Bf],[BrushColor]
899 ActiveBasic.Prompt.Detail.Line(sx As Long, sy As Long, bStep, ex As Long, ey As Long, ColorCode, fType, BrushColor)
900End Macro
901
902Macro PSET(x As Double, y As Double)(ColorCode As Long)
903 '呼び出し方法は以下のようになります(コンパイラがパラメータの並びを最適化します)
904 'PSet (x,y),ColorCode
905 ActiveBasic.Prompt.Detail.PSet(x As Long, y As Long, ColorCode)
906End Macro
907
908Macro PAINT(x As Double, y As Double, BrushColor As Long)(ByVal LineColor As Long)
909 '呼び出し方法は以下のようになります(コンパイラがパラメータの並びを最適化します)
910 'Paint (x,y),BrushColor,LineColor
911 ActiveBasic.Prompt.Detail.Paint(x As Long, y As Long, BrushColor, LineColor)
912End Macro
913
914
915'-----------
916' Functions
917'-----------
918
919Function Inkey$() As String
920 Return ActiveBasic.Prompt.Detail.Inkey$()
921End Function
922
923Function Input$(length As Long) As String
924 Return ActiveBasic.Prompt.Detail.Input$(length)
925End Function
926
927ActiveBasic.Prompt.Detail._PromptSys_Initialize()
928
929#endif '_INC_PROMPT
Note: See TracBrowser for help on using the repository browser.