个人觉得很难得一个问题:如何在PaintBox上实现文本框并且输入文字。(200)

  • 主题发起人 jiansheyou
  • 开始时间
J

jiansheyou

Unregistered / Unconfirmed
GUEST, unregistred user!
这个问题我想了很久都没有想出解决的方法,问题入下:在PaintBox上创建了一个类似于Word中的文本框,现在文本框的选中、移动、缩放、旋转操作都已经实现了,但是关键是无法输入文字,我指的是像Word文本框那样直接在文本框中出现输入焦点,然后键入字符就出现的方法。而不是先输入到某个Edit之中,然后再通过TextOut函数绘制文本的方法。请说的越详细越好,最好能有源码,十分感谢,分不够可以再加。谢谢谢谢。。。
 
太有难度了,我记得以前看到一个HOHO游戏引擎,C++写的,可以实现图像上写字
 
据我估计应该是先输入到edit中再画在图上的。好象excel也是这样做的。
 
基本原理如下所示:var Edit: TEdit; EditRect:TRect;// 任何其他地方单击就消除掉EDITprocedure TForm1.PaintBox1Click(Sender: TObject);var pt:TPoint;begin if GetCursorPos(pt) then begin pt := ScreenToClient(pt); if (not ptInRect(EditRect, pt)) and (Assigned(Edit)) then begin /// 1) 转移已经写入 Edit 的文字 /// 2) 把文字写入内存画布 /// 3) 将内存画布与背景画布放入同一个刷新链 /// 之后: Edit.Hide; FreeAndNil(Edit); //ValidateRect(Handle, @EditRect); PaintBox1.Repaint; end; end;end;// 双击后显示一个可以输入文字的EDITprocedure TForm1.PaintBox1DblClick(Sender: TObject);var pt:TPoint;begin if GetCursorPos(pt) then begin pt := ScreenToClient(pt); Edit:= TEdit.Create(Self); Edit.SetBounds(pt.X, pt.Y, 120, 21); EditRect:=Edit.BoundsRect; Edit.Parent := Self; Edit.Show; Edit.SetFocus; end;end;
 
其实创建个Edit再输入是最简单的方法如果你非要自己做,无非就是自己画的问题只要把光标画出来,就有输入框的效果了,然后用户输入什么你显示出什么来。当然还有一些什么输入法状态之类的东西都要处理。最后还是建议自己搞个EDIT框吧。
 
// CustomEdit.cpp#include "stdafx.h"#include "customedit.h"#include "../Graphics/BitmapX.h"#include "../Graphics/Display.h"CCustomEdit::CCustomEdit(void){ m_lX = 0; m_lY = 0; m_lWidth = 0; m_lHeight = 16; m_lSize = MAX_INPUT_DATA; m_hFatherWnd = NULL; m_hWnd = NULL; m_hDC = NULL; m_DefProc = NULL; memset( m_strInputBuffer, 0, MAX_INPUT_DATA ); m_pBitmap = NULL; m_pDisplay = NULL;}CCustomEdit::~CCustomEdit(void){ if( m_pDisplay != NULL ) m_pDisplay->RemoveBitmap( m_pBitmap );}// -------------------------------------------------------// Name: Create()// Describe: 创建并初始化// -------------------------------------------------------long CCustomEdit::Create( HWND hMainWnd, CDisplay* pDisplay, long x, long y, long width, long height, bool bIsPass, bool bIsLimit ){ m_pDisplay = pDisplay; m_lX = x; m_lY = y; m_lWidth = width; m_lHeight = height; m_hFatherWnd = hMainWnd; // 创建Edit窗口 DWORD dwStyle = WS_CHILD | ES_LEFT | ES_AUTOHSCROLL; if( bIsPass ) { dwStyle |= ES_PASSWORD; } if( bIsLimit ) { dwStyle &= ~ES_AUTOHSCROLL; } m_hWnd = CreateWindow( "EDIT", NULL, dwStyle, x, y, width, height, hMainWnd, NULL, (HINSTANCE)GetWindowLong( hMainWnd, GWL_HINSTANCE ), NULL ); if( m_hWnd == NULL ) return -1; // 初始化 UpdateWindow( m_hWnd ); ShowWindow( m_hWnd, SW_SHOW); m_hDC = GetDC( m_hWnd ); m_DefProc = (WNDPROC)GetWindowLong( m_hWnd, GWL_WNDPROC ); SetWindowLong( m_hWnd, GWL_WNDPROC, (LONG)CustomEditProc); m_pBitmap = pDisplay->CreateSurface( width, height ); m_pBitmap->SetColorKey( RGB(255, 0, 0) ); return 0;}// -------------------------------------------------------// Name: Show()// Describe: 显示文本编辑框// -------------------------------------------------------long CCustomEdit::Show( ){ static HDC hDC; ((LPDIRECTDRAWSURFACE7)(m_pBitmap->m_pBuffer))->GetDC( &hDC ); BitBlt( hDC, 0, 0, m_lWidth, m_lHeight, m_hDC, 0, 0, SRCCOPY ); ((LPDIRECTDRAWSURFACE7)(m_pBitmap->m_pBuffer))->ReleaseDC( hDC ); m_pDisplay->DrawSurface( m_lX, m_lY, m_pBitmap, m_pDisplay->GetBackSurface() ); return 0;}// -------------------------------------------------------// Name: GetString()// Describe: 获取文本编辑框的文字串// -------------------------------------------------------char* CCustomEdit::GetString( ){ memset( m_strInputBuffer, 0, MAX_INPUT_DATA ); ::GetWindowText( m_hWnd, m_strInputBuffer, MAX_INPUT_DATA ); return m_strInputBuffer;}list<CCustomEdit*> g_listCustomEdit;typedef list<CCustomEdit* >::iterator CustomEditIterator;CCustomEdit* g_pActiveCustomEdit = NULL;// 文本输入框创建函式CCustomEdit* CreateCustomEdit( HWND hMainWnd, CDisplay* pDisplay, long x, long y, long width, long height, bool bIsPass, bool bIsLimit ){ CCustomEdit* pEdit = new CCustomEdit; assert( pEdit ); pEdit->Create( hMainWnd, pDisplay, x, y, width, height, bIsPass, bIsLimit ); g_listCustomEdit.push_back( pEdit ); return pEdit;}// 设置活动编辑框void SetActiveCustomEdit( CCustomEdit* pEdit ){ if( pEdit != NULL ) g_pActiveCustomEdit = pEdit; SetFocus( g_pActiveCustomEdit->m_hWnd );}// 显示活动编辑框void ShowCustomEdit( ){ if( g_listCustomEdit.size() == 0 ) return; for( CustomEditIterator it=g_listCustomEdit.begin(); it!=g_listCustomEdit.end(); it++ ) { CCustomEdit* p = *it; p->Show(); }}// 移除活动编辑框void RemoveCustomEdit( CCustomEdit* pEdit ){ if( g_listCustomEdit.size() == 0 ) { SAFE_DELETE( pEdit ); return; } g_listCustomEdit.remove( pEdit ); SAFE_DELETE( pEdit );}// 施放活动编辑框void ReleaseCustomEdit( ){ if( g_listCustomEdit.size() == 0 ) return; for( CustomEditIterator it=g_listCustomEdit.begin(); it!=g_listCustomEdit.end(); it++ ) { CCustomEdit* p = *it; SAFE_DELETE( p ); }}// 文本输入框消息响应函数LRESULT CALLBACK CustomEditProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam){ switch (message) { case WM_KEYDOWN: { switch(wParam) { case VK_ESCAPE: break; case VK_RETURN: { // 此处使用了自定义消息 // WM_USER+10 : 响应输入确认消息 SendMessage( g_pActiveCustomEdit->m_hFatherWnd, WM_USER+10, 0, 0); } break; case VK_TAB: { } break; default: break; } } break; case WM_CHAR: { } break; case WM_LBUTTONDOWN: break; case WM_PAINT: break; default: break; } return CallWindowProc( g_pActiveCustomEdit->m_DefProc, hWnd, message, wParam, lParam );}
 
/* /-/ /-/ / / / / / /__/ / / / / /--/ / / / / / oHo Game Engine v3.0 (共享版) / / / / Http://www.gameres.com /_/ /_/ Email:lindehui@263.netFileName:CustomEdit.cpp CustomEdit.hDescribe:文本输入框 (构建于系统编辑框之上)Author:林德辉(Sea_Bug)CreateDate: 2003.03.04UpdateDate: 2003.03.05*/#pragma once#define MAX_INPUT_DATA 256class CBitmapX;class CDisplay;class CCustomEdit{public: long Create( HWND hMainWnd, CDisplay* pDisplay, long x, long y, long width, long height, bool bIsPass, bool bIsLimit ); long Show( void ); char* GetString( void ); void SetSize( long lSize ) { m_lSize = lSize; }public: CCustomEdit(void); ~CCustomEdit(void);public: long m_lX; long m_lY; long m_lWidth; long m_lHeight; long m_lSize; HWND m_hFatherWnd; HWND m_hWnd; HDC m_hDC; WNDPROC m_DefProc; char m_strInputBuffer[MAX_INPUT_DATA];private: CBitmapX* m_pBitmap; CDisplay* m_pDisplay;};extern CCustomEdit* g_pActiveCustomEdit;CCustomEdit* CreateCustomEdit( HWND hMainWnd, CDisplay* pDisplay, long x, long y, long width, long height=16, bool bIsPass=false, bool bIsLimit=false );void SetActiveCustomEdit( CCustomEdit* pEdit );void ShowCustomEdit( void );void ReleaseCustomEdit( void );void RemoveCustomEdit( CCustomEdit* pEdit );LRESULT CALLBACK CustomEditProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
 
unit Unit1;interfaceuses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;type TForm1 = class(TForm) Button1: TButton; procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } end;var Form1: TForm1;implementation{$R *.dfm}varOldWndProc: Pointer;function EditWndProc(hwnd: HWnd; Msg: Cardinal; wParam, lParam: Integer): Integer; stdcall;begin if Msg = WM_KEYDOWN then begin // ShowMessage('123'); end; Result := CallWindowProc(OldWndProc,hwnd,Msg,wParam,lParam);end;procedure TForm1.Button1Click(Sender: TObject);var eHandle: HWND;begin eHandle := CreateWindow('Edit',Nil,WS_CHILD or WS_VISIBLE or WS_BORDER,0,0,120,20,Self.Handle,0,hInstance,Nil); OldWndProc:=Pointer(GetWindowLong(eHandle,GWL_WNDPROC)); SetWindowLong(eHandle,GWL_WNDPROC,LongInt(@EditWndProc)); //设置显示位置 SetWindowPos(eHandle, 0, 100, 100, 300, 20, SWP_NOZORDER + SWP_NOACTIVATE)end;end.
 
顶部