• <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")

            [基礎]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 閱讀(694) 評論(0)  編輯 收藏 引用 所屬分類: C++

            久久Av无码精品人妻系列| 囯产极品美女高潮无套久久久 | 国产真实乱对白精彩久久| 2020久久精品亚洲热综合一本| 狠狠色丁香婷婷久久综合不卡 | 久久精品嫩草影院| 国产A三级久久精品| 91久久九九无码成人网站| 亚洲精品无码久久久久去q| 欧美大战日韩91综合一区婷婷久久青草| 久久偷看各类wc女厕嘘嘘| 亚洲乱码日产精品a级毛片久久| 久久线看观看精品香蕉国产| 久久久久人妻一区精品性色av| 久久人人爽人人爽人人片av麻烦| 久久精品国产一区二区三区不卡| 久久99久久99小草精品免视看| 久久人爽人人爽人人片AV | 亚洲国产成人乱码精品女人久久久不卡 | 精品国产一区二区三区久久蜜臀| 囯产极品美女高潮无套久久久| 久久综合成人网| 污污内射久久一区二区欧美日韩| 久久综合九色综合欧美就去吻| 国产激情久久久久影院小草| 国产精品一区二区久久精品| www久久久天天com| 国产69精品久久久久777| www.久久精品| 精品久久一区二区三区| 久久国产精品久久| 久久久国产精品福利免费 | 久久91精品国产91久久小草| 99久久99这里只有免费的精品| 久久精品国产亚洲AV高清热| 久久人人爽人人爽人人片AV不| 久久精品国产亚洲AV无码娇色 | 大香伊人久久精品一区二区| 91麻豆国产精品91久久久| 国产69精品久久久久久人妻精品| 日韩人妻无码精品久久免费一 |