Console in C++ application - c++

I want to implement a console inside my C++ application. Like ftp for example. Or (IIRC) sql, once you've connected to a Server.
Does anybody know a library which implements this? Ideally with auto-completion and such? My searches for this only come up with "how to build a C++ console application", which I do know how to do.

GNU Readline implements the features you want. If filename auto-completion is not the sort you need, use a custom auto-complete routine.

For Windows: Use AllocConsole() to attach a text console to your GUI app and freopen( "CON", "w", stdout ) ; to redirect and printf() to output text.
http://msdn.microsoft.com/en-us/library/windows/desktop/ms681944(v=vs.85).aspx
Sample code:
#include <stdio.h>
#include <stdlib.h>
// Function prototypes.
LRESULT CALLBACK WndProc( HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam );
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLine, int iCmdShow );
// In a C++ Windows app, the starting point is WinMain().
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLine, int iCmdShow )
{
// these next few lines create and attach a console
// to this process. note that each process is only allowed one console.
AllocConsole() ;
freopen( "CON", "w", stdout ) ;
printf("HELLO!!! I AM THE CONSOLE!\n" ) ;
WNDCLASSEX wc = { 0 };
wc.cbSize = sizeof( WNDCLASSEX ) ;
wc.cbClsExtra = 0; // ignore for now
wc.cbWndExtra = 0; // ignore for now
wc.hbrBackground = (HBRUSH)GetStockObject( WHITE_BRUSH );
wc.hCursor = LoadCursor( NULL, IDC_ARROW );
wc.hIcon = LoadIcon( NULL, IDI_APPLICATION );
wc.hInstance = hInstance;
wc.lpfnWndProc = WndProc;
wc.lpszClassName = TEXT(" ");
wc.lpszMenuName = 0;
wc.style = CS_HREDRAW | CS_VREDRAW; // Redraw the window
RegisterClassEx( &wc );
HWND hwnd = CreateWindowEx( 0, TEXT(" "), TEXT("window's title!"), WS_OVERLAPPEDWINDOW, 10, 10, 200, 200, NULL, NULL, hInstance, NULL );
ShowWindow(hwnd, iCmdShow );
UpdateWindow(hwnd);
MSG msg;
while( GetMessage( &msg, NULL, 0, 0 ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
return msg.wParam; // return from WinMain
}
LRESULT CALLBACK WndProc( HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam )
{
switch( message )
{
case WM_CREATE:
// upon creation, let the speaker beep at 50Hz, for 10ms.
Beep( 50, 10 );
printf("HELLO!!! I AM THE CONSOLE!\n" ) ;
return 0;
break;
case WM_PAINT:
{
// we would place our Windows painting code here.
HDC hdc;
PAINTSTRUCT ps;
hdc = BeginPaint( hwnd, &ps );
// draw a circle and a 2 squares
Ellipse( hdc, 20, 20, 160, 160 );
Rectangle( hdc, 50, 50, 90, 90 );
Rectangle( hdc, 100, 50, 140, 90 );
printf("HELLO!!! I AM THE CONSOLE!\n" ) ;
EndPaint( hwnd, &ps );
}
return 0;
break;
case WM_LBUTTONDOWN:
printf("STOP POKING MEEE!!!\n") ;
break;
case WM_DESTROY:
PostQuitMessage( 0 ) ;
return 0;
break;
}
return DefWindowProc( hwnd, message, wparam, lparam );
}

If you want also autocomplete you could
check the example of linenoise (a lightweight readline alternative).
Basically you have to parse the Userinput Line in a Loop.
Example for a very basic CommadLineInterface :
show prompt and read input in a while loop,
call something like parseLine() on \n
split the Line in Tokens by at least Space (then ;) take the first String as Command cmd and the rest as args.
call dispatch(cmd, args);

Related

WinApi and C++ - status bar does not update

My status bar does not refresh during the program execution and I don't know why. First the pseudo-code. I have deleted most of it, leaving only the idea.
#include ... (many includes)
using namespace std;
#include "MyHeaderFile.hpp"
LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam);
//here some global variables. Thereare more of them, I leave only teh important ones.
HWND g_hButtonStart;
MSG msg;
//----------------------------------- windows ------------------------------------------------------
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{ WNDCLASSEX wc;
HWND hwnd;
memset(&wc,0,sizeof(wc));
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = 0;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = CreateSolidBrush(RGB(240,240,240));//(HBRUSH)(COLOR_WINDOW+1);
wc.lpszMenuName = NULL;
wc.lpszClassName = "WindowClass";
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
//window class register
if(!RegisterClassEx(&wc))
{ MessageBox(NULL, "Rejestracja klasy okna nie powiodła się!","BMP->DXF: Błąd!",MB_ICONEXCLAMATION|MB_OK);
return 0;
}
hwnd = CreateWindowEx(WS_EX_WINDOWEDGE,"WindowClass","BMP -> DXF",WS_VISIBLE|WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
500,
275,
NULL,NULL,hInstance,NULL);
if(hwnd == NULL)
{ MessageBox(NULL, "Window Creation Failed!","Error!",MB_ICONEXCLAMATION|MB_OK);
return 0;
}
//group boxes, text boxes, buttons ...
//most important are the "START" button and the status bar:
g_hButtonStart = CreateWindowEx( 0, "BUTTON", "S T R T", WS_CHILD | WS_VISIBLE, 243, 133, 100, 30, hwnd, NULL, hInstance, NULL );
ShowWindow( hwnd, nCmdShow );
UpdateWindow( hwnd );
//status bar things
INITCOMMONCONTROLSEX icmc;
icmc.dwSize = sizeof( INITCOMMONCONTROLSEX );
icmc.dwICC = ICC_BAR_CLASSES;
InitCommonControlsEx( & icmc );
g_hStatusBar = CreateWindowEx( 0, STATUSCLASSNAME, NULL, SBARS_SIZEGRIP | WS_CHILD | WS_VISIBLE, 0, 0, 0, 0, hwnd,( HMENU ) 200, hInstance, NULL );
SendMessage( g_hStatusBar, SB_SETTEXT, 0,( LPARAM ) "some info" );
//status bar - end
while(GetMessage(&msg, NULL, 0, 0))
{ if (!IsDialogMessage(hwnd, &msg))
{TranslateMessage(&msg);
DispatchMessage(&msg); }
}
return msg.wParam;
}
//messages
LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
{ bool ParameterWarning=false;
string Info;
switch(Message)
{ case WM_CLOSE:
{ DestroyWindow( hwnd );
}
break;
case WM_DESTROY:
{ PostQuitMessage(0);
break;
}
//here is the most important part of the code
case WM_COMMAND:
{ if(( HWND ) lParam == g_hButtonStart )
{ //enabling and disabling some buttons, edit boxes etc.
//some variables declarations and initializations...
SendMessage( g_hStatusBar, SB_SETTEXT, 0,( LPARAM ) "message 1" );
//opening the in file ...
//reading file parameters and checking for errors ...
SendMessage( g_hStatusBar, SB_SETTEXT, 0,( LPARAM ) "message 2" );
//here some large calculations start, lasting for 30mins, for example; written in C++
for(int N=0;N<one_of_the_variables;N++)
{
//calculations part 1; also writing to out file ...
SendMessage( g_hStatusBar, SB_SETTEXT, 0,( LPARAM ) "message 3" );
//calculations part 2; also writing to out file ...
SendMessage( g_hStatusBar, SB_SETTEXT, 0,( LPARAM ) "message 4" );
//calculations part 3; also writing to out file ...
SendMessage( g_hStatusBar, SB_SETTEXT, 0,( LPARAM ) "message 5" );
}
//enabling and disabling some buttons, edit boxes etc. ...
//closing the out file ...
}
default:
return DefWindowProc(hwnd, Message, wParam, lParam);
}
return 0;
}
During the calculations, my main window displays "(Not Responding)" in the title. It doesn't bother me (yet). The status bar shows only some of the messages - it seems to be random. Sometimes only the last message, sometimes two or three of them. But it never shows them all correctly during the whole calculation. What should I do to make it work?
The not responding is another symptom of the problem. A GUI app needs to process its message queue frequently. It is this act of pumping the message queue that allows the UI to update. Your long running tasks stops the message queue from being pumped and leads to the various problems that you report.
The solution is to pump the message queue frequently. Don't perform long running tasks in the main thread because that stops you being able to service the message queue. Move these tasks into a separate thread.

C++ Win32 Background Image

I have looked at some background drawing tutorials but I still can't draw my background; it's always white. My resources are already in the project. I have tried a few other ways by using paint instead but it still would not draw the background image.
#include <windows.h>
#include <commctrl.h>
#include "resource.h"
HINSTANCE hInst;
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
HWND hProgress, hWndBottom;
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
hInst = hInstance;
MSG msg = {0};
WNDCLASS wc = {0};
wc.lpfnWndProc = WndProc;
wc.hInstance = hInstance;
wc.hbrBackground = CreatePatternBrush( LoadBitmap( hInstance, MAKEINTRESOURCE(IDB_BG) ));//(HBRUSH)(COLOR_BACKGROUND);
wc.lpszClassName = "Test";
if( !RegisterClass(&wc) )
return 1;
if( !CreateWindow(wc.lpszClassName,
"Tests",
WS_POPUPWINDOW|WS_VISIBLE, //WS_OVERLAPPEDWINDOW|WS_VISIBLE
1,1,200,250,0,0,hInstance,NULL))
return 2;
while( GetMessage( &msg, NULL, 0, 0 ) > 0 )
DispatchMessage( &msg );
return 0;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
//Make TopMost
::SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
INITCOMMONCONTROLSEX InitCtrlEx;
InitCtrlEx.dwSize = sizeof(INITCOMMONCONTROLSEX);
InitCtrlEx.dwICC = ICC_PROGRESS_CLASS;
SendMessage(hProgress, PBM_SETRANGE, 0, MAKELPARAM(0, 100));
switch(message)
{
case WM_CREATE:
{
hProgress = CreateWindowEx(0, PROGRESS_CLASS, NULL,
WS_CHILD | WS_VISIBLE | PBS_SMOOTH,
10, 190, 170, 10,
hWnd, NULL, hInst, NULL);
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
If you're going to draw a bitmap for your background, you do not just set the background brush to the handle of your bitmap.
Instead, you set the background brush to NULL, and handle the WM_ERASEBKGND message. You respond to it by drawing your bitmap (e.g., with BitBlt or StretchBlt), then you return TRUE (or any other non-zero value) to tell DefWindowProc that the background has been erased, so it shouldn't try to erase it.
Note that if you're doing this in an MDI program, you need to do this in the MDI client window. With MDI, you have a parent window, a client window, and some number of MDI child windows. What looks like the background of the main window is really occupied by the MDI client window, so that's where you need to draw in your background.

Trying to learn winapi. made a first program which has to show me a window. CMD shows but there is no window

#include<windows.h>
LPSTR NazwaKlasy = "Klasa Okienka";
MSG Komunikat;
LRESULT CALLBACK WndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam );
int WINAPI WinMain( HINSTANCE hInstance,HINSTANCE hPrevInstance, LPSTR lpCmdLine,int nShowCmd)
{
WNDCLASSEX wc;
wc.cbSize = sizeof( WNDCLASSEX );
wc.style = 0;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon( NULL, IDI_APPLICATION );
wc.hCursor = LoadCursor( NULL, IDC_ARROW );
wc.hbrBackground =( HBRUSH )( COLOR_WINDOW + 1 );
wc.lpszMenuName = NULL;
wc.lpszClassName = NazwaKlasy;
wc.hIconSm = LoadIcon( NULL, IDI_APPLICATION );
//tutaj kłądż okienka
HWND hwnd;
hwnd = CreateWindowEx ( WS_EX_CLIENTEDGE,NazwaKlasy,"Okienko",WS_EX_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,400,400,NULL,NULL,hInstance,NULL);
//koniec obszaru okienek
ShowWindow( hwnd, nShowCmd ); // Pokaż okienko...
UpdateWindow( hwnd );
while( GetMessage( & Komunikat, NULL, 0, 0 ) )
{
TranslateMessage( & Komunikat );
DispatchMessage( & Komunikat );
}
return Komunikat.wParam;
}
LRESULT CALLBACK WndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
switch( msg )
{
case WM_CLOSE:
DestroyWindow( hwnd );
break;
case WM_DESTROY:
PostQuitMessage( 0 );
break;
default:
return DefWindowProc( hwnd, msg, wParam, lParam );
}
return 0;
}
the editor shows no errors and runs the program without any problems but there are no signs of the window
im not very experienced at programming so its most probably a stupid error which i cant just find but everyone has to start somewhere
i think i formated the post correctly
You're not registering the window class. You fill out the WNDCLASSEX structure ok, but you neglect to call RegisterClassEx to actually register it.

Adding child window to Metatrader4's chart via DLL - blinking (not redrawing)

I would like to add a child window to Metatrader4's chart window which always stays on top, without blinking, just statically there all the time upon eveything (in parent window). I am doing this from a DLL (C++).
I call this method from the mql side:
MT4_EXPFUNC int __stdcall testWindow(HWND hwnd) {
prnt_hWnd = hwnd;
CreateThread(0, NULL, ThreadProc, (LPVOID)L"Window Title", NULL, NULL);
return 0;
}
The parent window's (chart) handle is given as a parameter.
DWORD WINAPI ThreadProc( LPVOID lpParam )
{
MSG messages;
/*
... in createWindowClass:
WNDCLASSEX wc;
wc.hInstance = GetModuleHandle(NULL);
wc.lpszClassName = (LPCWSTR)L"MyClass";
wc.lpszClassName = (LPCWSTR)szClassName;
wc.lpfnWndProc = DLLWindowProc;
wc.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
...
*/
CreateWindowClass(L"MyClass");
HWND hwnd = CreateWindowEx (0, L"MyClass", NULL, WS_VISIBLE | WS_CHILD , CW_USEDEFAULT, CW_USEDEFAULT, 400, 300, prnt_hWnd, NULL, GetModuleHandle(NULL), NULL );
ShowWindow (hwnd, SW_SHOWNORMAL);
while (GetMessage (&messages, NULL, 0, 0))
{
TranslateMessage(&messages);
DispatchMessage(&messages);
}
return 1;
}
I handle window's messages this way:
LRESULT CALLBACK DLLWindowProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message) {
case WM_PAINT: {
PAINTSTRUCT ps;
BeginPaint( hwnd, &ps );
EndPaint( hwnd, &ps );
return 0;
}
case WM_COMMAND:
/* */
break;
case WM_DESTROY:
PostQuitMessage (0);
break;
default:
return DefWindowProc (hwnd, message, wParam, lParam);
}
return 0;
}
My child window at the begining appears, then after (I guess) the parent window is getting being redrawn, suddenly it disappears, then it is just blinking (fastly appears-disappear).
My goal is to have a child window on that chart statically, so always topmost, without blinking. I could achieve this only without the WS_CHILD property. But then my child window is not ON the parent.
Try adding the WS_CLIPCHILDREN style to the chart window. I would pass the handle on the MQL4 side in init() via some MT4 export function. For example, SetChartWnd( HWND hChartWnd ) and passing WindowHandle( Symbol(), Period() ) as the parameter.
Then inside that function, I would try doing something like the following:
if ( ::IsWindow( hChartWnd ) ) {
DWORD style = GetWindowLong( hChartWnd, GWL_STYLE );
style |= WS_CLIPCHILDREN;
SetWindowLong( hChartWnd, GWL_STYLE, style );
}
}

Visual studio "cannot find the path specified" error

I am having a problem creating a simple window in C++ visual studio. I started a new "empty project" and only created one .cpp file. When I try to run the program, I get this error:
Unable to start program C:\...\Project1.exe. The system cannot find the file specified.
Why does this happen? I'm using visual studio 2010.
Here is my code:
#include <windows.h>
// Function prototypes.
LRESULT CALLBACK WndProc( HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam );
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLine, int iCmdShow );
int WINAPI WinMain( HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR szCmdLine,
int iCmdShow )
#pragma region part 1 - STARTUP STUFF
WNDCLASS wc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hbrBackground = (HBRUSH)GetStockObject( WHITE_BRUSH );
wc.hCursor = LoadCursor( NULL, IDC_ARROW );
wc.hIcon = LoadIcon( NULL, IDI_APPLICATION );
wc.hInstance = hInstance;
wc.lpfnWndProc = WndProc;
wc.lpszClassName = TEXT("Philip");
wc.lpszMenuName = 0; // no menu - ignore
wc.style = CS_HREDRAW | CS_VREDRAW; // Redraw the window
RegisterClass( &wc );
HWND hwnd = CreateWindow(
TEXT("Philip"),
TEXT("window's title!"),// appears in title of window
WS_OVERLAPPEDWINDOW,
10, 10,
200, 200,
NULL, NULL,
hInstance, NULL );
ShowWindow(hwnd, iCmdShow );
UpdateWindow(hwnd);
#pragma endregion
#pragma region part 2 - ENTER A LOOP TO CONTINUALLY KEEP CHECKING WITH WIN O/S FOR USER INTERACTION
MSG msg;
while( GetMessage( &msg, NULL, 0, 0 ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
#pragma endregion
return msg.wParam; // return from WinMain
}
LRESULT CALLBACK WndProc( HWND hwnd, // "handle" to the window that this message is for
UINT message, // TYPE of message (e.g. WM_PAINT is a message asking to paint the window)
WPARAM wparam, // information about the actual message
LPARAM lparam ) // MORE info about the message
{
switch( message )
{
case WM_CREATE:
// upon creation, let the speaker beep at 50Hz, for 10ms.
Beep( 50, 10 );
return 0;
break;
case WM_PAINT:
{
HDC hdc;
PAINTSTRUCT ps;
hdc = BeginPaint( hwnd, &ps );
// draw a circle and a 2 squares
Ellipse( hdc, 20, 20, 160, 160 );
Rectangle( hdc, 50, 50, 90, 90 );
Rectangle( hdc, 100, 50, 140, 90 );
EndPaint( hwnd, &ps );
}
return 0;
break;
case WM_DESTROY:
PostQuitMessage( 0 ) ;
return 0;
break;
}
return DefWindowProc( hwnd, message, wparam, lparam );
}
If you want to create a window then your kind of project is Windows Form Application (see picture above).
The solutions are an abstract concept to get together several projects. For example you could want to have a Windows Form Application using the features of a Class Library.