• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            我住包子山

            this->blog.MoveTo("blog.baozishan.in")

            [基礎(chǔ)]Win32 Console Applications - Part 2 of 6 from adrianxw.dk

            Win32 Console Applications - Part 2.

            I started part 1 of this tutorial by showing the classic "Hello Worlrd!" program. The output looked like this.

            Hello World

            By default, Windows places the path of the executable in the window title. You can change this to a word or phrase of your choice. Here is the Hello World! program modified to do this.

            #include <windows.h>
            #include <iostream>
            using namespace std;
            
            int main()
            {
                SetConsoleTitle("Hello!");
                cout << "Hello World!" << endl;
                return 0;
            }
            

            Notice I've now added the windows.h header to the program, and a call to SetConsoleTitle(). The output now looks like this.

            Hello World

            Later on, we'll see that knowing the name of your window can be useful, and setting it yourself is, of course, an easy way of knowing it!

            As an aside, almost all of the API routines return a status indicating success or failure. For clarity of the example code in these tutorials, I am not checking this value. To be more professional, you should check the return values of API routines you call. Even if you cannot recover from the error, it is often useful in debugging to know what routine failed, and if possible, why. This program shows the checking of the return status and aborts the program if the routine fails, (note the inclusion of process.h for the exit() API routine). You should refer to your compiler's help or MSDN to see what the return values of a routine are.

            #include <windows.h>
            #include <process.h>
            #include <iostream>
            using namespace std;
            
            int main()
            {
                int Status;
            
                Status = SetConsoleTitle("Hello!");
                if (Status == 0)
                {
                    Status = GetLastError();
                    cout << "SetConsoleTitle() failed! Reason : " << Status << endl;
                    exit(Status);
                }
            
                cout << "Hello World!" << endl;
                return 0;
            }
            
            ----------

            All consoles have 3 "standard handles" and many of the console handling functions require a "handle" to perform I/O.

            A "handle" is simply a 32 bit integer. It is the way Windows differentiates between objects of the same type. Consider the console, it has a title bar, minimize, maximize and close buttons, one or more scroll bars, etc. It is, when you think about it, quite a complicated thing, and somewhere there must be a lot of data that the system is using to make it all work. Windows hides all of that complexity from you, you can play with all this data if you want to of course, but the point here is, you don't have to if you don't want to. Windows looks after it all for you, and all you have to do is tell it the handle of whatever it is you want to use. Once you get into full Windows programming, you'll find a lot of things are used by supplying a "handle". If you don't understand right now, don't worry about it, a handle is easy to get, and easy to use.

            To get the standard handles, declare variable of type HANDLE and initialise them with a call to GetStdHandle(). This program, (which doesn't actually do anything!), illustrates the process. We'll use the standard handles later.

            #include <windows.h>
            
            int main()
            {
                HANDLE hIn;
                HANDLE hOut;
                HANDLE hError;
            
                hIn = GetStdHandle(STD_INPUT_HANDLE);
                hOut = GetStdHandle(STD_OUTPUT_HANDLE);
                hError = GetStdHandle(STD_ERROR_HANDLE);
            
                return 0;
            }
            

            The standard input handle is used with routines that read data from a console, the standard output handle with routines that send data to a console. The standard error handle also outputs to the console by default, and frankly is not used very much, just be aware of it.

            There are a couple of routines ReadConsole() and WriteConsole() that perform I/O using these handles, but for now at least, we'll continue with the standard C++ I/O functions.

            ----------

            Now we've got the handles, lets do something with them, let's move the cursor around. To do this we'll need to use a COORD structure. This is a very simple structure containing an x and y coordinate. It is declared like this.

            typedef struct _COORD {
                SHORT X;
                SHORT Y;
            } COORD; 
            

            To move the cursor, you simply set up the COORD to the coordinates you want the cursor moved to and call the SetConsoleCursorPosition() API function. Here is a simple program which does just that.

            #include <windows.h>
            #include <iostream>
            using namespace std;
            
            int main()
            {
                HANDLE hOut;
                int i;
                COORD Position;
            
                hOut = GetStdHandle(STD_OUTPUT_HANDLE);
            
                for(i=0; i<10; i+=2)
                {
                    Position.X = i;
                    Position.Y = i;
                    SetConsoleCursorPosition(hOut,
                                             Position);
                    cout << "*" << flush;
                }
            
                return 0;
            }
            

            The output looks like this.

            Move Cursor

            As you see, each iteration of the loop moves the cursor two rows down and two columns right. To return the cursor to the "home" position, (top left corner), send it to (0,0). Creative use of this function can give pleasing effects.

            ----------

            The next routine I want to show you is FillConsoleOutputCharacter(). This routine allows you to write a whole load of characters to the console in one go. The function prototype is shown here.

            BOOL FillConsoleOutputCharacter(
              HANDLE hConsoleOutput,
              TCHAR cCharacter,
              DWORD nLength,
              COORD dwWriteCoord,
              LPDWORD lpNumberOfCharsWritten
            );
            

            A bit more complicated then any of the routines we've used so far, but really very easy to use. The first parameter is the handle to the output buffer, you know how to get that. The next is the character you want to write, easy enough. The next, is how many times you want it to write the character out, still easy. Next is a COORD telling it where to start, we've already covered that. Finally, the routine wants a place where it can tell you how many characters it actually wrote, this has to be therefore, the address of a variable in your program. You may be wondering why this argument is there at all, but consider the situation where your screen buffer is, for example, 5000 characters long. If you tell the routine to output 5100, it will not error, it will fill the 5000 characters, and then tell you that it did that by setting the value accordingly. If you're not interested, ignore it, but you must supply a place for the routine to use, in this case, I've passed the address of the "Written" variable like this &Written.

            This program uses FillConsoleOutputCharacter() to draw a line of 15 "X" characters starting at (4,4), the unsuprising output of the program is also shown below.

            #include <windows.h>
            #include <iostream>
            using namespace std;
            
            int main()
            {
                HANDLE hOut;
                COORD Position;
                DWORD Written;
            
                hOut = GetStdHandle(STD_OUTPUT_HANDLE);
            
                Position.X = 4;
                Position.Y = 4;
            
                FillConsoleOutputCharacter(hOut,
                                           'X',
                                           15,
                                           Position,
                                           &Written);
            
                return 0;
            }
            
            Fill Console

            See what happens if I change the call to output 150 instead of 15 characters, (I've shrunk the picture to make it load faster - changing the call did not change the screen resolution!!!).

            Fill Console

            The point to note is that when the routine reached the end of the line, it continued at the beginning of the line below. Suppose, instead of line 5 column 5 I'd said (0,0), and suppose I'd used a space character instead of an 'X', and suppose I'd told it to draw enough characters to completely fill the screen buffer - hey - I've cleared the screen! Clearing the screen is THE most common console related question that comes up in the forums, there's the answer.

            ----------

            It is also possible to read one or more characters from a specific position in the screen buffer. To do that, we use the ReadConsoleOutputCharacter() API routine. This routine has very similar parameters to the last, it's prototype is shown here.

            BOOL ReadConsoleOutputCharacter(
              HANDLE hConsoleOutput,
              LPTSTR lpCharacter,
              DWORD nLength,
              COORD dwReadCoord,
              LPDWORD lpNumberOfCharsRead 
            );
            

            As before, the first is the standard handle. Next, remember, we are reading now, so the routine wants somewhere to write the information to, so it needs a pointer to a place where it can store characters. The rest of the parameters are as before, the number of characters to process, the start point, and a pointer to a place it can write the actual number read.

            This program uses the routine twice, once to retrieve the single character at the (0,0) position, and a second time to retrieve 5 characters starting from position (4,0). If the number of characters requested is longer than the current line, reading continues from the first character of the line below as before. Again, as before, if the number requested is more than there are in the buffer, the characters up to the end of the buffer are returned, the actual number appearing in the final parameter.

            #include <windows.h>
            #include <iostream>
            using namespace std;
            
            int main()
            {
                HANDLE hOut;
                char Letter;
                char Letters[5];
                COORD Where;
                DWORD NumRead;
                int i;
            
                hOut = GetStdHandle(STD_OUTPUT_HANDLE);
            
                cout << "A line of little consequence." << endl;
            
                Where.X = 0;
                Where.Y = 0;
                ReadConsoleOutputCharacter(hOut,
                                           &Letter,
                                           1,
                                           Where,
                                           &NumRead);
                cout << "Letter at (0,0) is " << Letter << endl;
            
                Where.X = 4;
                ReadConsoleOutputCharacter(hOut,
                                           Letters,
                                           5,
                                           Where,
                                           &NumRead);
                cout << "5 letters starting from (4,0) ";
                for (i=0; i<5; i++)
                {
                    cout << Letters[i];
                }
                cout << endl;
            
                return 0;
            }
            

            The output from the program looks like this.

            ReadConsoleOutputCharacter

            It would have been quite permissable to dimension the Letters array to 6, read the 5 characters from the console then manually set the final character to NULL. In that way, the cout could have taken the name of the string, (as it is now NULL terminated), instead of writing the characters out individually in a loop.

            In the next part of the tutorial, we'll look at the limited graphical capabilities of consoles, drawing lines, boxes and grids.

            Win32 Console Applications - Part 2.

            I started part 1 of this tutorial by showing the classic "Hello Worlrd!" program. The output looked like this.

            Hello World

            By default, Windows places the path of the executable in the window title. You can change this to a word or phrase of your choice. Here is the Hello World! program modified to do this.

            #include <windows.h>
            #include <iostream>
            using namespace std;
            
            int main()
            {
                SetConsoleTitle("Hello!");
                cout << "Hello World!" << endl;
                return 0;
            }
            

            Notice I've now added the windows.h header to the program, and a call to SetConsoleTitle(). The output now looks like this.

            Hello World

            Later on, we'll see that knowing the name of your window can be useful, and setting it yourself is, of course, an easy way of knowing it!

            As an aside, almost all of the API routines return a status indicating success or failure. For clarity of the example code in these tutorials, I am not checking this value. To be more professional, you should check the return values of API routines you call. Even if you cannot recover from the error, it is often useful in debugging to know what routine failed, and if possible, why. This program shows the checking of the return status and aborts the program if the routine fails, (note the inclusion of process.h for the exit() API routine). You should refer to your compiler's help or MSDN to see what the return values of a routine are.

            #include <windows.h>
            #include <process.h>
            #include <iostream>
            using namespace std;
            
            int main()
            {
                int Status;
            
                Status = SetConsoleTitle("Hello!");
                if (Status == 0)
                {
                    Status = GetLastError();
                    cout << "SetConsoleTitle() failed! Reason : " << Status << endl;
                    exit(Status);
                }
            
                cout << "Hello World!" << endl;
                return 0;
            }
            
            ----------

            All consoles have 3 "standard handles" and many of the console handling functions require a "handle" to perform I/O.

            A "handle" is simply a 32 bit integer. It is the way Windows differentiates between objects of the same type. Consider the console, it has a title bar, minimize, maximize and close buttons, one or more scroll bars, etc. It is, when you think about it, quite a complicated thing, and somewhere there must be a lot of data that the system is using to make it all work. Windows hides all of that complexity from you, you can play with all this data if you want to of course, but the point here is, you don't have to if you don't want to. Windows looks after it all for you, and all you have to do is tell it the handle of whatever it is you want to use. Once you get into full Windows programming, you'll find a lot of things are used by supplying a "handle". If you don't understand right now, don't worry about it, a handle is easy to get, and easy to use.

            To get the standard handles, declare variable of type HANDLE and initialise them with a call to GetStdHandle(). This program, (which doesn't actually do anything!), illustrates the process. We'll use the standard handles later.

            #include <windows.h>
            
            int main()
            {
                HANDLE hIn;
                HANDLE hOut;
                HANDLE hError;
            
                hIn = GetStdHandle(STD_INPUT_HANDLE);
                hOut = GetStdHandle(STD_OUTPUT_HANDLE);
                hError = GetStdHandle(STD_ERROR_HANDLE);
            
                return 0;
            }
            

            The standard input handle is used with routines that read data from a console, the standard output handle with routines that send data to a console. The standard error handle also outputs to the console by default, and frankly is not used very much, just be aware of it.

            There are a couple of routines ReadConsole() and WriteConsole() that perform I/O using these handles, but for now at least, we'll continue with the standard C++ I/O functions.

            ----------

            Now we've got the handles, lets do something with them, let's move the cursor around. To do this we'll need to use a COORD structure. This is a very simple structure containing an x and y coordinate. It is declared like this.

            typedef struct _COORD {
                SHORT X;
                SHORT Y;
            } COORD; 
            

            To move the cursor, you simply set up the COORD to the coordinates you want the cursor moved to and call the SetConsoleCursorPosition() API function. Here is a simple program which does just that.

            #include <windows.h>
            #include <iostream>
            using namespace std;
            
            int main()
            {
                HANDLE hOut;
                int i;
                COORD Position;
            
                hOut = GetStdHandle(STD_OUTPUT_HANDLE);
            
                for(i=0; i<10; i+=2)
                {
                    Position.X = i;
                    Position.Y = i;
                    SetConsoleCursorPosition(hOut,
                                             Position);
                    cout << "*" << flush;
                }
            
                return 0;
            }
            

            The output looks like this.

            Move Cursor

            As you see, each iteration of the loop moves the cursor two rows down and two columns right. To return the cursor to the "home" position, (top left corner), send it to (0,0). Creative use of this function can give pleasing effects.

            ----------

            The next routine I want to show you is FillConsoleOutputCharacter(). This routine allows you to write a whole load of characters to the console in one go. The function prototype is shown here.

            BOOL FillConsoleOutputCharacter(
              HANDLE hConsoleOutput,
              TCHAR cCharacter,
              DWORD nLength,
              COORD dwWriteCoord,
              LPDWORD lpNumberOfCharsWritten
            );
            

            A bit more complicated then any of the routines we've used so far, but really very easy to use. The first parameter is the handle to the output buffer, you know how to get that. The next is the character you want to write, easy enough. The next, is how many times you want it to write the character out, still easy. Next is a COORD telling it where to start, we've already covered that. Finally, the routine wants a place where it can tell you how many characters it actually wrote, this has to be therefore, the address of a variable in your program. You may be wondering why this argument is there at all, but consider the situation where your screen buffer is, for example, 5000 characters long. If you tell the routine to output 5100, it will not error, it will fill the 5000 characters, and then tell you that it did that by setting the value accordingly. If you're not interested, ignore it, but you must supply a place for the routine to use, in this case, I've passed the address of the "Written" variable like this &Written.

            This program uses FillConsoleOutputCharacter() to draw a line of 15 "X" characters starting at (4,4), the unsuprising output of the program is also shown below.

            #include <windows.h>
            #include <iostream>
            using namespace std;
            
            int main()
            {
                HANDLE hOut;
                COORD Position;
                DWORD Written;
            
                hOut = GetStdHandle(STD_OUTPUT_HANDLE);
            
                Position.X = 4;
                Position.Y = 4;
            
                FillConsoleOutputCharacter(hOut,
                                           'X',
                                           15,
                                           Position,
                                           &Written);
            
                return 0;
            }
            
            Fill Console

            See what happens if I change the call to output 150 instead of 15 characters, (I've shrunk the picture to make it load faster - changing the call did not change the screen resolution!!!).

            Fill Console

            The point to note is that when the routine reached the end of the line, it continued at the beginning of the line below. Suppose, instead of line 5 column 5 I'd said (0,0), and suppose I'd used a space character instead of an 'X', and suppose I'd told it to draw enough characters to completely fill the screen buffer - hey - I've cleared the screen! Clearing the screen is THE most common console related question that comes up in the forums, there's the answer.

            ----------

            It is also possible to read one or more characters from a specific position in the screen buffer. To do that, we use the ReadConsoleOutputCharacter() API routine. This routine has very similar parameters to the last, it's prototype is shown here.

            BOOL ReadConsoleOutputCharacter(
              HANDLE hConsoleOutput,
              LPTSTR lpCharacter,
              DWORD nLength,
              COORD dwReadCoord,
              LPDWORD lpNumberOfCharsRead 
            );
            

            As before, the first is the standard handle. Next, remember, we are reading now, so the routine wants somewhere to write the information to, so it needs a pointer to a place where it can store characters. The rest of the parameters are as before, the number of characters to process, the start point, and a pointer to a place it can write the actual number read.

            This program uses the routine twice, once to retrieve the single character at the (0,0) position, and a second time to retrieve 5 characters starting from position (4,0). If the number of characters requested is longer than the current line, reading continues from the first character of the line below as before. Again, as before, if the number requested is more than there are in the buffer, the characters up to the end of the buffer are returned, the actual number appearing in the final parameter.

            #include <windows.h>
            #include <iostream>
            using namespace std;
            
            int main()
            {
                HANDLE hOut;
                char Letter;
                char Letters[5];
                COORD Where;
                DWORD NumRead;
                int i;
            
                hOut = GetStdHandle(STD_OUTPUT_HANDLE);
            
                cout << "A line of little consequence." << endl;
            
                Where.X = 0;
                Where.Y = 0;
                ReadConsoleOutputCharacter(hOut,
                                           &Letter,
                                           1,
                                           Where,
                                           &NumRead);
                cout << "Letter at (0,0) is " << Letter << endl;
            
                Where.X = 4;
                ReadConsoleOutputCharacter(hOut,
                                           Letters,
                                           5,
                                           Where,
                                           &NumRead);
                cout << "5 letters starting from (4,0) ";
                for (i=0; i<5; i++)
                {
                    cout << Letters[i];
                }
                cout << endl;
            
                return 0;
            }
            

            The output from the program looks like this.

            ReadConsoleOutputCharacter

            It would have been quite permissable to dimension the Letters array to 6, read the 5 characters from the console then manually set the final character to NULL. In that way, the cout could have taken the name of the string, (as it is now NULL terminated), instead of writing the characters out individually in a loop.

            In the next part of the tutorial, we'll look at the limited graphical capabilities of consoles, drawing lines, boxes and grids.

            posted on 2006-07-20 22:46 Gohan 閱讀(699) 評論(0)  編輯 收藏 引用 所屬分類: C++

            综合久久精品色| 久久精品国产亚洲AV无码娇色| 久久久久久国产精品无码下载| 精品久久人人做人人爽综合| 久久美女人爽女人爽| 久久精品无码午夜福利理论片| 久久精品国产男包| 午夜精品久久久久久毛片| 久久天天躁狠狠躁夜夜不卡| 伊色综合久久之综合久久| 欧美国产成人久久精品| 奇米综合四色77777久久| 久久久久亚洲av成人无码电影| 无码久久精品国产亚洲Av影片| 国产综合免费精品久久久| 久久精品国产精品亚洲精品| 国产精品久久久久影院嫩草| .精品久久久麻豆国产精品| 狠狠色丁香婷婷综合久久来 | 激情五月综合综合久久69| 一本大道加勒比久久综合| 狠狠色综合久久久久尤物| 久久有码中文字幕| 久久综合狠狠综合久久| 亚洲嫩草影院久久精品| 亚洲国产成人久久一区WWW| 久久亚洲精品无码aⅴ大香| 久久97精品久久久久久久不卡| 亚洲国产成人久久综合一 | 亚洲va久久久噜噜噜久久天堂| 久久久国产精品亚洲一区| 久久精品国产亚洲精品| 亚洲狠狠婷婷综合久久久久| 亚洲国产精品久久| 7777精品久久久大香线蕉| 欧美激情精品久久久久| 囯产极品美女高潮无套久久久 | 热久久这里只有精品| 精品国产日韩久久亚洲| 久久99热狠狠色精品一区| 国产A三级久久精品|