// // Output messages in the chat area // // void TextChat::PrintMessage(const char* szMessage,const char* szSender,DWORD dwColor /*= BLACK*/) { // char szTextBoxBuffer[TEXTMAXSIZE]; // memset(szTextBoxBuffer,0,TEXTMAXSIZE); CHARRANGE cr; // Todo: test if chat text + sender + message > TEXTMAXSIZE -> Modulo display if (szSender != NULL) //print the sender's name { SendDlgItemMessage(m_hDlg, IDC_CHATAREA_EDIT,WM_GETTEXT, TEXTMAXSIZE-1,(LONG)m_szTextBoxBuffer); cr.cpMax = strlen(m_szTextBoxBuffer); // Select the last caracter to make the text insertion cr.cpMin = cr.cpMax; SendDlgItemMessage(m_hDlg, IDC_CHATAREA_EDIT,EM_EXSETSEL,0,(LONG) &cr); /***/ SetTextFormat(false,false,0x75,"MS Sans Serif",dwColor); _snprintf(m_szTextBoxBuffer,TEXTMAXSIZE-1,"<%s>: ",szSender); SendDlgItemMessage(m_hDlg, IDC_CHATAREA_EDIT,EM_REPLACESEL,FALSE,(LONG)m_szTextBoxBuffer); // Replace the selection with the message } if (szMessage != NULL) //print the sender's message { SendDlgItemMessage(m_hDlg, IDC_CHATAREA_EDIT,WM_GETTEXT, TEXTMAXSIZE-1,(LONG)m_szTextBoxBuffer); cr.cpMax = strlen(m_szTextBoxBuffer); // Select the last caracter to make the text insertion cr.cpMin = cr.cpMax; SendDlgItemMessage(m_hDlg, IDC_CHATAREA_EDIT,EM_EXSETSEL,0,(LONG) &cr); /***/ SetTextFormat(false, false, 0x75, "MS Sans Serif", dwColor != GREY ? BLACK : GREY); _snprintf(m_szTextBoxBuffer, TEXTMAXSIZE-1, "%s", szMessage); SendDlgItemMessage(m_hDlg, IDC_CHATAREA_EDIT,EM_REPLACESEL,FALSE,(LONG)m_szTextBoxBuffer); } // Scroll down the chat window // The following seems necessary under W9x & Me if we want the Edit to scroll to bottom... SCROLLINFO si; ZeroMemory(&si, sizeof(SCROLLINFO)); si.cbSize = sizeof(SCROLLINFO); si.fMask = SIF_RANGE|SIF_PAGE; GetScrollInfo(GetDlgItem(m_hDlg, IDC_CHATAREA_EDIT), SB_VERT, &si); si.nPos = si.nMax - max(si.nPage - 1, 0); SendDlgItemMessage(m_hDlg, IDC_CHATAREA_EDIT, WM_VSCROLL, MAKELONG(SB_THUMBPOSITION, si.nPos), 0L); // Scroll down the ch // This line does the bottom scrolling correctly under NT4,W2K, XP... // SendDlgItemMessage(m_hDlg, IDC_CHATAREA_EDIT, WM_VSCROLL, SB_BOTTOM, 0L); }
// ---------------------------------------------------------------- // Render // ---------------------------------------------------------------- void CD2DText::Render() { m_Matrix = D2D1::Matrix3x2F::Translation( 0, 0 ); m_pD2DRenderer->GetHwndRenderTarget()->SetTransform( m_Matrix ); SetTextFormat(); m_pD2DRenderer->GetHwndRenderTarget()->DrawTextW( m_Text.c_str(), wcslen(m_Text.c_str()), m_TextFormat, D2D1::RectF( 0, 0, m_pD2DRenderer->GetHwndRenderTarget()->GetSize().width, m_pD2DRenderer->GetHwndRenderTarget()->GetSize().height), m_Brush ); }
// 初始化 HRESULT TextFormatCache::Init(DWriteFactory** ppO) { s_ppDWriteFactory = ppO; #ifdef _DEBUG if (!s_ppDWriteFactory || !(*s_ppDWriteFactory)){ MessageBoxW(nullptr, L"参数错误!\n INVALIDARG!", L"Error", MB_OK); return E_INVALIDARG; } #endif // 检查自定义字体 HRESULT hr = S_OK; UINT fileCount = 0; SArray<WCHAR*, 256> aryFilePath(nullptr); WIN32_FIND_DATA fileinfo; HANDLE hFile = FindFirstFileW(L"Font/*.*tf", &fileinfo); DWORD errorcode = 0; while (hFile != INVALID_HANDLE_VALUE&&errorcode != ERROR_NO_MORE_FILES) { aryFilePath[fileCount] = (WCHAR*)MPool.Alloc(MAX_PATH); if (!aryFilePath[fileCount]){ hr = E_OUTOFMEMORY; break; } //wcscpy_s(aryFilePath[fileCount], MAX_PATH, fileinfo.cFileName); wsprintf(aryFilePath[fileCount], L"Font/%s", fileinfo.cFileName); ++fileCount; FindNextFile(hFile, &fileinfo); errorcode = GetLastError(); } FindClose(hFile); hFile = nullptr; // if (!fileCount) goto seek_text_format; // 载入字体 s_pLoader = new LocalFontCollectionLoader; if (!s_pLoader) return E_OUTOFMEMORY; hr = (*s_ppDWriteFactory)->RegisterFontCollectionLoader(s_pLoader); if (FAILED(hr)) { MessageBoxW(nullptr, L"RegisterFontCollectionLoader 失败-Failed", L"Error", MB_OK); return hr; } // hr = (*s_ppDWriteFactory)->CreateCustomFontCollection(s_pLoader, aryFilePath, fileCount * sizeof aryFilePath[0], &s_pCollection); if (FAILED(hr)) { MessageBoxW(nullptr, L"CreateCustomFontCollection 失败-Failed", L"Error", MB_OK); return hr; } // 载入系统笔刷 seek_text_format: std::ifstream ifs("Data/system.tft", std::ios::binary); UINT32 data, length; TextFormatCache::TextFormatParameter* pParameter(nullptr); if (ifs.good()){ // 读取首数据 ifs.read((char*)&data, sizeof data); for (UINT i = 0; i < data; ++i){ // 读取长度 ifs.read((char*)&length, sizeof length); if (length){ if (pParameter = (TextFormatParameter*)MPool.Alloc(length)){ pParameter->this_length = length; ifs.read((char*)&(pParameter->verson), length - sizeof(length)); // 检查版本 // if(pParameter->verson) SetTextFormat(i, pParameter); MPool.Free(pParameter); } } } ifs.close(); } // 设定C++笔刷 return S_OK; }
VALUE TextFormatCache::RB_CreateFont(int argc, VALUE* argv, VALUE self){ if (argc < 3 || argc > 13) { rb_raise(rb_eArgError, "wrong number of arguments\n参数数量出错"); return Qfalse; } /* 参数说明: create_font(index, font_name, font_size, [font_weight, font_style, font_stretch, text_alignmen, paragraph_alignment, word_wrapping, incremental_tabstop, line_spacing_method, line_spacing, baseline]) */ wchar_t buffer[MAX_PATH]; UINT length = ::MultiByteToWideChar(CP_UTF8, NULL, RSTRING_PTR(argv[1]), RSTRING_LEN(argv[1]) + 1, buffer, sizeof buffer); // 多用几字节又不会死 UINT this_length = length + sizeof TextFormatParameter; TextFormatParameter* pParameter((TextFormatParameter*)MPool.Alloc(this_length)); if (pParameter){ new(pParameter)TextFormatParameter(); pParameter->this_length = this_length; // font_name wcscpy_s(pParameter->font_name, length, buffer); // font_size pParameter->font_size = RB_INT_FLOAT_TO_FLOAT(argv[2]); // font_weight if (argc >= 4){ pParameter->font_weight = (DWRITE_FONT_WEIGHT)FIX2INT(argv[3]); } // font_style if (argc >= 5){ pParameter->font_style = (DWRITE_FONT_STYLE)FIX2INT(argv[4]); } // font_style if (argc >= 6){ pParameter->font_stretch = (DWRITE_FONT_STRETCH)FIX2INT(argv[5]); } // text_alignmen if (argc >= 7){ pParameter->text_alignmen = (DWRITE_TEXT_ALIGNMENT)FIX2INT(argv[6]); } // paragraph_alignment if (argc >= 8){ pParameter->paragraph_alignment = (DWRITE_PARAGRAPH_ALIGNMENT)FIX2INT(argv[7]); } // word_wrapping if (argc >= 9){ pParameter->word_wrapping = (DWRITE_WORD_WRAPPING)FIX2INT(argv[8]); } // incremental_tabstop if (argc >= 10){ pParameter->incremental_tabstop = RB_INT_FLOAT_TO_FLOAT(argv[9]); } // line_spacing_method if (argc >= 11){ pParameter->line_spacing_method = (DWRITE_LINE_SPACING_METHOD)FIX2INT(argv[10]); } // line_spacing if (argc >= 12){ pParameter->line_spacing = RB_INT_FLOAT_TO_FLOAT(argv[11]); } // baseline if (argc >= 13){ pParameter->baseline = RB_INT_FLOAT_TO_FLOAT(argv[12]); } auto rcode = SetTextFormat(FIX2INT(*argv), pParameter); MPool.Free(pParameter); return rcode ? Qtrue : Qfalse; } return Qfalse; }