How to display cmd prompt after printing output to cmd.exe? - c++

I have an winmain application that is executed from cmd.exe and prints output to it. I atach to the cmd.exe using AttachConsole(ATTACH_PARENT_PROCESS). After application is executed and output is printed to cmd.exe command line prompt is not displayed and it looks like application is stil running(while it is already closed). Before closing my application I release the console using FreeConsole().
#include <iostream>
#include <fstream>
#include <windows.h>
int wWinMain
(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPWSTR lpCmdLine,
int nCmdShow
)
{
AttachConsole(ATTACH_PARENT_PROCESS);
std::wofstream console_out("CONOUT$");
std::wcout.rdbuf(console_out.rdbuf());
std::wcout << L"\nSome Output" << std::endl;
FreeConsole();
return 0;
}
Current result:
My goal:
How should I make prompt C:New folder> appear after myapp.exe has printed its output and is closed.

In case the question has not been answered yet (after such a long time), it is required to simulate the actual pressing of the 'Enter' key in the console window by sending (or, preferably, posting) the corresponding WM_KEYDOWN message to the console window, i.e.
after
std::wcout << L"\nSome Output" << std::endl;
and before calling
FreeConsole(),
insert the following:
HWND hWndCon_ = ::GetConsoleWindow();
if( hWndCon_ ) {
::PostMessage( hWndCon_, WM_KEYDOWN, VK_RETURN, 0 );
}
or simply
::PostMessage( ::GetConsoleWindow(), WM_KEYDOWN, VK_RETURN, 0 );

Related

How can I know which process is using the keyboard to input in windows 10?

How can I know which process is using the keyboard to input in windows 10 ?
To obtain a window handle to to the foreground window (which is the window on which the user is currently working, and to which the operating system sends all keyboard input), you can use the function GetForegroundWindow.
To get the process ID of the thread that created that window, you can use the function GetWindowThreadProcessId.
The following console program will print, in intervals of 5 seconds, the value of the handle of the foreground window, and the Thread and Process ID that created that window.
#include <windows.h>
#include <stdio.h>
int main( void )
{
HWND hWnd;
DWORD dwTID, dwPID;
while ( 1 )
{
hWnd = GetForegroundWindow();
dwTID = GetWindowThreadProcessId( hWnd, &dwPID );
printf(
"Handle of current foreground window: %p\n"
"That window was created by:\n"
"Thread ID: %u\n"
"Process ID: %u\n",
hWnd, dwTID, dwPID
);
fflush( stdout );
Sleep( 5000 );
printf( "\n" );
}
}

Output LRESULT to console

I'm trying to output text from Notepad window to console and it's always 0.
What I'm doing wrong?
int main()
{
HWND hwnd = (HWND)0x0031019C; // Window Handler of Notepad
char szBuf[4096];
HWND hwndEdit;
LRESULT result;
hwndEdit = FindWindowEx(hwnd, NULL, L"Edit", NULL); // Class for edit box
result = SendMessage(hwndEdit, WM_GETTEXT, sizeof(szBuf) / sizeof(szBuf[0]), (LPARAM)szBuf);
cout<<"Contents: \n"<<result;
cin.get();
return 0;
}
I tried print_f, but it outputs unreadable characters:
printf( "Contents: %s\n", result, szBuf );
It looks to me like you probably have a little bit of a mismatch happening.
Based on the L"Edit", you seem to be doing a Unicode build (otherwise, you'd get an error message about not being able to convert an wchar_t const[5] to LPCSTR, and the code wouldn't compile.
If you do a Unicode build, however, WM_GETTEXT is going to write Unicode data to your buffer, so you need to prepare for and use Unicode instead of narrow characters for your buffer.
For convenience, I've modified it a little to find Notepad instead of using a hard-coded Window handle.
#include <windows.h>
#include <stdio.h>
#define elements(b) (sizeof(b)/sizeof(b[0]))
int main() {
HWND hwnd; // Window Handler of Notepad
wchar_t buf[4096]={0};
HWND hwndEdit;
LRESULT result;
hwnd=FindWindowEx(NULL, NULL, L"Notepad", NULL);
hwndEdit=FindWindowEx(hwnd, NULL, L"Edit", NULL); // Class for edit box
result = SendMessage(hwndEdit, WM_GETTEXT, elements(buf), (LPARAM)buf);
printf("%S", buf);
return 0;
}
I built with:
cl /DUNICODE whatever.cpp user32.lib
Then I did a quick test that printed out exactly the text I'd typed into Notepad. To verify the result, I then edited the text in notepad, ran it again, and it printed out the modified text.

How can I prevent my program from closing when a open console window is closed?

I am trying to open the console from my main program (Win32). I found some code, and it works, but I don't understand it. The problem I'm happening is that when I click X on the console, it closes the program as well.
Roughly I have this:
int APIENTRY WinMain (HINSTANCE hThisInstance, HINSTANCE hPrevInstance, LPSTR lpszArgument, int nFunsterStil) {
// create the main program window, classes registered, etc...
hwnd = CreateWindowEx(0, csClassName, "theNewTimer", WS_POPUP | WS_CLIPCHILDREN, 300, 0, WINDOW_WIDTH, WINDOW_HEIGHT, HWND_DESKTOP, NULL, hThisInstance, NULL);
ShowWindow (hwnd, nFunsterStil);
// and now the console
AllocConsole();
HANDLE handle_out = GetStdHandle(STD_OUTPUT_HANDLE);
int hCrt = _open_osfhandle((long) handle_out, _O_TEXT);
FILE* hf_out = _fdopen(hCrt, "w");
setvbuf(hf_out, NULL, _IONBF, 1);
*stdout = *hf_out;
HANDLE handle_in = GetStdHandle(STD_INPUT_HANDLE);
hCrt = _open_osfhandle((long) handle_in, _O_TEXT);
FILE* hf_in = _fdopen(hCrt, "r");
setvbuf(hf_in, NULL, _IONBF, 128);
*stdin = *hf_in;
// and then the message loop concluding
I googled some of it, but had no idea of what I was reading.
One thing you can do is disable the close button on the console window:
HWND hwnd = ::GetConsoleWindow();
if (hwnd != NULL)
{
HMENU hMenu = ::GetSystemMenu(hwnd, FALSE);
if (hMenu != NULL) DeleteMenu(hMenu, SC_CLOSE, MF_BYCOMMAND);
}
I do not think this is possible. From the MSDN documentation for a HandlerRoutine, there's this sentence.
The CTRL_CLOSE_EVENT, CTRL_LOGOFF_EVENT, and CTRL_SHUTDOWN_EVENT signals give the process an opportunity to clean up before termination.
I read this as saying that CTRL_CLOSE_EVENT is advisory, and that the process is going to exit regardless. My guess is that when the system sends CTRL_CLOSE_EVENT, it starts a timer. The process is allowed to keep running for a little bit of time, but eventually, the OS will just kill the process unilaterally.
Here's the handler that I registered
BOOL WINAPI ConsoleCtrlHandler(DWORD dwCtrlType) {
switch (dwCtrlType) {
case CTRL_C_EVENT:
case CTRL_CLOSE_EVENT:
return TRUE; // breakpoint set here
default:
return FALSE;
}
}
Here's how I registered the handler, after my call to AllocConsole:
BOOL result = SetConsoleCtrlHandler(ConsoleCtrlHandler, TRUE /* Add */);
assert(result);
I set a breakpoint on the line marked //breakpoint set here. Then, I ran the process under the Visual Studio debugger. When the console window was focused, I pressed Ctrl+C. My breakpoint got hit, and I was able to step through my handler and back into KernelBase.dll!CtrlRoutine and so on. The process kept running when I let the process resume normal execution.
However, when I closed the console window, my handler did get called, but I was unable to trace its execution very far. I was able to single step execution a few times, but then the process simply exited. Visual Studio reported "The program '[10644] Win32Project.exe' has exited with code -1073741510 (0xc000013a)."
0xc000013a is STATUS_CONTROL_C_EXIT:
c:\Tools\ERR>Err.exe 0xc000013a
# for hex 0xc000013a / decimal -1073741510 :
STATUS_CONTROL_C_EXIT ntstatus.h
# {Application Exit by CTRL+C}
# The application terminated as a result of a CTRL+C.
# 1 matches found for "0xc000013a"

Is any application have HWND?

I'm learning C++. I wonder is any C++ application have HWND. Example bellow app, with no window created.
If it have, how I can get its HWND? Thank you very much!
#include <windows.h>
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLine, int iCmdShow )
{
MSG msg;
while( GetMessage( &msg, NULL, 0, 0 ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
}
"I'm learning C++. I wonder is any C++ application have HWND."
The shortest answer is no. HWND is a defined type in a library used to write Windows applications. C++ is a language that can be used to do that as long as you have library that gives you functions (including HWND type.)
You can write programs for CMD prompt or for Unix which have nothing to do with Windows.
Try this C style program. Copy text below to a.cpp file, and compile it to generate a.exe:
#include <stdio.h>
int main()
{
printf( "Hello world\n" ) ;
return 0 ;
}
When you run cmd, change directory to where a.exe is, and run a.exe then you will see:
Hello world
If you plan on learning C++ you don't need to write Windows applications. You can write CMD or Linux programs.
Find a good book on the C++ subject.
Good luck!
You need to create one.
check out CreateWindowEx and ShowWindow

SetWindowsHookEx with WH_KEYBOARD doesn't work for me, what do I wrong?

#include <iostream>
#include <fstream>
#define _WIN32_WINNT 0x501
#include <windows.h>
using namespace std;
HHOOK hKeyboardHook = 0;
LRESULT CALLBACK KeyboardCallback(int code,WPARAM wParam,LPARAM lParam) {
cout << "a key was pressed" << endl;
ofstream myfile;
myfile.open ("hookcheck.txt", ios::ate | ios::app);
myfile << "a key was pressed\n";
myfile.close();
return CallNextHookEx(hKeyboardHook,code,wParam,lParam);
}
int main() {
HWND consoleWindow = GetConsoleWindow();
HINSTANCE hInstCons = (HINSTANCE)GetWindowLong( consoleWindow, GWL_HINSTANCE );
hKeyboardHook = SetWindowsHookEx( WH_KEYBOARD, (HOOKPROC)KeyboardCallback, (HINSTANCE)consoleWindow, GetCurrentThreadId());
MessageBox(NULL, "It is keyboard time!", "Let's Go", MB_OK);
}
This code on every key press while the loop is going should print message on console and create a file, but nothing is happening. What do I wrong ?
I will quote from another topic:
Console windows are handled entirely by CSRSS, which is a system
process. Installing a hook into a process means injecting your DLL
into it. Since CSRSS is so important (it's vital for running of the
system, and code within runs as LocalSystem, which is the local
super-admin user), you're not allowed to inject code into it. So you
can't hook any of its windows.
There are no real window messages taking place in your simple console application, so your hook does not have to be called, and in your case you are not even injecting your hook but using thread mode hook only. Per MSDN documentation it is called when messages are about to be processed:
An application-defined or library-defined callback function used with
the SetWindowsHookEx function. The system calls this function whenever
an application calls the GetMessage or PeekMessage function and there
is a keyboard message (WM_KEYUP or WM_KEYDOWN) to be processed.
Now let me show you what you can do to start receiving calls on your hook:
MessageBox(NULL, _T("It is keyboard time!"), _T("Let's Go"), MB_OK);
//for(int i=0; i<=10; i++) {
// cout << i << endl;
// Sleep(1000);
//}
Do MessageBox and before closing it start typing - you will start getting hook calls.
Read the documentation for SetWindowsHookEx. Is it working, it will return NULL if it fails and GetLastError() can be called to get an error code to help diagnose what is wrong.
http://msdn.microsoft.com/en-us/library/windows/desktop/ms644990(v=vs.85).aspx
Sleep(1000) suspends the execution of the current thread until the time-out interval elapses. It means that your program is not actually running (ie. processing messages) during this sleep.
You need to use a different kind of command, that will keep the message loop running. The simplest thing would be to wait for user input
while(true)
std::cin.get();
I have created a dll that hooked the keyboard and in there I used the DllMainfunction to retrieve a HINSTANCE that can be used in SetWindowsHookEx.
Next to that I also used 0 as the threadid so all threads get hooked.
Perhaps you could try a similar tactic as well.