番号
Re: 番号
> MainWndのEditBoxの左端に「ActiveBASIC」のように行数の番号を表示
> したいのですが、名前の通りまったくの初心者のため、ソースと詳しい解説
> をお願いします。
外見上はこうしたいってことですよね。
もちろんこれは独自にエディットコントロールを作る必要があるので初心者の方には難しいと思います...。
で、申し訳ないですけど、通常のエディットボックスやリッチエディットではどうやるのか分かりません...。
> したいのですが、名前の通りまったくの初心者のため、ソースと詳しい解説
> をお願いします。
外見上はこうしたいってことですよね。
[ここをクリックすると内容が表示されます]
とりあえず、自分だったらCreateWindowEx()関数でウィンドウを作って、そのウィンドウのクライアント領域左側を適当な分だけ行数表示の領域と考え、そこにはDrawText()関数とかDrawTextEx()関数で行数を描写、右側にはユーザーが入力した文字列を描写って感じにします。コード: 全て選択
'-----------------------------------------------------------------------------
' イベント プロシージャ
'-----------------------------------------------------------------------------
' このファイルには、ウィンドウ [MainWnd] に関するイベントをコーディングします。
' ウィンドウ ハンドル: hMainWnd
' TODO: この位置にグローバルな変数、構造体、定数、関数を定義します。
Dim OEditWC As WNDCLASSEX
Dim hEdit As HWND
Dim hBackBrush[1] As HBRUSH
'-----------------------------------------------------------------------------
' ウィンドウメッセージを処理するためのコールバック関数
Function MainWndProc(hWnd As HWND, dwMsg As DWord, wParam As WPARAM, lParam As LPARAM) As DWord
' TODO: この位置にウィンドウメッセージを処理するためのコードを記述します。
' イベントプロシージャの呼び出しを行います。
MainWndProc=EventCall_MainWnd(hWnd,dwMsg,wParam,lParam)
End Function
Function OEditProc(hWnd As HWND, dwMsg As DWord, wParam As WPARAM, lParam As LPARAM) As DWord
Select Case dwMsg
Case WM_PAINT
Dim ps As PAINTSTRUCT
Dim hDC As HDC
Dim rc As RECT
hDC=BeginPaint(hWnd,ps)
GetClientRect(hEdit,rc)
rc.right=40
FillRect(hDC,rc,hBackBrush[1])
GetClientRect(hEdit,rc)
rc.left=40
FillRect(hDC,rc,hBackBrush[0])
TextOut(hDC,5,5,"0:",2)
TextOut(hDC,5,25,"1:",2)
TextOut(hDC,5,45,"2:",2)
TextOut(hDC,45,5,"TEST1",5)
TextOut(hDC,45,25,"TEST2",5)
TextOut(hDC,45,45,"TEST3",5)
EndPaint(hWnd,ps)
End Select
OEditProc=DefWindowProc(hWnd,dwMsg,wParam,lParam)
End Function
'-----------------------------------------------------------------------------
' ここから下は、イベントプロシージャを記述するための領域になります。
Sub MainWnd_Destroy()
DeleteObject(hBackBrush[0])
DeleteObject(hBackBrush[1])
abc_DestroyObjects()
PostQuitMessage(0)
End Sub
Sub MainWnd_Create(ByRef CreateStruct As CREATESTRUCT)
With OEditWC
.cbSize=SizeOf(WNDCLASSEX)
.hInstance=GetModuleHandle(0)
.style=CS_HREDRAW or CS_VREDRAW
.hCursor=LoadCursor(NULL,MAKEINTRESOURCE(IDC_IBEAM))
.lpszClassName="OEDIT"
.lpfnWndProc=AddressOf(OEditProc)
End With
RegisterClassEx(OEditWC)
hEdit=CreateWindowEx(
WS_EX_CLIENTEDGE,
"OEDIT",
"",
WS_CHILD or WS_VISIBLE or ES_AUTOHSCROLL or WS_HSCROLL or WS_VSCROLL,
0,0,0,0,
hMainWnd,
0,
GetModuleHandle(0),
0)
UpdateWindow(hEdit)
hBackBrush[0]=CreateSolidBrush(RGB(0,0,0))
hBackBrush[1]=CreateSolidBrush(RGB(220,220,220))
End Sub
Sub MainWnd_Resize(SizeType As Long, cx As Integer, cy As Integer)
MoveWindow(hEdit,0,0,cx,cy,TRUE)
End Sub
もちろんこれは独自にエディットコントロールを作る必要があるので初心者の方には難しいと思います...。
で、申し訳ないですけど、通常のエディットボックスやリッチエディットではどうやるのか分かりません...。
Re: EditBoxの作り方は
> 7さんのおっしゃっていた、自分でEditBoxをつくるとはどうすればいいのですか。
ソースなんて隠す必要あるのかなんて考える人間なので提示できたらするんですけど、できないのでしません。
というか、以前のソースをどこまでも改造していけばいつかできると思います。
ウィンドウクラスの情報を設定する時に背景色を設定し忘れてるのとか訂正しながら。
歯磨いて寝よっ。
- 1. ウィンドウを作る。
- 1. スクロールバーを操作する関数群を実装する。
- 1. etcetc...
3. リサイズ時の処理を実装する。
4. キャレットを操作する関数群を作る。- 1. etcetc...
- 1. 循環リストを実装する。(行単位での双方向が望ましい?)
- 1. しかるべき行のノードの追加、挿入、削除する機能を実装する。
2. しかるべき行のノードにデータを適切に追加、挿入、削除する機能を実装する。
3. etcetc...
- 1. しかるべき行のノードの追加、挿入、削除する機能を実装する。
- 1. ダブルバッファリングを実装する。
2. しかるべき位置に行数を描写する必要がある。
3. しかるべき位置に入力された文字列を描写する必要がある。
4. etcetc...
- 1. スクロールバーを操作する関数群を実装する。
ソースなんて隠す必要あるのかなんて考える人間なので提示できたらするんですけど、できないのでしません。
というか、以前のソースをどこまでも改造していけばいつかできると思います。
ウィンドウクラスの情報を設定する時に背景色を設定し忘れてるのとか訂正しながら。
歯磨いて寝よっ。
まったくの初心者のため...
本当にすみません。
名前の通りまったくの初心者のため、解説に加えソースコードも投稿していただけませんか。
7さんには本当にご迷惑をおかけしていることはよく存じています。
お願いします。m(..)m
名前の通りまったくの初心者のため、解説に加えソースコードも投稿していただけませんか。
7さんには本当にご迷惑をおかけしていることはよく存じています。
お願いします。m(..)m
Re: できました。
> 何とか番号を表示するようにはなったのですが、肝心の文字が打てません。
> 打ち込むにはどうすればいいでしょうか。
ユーザーがキーボードを押した時の処理も全部自分で実装しなくてはなりません。
> また、改行したときに、番号もそれにあわせて、増えていくようにするにはどうすれば
> いいですかね。
例えば、ユーザーが改行するたびに行数をカウントアップしてその数だけ番号を描写したらいいんじゃないでしょうかねぇ。
このサイトを参考にご自分で頑張っては如何でしょう。
http://vivi.dyndns.org/tech/tech.phtml
自分は「行単位双方向リンク」という項目に悩んでます...。
所でエディットボックスに行数を表示する機能を考えて思いついたんですけど、エディットボックスを2つ用意して1つは行数だけ表示してれば良さそうですよね。
もう1つが改行するたびに行数を増やして。(意味不明かな...?)
入力するエディットボックスに同期させないと無理なんですけどねぇ。
> 打ち込むにはどうすればいいでしょうか。
ユーザーがキーボードを押した時の処理も全部自分で実装しなくてはなりません。
> また、改行したときに、番号もそれにあわせて、増えていくようにするにはどうすれば
> いいですかね。
例えば、ユーザーが改行するたびに行数をカウントアップしてその数だけ番号を描写したらいいんじゃないでしょうかねぇ。
[ここをクリックすると内容が表示されます]
随分と手抜きで間の抜けた作りなので参考程度にしかなりません。コード: 全て選択
'-----------------------------------------------------------------------------
' イベント プロシージャ
'-----------------------------------------------------------------------------
' このファイルには、ウィンドウ [MainWnd] に関するイベントをコーディングします。
' ウィンドウ ハンドル: hMainWnd
' TODO: この位置にグローバルな変数、構造体、定数、関数を定義します。
Dim OEditWC As WNDCLASSEX
Dim hEdit As HWND
Dim editString As LPSTR
Dim nLineCount As Long
Dim nLineIndex As Long
Dim nLineDigit As Long
Dim hBackBrush[1] As HBRUSH
'-----------------------------------------------------------------------------
' ウィンドウメッセージを処理するためのコールバック関数
Function MainWndProc(hWnd As HWND, dwMsg As DWord, wParam As WPARAM, lParam As LPARAM) As DWord
Select Case dwMsg
Case WM_ACTIVATE
SetFocus(hEdit)
Exit Function
End Select
MainWndProc=EventCall_MainWnd(hWnd,dwMsg,wParam,lParam)
End Function
Function OEditProc(hWnd As HWND, dwMsg As DWord, wParam As WPARAM, lParam As LPARAM) As DWord
Select Case dwMsg
Case WM_ERASEBKGND
OEditProc=TRUE
Exit Function
Case WM_CHAR
Select Case wParam
Case 8
' 現在参照している位置までの文字数を取得する必要がある。
' 消そうとしている文字が2バイト文字であるか判断する必要がある。
editString[lstrlen(editString)-1]=NULL
If nLineDigit>0 Then
nLineDigit--
End If
Case 13 , 10
If lstrlen(editString)>1023 Then Exit Function
nLineCount++
nLineIndex++
nLineDigit=0
lstrcat(editString,Ex"\r\n")
Case Else
If lstrlen(editString)>1023 Then Exit Function
nLineDigit++
lstrcat(editString,Chr$(wParam))
End Select
SetCaretPos(43+(nLineDigit*8),5+(nLineIndex*20))
InvalidateRect(hEdit,ByVal NULL,TRUE)
Case WM_KEYDOWN
Select Case wParam
Case 37 ' ←
If nLineDigit>0 Then
nLineDigit--
End If
Case 38 ' ↑
If nLineIndex>0 Then
nLineIndex--
End If
Case 39 ' →
' 参照している行の文字数を取得する必要がある。
' If nLineDigit<nLineLength Then
nLineDigit++
' End If
Case 40 ' ↓
If nLineCount>nLineIndex Then
nLineIndex++
End If
End Select
SetCaretPos(43+(nLineDigit*8),5+(nLineIndex*20))
Case WM_SETFOCUS
MainEdit_SetFocus()
Case WM_KILLFOCUS
MainEdit_KillFocus()
Case WM_PAINT
Dim ps As PAINTSTRUCT
Dim hDC As HDC
hDC=BeginPaint(hWnd,ps)
MainEdit_Paint(hDC)
EndPaint(hWnd,ps)
Case Else
OEditProc=DefWindowProc(hWnd,dwMsg,wParam,lParam)
Exit Function
End Select
OEditProc=0
End Function
'-----------------------------------------------------------------------------
' ここから下は、イベントプロシージャを記述するための領域になります。
Sub MainWnd_Destroy()
free(editString)
DeleteObject(hBackBrush[0])
DeleteObject(hBackBrush[1])
abc_DestroyObjects()
PostQuitMessage(0)
End Sub
Sub MainWnd_Create(ByRef CreateStruct As CREATESTRUCT)
With OEditWC
.cbSize=SizeOf(WNDCLASSEX)
.hInstance=GetModuleHandle(0)
.style=CS_HREDRAW or CS_VREDRAW
.hCursor=LoadCursor(NULL,MAKEINTRESOURCE(IDC_IBEAM))
.lpszClassName="OEDIT"
.lpfnWndProc=AddressOf(OEditProc)
End With
RegisterClassEx(OEditWC)
hEdit=CreateWindowEx(
WS_EX_CLIENTEDGE,
"OEDIT",
"",
WS_CHILD or WS_VISIBLE or ES_AUTOHSCROLL or WS_HSCROLL or WS_VSCROLL,
0,0,0,0,
hMainWnd,
0,
GetModuleHandle(0),
0)
UpdateWindow(hEdit)
hBackBrush[0]=CreateSolidBrush(RGB(0,0,0))
hBackBrush[1]=CreateSolidBrush(RGB(220,220,220))
CreateCaret(hEdit,0,1,16)
SetCaretPos(43,5+(nLineCount*20))
ShowCaret(hEdit)
' エディットコントロールに入力できるのは 1024 バイト
editString=calloc(1025)
End Sub
Sub MainWnd_Resize(SizeType As Long, cx As Integer, cy As Integer)
MoveWindow(hEdit,0,0,cx,cy,TRUE)
End Sub
Sub MainEdit_SetFocus()
CreateCaret(hEdit,0,1,16)
ShowCaret(hEdit)
End Sub
Sub MainEdit_KillFocus()
DestroyCaret()
End Sub
Sub MainEdit_Paint(ByVal hDC As HDC)
Dim rc As RECT
Dim cnt As Long
Dim line[256] As Byte
GetClientRect(hEdit,rc)
rc.right=40
FillRect(hDC,rc,hBackBrush[1])
GetClientRect(hEdit,rc)
rc.left=40
FillRect(hDC,rc,hBackBrush[0])
SetTextColor(hDC,RGB(0,0,0))
SetBkColor(hDC,RGB(220,220,220))
For cnt=0 To nLineCount
lstrcpy(line,Str$(cnt)+":")
TextOut(hDC,5,5+(cnt*20),line,lstrlen(line))
Next
SetTextColor(hDC,RGB(255,255,255))
SetBkColor(hDC,RGB(0,0,0))
rc.left+=5
rc.top+=5
DrawText(hDC,editString,-1,rc,DT_EDITCONTROL Or DT_LEFT)
End Sub
このサイトを参考にご自分で頑張っては如何でしょう。
http://vivi.dyndns.org/tech/tech.phtml
自分は「行単位双方向リンク」という項目に悩んでます...。
所でエディットボックスに行数を表示する機能を考えて思いついたんですけど、エディットボックスを2つ用意して1つは行数だけ表示してれば良さそうですよね。
もう1つが改行するたびに行数を増やして。(意味不明かな...?)
入力するエディットボックスに同期させないと無理なんですけどねぇ。
2エディットボックスの同期スクロール
すみません、ここへ割り込んでいいのかどうか。
下記で悩んでいて7さんの文章がが目に入りましたので飛びつきました。
2つのエディットボックスを用意して、スクロールバーで2つのエディットボックスをスクロールさせる方法についてお知らせ下さい。
初心者向けにお願い致します。
>所でエディットボックスに行数を表示する機能を考えて思いついたんですけど、エディットボックスを2つ用意して1つは行数だけ表示してれば良さそうですよね。
>もう1つが改行するたびに行数を増やして。(意味不明かな...?)
>入力するエディットボックスに同期させないと無理なんですけどねぇ。
下記で悩んでいて7さんの文章がが目に入りましたので飛びつきました。
2つのエディットボックスを用意して、スクロールバーで2つのエディットボックスをスクロールさせる方法についてお知らせ下さい。
初心者向けにお願い致します。
>所でエディットボックスに行数を表示する機能を考えて思いついたんですけど、エディットボックスを2つ用意して1つは行数だけ表示してれば良さそうですよね。
>もう1つが改行するたびに行数を増やして。(意味不明かな...?)
>入力するエディットボックスに同期させないと無理なんですけどねぇ。
Re: 2エディットボックスの同期スクロール
> 2つのエディットボックスを用意して、スクロールバーで2つのエディットボックスをスクロールさせる方法についてお知らせ下さい。
お知らせです。
思いついただけで出来るか試してないので動くか分かりませんよ。
まず、スクロールバーが動いた時(動き終わった時か)にGetScrollInfo()関数でスクロールバーの情報を取得。
次に2つのエディットボックスに対し、SetScrollInfo()関数でスクロールバーの情報を設定してやります。
これでいいんじゃないかと思ったんですけど...。
> 初心者向けにお願い致します。
スクロールバーについて、ヘルプを見たり、インターネットで検索してみて、それで分からないことがあったらまた質問して下さい。
お知らせです。
思いついただけで出来るか試してないので動くか分かりませんよ。
まず、スクロールバーが動いた時(動き終わった時か)にGetScrollInfo()関数でスクロールバーの情報を取得。
次に2つのエディットボックスに対し、SetScrollInfo()関数でスクロールバーの情報を設定してやります。
これでいいんじゃないかと思ったんですけど...。
> 初心者向けにお願い致します。
スクロールバーについて、ヘルプを見たり、インターネットで検索してみて、それで分からないことがあったらまた質問して下さい。
アドバイスありがとうございます。
7さんありがとうございます。
思うようにスクロールバーを操作するには時間がかかりそうなので、2つの内容をTABで1行にくっつけて、1つのエディットボックスでスクロールさせる姑息な手段をとりました。
掲示板ではHELPにないコマンドなどを見かけます。
ABHelperを参考にさせていただいておりますが、更なる充実を待ち望んでいます。
思うようにスクロールバーを操作するには時間がかかりそうなので、2つの内容をTABで1行にくっつけて、1つのエディットボックスでスクロールさせる姑息な手段をとりました。
掲示板ではHELPにないコマンドなどを見かけます。
ABHelperを参考にさせていただいておりますが、更なる充実を待ち望んでいます。
Re: アドバイスありがとうございます。
いや、スクロールバーを同期させようってのも結構姑息なやり方だと思いますよ。hige3さん さんが書きました:思うようにスクロールバーを操作するには時間がかかりそうなので、2つの内容をTABで1行にくっつけて、1つのエディットボックスでスクロールさせる姑息な手段をとりました。
解決したようですけど、とりあえず同期させようと思ってやってみました。ちょっと面倒そうです...。
Edit1のスクロールバーの情報を取得、Edit2のスクロールバーの情報を設定しようとすると、Edit2のスクロールバーが有効状態(?)じゃないと設定できなくて、まずこれが問題です。
適当にEdit2の内容を改行してスクロールバーを有効状態にして、スクロールバーの情報を設定するんですけど、Edit2に表示される内容はスクロールしてくれないんですよね。盲点でした。これも問題です。
EM_SCROLLを使ったり色々やればできるのかもしれませんけど、面倒なので止めます。
> 掲示板ではHELPにないコマンドなどを見かけます。
> ABHelperを参考にさせていただいておりますが、更なる充実を待ち望んでいます。
ActiveBasic付属のヘルプに載っていないヘルプから作っていけば読む方としては効率が良いんでしょうけど、現状は...。
頑張ろうと思います。