FOX-TOOLKIT的网站及简介:
www.fox-toolkit.org
FOX is a C++ based Toolkit for developing Graphical User Interfaces easily and effectively. It offers a wide, and growing, collection of Controls, and provides state of the art facilities such as drag and drop, selection, as well as OpenGL widgets for 3D graphical manipulation. FOX also implements icons, images, and user-convenience features such as status line help, and tooltips. Tooltips may even be used for 3D objects!
刚开始学习FOX TOOLKIT,做了一个简单的文本显示例子,在Windows平台上我使用了MultiByteToWideChar来实现代码页转换,如果谁能有基于FOX的解决方案,欢迎进行指点和帮助。
对比WTL,FOX在界面设计和消息传递上要更加简洁和灵活,缺点是不支持本地UI。在本程序中FXText控件的执行效率较低,可以考虑使用fxscintilla来代替。
1
//
FoxTest.cpp : 定义控制台应用程序的入口点。
2
//
3
#include
"
stdafx.h
"
4
#include
<
fx.h
>
5
#include
<
windows.h
>
6
7
class
TextWindow :
public
FXMainWindow
8
{
9
FXDECLARE(TextWindow)
10
public
:
11
TextWindow(){}
12
~
TextWindow(){}
13
public
:
14
enum
{
15
ID_QUIT
=
FXMainWindow::ID_LAST,
16
ID_TEXT,
17
ID_DIRECTORYLIST,
18
ID_UPDATE_FILE,
19
};
20
public
:
21
FXDirList
*
dirlist;
22
FXText
*
editor;
23
FXString filename;
24
public
:
25
TextWindow(FXApp
*
app);
26
virtual
void
create();
27
FXbool loadFile(
const
FXString
&
file);
28
void
DumpWidgets();
29
public
:
30
long
onCmdQuit(FXObject
*
,FXSelector,
void
*
);
31
long
onCmdOpenFile(FXObject
*
,FXSelector,
void
*
);
32
long
onUpdateFile(FXObject
*
,FXSelector,
void
*
);
33
};
34
35
FXDEFMAP(TextWindow) TextWindowMap[]
=
{
36
FXMAPFUNC(SEL_COMMAND, TextWindow::ID_DIRECTORYLIST, TextWindow::onCmdOpenFile),
37
FXMAPFUNC(SEL_COMMAND, TextWindow::ID_QUIT, TextWindow::onCmdQuit),
38
FXMAPFUNC(SEL_UPDATE, TextWindow::ID_UPDATE_FILE, TextWindow::onUpdateFile),
39
};
40
41
FXIMPLEMENT(TextWindow,FXMainWindow,TextWindowMap,ARRAYNUMBER(TextWindowMap))
42
43
TextWindow::TextWindow(FX::FXApp
*
app): FXMainWindow(app,L
"
FOX TOOLKIT学习 - 显示文本 make: VisualFC 2009.6.24
"
,NULL,NULL,DECOR_ALL,
0
,
0
,
800
,
600
)
44
{
45
new
FXToolTip(app);
46
47
new
FXStatusBar(
this
,LAYOUT_SIDE_BOTTOM
|
LAYOUT_FILL_X);
48
49
FXHorizontalFrame
*
main
=
new
FXHorizontalFrame(
this
,LAYOUT_SIDE_TOP
|
LAYOUT_FILL_X
|
LAYOUT_FILL_Y
|
FRAME_RAISED);
50
51
FXSplitter
*
splitter
=
new
FXSplitter(main,LAYOUT_SIDE_TOP
|
FRAME_RAISED
|
LAYOUT_FILL_X
|
LAYOUT_FILL_Y
|
SPLITTER_TRACKING);
52
53
FXVerticalFrame
*
group1
=
new
FXVerticalFrame(splitter,LAYOUT_FIX_WIDTH
|
LAYOUT_FILL_Y
|
FRAME_THICK
|
FRAME_SUNKEN,
0
,
0
,
180
,
0
,
0
,
0
,
0
,
0
,
0
,
0
);
54
FXVerticalFrame
*
group2
=
new
FXVerticalFrame(splitter,LAYOUT_FILL_X
|
LAYOUT_FILL_Y
|
FRAME_THICK
|
FRAME_SUNKEN,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
);
55
56
FXHorizontalFrame
*
header1
=
new
FXHorizontalFrame(group1,LAYOUT_FILL_X
|
FRAME_RAISED
|
FRAME_THICK,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
);
57
new
FXLabel(header1,L
"
目录
"
,NULL,LAYOUT_FILL_X
|
JUSTIFY_LEFT);
58
new
FXButton(header1,L
"
×/t隐藏目录/t隐藏目录选择窗口
"
,NULL,group1,FXWindow::ID_HIDE,BUTTON_TOOLBAR
|
FRAME_RAISED,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
);
59
60
dirlist
=
new
FXDirList(group1,
this
,ID_DIRECTORYLIST,DIRLIST_SHOWFILES
|
LAYOUT_FILL_X
|
LAYOUT_FILL_Y
|
LAYOUT_TOP
|
LAYOUT_RIGHT
|
TREELIST_SHOWS_LINES
|
TREELIST_SHOWS_BOXES
|
TREELIST_BROWSESELECT
|
DIRLIST_NO_OWN_ASSOC);
61
62
FXHorizontalFrame
*
header2
=
new
FXHorizontalFrame(group2,LAYOUT_FILL_X
|
FRAME_RAISED
|
FRAME_THICK,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
);
63
FXLabel
*
fileslabel
=
new
FXLabel(header2,L
"
显示文件 :
"
,NULL,LAYOUT_FILL_X
|
JUSTIFY_LEFT);
64
fileslabel
->
setTarget(
this
);
65
fileslabel
->
setSelector(ID_UPDATE_FILE);
66
67
new
FXButton(header2,L
"
>>/t显示目录/t显示目录选择窗口
"
,NULL,group1,FXWindow::ID_SHOW,BUTTON_TOOLBAR
|
FRAME_RAISED,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
);
68
editor
=
new
FXText(group2,
this
,ID_TEXT,LAYOUT_FILL_X
|
LAYOUT_FILL_Y);
//
|FRAME_RAISED|FRAME_THICK |TEXT_WORDWRAP);
69
editor
->
setHiliteMatchTime(
2000000000
);
70
//
editor->setBarColumns(6);
71
DumpWidgets();
72
}
73
74
void
TextWindow::create()
75
{
76
FXMainWindow::create();
77
show(PLACEMENT_SCREEN);
78
}
79
80
long
TextWindow::onCmdQuit(FXObject
*
,FXSelector,
void
*
)
81
{
82
getApp()
->
exit();
83
return
1
;
84
}
85
86
long
TextWindow::onCmdOpenFile(FXObject
*
,FXSelector,
void
*
ptr)
87
{
88
FXTreeItem
*
item
=
(FXTreeItem
*
)ptr;
89
FXString file;
90
if
(
!
item
||
!
dirlist
->
isItemFile(item))
return
1
;
91
92
file
=
dirlist
->
getItemPathname(item);
93
editor
->
setText(
""
);
94
if
(loadFile(file)){
95
filename
=
file;
96
}
97
98
return
1
;
99
}
100
101
void
TextWindow::DumpWidgets()
102
{
103
register FXWindow
*
w
=
getApp()
->
getRootWindow();
104
register FXObject
*
t;
105
register FXint lev
=
0
;
106
register FXchar s;
107
FXString str
=
"
FOX TOOLKIT Dump Widgets:/n
"
;
108
FXString tmp;
109
while
(w){
110
t
=
w
->
getTarget();
111
s
=
w
->
shown()
?
'
+
'
:
'
-
'
;
112
if
(t){
113
tmp.format(
"
%*c%s (%p): wk=%d id=%lu target=%s (%p) sel=%d x=%d y=%d w=%d h=%d/n
"
,lev
*
2
,s,w
->
getClassName(),w,w
->
getKey(),w
->
id(),t
->
getClassName(),t,w
->
getSelector(),w
->
getX(),w
->
getY(),w
->
getWidth(),w
->
getHeight());
114
str.append(tmp);
115
}
116
else
{
117
tmp.format(
"
%*c%s (%p): wk=%d id=%lu x=%d y=%d w=%d h=%d/n
"
,lev
*
2
,s,w
->
getClassName(),w,w
->
getKey(),w
->
id(),w
->
getX(),w
->
getY(),w
->
getWidth(),w
->
getHeight());
118
str.append(tmp);
119
}
120
if
(w
->
getFirst()){
121
w
=
w
->
getFirst();
122
lev
++
;
123
continue
;
124
}
125
while
(
!
w
->
getNext()
&&
w
->
getParent()){
126
w
=
w
->
getParent();
127
lev
--
;
128
if
(lev
==
1
) str.append(
"
/n
"
);
129
}
130
w
=
w
->
getNext();
131
}
132
editor
->
setText(str);
133
}
134
135
long
TextWindow::onUpdateFile(FXObject
*
sender,FXSelector,
void
*
)
136
{
137
FXString
string
=
L
"
显示文件 :
"
+
filename;
138
sender
->
handle(
this
,FXSEL(SEL_COMMAND,FXWindow::ID_SETSTRINGVALUE),(
void
*
)
&
string
);
139
return
1
;
140
}
141
142
143
FXbool TextWindow::loadFile(
const
FXString
&
file){
144
145
FXFile textfile(file,FXFile::Reading);
146
147
//
Opened file?
148
if
(textfile.isOpen()){
149
FXchar
*
text; FXint size,n,i,j,c;
150
151
//
Get file size
152
size
=
textfile.size();
153
//
限制最大读取字节为10MB
154
if
(size
>=
10240
*
1024
)
155
size
=
10240
*
1024
;
156
157
//
Make buffer to load file
158
if
(allocElms(text,size)){
159
160
//
Set wait cursor
161
getApp()
->
beginWaitCursor();
162
163
//
Read the file
164
n
=
textfile.readBlock(text,size);
165
if
(
0
<
n){
166
#ifdef WIN32
167
//
使用了 MultiByteToWideChar 实现代码页转换,只能用于Windows环境
168
int
buf_len
=
MultiByteToWideChar(CP_ACP,
0
, text, size,NULL,
0
);
169
wchar_t
*
data
=
new
wchar_t[buf_len
+
1
];
170
data[
0
]
=
L
'
/0
'
;
171
buf_len
=
MultiByteToWideChar(
0
,
0
, text, size,data, buf_len);
172
data[buf_len]
=
_T(
'
/0
'
);
173
174
for
(i
=
j
=
0
; j
<
buf_len; j
++
){
175
c
=
data[j];
176
if
(c
!=
L
'
/r
'
){
177
data[i
++
]
=
c;
178
}
179
}
180
n
=
i;
181
data[n]
=
L
'
/0
'
;
182
editor
->
setText(data);
183
delete[] data;
184
#else
185
for
(i
=
j
=
0
; j
<
n; j
++
){
186
c
=
text[j];
187
if
(c
!=
'
/r
'
){
188
text[i
++
]
=
c;
189
}
190
}
191
n
=
i;
192
editor
->
setText(text,n);
193
#endif
194
}
195
//
Kill wait cursor
196
getApp()
->
endWaitCursor();
197
//
Free buffer
198
freeElms(text);
199
return
true
;
200
}
201
}
202
editor
->
setText(
""
);
203
204
return
false
;
205
}
206
207
int
main(
int
argc,
char
*
argv[])
208
{
209
FXApp app;
210
app.init(argc,argv);
211
TextWindow
*
win
=
new
TextWindow(
&
app);
212
app.create();
213
return
app.run();
214
}
215
216