how to write to output window in Visual Studio 2013? - visual-studio

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

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

UnicodeString::Length() interferes with debugger display

The debugger seems to suppress viewing the contents of a UnicodeString in the Local Variable and Watch windows whenever the current function contains a UnicodeString::Length() call.
Running C++ Builder 10.3 Rio Enterprise (upgraded to 10.31 to try to solve the issue) where I have started a new project, added a button and put the following code in for the button. This a stripped down version of a large piece of code to track down and reproduce the issue.
void __fastcall TForm1::Button1Click(TObject *Sender)
{
TFDQuery* qry = new TFDQuery(NULL);
UnicodeString search = "SELECT *\rFROM Client\rWHERE id>0;";
UnicodeString currLine;
int to, len;
qry->SQL->Clear();
to = search.Pos("\r");
while (to > 0) {
currLine = search.SubString(1, to-1);
qry->SQL->Add(currLine);
//len = search.Length()-1; // Offending line
search = search.SubString(to+1, 999999);
to = search.Pos("\r");
}
currLine = search;
qry->SQL->Add(currLine);
}
The picture below shows two different runs of this code. One is exactly as shown above (with one line commented out). The other shows with the line included.
My concern is that the the debugger only shows the apparent address of the variable named "search" and if I expand it, it shows "????", not the contents of the variable as shown by the arrow. Also note, the breakpoint is above the line that causes the debugger to switch views. Any ideas how I can get the contents of "search" to appear if I actually calculate the length of the substring (rather than placing "999999" for its length)?
After some experimenting, I can now partially answer my own question with a potential workaround. Replacing the "search.Length()" with "wcslen(search.c_str())" seems to work, at least it does not have the side effect of displaying only addresses for UnicodeStrings in the watch list and and local variables windows. At this point, I haven't thoroughly tested if this eventually raises some other problem. But why should I have to do this for such a fundamental type to the language?

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

How to open a file from network drive/path with default program?

from my application I want to open files (jpg, pdf, ..) with the default windows-program from network drives. I know start, but it doesn't seem to work for network paths.
I tried the following commands, but all I get is the windows dialog telling me that he doesn't know how to open that file and whether I want to use a web-service to ask for a programm or choose manually.
From cmd.exe (P:\ is a network drive):
cmd /c "start \server\path\to\image.jpg"
> cmd /c "start P:\path\to\image.jpg"
The path to the file is correct and clicking on it in the explorer works fine.
Thanks
UPDATE: I found the problem. See my answer below.
I think the function you need is ShellExecute - it would look something like this:
ShellExecute(ParentWindowHandl, "open", "Z:\SQLWriter.doc", NULL, SW_SHOWNORMAL);
P.S. I know I should post this as comment, but can't comment on all posts yet.
I tried these two commands:
start Z:\SQLWriter.doc
start \192.168.10.230\MyFolder\SQLWriter.doc
Both the commands worked perfectly. I didn't get any error messages.
You can use these if you want it to launch.
SHELLEXECUTEINFO ExecuteInfo;
memset(&ExecuteInfo, 0, sizeof(ExecuteInfo));
ExecuteInfo.cbSize = sizeof(ExecuteInfo);
ExecuteInfo.fMask = 0;
ExecuteInfo.hwnd = 0;
ExecuteInfo.lpVerb = "open"; // Operation to perform
ExecuteInfo.lpFile = "cmd.exe"; // Application name
ExecuteInfo.lpParameters = "start P:\Myfile.jpg"; // Additional parameters
ExecuteInfo.lpDirectory = 0; // Default directory
ExecuteInfo.nShow = SW_SHOW;
ExecuteInfo.hInstApp = 0;
if(ShellExecuteEx(&ExecuteInfo) == FALSE)
Or you can go through this link: http://www.codeguru.com/forum/showthread.php?t=302501
Ok, I have found the problem. Seems like the windows registry was a bit confused.
As commented before, other files like text and doc work, so the only problem was JPEG files.
Double Clicking them in the Windows Explorer worked fine for them, but using the start command showed me the popup described above. Selecting a program here once and marking it as permanent resolved my problem. Further calls with start now correctly open the image directly.

Redirect stdout to an edit control (Win32)

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.

Resources