lccwin32 的 Resource Editor 的使用

本文用一个完整的小例子讲解如何用lcc-win32的LFC库(Lcc-win32 Foundation Classes,lcc-win32基础类)开发win32 应用程序。大概有以下四个步骤:

一、定义我们的需求;

二、创建Wedit工程;

三、创建对话框;

四、添加特定的代码。

以下我们一步一步讲解。

一、定义我们的需求

为了介绍如何使用Wedit和LFC,我们将开发一个帮助我们记住老朋友的小程序。这个小程序的用户界面基于对话框(Dialog Box),请见下图:

 分页控件(Tab control)选取人名的首字母,而combo box显示以该字母打头的所有人名,radio按钮给出Mrs,Miss或者Mr,日期控件显示生日,编缉框给出附加的信息。

应用程序拥有一个分页控件:当我们点选了一个页面程序就会显示所有以该页标签字母打头的人名,我们再选取一个朋友(人名),就能看到该朋友的相关信息,象生日等等。

二、创建Wedit工程

首先启动Wedit,创建一个新工程:

 我们接着给出工程名friends:

 我们要创建的是windows可执行程序:

现在我们要Wedit创建应用程序框架:

显然这是法语版的Wedit,不过没关系...我们需要基于对话框的程序:

程序框架已创建好了:

接下来我们要为编译器提供一些必需的信息。因要用到LFC,我们得将gc.lib,lfc.lib和weidtres.lib添加给链接器。点击'Next'来到向导下一页:

如果你愿意,现在就可以编译生成可执行程序,但那只是一个只有关闭按钮的对话框而已。我们得利用LFC深入写下去。

三、创建对话框

选取主菜单下"Design"->Open/New 来打开资源文件:

因是第一次打开资源文件,我们得指定哪个文件包含着资源定义以便把它添加进工程,这里我们选取friendsres.h,单击'OK':

然后在打开的资源编缉器窗口里双击打开对话框"IDD_MAINDIALOG 100 friends":

现在重头戏来了。我们看到了向导帮着自动创建起来的对话框。你可以通过单击选中整个对话框(也可以单击选中一个按钮),被选中的对象会被由多个红点组成的矩形框包围,它们允许我们改变被选中对象的大小。如果你按下Ctrl-Y键,你就能看到或是改变被选中对象的静态及动态属性:

你可以关闭属性设置窗口。在本程序中我们不需要OK和Cancel按钮,所以我们选中OK按Ctrl-Del,再选中Cancel再按Ctrl-Del。现在我们手上的是拥有标题和关闭按钮的对话框。我们把它拉大一点:选中对话框右下方的红色手柄然后向着屏幕右下拉动:

现在我们来添加分页控件(Tab Control)。把鼠标指向工具栏里的第一件工具(有向下箭头的那个)然后停顿一两秒,所有可用的控件就会显露出来:

选取分页控件(Tab Control):

然后在对话框上随便单击一下,分页控件就添加了进来,我们再改变一下它的大小:

现在我们把一个combo box控件添加给Tab Control:选中combo box然后把它扔进Tab Control:

combo box默认的式样不适合本程序的需要,我们右击它然后选择"Property":

属性对话框如下所示,我们选取简单式样"simple":

它的样子如下:

在右下把它拉大----一路拉到底,嗯,相当的大。我们在属性设置对话框里设置当它被选中时能够通知我们:首先右击combo box,选择"Property",在打开的窗口里选择"Dynamic",找到"Selection change",设置为"On":

现在我们再来添加第一个radio 按钮,我们鼠标指向工具栏,选取"Radio button":

把它扔在Combo box 的右边,并将主菜单正下方的名称字段(Name)的值改为RB_MRS,文本(Text)的值改为Mrs:

用同样的方法添加另两个radio 按钮,分别将Name 改为RB_MISS和RM_MR,将Text 改变Miss和Mr:

接着再选取日期控件,并改名为ID_DATE。再选取一个标签控件(Label),将它放在日期控件的左边。现在看起来应该象下面这样:

 最后选取一个文本控件,改变它的大小,使看起来这样:

现在所有的控件都已创建完成。你可以得新排一排,改改大小,使看起来合适舒服一些。注意分页控件:我们需要三行分页页面选项,所以你要给它留够空间。

几时你想看看界面的样子,单击"Test"按钮:

别忘了分页控件最少也得有四个页面,所以你要留给分页控件比测试时看到的景象更多的空间。测试模式显示上截止目前我们设计的界面的实际样子。关闭以退出测试模式:

是时候来校对所有控件的属性了。如果你已关闭了属性窗口,打开它(Ctrl-Y 或右击,然后“Property”)。你可以选取一个控件然后查看它的属性设置的对不对,如有需要就改好它。

我们想要分页控件的静态属性是这样子的:

即多行;而分页控件的动态属性则是这样子:

即通知单击事件。

其它控件的属性都保留默认,除combo box之外,而它我们已在前面设置过了。最后一个要设置属性的是对话框本身。选取它,选中动态属性,弄成这样:

最后象下面这样保存对话框资源定义文件。

接下来要做的是添加回调函数。要给一个控件添加回调函数,选中该控件,然后右击它,再选中"Callbacks"。我们来为combo box添加回调,画面看起来应该像这样:

我们要写的回调在左手边的列表框。它(们)对应于动态属性:当我们将某一动态属性设置成"On"时,我们就得到一回调,这里的名字就是我们想要的回调,我们就用系统默认好了。

要创建一个回调,只要双击它的名字就好了。包含了回调函数的文件在Wedit中已被打开,光标就停在你所要的函数上。如果需要,该回调就会被创建一个正确的函数定义,象这样:

当combo box 选取发生改变时,这个回调这会就呼叫。回调的第一个参数对应于相应的控件(这里是combo box),第二个参数对应于该对话框,有了它我们就可以访问每一个对话框里的的控件了。

下面是这个例子回调数:

获取一个选项要用下面的方式:

ctrl->GetCurSel();

如果没有选择任何选项,结果为-1,否则结果为该选项的索引。所以我们用下面的方法获取一个选项的文本:

ctrl->GetLBText(SelectedFriend,Name);

如果要访问另一个控件,就要用到dlg参数。例如,我们用下面的代码来设置文本框的文本:

dlg->id_text->SetWindowText(f->Text);

回到设计窗口,在Window菜单下选取Resources:

你现在可以选择另一个回调来编缉它。要知道所有在属性设置窗口里打开了开关"On"的回调都必须要实现,如果少了任一个,都不可能通过编译。当然,如果某个回调你一时用不着,你也可以很容易的在属性设置窗口里通过将其设置为"Off"来关闭掉。

我们要写的回调分别是Dlg100Combo_box102SeChange,Dlg100Tab_control101Selected,Dlg100Init和Dlg100Destroy。用户接口不再需要其它的函数了!

当然我们会写其它的一些helper 函数,以免我们的代码膨胀。

四、添加特定代码

在friends.c里的WinMain函数中有两个地方要修改。

首先打开friends.c,找到第30行,在WNDCLASS wx 后插入:

INITCOMMONCONTROLSEX IC;
IC.dwSize
=sizeof(IC);
IC.dwICC
=ICC_WIN95_CLASSES|ICC_DATE_CLASSES|ICC_USEREX_CLASSES;
InitCommonControlsEx(
&IC);

而且我们得呼叫LFC函数而不是对话框默认的那个,这个函数的最后一行应为:

return DialogBox(hinst,MAKEINTRESOURCE(IDD_MAINDIALOG),NULL,(DLGPROC)Dlg100);

最后一件事情就是给Wedit工程添加其它的文件。选择"Project",Add/Delete Files:

然后添加friends_cbk.c 和friends_gen.c这两个文件。工程现在可以编译并运行了。

完整的friends_cbk.c 代码如下:

代码
1 #include <windows.h>
2 #include "friendsres.h"
3 #include <gc.h>
4 #include >stdio.h<
5
6  // A structure for one friend, chained to the next one
7  struct SFRIENDS {
8 struct SFRIENDS *Next;
9 char Name[256];
10 int Mrs;
11 SYSTEMTIME Birth;
12 char Text[4096];
13 } *Friends;
14  int SelectedFriend;
15
16  // Write the file when we leave
17  void WriteFriends(HWND hwnd)
18 {
19 int i;
20 HANDLE file;
21 char buffer[6000];
22 DWORD nb;
23
24 // The file is named "friends.txt" and is in the default directory.
25   file=CreateFile("friends.txt",GENERIC_WRITE,FILE_SHARE_READ,NULL,
CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
26 if (file==INVALID_HANDLE_VALUE) {
27 MessageBox(hwnd,"Unable to create the file \"friends.txt\"",
"Error",MB_OK|MB_SETFOREGROUND);
28 return;
29 }
30 // The file is created
31   while (Friends) {
32 sprintf(buffer,"\"%s\",%d,%d,%d,%d,\"%s\"\r\n",
Friends->Name,Friends->Mrs,
33 Friends->Birth.wYear,Friends->Birth.wMonth,
Friends->Birth.wDay,Friends->Text);
34 WriteFile(file,buffer,strlen(buffer),&nb,NULL);
35 Friends=Friends->Next;
36 }
37 CloseHandle(file);
38 }
39
40 // Get rid of double quotes in the string
41 char * GetString(char *dest, char *inp, int nb)
42 {
43 int i;
44 char c;
45 for (i=0; ielt;nb; i++) {
46 c=inp[i];
47 if (c==0) break;
48 if (c=='"') {
49 i++;
50 break;
51 }
52 *dest++=c;
53 }
54 *dest=0;
55 // Return next position
56 return inp+i;
57 }
58
59 // Read the file friends.txt in the default directory
60 struct SFRIENDS *ReadFriends(void)
61 {
62 HANDLE file;
63 char *buffer, *p, c;
64 DWORD size, read;
65 struct SFRIENDS *f;
66
67 Friends=0;
68 // Try to open the file friends.txt
69 file=CreateFile("friends.txt",GENERIC_READ,FILE_SHARE_READ,
NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
70 if (file==INVALID_HANDLE_VALUE) return Friends;
71 size=GetFileSize(file, NULL);
72 if (size==0xFFFFFFFF) {
73 CloseHandle(file);
74 return Friends;
75 }
76
77 // Read the entire file
78 buffer=GC_malloc(size);
79 ReadFile(file,buffer,size,&read,NULL);
80 CloseHandle(file);
81
82 // Put the data into chained structures
83 p=buffer;
84 while (p && *p) {
85 f=GC_malloc(sizeof(struct SFRIENDS));
86 // Go to next '"' char
87 p=strchr(p,'"');
88 if (!p) break;
89 p++;
90 // The first string in quotes is the name
91 p=GetString(f->Name,p,255);
92 if (!(p && *p)) break;
93 p=strchr(p,',');
94 if (!p) break;
95 p++;
96 // A number represents Mrs, Miss or Mr
97 f->Mrs=atoi(p);
98 p=strchr(p,',');
99 if (!p) break;
100 p++;
101 // The date is stored in 3 numbers
102 f->Birth.wYear=atoi(p);
103 p=strchr(p,',');
104 if (!p) break;
105 p++;
106 f->Birth.wMonth=atoi(p);
107 p=strchr(p,',');
108 if (!p) break;
109 p++;
110 f->Birth.wDay=atoi(p);
111 p=strchr(p,',');
112 if (!p) break;
113 p++;
114 // Go to the next quote
115 p=strchr(p,'"');
116 if (!p) break;
117 p++;
118 // Read all the text in quotes
119 p=GetString(f->Text,p,4095);
120 f->Next=Friends;
121 Friends=f;
122 }
123 return Friends;
124 }
125
126 // Get rid of new lines in the text.
127 void VerifyChars(char *str)
128 {
129 char *dest=str, c;
130 while (0!=(c=*str++)) {
131 if (c=='"') c='\'';
132 else if (c=='\r') continue;
133 else if (c=='\n') c=' ';
134 *dest++=c;
135 }
136 *dest=0;
137 }
138
139 // Add a friend in a SFRIENDS structure and chain it
140 void StoreCurrentFriend(struct _Dlg100 *dlg)
141 {
142 struct SFRIENDS *f, *g, *o;
143 int addit;
144 char c, init;
145
146 f=GC_malloc(sizeof(struct SFRIENDS));
147
148 dlg->id_names->GetWindowText(f->Name,255);
149 if (!*f->Name) return; // Nothing to store
150
151 // Avoid stange chars in name
152 VerifyChars(f->Name);
153
154 // Before store the new one, forget the old selected friend
155 if (SelectedFriend!=-1) {
156 char name[256];
157 dlg->id_names->GetLBText(SelectedFriend,name);
158 o=0;
159 for (g=Friends; g; o=g, g=g->Next) {
160 if (!strcmp(g->Name,name)) {
161 if (o) o->Next = g->Next;
162 else Friends=g->Next;
163 break;
164 }
165 }
166 }
167
168 if (dlg->rb_mrs->GetState()& BST_CHECKED) f->Mrs=1;
169 else if (dlg->rb_miss->GetState()& BST_CHECKED) f->Mrs=2;
170 else if (dlg->rb_mr->GetState()& BST_CHECKED) f->Mrs=3;
171 dlg->id_date->GetSystemTime(&f->Birth);
172 dlg->id_text->GetWindowText(f->Text,4096);
173
174 // Avoid stange chars in text
175 VerifyChars(f->Text);
176
177 // And force the line in the combo to be that one
178 if (SelectedFriend!=-1) {
179 dlg->id_names->DeleteString(SelectedFriend);
180 }
181 // Leave the name if it is not in that tab
182 init='A'+dlg->id_tab->GetCurSel();
183 c=*f->Name;
184 addit=1;
185 if (init<='Z') {
186 if (c!=init && c!=init+'a'-'A') addit=0;
187 }
188 else {
189 if ((c>='A' && c<='Z') || (c>='a' && c<='z')) addit=0;
190 }
191 if (addit) dlg->id_names->AddString(f->Name);
192
193 // Chain the structure
194 f->Next=Friends;
195 Friends=f;
196 }
197
198 // Clear all the frind information on the screen
199 void ClearSelectedFriend(struct _Dlg100 *dlg)
200 {
201 SYSTEMTIME st;
202 dlg->id_names->SetWindowText("");
203 dlg->rb_mrs->SetCheck(BST_UNCHECKED);
204 dlg->rb_miss->SetCheck(BST_UNCHECKED);
205 dlg->rb_mr->SetCheck(BST_UNCHECKED);
206 GetSystemTime(&st);
207 dlg->id_date->SetSystemTime(GDT_VALID,&st);
208 dlg->id_text->SetWindowText("");
209 SelectedFriend=-1;
210 }
211
212 // Callback : the selected item of the combo box has changed
213 long Dlg100Combo_box102SelChange(ST_COMBOBOX *ctrl,struct _Dlg100 *dlg)
214 {
215 struct SFRIENDS *f;
216 char Name[256];
217
218 // First store the currently selected friend
219 StoreCurrentFriend(dlg);
220
221 // Get the selected friend
222 SelectedFriend=ctrl->GetCurSel();
223 if (SelectedFriend==-1) {
224 // No one selected : clear the screen
225 ClearSelectedFriend(dlg);
226 return 0;
227 }
228
229 // Find the structure corresponding to the selected friend
230 ctrl->GetLBText(SelectedFriend,Name);
231 for (f=Friends; f; f=f->Next) {
232 if (!strcmp(f->Name,Name)) {
233 // It's that friend : display it's information
234 dlg->id_names->SetWindowText(f->Name);
235 dlg->rb_mrs->SetCheck((f->Mrs==1)?BST_CHECKED:BST_UNCHECKED);
236 dlg->rb_miss->SetCheck((f->Mrs==2)?BST_CHECKED:BST_UNCHECKED);
237 dlg->rb_mr->SetCheck((f->Mrs==3)?BST_CHECKED:BST_UNCHECKED);
238 dlg->id_date->SetSystemTime(GDT_VALID,&f->Birth);
239 dlg->id_text->SetWindowText(f->Text);
240 break;
241 }
242 }
243 return 1;
244 }
245
246 // Select a letter in the tab control : clear the displayed friend and
//display the new list
247 void SelectLetter(ST_TABCTRL *ctrl,struct _Dlg100 *dlg)
248 {
249 struct SFRIENDS *f;
250 char init, c;
251
252 // Clear the actual friend
253 ClearSelectedFriend(dlg);
254
255 // Set up the list of friends with same initial
256 dlg->id_names->ResetContent();
257 init='A'+ctrl->GetCurSel();
258 for (f=Friends; f; f=f->Next) {
259 c=*f->Name;
260 if (init<='Z') {
261 if (c!=init && c!=init+'a'-'A') continue;
262 }
263 else {
264 if ((c>='A' && c<='Z') || (c>='a' && c<='z')) continue;
265 }
266 dlg->id_names->AddString(f->Name);
267 }
268 }
269
270 // Start-up : load the file, and initialize a few controls
271 long Dlg100Init(ST_DIALOGBOX *ctrl,struct _Dlg100 *dlg)
272 {
273 // Initialize the dialog
274 TC_ITEM item;
275 int i;
276 char buffer[256];
277
278 // Read the file
279 Friends = ReadFriends();
280
281 // Limit size...
282 dlg->id_text->SetLimitText(4095);
283 dlg->id_names->LimitText(255);
284
285 // Create the tabs : one for each letter and 'other'
286 memset(&item,0,sizeof(item));
287 item.mask=TCIF_TEXT;
288 item.pszText=buffer;
289 buffer[1]=0;
290 for (i=0; i<26; i++) {
291 *buffer='A'+i;
292 dlg->id_tab->InsertItem(i,&item);
293 }
294 item.pszText="Other";
295 dlg->id_tab->InsertItem(i,&item);
296
297 // 'A' is selected
298 SelectLetter(dlg->id_tab, dlg);
299
300 return 0;
301 }
302
303 // A new letter is selected : store the current friend and change the letter
304 long Dlg100Tab_control101Selected(ST_TABCTRL *ctrl,struct _Dlg100 *dlg)
305 {
306 // Store the current informations
307 StoreCurrentFriend(dlg);
308 // and select the new letter
309 SelectLetter(ctrl, dlg);
310
311 return 0;
312 }
313
314 // End of application : store the new file
315 void Dlg100Destroy(HWND hwnd)
316 {
317 WriteFriends(hwnd);
318 }
319
320

 原文出自:http://www.q-software-solutions.de/products/resource-editor/index.shtml

原文地址:https://www.cnblogs.com/godspeedsam/p/1867416.html