// 汉字字符串转换为拼音 // 如果函数中已经MessageBox报错,则strError第一字符会为空格 // return: // -1 出错 // 0 用户希望中断 // 1 正常 public int SmartHanziTextToPinyin( string strText, PinyinStyle style, out string strPinyin, out string strError) { strPinyin = ""; strError = ""; Stop new_stop = new DigitalPlatform.Stop(); new_stop.Register(MainForm.stopManager, true); // 和容器关联 new_stop.OnStop += new StopEventHandler(new_stop_OnStop); new_stop.Initial("正在获得 '" + strText + "' 的拼音信息 (从服务器 " + this.MainForm.PinyinServerUrl + ")..."); new_stop.BeginLoop(); m_gcatClient = null; try { m_gcatClient = GcatNew.CreateChannel(this.MainForm.PinyinServerUrl); REDO_GETPINYIN: int nStatus = -1; // 前面一个字符的类型 -1:前面没有字符 0:普通英文字母 1:空格 2:汉字 string strPinyinXml = ""; // return: // -2 strID验证失败 // -1 出错 // 0 成功 int nRet = GcatNew.GetPinyin( new_stop, m_gcatClient, m_strPinyinGcatID, strText, out strPinyinXml, out strError); if (nRet == -1) { DialogResult result = MessageBox.Show(this, "从服务器 '" + this.MainForm.PinyinServerUrl + "' 获取拼音的过程出错:\r\n" + strError + "\r\n\r\n是否要临时改为使用本机加拼音功能? \r\n\r\n(注:临时改用本机拼音的状态在程序退出时不会保留。如果要永久改用本机拼音方式,请使用主菜单的“参数配置”命令,将“服务器”属性页的“拼音服务器URL”内容清空)", "EntityForm", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2); if (result == System.Windows.Forms.DialogResult.Yes) { this.MainForm.ForceUseLocalPinyinFunc = true; strError = "将改用本机拼音,请重新操作一次。(本次操作出错: " + strError + ")"; return -1; } strError = " " + strError; return -1; } if (nRet == -2) { IdLoginDialog login_dlg = new IdLoginDialog(); login_dlg.Text = "获得拼音 -- " + ((string.IsNullOrEmpty(this.m_strPinyinGcatID) == true) ? "请输入ID" : strError); login_dlg.ID = this.m_strPinyinGcatID; login_dlg.SaveID = this.m_bSavePinyinGcatID; login_dlg.StartPosition = FormStartPosition.CenterScreen; if (login_dlg.ShowDialog(this) == DialogResult.Cancel) { return 0; } this.m_strPinyinGcatID = login_dlg.ID; this.m_bSavePinyinGcatID = login_dlg.SaveID; goto REDO_GETPINYIN; } XmlDocument dom = new XmlDocument(); try { dom.LoadXml(strPinyinXml); } catch (Exception ex) { strError = "strPinyinXml装载到XMLDOM时出错: " + ex.Message; return -1; } foreach (XmlNode nodeWord in dom.DocumentElement.ChildNodes) { if (nodeWord.NodeType == XmlNodeType.Text) { SelPinyinDlg.AppendText(ref strPinyin, nodeWord.InnerText); nStatus = 0; continue; } if (nodeWord.NodeType != XmlNodeType.Element) continue; string strWordPinyin = DomUtil.GetAttr(nodeWord, "p"); if (string.IsNullOrEmpty(strWordPinyin) == false) strWordPinyin = strWordPinyin.Trim(); // 目前只取多套读音的第一套 nRet = strWordPinyin.IndexOf(";"); if (nRet != -1) strWordPinyin = strWordPinyin.Substring(0, nRet).Trim(); string[] pinyin_parts = strWordPinyin.Split(new char[] { ' ' }); int index = 0; // 让选择多音字 foreach (XmlNode nodeChar in nodeWord.ChildNodes) { if (nodeChar.NodeType == XmlNodeType.Text) { SelPinyinDlg.AppendText(ref strPinyin, nodeChar.InnerText); nStatus = 0; continue; } string strHanzi = nodeChar.InnerText; string strCharPinyins = DomUtil.GetAttr(nodeChar, "p"); if (String.IsNullOrEmpty(strCharPinyins) == true) { strPinyin += strHanzi; nStatus = 0; index++; continue; } if (strCharPinyins.IndexOf(";") == -1) { DomUtil.SetAttr(nodeChar, "sel", strCharPinyins); SelPinyinDlg.AppendPinyin(ref strPinyin, SelPinyinDlg.ConvertSinglePinyinByStyle( strCharPinyins, style) ); nStatus = 2; index++; continue; } #if _TEST_PINYIN // 调试! string[] parts = strCharPinyins.Split(new char[] {';'}); { DomUtil.SetAttr(nodeChar, "sel", parts[0]); AppendPinyin(ref strPinyin, parts[0]); nStatus = 2; index++; continue; } #endif string strSampleText = ""; int nOffs = -1; SelPinyinDlg.GetOffs(dom.DocumentElement, nodeChar, out strSampleText, out nOffs); { // 如果是多个拼音 SelPinyinDlg dlg = new SelPinyinDlg(); float ratio_single = dlg.listBox_multiPinyin.Font.SizeInPoints / dlg.Font.SizeInPoints; float ratio_sample = dlg.textBox_sampleText.Font.SizeInPoints / dlg.Font.SizeInPoints; GuiUtil.SetControlFont(dlg, this.Font, false); // 维持字体的原有大小比例关系 dlg.listBox_multiPinyin.Font = new Font(dlg.Font.FontFamily, ratio_single * dlg.Font.SizeInPoints, GraphicsUnit.Point); dlg.textBox_sampleText.Font = new Font(dlg.Font.FontFamily, ratio_sample * dlg.Font.SizeInPoints, GraphicsUnit.Point); // 这个对话框比较特殊 GuiUtil.SetControlFont(dlg, this.Font, false); dlg.Text = "请选择汉字 '" + strHanzi + "' 的拼音 (来自服务器 " + this.MainForm.PinyinServerUrl + ")"; dlg.SampleText = strSampleText; dlg.Offset = nOffs; dlg.Pinyins = strCharPinyins; if (index < pinyin_parts.Length) dlg.ActivePinyin = pinyin_parts[index]; dlg.Hanzi = strHanzi; MainForm.AppInfo.LinkFormState(dlg, "SelPinyinDlg_state"); dlg.ShowDialog(this); MainForm.AppInfo.UnlinkFormState(dlg); Debug.Assert(DialogResult.Cancel != DialogResult.Abort, "推断"); if (dlg.DialogResult == DialogResult.Abort) { return 0; // 用户希望整个中断 } DomUtil.SetAttr(nodeChar, "sel", dlg.ResultPinyin); if (dlg.DialogResult == DialogResult.Cancel) { SelPinyinDlg.AppendText(ref strPinyin, strHanzi); nStatus = 2; } else if (dlg.DialogResult == DialogResult.OK) { SelPinyinDlg.AppendPinyin(ref strPinyin, SelPinyinDlg.ConvertSinglePinyinByStyle( dlg.ResultPinyin, style) ); nStatus = 2; } else { Debug.Assert(false, "SelPinyinDlg返回时出现意外的DialogResult值"); } index++; } } } #if _TEST_PINYIN #else // return: // -2 strID验证失败 // -1 出错 // 0 成功 nRet = GcatNew.SetPinyin( new_stop, m_gcatClient, "", dom.DocumentElement.OuterXml, out strError); if (nRet == -1) return -1; #endif return 1; } finally { new_stop.EndLoop(); new_stop.OnStop -= new StopEventHandler(new_stop_OnStop); new_stop.Initial(""); new_stop.Unregister(); if (m_gcatClient != null) { m_gcatClient.Close(); m_gcatClient = null; } } }
// 获得著者号 // return: // -1 error // 0 canceled // 1 succeed public int GetGcatAuthorNumber(string strGcatWebServiceUrl, string strAuthor, out string strAuthorNumber, out string strError) { strError = ""; strAuthorNumber = ""; if (String.IsNullOrEmpty(strGcatWebServiceUrl) == true) strGcatWebServiceUrl = "http://dp2003.com/gcatserver/"; // "http://dp2003.com/dp2libraryws/gcat.asmx"; if (strGcatWebServiceUrl.IndexOf(".asmx") != -1) { if (this.GcatChannel == null) this.GcatChannel = new DigitalPlatform.GcatClient.Channel(); string strDebugInfo = ""; BeginGcatLoop("正在获取 '" + strAuthor + "' 的著者号,从 " + strGcatWebServiceUrl + " ..."); try { // return: // -1 error // 0 canceled // 1 succeed int nRet = this.GcatChannel.GetNumber( this.DetailForm.stop, this.DetailForm, strGcatWebServiceUrl, strAuthor, true, // bSelectPinyin true, // bSelectEntry true, // bOutputDebugInfo new DigitalPlatform.GcatClient.BeforeLoginEventHandle(gcat_channel_BeforeLogin), out strAuthorNumber, out strDebugInfo, out strError); if (nRet == -1) { strError = "取 著者 '" + strAuthor + "' 之号码时出错 : " + strError; return -1; } return nRet; } finally { EndGcatLoop(); } } else { // 新的WebService string strID = this.DetailForm.MainForm.AppInfo.GetString("DetailHost", "gcat_id", ""); bool bSaveID = this.DetailForm.MainForm.AppInfo.GetBoolean("DetailHost", "gcat_saveid", false); Hashtable question_table = (Hashtable)this.DetailForm.MainForm.ParamTable["question_table"]; if (question_table == null) question_table = new Hashtable(); REDO_GETNUMBER: string strDebugInfo = ""; BeginGcatLoop("正在获取 '" + strAuthor + "' 的著者号,从 " + strGcatWebServiceUrl + " ..."); try { // return: // -1 error // 0 canceled // 1 succeed int nRet = GcatNew.GetNumber( ref question_table, this.DetailForm.stop, this.DetailForm, strGcatWebServiceUrl, strID, // ID strAuthor, true, // bSelectPinyin true, // bSelectEntry true, // bOutputDebugInfo out strAuthorNumber, out strDebugInfo, out strError); if (nRet == -1) { strError = "取 著者 '" + strAuthor + "' 之号码时出错 : " + strError; return -1; } if (nRet == -2) { IdLoginDialog login_dlg = new IdLoginDialog(); GuiUtil.AutoSetDefaultFont(login_dlg); login_dlg.Text = "获得著者号 -- " + ((string.IsNullOrEmpty(strID) == true) ? "请输入ID" : strError); login_dlg.ID = strID; login_dlg.SaveID = bSaveID; login_dlg.StartPosition = FormStartPosition.CenterScreen; if (login_dlg.ShowDialog(this.DetailForm) == DialogResult.Cancel) { return -1; } strID = login_dlg.ID; bSaveID = login_dlg.SaveID; if (login_dlg.SaveID == true) { this.DetailForm.MainForm.AppInfo.SetString("DetailHost", "gcat_id", strID); } else { this.DetailForm.MainForm.AppInfo.SetString("DetailHost", "gcat_id", ""); } this.DetailForm.MainForm.AppInfo.SetBoolean("DetailHost", "gcat_saveid", bSaveID); goto REDO_GETNUMBER; } this.DetailForm.MainForm.ParamTable["question_table"] = question_table; return nRet; } finally { EndGcatLoop(); } } }
// 汉字字符串转换为拼音。新版本 // 如果函数中已经MessageBox报错,则strError第一字符会为空格 /// <summary> /// 汉字字符串转换为拼音,智能方式 /// </summary> /// <param name="owner">用于函数中 MessageBox 和对话框 的宿主窗口</param> /// <param name="strText">输入字符串</param> /// <param name="style">转换为拼音的风格</param> /// <param name="strDuoyinStyle">是否自动选择多音字。auto/first 的一个或者组合。如果为 auto,first 表示优先按照智能拼音选择,没有智能拼音的,选择第一个</param> /// <param name="strPinyin">返回拼音字符串</param> /// <param name="strError">返回出错信息</param> /// <returns>-1: 出错; 0: 用户希望中断; 1: 正常; 2: 结果字符串中有没有找到拼音的汉字</returns> public int SmartHanziTextToPinyin( IWin32Window owner, string strText, PinyinStyle style, string strDuoyinStyle, // bool bAutoSel, out string strPinyin, out string strError) { strPinyin = ""; strError = ""; bool bAuto = StringUtil.IsInList("auto", strDuoyinStyle); bool bFirst = StringUtil.IsInList("first", strDuoyinStyle); bool bNotFoundPinyin = false; // 是否出现过没有找到拼音、只能把汉字放入结果字符串的情况 Stop new_stop = new DigitalPlatform.Stop(); new_stop.Register(this.stopManager, true); // 和容器关联 new_stop.OnStop += new StopEventHandler(new_stop_OnStop); new_stop.Initial("正在获得 '" + strText + "' 的拼音信息 (从服务器 " + this.PinyinServerUrl + ")..."); new_stop.BeginLoop(); m_gcatClient = null; try { m_gcatClient = GcatNew.CreateChannel(this.PinyinServerUrl); REDO_GETPINYIN: //int nStatus = -1; // 前面一个字符的类型 -1:前面没有字符 0:普通英文字母 1:空格 2:汉字 string strPinyinXml = ""; // return: // -2 strID验证失败 // -1 出错 // 0 成功 int nRet = GcatNew.GetPinyin( new_stop, m_gcatClient, m_strPinyinGcatID, strText, out strPinyinXml, out strError); if (nRet == -1) { if (new_stop != null && new_stop.State != 0) return 0; DialogResult result = MessageBox.Show(owner, "从服务器 '" + this.PinyinServerUrl + "' 获取拼音的过程出错:\r\n" + strError + "\r\n\r\n是否要临时改为使用本机加拼音功能? \r\n\r\n(注:临时改用本机拼音的状态在程序退出时不会保留。如果要永久改用本机拼音方式,请使用主菜单的“参数配置”命令,将“服务器”属性页的“拼音服务器URL”内容清空)", "EntityForm", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2); if (result == System.Windows.Forms.DialogResult.Yes) { this.ForceUseLocalPinyinFunc = true; strError = "将改用本机拼音,请重新操作一次。(本次操作出错: " + strError + ")"; return -1; } strError = " " + strError; return -1; } if (nRet == -2) { IdLoginDialog login_dlg = new IdLoginDialog(); login_dlg.Text = "获得拼音 -- " + ((string.IsNullOrEmpty(this.m_strPinyinGcatID) == true) ? "请输入ID" : strError); login_dlg.ID = this.m_strPinyinGcatID; login_dlg.SaveID = this.m_bSavePinyinGcatID; login_dlg.StartPosition = FormStartPosition.CenterScreen; if (login_dlg.ShowDialog(owner) == DialogResult.Cancel) { return 0; } this.m_strPinyinGcatID = login_dlg.ID; this.m_bSavePinyinGcatID = login_dlg.SaveID; goto REDO_GETPINYIN; } XmlDocument dom = new XmlDocument(); try { dom.LoadXml(strPinyinXml); } catch (Exception ex) { strError = "strPinyinXml装载到XMLDOM时出错: " + ex.Message; return -1; } foreach (XmlNode nodeWord in dom.DocumentElement.ChildNodes) { if (nodeWord.NodeType == XmlNodeType.Text) { SelPinyinDlg.AppendText(ref strPinyin, nodeWord.InnerText); //nStatus = 0; continue; } if (nodeWord.NodeType != XmlNodeType.Element) continue; string strWordPinyin = DomUtil.GetAttr(nodeWord, "p"); if (string.IsNullOrEmpty(strWordPinyin) == false) strWordPinyin = strWordPinyin.Trim(); // 目前只取多套读音的第一套 nRet = strWordPinyin.IndexOf(";"); if (nRet != -1) strWordPinyin = strWordPinyin.Substring(0, nRet).Trim(); string[] pinyin_parts = strWordPinyin.Split(new char[] { ' ' }); int index = 0; // 让选择多音字 foreach (XmlNode nodeChar in nodeWord.ChildNodes) { if (nodeChar.NodeType == XmlNodeType.Text) { SelPinyinDlg.AppendText(ref strPinyin, nodeChar.InnerText); //nStatus = 0; continue; } string strHanzi = nodeChar.InnerText; string strCharPinyins = DomUtil.GetAttr(nodeChar, "p"); if (String.IsNullOrEmpty(strCharPinyins) == true) { strPinyin += strHanzi; //nStatus = 0; index++; continue; } if (strCharPinyins.IndexOf(";") == -1) { DomUtil.SetAttr(nodeChar, "sel", strCharPinyins); SelPinyinDlg.AppendPinyin(ref strPinyin, SelPinyinDlg.ConvertSinglePinyinByStyle( strCharPinyins, style) ); //nStatus = 2; index++; continue; } #if _TEST_PINYIN // 调试! string[] parts = strCharPinyins.Split(new char[] {';'}); { DomUtil.SetAttr(nodeChar, "sel", parts[0]); AppendPinyin(ref strPinyin, parts[0]); nStatus = 2; index++; continue; } #endif string strSampleText = ""; int nOffs = -1; SelPinyinDlg.GetOffs(dom.DocumentElement, nodeChar, out strSampleText, out nOffs); { // 如果是多个拼音 SelPinyinDlg dlg = new SelPinyinDlg(); //float ratio_single = dlg.listBox_multiPinyin.Font.SizeInPoints / dlg.Font.SizeInPoints; //float ratio_sample = dlg.textBox_sampleText.Font.SizeInPoints / dlg.Font.SizeInPoints; MainForm.SetControlFont(dlg, this.Font, false); // 维持字体的原有大小比例关系 //dlg.listBox_multiPinyin.Font = new Font(dlg.Font.FontFamily, ratio_single * dlg.Font.SizeInPoints, GraphicsUnit.Point); //dlg.textBox_sampleText.Font = new Font(dlg.Font.FontFamily, ratio_sample * dlg.Font.SizeInPoints, GraphicsUnit.Point); // 这个对话框比较特殊 MainForm.SetControlFont(dlg, this.Font, false); dlg.Text = "请选择汉字 '" + strHanzi + "' 的拼音 (来自服务器 " + this.PinyinServerUrl + ")"; dlg.SampleText = strSampleText; dlg.Offset = nOffs; dlg.Pinyins = strCharPinyins; if (index < pinyin_parts.Length) dlg.ActivePinyin = pinyin_parts[index]; dlg.Hanzi = strHanzi; #if NO if (bAutoSel == true && string.IsNullOrEmpty(dlg.ActivePinyin) == false) { dlg.ResultPinyin = dlg.ActivePinyin; dlg.DialogResult = DialogResult.OK; } else { this.AppInfo.LinkFormState(dlg, "SelPinyinDlg_state"); dlg.ShowDialog(owner); this.AppInfo.UnlinkFormState(dlg); } #endif if (bAuto == true && string.IsNullOrEmpty(dlg.ActivePinyin) == false) { dlg.ResultPinyin = dlg.ActivePinyin; dlg.DialogResult = DialogResult.OK; } else if (bFirst == true && string.IsNullOrEmpty(dlg.Pinyins) == false) { dlg.ResultPinyin = SelPinyinDlg.GetFirstPinyin(dlg.Pinyins); dlg.DialogResult = DialogResult.OK; } else { this.AppInfo.LinkFormState(dlg, "SelPinyinDlg_state"); dlg.ShowDialog(owner); this.AppInfo.UnlinkFormState(dlg); } Debug.Assert(DialogResult.Cancel != DialogResult.Abort, "推断"); if (dlg.DialogResult == DialogResult.Abort) { return 0; // 用户希望整个中断 } DomUtil.SetAttr(nodeChar, "sel", dlg.ResultPinyin); if (dlg.DialogResult == DialogResult.Cancel) { SelPinyinDlg.AppendText(ref strPinyin, strHanzi); //nStatus = 2; bNotFoundPinyin = true; } else if (dlg.DialogResult == DialogResult.OK) { SelPinyinDlg.AppendPinyin(ref strPinyin, SelPinyinDlg.ConvertSinglePinyinByStyle( dlg.ResultPinyin, style) ); //nStatus = 2; } else { Debug.Assert(false, "SelPinyinDlg返回时出现意外的DialogResult值"); } index++; } } } #if _TEST_PINYIN #else // 2014/10/22 // 删除 word 下的 Text 节点 XmlNodeList text_nodes = dom.DocumentElement.SelectNodes("word/text()"); foreach (XmlNode node in text_nodes) { Debug.Assert(node.NodeType == XmlNodeType.Text, ""); node.ParentNode.RemoveChild(node); } // 把没有p属性的<char>元素去掉,以便上传 XmlNodeList nodes = dom.DocumentElement.SelectNodes("//char"); foreach (XmlNode node in nodes) { string strP = DomUtil.GetAttr(node, "p"); string strSelValue = DomUtil.GetAttr(node, "sel"); // 2013/9/13 if (string.IsNullOrEmpty(strP) == true || string.IsNullOrEmpty(strSelValue) == true) { XmlNode parent = node.ParentNode; parent.RemoveChild(node); // 把空的<word>元素删除 if (parent.Name == "word" && parent.ChildNodes.Count == 0 && parent.ParentNode != null) { parent.ParentNode.RemoveChild(parent); } } // TODO: 一个拼音,没有其他选择的,是否就不上载了? // 注意,前端负责新创建的拼音仍需上载;只是当初原样从服务器过来的,不用上载了 } if (dom.DocumentElement.ChildNodes.Count > 0) { // return: // -2 strID验证失败 // -1 出错 // 0 成功 nRet = GcatNew.SetPinyin( new_stop, m_gcatClient, "", dom.DocumentElement.OuterXml, out strError); if (nRet == -1) { if (new_stop != null && new_stop.State != 0) return 0; return -1; } } #endif if (bNotFoundPinyin == false) return 1; // 正常结束 return 2; // 结果字符串中有没有找到拼音的汉字 } finally { new_stop.EndLoop(); new_stop.OnStop -= new StopEventHandler(new_stop_OnStop); new_stop.Initial(""); new_stop.Unregister(); if (m_gcatClient != null) { m_gcatClient.Close(); m_gcatClient = null; } } }