Why C?

J

jacob navia

Many people wonder why C is still being used to write
GUI applications when so many alternatives exist, that
are proclaimed "better" by the "experts".

Here are some points that could be interesting to know
when planning a new application.

Let's compare two applications then, one written in C,
the other in Visual Basic dot net.

The Visual Basic application is a "notepad" clone, but
missing some features like "Find". It will load and
display a text file in a window.

The C application is the IDE of lcc-win32: it features also
a text display, but contains a debugger, a project management
module, code analysis, software metrics, regular expression search,
and a very long ETC that would be too long to enumerate here.

Test part 1: Loading the application into memory. No files open.
Memory footprint.
vb.net: 24 284 Kb
wedit: 12 060 Kb

With all the features, the C application uses 50% of the memory
footprint of the VB application. I thought at first that this
would be the overhead for loading the first vb.net application and
that following applications would need less memory but no, that
is not the case. A second vb.net notepad uses also 24MB.

Test part2: Loading a file of 376 879 bytes.
vb.net 31 548K
wedit 17 316K

The vb application needs 7 264 Kb to hold the file, wedit needs
5 256. This is a lot of overhead still, but wedit needs only 1MB
more to store a second file of the same size.
This means that a lot of it is the overhead of loading
the first file. This comparison is not possible with the vb
application since it can hold only one file at a time.

Test part3: Opening the "about" dialog box.
vb.net: 32 480K
wedit: 17 280K

Just to show a simple "About" dialog box, the vb.net
application uses almost a megabyte more of memory. The
memory consumption of wedit goes DOWN slightly since a
garbage collection happens. Both applications use a
garbage collector.

The numbers speak by themselves.

jacob
 
M

Mabden

jacob navia said:
Many people wonder why C is still being used to write
GUI applications when so many alternatives exist, that
are proclaimed "better" by the "experts".

First of all, just to "center" you, the language you are prefering was
written in C, probably c++, but mostly in C. (some people will argue
that "once you go C++, it is ALL c++", but it was written in C, trust
me)
Let's compare two applications then, one written in C,
the other in Visual Basic dot net.

Apple meet Orange

blah blah blah

I didn't even read it, but you are wrong.

If you want to make a point, make a point. Tell me what you are about to
prove.

Don't assume I don't program another language because I post here.
 
S

Skarmander

jacob said:
Many people wonder why C is still being used to write
GUI applications when so many alternatives exist, that
are proclaimed "better" by the "experts".

Here are some points that could be interesting to know
when planning a new application.
You make only one: memory requirements. A good point, but not the only
or even the main point to consider when designing an application.
Let's compare two applications then, one written in C,
the other in Visual Basic dot net.
Inherent bias alert. Comparing language use by comparing two random
applications that happen to be written in those languages must be taken
with lots of salt grains. Bags full of it, in fact. I'd go so far as to
call it off-topic.
The Visual Basic application is a "notepad" clone, but
missing some features like "Find". It will load and
display a text file in a window.
Comparing programs that do exactly the same thing (and I mean on the
input/output level, not the concept level) would be more meaningful.
The C application is the IDE of lcc-win32: it features also
a text display, but contains a debugger, a project management
module, code analysis, software metrics, regular expression search,
and a very long ETC that would be too long to enumerate here.
Re-illustrating my point. Since you can't compare these features,
mentioning them is biased and pointless.

Also, comparing a "Notepad clone" with an IDE? Dare I make the assertion
that one is optimized for practical use and the other is not?

The numbers speak by themselves.
"Lies, damn lies, and statistics"... This sort of off-the-cuff
observation really only establishes the following, if we graciously
generalize the result: applications written in C tend to have a smaller
memory footprint than comparable applications written in VB.NET.

Without citing reasons or numbers (though these exist), I'd go so far as
to assert that many applications written in C tend to have smaller
memory footprints and execution times than comparable applications
written in most other languages. In short, C and its implementations
allow you to write particularly efficient applications. This is nothing new.

There are also lots of reasons for people (not) to use C when writing
programs. I sincerely doubt this is a surprising or powerful
observation, and I also don't think that those people who "wonder why C
is still being used" for GUI development are doing so because they don't
know this.

For a lighter note, let's all sing along to the old classic:
http://www.cs.bgu.ac.il/~omri/Humor/write_in_c.html

Maybe it could be updated to include more modern languages, although
"only wimps use BASIC" might still apply.

S.
 
M

Michael Mair

jacob said:
Many people wonder why C is still being used to write
GUI applications when so many alternatives exist, that
are proclaimed "better" by the "experts".

Here are some points that could be interesting to know
when planning a new application.

Let's compare two applications then, one written in C,
the other in Visual Basic dot net.

The Visual Basic application is a "notepad" clone, but
missing some features like "Find". It will load and
display a text file in a window.

The C application is the IDE of lcc-win32: it features also
a text display, but contains a debugger, a project management
module, code analysis, software metrics, regular expression search,
and a very long ETC that would be too long to enumerate here.
<snip: comparison of memory footprint>

What do you want to prove?
If the VB.NET-"Editor" can be cobbled together in half an
hour from tested ingredients and a hand-rolled editor written
in C from ground up takes more than a man-week, then it depends
on what you are going to do with the thing. If the editor is just
an add-on to another product intended to be there until the
customer replaces it in the options of the main product by his
favourite editor, then the cheap solution maybe a little bit
extended may be exactly what you need at the lowest possible
cost.
Nobody ever claimed that VB.NET was the tool for everything.

Even though I appreciate real life examples of C's usefulness outside
of embedded systems, I do not think that yours helps much.


Cheers
Michael
 
J

jacob navia

Michael Mair a écrit :
If the VB.NET-"Editor" can be cobbled together in half an
hour from tested ingredients and a hand-rolled editor written
in C from ground up takes more than a man-week, then it depends
on what you are going to do with the thing. If the editor is just
an add-on to another product intended to be there until the
customer replaces it in the options of the main product by his
favourite editor, then the cheap solution maybe a little bit
extended may be exactly what you need at the lowest possible
cost.
Nobody ever claimed that VB.NET was the tool for everything.

Of course. For throw away applications like that I think VB.NET is
the best.
 
J

jacob navia

Skarmander a écrit :
You make only one: memory requirements. A good point, but not the only
or even the main point to consider when designing an application.

Inherent bias alert. Comparing language use by comparing two random
applications that happen to be written in those languages must be taken
with lots of salt grains. Bags full of it, in fact. I'd go so far as to
call it off-topic.

Well, the applications do exactly the same thing:
They load a text file and display it in a window.

What I am showing is just how enormous the memory requirements
for even a minimal application are in VB.

And if the requirements for a simple application that does nothing
are so huge, what will happen with real world applications?

Note that starting just 4 of those small text editors will
swallow 100MB of memory, 20% of the whole memory of a small
workstation with 512K.

What will happen when several of those applications are loaded?

The programming language JAVA has the same problem in many
situations. The memory requirements are so huge that any
machine is brought down when you attempt to load several of them
at the same time.

Contrast that with the memory requirements of C.

This is the point I wanted to make.
 
S

Skarmander

jacob said:
Skarmander a écrit :


Well, the applications do exactly the same thing:
They load a text file and display it in a window.
Do they use common controls? Do either or both support different fonts,
line lengths, text styles? Are there editing facilities? Are these
equal? These things impact the representation in memory.

Let's accept for the sake of argument that they're roughly comparable; I
haven't seen the applications in action, but let's say the manner of
display is "equal enough".
What I am showing is just how enormous the memory requirements
for even a minimal application are in VB.

And if the requirements for a simple application that does nothing
are so huge, what will happen with real world applications?
That's like saying "if a solution to a simple problem is very
inefficient, how much more inefficient will the solution to a difficult
problem be?" It overlooks that smarter solutions will be tried, and that
the inefficiency doesn't necessarily scale with the problem (that is, if
application A in VB.NET uses twice as much memory as comparable
application B in C, it doesn't follow that all VB.NET applications use
twice as much memory compared to their C counterparts).

There's no doubt that applications in VB.NET incur overhead. What your
demonstration does not convincingly show is that this overhead will
necessarily be devastating in "real world applications". There will no
doubt be examples of the form "I had to rewrite this in C or I couldn't
get it done", but this isn't one of them.
Note that starting just 4 of those small text editors will
swallow 100MB of memory, 20% of the whole memory of a small
workstation with 512K.

What will happen when several of those applications are loaded?
Then it's time to buy more memory, isn't it? :p

You understand as well as I do that memory requirements are just part of
the cost of an application. Even when they are considerable. Don't
forget that the larger part of cost comes from maintaining an application.
The programming language JAVA has the same problem in many
situations. The memory requirements are so huge that any
machine is brought down when you attempt to load several of them
at the same time.

Contrast that with the memory requirements of C.
Contrast the portability of Java applications with those of C. Contrast
the development time of applications in VB.NET with those of C. Balance
in all things.
This is the point I wanted to make.

And it's a point nobody will dispute (I'm not contradicting you, just
adding some side notes). The relative importance is another matter.

S.
 
J

jacob navia

Skarmander a écrit :
Do they use common controls?
No. Wedit doesn't use any control and writes directly in a window with
TextOut. VB uses a edit field control
Do either or both support different fonts, yes
line lengths,
yes
text styles?
no
Are there editing facilities?

In wedit quite, the VB control has only standard copy/cut/etc
Are these
equal? These things impact the representation in memory.
Probably.

Let's accept for the sake of argument that they're roughly comparable; I
haven't seen the applications in action, but let's say the manner of
display is "equal enough".

That's like saying "if a solution to a simple problem is very
inefficient, how much more inefficient will the solution to a difficult
problem be?" It overlooks that smarter solutions will be tried, and that
the inefficiency doesn't necessarily scale with the problem (that is, if
application A in VB.NET uses twice as much memory as comparable
application B in C, it doesn't follow that all VB.NET applications use
twice as much memory compared to their C counterparts).

There's no doubt that applications in VB.NET incur overhead. What your
demonstration does not convincingly show is that this overhead will
necessarily be devastating in "real world applications". There will no
doubt be examples of the form "I had to rewrite this in C or I couldn't
get it done", but this isn't one of them.

Then it's time to buy more memory, isn't it? :p

Well it depends of your budget... and your willingness to
always buy more stuff to support ever more inefficient
software.

Just a few years ago 512K RAM would have been something that
only huge database system required. Now, you need that to start a
few run of the mill applications written with grossly inefficient
languages.
You understand as well as I do that memory requirements are just part of
the cost of an application. Even when they are considerable. Don't
forget that the larger part of cost comes from maintaining an application.

Contrast the portability of Java applications with those of C.

C is quite portable mind you.
Contrast
the development time of applications in VB.NET with those of C. Balance
in all things.

Yes. I just wanted to point out that for applications where
performance is important C is still the only choice left.

Of course we have discussed about one data point:
memory requirements.

Another point is raw performance, what I will discuss in a next
post.
 
F

Flash Gordon

jacob navia wrote:

Well, the applications do exactly the same thing:
They load a text file and display it in a window.

What I am showing is just how enormous the memory requirements
for even a minimal application are in VB.

And if the requirements for a simple application that does nothing
are so huge, what will happen with real world applications?

With all languages the memory used is a constant minimum plus the size
of the code for the actual application. Last I checked VB was an
interpreted language and therefore had a higher minimum footprint.
However, this *may* mean that the size of a VB application won't
increase as fast as with C, or it may not.
Note that starting just 4 of those small text editors will
swallow 100MB of memory, 20% of the whole memory of a small
workstation with 512K.

Did you test to see if that actually happened? It may be that running 4
of those editors would use no more memory than running one, since the
techniques for having only one copy of an executable in memory for
several instances have long been known. Also, if I am right and it is
still interpreted, then even if it was 4 different applications it might
only load one copy of the interpreter in memory.
What will happen when several of those applications are loaded?

Without testing or reading up properly on the subject, *none* of us know.
The programming language JAVA has the same problem in many
situations. The memory requirements are so huge that any
machine is brought down when you attempt to load several of them
at the same time.

Or you find that there is only one copy of the JVM resident in memory
however many Java applications you are running.
Contrast that with the memory requirements of C.

This is the point I wanted to make.

You failed because you have given no evidence of having fully researched
the situation.

In any case, this is all off topic here, either a Microsoft or general
group would seem to be more appropriate.

BTW, I do C programming in Windows and have also done VB programming in
Windows, but that still does not mean that I want this discussion here.
 
K

Keith Thompson

jacob navia said:
Just a few years ago 512K RAM would have been something that
only huge database system required. Now, you need that to start a
few run of the mill applications written with grossly inefficient
languages.

I think you mean 512M, not 512K.

<MOSTLY_OT>
I've been around this business long enough for most storage quantities
to increase by one metric prefix, and then some. I remember when 56K
of memory (yes, a total of 57344 bytes) seemed ample; now I'm typing
this on a laptop with 1G of RAM, and 32-bit addresses are starting to
look cramped.

Uphill, both ways, through six-foot blazing snowdrifts.
</MOSTLY_OT>

To inject a little relevance to C:

In the past, poorly written (or just old) code that assumes an address
will fit in an unsigned int was likely to "work". As addressable
memory spaces approach and exceed a full 32 bits (4 gigabytes), that's
no longer true. On most systems, there are reasons not to make int
larger than 32 bits; with 8-bit bytes, a 64-bit int means you can't
have both a standard 16-bit integer type and a standard 32-bit integer
type. (C99's extended types could address this, but I haven't seen
that happening.) We're seeing the effects as code is ported to 64-bit
systems and bugs are weeded out.
 
J

jacob navia

Keith Thompson a écrit :
I think you mean 512M, not 512K.

Yes of course. Excuse me.
<MOSTLY_OT>
I've been around this business long enough for most storage quantities
to increase by one metric prefix, and then some. I remember when 56K
of memory (yes, a total of 57344 bytes) seemed ample; now I'm typing
this on a laptop with 1G of RAM, and 32-bit addresses are starting to
look cramped.

Uphill, both ways, through six-foot blazing snowdrifts.

Well, I have nothing against more memory if it is used for
something. But if with 1GB of memory I can run the same
number of applications that DOS with 640 could, then I see no
real progress.

The problem with memory inflation is that there is no
improvement at all with the new hardware. I would not mind
if with 1GB I could run twice as many applications as
with an older system of only 512MB but if with 1GB the
new "improved" system makes me run the same number of
applications (or less) where is the progress?
 
S

Skarmander

jacob navia wrote:
[big discussion about memory requirements of C vs. VB.NET apps]
Another point is raw performance, what I will discuss in a next
post.

I'll opt out of that one, since I already know the results, and trust
everyone can draw their own conclusions about it.

That said, you're preaching to the choir. Why are you posting in
comp.lang.c about how C is good compared to other languages? This is
unlikely to enlighten anyone. Never mind that these topics are big and
old and a fertile ground for flamewars wherever they go -- in the past
the discussion might have been C vs. Pascal, or C vs. LISP, now it's C
vs. the unwashed .NET hordes, tomorrow it'll probably be something else.

"With C you can write small and fast programs" is not news to anyone.
Not even to the unwashed .NET hordes.

S.
 
D

Dik T. Winter

>
> C is quite portable mind you.

lcc-win32 is not so very portable. I do not have direct access to any
machine where I can use it. Neither at home, nor at work.
 
D

Dik T. Winter

> The problem with memory inflation is that there is no
> improvement at all with the new hardware. I would not mind
> if with 1GB I could run twice as many applications as
> with an older system of only 512MB but if with 1GB the
> new "improved" system makes me run the same number of
> applications (or less) where is the progress?

On quite some machines I work on, when I double the memory I can in general
run three or four times as many applications concurrently. It depends on
the application, of course. Think code-sharing.
 
K

k_over_hbarc

Keith said:
To inject a little relevance to C:

In the past, poorly written (or just old) code that assumes an address
will fit in an unsigned int was likely to "work". As addressable
memory spaces approach and exceed a full 32 bits (4 gigabytes), that's
no longer true.

If it isn't, the compiler is broken. An int is the machine's native
word size; that's always been the meaning.
On most systems, there are reasons not to make int
larger than 32 bits; with 8-bit bytes, a 64-bit int means you can't
have both a standard 16-bit integer type and a standard 32-bit integer
type.

Why do you need ints shorter than a word? They're inefficient, and I
don't think anyone worries about memory usage anymore with simple
variables.
(C99's extended types could address this, but I haven't seen
that happening.) We're seeing the effects as code is ported to 64-bit
systems and bugs are weeded out.

The simple way:
#define int long long

Yes, you can redefine fundamental types - I always like
#define char unsigned char
so that char arithmetic works.

Andrew Usher
 
K

Keith Thompson

If it isn't, the compiler is broken. An int is the machine's native
word size; that's always been the meaning.

There's no consistent definition for "machine word size". An int is
whatever size is defined by the C implementation. Different C
implementations might have 16 or 32 bit ints on the same hardware.
Why do you need ints shorter than a word? They're inefficient, and I
don't think anyone worries about memory usage anymore with simple
variables.

It's not a matter of memory usage. You might need sub-word integer
types to match externally defined data layouts. If int is 64 bits,
char is 8 bits, and short is, say, 16 bits, then there's no predefined
32 bit integer type.
The simple way:
#define int long long

Yes, you can redefine fundamental types - I always like
#define char unsigned char
so that char arithmetic works.

That's a really bad idea. If you want unsigned char, just use
unsigned char. With that macro definition, you can't use "signed char".
 
P

pete

Keith said:
(e-mail address removed) writes:

That's a really bad idea.

Really really.
If you want unsigned char, just use
unsigned char.
With that macro definition, you can't use "signed char".

Also, it's likely that anybody else reading the code
won't suspect that they're reading it wrong.
 
M

Malcolm

jacob navia said:
Yes. I just wanted to point out that for applications where
performance is important C is still the only choice left.

Of course we have discussed about one data point:
memory requirements.

Another point is raw performance, what I will discuss in a next
post.
As a point of interest I decided to write a notepad in C, to run under
Windows.

It took less than three hours to put together, but it isn't quite
releaseable yet - a real user would wnat icons and shortcuts and some safety
against accidentally deleting text. It also hasn't had any more than minimal
testing.

The executable was an acceptable 44k, but the meory footprint was 2MB - more
than I had on my first Windows 3.1 machine

If you look at how the lines are being used, most are to "gift wrap"
functions to open and close files. Most of the rest is boilerplate code -
the FillMenus() function was lifted from another program, and the strings
changed, for example.

I don't know if this is a comment on C or on the libraries.


#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define ID_TEXT_EDT 1

#define ID_NEW_MNU 101
#define ID_OPEN_MNU 102
#define ID_SAVEME_MNU 103
#define ID_SAVEAS_MNU 104
#define ID_EXIT_MNU 105

void RegisterAsciiEditor(HINSTANCE hInstance);
HWND CreateAsciiEditor(HINSTANCE hInstance, int nCmdShow);
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
void CreateChildren(HWND hwnd);
static void FillMenus(HWND hwnd);
void Resize(HWND hwnd, int width, int height);
void DoNew(HWND hwnd);
void DoOpen(HWND hwnd);
void DoSave(HWND hwnd);
void DoSaveAs(HWND hwnd);
char *GetOpenFile(HWND hwnd);
char *GetSaveFile(HWND hwnd);
static char *loadfile(char *path);
static int savefile(char *path, char *str);
static char *mystrdup(char *str);

static char filename[MAX_PATH];

/*
Windows main routine
*/
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR
lpcmdline, int nCmdShow)
{
MSG msg;

RegisterAsciiEditor(hInstance);

CreateAsciiEditor(hInstance, nCmdShow);

while(GetMessage(&msg, 0, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}

return 0;
}

/*
register main window class
*/
void RegisterAsciiEditor(HINSTANCE hInstance)
{
WNDCLASSEX wndclass;

wndclass.cbSize = sizeof(WNDCLASSEX);
wndclass.style = CS_HREDRAW | CS_VREDRAW;
wndclass.lpfnWndProc = WndProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = hInstance;
//wndclass.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_MANDICON));
wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndclass.hbrBackground = (HBRUSH) (COLOR_MENU + 1);
wndclass.lpszMenuName = 0;
wndclass.lpszClassName = "asciiedit";
//wndclass.hIconSm = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_MANDICON));
wndclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);

RegisterClassEx(&wndclass);

}

/*
Create main window
*/
HWND CreateAsciiEditor(HINSTANCE hInstance, int nCmdShow)
{
HWND answer;
RECT rect;

rect.left = 0;
rect.top = 0;
rect.right = 201;
rect.bottom = 201;

AdjustWindowRectEx(&rect, 0, 0, WS_EX_CLIENTEDGE);

answer = CreateWindowEx(
WS_EX_CLIENTEDGE,
"asciiedit",
"Ascii Editor",
WS_OVERLAPPED | WS_MINIMIZEBOX | WS_SYSMENU | WS_CAPTION | WS_SIZEBOX,
CW_USEDEFAULT,
CW_USEDEFAULT,
rect.right,
rect.bottom,
NULL,
NULL,
hInstance,
NULL
);

FillMenus(answer);

ShowWindow(answer, nCmdShow);
UpdateWindow(answer);

return answer;
}

/*
main window procedure
*/
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_CREATE:
strcpy(filename, "");
CreateChildren(hwnd);
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
case WM_SIZE:
Resize(hwnd, LOWORD(lParam), HIWORD(lParam) );
return 0;
case WM_COMMAND:
switch(LOWORD(wParam))
{
case ID_NEW_MNU:
DoNew(hwnd);
break;
case ID_OPEN_MNU:
DoOpen(hwnd);
break;
case ID_SAVEME_MNU:
DoSave(hwnd);
break;
case ID_SAVEAS_MNU:
DoSaveAs(hwnd);
break;
case ID_EXIT_MNU:
DestroyWindow(hwnd);
break;
}
break;
return 0;
}
return DefWindowProc(hwnd, msg,wParam, lParam);
}

/*
Create Child controls
*/
void CreateChildren(HWND hwnd)
{
RECT rect;
HWND hctl;

GetClientRect(hwnd, &rect);

hctl = CreateWindow(
"edit",
"",
WS_CHILD | WS_VISIBLE | WS_VSCROLL | ES_MULTILINE | ES_AUTOVSCROLL ,
rect.left,
rect.top + 30,
rect.right - rect.left,
rect.bottom - rect.top - 30,
hwnd,
(HMENU) ID_TEXT_EDT,
(HINSTANCE) GetWindowLong(hwnd, GWL_HINSTANCE),
0);
ShowWindow(hctl, SW_SHOWNORMAL);
}

/*
Set up menus
*/
static void FillMenus(HWND hwnd)
{
HMENU hmenu;
HMENU hfile;

hfile = CreateMenu();
AppendMenu(hfile, MF_STRING, ID_NEW_MNU, "New");
AppendMenu(hfile, MF_STRING, ID_OPEN_MNU, "Open ...");
AppendMenu(hfile, MF_STRING, ID_SAVEME_MNU, "Save");
AppendMenu(hfile, MF_STRING, ID_SAVEAS_MNU, "Save As ...");
AppendMenu(hfile, MF_STRING, ID_EXIT_MNU, "Exit");


hmenu = CreateMenu();
AppendMenu(hmenu, MF_POPUP | MF_STRING, (int) hfile, "File");


SetMenu(hwnd, hmenu);
}

/*
handle resizes
*/
void Resize(HWND hwnd, int width, int height)
{
HWND hedt;

hedt = GetDlgItem(hwnd, ID_TEXT_EDT);
MoveWindow(hedt,
0,
0,
width,
height,
TRUE);

}

/*
create an empty file
*/
void DoNew(HWND hwnd)
{
SetWindowText(hwnd, "");
strcpy(filename, "");
SetWindowText(hwnd, "");
}

/*
open text for editing
*/
void DoOpen(HWND hwnd)
{
char *fname;
char *buff;

fname = GetOpenFile(hwnd);
if(!fname)
return;
buff = loadfile(fname);
if(!buff)
return;


SendMessage(GetDlgItem(hwnd, ID_TEXT_EDT), WM_SETTEXT, 0, (LPARAM) buff);

free(buff);

strcpy(filename, fname);

SetWindowText(hwnd, filename);
free(fname);

}

/*
Save text
*/
void DoSave(HWND hwnd)
{
HWND hedt;
int len;
char *buff;

if(!strlen(filename))
DoSaveAs(hwnd);

hedt = GetDlgItem(hwnd, ID_TEXT_EDT);

len = GetWindowTextLength(hedt);
buff = malloc(len + 100);
if(!buff)
return;
len = SendMessage(hedt, WM_GETTEXT, len, (LPARAM) buff);
buff[len] = 0;

savefile(filename, buff);
free(buff);
}

/*
save text to new file
*/
void DoSaveAs(HWND hwnd)
{
char *fname;
char *buff;
HWND hedt;
int ans;
int len;

fname = GetSaveFile(hwnd);
if(!fname)
return;

hedt = GetDlgItem(hwnd, ID_TEXT_EDT);

len = GetWindowTextLength(hedt);
buff = malloc(len + 100);
if(!buff)
return;
len = SendMessage(hedt, WM_GETTEXT, len, (LPARAM) buff);
buff[len] = 0;

ans = savefile(filename, buff);
free(buff);

if(ans == 0)
{
strcpy(filename, fname);
SetWindowText(hwnd, filename);
}
free(buff);
free(fname);

}

/*
get the name of a text file to open
*/
char *GetOpenFile(HWND hwnd)
{
OPENFILENAME ofn;
char path[MAX_PATH];

strcpy(path, " ");

ofn.lStructSize = sizeof(OPENFILENAME);
ofn.hwndOwner = hwnd;
ofn.hInstance = (HINSTANCE) GetWindowLong(hwnd, GWL_HINSTANCE);
ofn.lpstrFilter = "Ascii files\0*.txt\0All files\0*.*\0\0";
ofn.lpstrCustomFilter = 0;
ofn.nMaxCustFilter = 0;
ofn.nFilterIndex = 0;
ofn.lpstrFile = path;
ofn.nMaxFile = MAX_PATH;
ofn.lpstrFileTitle = 0;
ofn.nMaxFileTitle = 0;
ofn.lpstrInitialDir = 0;
ofn.lpstrTitle = "Load Text file";
ofn.Flags = OFN_FILEMUSTEXIST;
ofn.nFileOffset = 0;
ofn.nFileExtension = 0;
ofn.lpstrDefExt= "txt";
ofn.lCustData = 0;
ofn.lpfnHook = 0;
ofn.lpTemplateName = 0;

if( GetOpenFileName(&ofn) )
return mystrdup(path);
else
return 0;
}

/*
get name of text file to save to
*/
char *GetSaveFile(HWND hwnd)
{
OPENFILENAME ofn;
char path[MAX_PATH];

strcpy(path, "");

ofn.lStructSize = sizeof(OPENFILENAME);
ofn.hwndOwner = hwnd;
ofn.hInstance = (HINSTANCE) GetWindowLong(hwnd, GWL_HINSTANCE);
ofn.lpstrFilter = "Ascii files\0*.txt\0All files\0*.*\0\0";
ofn.lpstrCustomFilter = 0;
ofn.nMaxCustFilter = 0;
ofn.nFilterIndex = 0;
ofn.lpstrFile = path;
ofn.nMaxFile = MAX_PATH;
ofn.lpstrFileTitle = 0;
ofn.nMaxFileTitle = 0;
ofn.lpstrInitialDir = 0;
ofn.lpstrTitle = "Save text file";
ofn.Flags = OFN_NOREADONLYRETURN;
ofn.nFileOffset = 0;
ofn.nFileExtension = 0;
ofn.lpstrDefExt= "wld";
ofn.lCustData = 0;
ofn.lpfnHook = 0;
ofn.lpTemplateName = 0;

if( GetSaveFileName(&ofn) )
return mystrdup(path);
else
return 0;
}

/*
load a file
*/
static char *loadfile(char *path)
{
FILE *fp;
char *answer;
long len;
long i;
int ch;

fp = fopen(path, "r");
if(!fp)
return 0;

fseek(fp, 0, SEEK_END);
len = ftell(fp);
fseek(fp, 0, SEEK_SET);

answer = malloc(len * len/10 + 100);
if(!answer)
return 0;

while( (ch = fgetc(fp)) != EOF)
{
/* note Windows like carraige returns before newlines */
if(ch == '\n')
answer[i++] = '\r';
answer[i++] = ch;
}

answer = 0;

fclose(fp);

return answer;

}

/*
save a file to disk
*/
static int savefile(char *path, char *str)
{
FILE *fp;

fp = fopen(path, "w");
if(!fp)
return -1;
if(fwrite(str, strlen(str), 1, fp) != 1)
{
fclose(fp);
return -1;
}

return fclose(fp);
}

/*
strdup
*/
static char *mystrdup(char *str)
{
char *answer;

answer = malloc(strlen(str) + 1);
strcpy(answer, str);
return answer;
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,065
Latest member
OrderGreenAcreCBD

Latest Threads

Top