Problem with the SetConsoleCursorPosition() function - c++

I need a hand because I can't get the SetConsoleCursorPosition () function to work, I made a dll project and then I allocated the console with its main functions (cout and cin), but I don't know how to make that function work as well , in the sense that I do not go to the line that I have set, as the code ignored that instruction
void consolerefresh()
{
static const HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
COORD coord = { (SHORT)0, (SHORT)10 };
SetConsoleCursorPosition(hConsole, coord);
for (int i = 0; i < (sizeof(last) / sizeof(last[0])); i++)
{
if (last[i] != 2) {
cout << last[i] << endl;
}
}
}
My allocConsole code:
void createconsole()
{
AllocConsole();
FILE* fDummy;
freopen_s(&fDummy, "CONOUT$", "w", stdout);
freopen_s(&fDummy, "CONOUT$", "w", stderr);
freopen_s(&fDummy, "CONIN$", "r", stdin);
std::cout.clear();
std::clog.clear();
std::cerr.clear();
std::cin.clear();
}
EDIT: I fixed the error in the code but it still doesn't work.

Per SetConsoleCursorPosition, the first argument must be "a handle to the console screen buffer". Per GetStdHandle, the handle to the active console screen buffer is returned by STD_OUTPUT_HANDLE, not STD_INPUT_HANDLE which is the handle to the console input buffer.
Using the correct handle will get SetConsoleCursorPosition to work as expected.
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); // instead of STD_INPUT_HANDLE
[ EDIT ]   The following was verified to work in VS 2019 using a default wizard-generated Win app with the following code added around wWinMain.
//... wizard generated code
#include <stdio.h>
#include <iostream>
void consolerefresh()
{
static const HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
COORD coord = { 5, 5 };
SetConsoleCursorPosition(hConsole, coord);
std::cout << "at (5, 5)" << std::endl;
}
void createconsole()
{
AllocConsole();
FILE* fDummy;
freopen_s(&fDummy, "CONOUT$", "w", stdout);
}
int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPWSTR lpCmdLine,
_In_ int nCmdShow)
{
createconsole();
consolerefresh();
UNREFERENCED_PARAMETER(hPrevInstance);
//... rest of wizard generated code
Running the program creates a console window and displays the following.

Related

WM_GETTEXT not showing correct text

i am having issues with making an injectable notepad text viewer. I think I may have accessed the hwndEdit HWND wrongly. Currently when i run the program it shows
╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠
as the text
#include <stdio.h>
#include <iostream>
#include <string>
#include <Windows.h>
int main() {
AllocConsole();
SetConsoleTitleA("Notepad Viewer");
FILE *c;
freopen_s(&c, "CONOUT$", "w", stdout);
freopen_s(&c, "CONIN$", "r", stdin);
DWORD hwndEditAddress = 0x41E1B4;
HWND hwndEdit = *(HWND*)&hwndEditAddress;
for (;;) {
TCHAR text[256];
SendMessage(hwndEdit, WM_GETTEXT, sizeof(text) / sizeof(text[0]), LPARAM(text));
std::cout << "Current Text: " << text;
std::string input;
std::getline(std::cin, input);
}
}
╠ corresponds to the (extended) ASCII code 204, which is 0xCC in hex. A sequence of 0xCC bytes is used by the Visual C++ CRT to mark uninitialized memory. So, your output is basically a dump of some uninitialized memory region.
In your code, you call SendMessge passing the hwndEdit handle; but the logic you used to initialize this handle is unclear and smells of bug:
DWORD hwndEditAddress = 0x41E1B4;
HWND hwndEdit = *(HWND*)&hwndEditAddress;
This code is strange
DWORD hwndEditAddress = 0x41E1B4;
HWND hwndEdit = *(HWND*)&hwndEditAddress;
You may as well write
HWND hwndEdit = (HWND)0x41E1B4;
Which has the exact same effect.
What happens next is that this value is not the value of a window handle. Therefore the attempt to read the text fails, and text is never modified. Finally, you print an uninitialized character array, which is undefined behaviour.
You need to revisit your logic that obtains the window handle.

Get processID using part of WINDOW heading

i use the following program in c++ ,in Visual C++ 6.0, to inform me with message box when the MS Paint program is opened. It uses the exact name of the WINDOW of MS Paint,which is "Untitled - Paint" . However now i need to make the program inform me with message box when i know only a part of the name of the actual WINDOW , for example , if the window is "Abcdefgh - Paint" and i set the string name in this way - std::wstring windowName(L"Paint"); - the program to work again. Using the following 3 rows of code the program works fine when the actual WINDOW name is the exact name of the MS Paint window:
HWND windowHandle = FindWindowW(NULL, windowName.c_str());
DWORD* processID = new DWORD;
GetWindowThreadProcessId(windowHandle, processID);
But it will not work if the string windowName is just part of the name, i mean if it is "Paint".
Can someone show me how to do this? I thought to take a list of the names of all opened WINDOWS and to compare them with my part of the real name, i mean to search match of the substring "Paint" in their names, but i don't know how to get all opened windows.
Also, this is very important, my computer is old and i am using Visual C++ 6.0, so i can not use all the evolution features of C++ and the program environments nowadays, i mean , i can not use code which is compiled correctly in .NET but does not compiles in Visual C++ 6.0.
Thanks
#include "stdafx.h"
#include < iostream>
#include < string>
#include < windows.h>
#include < sstream>
#include < ctime>
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
// TODO: Place code here.
std::wstring windowName(L"Untitled - Paint");
while(true)
{
Sleep(1000*5);
time_t t = time(0); // get time now
struct tm * now = localtime( & t );
int tday = now->tm_mday;
int tmin = now->tm_min;
int thour = now->tm_hour;
HWND windowHandle = FindWindowW(NULL, windowName.c_str());
DWORD* processID = new DWORD;
GetWindowThreadProcessId(windowHandle, processID);
char probaintstr[20];
sprintf(probaintstr,"%d",*processID);
if(strlen(probaintstr) <=5 )
{
Sleep(1000*10);
MessageBox(NULL,"niama go Notepad ili Wordpad","zaglavie",MB_OK);
}
else {
}
}
return 0;
}
You can use EnumWindows, for example
BOOL CALLBACK enumWindow(HWND hwnd, LPARAM lp)
{
std::string str(512, 0);
int len = GetWindowText(hwnd, &str[0], str.size());
if (str.find("Paint") != std::string::npos)
{
MessageBox(0, str.c_str(), 0, 0);
}
return true;
}
int APIENTRY WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
EnumWindows(enumWindow, 0);
return 0;
}
Or you can use FindWindowEx and look for classname. The classname for MS Paint is "MSPaintApp". You can find this information from "Spy" utility for windows.
int APIENTRY WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
for (HWND hwnd = NULL;;)
{
hwnd = FindWindowExA(NULL, hwnd, "MSPaintApp", 0);
if (!hwnd)
break;
std::string str(512, 0);
int len = GetWindowText(hwnd, &str[0], 512);
str.resize(len);
if (str.find("Paint") != std::string::npos)
MessageBox(0, str.c_str(), 0, 0);
}
return 0;
}
For process id you don't need to allocate memory. Just use a reference:
DWORD processID;
GetWindowThreadProcessId(windowHandle, &processID);

How to display cmd prompt after printing output to cmd.exe?

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 );

Unhandled Exception - Access violation if /SUBSYSTEM parameter is changed

I have an application, in which I use a console to see some of the values being output. Now some of the requirements have changed, and I do not need the console during runtime anymore.
I tried to change that, by toggling the /SUBSYSTEM parameter, found under Project Properties->Linker->System->Subsystem from Console to Windows, as I'd done the same for an earlier thing, and it had worked.
On this occasion, it gives me an Unhandled Exception, in mfc110u.dll, as the object cannot be instantiated.
Why does this exception occur, and how else can I turn off the console with the running program? I'm using VS2012 as the dev environment.
If you don't want a console, declare a winmain. This is the non-unicode version
#include <windows.h>
#include <iostream>
#include <cstdio>
int main (int, char**);
// If we just start with main, we will always get a console window
int WINAPI WinMain (
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow
)
{
int argc = __argc;
char** argv = __argv;
#ifdef DEBUG
// If we are running in debug mode, open a console window
AllocConsole();
freopen("conin$", "r", stdin);
freopen("conout$", "w", stdout);
freopen("conout$", "w", stderr);
#endif
return main (argc, argv);
}
int main (
int argc,
char** argv
)
{
MessageBox(NULL, "Whoo hoo", "It Works!!!", MB_OK);
return 0;
}

I've created a new console in win32 window-only app, console is created but nothing gets print on it

this code is compiled with -mwindows under gcc , there is no winapi error message.
#include <windows.h>
#include <stdio.h>
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPTSTR, int nCmdShow) {
AllocConsole();
printf("%s\n", "sample text");
return 0;
}
Result is that console is black empty, no text, no error message.
Use:
freopen("CONOUT$", "wb", stdout);
to reopen the stdout after you have created the console. If you plan on using it for input too, then you need:
freopen("CONIN$", "rb", stdin);
and stderr may need opening too:
freopen("CONOUT$", "wb", stderr);