Redirect stdout to an edit control (Win32) - winapi

I have a simple Win32 GUI app which has an edit control in the main window. If I write:
printf("Hello world!\n");
I would like the text to appear in that control instead of the console. How to?
Update: The app is just simple window with edit control and I can compile it with or without displaying the console (gcc -mwindows). Sometimes I call an external function, which might printf() something - and I would like to catch that something and display it in the edit control. So far, SetStdHandle() seems to be closest to what I try to achieve but I cannot get it to work, yet...
Update 2:
Please, can someone tell me why this is not working and how to fix it?
HANDLE hRead, hWrite;
CreatePipe(&hRead, &hWrite, NULL, 0);
SetStdHandle(STD_OUTPUT_HANDLE, hWrite);
printf("Hello world!\n");
CloseHandle(hWrite); // Why is this needed?
DWORD dwRead;
BOOL bSuccess;
CHAR chBuf[4096];
bSuccess = ReadFile(hRead, chBuf, 4096, &dwRead, NULL); // This reads nothing :(
Also, it still prints "Hello world" to the console, I expected it not to..?

Check out the API call SetStdHandle. Once the stdout is redirected to your stream, read from it and send the text to the edit control.
[Edit]
Take a look at using dup2. The following code seems to work.
int fds[2];
_pipe (fds, 1024, O_TEXT);
_dup2 (fds[1], 1); // 1 is stdout
printf ("Test\r\n");
char buffer[100];
_flushall(); // Need to flush the pipe
int len = _read (fds[0], buffer, 100);
buffer[len] = 0; // Buffer now contains "Test\r\n"

You can do that in Windows by redirecting stdout when you create the process. You do so by setting flags and setting some handles in the STARTUPINFO structure passed to CreateProcess. See this example on MSDN for detail on how to set this up.
Once you have that setup can use ReadFile to read from the redirected stdout of the console process then send it to the edit control.

Write a internal __printf function can output the text to edit control, then replace all printf functions with that.

Related

WinAPI CreateDialog Ressource not found error 0x715

Like often, I post here after several hours of research and tries without any success
I have this old dll written in C. For the moment, it has no interface but I need to add a dialog box to it.
I work with VS2017 and tried the following :
Using VS2017 ressource editor, I added a dialog box (id : IDD_DIALOG_REPLAY, automatically defined to 101 in resource.h file by resource editor) and added the following code to create my dialog box :
INITCOMMONCONTROLSEX InitCtrls;
InitCtrls.dwSize = sizeof(InitCtrls);
InitCtrls.dwICC = ICC_LINK_CLASS | ICC_STANDARD_CLASSES | ICC_WIN95_CLASSES;
InitCommonControlsEx(&InitCtrls);
HWND hDialog = 0;
hDialog = CreateDialog(pSGL->hInstance,MAKEINTRESOURCE(IDD_DIALOG_REPLAY),NULL,WndProc);
if (!hDialog)
{
char buf [100];
wsprintf (buf, "Error x%x", GetLastError ());
MessageBox (0, buf, "CreateDialog", MB_ICONEXCLAMATION | MB_OK);
return 1;
}
ShowWindow(hDialog, SW_SHOW);
Note 1 : The message loop is already present in another dll executed in the same thread
Note 2 : in a first time, I use a call back function WndProc which is pretty standard and which basically executes the DefWindowProc function
When I compile my dll (with ressource compilation verbose option set), I get the following messages :
1>Writing DIALOG:101, lang:0x40c, size 452.
1>Writing AFX_DIALOG_LAYOUT:101, lang:0x40c, size 2.
When I open the binary of my dll in VS2017, I can see that there is a dialogbox id 101
=> The dialog box is actually present in my binary file.
But when I execute it, I get an error 0x715 : ERROR_RESOURCE_TYPE_NOT_FOUND and of course, the dialog box is not created.
Note : this happen, no matter if the dialog box contains controls or if it is empty
I have absolutly no clue why this is happening. Any help would be really welcome.
Thanks in advance,
Antoine
Ok,thanks to Hans, I found the reason.
I was using the exe hInstance and so, the program was looking for the dialog box inside the exe and not inside the dll.
Changing the hInstance to the dll one fixed my issue.
Thanks again Hans

Gpm_Open() connects, but prints to the console on mouse click

I am trying to use libgpm, looks like the program detects mouse clicks,
but as a side effect it prints something like this to the terminal:
^[[M <7^[[M#<7^[[M <7^[[M#<7^[[M <7^[[M#<7^[[M <7^[[M#<7^[[M Y=^[[M#M<^[[M !=^[[M#)=
Even if I remove any calls to Gpm_Getc(), leaving the code as simple as this:
#include <gpm.h>
int main(int argc, char *argv[])
{
Gpm_Connect conn;
int c;
conn.eventMask = 0;
conn.defaultMask = ~0;
conn.minMod = 0;
conn.maxMod = ~0;
if (Gpm_Open(&conn, 0) == -1)
printf("Cannot connect to mouse server\n");
while (1);
Gpm_Close();
return 0;
}
I still see those gibberish codes. I reckon, they represent the mouse events. But in my code there is no direct instruction to print them. Why are they printed to my terminal? How can this be avoided?
I use gnome-terminal on linux, not a real console, if that matters.
If the TERM environment variable is xterm, GPM won't try to open the Linux console.
Instead, it simply turns on xterm mouse-mode (which makes the terminal send escape sequences), and it turns out, expects the application to handle that rather than transforming the escape sequences into its protocol.
From ncurses' viewpoint, for instance, that makes its behavior in a terminal emulator less than useful, and the library checks for this case and ignores GPM (since 2010).

check if read operation is for spesific file in filter driver

Hello im new at filter driver programming, i took windows swapBuffer example and i try to modify it to pritn me the file name for each read/write operation
and print the data tryed to read/ write.
i tried to do it like this:
FLT_PREOP_CALLBACK_STATUS SwapPreWriteBuffers(
_Inout_ PFLT_CALLBACK_DATA Data,
_In_ PCFLT_RELATED_OBJECTS FltObjects,
_Flt_CompletionContext_Outptr_ PVOID *CompletionContext)
{
/* here we do some logic that check that we want to write more the
0 bytes and get volume context and allocate aligned nonPaged memory
for the "swapping memory" , build a MDL and then if all succeed i try this:
*/
WCHAR filename[300] = {0};
wfprintf(filename, "%wZ\0", Data->Iopb->TargetFileObject->FileName);
if (NULL != wcstr(filename, L"try_me.txt"))
{
DbgPrint("Fname %S try to write %S\n", filename, Data->Iopb->Parameters.Write.WriteBuffe);
}
}
my main problem (i think) Data->Iopb->TargetFileObject->FileName is unicode and i dont know how to make the compae betwine this and a string of the file name
my outher problem is how do i print the buffer curretly to the dbg string without risking at getting blue screen? (i got alot from them laytly...) sometimes i get to this function without writing a string , how do i recognize the different and printing it saftely?
last question , are there any way to nake try except in drivers or all the faults are continue directly to blue screen?
thank you
p.s.
here is the link to the entire code (Without the additions I wrote (which I listed in this post above))
https://github.com/Microsoft/Windows-driver-samples/blob/master/filesys/miniFilter/swapBuffers/swapBuffers.c
File name are the concepts at IRP_MJ_CREATE. you can't rely on the name at irp_mj_write or read. so better to do it in create. also try to get the name from FltObject->FileObject->FileName it may give you the desired name of your file aling with other names too.
For printing the written data you need to check for Irp flag in minifilter it is from Data->Iopb->IrpFlags, IRP_PAGING_IO if its true then print the buffer using
KdPrint((".... "));
Yes, you can use try, except in driver too.
Hope this may help.
:)

how to write to output window in Visual Studio 2013?

I am able to compile and run my visual c++ program. It is not a console application. I am modifying an existing MFC application. I am trying to troubleshoot my program. I cannot run in debug and get the traces I need because my program also reads the mouse cursor. I also tried to use a messagebox to output this string, but again, a message box interferes with the mouse.
In the output window, I right-click and make sure that Program Output is enabled.
cout << "something" << endl;
However, in the output window, I do not see anything.
Looking at SO posts, I tried
std::string stro = "something ";
OutputDebugString(stro);
error C2664: 'void OutputDebugStringW(LPCWSTR)' : cannot convert
argument 1 from 'std::string' to 'LPCWSTR'
So changed to std::wstring stro
and
OutputDebugString(stro.c_str());
to append an int, I had to
std::wostringstream wso;
wso << i;
stro = stro + wso.str();
OutputDebugString(stro.c_str());
But I cannot see output in the window when not running in DEBUG. Is there any way to see output in non-DEBUG? This is surprisingly frustrating.
In the comments, writing a separate overloaded class was suggested; this seems like overkill. Java has System.out.println even in GUI programs. Android has Log.v(). Such a pity the equivalent is not available here.
Console applications have console output, which is what cout sends to. Since this isn't a console application, you'll want to try another approach. It's strange you object "I don't see Debug output when I'm not in Debug", that's the point of it - don't use OutputDebugString and expect it to be for something other than debug output.
I think the best way to understand what your application is doing, without interacting with it under the debugger (I know the frustration of trying to debug event handlers that keep being re-triggered by your debugging activities) is to try tracepoints. I blogged about them back in 2006 and they're still a great technique. Reading the mouse cursor won't interfere with tracepoints, and you can turn them on and off without rebuilding your app or making any code changes.
Set up a breakpoint, then right-click the red dot and choose When Hit. You can adjust the default message that goes into the output window to show you any values you are interested in - you can even call functions in the trace message, as you can see in the blog entry where I call the size() method of a collection. If necessary, you can even debug a release build.
Actually OutputDebugStrng should work in release builds - as long as you're running the app from the debugger. However cout cannot route output to the VS output pane.
If you already have a lot of 'cout' style debugging code, the easiest route might be to replace it with a custom ostream overload which does print to the output pane. Here's one, here's another.
If you can rewrite the debugging code completely, some macro wrappers around OutputDebugString might be better for you.
Having a stdout/stderr console window for debugging is very useful, and I always miss it when working on WinMain based apps. I use this code fragment to create a console for windows apps (and chain it in with existing loggers, etc.) After running this, your cout/cerr should work fine. OutputDebugString output can be seen outside of DevStudio using the DebugView app, but I prefer this:
#include <io.h>
#include <fcntl.h>
...
// DOS box console for stdin/stdout/stderr
void makeConsole()
{
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, 2);
*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, 2);
*stdin = *hf_in;
HANDLE handle_err = GetStdHandle(STD_ERROR_HANDLE);
hCrt = _open_osfhandle((long)handle_err, _O_TEXT);
FILE* hf_err = _fdopen(hCrt, "w");
setvbuf(hf_err, NULL, _IONBF, 2);
*stderr = *hf_err;
ios::sync_with_stdio();
}

Printing variable values to console visual c++ windows store Modern UI app

I'm just starting learning C++/XAML windows store app development but for the life of me I can't find a nice way to print variable values to the "Output" window in VS2012.
Debug.WriteLine() doesn't seem to exist for Windows Store apps and I can't find a way to print other than OutputDebugString() which I can't use to print variable values (without some heavy formatting).
Is there just an easy way to print the example line:
mouse position X: 12
for example, where 12 is an integer that comes from MouseDelta.
Thanks for your time,
Poncho
Not really, no. You could write a little function that formatted like printf and passed along the resulting string to OutputDebugString() but there's nothing more straightforward available.
I guess you could use ToString(), Platform::String::operator+, and Platform::String::Data() to accomplish this; though it's a little ugly:
OutputDebugString( ("mouse position X:" + MouseDelta.X.ToString())->Data() );
Here is a nice alternative: http://seaplusplus.com/2012/06/25/printf-debugging-in-metro-style-apps/, basically it allocates a console for your Windows Store App, obviously this will fail certification but given that this may be just for debug purposes only, it will fine. I'm copying the relevant code here:
// Include Windows.h for WINBASEAPI and WINAPI:
#include <Windows.h>
// Declare AllocConsole ourselves, since Windows.h omits it:
extern "C" WINBASEAPI int WINAPI AllocConsole();
auto main(Platform::Array<Platform::String^>^) -> int
{
AllocConsole();
std::wcout << L"Hello there!" << std::endl;
std::getchar();
return EXIT_SUCCESS;
}
However if you want to see such output inside your app, then you may want to use Console Class for Modern UI Apps which implements part of the .NET System.Console and can be safely used inside Windows Store apps.
This solution uses a wrapper around OutputDebugString:
void WinLog(const wchar_t *text, int n)
{
wchar_t buf[1024];
_snwprintf_s(buf, 1024, _TRUNCATE, L"%s %d\n", text, n);
OutputDebugString(buf);
}
which can be called as follows:
WinLog(L"The Answer is", 42);

Resources