原創 VisualFC
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來代替。
源碼下載:
http://www.shnenglu.com/Files/visualfc/FoxTest.zip程序運行界面如下:

程序代碼如下:
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