![]() |
|||||
|---|---|---|---|---|---|
| Home | Products | Support | Services | Shop | Company |
Products >Resource Editor
The development of an application with LFC (the "lcc-win32 foundation classes")is shown below. The steps are :
To show you how to use WEDIT and LFC, we are going to develop a little application that will help us to memorize informations concerning our friends.
The user interface will be a dialog box like this one :
The tab control selects the first letter of the name, the combo box shows all the
names, and when we select a name, the radio buttons give Mrs, Miss or Mr, the date control
shows the birth date and the edit field gives additional information.
We can modify the information when a name is selected, so we have to memorize it when
the selection is changed : we can select another name in the listbox or select another tab.
All this information is contained in a file that is read when the application is
loaded, and written when we quit the application.
The application will have a tab control : we then click on a tab to select all our friends whose name begins with this letter. Then we select one friend, so we can see the corresponding information, like the birth date.
First step : we load Wedit and create the new project :
We give the project name :
We want to create a Windows executable :
Now we ask Wedit to create the skeleton of the application :
Obviously this is a french version of Windows ! But we can go on... We want a dialog box based application :
The application is created :
Now we have to give informations to the compiler. As we will use LFC, we have to add 'gc.lib', 'lfc.lib' and 'weditres.lib' to the link. Click on 'Next' to go to the next page :
Now we can compile the application if we want to, but we could only test a dialog box that we can close. We have to use LFC to go further.
Choose the menu item 'Design' and open the resource :
As it is the first time we open the resource, we have to specify which file contains the definitions and is to be included :
Select the dialog box with a double-click :
Now the serious things are coming. We see the dialog box that has been automatically created by the wizard. We can select the entire dialog box with a click in it's area (aclick on a button selects it). The object that is selected is shown in a special rectangle with red handle. They allow us to resize the object. We can also see and change the static and dynamic settings of the selected control if we hit the Ctrl-Y key :
You can close the settings window. We do not want the OK and Cancel buttons : select one and press Ctrl-Del, select the other one and press Ctrl-Del. We have a dialog box with a title and the system buttons. We can give it a more reasonable size : select the lower right red handle and push it to the right and the bottom of the screen :
We can now add the tab control. Leave a few moments the cursor on the first tool to obtain the list of available controls :
and select the tab control :
Put the control with a simple click on the top left of the dialog, and resize it :
Now we put a combo box in the tab control : select the combo box control and put it into the tab control :
The default combo box does not have the style we prefer, so press the right button on the combo box and select 'Properties' :
This shows the properties. We can choose the simple style :
The displayed combo box looks now like this :
Take the bottom right handle to resize the combo. We want it to go to the bottom of the dialog, and it may be relatively large. We can already set up the property that will specify that we want to know when the selection changes. First select the dynamic properties, and set the 'Selection change' option :
Now we add the first radio button. Let the mouse on the first tool button and select the control 'Radio button' :
Drop the radio button on the right of the combo box, and go to the name field to give it the right name (RB_MRS) and the text (Mrs) :
Do the same for the other radio buttons, named RB_MISS and RB_MR, with the text Miss and Mr :
Select the date control and name it ID_DATE. Select the text label and put one just before the date control. You should obtain something like :
Now select the edit field and resize it :
Now all the controls are created. You can rearrange them so they have a convenient size. Take care of the tab control : we need 3 lines of tabulations in the example that is shown, so we need to leave enough room for it.
When you want to see how it looks, you just have to click on the 'Test' button :
Don't forget that the tab control will contain more than 4 tabs, so you have to leave
more room that the test mode seems to show.
The test mode shows a dialog box that is created with the definitions we gave. Just close it
to terminate the test mode :
It's time to verify the properties concerning all the controls. If the properties window
is closed, open it (press Ctrl-Y or right click and choose 'Properties').
You can now select a control and see if the properties are correct. Modify them if necessary.
We want for the tab control :
for the static properties (multi-line on) and
for the dynamic properties (we want the click notification).
The properties for the other controls are set to the default, except the combo box, but we have already set them. The last properties concern the dialog box itself. Select it and selexct the dynamic properties. We sould have :
Save the dialog box definition, now we only have to add the callbacks :
To add a callback concerning a control, select it with a click, and right-click and choose 'Callbacks'. We do that for the combo box. We obtain :
The callbacks we have to write are displayed in the left-hand listbox. They correspond to the dynamic
properties : we get one callback when we set the corresponding option to On, and the name
is that one we have asked for. We can use the default names.
To create a callback, just double-click on it's name. The file containing the callbacks
is opened in Wedit, and the cursor is in the desired function. If necessary, the function is created,
with the correct prototype, as now :
This function will be called when the selection of the combo box changes. The first
argument corresponds to the control (here the combo box) and the second one corresponds to the
entire dialog box, and allows us to access to each control.
The function in this example is :
We get the selection :
ctrl->GetCurSel();
The result is -1 if no line is selected, or the index of the line. So we get the text with :
ctrl->GetLBText(SelectedFriend,Name);
To access to another control, we use the dlg argument. For instance, we set the text of
the edit field with :
dlg->id_text->SetWindowText(f->Text);
Top of page
Main product page
To go back to the design window, select Resources in the Window menu :
You can now select another callback. Note that all the callbacks that are set up to On in the properties have to exist, it will be impossible to compile the application if one is missing. But it is easy to set the option to Off if you don't need it...
The callbacks we have to write are Dlg100Combo_box102SelChange, Dlg100Tab_control101Selected,
Dlg100Init and Dlg100Destroy. The user interface does not need more functions !
Of course, we write other functions, because we have to limit each function to a readable code.
We have two modifications to do in clients.c, in the WinMain function.
Open friends.c and go to the line number 30. Insert these lines after WNDCLASS wc :
INITCOMMONCONTROLSEX IC;
IC.dwSize = sizeof(IC);
IC.dwICC = ICC_WIN95_CLASSES | ICC_DATE_CLASSES | ICC_USEREX_CLASSES;
InitCommonControlsEx(&IC);
And we have to call the LFC function instead of the default one for use with the dialog box.
The last line of this function must be :
return DialogBox(hinst, MAKEINTRESOURCE(IDD_MAINDIALOG), NULL, (DLGPROC) Dlg100);
The last thing to do is to add the additional files to the Wedit project. Select Project, Add/Delete files :
Then add the 2 files friends_cbk.c and friends_gen.c. The project can be compiled, and you can run the application.
The entire file we have to write is :
#include <windows.h>
#include "friendsres.h"
#include <gc.h>
#include >stdio.h<
// A structure for one friend, chained to the next one
struct SFRIENDS {
struct SFRIENDS *Next;
char Name[256];
int Mrs;
SYSTEMTIME Birth;
char Text[4096];
} *Friends;
int SelectedFriend;
// Write the file when we leave
void WriteFriends(HWND hwnd)
{
int i;
HANDLE file;
char buffer[6000];
DWORD nb;
// The file is named "friends.txt" and is in the default directory.
file=CreateFile("friends.txt",GENERIC_WRITE,FILE_SHARE_READ,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
if (file==INVALID_HANDLE_VALUE) {
MessageBox(hwnd,"Unable to create the file \"friends.txt\"","Error",MB_OK|MB_SETFOREGROUND);
return;
}
// The file is created
while (Friends) {
sprintf(buffer,"\"%s\",%d,%d,%d,%d,\"%s\"\r\n",Friends->Name,Friends->Mrs,
Friends->Birth.wYear,Friends->Birth.wMonth,Friends->Birth.wDay,Friends->Text);
WriteFile(file,buffer,strlen(buffer),&nb,NULL);
Friends=Friends->Next;
}
CloseHandle(file);
}
// Get rid of double quotes in the string
char * GetString(char *dest, char *inp, int nb)
{
int i;
char c;
for (i=0; ielt;nb; i++) {
c=inp[i];
if (c==0) break;
if (c=='"') {
i++;
break;
}
*dest++=c;
}
*dest=0;
// Return next position
return inp+i;
}
// Read the file friends.txt in the default directory
struct SFRIENDS *ReadFriends(void)
{
HANDLE file;
char *buffer, *p, c;
DWORD size, read;
struct SFRIENDS *f;
Friends=0;
// Try to open the file friends.txt
file=CreateFile("friends.txt",GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
if (file==INVALID_HANDLE_VALUE) return Friends;
size=GetFileSize(file, NULL);
if (size==0xFFFFFFFF) {
CloseHandle(file);
return Friends;
}
// Read the entire file
buffer=GC_malloc(size);
ReadFile(file,buffer,size,&read,NULL);
CloseHandle(file);
// Put the data into chained structures
p=buffer;
while (p && *p) {
f=GC_malloc(sizeof(struct SFRIENDS));
// Go to next '"' char
p=strchr(p,'"');
if (!p) break;
p++;
// The first string in quotes is the name
p=GetString(f->Name,p,255);
if (!(p && *p)) break;
p=strchr(p,',');
if (!p) break;
p++;
// A number represents Mrs, Miss or Mr
f->Mrs=atoi(p);
p=strchr(p,',');
if (!p) break;
p++;
// The date is stored in 3 numbers
f->Birth.wYear=atoi(p);
p=strchr(p,',');
if (!p) break;
p++;
f->Birth.wMonth=atoi(p);
p=strchr(p,',');
if (!p) break;
p++;
f->Birth.wDay=atoi(p);
p=strchr(p,',');
if (!p) break;
p++;
// Go to the next quote
p=strchr(p,'"');
if (!p) break;
p++;
// Read all the text in quotes
p=GetString(f->Text,p,4095);
f->Next=Friends;
Friends=f;
}
return Friends;
}
// Get rid of new lines in the text.
void VerifyChars(char *str)
{
char *dest=str, c;
while (0!=(c=*str++)) {
if (c=='"') c='\'';
else if (c=='\r') continue;
else if (c=='\n') c=' ';
*dest++=c;
}
*dest=0;
}
// Add a friend in a SFRIENDS structure and chain it
void StoreCurrentFriend(struct _Dlg100 *dlg)
{
struct SFRIENDS *f, *g, *o;
int addit;
char c, init;
f=GC_malloc(sizeof(struct SFRIENDS));
dlg->id_names->GetWindowText(f->Name,255);
if (!*f->Name) return; // Nothing to store
// Avoid stange chars in name
VerifyChars(f->Name);
// Before store the new one, forget the old selected friend
if (SelectedFriend!=-1) {
char name[256];
dlg->id_names->GetLBText(SelectedFriend,name);
o=0;
for (g=Friends; g; o=g, g=g->Next) {
if (!strcmp(g->Name,name)) {
if (o) o->Next = g->Next;
else Friends=g->Next;
break;
}
}
}
if (dlg->rb_mrs->GetState()& BST_CHECKED) f->Mrs=1;
else if (dlg->rb_miss->GetState()& BST_CHECKED) f->Mrs=2;
else if (dlg->rb_mr->GetState()& BST_CHECKED) f->Mrs=3;
dlg->id_date->GetSystemTime(&f->Birth);
dlg->id_text->GetWindowText(f->Text,4096);
// Avoid stange chars in text
VerifyChars(f->Text);
// And force the line in the combo to be that one
if (SelectedFriend!=-1) {
dlg->id_names->DeleteString(SelectedFriend);
}
// Leave the name if it is not in that tab
init='A'+dlg->id_tab->GetCurSel();
c=*f->Name;
addit=1;
if (init<='Z') {
if (c!=init && c!=init+'a'-'A') addit=0;
}
else {
if ((c>='A' && c<='Z') || (c>='a' && c<='z')) addit=0;
}
if (addit) dlg->id_names->AddString(f->Name);
// Chain the structure
f->Next=Friends;
Friends=f;
}
// Clear all the frind information on the screen
void ClearSelectedFriend(struct _Dlg100 *dlg)
{
SYSTEMTIME st;
dlg->id_names->SetWindowText("");
dlg->rb_mrs->SetCheck(BST_UNCHECKED);
dlg->rb_miss->SetCheck(BST_UNCHECKED);
dlg->rb_mr->SetCheck(BST_UNCHECKED);
GetSystemTime(&st);
dlg->id_date->SetSystemTime(GDT_VALID,&st);
dlg->id_text->SetWindowText("");
SelectedFriend=-1;
}
// Callback : the selected item of the combo box has changed
long Dlg100Combo_box102SelChange(ST_COMBOBOX *ctrl,struct _Dlg100 *dlg)
{
struct SFRIENDS *f;
char Name[256];
// First store the currently selected friend
StoreCurrentFriend(dlg);
// Get the selected friend
SelectedFriend=ctrl->GetCurSel();
if (SelectedFriend==-1) {
// No one selected : clear the screen
ClearSelectedFriend(dlg);
return 0;
}
// Find the structure corresponding to the selected friend
ctrl->GetLBText(SelectedFriend,Name);
for (f=Friends; f; f=f->Next) {
if (!strcmp(f->Name,Name)) {
// It's that friend : display it's information
dlg->id_names->SetWindowText(f->Name);
dlg->rb_mrs->SetCheck((f->Mrs==1)?BST_CHECKED:BST_UNCHECKED);
dlg->rb_miss->SetCheck((f->Mrs==2)?BST_CHECKED:BST_UNCHECKED);
dlg->rb_mr->SetCheck((f->Mrs==3)?BST_CHECKED:BST_UNCHECKED);
dlg->id_date->SetSystemTime(GDT_VALID,&f->Birth);
dlg->id_text->SetWindowText(f->Text);
break;
}
}
return 1;
}
// Select a letter in the tab control : clear the displayed friend and display the new list
void SelectLetter(ST_TABCTRL *ctrl,struct _Dlg100 *dlg)
{
struct SFRIENDS *f;
char init, c;
// Clear the actual friend
ClearSelectedFriend(dlg);
// Set up the list of friends with same initial
dlg->id_names->ResetContent();
init='A'+ctrl->GetCurSel();
for (f=Friends; f; f=f->Next) {
c=*f->Name;
if (init<='Z') {
if (c!=init && c!=init+'a'-'A') continue;
}
else {
if ((c>='A' && c<='Z') || (c>='a' && c<='z')) continue;
}
dlg->id_names->AddString(f->Name);
}
}
// Start-up : load the file, and initialize a few controls
long Dlg100Init(ST_DIALOGBOX *ctrl,struct _Dlg100 *dlg)
{
// Initialize the dialog
TC_ITEM item;
int i;
char buffer[256];
// Read the file
Friends = ReadFriends();
// Limit size...
dlg->id_text->SetLimitText(4095);
dlg->id_names->LimitText(255);
// Create the tabs : one for each letter and 'other'
memset(&item,0,sizeof(item));
item.mask=TCIF_TEXT;
item.pszText=buffer;
buffer[1]=0;
for (i=0; i<26; i++) {
*buffer='A'+i;
dlg->id_tab->InsertItem(i,&item);
}
item.pszText="Other";
dlg->id_tab->InsertItem(i,&item);
// 'A' is selected
SelectLetter(dlg->id_tab, dlg);
return 0;
}
// A new letter is selected : store the current friend and change the letter
long Dlg100Tab_control101Selected(ST_TABCTRL *ctrl,struct _Dlg100 *dlg)
{
// Store the current informations
StoreCurrentFriend(dlg);
// and select the new letter
SelectLetter(ctrl, dlg);
return 0;
}
// End of application : store the new file
void Dlg100Destroy(HWND hwnd)
{
WriteFriends(hwnd);
}
© Q-Software Solutions GmbH
1999-2010
Terms and
Conditions