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

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

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

File size: 26.3 KB
RevLine 
[1]1'prompt.sbp
2
3
4#ifndef _INC_PROMPT
5#define _INC_PROMPT
6
[258]7Namespace ActiveBasic
8Namespace Prompt
9Namespace Detail
[497]10
[142]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)
[411]21 If _PromptSys_TextOut = 0 Then Debug
[142]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
[1]36Dim _PromptSys_hWnd As HWND
37Dim _PromptSys_dwThreadID As DWord
[127]38Dim _PromptSys_hInitFinish As HANDLE
[1]39
40'text
[126]41Type _PromptSys_CharacterInformation
42 ForeColor As COLORREF
43 BackColor As COLORREF
44End Type
[125]45
[126]46Type _PromptSys_LineInformation
47 Length As Long
[497]48 Text As *Char
[126]49 CharInfo As *_PromptSys_CharacterInformation
50End Type
51
[1]52Dim _PromptSys_hFont As HFONT
53Dim _PromptSys_FontSize As SIZE
[497]54Dim _PromptSys_InputStr[255] As Char
[258]55Dim _PromptSys_InputLen = -1 As Long
[1]56Dim _PromptSys_KeyChar As Byte
57Dim _PromptSys_CurPos As POINTAPI
[126]58Dim _PromptSys_TextLine[100] As _PromptSys_LineInformation
[121]59Dim _PromptSys_NowTextColor As COLORREF
60Dim _PromptSys_NowBackColor As COLORREF
[1]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
[258]70Sub _PromptSys_Initialize()
[272]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)
[258]78End Sub
[1]79
[691]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
[1]104Sub DrawPromptBuffer(hDC As HDC, StartLine As Long, EndLine As Long)
[691]105 Dim i As Long
[1]106
[121]107 Dim hOldFont = SelectObject(hDC, _PromptSys_hFont) As HFONT
[1]108
109 'Scroll
110 Dim rc As RECT
[121]111 GetClientRect(_PromptSys_hWnd, rc)
[125]112 While (_PromptSys_CurPos.y+1) * _PromptSys_FontSize.cy > rc.bottom and _PromptSys_CurPos.y > 0
[126]113 _System_free(_PromptSys_TextLine[0].Text)
114 _System_free(_PromptSys_TextLine[0].CharInfo)
[125]115 For i = 0 To 100 - 1
[126]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
[1]119 Next
[126]120 _PromptSys_TextLine[100].Length = 0
[497]121 _PromptSys_TextLine[100].Text = _System_calloc(SizeOf (Char) * 255)
[126]122 _PromptSys_TextLine[100].CharInfo = _System_calloc(SizeOf (_PromptSys_CharacterInformation) * 255)
[90]123 _PromptSys_CurPos.y--
[1]124
125 'Redraw
[125]126 StartLine = -1
[1]127 Wend
128
[691]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
[1]141 End If
[90]142 i++
[1]143 Wend
[121]144 SelectObject(hDC, hOldFont)
[1]145End Sub
146
147Sub PRINT_ToPrompt(buf As String)
[691]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)
[121]169 With _PromptSys_CurPos
[691]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
[1]177
[691]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()
[1]217
218 LeaveCriticalSection(_PromptSys_SectionOfBufferAccess)
[691]219
220 InvalidateRect(_PromptSys_hWnd, ByVal 0, TRUE)
221 UpdateWindow(_PromptSys_hWnd)
[1]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
[126]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
[1]248
[126]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)
[1]256
[126]257 'Initialize for Win9x
[685]258 ClearGraphicsScreen()
[1]259
[126]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
[411]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
[126]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)
[258]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)
[126]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
[121]316 End With
[126]317 ImmSetCompositionWindow(himc, CompForm)
[258]318
319 Dim lf As LOGFONT
320 GetObject(_PromptSys_hFont, Len(lf), lf)
321 ImmSetCompositionFont(himc, lf)
[126]322 End If
323 ImmReleaseContext(hwnd, himc)
[1]324
[126]325 CreateCaret(hwnd, 0, 9, 6)
[132]326 With _PromptSys_CurPos
[691]327 SetCaretPos(.x * _PromptSys_FontSize.cx, (.y + 1) * _PromptSys_FontSize.cy - 7)
[132]328 End With
[126]329 ShowCaret(hwnd)
330 End If
331End Sub
[1]332
[126]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
[1]363 End If
[126]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
[142]369/*
[126]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
[121]375#ifdef UNICODE 'A版ウィンドウプロシージャ用
[126]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)
[119]380#else
[126]381 TempStr = ZeroString(lstrlen(pTemp) + 1)
382 lstrcpy(StrPtr(TempStr), pTemp)
[119]383#endif
[126]384 memcpy(VarPtr(_PromptSys_InputStr[_PromptSys_InputLen]), TempStr.Chars, SizeOf (Char) * TempStr.Length)
385 _PromptSys_InputLen += TempStr.Length
[1]386
[126]387 GlobalUnlock(hGlobal)
388 CloseClipboard()
[142]389*/
[126]390 Else
[272]391 Dim t = wParam As TCHAR
392 TempStr = New String(VarPtr(t), 1)
393 _PromptSys_InputStr[_PromptSys_InputLen] = TempStr[0]
[126]394 _PromptSys_InputLen++
395 End If
[1]396
[126]397 SendMessage(hwnd, WM_KILLFOCUS, 0, 0)
[258]398 ActiveBasic.Prompt.Detail.PRINT_ToPrompt(TempStr)
[126]399 SendMessage(hwnd, WM_SETFOCUS, 0, 0)
400 End If
401End Sub
[1]402
[142]403Function _PromptWnd_GetCompositionStringW(himc As HIMC, ByRef rpsz As PWSTR) As Long
404 Dim size = ImmGetCompositionStringW(himc, GCS_RESULTSTR, 0, 0) 'sizeはバイト単位
[411]405 rpsz = GC_malloc(size) As PWSTR
[142]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はバイト単位
[411]415 rpsz = GC_malloc(size) As PSTR
[142]416 If rpsz = 0 Then
417 'Debug
418 Return 0
419 End If
420 Return ImmGetCompositionStringA(himc, GCS_RESULTSTR, rpsz, size)
421End Function
422
[126]423Function _PromptWnd_OnImeCompostion(hwnd As HWND, wp As WPARAM, lp As LPARAM) As LRESULT
[125]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
[272]430 Dim tempStr = Nothing As String
[497]431 Dim str As *Char
432#ifdef UNICODE
[258]433 Dim osver = System.Environment.OSVersion
434 With osver
[497]435 ' GetCompositionStringW is not implimented in Windows 95
[258]436 If .Version.Major = 4 And .Version.Minor = 0 And .Platform = System.PlatformID.Win32Windows Then
[142]437 Dim strA As PCSTR
438 Dim sizeA = _PromptWnd_GetCompositionStringA(himc, strA)
[272]439 tempStr = New String(strA, sizeA As Long)
[142]440 Else
441 Dim size = _PromptWnd_GetCompositionStringW(himc, str)
[272]442 tempStr = New String(str, (size \ SizeOf (WCHAR)) As Long)
[142]443 End If
444 End With
[497]445#else
446 Dim size = _PromptWnd_GetCompositionStringA(himc, str)
447 tempStr = New String(str, size As Long)
[142]448#endif
[125]449 ImmReleaseContext(hwnd, himc)
450
[272]451 ActiveBasic.Strings.ChrCopy(VarPtr(_PromptSys_InputStr[_PromptSys_InputLen]), tempStr.StrPtr, tempStr.Length As SIZE_T)
[142]452 _PromptSys_InputLen += tempStr.Length
[125]453
[258]454 SendMessage(hwnd, WM_KILLFOCUS, 0, 0)
455 ActiveBasic.Prompt.Detail.PRINT_ToPrompt(tempStr)
[125]456 SendMessage(hwnd, WM_SETFOCUS, 0, 0)
457
[126]458 _PromptWnd_OnImeCompostion = 0
[125]459 Else
[126]460 _PromptWnd_OnImeCompostion = DefWindowProc(hwnd, WM_IME_COMPOSITION, wp, lp)
[125]461 End If
462End Function
463
[537]464Function PromptMain(data As VoidPtr) As DWord
[1]465 Dim i As Long
466 'Allocate
[126]467 For i = 0 To 100
468 With _PromptSys_TextLine[i]
469 .Length = 0
[497]470 .Text = _System_calloc(SizeOf (Char) * 255)
[126]471 .CharInfo = _System_calloc(SizeOf (_PromptSys_CharacterInformation) * 255)
472 End With
[1]473 Next
474
475 'Current Colors initialize
[126]476 _PromptSys_NowTextColor = RGB(255, 255, 255)
477 _PromptSys_NowBackColor = RGB(0, 0, 0)
[1]478
479 'Setup
[125]480 With _PromptSys_ScreenSize
481 .cx = GetSystemMetrics(SM_CXSCREEN)
482 .cy = GetSystemMetrics(SM_CYSCREEN)
483 End With
[1]484
485 'Critical Section
486 InitializeCriticalSection(_PromptSys_SectionOfBufferAccess)
487
488 'Regist Prompt Class
489 Dim wcl As WNDCLASSEX
[123]490 ZeroMemory(VarPtr(wcl), Len(wcl))
491 With wcl
492 .cbSize = Len(wcl)
493 .hInstance = GetModuleHandle(0)
[126]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
[258]498 .lpszClassName = ToTCStr("PROMPT")
[123]499 .lpfnWndProc = AddressOf(PromptProc)
500 .hbrBackground = GetStockObject(BLACK_BRUSH)
501 End With
[121]502 Dim atom = RegisterClassEx(wcl)
[1]503
504 'Create Prompt Window
[258]505 _PromptSys_hWnd = CreateWindowEx(WS_EX_CLIENTEDGE, atom As ULONG_PTR As LPCTSTR, ToTCStr("BASIC PROMPT"), _
[192]506 WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, _
[125]507 0, 0, wcl.hInstance, 0)
[123]508 ShowWindow(_PromptSys_hWnd, SW_SHOW)
[119]509 UpdateWindow(_PromptSys_hWnd)
[127]510 SetEvent(_PromptSys_hInitFinish)
[123]511 Dim msg As MSG
[1]512 Do
[123]513 Dim iResult = GetMessage(msg, 0, 0, 0)
[258]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
[1]520 TranslateMessage(msg)
521 DispatchMessage(msg)
522 Loop
523
[121]524 '強制的に終了する
[258]525 End
[121]526
[1]527 EnterCriticalSection(_PromptSys_SectionOfBufferAccess)
[126]528
529 For i = 0 to 100
530 _System_free(_PromptSys_TextLine[i].Text)
531 _System_free(_PromptSys_TextLine[i].CharInfo)
[121]532 Next
[17]533
[1]534 LeaveCriticalSection(_PromptSys_SectionOfBufferAccess)
535
536 DeleteCriticalSection(_PromptSys_SectionOfBufferAccess)
537
[258]538 End
[1]539End Function
540
[685]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
[258]553'Prompt text command functoins
[1]554
[258]555Sub Cls(n As Long)
[1]556 Dim i As Long
557
558 'When parameter was omitted, num is set to 1
[258]559 If n = 0 Then n = 1
[1]560
[258]561 If n = 1 Or n = 3 Then
[1]562 'Clear the text screen
[123]563 For i = 0 To 100
[126]564 With _PromptSys_TextLine[i]
[497]565 .Text[0] = 0 '_System_FillChar(_PromptSys_TextLine[i].Text, -1 As Char, 0)
[126]566 .Length = 0
567 End With
[1]568 Next
[123]569 With _PromptSys_CurPos
570 .x = 0
571 .y = 0
572 End With
[1]573 End If
574
[258]575 If n = 2 Or n = 3 Then
[1]576 'Clear the graphics screen
[685]577 ClearGraphicsScreen()
[1]578 End If
579
580 'Redraw
[126]581 InvalidateRect(_PromptSys_hWnd, ByVal 0, 0)
[258]582End Sub
[1]583
[258]584Sub Color(textColorCode As Long, backColorCode As Long)
585 _PromptSys_NowTextColor = GetBasicColor(textColorCode)
586 If backColorCode = -1 Then
[126]587 _PromptSys_NowBackColor = -1
[1]588 Else
[258]589 _PromptSys_NowBackColor = GetBasicColor(backColorCode)
[1]590 End If
[258]591End Sub
[1]592
[258]593Sub INPUT_FromPrompt(showStr As String)
[1]594*InputReStart
595
[258]596 ActiveBasic.Prompt.Detail.PRINT_ToPrompt(showStr)
[1]597
598 'Input by keyboard
[126]599 _PromptSys_InputLen = 0
600 SendMessage(_PromptSys_hWnd, WM_SETFOCUS, 0, 0)
601 While _PromptSys_InputLen <> -1
[1]602 Sleep(10)
603 Wend
[126]604 SendMessage(_PromptSys_hWnd, WM_KILLFOCUS, 0, 0)
[1]605
606 'Set value to variable
[497]607 Const comma = &h2c As Char 'Asc(",")
[272]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
[258]612 ActiveBasic.Prompt.Detail.PRINT_ToPrompt(Ex"入力データの個数が多すぎます\r\n")
[1]613 Goto *InputReStart
614 End If
[635]615 _System_Input_SetArgument(_System_InputDataPtr[i], _System_InputDataType[i], broken.Item[i])
[272]616 Next
[1]617
[272]618 If _System_InputDataPtr[i]<>0 Then
619 ActiveBasic.Prompt.Detail.PRINT_ToPrompt(Ex"入力データの個数が足りません\r\n")
620 Goto *InputReStart
621 End If
[1]622End Sub
623
[258]624Sub Locate(x As Long, y As Long)
[126]625 If x < 0 Then x = 0
626 If y < 0 Then y = 0
627 If y > 100 Then y = 100
[123]628 With _PromptSys_CurPos
629 .x = x
630 .y = y
631 End With
[1]632
[126]633 Dim i = _PromptSys_TextLine[y].Length
[123]634 If i < x Then
[497]635 ActiveBasic.Strings.ChrFill(VarPtr(_PromptSys_TextLine[y].Text[i]), x - i, &h20 As Char) 'Asc(" ")
[126]636 Dim i2 As Long
637 For i2 = i To ELM(x)
638 _PromptSys_TextLine[y].CharInfo[i2].BackColor = -1
[1]639 Next
[126]640 _PromptSys_TextLine[y].Length = x
[1]641 End If
[258]642End Sub
[1]643
[258]644'Prompt graphic command functions
[1]645
[688]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))
[126]648 Dim hBrush As HBRUSH
[1]649 If bFill Then
[126]650 hBrush = CreateSolidBrush(GetBasicColor(BrushColor))
[1]651 Else
[126]652 hBrush = GetStockObject(NULL_BRUSH)
[1]653 End If
654
[688]655 Dim hdc = GetDC(_PromptSys_hWnd)
656 Dim hOldPenDC = SelectObject(hdc, hPen)
657 Dim hOldBrushDC = SelectObject(hdc, hBrush)
[126]658 Dim hOldPen = SelectObject(_PromptSys_hMemDC, hPen)
659 Dim hOldBrush = SelectObject(_PromptSys_hMemDC, hBrush)
[1]660
[688]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
[1]669 Else
[688]670 yRadius = radius
671 xRadius = radius / Aspect
[1]672 End If
673
[688]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)
[1]682 Else
[688]683 Dim isPie As Boolean
684 If StartPos < 0 Or EndPos < 0 Then
685 isPie = True
[684]686 StartPos = Math.Abs(StartPos)
687 EndPos = Math.Abs(EndPos)
[1]688 Else
[688]689 isPie = False
[1]690 End If
691
[688]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
[1]697
[688]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)
[1]701 Else
[688]702 Arc(hdc, x1, y1, x2, y2, startX, startY, endX, endY)
703 Arc(_PromptSys_hMemDC, x1, y1, x2, y2, startX, startY, endX, endY)
[1]704 End If
705 End If
706
[688]707 SelectObject(hdc, hOldPenDC)
708 SelectObject(hdc, hOldBrushDC)
709 ReleaseDC(_PromptSys_hWnd, hdc)
[126]710 SelectObject(_PromptSys_hMemDC, hOldPen)
711 SelectObject(_PromptSys_hMemDC, hOldBrush)
[1]712 DeleteObject(hPen)
713 If bFill Then DeleteObject(hBrush)
[258]714End Sub
[1]715
[258]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)
[1]717 Dim temp As Long
718
[126]719 If sx = &H80000000 And sy = &H80000000 Then
720 With _PromptSys_GlobalPos
721 sx = .x
722 sy = .y
723 End With
[1]724 End If
725
726 If bStep Then
[90]727 ex += sx
728 ey += sy
[1]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
[258]745 Dim hdc = GetDC(_PromptSys_hWnd)
[121]746 Dim hPen = CreatePen(PS_SOLID, 1, GetBasicColor(ColorCode))
747 Dim hBrush As HBRUSH
[1]748 If fType=2 Then
[126]749 hBrush = CreateSolidBrush(GetBasicColor(BrushColor))
[1]750 Else
[126]751 hBrush = GetStockObject(NULL_BRUSH)
[1]752 End If
753
[258]754 SelectObject(hdc, hPen)
755 SelectObject(hdc, hBrush)
[126]756 Dim hOldPen = SelectObject(_PromptSys_hMemDC, hPen)
757 Dim hOldBrush = SelectObject(_PromptSys_hMemDC, hBrush)
[1]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))
[258]765 MoveToEx(hdc,sx,sy,ByVal NULL)
766 LineTo(hdc,ex,ey)
767 SetPixel(hdc,ex,ey,GetBasicColor(ColorCode))
[1]768 Case Else
769 'Rectangle
[258]770 Rectangle(hdc,sx,sy,ex+1,ey+1)
[1]771 Rectangle(_PromptSys_hMemDC,sx,sy,ex+1,ey+1)
772 End Select
773
[258]774 ReleaseDC(_PromptSys_hWnd,hdc)
[1]775 SelectObject(_PromptSys_hMemDC,hOldPen)
776 SelectObject(_PromptSys_hMemDC,hOldBrush)
777 DeleteObject(hPen)
[126]778 If fType = 2 Then DeleteObject(hBrush)
779 With _PromptSys_GlobalPos
780 .x = ex
781 .y = ey
782 End With
[258]783End Sub
[1]784
[258]785Sub PSet(x As Long, y As Long, ColorCode As Long)
786 Dim hdc = GetDC(_PromptSys_hWnd)
787 SetPixel(hdc, x, y, GetBasicColor(ColorCode))
[126]788 SetPixel(_PromptSys_hMemDC, x, y, GetBasicColor(ColorCode))
[258]789 ReleaseDC(_PromptSys_hWnd, hdc)
[126]790 With _PromptSys_GlobalPos
791 .x = x
792 .y = y
793 End With
[258]794End Sub
[1]795
[258]796Sub Paint(x As Long, y As Long, BrushColor As Long, LineColor As Long)
797 Dim hbr = CreateSolidBrush(GetBasicColor(BrushColor))
[1]798
[258]799 Dim hdc = GetDC(_PromptSys_hWnd)
800 Dim hbrOld = SelectObject(_PromptSys_hMemDC, hbr)
801 Dim hbrOldWndDC = SelectObject(hdc, hbr)
[1]802
[258]803 ExtFloodFill(hdc, x, y, GetBasicColor(LineColor), FLOODFILLBORDER)
[126]804 ExtFloodFill(_PromptSys_hMemDC, x, y, GetBasicColor(LineColor), FLOODFILLBORDER)
[1]805
[258]806 ReleaseDC(_PromptSys_hWnd, hdc)
807 SelectObject(_PromptSys_hMemDC, hbrOld)
808 SelectObject(hdc, hbrOldWndDC)
809 DeleteObject(hbr)
810End Sub
[1]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
[258]822 Dim i = 0 As Long
[1]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
[90]833 i++
[126]834 If i >= length Then
[1]835 Exit While
836 End If
837 End If
838 Sleep(1)
839 Wend
840End Function
841
[258]842End Namespace 'Detail
[1]843
[258]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
[288]875/* TODO: _System_GetUsingFormatを用意して実装する
[258]876Sub PRINTUSING_ToPrompt(UsingStr As String)
877 ActiveBasic.Prompt.Detail.PRINT_ToPrompt(_System_GetUsingFormat(UsingStr))
878End Sub
[288]879*/
[258]880
[684]881Macro LOCATE(x As Double, y As Double)
882 ActiveBasic.Prompt.Detail.Locate(x As Long, y As Long)
[258]883End Macro
884
885
886'-------------------
887' Graphics Commands
888'-------------------
889
[684]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)
[258]891 '呼び出し方法は以下のようになります(コンパイラがパラメータの並びを最適化します)
892 'Circle (x, y), radius [, color] [, start] [, end] [, aspect] [, f] [, color2]
[688]893 ActiveBasic.Prompt.Detail.Circle(x, y, radius, ColorCode, StartPos, EndPos, Aspect, bFill, BrushColor)
[258]894End Macro
895
[684]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)
[258]897 '呼び出し方法は以下のようになります(コンパイラがパラメータの並びを最適化します)
898 'Line (sx,sy)-[STEP](ex,ey),[ColorCode],[B/Bf],[BrushColor]
[684]899 ActiveBasic.Prompt.Detail.Line(sx As Long, sy As Long, bStep, ex As Long, ey As Long, ColorCode, fType, BrushColor)
[258]900End Macro
901
[684]902Macro PSET(x As Double, y As Double)(ColorCode As Long)
[258]903 '呼び出し方法は以下のようになります(コンパイラがパラメータの並びを最適化します)
904 'PSet (x,y),ColorCode
[684]905 ActiveBasic.Prompt.Detail.PSet(x As Long, y As Long, ColorCode)
[258]906End Macro
907
[684]908Macro PAINT(x As Double, y As Double, BrushColor As Long)(ByVal LineColor As Long)
[258]909 '呼び出し方法は以下のようになります(コンパイラがパラメータの並びを最適化します)
910 'Paint (x,y),BrushColor,LineColor
[684]911 ActiveBasic.Prompt.Detail.Paint(x As Long, y As Long, BrushColor, LineColor)
[258]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.