一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

【在窗口上寫字】

 qinjianguo18 2011-04-20

【在窗口上寫字】 收藏

在窗口上寫字

 

以前寫過一個類似的:http://dev.csdn.net/develop/article/29/29193.shtm

 

不過沒有處理好back space等問題。而且顯示字體也收到限制。這個依然是個不成熟的,不過可以改進(jìn)。

 

類代碼:

==============================================================

---TextFun.h---

/************************************************************

* Note:

* A class of drawing font on any window witch was attached to

* an instance of this class.

*

* Bugs to fit:

* 1, No memory dc supported so that XORPEN maybe disturb the

*     existing font shape on dc.

* 2, The class cannot serialize the drawing opts.

* 3, On small font, the urgly face to be improved.

*

* By enoloo

* First edition 8/10,2004

************************************************************/

#ifndef _TextFun_H_

#define _TextFun_H_

 

#include <string>

#include <tchar.h>

#include <windows.h>

#include <assert.h>

class CTextFun

{

public:

       CTextFun(){}

       CTextFun(HWND hWnd,HFONT hFont = NULL,

              COLORREF color = #0000ff);

       ~CTextFun();

 

public:

       void Attach(HWND hWnd,HFONT hFont = NULL,

              COLORREF color = #0000ff);

       void Enter(POINT point);

       void Leave();

 

       bool IsAttached() const { return (m_hWnd != NULL && ::IsWindow(m_hWnd)); }

 

public:

       bool PushChar(UINT nChar,bool bForward);

       void PopChar();

       void PushString(LPCTSTR str2Push);

      

       std::string GetString() const { return m_strText; }

       long GetHeight() const { return m_nHeight; }

       long GetWidth() const { return (m_ptNow.x - m_ptStart.x); }

       POINT GetCurrentPoint() const { return m_ptNow; }

protected:

       // create a default TRUE-TYPE font here.

       void CreateDefaultFont();

       void _PushString(LPCTSTR str2Push,bool bForward);

 

protected:

       HWND m_hWnd;

       HFONT m_hFont;

 

       std::string m_strText;

       POINT m_ptStart;

       POINT m_ptNow;

       COLORREF m_clColor;

       long m_nHeight;

 

       bool m_bDefaultFont;

};

#endif

========================================================

---TextFun.cpp---

#include "TextFun.h"

 

CTextFun::CTextFun(HWND hWnd, HFONT hFont /* = NULL */,

                               COLORREF color /* = RGB */)

{

       Attach(hWnd,hFont,color);

}

 

CTextFun::~CTextFun()

{

       if(m_bDefaultFont)

              ::DeleteObject(m_hFont);

       Leave();

}

 

// NOTE: hFont must be a true type font.

void CTextFun::Attach(HWND hWnd,HFONT hFont /* = NULL */, COLORREF color /* = RGB */)

{

       assert(hWnd);

       assert(::IsWindow(hWnd));

       m_hWnd = hWnd;

       HDC hdc = NULL;

       hdc = ::GetDC(hWnd);

       assert(hdc);

 

       if(hFont == NULL)

       {

              m_bDefaultFont = true;

              /*

              HFONT hft = (HFONT)::GetCurrentObject(hdc, OBJ_FONT);

              assert(hft);

              m_hFont = hft;

              */

              CreateDefaultFont();

       }

       else

       {

              m_bDefaultFont = false;

              m_hFont = hFont;

       }

 

       m_clColor = color; //color;

 

       HFONT oldFt = (HFONT)::SelectObject(hdc,m_hFont);

       TEXTMETRIC tm;

       ::GetTextMetrics(hdc, &tm);

       m_nHeight = tm.tmHeight;

       ::SelectObject(hdc,oldFt);

 

       ::ReleaseDC(hWnd,hdc);

}

 

void CTextFun::Enter(POINT point)

{

       m_ptStart = m_ptNow = point;

 

       ::DestroyCaret();

       assert( ::CreateCaret(m_hWnd, NULL, 1, m_nHeight) );

       ::ShowCaret(m_hWnd);

       ::SetCaretPos(point.x, point.y);

}

 

void CTextFun::Leave()

{

       m_ptStart.x = m_ptNow.x = m_ptStart.y = m_ptNow.y = 0;

       m_strText.erase();

       ::HideCaret(m_hWnd);

       ::DestroyCaret();

}

 

// for OnChar...

bool CTextFun::PushChar(UINT nChar,bool bForward)

{

       static bool bFirstChinese = false;

       static char strTemp[3];

      

       if(nChar > 127 && !bFirstChinese)  // maybe a chinese char code

       {

              if(bForward)

                     strTemp[0] = nChar;

              else

                     strTemp[1] = nChar;

              bFirstChinese = true;

              return false;                                // wait for the second char code

       }

       else if(nChar > 127 && bFirstChinese)

       {

              if(bForward)

                     strTemp[1] = nChar;

              else

                     strTemp[0] = nChar;

              strTemp[2] = 0;

              bFirstChinese = false;

       }

       else        // an ascii char code

       {

              bFirstChinese = false; // back the status here.

              strTemp[0] = nChar;

              strTemp[1] = 0;

       }

 

       _PushString(strTemp,bForward);

 

       return true;

}

 

void CTextFun::PopChar()

{

       int strLength = m_strText.length();

       if(m_strText.empty())

              return;

 

       HDC hdc = NULL;

       hdc = ::GetDC(m_hWnd);

       assert(hdc);

      

       if(!PushChar( m_strText[strLength - 1], false )) // maybe a chinese char code

       {

              if(m_strText.empty())

              {    

                     m_strText.erase();

                     return;

              }

              PushChar( m_strText[strLength - 2], false );

       }

       return;

}

 

void CTextFun::_PushString(LPCTSTR str2Push,bool bForward)

{

       // Create a caret always.

       int strLen = _tcsclen(str2Push);

       assert (strLen >= 0);

 

       assert( ::CreateCaret(m_hWnd, NULL, 1, m_nHeight) );

       ::ShowCaret(m_hWnd);

      

       HDC hdc = NULL;

       hdc = ::GetDC(m_hWnd);

       assert(hdc);

 

       int preX = m_ptNow.x;             // save it.

      

       LOGBRUSH logBr;

       logBr.lbColor = m_clColor;

       logBr.lbHatch = 0;

       logBr.lbStyle = BS_SOLID;

      

       HPEN pen,oldPen;

       pen = (HPEN)::ExtCreatePen( PS_GEOMETRIC | PS_SOLID |

              PS_ENDCAP_SQUARE | PS_JOIN_BEVEL, 1, &logBr, 0, NULL);

       //     pen = (HPEN)::CreatePen(PS_SOLID,1,m_clColor);

       oldPen = (HPEN)::SelectObject(hdc, (HGDIOBJ)pen);

      

       HBRUSH br,oldBr;

       br = ::CreateSolidBrush(m_clColor);

       oldBr = (HBRUSH)::SelectObject(hdc, (HGDIOBJ)br);

      

       HFONT oldFt = (HFONT)::SelectObject(hdc,m_hFont);

      

       RECT rtQuery;

       ::DrawText(hdc, str2Push, _tcslen(str2Push), &rtQuery, DT_CALCRECT);    // get the RECT for the char to draw      

      

       HRGN hRgn;

       if(bForward)

       {

              m_ptNow.x = m_ptNow.x + (rtQuery.right - rtQuery.left);

              hRgn = ::CreateRectRgn(preX, m_ptNow.y, m_ptNow.x, m_ptNow.y + m_nHeight);

       }

       else

       {

              m_ptNow.x = m_ptNow.x - (rtQuery.right - rtQuery.left);

              hRgn = ::CreateRectRgn(m_ptNow.x, m_ptNow.y, preX, m_ptNow.y + m_nHeight);

       }

       //     ::ExtSelectClipRgn(hdc,hRgn,RGN_COPY);

      

       // set the caret's pos now

       ::SetCaretPos(m_ptNow.x, m_ptNow.y);

       ::SetBkMode(hdc,TRANSPARENT);

      

       // draw the char code

       // ::SetPolyFillMode(hdc,ALTERNATE);

       int preR2 = ::SetROP2(hdc,R2_NOTXORPEN);

      

       ::BeginPath(hdc);

       if(bForward)

              ::TextOut(hdc, preX, m_ptNow.y, str2Push , _tcslen(str2Push));

       else

              ::TextOut(hdc, m_ptNow.x, m_ptNow.y, str2Push, _tcslen(str2Push));

       ::EndPath(hdc);

      

       // NOTE: DONT call a silly function StrokeAndFillPath!

       ::StrokeAndFillPath(hdc);

       // ::SelectClipPath(hdc,RGN_AND);

       ::SetROP2(hdc,preR2);

      

       ::SelectObject(hdc, (HGDIOBJ)oldPen);

       ::SelectObject(hdc, (HGDIOBJ)oldBr);

       ::SelectObject(hdc, (HGDIOBJ)oldFt);

      

       // save the char code

       if(bForward)

              m_strText += std::string(str2Push);

       else

              m_strText = m_strText.substr(0, m_strText.length() - _tcslen(str2Push));

 

       return;

}

 

void CTextFun::PushString(LPCTSTR str2Push)

{

       _PushString(str2Push,true);

}

 

void CTextFun::CreateDefaultFont()

{

       LOGFONT  lf;

       ::memset(&lf,0,sizeof(LOGFONT));

       lf.lfHeight = 40;

       lf.lfWeight = /*FW_BOLD*/ FW_NORMAL;

       lf.lfEscapement  = 0;

       lf.lfOrientation = 0;

       lf.lfItalic = FALSE;

       lf.lfUnderline = FALSE;

       lf.lfStrikeOut = FALSE;

       lf.lfCharSet   = ANSI_CHARSET;

       lf.lfOutPrecision   = OUT_DEFAULT_PRECIS;

       lf.lfClipPrecision  = DRAFT_QUALITY;

       lf.lfPitchAndFamily = VARIABLE_PITCH | FF_MODERN;

       strcpy(lf.lfFaceName, "Arial");

       m_hFont = ::CreateFontIndirect(&lf);

}

 

說明:

類支持在一個和類對象綁定(Attach)的窗口上寫字,支持所有true-type字體。支持bake escape鍵。如果換行,可以從類中得到高度,在下面創(chuàng)建一個新的類對象就可以了。

不支持上下左右光標(biāo),沒有memdc的支持,因為是用NotXorPen和路徑作出來的,所以文字會在疊加的時候產(chǎn)生干擾。 解決這些問題應(yīng)該不是很困難。

 

使用:

1,  將窗體和CTextFun對象綁定。綁定中可以指定true-type字體和顏色。也可以使用默認(rèn)的。m_fun為一個CTextFun對象,調(diào)用:

              m_fun.Attach(this->GetSafeHwnd());

2,顯示文字可以調(diào)用EnterLeave來完成。Enter函數(shù)設(shè)置顯示光標(biāo)的位置,Leave函數(shù)清空保存的緩沖文字?jǐn)?shù)據(jù)。如果在視圖中,可以在OnLButtonDown中調(diào)用:

m_fun.Enter(point);

OnChar中,可以這么調(diào)用:

void CChildView::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)

{

       // TODO: Add your message handler code here and/or call default

       if(nChar == VK_BACK) // back鍵就退格,和文本框一樣

       {

              m_fun.PopChar();

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

              return;

       }

       else if(nChar == VK_RETURN) // 回車鍵,結(jié)束顯示

       {

              m_fun.Leave();

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

              return;

       }

 

       m_fun.PushChar(nChar,true); // 普通鍵,再綁定的窗口上顯示

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

}

 

3,上面在OnChar中同步顯示字符,如果要一次顯示一個串呢,可以調(diào)用:

              m_fun.PushString("中國"); // 比如在OnLButtonDown中調(diào)用

 

效果如下:

 

 

測試代碼等找到免費空間之后傳上來的J

 

By enoloo,

8/10,2004

 

發(fā)表于 @ 2004年08月10日 21:26:00 | 評論( 0 ) | 舉報| 收藏

舊一篇:(轉(zhuǎn)載)利用 .NET 框架簡化發(fā)布和解決 DLL Hell 問題 | 新一篇:[轉(zhuǎn)載]行進(jìn)中開火

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多

    视频一区日韩经典中文字幕| 日本一本在线免费福利| 青草草在线视频免费视频| 国产精品一区二区高潮| 亚洲欧洲成人精品香蕉网| 好吊色免费在线观看视频| 欧美不卡一区二区在线视频| 国产精品日韩精品一区| 欧美日韩三区在线观看| 欧美三级精品在线观看| 中文字幕日韩精品人一妻| 中文字幕一区久久综合| 国产精品免费视频专区| 亚洲精品国产主播一区| 国产三级黄片在线免费看| 色偷偷偷拍视频在线观看| 午夜国产精品国自产拍av| 日韩一级毛一欧美一级乱| 欧美精品亚洲精品日韩专区| 国产一区在线免费国产一区| 中文字幕乱码免费人妻av| 欧美精品久久99九九| 亚洲熟女国产熟女二区三区| 国产成人一区二区三区久久| 国产成人av在线免播放观看av | 国产内射一级一片内射高清| 国产精品伦一区二区三区在线| 老外那个很粗大做起来很爽| 国产91人妻精品一区二区三区| 美女激情免费在线观看| 91香蕉国产观看免费人人| 亚洲中文字幕三区四区| 麻豆视传媒短视频在线看| 亚洲天堂有码中文字幕视频| 色好吊视频这里只有精| 国产精品亚洲一级av第二区| 亚洲a码一区二区三区| 夜色福利久久精品福利| 免费国产成人性生活生活片| 国产精品内射婷婷一级二级| 日本二区三区在线播放|