gettextextentexpoint

GetTextExtentPoint函数详解
本文详细介绍了GetTextExtentPoint函数的功能与使用方法。该函数能够获取指定字符串中每个字符的逻辑宽度,并计算整个字符串的尺寸。适用于自动换行计算等场景。
  name="google_ads_frame" marginwidth="0" marginheight="0" src="http://pagead2.googlesyndication.com/pagead/ads?client=ca-pub-5572165936844014&dt=1193665761703&lmt=1193665780&format=336x280_as&output=html&correlator=1193665761687&url=http%3A%2F%2Fwww.codeguru.cn%2Fpublic%2Fiframe%2Fwinapiiframe.htm&color_bg=FFFFFF&color_text=000000&color_link=000000&color_url=FFFFFF&color_border=FFFFFF&ad_type=text&ga_vid=1285758818.1193665762&ga_sid=1193665762&ga_hid=111695597&flash=9&u_h=768&u_w=1024&u_ah=740&u_aw=1024&u_cd=32&u_tz=480&u_his=8&u_java=true" frameborder="0" width="336" scrolling="no" height="280" allowtransparency="allowtransparency">     函数功能:该函数取得一个指定字符串里的字符数,该字符串将符合一个指定的空间,并且将其中每一个字符的范围放入一个数组。(一个正文的范围是指空间开始处到一个字符的间距)。此函数对自动换行的计算非常有用。

    函数原型:BOOL GetTextExtentPoint(HDC hdc, LPCTSTR lpszStr, int cchString, int nMaxExten, LPINT lpnFit, LPINT alpDx, LPSIZE lpSize);

    参数:

    hdc:设备环境句柄。

    lpszStr:指向以/0(Null)结束的字符串的指针,函数取得该字符中的范围。

    cchString:指定由lpszStr指向的字符串的字节数。

    nMaxExtent:为格式经的字符串指定最大可允许的逻辑单位宽度。

    lpnFit:指向整数的指针,该整数用于接收符合指定范围的字符的最大个数,该范围由nMaxExtent指定。如果lpnFit为NULL,则nMaxExtent无效。

    alpDx:指向整数数组的指针,该数组用于接收部分字符串范围。此数组的每一个元素给出一个间隔值,(按逻辑单位),表示字符串的开始处和在由nMaxExtent指定的空间里的一个字符之间的距离。尽管此数组应当至少有cchString指定那么多个元素,但函数向数组中填入其范围的字符数却由lpnFit确定。如果alpDx为NULL,则函数不计算局部字符串宽度。

    lpSize:指向结构SIZE的指针,该结构在函数返回时含有字符串的尺寸(按逻辑单位)。

    返回值:如果函数调用成功,返回值非零,如果函数调用失败,返回值是0。

    Windows NT:若想获得更多错误信息,请调用GetLastError函数。

    备注:如果lpnFit和alpDx的值均为NULL,则调用GetTextExtentPoint等同于调用GetTextExtentExPoint。

    Windows CE:cchString指定由lpszStr指向的字符串的字符个数而不是字节数。在Windows桌面平台下也是如此。

    速查:Windows NT:3.1及以上版本;Windows:95及以上版本;Windows CE:1.0及以上版本;头文件:wingdi.h;库文件:gdi32.lib;Unicode:在Windows NT环境下实现为Unicode和ANSI两种版本。

根据我提供的控件源码,写出一个更好的控件 #ifndef _CONSOLE_H_ #define _CONSOLE_H_ #define _CRT_SECURE_NO_WARNINGS #define NO_WARN_MBCS_MFC_DEPRECATION #include <SDKDDKVer.h> //#include <afxwin.h> #include <afxcmn.h> #include <concurrent_vector.h> #define CONSOLECOLOR_BLACK "\x1E\x1D" //字体 黑色 #define CONSOLECOLOR_RED "\x1E\x1F" //字体 红色 #define CONSOLECOLOR_GREEN "\x1E\x20" //字体 绿色 #define CONSOLECOLOR_YELLOW "\x1E\x21" //字体 黄色 #define CONSOLECOLOR_BLUE "\x1E\x22" //字体 蓝色 #define CONSOLECOLOR_PURPLE "\x1E\x23" //字体 紫色 #define CONSOLECOLOR_CYAN "\x1E\x24" //字体 青色 #define CONSOLECOLOR_DEF "\x1E\x25" //字体 默认色 class ScrollBar; struct LineInfo { DWORD m_dwStrLen;//行内容的长度 DWORD m_dwHead;//行首的sel游标 DWORD m_dwMaxSelWnd;//当前控件x轴尽头的sel DWORD m_dwTail;//行尾的sel int m_xPos;//行首的x开始坐标 int m_yPos;//行首的y开始坐标 DWORD m_dwMaxPixl;//此行内容占最大的像素 int* m_pDx; ~LineInfo() { if (m_pDx)delete[]m_pDx; } }; class Console: public CRichEditCtrl { public: Console(CWnd* _pParent); ~Console(); template<class ...Args> void Printf(const char* pformat, Args... args) { int len = std::snprintf(nullptr, 0, pformat, args...); if (len > 0) { char* szBuf = new char[len+1]; std::snprintf(szBuf, len+1, pformat, args...); split(szBuf); delete[]szBuf; } } private: void split(const char* _szText); void printf(const char* _szText); private: CDC* m_pDC; CRect m_rcWnd; BOOL m_bIsTrack; CFont m_Font;//默认字体,只是方便计算字体占屏幕长度使用的 int m_nFontSize;//默认字体大小(单位Twips) 如220Twip = 220/20 = 11磅 CHARFORMAT2 m_CF;//最终字体的数据 concurrency::concurrent_vector<LineInfo> m_vecLineInfo; ScrollBar* m_pHScroll; SCROLLINFO m_infoHScroll; DWORD m_pixCurMaxChars; ScrollBar* m_pVScroll; SCROLLINFO m_infoVScroll; int m_iLineHeight; int m_iStartPos_x; int m_iPrePos_x; bool m_bIsCapture; CHARRANGE m_StartSel; public: DECLARE_MESSAGE_MAP() afx_msg void OnEnSelchange(NMHDR* pNMHDR, LRESULT* pResult); afx_msg void OnEnMsgfilter(NMHDR* pNMHDR, LRESULT* pResult); afx_msg void OnMouseLeave(); afx_msg void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar); }; extern Console* pConsole; #define console(_format, ...)pConsole->Printf(_format, ##__VA_ARGS__); #endif#include "Console.h" #include <io.h> #include <thread> #include "ScrollBar/ScrollBar.h" Console* pConsole = NULL; Console::Console(CWnd* _pParent) : m_nFontSize(10 * 10), m_bIsTrack(FALSE), m_pHScroll(NULL), m_pVScroll(NULL), m_pixCurMaxChars(0), m_iPrePos_x(0), m_iStartPos_x(0), m_bIsCapture(FALSE) { if (_pParent) { const char* szFontName = "lucida consoles"; //Arial _pParent->GetWindowRect(&m_rcWnd); m_rcWnd = {10, 0, m_rcWnd.Width()-15, m_rcWnd.Height()-15};//682 //| WS_HSCROLL | WS_VSCROLL if (CreateEx(NULL, WS_CHILD | WS_VISIBLE | ES_LEFT | ES_WANTRETURN | ES_MULTILINE | ES_READONLY | ES_AUTOHSCROLL | ES_AUTOVSCROLL, m_rcWnd, _pParent, 0))// { m_pDC = GetDC(); SetBackgroundColor(false, RGB(30, 30, 30));//设置背景颜色 LimitText(32767);//系统默认设置是 32767 = 31.999kb 只能限制用户的输入 //创建新字体数据,此字体只是方便计算屏幕显示的长度用的。最终字体数据以 CHARFORMAT2 为准 //以十分之一磅为单位。例如,如果你想要一个12磅的字体,你应该传递120作为这个参数。 m_Font.CreatePointFont(m_nFontSize, szFontName);// 100/10 =10磅,相当于200Twip CreatePointFont用的单位是Point, 是磅的10倍,刚好是Twips的一半 SetFont(&m_Font);//设置字体 m_pDC->SelectObject(&m_Font);//dc选择当前字体 /* 1缇等于1/1440 英寸或1/567厘米 缇(Twips) (缇:计量单位,等于“磅”的 1/20,英寸的 1/1440。一厘米有 567 缇。 像素(Pixels):监视器或打印机分辨率的最小单位 右键单击桌面,选择属性,选择“设置”选卡,单击高级按钮。 里面出现DPI设置。一般为“正常尺寸(96 DPI)”。 DPI的意思就是 DPI(Dots per Inch)。因此我们可以得到如下换算公式 1 Pixel = 1440 TPI / 96 DPI = 15 Twips 1 Twip = 96 DPI / 1440 TPI = 0.0666667 Pixels 磅:指打印的字符的高度的度量单位, 1磅等于1/72英寸,或大约等于1厘米的 1/28。 英寸:2.54 厘米 一般情况下:1厘米=8505像素 20Twip = 1磅 = 20*0.0666667 = 1.333334 Pixels */ LRESULT FontStyle = 0; FontStyle = SendMessage(EM_GETLANGOPTIONS, 0, 0); if (FontStyle & IMF_DUALFONT) { FontStyle &= ~IMF_DUALFONT; //"<CRichEdit_Ctrl::CRichEdit_Ctrl>成功去掉IMF_DUALFONT"; } SendMessage(EM_SETLANGOPTIONS, 0, (LPARAM)FontStyle); /* PARAFORMAT2 pf; ZeroMemory(&pf, sizeof(PARAFORMAT2)); pf.cbSize = sizeof pf; pf.dwMask |= PFM_ALL; pf.bLineSpacingRule = 100; pf.dyLineSpacing = 400; pf.dySpaceAfter = 400; pf.dySpaceBefore = 400; pf.dxStartIndent = 100; pf.dxRightIndent = 100; SetParaFormat(pf); */ TEXTMETRIC tm; ::GetTextMetrics(m_pDC->GetSafeHdc(), &tm); m_iLineHeight = tm.tmHeight + (tm.tmDescent*2);//取得行高 //准确的字体数据 memset(&m_CF, 0, sizeof(m_CF)); //StrCpyA(m_CF.szFaceName, szFontName);//设置字体 //m_CF.cbSize = sizeof(CHARFORMAT2); m_CF.dwMask = CFM_EFFECTS | CFM_COLOR; m_CF.dwEffects = 0; m_CF.crTextColor = RGB(165, 165, 165);//设置颜色 //m_CF.yHeight = m_nFontSize;//除20得到磅 如 200/20 = 10磅 //默认的字符磅数 SetDefaultCharFormat(m_CF);//设置字体 SetEventMask(GetEventMask() | ENM_CHANGE | ENM_SELCHANGE | ENM_SCROLL | ENM_MOUSEEVENTS); //创建滚动动 m_pHScroll = new ScrollBar(); if (m_pHScroll->Create(SB_HORZ, CRect(m_rcWnd.left, m_rcWnd.Height(), m_rcWnd.right, m_rcWnd.Height()+15), _pParent)) { m_pHScroll->SetTarget(this); memset(&m_infoHScroll, 0, sizeof m_infoHScroll); m_infoHScroll.cbSize = sizeof m_infoHScroll; m_infoHScroll.fMask = SIF_ALL; m_infoHScroll.nPage = m_rcWnd.Width(); } m_pVScroll = new ScrollBar(); if (m_pVScroll->Create(SB_VERT, CRect(m_rcWnd.right, m_rcWnd.top, m_rcWnd.right+15, m_rcWnd.bottom), _pParent)) { m_pVScroll->SetTarget(this); memset(&m_infoVScroll, 0, sizeof m_infoVScroll); m_infoVScroll.cbSize = sizeof m_infoVScroll; m_infoVScroll.fMask = SIF_ALL; m_infoVScroll.nPage = m_rcWnd.Height(); } } } } Console::~Console() { m_Font.DeleteObject(); if (m_pHScroll)delete m_pHScroll; if (m_pVScroll)delete m_pVScroll; for (concurrency::concurrent_vector<LineInfo>::iterator iter = m_vecLineInfo.begin(); iter != m_vecLineInfo.end(); iter++) { if (iter->m_pDx) { delete[] iter->m_pDx; iter->m_pDx = NULL; } } } /* *0x1E RS (Record Separator) 记录分离符 属性代码 颜色 29 黑色 = 0x1D 31 红色 = 0x1F 32 绿色 = 0x20 33 黄色 = 0x21 34 蓝色 = 0x22 35 紫色 = 0x23 36 青色 = 0x24 */ void Console::printf(const char* _szText) { const char* szText = _szText; char byteColor = 0; //如果\n会替换成\r int indexLine = LineFromChar(-1);//取出当前行号 long lStart = 0; long lEnd = 0; GetSel(lStart, lEnd);//取得当前的光标位置 CString szStart; GetTextRange(lStart - 1, lEnd, szStart);//当前光标向后选择一位字符,并取出此字符 if (szStart == '\r' || szStart == "")//判断字符是否行头 { CPoint point = PosFromChar(lEnd); LineInfo info; memset(&info, 0, sizeof info); info.m_dwHead = lEnd; info.m_xPos = point.x; info.m_yPos = point.y; m_vecLineInfo.push_back(info);//保存行头的光标位置 } if (_szText[0] == '\x1E') { switch (_szText[1]) { case '\x1D': { m_CF.crTextColor = RGB(0, 0, 0); break; } case '\x1F': { m_CF.crTextColor = RGB(255, 0, 0); break; } case '\x20': { m_CF.crTextColor = RGB(0, 255, 0); break; } case '\x21': { m_CF.crTextColor = RGB(255, 255, 0); break; } case '\x22': { m_CF.crTextColor = RGB(0, 0, 255); break; } case '\x23': { m_CF.crTextColor = RGB(199, 0, 106); break; } case '\x24': { m_CF.crTextColor = RGB(0, 255, 255); break; } default: { m_CF.crTextColor = RGB(165, 165, 165); break; } } szText = _szText+2; SetSelectionCharFormat(m_CF); } ReplaceSel(szText); m_CF.crTextColor = RGB(165, 165, 165);//重置回原始颜色 SetSelectionCharFormat(m_CF); LineInfo* pInfo = &(m_vecLineInfo[indexLine]); //尝试取出控件尽头x轴末尾是否有字符存在 GetSel(lStart, lEnd);//取得当前的光标位置 GetTextRange(lEnd - 1, lEnd, szStart);//当前光标向后选择一位字符,并取出此字符 bool bIsEnter = false; if (szStart == '\r') { //已经完成换行操作 bIsEnter = true; pInfo->m_dwTail = lEnd - 1; GetTextRange(pInfo->m_dwHead, pInfo->m_dwTail, szStart);//取出本行内容 CPoint point = PosFromChar(pInfo->m_dwTail); pInfo->m_dwMaxPixl = point.x-1;//此行文本的最大像素 int len = szStart.GetLength(); int iFit = 0; CSize size = { 0, 0 }; if (pInfo->m_pDx) { delete [] pInfo->m_pDx; pInfo->m_pDx = NULL; } pInfo->m_pDx = new int[len]; pInfo->m_dwStrLen = len; ::GetTextExtentExPoint(m_pDC->GetSafeHdc(), szStart, len, point.x, &iFit, pInfo->m_pDx, &size);//计算出本行每个字符所占的像素,并把每个字符的像素存在m_pDx数组里面 pInfo->m_yPos = indexLine * m_iLineHeight; } else { pInfo->m_dwTail = lEnd; CPoint point = PosFromChar(pInfo->m_dwTail); pInfo->m_dwMaxPixl = point.x;//此行文本的最大像素 } //重置水平滚动条信息 if (pInfo->m_dwMaxPixl > (DWORD)m_rcWnd.Width() && pInfo->m_dwMaxPixl > m_pixCurMaxChars) { m_pixCurMaxChars = pInfo->m_dwMaxPixl; m_infoHScroll.nMax = m_pixCurMaxChars; m_pHScroll->SetScrollInfo(m_infoHScroll); } if (bIsEnter) { //已经完成换行操作 if (((indexLine + 1) * m_iLineHeight) > m_rcWnd.Height()) { m_infoVScroll.nMax = ((indexLine + 1) * m_iLineHeight); m_pVScroll->SetScrollInfo(m_infoVScroll); m_pVScroll->SetScrollPos(m_infoVScroll.nMax - m_rcWnd.Height());//向下滚动 } LineScroll(1); } } void Console::split(const char* _szText) { const char* szCurText = _szText; const char* szOldText = _szText; char* szPreText = NULL; int len = NULL; const char* szClrText = NULL; if (_szText[0] != '\x1E') { bool bIsFined = false; while ((szClrText = strchr(szCurText, '\x1E'))) { bIsFined = true; len = szClrText - szOldText; szPreText = new char[len + 1]; szPreText[len] = 0; memcpy(szPreText, szOldText, len); Console::printf(szPreText); delete[]szPreText; szCurText = szClrText + 1; szOldText = szClrText; } if (bIsFined) { if(szOldText)Console::printf(szOldText); } else { Console::printf(_szText); } } else { bool bIsFined = false; szCurText = _szText + 1; while ((szClrText = strchr(szCurText, '\x1E'))) { bIsFined = true; len = szClrText - szOldText; szPreText = new char[len + 1]; szPreText[len] = 0; memcpy(szPreText, szOldText, len); Console::printf(szPreText); delete[]szPreText; szCurText = szClrText + 1; szOldText = szClrText; } if (szOldText) { Console::printf(szOldText); } } } BEGIN_MESSAGE_MAP(Console, CRichEditCtrl) ON_NOTIFY_REFLECT(EN_SELCHANGE, &Console::OnEnSelchange) ON_NOTIFY_REFLECT(EN_MSGFILTER, &Console::OnEnMsgfilter) ON_WM_MOUSELEAVE() ON_WM_VSCROLL() END_MESSAGE_MAP() void Console::OnEnSelchange(NMHDR* pNMHDR, LRESULT* pResult) { SELCHANGE* pSelChange = reinterpret_cast<SELCHANGE*>(pNMHDR); // TODO: 控件将不发送此通知,除非您重写 // CRichEditCtrl::OnInitDialog() 函数,以将 EM_SETEVENTMASK 消息发送 // 到该控件,同时将 ENM_SELCHANGE 标志“或”运算到 lParam 掩码中。 // TODO: 在此添加控件通知处理程序代码 int iLineIndex = -1; iLineIndex = LineFromChar(pSelChange->chrg.cpMax); if (iLineIndex != -1 && iLineIndex < (int)m_vecLineInfo.size()) { CHARRANGE LineStartSel; LineInfo* pInfo = &m_vecLineInfo[iLineIndex]; switch (pSelChange->seltyp) { case 0://鼠标点击在某处文本的某个sel中 { //开始存储此行的选择sel起始位置 m_StartSel = pSelChange->chrg; break; } case CBN_EDITCHANGE://鼠标左键按住拖动选择文本 { //通过m_StartSel算出本行的选择起始位置 CPoint point = PosFromChar(m_StartSel.cpMin);//算出sel处于控件内坐标 int x = point.x; point.y = pInfo->m_yPos;//替换上本行的y坐标 LineStartSel.cpMin = CharFromPos(point);//算出本行起始位置 LineStartSel.cpMax = LineStartSel.cpMin; point = PosFromChar(LineStartSel.cpMin); if (point.x < x - 5) { //outputdebug_default("行号:%d 检测到起始位置异常,和原位差太远", iLineIndex); LineStartSel.cpMin = 0; LineStartSel.cpMax = 0; if (point.x > m_rcWnd.Width()) { m_pHScroll->SetScrollPos(point.x - m_rcWnd.Width());//通知滚动条 } else { m_pHScroll->SetScrollPos(0); } } if (pSelChange->chrg.cpMax > LineStartSel.cpMax) { //outputdebug_default("行号:%d 从左向右选择文本: %d", iLineIndex, pSelChange->chrg.cpMax); CString str; GetTextRange(pInfo->m_dwHead, pSelChange->chrg.cpMax, str); int len = str.GetLength(); if (--len > -1 && len < (int)pInfo->m_dwStrLen) { //outputdebug_default("行号:%d, 当前光标所占像素: %d", iLineIndex, pInfo->m_pDx[len]); int pix = pInfo->m_pDx[len]; if (pix > m_rcWnd.Width()) { //outputdebug_default("行号:%d, 当前光标所占像素超出控件长度: %d", iLineIndex, pix); m_pHScroll->SetScrollPos(pix - m_rcWnd.Width());//通知滚动条 } } else { if (--len > -1 && pInfo->m_dwStrLen == 0) { //此行末尾没有/r回车符 CPoint point = PosFromChar(pSelChange->chrg.cpMax); if (point.x > m_rcWnd.Width()) { m_pHScroll->SetScrollPos(point.x - m_rcWnd.Width());//通知滚动条 } else { m_pHScroll->SetScrollPos(0); } } else { int i = 0; } } } else if (pSelChange->chrg.cpMax != pInfo->m_dwHead) { //outputdebug_default("行号:%d 从右向左选择文本: head:%d start:%d, min:%d max:%d", iLineIndex, pInfo->m_dwHead, LineStartSel.cpMax, pSelChange->chrg.cpMin, pSelChange->chrg.cpMax); if (pSelChange->chrg.cpMin == pInfo->m_dwHead) { m_pHScroll->SetScrollPos(0); } } else { //outputdebug_default("x行号:%d 从右向左选择文本: head:%d start:%d, min:%d max:%d", iLineIndex, pInfo->m_dwHead, LineStartSel.cpMax, pSelChange->chrg.cpMin, pSelChange->chrg.cpMax); if (pInfo->m_dwHead == pSelChange->chrg.cpMax)//本行头部和上一行行尾重复,定位回上一行 { if (--iLineIndex > -1) { pInfo = &m_vecLineInfo[iLineIndex]; CString str; GetTextRange(pInfo->m_dwHead, pSelChange->chrg.cpMax, str); int len = str.GetLength(); //outputdebug_default("行号:%d, 当前光标所占像素: %d len:%d", iLineIndex, pInfo->m_pDx[len-2], len); if (--len > -1 && len <= (int)pInfo->m_dwStrLen) { int pix = pInfo->m_pDx[len-1]; if (pix > m_rcWnd.Width()) { //outputdebug_default("行号:%d, 当前光标所占像素超出控件长度: %d", iLineIndex, pix); //m_pHScroll->SetScrollPos(pix - m_rcWnd.Width());//通知滚动条 } } } } } break; } } } //outputdebug_default("min:%d max:%d", pSelChange->chrg.cpMin, pSelChange->chrg.cpMax); *pResult = 0; } void Console::OnEnMsgfilter(NMHDR* pNMHDR, LRESULT* pResult) { MSGFILTER* pMsgFilter = reinterpret_cast<MSGFILTER*>(pNMHDR); // TODO: 控件将不发送此通知,除非您重写 // CRichEditCtrl::OnInitDialog() 函数,以将 EM_SETEVENTMASK 消息发送 // 到该控件,同时将 ENM_KEYEVENTS 或 ENM_MOUSEEVENTS 标志 //“或”运算到 lParam 掩码中。 // TODO: 在此添加控件通知处理程序代码 switch(pMsgFilter->msg) { case WM_MOUSEMOVE: { /* if (pMsgFilter->wParam == MK_LBUTTON) { int xPos = GET_X_LPARAM(pMsgFilter->lParam); int yPos = GET_Y_LPARAM(pMsgFilter->lParam); //outputdebug_default("x: %d, y:%d",xPos, yPos); if (m_bIsCapture) { if (xPos > m_iStartPos_x) { //outputdebug_default("正在从左向右选择文本."); } else { //outputdebug_default("正在从右向左选择文本."); } m_iPrePos_x = xPos; } }*/ if (!m_bIsTrack) { m_bIsTrack = TRUE; TRACKMOUSEEVENT tme; tme.cbSize = sizeof(tme); tme.hwndTrack = m_hWnd; tme.dwFlags = TME_LEAVE | TME_HOVER; tme.dwHoverTime = 1;// 鼠标在按钮上停留超过 1ms ,才认为成功 _TrackMouseEvent(&tme); } break; } case WM_LBUTTONDOWN: { if (pMsgFilter->wParam == MK_LBUTTON) { int xPos = GET_X_LPARAM(pMsgFilter->lParam); int yPos = GET_Y_LPARAM(pMsgFilter->lParam); m_iPrePos_x = xPos; m_iStartPos_x = xPos; m_bIsCapture = TRUE; //outputdebug_default("x: %d, y:%d", xPos, yPos); } break; } case WM_LBUTTONUP: { if (pMsgFilter->wParam == MK_LBUTTON) { m_bIsCapture = FALSE; } break; } } *pResult = 0; } void Console::OnMouseLeave() { // TODO: 在此添加消息处理程序代码和/或调用默认值 m_bIsTrack = FALSE; ::SetCursor(AfxGetApp()->LoadStandardCursor(IDC_ARROW)); CRichEditCtrl::OnMouseLeave(); } void Console::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) { // TODO: 在此添加消息处理程序代码和/或调用默认值 CRichEditCtrl::OnVScroll(nSBCode, nPos, pScrollBar); }
07-02
//绘制字体和工具栏 static void draw_font_and_toolbar(HWND hwnd, char *str) { HDC hdc = BeginPaint(hwnd); RECT rc; GetClientRect(hwnd, &rc); //清除背景 SetBrushColor(hdc, PIXEL_black); FillBox(hdc, 0, 0, RECTW(rc), RECTH(rc)); // FillBoxWithBitmap(hdc, 0, 5, 10, 15, &g_control_panel.hCamsetBtn); SetPenColor(hdc, PIXEL_darkblue); SetPenWidth(hdc, 2); // Rectangle(hdc, 0, 0, RECTW(rc) - 2, RECTH(rc) - 2); RoundRect(hdc, 0, 0, RECTW(rc) - 2, RECTH(rc) - 2, 10, 10); SetTextColor(hdc, PIXEL_lightwhite); SetBkMode(hdc, BM_TRANSPARENT); DrawText(hdc, str, -1, &rc, DT_CENTER | DT_VCENTER | DT_SINGLELINE); if(strcmp(str,"CamSet") == 0) { LoadBitmapFromFile(HDC_SCREEN, &g_control_panel.hCamsetBmp, "/usr/local/share/minigui/res/bmp/camset.png"); FillBoxWithBitmap(hdc, 6, 0, g_control_panel.hCamsetBmp.bmWidth, g_control_panel.hCamsetBmp.bmHeight,&g_control_panel.hCamsetBmp); UnloadBitmap(&g_control_panel.hCamsetBmp); } if(strcmp(str,"Pause") == 0) { LoadBitmapFromFile(HDC_SCREEN, &g_control_panel.hPauseBmp, "/usr/local/share/minigui/res/bmp/pause.png"); FillBoxWithBitmap(hdc, 6, 0, g_control_panel.hPauseBmp.bmWidth, g_control_panel.hPauseBmp.bmHeight,&g_control_panel.hPauseBmp); UnloadBitmap(&g_control_panel.hPauseBmp); } if(strcmp(str,"Play") == 0) { LoadBitmapFromFile(HDC_SCREEN, &g_control_panel.hPlayBmp, "/usr/local/share/minigui/res/bmp/play.png"); FillBoxWithBitmap(hdc, 6, 0, g_control_panel.hPlayBmp.bmWidth, g_control_panel.hPlayBmp.bmHeight,&g_control_panel.hPlayBmp); UnloadBitmap(&g_control_panel.hPlayBmp); } if(strcmp(str,"Clock") == 0) { LoadBitmapFromFile(HDC_SCREEN, &g_control_panel.hClockBmp, "/usr/local/share/minigui/res/bmp/clock.png"); FillBoxWithBitmap(hdc, 6, 0, g_control_panel.hClockBmp.bmWidth, g_control_panel.hClockBmp.bmHeight,&g_control_panel.hClockBmp); UnloadBitmap(&g_control_panel.hClockBmp); } if(strcmp(str,"Full") == 0) { LoadBitmapFromFile(HDC_SCREEN, &g_control_panel.hFullscreenBmp, "/usr/local/share/minigui/res/bmp/fullscreen.png"); FillBoxWithBitmap(hdc, 6, 0, g_control_panel.hFullscreenBmp.bmWidth, g_control_panel.hFullscreenBmp.bmHeight,&g_control_panel.hFullscreenBmp); UnloadBitmap(&g_control_panel.hFullscreenBmp); } if(strcmp(str,"Split") == 0) { LoadBitmapFromFile(HDC_SCREEN, &g_control_panel.hSplitscreenBmp, "/usr/local/share/minigui/res/bmp/splitscreen.png"); FillBoxWithBitmap(hdc, 6, 0, g_control_panel.hSplitscreenBmp.bmWidth, g_control_panel.hSplitscreenBmp.bmHeight,&g_control_panel.hSplitscreenBmp); UnloadBitmap(&g_control_panel.hSplitscreenBmp); } EndPaint(hwnd, hdc); }字体绘制,怎么确定起始坐标
最新发布
11-10
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值