powerpoint のようなテキストボックス
powerpoint のようなテキストボックス
現在グラフを描画するプログラムを作成中なのですが、powerpointのように画面上にテキストボックスを自由に配置できて、可逆的にテキストを編集できるような機能を追加したいと考えています。しかし、どのようにすればその機能が実現できるのか見当がつきません。リッチエディットテキストボックスで実現できるものでしょうか?
教えていただけると幸いです。よろしくお願いします。
教えていただけると幸いです。よろしくお願いします。
powerpointを使った事がない上に、「可逆的に~編集」あたりの意味が分かりませんが、CreateWindowExを使えばエディットボックスを自由に配置できると思います。
Website→http://web1.nazca.co.jp/himajinn13sei/top.html
ここ以外の場所では「暇人13世」というHNを主として使用。
に署名を書き換えて欲しいと言われたので暇だしやってみるテスト。
ここ以外の場所では「暇人13世」というHNを主として使用。
に署名を書き換えて欲しいと言われたので暇だしやってみるテスト。
> 返信ありがとうございます。
> 説明がわかりにくかったようで、すみません。
> 私が想定している機能は、PowerPoint や Word のようにソフトの使用者が自由にテキストボックスを作成してドラッグ移動でき、かつテキストの内容を好きなときに再編集できるようなものです。年賀状の作成ソフトなどにも同じ機能があります。
> 非常にあいまいな質問で申し訳ないのですが、このようなテキストボックスの実現方法(使用するコントロール、APIなど)があれば教えていただけるとうれしいです。
なんとなくわかります。
「トラック」(四角形の枠を自由にうごかせれるやつ)を作って、
それにテキストボックスなんかをやっていけばいいと思います。
なんか説明がわからなかったらすいません。
> 説明がわかりにくかったようで、すみません。
> 私が想定している機能は、PowerPoint や Word のようにソフトの使用者が自由にテキストボックスを作成してドラッグ移動でき、かつテキストの内容を好きなときに再編集できるようなものです。年賀状の作成ソフトなどにも同じ機能があります。
> 非常にあいまいな質問で申し訳ないのですが、このようなテキストボックスの実現方法(使用するコントロール、APIなど)があれば教えていただけるとうれしいです。
なんとなくわかります。
「トラック」(四角形の枠を自由にうごかせれるやつ)を作って、
それにテキストボックスなんかをやっていけばいいと思います。
なんか説明がわからなかったらすいません。
> 私が想定している機能は、PowerPoint や Word のようにソフトの使用者が自由にテキストボックスを作成して
> ドラッグ移動でき、かつテキストの内容を好きなときに再編集できるようなものです。
これはCreateWindowEXで作成した後、そのテキストボックスそのものをドラッグ移動させるという事ですか?
ドラッグ移動に関してなら下の例のようなやり方があります。もしかしたら利用できるかも知れません。
テキストの内容の再編集にはその内容をコピーしてから座標の計算もして描画するとか。
ただ、そのような市販ソフトレベルの高機能をそのまま実現したいのならAPIの組み合わせだけでは簡単にいかない感じがします。
> ドラッグ移動でき、かつテキストの内容を好きなときに再編集できるようなものです。
これはCreateWindowEXで作成した後、そのテキストボックスそのものをドラッグ移動させるという事ですか?
ドラッグ移動に関してなら下の例のようなやり方があります。もしかしたら利用できるかも知れません。
テキストの内容の再編集にはその内容をコピーしてから座標の計算もして描画するとか。
ただ、そのような市販ソフトレベルの高機能をそのまま実現したいのならAPIの組み合わせだけでは簡単にいかない感じがします。
コード: 全て選択
'EditBox1をドラッグ移動させる簡単な例(この例ではウィンドウにEditBox1がすでにRAD上で作ってあるとします
'CreateWindowEXでEditを作成した場合は作成した方のハンドルを使ってください)
Dim EditCallBackhWnd As Long
const DRAGMOVE = &HF012
Function EditWndProc(hWnd As Long,uMsg As Long,wParam As Long,lParam As Long) As Long
Select Case uMsg
Case WM_LBUTTONDOWN
ReleaseCapture()
SendMessage(GetDlgItem(hMainWnd,EditBox1),WM_SYSCOMMAND,DRAGMOVE,0)
EditWndProc=0
Case Else
EditWndProc=CallWindowProc(EditCallBackhWnd As VoidPtr,hWnd As HWND,uMsg,wParam,lParam)
End Select
End Function
'メインウインドウのWM_CREATEでサブクラス化を設定
Sub MainWnd_Create(ByRef CreateStruct As CREATESTRUCT)
EditCallBackhWnd = SetWindowLong(GetDlgItem(hMainWnd,EditBox1),GWL_WNDPROC,AddressOf(EditWndProc) As Long)
End Sub
要するに
メインウィンドウにエディットボックスを貼り付けて以下のコードをメインウィンドウのWM_PAINTイベント内に書いて実行してみて下さい
Wordなんかのは専用のウィンドウクラスのウィンドウを作ってんのかも知れませんが
ABではこれが精一杯だと思います
これのリサイズとドラッグを実現するには、マウスカーソルがエディットボックスの境界付近によってる時におきたWM_RBUTTONDOWNをキャプチャすれば良いでしょう
境界付近かどうかの判断はGetWindowRectとGetCursorPosを使えば可能です
リサイズにしろドラッグにしろマウスが押された位置と離された位置の座標があれば処理は可能なはずです
[ここをクリックすると内容が表示されます]
周囲の黒枠と黒ポチはGDIで手書きしているだけですコード: 全て選択
Dim r As RECT,r2 As RECT
GetClientRect(GetDlgItem(hMainWnd,EditBox1),r)
r.top = r.top-6
r.left = r.left-6
r.right = r.right+6
r.bottom = r.bottom+6
FrameRect(hDC,r,GetStockObject(BLACK_BRUSH))
r2.top = r.top-3
r2.left = r.left-3
r2.right = r.left+3
r2.bottom = r.top+3
FillRect(hDC,r2,GetStockObject(BLACK_BRUSH))
r2.left = (r.left+r.right)/2-3
r2.right = (r.left+r.right)/2+3
FillRect(hDC,r2,GetStockObject(BLACK_BRUSH))
r2.left = r.right-3
r2.right = r.right+3
FillRect(hDC,r2,GetStockObject(BLACK_BRUSH))
r2.top = (r.top+r.bottom)/2-3
r2.left = r.left-3
r2.right = r.left+3
r2.bottom = (r.top+r.bottom)/2+3
FillRect(hDC,r2,GetStockObject(BLACK_BRUSH))
r2.left = r.right-3
r2.right = r.right+3
FillRect(hDC,r2,GetStockObject(BLACK_BRUSH))
r2.top = r.bottom-3
r2.left = r.left-3
r2.right = r.left+3
r2.bottom = r.bottom+3
FillRect(hDC,r2,GetStockObject(BLACK_BRUSH))
r2.left = (r.left+r.right)/2-3
r2.right = (r.left+r.right)/2+3
FillRect(hDC,r2,GetStockObject(BLACK_BRUSH))
r2.left = r.right-3
r2.right = r.right+3
FillRect(hDC,r2,GetStockObject(BLACK_BRUSH))
EndPaint(GetDlgItem(hMainWnd,EditBox1),ps)
Wordなんかのは専用のウィンドウクラスのウィンドウを作ってんのかも知れませんが
ABではこれが精一杯だと思います
これのリサイズとドラッグを実現するには、マウスカーソルがエディットボックスの境界付近によってる時におきたWM_RBUTTONDOWNをキャプチャすれば良いでしょう
境界付近かどうかの判断はGetWindowRectとGetCursorPosを使えば可能です
リサイズにしろドラッグにしろマウスが押された位置と離された位置の座標があれば処理は可能なはずです
失礼、貼るコードと場所を間違ってました
[ここをクリックすると内容が表示されます]
これをMainWndProcの中に貼ってくださいコード: 全て選択
If dwMsg=WM_PAINT Then
Dim r As RECT,r2 As RECT,ps As PAINTSTRUCT
GetClientRect(GetDlgItem(hMainWnd,EditBox1),r)
BeginPaint(GetDlgItem(hMainWnd,EditBox1),ps)
r.top = r.top-6
r.left = r.left-6
r.right = r.right+6
r.bottom = r.bottom+6
FrameRect(ps.hdc,r,GetStockObject(BLACK_BRUSH))
r2.top = r.top-3
r2.left = r.left-3
r2.right = r.left+3
r2.bottom = r.top+3
FillRect(ps.hdc,r2,GetStockObject(BLACK_BRUSH))
r2.left = (r.left+r.right)/2-3
r2.right = (r.left+r.right)/2+3
FillRect(ps.hdc,r2,GetStockObject(BLACK_BRUSH))
r2.left = r.right-3
r2.right = r.right+3
FillRect(ps.hdc,r2,GetStockObject(BLACK_BRUSH))
r2.top = (r.top+r.bottom)/2-3
r2.left = r.left-3
r2.right = r.left+3
r2.bottom = (r.top+r.bottom)/2+3
FillRect(ps.hdc,r2,GetStockObject(BLACK_BRUSH))
r2.left = r.right-3
r2.right = r.right+3
FillRect(ps.hdc,r2,GetStockObject(BLACK_BRUSH))
r2.top = r.bottom-3
r2.left = r.left-3
r2.right = r.left+3
r2.bottom = r.bottom+3
FillRect(ps.hdc,r2,GetStockObject(BLACK_BRUSH))
r2.left = (r.left+r.right)/2-3
r2.right = (r.left+r.right)/2+3
FillRect(ps.hdc,r2,GetStockObject(BLACK_BRUSH))
r2.left = r.right-3
r2.right = r.right+3
FillRect(ps.hdc,r2,GetStockObject(BLACK_BRUSH))
EndPaint(GetDlgItem(hMainWnd,EditBox1),ps)
End If
ユーザーによるサイズ変更ですが、
APIにはWS_THICKFRAMEというサイズ変更境界のあるウインドウスタイルがもともと用意されてるので、
それをコントロールに設定するとかなり簡単に実現できます。(座標計算など他の方法もあります。)
Editに限らず他のコントロールも適用できるのでいろいろと応用して使えるのではないでしょうか。
無論、他の方法との組み合わせで使っていくのも良いかもしれません。
APIにはWS_THICKFRAMEというサイズ変更境界のあるウインドウスタイルがもともと用意されてるので、
それをコントロールに設定するとかなり簡単に実現できます。(座標計算など他の方法もあります。)
Editに限らず他のコントロールも適用できるのでいろいろと応用して使えるのではないでしょうか。
無論、他の方法との組み合わせで使っていくのも良いかもしれません。
コード: 全て選択
'メインウインドウのWM_CREATEでEditBox1にWS_THICKFRAMEを設定している例です。(注:この場合、座標の計算や自前の描画の必要はありません)
Sub MainWnd_Create(ByRef CreateStruct As CREATESTRUCT)
Dim style As Long
style = GetWindowLong(GetDlgItem(hMainWnd,EditBox1), GWL_STYLE) or WS_THICKFRAME
SetWindowLong(GetDlgItem(hMainWnd,EditBox1), GWL_STYLE, style)
SetWindowPos(GetDlgItem(hMainWnd,EditBox1),hMainWnd,0,0,0,0,SWP_NOZORDER or SWP_NOSIZE or SWP_NOMOVE or SWP_DRAWFRAME)
End Sub