1.14.3 Defining new types 74
1.14.4 Unions 75
1.15 Using structures 77
1.15.1 Fine points of structure use 79
1.16 Identifier scope and linkage 80
1.17 Top-down analysis 82
1.18 Extending a program 85
1.19 Improving the design 90
1.20 Path handling 91
1.20.1 Normal handling 91
1.20.2 Security considerations 94
1.21 Traditional string representation in C 97
1.22 Memory management and memory layout 99
1.22.1 Functions for memory allocation 101
1.22.2 Memory layout under windows 101
1.23 Counting words 102
1.23.1 The organization of the table 104
1.23.2 Memory organization 105
1.23.3 Displaying the results 107
1.23.4 Code review 108
1.24 A closer look at the pre-processor 109
1.25 Time and Date functions 111
1.26 Using structures (continued) 114
1.26.1 Lists 114
1.26.2 Hash tables 117
1.27 The preprocessor in detail 118
1.27.1 Preprocessor commands 118
1.27.1.1 Preprocessor macros 119
1.27.1.2 Conditional compilation 120
1.27.1.3 The pragma directive 120
1.27.1.4 The ## operator 121
1.27.2 Things to watch when using the preprocessor 121
1.28 Pitfalls of the C language 122
1.28.1 Defining a variable in a header file 122
1.28.2 Confusing = and == 122
1.28.3 Forgetting to close a comment 122
1.28.4 Easily changed block scope. 122
1.28.5 Using the ++ or more than once in an expression. 123
1.28.6 Unexpected Operator Precedence 123
1.28.7 Extra Semi-colon in Macros 124
Chapter 2 Windows Programming 125
2.1 Introduction 125
2.2 WinMain 128
2.3 Resources 131
2.4 The dialog box procedure 135
2.5 A more advanced dialog box procedure 138
2.6 User interface considerations 140
2.7 Libraries 143
2.8 Dynamically linked libraries (DLLs) 149
2.9 Using a DLL 152
2.10 A more formal approach. 155
2.10.1 New syntax 155
2.10.2 Event oriented programming 156
2.11 A more advanced window 157
2.12 A more complex example: a "clone" of spy.exe 163
2.12.1 Creating the child windows 163
2.12.2 Moving and resizing the child windows 164
2.12.3 Starting the scanning. 164
2.12.4 Building the window tree. 165
2.12.5 Scanning the window tree 165
2.12.6 Review 166
2.12.7 Filling the status bar 168
2.12.8 Auxiliary procedures 169
2.13 Numerical calculations in C. 172
2.14 Filling the blanks 177
2.15 Using the graphical code generator 186
2.16 Understanding the wizard generated sample code 190
2.16.1 Making a new menu or modifying the given menu. 190
2.16.2 Adding a dialog box. 190
2.16.3 Drawing the window 191
2.16.4 Initializing or cleaning up 191
2.16.5 Getting mouse input. 191
2.16.6 Getting keyboard input 191
2.16.7 Handling moving/resizing 191
2.16.8 Getting notified when the mouse passes over your window 192
2.16.9 Creating additional controls in your window without using a dialog box
192
2.17 Customizing controls 193
2.17.1 Processing the WM_CTLCOLORXXX message 193
2.17.2 Using the WM_DRAWITEM message 195
2.18 Etc. 199
2.18.1 Clipboard 200
2.18.2 Communications. 200
2.18.3 Files 200
2.18.4 File systems 201
2.18.5 Graphics 201
2.18.6 Handles and Objects 201
2.18.7 Inter-Process Communications 202
2.18.8 Mail 202
2.18.9 Multimedia 203
2.18.10 Network 203
2.18.11 Hooks 203
2.18.12 Registry 203
2.18.13 Shell Programming 204
2.18.14 Services 204
2.18.15 Windows 204
2.19 Advanced C programming with lcc-win32 206
2.19.1 Operator overloading 206
2.19.2 References 206
2.19.3 Overloaded functions 207
2.19.4 Default arguments 207
2.20 Advanced windows techniques 207
2.20.1 Memory mapped files 207
2.20.2 Letting the user browse for a folder: using the shell 210
2.21 Some Coding Tips 213
2.21.1 Determining which version of Windows the program is running 214
2.21.2 Translating the value returned by GetLastError() into a readable string
214
2.21.3 Clearing the screen in text mode 214
2.21.4 Getting a pointer to the stack 215
2.21.5 Disabling the screen saver from a program 215
2.21.6 Drawing a gradient background 216
2.21.7 Capturing and printing the contents of an entire window 216
2.21.8 Centering a dialog box in the screen 219
2.21.9 Determining the number of visible items in a list box 219
2.21.10 Starting a non-modal dialog box 220
2.21.11 Propagating environment variables to the parent environment 220
2.21.12 Restarting the shell under program control 220
2.21.13 Translating client coordinates to screen coordinates 221
2.21.14 Passing an argument to a dialog box procedure 221
2.21.15 Calling printf from a windows application 221
2.21.16 Enabling or disabling a button or control in a dialog box. 221
2.21.17 Making a window class available for all applications in the system. 222
2.21.18 Accessing the disk drive directly without using a file system 222
2.21.19 Enumerating registry subkeys 223
2.21.20 Retrieving the Last-Write Time 224
2.21.21 Setting the System Time 225
2.21.22 Changing a File Time to the Current Time 225
2.21.23 Displaying the amount of disk space for each drive 225
2.22 FAQ 226
2.22.1 How do I create a progress report with a Cancel button? 226
2.22.2 How do I show in the screen a print preview? 228
2.22.3 How do I change the color of an edit field? 229
2.22.4 How do I draw a transparent bitmap? 229
2.22.5 How do I draw a gradient background? 232
2.22.6 How do I calculate print margins? 233
2.22.7 How do I calculate the bounding rectangle of a string of text? 233
2.22.8 How do I close an open menu? 234
2.22.9 How do I center a dialog box in the screen? 234
2.22.10 How do I create non-rectangular windows? 235
2.22.11 How do I implement a non-blinking caret? 235
2.22.12 How do I create a title window (splash screen)? 235
2.22.13 How do I append text to an edit control? 239
2.22.14 How do I spawn a process with redirected stdin and stdout? 240
2.22.15 How to modify the width of the list of a combo box 240
2.22.16 How do I modify environment variables permanently? 242
2.22.17 How do I translate between dialog units and pixels? 243
2.22.18 How do I translate between client coordinates to screen coordinates? 243
2.22.19 When should I use critical sections and when is a mutex more appropi-
ate? 243
2.22.20 Why is my call to CreateFile failing when I use conin$ or conout$? 244
2.23 Overview of lcc-win32’s documentation 245
2.24 Bibliography 245
2.25 Newsgroups 246
2.26 Appendix. Code listings 250
2.26.1 The window tree. 250
2.26.2 Counting chars: countchars.c 255
1
Chapter
Introduction to C
This tutorial to the C language supposes you have the lcc-win32 compiler system installed.
You will need a compiler anyway, and lcc-win32 is free for you to use, so please (if you
haven’t done that yet) download it and install it before continuing. http://www.q-software-
solutions.com
What the C language concerns, this is not a full-fledged introduction to all of C. There are
other, better books that do that (see the bibliography at the end of this book). Even if I try to
explain things from ground up, there isn’t here a description of all the features of the language.
Note too, that this is not just documentation or a reference manual. Functions in the standard
library are explained, of course, but no exhaustive documentation of any of them is provided
in this tutorial.
1
But before we start, just a quick answer to the question: why learn C?
C has been widely criticized, and many people are quick to show its problems and drawbacks.
But as languages come and go, C stands untouched. The code of lcc-win32 has software that
was written many years ago, by many people, among others by Dennis Ritchie, the creator of
the language itself
2
. The answer to this question is very simple: if you write software that is
going to stay for some time, do not learn “the language of the day”; learn C.
C doesn’t impose you any point of view. It is not object oriented, but you can do object ori-
ented programming in C if you wish.
3
It is not a functional language but you can do functional
programming
4
with it if you feel like. Most LISP interpreters and Scheme interpreters/compil-
ers are written in C. You can do list processing in C, surely not so easily like in lisp, but you
can do it. It has all essential features of a general purpose programming language like recur-
sion, procedures as first class data types, and many others that this tutorial will show you.
Many people feel that C lacks the simplicity of Java, or the sophistication of C++ with its tem-
plates and other goodies. True. C is a simple language, without any frills. But it is precisely
this lack of features that makes C adapted as a first time introduction into a complex high-level
language that allows you fine control over what your program is doing without any hidden
1. For an overview of the lcc-win32 documentation see "How to find more information"
2. Dennis Ritchie wrote the pre-processor of the lcc-win32 system.
3. Objective C generates C, as does Eiffel and several other object-oriented languages. C, precisely
because of this lack of a programming model is adapted to express all of them. Even C++ started as a pre-
processor for the C compiler.
4. See the “Illinois FP” language implementations in C, and many other functional programming
languages that are coded in C.
2 C Tutorial
features. The compiler will not do anything else than what you told it to do. The language
remains transparent, even if some features from Java like the garbage collection are incorpo-
rated into the implementation of C you are going to use.
5
As languages come and go, C remains. It was at the heart of the UNIX operating system devel-
opment in the seventies
6
, it was at the heart of the microcomputer revolution in the eighties,
and as C++, Delphi, Java, and many others came and faded, C remained, true to its own
nature.
1.1 Organization of C programs
A program in C is written in one or several text files called source modules. Each of those
modules is composed of functions, i.e. smaller pieces of code that accomplish some task
7
, and
data, i.e. variables or tables that are initialized before the program starts. There is a special
function called main that is where the execution of the program begins.
8
In C, the organization
of code in files has semantic meaning. The main source file given as an argument to the com-
piler defines a compilation unit.
9
A unit can import common definitions using the #include preprocessor directive, or just by
declaring some identifier as extern.
10
C supports the separate compilation model, i.e. you can split the program in several indepen-
dent units that are compiled separately, and then linked with the link editor to build the final
program. Normally each module is written in a separate text file that contains functions or data
declarations. Interfaces between modules are written in “header files” that describe types or
functions visible to several modules of the program. Those files have a “.h” extension, and
they come in two flavors: system-wide, furnished with lcc-win32, and private, specific to the
application you are building.
A function has a parameter list, a body, and possibly a return value.
11
The body can contain
declarations for local variables, i.e. variables activated when execution reaches the function
body.
5. Lisp and scheme, two list oriented languages featured automatic garbage collection since several
decades. APL and other interpreters offered this feature too. Lcc-win32 offers you the garbage collector
developed by Hans Boehm.
6. And today, the linux kernel is written entirely in C as most operating systems.
7. There is no distinction between functions and procedures in C. A procedure is a function of return
type void.
8. Actually, the startup code calls main. When main returns, the startup code regains control and ends
the program. This is explained in more detail in the technical documentation.
9. Any program, in any computer in any language has two main types of memory at the start:
The code
of the program, i.e. the sequence of machine instructions that the program will execute. This
section has an “entry point”, the above mentioned “main” procedure in C, or other procedure that is
used as the entry point
The static data
of the program, i.e. the string literals, the numbers or tables that are known when the
program starts. This data area con be further divided into an initialized data section, or just empty,
reserved space that is initialized by the operating system to zero when the program is loaded.
10. There is no way to import selectively some identifiers from another included file. Either you import
all of it or none.
Hello 3
The body is a series of expressions separated by semicolons. Each statement can be an arith-
metic operation, an assignment, a function call, or a compound statement, i.e. a statement that
contains another set of statements.
1.2 Hello
To give you an idea of the flavor of C we use the famous example given already by the authors
of the language
12
. We build here a program that when invoked will put in the screen the mes-
sage “hello”.
#include <stdio.h> (1)
int main(void) (2)
{ (3)
printf("Hello\n"); (4)
return 0; (5)
} (6)
1) Using a feature of the compiler called ‘pre-processor’, you can textually include a whole
file of C source with the “#include” directive. In this example we include from the standard
includes of the compiler the “stdio.h” header file.
13
2) We define a function called “main” that returns an integer as its result, and receives no
arguments (void).
14
3) The body of the function is a list of statements enclosed by curly braces.
4) We call the standard function “printf” that formats its arguments in a character string that is
displayed in the screen. A function call in C is written like this:function-name ‘(‘
argument-list ‘)’. In this case the function name is “printf”, and its argument
list is the character string “Hello\n”
15
. Character strings are enclosed in double quotes.
They are represented in C as an array of characters finished by a zero byte.
5) The return statement indicates that control should be returned (hence its name) to the
calling function. Optionally, it is possible to specify a return result, in this case the integer
zero.
6) The closing brace finishes the function scope.
11. In C, only one return value is possible. A function, however can return several return values if it
modifies its environment.
12. This example is a classic, and appears already in the tutorial of the C language published by B. W.
Kernighan in 1974, four years before the book “The C programming language” was published. Their example
would still compile today, albeit with some warnings:
main() { printf(“Hello world\n”); }
13. The name of the include file is enclosed within a <> pair. This indicates the compiler that it should
look for this include file in the standard include directory, and not in the current directory. If you want to
include a header file in another directory or in the compilation directory, use the double quotes to enclose the
name of the file, like #include “myfile.h”
14. This is one of the two possible definitions of the “main” function. Later we will see the other one.
15. Character strings can contain sequences of characters that denote graphical characters like new line
(\n) tab (\t), backspace (\b), or others. In this example, the character string is finished by the new line
character \n.
4 C Tutorial
Programs in C are defined in text files that normally have the .c extension. You can create
those text files with any editor that you want, but lcc-win32 proposes a specialized editor for
this task called “Wedit”. This program allows you to enter the program text easily, since it is
adapted to the task of displaying C source text.
To make this program then, we start Wedit and enter the text of that program above.
16
Once this
is done, you can compile, and link-edit your program by just clicking in the compile menu or
pressing F9.
17
To run the program, you use the “execute” option in the compile menu (Ctrl+F5), or you open
a command shell and type the program’s name. Let’s do it the hard way first.
16. You start wedit by double clicking in its icon, or, if you haven’t an icon for it by going to the “Start”
menu, run, and then type the whole path to the executable. For instance, if you installed lcc-win32 in c:\lcc,
wedit will be in c:\lcc\bin\wedit.exe
17. If this doesn’t work or you receive warnings, you have an installation problem (unless you made a
typing mistake). Or maybe I have a bug. When writing mail to me do not send messages like: “It doesn’t
work”. Those messages are a nuisance since I can’t possibly know what is wrong if you do not tell me exactly
what is happening. Wedit doesn’t start? Wedit crashes? The computer freezes? The sky has a black color?
Keep in mind that in order to help you I have to reproduce the problem in my setup. This is impossible
without a detailed report that allows me to see what goes wrong.
Wedit will make a default project for you, when you click the “compile” button. This can go wrong if
there is not enough space in the disk to compile, or the installation of lcc-win32 went wrong and Wedit can’t
find the compiler executable, or many other reasons. If you see an error message please do not panic, and try
to correct the error the message is pointing you to.
A common failure happens when you install an older version of Wedit in a directory that has spaces in it.
Even if there is an explicit warning that you should NOT install it there, most people are used to just press
return at those warnings without reading them. Then, lcc-win32 doesn’t work and they complain to me. I have
improved this in later versions, but still problems can arise.
Hello 5
The first thing we need to know is the name of the program we want to start. This is easy; we
ask Wedit about it using the “Executable stats” option in the “Utils” menu. We get the follow-
ing display.
We see at the first line of the bottom panel, that the program executable is called:
h:\lcc\projects\hello.exe
We open a command shell window, and type the command:
C:\>h:\lcc\projects\lcc1\hello.exe
Hello
C:\>
Our program displays the character string “Hello” and then a new line, as we wanted. If we
erase the \n of the character string, press F9 again to recompile and link, the display will be:
C:\>h:\lcc\projects\lcc1\hello.exe
Hello
C:\>
But how did we know that we have to call “printf” to display a string?
Because the documentation of the library told us so… The first thing a beginner to C must do
is to get an overview of the libraries provided already with the system so that he/she doesn’t
waste time rewriting programs that can be already used without any extra effort. Printf is one
of those, but are several thousands of pre-built functions of all types and for all tastes. We
present an overview of them in the next section.
1.2.1 An overview of the compilation process
When you press F9 in the editor, a complex sequence of events, all of them invisible to you,
produce an executable file. Here is a short description of this, so that at least you know what’s
happening behind the scene.
Wedit calls the C compiler proper. This program is called lcc.exe and is in the installation
directory of lcc, in the bin directory. For instance, if you installed lcc in c:\lcc, the compiler
will be in c:\lcc\bin.
This program will read your source file, and produce another file called object file,
18
that has
the same name as the source file but a .obj extension. C supports the separate compilation
Không có nhận xét nào:
Đăng nhận xét