【作图】在图片上直接敲入字符

类别:VC语言 点击:0 评论:0 推荐:

【作图】在图片上直接敲入字符

作者:enoloo

在论坛经常看到提出怎么在图片上直接敲入字符。今天又碰到一个,于是趁着月黑风高写了几个小程序。

第一个程序,效果图如下:

 

 

第二个程序,效果如下:

 

 

[说明]

第一个程序:
开始想到的。用半透明文本框(真是很不爽,搞了半天截图软件也不能截取透明窗口的像样图片 @_@)。没有用SDK,用USER32.dll的函数SetLayeredWindowAttributes。网上有很多这方面的介绍。主要是:
1, m_hDll = ::LoadLibrary(_T("USER32.dll"));


2, ::SetWindowLong(hWnd, GWL_EXSTYLE, ::GetWindowLong(hWnd, GWL_EXSTYLE) | WS_EX_LAYERED);


3, if (m_hDll)
 {
  lpfnSetLayeredWindowAttributes pFn = NULL;
  pFn = (lpfnSetLayeredWindowAttributes)GetProcAddress(m_hDll, "SetLayeredWindowAttributes");
  if (pFn)
  {
   bRetValue = pFn(hWnd, crKey, bAlpha, dwFlags);
  } 
 }


4, if (m_hDll) ::FreeLibrary(m_hDll);
 m_hDll = NULL;

5, 有几个标志WS_EX_LAYERED等需要define一下。
#define WS_EX_LAYERED           0x00080000
#define LWA_COLORKEY            0x00000001
#define LWA_ALPHA               0x00000002

 

在某个窗体上随便写文字,还是老办法,鼠标点击的时候Create一个文本框(半透明),离开的时候把文本框中的文字写入窗口上文本框的那个位置,然后Destroy文本框。
窗口半透明之后,虽然能够看到窗口下面的东西,但是窗口里面所有的东西都半透明了,包括插入符,文字等等。所以,如果透明度很高的话,书写的文字是很难看清楚,所以,如果要实现完全透明的输入窗口并写东西,是很难控制的,因为找不到插入符在哪里。不过半透明的输入框也是挺有意思的。这个程序我没有深入写下去。

第二个程序:

功能:
1,鼠标点击窗体客户区的某个地方,产生一个插入符。
2,敲击键盘能过直接在窗体上写上字符,包括汉字,字母。因为是个测试程序,我只处理了等宽字体。
3,支持BackSpace消除字符,回车书写完毕。

因为写得比较匆忙,肯定有不少bug,我处理了一些。这算是抛砖引玉,大家有兴趣的话可以参考并完善。

程序代码(部分):
/*!
*
* 处理字符消息,并将字符写在窗体上
* \note 能处理中文,支持backspace编辑
* \bug 不支持HOME,END,LEFT,RIGHT等键,需要改进
* \bug 字符宽度需要改进,某些字体不受支持
* \author enoloo
* \date 2004-6-14 /first edition
*/
void CChildView::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
{
 // TODO: Add your message handler code here and/or call default
 if(!m_bShow)
 {
  CWnd::OnChar(nChar,nRepCnt,nFlags);
  return;
 }

 static char sTmp[3] = "";
 static BOOL bTmp = FALSE;
 CClientDC dc(this);
 dc.SetBkMode(TRANSPARENT);
 
 CRect rtTmp;
 
 if(nChar == VK_RETURN)  
 {
  m_bShow = false;
  ::HideCaret(this->GetSafeHwnd());
 }
 else if(nChar == VK_BACK)
 {
  if(m_nPos > 0)
  {
  
   --m_nPos;
   if(!bChinese)
   {
    rtTmp.left = m_xPos + m_nPos*m_xChar;
    rtTmp.top = m_yPos;
    rtTmp.right = m_xPos + m_strText.GetLength()*m_xChar;
    rtTmp.bottom = m_yPos + m_yChar;
    InvalidateRect( &rtTmp );
    ::SetCaretPos((m_xPos + m_nPos*m_xChar), m_yPos);
   
   }
   else
   {
    rtTmp.left = m_xPos + m_nPos*m_xChar*2;
    rtTmp.top = m_yPos;
    rtTmp.right = m_xPos + m_strText.GetLength()*m_xChar*2;
    rtTmp.bottom = m_yPos + m_yChar;
    InvalidateRect( &rtTmp );
    ::SetCaretPos((m_xPos + m_nPos*m_xChar*2), m_yPos);
   }
   m_strText.Delete(m_nPos);

  }
 }
 else  // 正常的字符码
 { 
  CString strTmp;
  
  if(nChar > 127 && bTmp)
  {
   sTmp[1] = nChar;
   sTmp[2] = 0;
   bChinese = true;
   bTmp = false;
  }
  else if(nChar > 127 && !bTmp)
  {
   sTmp[0] = nChar;
   bTmp = true;
   CWnd::OnChar(nChar,nRepCnt,nFlags);
   return;
  }
  else
  {
   bChinese = false;
   sTmp[0] = nChar;
   sTmp[1] = 0;
  }
  strTmp = sTmp;
  if(!bChinese)
  {
   dc.TextOut((m_xPos + m_nPos*m_xChar + 2), m_yPos, strTmp);
   ++m_nPos;
   ::SetCaretPos((m_xPos + m_nPos*m_xChar), m_yPos);
   
  }
  else
  {
   dc.TextOut((m_xPos + m_nPos*m_xChar*2 + 2), m_yPos, strTmp);
   
   ++m_nPos;
   ::SetCaretPos((m_xPos + m_nPos*m_xChar*2), m_yPos);
  }
  m_strText += strTmp;
  
  CWnd::OnChar(nChar, nRepCnt, nFlags);
  return;
 }

 CWnd ::OnChar(nChar, nRepCnt, nFlags);
}

我的免费空间正在升级,所以暂时没有空间摆上工程代码。空间好了,我会贴出来的。

 

 

 

 


 

本文地址:http://com.8s8s.com/it/it821.htm