How to start BGI window of c++ program in maximized mode? - c++

I am making a c++ project for my High School. I am using Dev c++ with graphics. What I want is when BGI window opens it should start in maximized mode instead of normal window.
following is my code but it doesn't works :(
#include<iostream>
#include<conio.h>
#include<graphics.h>
#include<windows.h>
using namespace std;
void loading() {
int x=170,i,gdriver=DETECT,gmode;
initgraph(&gdriver,&gmode,"");
settextstyle(DEFAULT_FONT,HORIZ_DIR,2);
outtextxy(170,180,"LOADING,PLEASE WAIT");
for(i=0;i<300;++i)
{
delay(30);
line(x,200,x,220);
x++;
}
getch();
}
main() {
ShowWindow( GetConsoleWindow(), SW_HIDE );
loading();
ShowWindow(FindWindow(NULL,"Windows BGI"),SW_MAXIMIZE);
}
console window gets hide according to my need but BGI window don't get Maximized. I am newbie to c++ so i don't know how to handle windows with c++. Please help with some useful code or solution.

I don't have an immediate answer, but I can suggest a direction.
You need to break this down to see where it is failing (an approach that helps with many different kinds of bugs).
Are you getting to the second "ShowWindow" line of code? You can check with a breakpoint on that line.
What is FindWindow returning? My guess would be NULL, but you can confirm that (such as by pulling it out to its own line:
HWND hwndBGI = FindWindow(NULL,"Windows BGI");
ShowWindow(hwndBGI,SW_MAXIMIZE);
Then you can check what FindWindow returns. If NULL, you know where to look for the problem; in the call to FindWindow.
If FindWindow fails, a call to GetLastError after the call to FindWindow may give you more information.
FindWindow does not always succeed. Potential problems could be an inaccurate window name, issues finding a window in a different process, a window which is not a top-level window....
Wishing you success!

Open a maximum window using getmaxwidth(), getmaxheight()
/* getmaxwidth and getmaxheight example */
#include <graphics.h>
int main(void)
{
/* Make a window, as big as possible */
initwindow(getmaxwidth( ), getmaxheight( ));
/* clean up */
getch();
closegraph();
return 0;
}

Related

My program doesn't put characters out on the screen

I have tried several things but none of them did work. Does someone know what the problem is? Here's my code:
#include <iostream>
#include <Windows.h>
#include <iomanip>
#include <fstream>
#include <stdio.h>
using namespace std;
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int CmdShow) {
cout << "Hello World" << endl;
return 0;
}
Thanks
If you are using visual studio, and create a Win32 application, it will not create a console so the output does not appear on any window. If you create a Win32 Console application, std::cout will be directed to the console window but you will need to use a standard main() program entry point.
To avoid creating a new project, modify your code as shown here:
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int CmdShow) {
AllocConsole();
AttachConsole(GetCurrentProcessId());
freopen("CONOUT$", "w", stdout);
cout << "Hello World" << endl;
return 0;
}
On Windows, there are two main types of programs:
Console applications for single textual input and output. These are typically started from the command line in a command prompt.
GUI applications which use windows, buttons, the mouse, touch, etc. These are typically started by choosing from the start menu or double-clicking on an icon.
(There are ways to have a single application work both ways, but that's almost certainly not what you're after.)
Your code is exhibiting indications of trying to be both. It has a wWinMain, which suggests it's a GUI application, but it does regular textual output using std::cout, which suggests it's a console application.
I think you want a console application, but you accidentally started by choosing a Win32 application in the Visual Studio New Project Wizard. To fix this without starting over:
First, get rid of the unnecessary includes, specifically, delete #include <windows.h>.
Next Change the wWinMain to a standard C++ main function, like this:
int main() {
cout << "Hello World" << endl;
return 0;
}
Finally, right-click on your project in the Solution Explorer, and choose Properties from the pop-up menu. At the top of the pop-up dialog, set Configuration to All Configurations. In the left side, expand Linker and choose System, then, on the right side, change the SubSystem field to Console (/SUBSYSTEM:CONSOLE). Click OK.
Now you should be able to rebuild your program and it'll work.
One word of warning: If you run it directly from Visual Studio, a new console window will appear and, in the blink of an eye, your program will complete and the new console window will disappear, which makes it hard to tell if you did the right thing.
If you start your program from a CMD prompt, you won't have that problem. If you want to run from the debugger, put a breakpoint on the return statement in your main function. That will halt the program in the debugger just before it ends, and you'll be able to see what's in the console window. Some people have the program ask for keyboard input right before it finishes, which gives the user a change to see what's in the console window before it vanishes.
It appears you have created a windows application rather than a console application.
A console application has a main function with signature:
int main(int argc, char ** argv);
A windows application has a main function with signature:
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int CmdShow);
The latter is intended for applications that actually create a window. You choose which to create using the wizard in Visual Studio when you go to create a new project (assuming you are using Visual Studio).
Use:
https://msdn.microsoft.com/en-us/library/ms235629.aspx
Also, it is possible your application is exiting before you see the output.
In this case, we can use a non-standard platform specific call to ::system("pause") to make it wait until you hit a key to continue.
#include <iostream>
#include <iomanip>
#include <fstream>
#include <windows.h>
using namespace std;
int main(int argc, char ** argv)
{
cout << "Hello World" << endl;
system("pause");
return 0;
}
Alternativly, place a break point on the line where it says return 0; and use F5 to debug.

Highlighting text in console makes window unresponsive [duplicate]

This question already has answers here:
How and why does QuickEdit mode in Command Prompt freeze applications?
(2 answers)
Closed 6 years ago.
for an application of mine I have been playing around with the Windows API a bit, namely creating a very small wrapper for window functionality. Since I like to have console output as well, I created a console via AllocConsole(). I then noticed that highlighting text in this console (like if you want to copy something) 'freezes' the open window, ie. no messages will be processed, it is not click- or closable. Message loop and wndProc are both standard.
Two questions: is that intended/documented behaviour (I couldn't find anything about it) and if yes, is there a way to disable it? It's kind of annoying.
Thanks in advance
EDIT: as requested, the console creation code:
FILE *conOut = NULL;
FILE *conIn = NULL;
if (::AllocConsole())
{
::freopen_s(&conIn, "CONOUT$", "r", stdin);
::freopen_s(&conOut, "CONOUT$", "w", stdout);
// ...
if (conOut != NULL)
::fclose(conOut);
if (conIn != NULL)
::fclose(conIn);
::FreeConsole();
}
I created a test Win32 application with a basic Win32 project. I added a simple class to handle the console creation and tested two scenarios. What I found was the console window output will stop as if the thread generating the output is suspended when an Edit->Mark is done until the Mark is completed with a Copy or canceled.
The two scenarios tested with the Win32 application were: (1) printing to console window in a separate thread and (2) printing to console window in the main window message handling logic.
The particulars of the test program and details of the two scenarios tested are as follows.
Console.h
#pragma once
#include <stdio.h>
class CConsole
{
public:
CConsole(void);
~CConsole(void);
int Create(void);
public:
FILE *m_conOut;
FILE *m_conIn;
};
Console.cpp
#include "StdAfx.h"
#include "Console.h"
CConsole::CConsole(void)
{
}
CConsole::~CConsole(void)
{
}
int CConsole::Create(void)
{
if (::AllocConsole())
{
::freopen_s(&m_conIn, "CONIN$", "r", stdin);
::freopen_s(&m_conOut, "CONOUT$", "w", stdout);
}
return 0;
}
In the main file at the near the top where the Win32 project wizard put some global variables, I added an additional global variable CConsole myConsole; for my console and then I added a bit further down a simple function that is the target of a _beginthreadex(). The function looks like:
unsigned __stdcall myThread( void *x )
{
HWND hWnd = (HWND)x;
// allow for two different test scenarios depending on whether the
// SendMessage() is commented out or the fprintf() is commented out.
// if SendMessage() is live then the main window will write to the console window
// if fprintf() is live then this thread will write to the console window.
for (int i = 0; i < 50; i++) {
// SendMessage (hWnd, WM_USER, i, 0); // send a message to main window to request print
fprintf (myConsole.m_conOut, "This is line %d\n", i); // print from this thread
Sleep (1000);
}
return 0;
}
In the InitInstance(HINSTANCE hInstance, int nCmdShow) just before the return statement, I added the following two lines of code:
myConsole.Create();
_beginthreadex (NULL, 0, myThread, hWnd, 0, NULL);
Finally in the main message loop that handles the messages for the main window I added an additional message target:
case WM_USER:
fprintf (myConsole.m_conOut, "This is line %d\n", wParam);
break;
I then tried two different experiments by commenting out one of the two lines in my function that is the target of the _beginthreadex().
One was to print to the console window using fprintf() within that thread. The second test case was to send a message of WM_USER to the main window and ask it to use fprintf() to print to the console window.
What I found was that with the printing being done by the thread then I observed the following behavior when I used the Edit->Mark to begin the procedure of marking text to copy:
the main window was responsive to menu choices
the console window output stopped
when I cleared the mark or copied text, console window output resumed
The behavior was as if the thread writing to the console window was suspended until the Mark and Copy procedure was completed.
When the printing was done by the main window's message loop when handling the WM_USER message then I observed the following behavior when I used the Edit->Mark to begin the procedure of marking text to copy:
the main window was unresponsive to menu choices
the console window output stopped
when I cleared the mark or copied text, main window responsiveness returned as did console output
For some additional information about the Console Window Subsystem see Consoles. For a bit of information about the technology see WinEventProc Callback Function along with SetWinEventHook which describes this functionality to some extent as well as What Are WinEvents? and In-Context Hook Function Precautions.
See also Console Window Host in the book Windows Internals for a brief overview of the Console Window Subsystem.
And see Windows 7 / Windows Server 2008 R2: Console Host for an introduction to the architecture changes.
Finally The Console Host Process in Windows 7 from the book Inside Windows Debugging shows how to "discover the various layers involved in the printf sequence".
It may be possible to use the Console functions at a lower level to directly interface with the Console Window Subsystem in order to prevent the freezing of the thread which is doing I/O to the console window.

Handling drag and drop files in a running Windows console application

First, to clarify, I am not asking how to drag-and-drop a file onto an exe's icon. I want to know how to handle drag and drop onto an already running win32 console application. I'm also not asking how to handle drag and drop inside of WinMain based applications through the Windows message pump. I want to do this inside of a program with the entry point int main() that doesn't have a WndProc (yet) or anything.
That said, I'm wondering if my goal is achievable (and hoping that it is).
I have a server application that is running within a console window. Due to a large codebase and a lot of weird coupling, it is an 'output only' console for all intensive purposes. Within it though, I can still handle things like key presses, as I have an update loop ticking. I'd like to be able to drag and drop files full of commands (which use a custom syntax) onto my running application and have it process them.
Is this possible to do? I was thinking that potentially I could get a pointer to the HWND of the console (which hopefully is a thing?), and then maybe subclass that window to use a custom WndProc to listen for the WM_DROPFILES message.
I've never really tried to set up handling of windows messages in an int main() program instead of a WinMain program, but I'm hoping it's somehow possible.
Any help would be greatly appreciated!
Weird solutions are fine.
AFAIK, a console window does not support drag&drop by default. You can always create your own separate popup window with its own message loop so the user has something to drag items onto.
To use drag&drop on the console window itself, try using GetConsoleWindow() to get the console HWND, then either:
subclass the HWND using SetWindowLong/Ptr() or SetWindowSubClass(), then register the HWND using DragAcceptFiles() to start receiving WM_DROPFILES messages. Be sure to call DragAcceptFiles() again to stop receiving the messages and then unhook your subclass before exiting the app.
implement the IDropTarget interface and then register the HWND using RegisterDragDrop() to start receiving notifications. Be sure to call RevokeDragDrop() before exiting the app.
WM_DROPFILES is easier to code for, but IDropTarget is more flexible as it handles virtual items as well as physical files.
#include <vector>
#include <string>
#include <iostream>
#include <conio.h>
int main()
{
std::cout << "Please drop files and press [Enter] when done ...\n";
std::vector< std::string > files;
for( int ch = _getch(); ch != '\r'; ch = _getch() ) {
std::string file_name;
if( ch == '\"' ) { // path containing spaces. read til next '"' ...
while( ( ch = _getch() ) != '\"' )
file_name += ch;
} else { // path not containing spaces. read as long as chars are coming rapidly.
file_name += ch;
while( _kbhit() )
file_name += _getch();
}
files.push_back( file_name );
}
std::cout << "You dropped these files:\n";
for( auto & i : files )
std::cout << i << '\n';
}

Holding scroll-bar gets command prompt to pause in Windows

I have a program where I record data through an ADC system from National Instruments (NI).
The device buffers information for some time, and then the program collects the buffer data at some point. If the program collects data larger than the buffer, then the buffer would have to free without my program receiving the data, which will cause the NI library to throw an exception saying that requested data isn't available anymore, since it was lost.
Since my program is a command-prompt program, if the user clicks and holds the scrollbar, the program pauses, which could get this problem to happen.
How can I get over this problem without increasing the buffer size? Can I disable this holding thing in Windows?
Thanks.
Only the thread that is attempting to output to the console is blocked. Make this a separate thread, and your problem goes away.
Of course, you'll need to buffer up your output, and do something sensible if the buffer overflows.
For reference, here's the simple code I used to test this, you will note that the counter continues to increase even when the scroll bar is held down:
#include <Windows.h>
#include <stdio.h>
volatile int n = 0;
DWORD WINAPI my_thread(LPVOID parameter)
{
for (;;)
{
n = n + 1;
Sleep(800);
}
}
int main(int argc, char ** argv)
{
if (!CreateThread(NULL, 0, my_thread, NULL, 0, NULL))
{
printf("Error %u from CreateThread\n", GetLastError());
return 0;
}
for (;;)
{
printf("Hello! We're at %u\n", n);
Sleep(1000);
}
return 0;
}
Whilst there may be ways to bypass each individual problem you can possibly conceive with the output [including for example running it over a network on a sometimes slow output link, or some such], I think the correct thing to do is to disconnect your output from your collecting of data. It shouldn't be hard to do this by adding a separate thread that collects the data, and having the main thread display to the command prompt window. That way, not matter which variation of "output is blocked" Windows throws at you, it will work - at least until you run out of RAM, but tat that point it's YOUR program's decision to do something [e.g. throw away some data or some such].
This is generally how the problem "I need to collect something, and I also need to allow users to view the data, but I don't want the two to interfere with each other" is solved.
First use the GetConsoleWindow winapi function and get the HWND of your console.
now i suggest two ways to do this,
Method I
Subclass the window by creating your own WindowProcedure. (get help from here)
Now that you have subclassed it, you can intercept the WM_VSCROLL and WM_HSCROLL messages and do your own remedy to your code.
Method II
Change the size of the window using some function like SetWindowPos so that the scroll bars are not needed.
or Change the size of the console screen buffer so that the scroll bars are not needed.
Method I has lot of control over the application, but its a little bit complex than the method II which is very simple.
If you want to forbid the user from resizing the console window, just remove the WS_THICKFRAME from the WindowStyle of the console window.
I was in a similar situation and found that this kind of blocking behaviour could be caused by the quick edit "feature" of the command prompt. This question explains about it and the answer shows how to disable it. Hope that helps, even after some years :)

SDL does not show its window if I use a logging library

I'm trying to use log4cplus in conjunction with SDL to make a little graphic application.
I'm using minGW and Eclipse CDT on windows.
My problem is that whenever I use the library, my SDL window is not shown.
Instead I get this on the console [New Thread 2624.0x1270] and that is it. No error message, no compilation/linking problem, nothing (see edit for precisions).
If I don't use the library, a similar message appears on the console and then disappears, and my SDL window is shown properly.
Below is an example of this behavior. If I comment the two lines starting with "Logger ", then everything is fine. If I do not, SDL window is not shown.
Edit: I've tried using just the logging library and commenting all the other code but this fails as well somehow. I cannot put a breakpoint on the logger code, eclipse tells me: Breakpoint attribute problem: installation failed and the code don't seem to be executed.
*Edit2:*I was on the wrong track, see my post below. Problem kind of solved.
Any Idea?
#include <stdlib.h>
#include <SDL/SDL.h>
#include <SDL/SDL_endian.h> /* Used for the endian-dependent 24 bpp mode */
#include "Screen.h"
#include <log4cplus/logger.h>
#include <iomanip>
using namespace log4cplus;
int main(int argc, char **argv) {
if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) {
fprintf(stderr, "Impossible d'initialiser SDL: %s\n", SDL_GetError());
exit(1);
}
SDL_Surface *screen;
screen = SDL_SetVideoMode(640, 480, 32, SDL_SWSURFACE);
if ( screen == NULL ) {
fprintf(stderr, "Impossible de passer en 640x480 en 16 bpp: %s\n", SDL_GetError());
exit(1);
}
Logger root = Logger::getRoot();
Logger log_1 = Logger::getInstance(LOG4CPLUS_TEXT("test.log_1"));
while(true)
{
SDL_Event event;
SDL_WaitEvent(&event);
switch (event.type) {
case SDL_KEYDOWN:
printf("La touche %s a été préssée!\n",
SDL_GetKeyName(event.key.keysym.sym));
//SDL_Quit();
break;
case SDL_QUIT:
exit(0);
}
Screen::DrawPixel(screen,20,20,200,10,10);
}
}
I have no experience with log4cplus, but I do know that you should be aware that SDL does some obnoxious rewiring of stdout and stderr.
I was going to say that you should move your Logger setup to after your SDL_Init call, but I just noticed that you don't even have one. Try calling SDL_Init before setting up your display.
I found the problem. I hadn't noticed the error gdb gave me when running the program: "
gdb: unknown target exception 0xc0000135". In fact the program didn't start at all.
This means it could not load a dll because of some path problems. I tried putting the dll I use for log4cplus in the system path, tried other workarounds like starting eclipse from but to no avail. One way I found to make it work is simply to put the dll in the Debug folder.
The problem with this gdb error is quite widespread (see google). This is not a proper fix, but I will live with it for the time being, so I consider the problem solved.