ページ 1 / 1
powerpoint のようなテキストボックス
Posted: 2007年4月09日(月) 20:41
by なおゆき
現在グラフを描画するプログラムを作成中なのですが、powerpointのように画面上にテキストボックスを自由に配置できて、可逆的にテキストを編集できるような機能を追加したいと考えています。しかし、どのようにすればその機能が実現できるのか見当がつきません。リッチエディットテキストボックスで実現できるものでしょうか?
教えていただけると幸いです。よろしくお願いします。
Posted: 2007年4月09日(月) 21:30
by konisi
powerpointを使った事がない上に、「可逆的に~編集」あたりの意味が分かりませんが、CreateWindowExを使えばエディットボックスを自由に配置できると思います。
Posted: 2007年4月10日(火) 12:03
by なおゆき
返信ありがとうございます。
説明がわかりにくかったようで、すみません。
私が想定している機能は、PowerPoint や Word のようにソフトの使用者が自由にテキストボックスを作成してドラッグ移動でき、かつテキストの内容を好きなときに再編集できるようなものです。年賀状の作成ソフトなどにも同じ機能があります。
非常にあいまいな質問で申し訳ないのですが、このようなテキストボックスの実現方法(使用するコントロール、APIなど)があれば教えていただけるとうれしいです。
Posted: 2007年4月10日(火) 16:35
by MML
> 返信ありがとうございます。
> 説明がわかりにくかったようで、すみません。
> 私が想定している機能は、PowerPoint や Word のようにソフトの使用者が自由にテキストボックスを作成してドラッグ移動でき、かつテキストの内容を好きなときに再編集できるようなものです。年賀状の作成ソフトなどにも同じ機能があります。
> 非常にあいまいな質問で申し訳ないのですが、このようなテキストボックスの実現方法(使用するコントロール、APIなど)があれば教えていただけるとうれしいです。
なんとなくわかります。
「トラック」(四角形の枠を自由にうごかせれるやつ)を作って、
それにテキストボックスなんかをやっていけばいいと思います。
なんか説明がわからなかったらすいません。
Posted: 2007年4月13日(金) 22:05
by exx
> 私が想定している機能は、PowerPoint や Word のようにソフトの使用者が自由にテキストボックスを作成して
> ドラッグ移動でき、かつテキストの内容を好きなときに再編集できるようなものです。
これは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
Posted: 2007年4月14日(土) 01:59
by なおゆき
返事がおそくなってしまいすみません。ゆちボンさん、exxさん、返信ありがとうございます。
この数日、自分でもネットで検索してみたのですが、”トラック”については情報が見当たりませんでした。しかし、四角い枠というのは自分が想定しているものと近そうです。四角い枠の角にサイズ変更のための取っ手(?)があるようなものができればいいと思っています。もし詳しい情報があれば知りたいです。
それと、テキストボックスをドラッグ移動させるサンプルコードは、非常に参考になりました。自分でも工夫してみる必要がありそうですね。
要するに
Posted: 2007年4月14日(土) 10:40
by xss0423
メインウィンドウにエディットボックスを貼り付けて以下のコードをメインウィンドウのWM_PAINTイベント内に書いて実行してみて下さい
[ここをクリックすると内容が表示されます] [ここをクリックすると非表示にします]コード: 全て選択
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)
周囲の黒枠と黒ポチはGDIで手書きしているだけです
Wordなんかのは専用のウィンドウクラスのウィンドウを作ってんのかも知れませんが
ABではこれが精一杯だと思います
これのリサイズとドラッグを実現するには、マウスカーソルがエディットボックスの境界付近によってる時におきたWM_RBUTTONDOWNをキャプチャすれば良いでしょう
境界付近かどうかの判断はGetWindowRectとGetCursorPosを使えば可能です
リサイズにしろドラッグにしろマウスが押された位置と離された位置の座標があれば処理は可能なはずです
Posted: 2007年4月14日(土) 10:45
by xss0423
失礼、貼るコードと場所を間違ってました
[ここをクリックすると内容が表示されます] [ここをクリックすると非表示にします]コード: 全て選択
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
これをMainWndProcの中に貼ってください
Posted: 2007年4月15日(日) 19:15
by exx
ユーザーによるサイズ変更ですが、
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
試行錯誤中...
Posted: 2007年4月16日(月) 01:09
by なおゆき
返信ありがとうございます。
>xss0423さん
まさにこのような外観のテキストボックスを作りたいと思っていました!
これをベースに、テキストボックスのサイズ変更やドラッグ移動の方法、テキストボックス非選択時の枠消去の方法を考えてみたいと思います。
>exxさん
サイズ変更が簡単にできるウィンドウスタイルがあるとは知りませんでした。これは便利そうですね。あと、枠を表示したり非表示にしたりする切り替えができるとうれしかったのですが・・・