Lesson 33 of happy senior 4 introduced how to use CChart to draw curves in the console program. In fact, the method is very simple, that is, create a pop-up window and draw on this pop-up window. In fact, the technical content is relatively low.
In this lesson, Benben wants to introduce you how to draw directly on the console window. What, is that the Dos window of the black Raglan? Hearing this idea, do you want to vomit blood? ha-ha!!!!!
Drawing in the console window, the most difficult thing is that there are no things we take for granted in the Win32 window, such as various messages!
Let's go back to the Paleolithic age.
The first step is to establish a console program. Pay attention to selecting "A simple application", so that the IDE will help to establish an empty program and save a little trouble.
The second step is to introduce CChart and add the header file to be used.
#include "Chart.h" #if defined(_UNICODE) || defined(UNICODE) # pragma comment(lib,"CChartu.lib") #else # pragma comment(lib,"CChart.lib") #endif using namespace NsCChart; #include <windows.h> #include <stdio.h> #include <conio.h> #include <math.h> #define WM_MOUSEWHEEL 0x020A extern "C" WINBASEAPI HWND WINAPI GetConsoleWindow();
An unpublished API of Windows, GetConsoleWindow(), is introduced here to find the console window handle of the program. The API FindWindow can also be used, but it is troublesome.
Step 3: add two global variables.
CChart chart; HWND hWnd;
Here chart is used for drawing. Needless to say, hWnd is used to save the console window handle.
The fourth step is to write the drawing sub function.
// Drawing function void MyDraw() { HDC hDC = GetDC(hWnd); RECT rt; GetClientRect(hWnd, &rt); rt.top = (rt.top+rt.bottom)/2; chart.OnDraw(hDC, rt); ReleaseDC(hWnd, hDC); }
Everyone should be familiar with this routine. Note that we want to draw by using the lower half of the console window.
With the global HWND handle, use GetDC to obtain HDC and draw on HDC. Finally, the HDC must be released, or the memory will leak.
Step 5: initialize hWnd at the beginning of the main() function.
hWnd = GetConsoleWindow();
Here, the unpublished API is used to obtain the console window handle.
Step 6: set CChart data.
double pi = 4.0*atan(1.0); int perioid = 360; for(int i=0; i<4*perioid; ++i) { chart.AddPoint2D(i, 1.4*sin(i*2.0*pi/perioid)); } chart.SetTitle(_T("Drawing in console window"));
Of course, you can add any data here.
Step 7, drawing. Add after the above code:
MyDraw(); printf("Console window drawing!\n");
Here we simply call the drawing sub function written earlier. Since we are drawing in the lower half of the window, and the upper half can still be used for character output on the console, we tested the printf output function here.
The effect is as shown in the picture!
What about? Still good!
Step 8, adjust the style.
Here, CChart has a white background by default, and the console window has a black background, which is a little inconsistent. Let's add the following two sentences to adjust it.
chart.SetBkgndColor(RGB(0, 0, 0)); chart.SetTitleColor(RGB(245, 245, 245));
Now the effect is as shown in the figure.
Now it's integrated.
Step 9: add message loop and redraw function.
From the output image, you can see the words Press any key to continue. Old birds know that this means that the program has ended.
In addition, if we hide the console window and open it again, the image will disappear. This does not meet our needs.
Add the following code after the above code.
HANDLE hIn = GetStdHandle(STD_INPUT_HANDLE); HANDLE Hout = GetStdHandle(STD_OUTPUT_HANDLE); INPUT_RECORD inp; DWORD recnum; bool loop = true; while(loop) { ReadConsoleInput(hIn, &inp, 1, &recnum); switch(inp.EventType) { case FOCUS_EVENT: MyDraw(); break; } } CloseHandle(hIn); CloseHandle(Hout);
The effect is shown in the figure.
An endless loop is added to process messages. Unlike the normal Windows message loop, the message is read with ReadConsoleInput and displayed in the window focus event focus_ Redraw in event.
This solves the above problem. Note that the character cursor is flashing, indicating that the program is running and does not end.
Step 10: add an endless loop exit mechanism.
The above loop cannot exit. Although Ctrl+C can exit the program, it will affect the release of resources.
Add code.
case KEY_EVENT: if(inp.Event.KeyEvent.uChar.AsciiChar=='c' || inp.Event.KeyEvent.uChar.AsciiChar=='C')loop = false; break;
Now press the c key to exit. Note the difference between Ctrl+C and Ctrl+C. The c key just exits the loop, and the console window is still there. Ctrl+C closes even the console window.
Step 11: add a mouse to process the message.
Add two variables for message processing before the loop.
POINT point; UINT message;
Add message processing code.
case MOUSE_EVENT: if(inp.Event.MouseEvent.dwEventFlags == 0)//Click (including press or release) { if(inp.Event.MouseEvent.dwButtonState == FROM_LEFT_1ST_BUTTON_PRESSED)//Left key press { message = WM_LBUTTONDOWN; } else if(inp.Event.MouseEvent.dwButtonState == RIGHTMOST_BUTTON_PRESSED)//Right click { message = WM_CONTEXTMENU; } else if(inp.Event.MouseEvent.dwButtonState == FROM_LEFT_2ND_BUTTON_PRESSED)//Roller { message = WM_MOUSEWHEEL; } //When released: else if(inp.Event.MouseEvent.dwButtonState == 0) { message = WM_LBUTTONUP; } } else if(inp.Event.MouseEvent.dwEventFlags == DOUBLE_CLICK)//double-click { message = WM_LBUTTONDBLCLK; } else if(inp.Event.MouseEvent.dwEventFlags == MOUSE_MOVED)//move { message = WM_MOUSEMOVE; } else { message = WM_MOUSEMOVE; } GetCursorPos(&point); ScreenToClient(hWnd, &point); if(chart.OnEvent(hWnd, message, inp.Event.MouseEvent.dwControlKeyState, point.x + (point.y<<16))) MyDraw(); break;
As you can see, save it in input first_ The mouse event information in the RECORD variable is converted to the conventional mouse message of Windows, and then the CChart processing function OnEvent is called to process the message. In addition, input_ The record variable does not save the pixel position information of the mouse, but only the row and column information of character input. Here, the screen coordinates of the mouse are directly read and converted into the coordinates of the client area of the console window. The lower 16 bits of the LPARAM variable of the mouse message are the x coordinates of the client area and the upper 16 bits are the Y coordinates of the client area. The point. X + (point. Y < < 16) is used to convert the point into LPARAM.
The operation effect is shown in the figure.
Various messages of the mouse can be processed normally except the right-click menu. I don't know how to adjust the right-click menu of the console yet.
There are no problems with various dialog windows.
Today's trip to the Paleolithic age is over.