季版主,请指教...(非中文系统下显示中文界面)。
季版主,感谢您在这个帖子里的指点,
http://expert.csdn.net/Expert/topic/1327/1327619.xml
我已经解决了大部分的界面乱码问题(非中文系统下显示中文界面)。
但还有一些没有解决,比如:
1)TPageControl 的中文标签
2)TListBox 里的内容
3)TForm 的标题
4)Tmenu的菜单内容
5)TOpenDialog的Filter
你说过:
“对于那些仍然不能被正确显示的文字,一个办法就是将那些文字以资源(STRING
类型)的方法存放,然后在程序中动态添加这些存放在资源中的文字就可以了。”
请您详细说明一下,怎么使用资源解决上述乱码问题。
另外,关于自画菜单能否给些演示代码?
非常感谢! 问题点数:100、回复次数:31Top
1 楼pp616(坏蛋)回复于 2003-02-11 21:20:38 得分 3
自画。用图来表示。哪都不会错。Top
2 楼jishiping(JSP 季世平)回复于 2003-02-11 22:20:29 得分 20
首先,所有的字符,使用资源的方式都可以解决这个问题。但是使用资源
的缺陷是不明显,在设计时不能直接在界面上看到这些字符。
1)TPageControl 的中文标签 采用自画
2)TListBox 里的内容 属性Style设为lbOwnerDrawFixed就可以了
3)TForm 的标题 没有办法(只能使用资源文字)
4)Tmenu的菜单内容 采用自画
5)TOpenDialog的Filter 没有办法(只能使用资源文字)
1)TPageControl 的中文标签的自画:
属性OwnerDraw设为true,在事件OnDrawTab中写代码自画
void __fastcall TForm1::PageControlDrawTab(TCustomTabControl *Control,
int TabIndex, const TRect &Rect, bool Active)
{
((TRect*)&Rect)->top += 1;
DrawText(Control->Canvas->Handle, PageControl->
Pages[TabIndex]->Caption.c_str(), -1, (RECT*)
&Rect, DT_CENTER|DT_VCENTER|DT_SINGLELINE);
}
4)Tmenu的菜单内容的自画:
需要将菜单的属性OwnerDraw设为true,在每个菜单项的事件OnDrawItem
和OnMeasureItem里写代码:
void __fastcall TForm1::MenuDrawItem(TObject *Sender,
TCanvas *ACanvas, TRect &ARect, bool Selected)
{
TMenuItem* Item;
ACanvas->Pen->Style = psClear;
ACanvas->Rectangle(ARect);
ACanvas->Pen->Style = psSolid;
Item = dynamic_cast<TMenuItem*>(Sender);
ACanvas->Font->Charset = Font->Charset;
ACanvas->TextOut(ARect.Left+8, ARect.Top+2,
Item->Caption);
if (Item->ShortCut != 0) {
AnsiString str = ShortCutToText(Item->
ShortCut);
ACanvas->TextOut(ARect.Right-ACanvas->
TextWidth(str)-8, ARect.Top+2, str);
}
}
void __fastcall TForm1::MenuMeasureItem(TObject *Sender,
TCanvas *ACanvas, int &Width, int &Height)
{
TMenuItem* Item;
ACanvas->Font->Charset = Font->Charset;
Item = dynamic_cast<TMenuItem*>(Sender);
Width = 16 + ACanvas->TextWidth(Item->
Caption);
if (Item->ShortCut != 0) {
AnsiString str = ShortCutToText(Item
->ShortCut);
Width += 8 + ACanvas->TextWidth(str);
}
Height = 4 + ACanvas->TextHeight(Item->Caption);
}Top
3 楼jishiping(JSP 季世平)回复于 2003-02-11 22:31:03 得分 20
至于文字资源,可以写一个PAS文件,比如ReConst.pas,内容如下(这儿
我定义了3个字符串,这个文件的内容为横线中间的行):
-----------------------
unit ReConst;
interface
resourcestring
OKStr = '确定';
CancelStr = '取消';
CaptionStr = '窗口1标题';
implementation
end.
-------------------
将这个ReConst.pas文件假如Project中,然后打开这个文件,按Alt+F9
先编译这个PAS文件,编译成功后会自动生成ReConst.hpp文件,然后在
需要使用字符串的文件中,包含这个Reconst.hpp头文件,使用方法:
在字符串名前面加上“Reconst_”就表示你要使用的字符串。比如
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
Caption = Reconst_CaptionStr; //这样标题就是“窗口1标题”了
}Top
4 楼HenryGo(孺子牛)回复于 2003-02-11 22:41:26 得分 2
季版主的编程水平真是令人佩服的五体投地!
加油!
争取打进论坛专家排行榜前十名。Top
5 楼jishiping(JSP 季世平)回复于 2003-02-11 22:52:50 得分 18
补充说明,如果在设计时就将TPageControl 的属性OwnerDraw设为true,那么
在设计时就看不到TPageControl上的标签了。此时可以在设计时将OwnerDraw
设为false,而在程序中修改这个属性。
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
Caption = Reconst_CaptionStr; //这样标题就是“窗口1标题”了
PageControl1->OwnerDraw = true; //设计时属性OwnerDraw为false
}Top
6 楼sncel(地狱情人-杨勇)回复于 2003-02-12 08:46:30 得分 1
真是历害!Top
7 楼jbz(虚心求教)回复于 2003-02-12 09:31:38 得分 0
非常感谢!我先试试。Top
8 楼kingfish(工作很忙,很少来csdn...)回复于 2003-02-12 09:43:49 得分 1
学习!Top
9 楼Behard(我爱天安门)回复于 2003-02-12 09:49:56 得分 1
听课Top
10 楼tccsdn(紫乐)回复于 2003-02-12 10:13:09 得分 1
先学习Top
11 楼hdaq(一生何求)回复于 2003-02-12 10:49:13 得分 1
学习Top
12 楼ouygg(痞子酷)回复于 2003-02-12 11:00:25 得分 1
极大侠水平极高!!!!!!!!!
佩服!!!!!!!!!!!
Top
13 楼Lonemoon(月荒凉)回复于 2003-02-12 11:30:56 得分 1
markTop
14 楼45867371(45867371)回复于 2003-02-12 11:56:52 得分 1
佩!!!!!!!!!!!!!!!服!!!!!!!!!!!!!!!Top
15 楼zzddqq()回复于 2003-02-12 11:57:26 得分 1
太历害了,学习!Top
16 楼LiYaohui(Lee)回复于 2003-02-12 12:51:04 得分 1
学习ing...Top
17 楼cscer(时光之石头)回复于 2003-02-12 12:53:10 得分 1
感谢!
学习……Top
18 楼yangguo_god(狂学java....)回复于 2003-02-12 13:05:12 得分 1
呵呵,学习Top
19 楼Jim3(Jim)回复于 2003-02-12 13:18:06 得分 1
收藏先
留着以后用Top
20 楼shally5(我在一旁静静的看着你)回复于 2003-02-12 14:33:01 得分 1
又学习了一次啊!
Top
21 楼penu(懒猫·子在川上之再上征程·杀人无心之寓怒于静)回复于 2003-02-12 17:12:07 得分 2
还有一种方法:制作小汉字库。Top
22 楼jbz(虚心求教)回复于 2003-02-13 10:42:22 得分 0
非常感谢季版主的热心帮忙,经过实践学习,已经解决了大部分问题。
现在我把测试过程中遇到的问题反馈一下,请季版主及各位同道再指点一下。
1)非常奇怪的现象:加入ReConst.pas后,每次编译成功后,内容没有变,再点击编译,它就又来一遍,每次编译都要重新生成ReConst.hpp文件!所有包含它的文件也都要随之编译,非常费时,不应该这样呀,我在资源管理器里发现,ReConst.pas的日期是昨天的,而ReConst.hpp日期则是现在(原来不是的,工程没有变动就不应该再编译的。)
2)我给PopupMenu1指定了ImageList1,在菜单项前面有图标,(设置了ImageIndex)请问:我如何在自画菜单时让图标也显示出来?
3)使用资源显示Form的标题已经成功了80%,大部分汉字可以显示,但有些显示的是“?”(例如“确定”的“确”字),同样的字在自画菜单里没有问题,说明资源ReConst.pas里的汉字不是GB2312_CHARSET?但这样在ReConst.pas中设置呢?
4)各控件的提示信息Hint,是不是也必须使用资源?如果是就比较麻烦了,因为太多了。
5)TRadioGroup的内容如何处理?Top
23 楼jbz(虚心求教)回复于 2003-02-13 16:30:22 得分 0
upTop
24 楼jbz(虚心求教)回复于 2003-02-13 17:25:36 得分 0
第2个问题我已经解决,在MenuDrawItem事件中加入下面代码就可以了。
int k=Item->ImageIndex;
if(k>=0)ImageList1->Draw(ACanvas,ARect.Left,ARect.Top+2,k,true);
其他几个问题请继续讨论。Top
25 楼jishiping(JSP 季世平)回复于 2003-02-15 12:27:40 得分 15
1)对于PAS文件,BCB就是这样子的。“每次编译都要重新生成ReConst.hpp
文件!所有包含它的文件也都要随之编译”,这个问题可以这样解决。将文
件ReConst.hpp改名为ReConst.h,然后其它文件包含ReConst.h,而不要使用
ReConst.hpp,这样最多只有ReConst.pas每次重新编译。当然,一旦你修改了
ReConst.pas文件,就需要将新的ReConst.hpp改名为ReConst.h。
3)对于使用pas文件产生的资源,我也不知道如何设定语言。这样吧,你用
RC格式的资源文件,就可以设定语言了。下面是Reconst.rc的内容:
LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED
#pragma code_page(936)
#include "Reconst.h"
STRINGTABLE
{
_OKStr, "确定"
_CancelStr, "取消"
_CaptionStr, "窗口1标题"
}
下面是Reconst.h的内容:
#define _OKStr 0xFF00
#define _CancelStr 0xFF01
#define _CaptionStr 0xFF02
#define Reconst_OKStr System::LoadResourceString(_MoveOK)
#define Reconst_CancelStr System::LoadResourceString(_CancelStr)
#define Reconst_CaptionStr System::LoadResourceString(_CaptionStr)
4)在主窗口的构造函数里写代码设定:
void SetAppShowHint(bool ShowHint)
{
THintWindow* HintWin;
Application->ShowHint = ShowHint;
for(int n=0; n<Application->ComponentCount;
n++) {
HintWin = dynamic_cast<THintWindow*>(
Application->Components[n]);
if (HintWin != NULL) {
HintWin->Canvas->Font->Charset =
GB2312_CHARSET;
break;
}
}
}
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
SetAppShowHint(true);
}
5)在你看到的那个帖子里,我已经说了。不要使用TRadioGroup自动生成
TRadioButton。自已拖放TRadioButton在TForm上。
TCheckBox和TRadioButton拆成2个控件(Box的大小只包含那个方框或者圆
圈,右边放一个TLabel,设置TLabel的属性FocusControl,然后在TLabel的
事件OnClick里设置TCheckBox和TRadioButton的Checked属性值)。下面是
TCheckBox和TRadioButton右边放置的TLabel的OnClick事件的函数代码:
void __fastcall TForm1::BoxLabelClick(TObject *Sender)
{
TLabel* Label;
TCheckBox* ChkBox;
TRadioButton* RdoBtn;
Label = dynamic_cast<TLabel*>(Sender);
if (Label==0 || !Label->FocusControl)
return;
ChkBox = dynamic_cast<TCheckBox*>(
Label->FocusControl);
RdoBtn = dynamic_cast<TRadioButton*>(
Label->FocusControl);
if (ChkBox!=0 && ChkBox->Enabled) {
ChkBox->Checked =
!ChkBox->Checked;
if (ChkBox->OnClick != 0)
ChkBox->OnClick(ChkBox);
}
else if(RdoBtn && RdoBtn->Enabled
&& !RdoBtn->Checked) {
RdoBtn->Checked = true;
if (RdoBtn->OnClick != 0)
RdoBtn->OnClick(RdoBtn);
}
}Top
26 楼jbz(虚心求教)回复于 2003-02-17 09:27:36 得分 0
感激得我无话可说,先把这个帖子结了,再另外酬谢。Top
27 楼cscer(时光之石头)回复于 2003-02-17 09:38:13 得分 1
学习……
感谢!Top
28 楼jbz(虚心求教)回复于 2003-02-17 10:58:26 得分 0
#define Reconst_CaptionStr System::LoadResourceString(_CaptionStr)
这一行在编译时出错:
[C++ Error] Romain.cpp(40): E2034 Cannot convert 'int' to 'const ResourceString *'
[C++ Error] Romain.cpp(40): E2342 Type mismatch in parameter 'rsrc' (wanted 'const ResourceString * const', got 'int')
我查LoadResourceString函数的帮助也找不到。Top
29 楼jishiping(JSP 季世平)回复于 2003-02-17 13:11:07 得分 5
将LoadResourceString改成LoadStr就可以了。Top
30 楼jbz(虚心求教)回复于 2003-02-17 15:05:06 得分 0
改成LoadStr通过了,但是发现下面设置语言的代码不起作用:
LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED
#pragma code_page(936)
和原来的结果一样,有些汉字还是不能正常显示(比如“确”字)。
看来不能追求完美了,开始研究多语言界面。不能显示中文的就用ENGLISH...