Plotting a graph in C++ window - c++

I want to plot a graph out of simple functions/set of coordinates in a window. I know the c++ win32 basics and I can make a simple window with buttons and other control objects. But which is the fastest and easiest library to plot a graph to my program?

I expect you are using Win32 API (not CLR).
Theory is easy, you need to obain device context withing WM_PAINT message.
You can use main window or any child window (control - static, button) inside main window.
Here are some usefull links:
http://www.codeproject.com/Articles/2078/Guide-to-WIN32-Paint-for-Intermediates
http://www.codeproject.com/Articles/66250/BeginPaint-EndPaint-or-GetDC-ReleaseDC.aspx
eg:
case WM_PAINT:
BeginPaint(hWnd, &ps);
LineTo(ps.hDC, 30,30);
EndPaint(hWnd, &ps);
return 0;
This will draw line from 0,0 to 30,30

Here is the light, easy to use library:
http://www.codeproject.com/Articles/1546/Plot-Graphic-Library

Related

GDI Win32 Plotting Graphs

In my small, small and humble c++ Win32 GUI application, I got to the point of being able to draw a grid :
This is in preparation for displaying spectral data, the 36 (floats) measurement points returned from my device. I still have to get the axis labeled... This is my code for drawing the grid so far :
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &ps);
FillRect(hdc, &ps.rcPaint, HBRUSH (COLOR_WINDOW + 1));
bool Retour;
pen = (HPEN)GetStockObject(TRANSPARENT);
SelectObject(hdc, pen);
Brosse = CreateSolidBrush(RGB(240, 240, 240));
SelectObject(hdc, Brosse);
Retour = LineTo(hdc, 100, 500);*/
Retour = Rectangle(hdc, 350, 150, 750, 375);
for (int i = 380; i <= 730; i=i+10) { // 36 vertical lines
MoveToEx(hdc, i, 175, NULL);
LineTo(hdc, i, 350);
}
for (int i = 175; i <= 350; i = i + 17) {
MoveToEx(hdc, 375, i, NULL);
LineTo(hdc, 730, i);
}
DeleteObject(pen);
DeleteObject(Brosse);
EndPaint(hWnd, &ps);
As you can see, I located the code to draw the grid inside the WM_PAINT procedure. It made sense to locate the code there to experiment with GDI instructions but also because the grid needs to be visible at launch time as part of the interface.
My question is how should I go "updating" the graph when, after pressing the "Measure Sample" button, I have access to the data? I gather that the code to draw on the grid does not necessarily needs to be located inside the WM_PAINT procedure, does it? According to my limited understanding, as long as I can get a Device Context handle (hDC), I should be good to go? All I need to plot is a "line" uniting the 36 data points from left to right. Not sure I should use simple MOVE_TO and LINE_TO for this purpose? I think there is a way to draw a "smoothed" line that passes through all 36 data points?
One last thing, if I may... I'm going at this in a very elementary way because I'm intimidated by the idea of using a "graphic library" and objects. But I suspect they would make my life a lot easier while offering umpteen options that will take me too long to figure out, I'll bet, and implement?
Thank you so much in advance for your kind help and patience.
You should always do all your drawing in your WM_PAINT handler. That way, the window will redraw correctly when something that was covering it is removed, for example.
When your graph data changes, call InvalidateRect to prompt a redraw.
To determine what to redraw, you will need to pass suitable variables to your WM_PAINT handler. Start with MoveTo and LineTo (or Polyline or PolyPolyline) and get that working first. You can then investigate smoothing algorithms if you think you need them.
You should place all of your custom painting code in the WM_PAINT handler of the window, yes. You can call a separate function for painting the graph if you like. Pass it the HDC you get from BeginPaint(...) and your spectral data. However, that function needs to be called from the WM_PAINT handler.
If you handle painting in WM_PAINT then to update the graph when the data changes you would call InvalidateRect(...) on the window. InvalidateRect tells Windows essentially "this window has changed and needs to be repainted". It will drive a call to the paint handler.
One problem you are going to run into is that your graph is going to flicker. It may not be too noticeable. It may not bother you, but the problem is that in each call to the WM_PAINT handler you are erasing the graph in the screen device context; this erasure will be visible. A solution to this problem would be to "double-buffer" the graph: create an offscreen bitmap, paint into that when data changes, and paint the offscreen bitmap to the screen in WM_PAINT. You could also make the graph a separate child window that manages the offscreen bitmap, etc., if you are ever going to need multiple graphs or just to add some modularity to the code.
As for whether you'd have an easier time with a graphics library ... possibly, but more to the point: you would have an easier time using a higher level GUI library than the Win32 API. If you only care about Windows, consider the .Net frameworks WinForms or WPF. Otherwise, consider Qt.

How to color a specific pixel in windows console

I am new to c++ programming and I find it interesting and fun to learn.
Can anybody give me an idea in setting color for a specific pixel in a windows console while the color will stay permanent even the windows console is refreshed or moved.
I used Setpixel() for my recent code.Here are some code snippets assuming it inside the body of a function:
HWND myconsole = GetConsoleWindow();
HDC dc = GetDC(myconsole);
COLORREF color = RGB(255,120,120);
for(int count =0;count<100;count++)
{
SetPixel(dc,0,count,color);
}
Any idea and opinion would be a great help.Thanks!
Either you're question was unclear or you changed you're mind subsequently and decided you wanted to draw on a Win32 window, not a Win32 console window. In any case here are answers for both questions.
Drawing to a Win32 window (not a console)
You can draw to a Win32 project a number of ways (including graphics APIs like OpenGL and DirectX). The simplest way is to use Windows GDI (Graphics Device Interface) which is simply a number of functions which are part of Windows.h.
SetPixel() will draw to whichever Device Context you give it a handle to (the first argument). This handle must be to the Device Context of your main window if you wish to draw on the window (you could also give it a handle to an off-screen surface like a backbuffer).
So to get the handle to the Device Context of your main window use: GetDC(hWnd) where hWnd is a handle to your main window. The returned Device Context handle can be used in SetPixel() to draw to the window.
HDC _hWindowDC = GetDC(_hWnd);
SetPixel(_hWindowDC, _iXpos, _iYpos, _myColorRef);
If you want to draw to Device Context like you are trying to do, you need to make a Win32 Project, not a Win32 Console project.
Drawing to a Win32 console project
As mentioned in the comments, for a console project, you can only "draw" characters, not pixels. For example you could pick a screen coordinate and cout some characters like so:
COORD point;
point.X = _iX;
point.Y = _iY;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), point);
cout << "Whatever";
#Cody Gray this is the snippets when i tried WriteConsoleOutput.This is not so great but maybe it can help other.. if someone can give idea and correct some logics and misconception here then it is better.. thanks
const CHAR_INFO *buffer;
CHAR_INFO buffer1;
buffer = &buffer1;
buffer1. Char. AsciiChar= '-';
buffer1.Attributes = 0x0001;
const SECURITY_ATTRIBUTES *securityAttribute;
HANDLE writeConsole= GetStdHandle(STD_OUTPUT_HANDLE);
HANDLE readConsole = GetStdHandle(STD_INPUT_HANDLE);
COORD buffer1Size={10,10};
COORD position = { 4,4};
SMALL_RECT display ={4,4,50,50};
WriteConsoleOutput(writeConsole,buffer,buffer1Size,position,&display);

Cannot implement meter in windows API

I am using the windows API (in C++) to create a windows application.
Now, I have a progress bar which I want to show like a meter. A meter is blue and has no animation. I cannot figure out how to implement this, and if I have to, I will just settle for the usual green progress bar.
Please help.
EDIT: At least, is it possible to disable the animation (highlight the slides across the filled section of the bar)?
EDIT2:
Here is the C++ solution if anyone else is having this problem:
PAINTSTRUCT ps;
HDC hDC = BeginPaint(hwnd,&ps);
RECT r;
HTHEME theme = OpenThemeData(hwnd,L"PROGRESS");
SetRect(&r,10,10,100,25);
DrawThemeBackground(theme,hDC,11,2,&r,NULL);
SetRect(&r,10,10,50,25);
DrawThemeBackground(theme,hDC,5,4,&r,NULL);
CloseThemeData(theme);
EndPaint(hwnd,&ps);
You can draw this style of progress bar with DrawThemeBackground(). You'll find the theme name, part and state numbers in my answer in this thread.
The built in control cannot do this... however, it's not like ProgressBar is a complicated control. If you want nothing but a blue rectangle, use DrawRect and draw a blue rectangle.

most simple type of graphic application in visual studio

Whats the most simple way (without much fancy stuff and no big setup overhead) to create a c++ project with visual studio where i can create some graphical debug output? (mainly drawing some lines, circles and triangles in a window. doesn't have to be performant or look pretty)
thanks!
The quickest way: create a new project, find or create the paint message handler (in Win32 it'll be in WndProc under "case WM_PAINT:", and in a WinForms (.net) project you'll override OnPaint), and add code to draw some stuff.
Well, for this I'll assume you would want to just use Gdi.
In a windows app, process the WM_PAINT message.
Here is an example that draws a rectangle:
case WM_PAINT:
{
HDC hDC;
PAINTSTRUCT ps;
hDC = BeginPaint(hwnd,&ps);
Rectangle(hDC,10,10,30,30);
EndPaint(hwnd,&ps);
}

Drawing in a Win32 Console on C++?

What is the best way to draw things in the Console Window on the Win 32 platform using C++?
I know that you can draw simple art using symbols but is there a way of doing something more complex like circles or even bitmaps?
Yes, it is possible.
Get the HWND of the console window using GetConsoleWindow and then draw in it.
#define _WIN32_WINNT 0x601
#include <windows.h>
#include <stdio.h>
int main() {
// Get window handle to console, and device context
HWND console_handle = GetConsoleWindow();
HDC device_context = GetDC(console_handle);
//Here's a 5 pixels wide RED line [from initial 0,0] to 300,300
HPEN pen = CreatePen(PS_SOLID, 5, RGB(255, 0, 0));
SelectObject(device_context, pen);
LineTo(device_context, 300, 300);
ReleaseDC(console_handle, device_context);
getchar();
return 0;
}
Note: GetConsoleWindow was introduced in Windows 2000. It's available when _WIN32_WINNT is set to 0x500 or greater.
No you can't just do that because Win32 console doesn't support those methods. You can however use GDI to draw on the console window.
This is a great example of drawing a bitmap on a console by creating a child window on it:
http://www.daniweb.com/code/snippet216431.html
And this tells you how to draw lines and circles:
http://www.daniweb.com/code/snippet216430.html
This isn't really drawing in the console though. This is sort of drawing "over" the console but it still does the trick pretty well.
It is possible, albeit totally undocumented, to create a console screen buffer that uses an HBITMAP that is shared between the console window process and the calling process. This is the approach that NTVDM takes to display graphics once a DOS application switches to graphics mode.
See it.
As Nick Brooks has pointed out, you can use GDI calls in console apps, but the graphics cannot appear in the same window as the text console I/O. This may not matter since you can draw text elements in GDI.
A simplified interface to GDI calls in console apps is provided by WinBGIm. It is a clone of Borland's DOS BGI API, but with extensions to handle resizable windows, mouse input, and 24bit colour models. Since it is available as source code, it also serves a good demonstration of using GDI in this way.
It is possible to either have both a console and the GDI window, or you can suppress the console window by specifying that the application is a GUI app (the -mwindows linker option in GNU toolchain) - note that specifying a GUI app really only suppresses the console, it is only really a GUI app if it has a message loop. Having the console is good for debugging, since it is where stdout and stderr are output to by default.
Not without usng ASCII art. Back in the days of DOS it was "fairly" easy to do by redesigning the character bitmaps. It might only be possible in windows by creating your own font, but im really not sure thats possible