The Code Project View our sponsorsCodejock Software - Serious GUI CodeAdvertise on the CodeProject
Home >> C++ / MFC / STL >> Unedited Reader Contributions

The Code Project Visual C++ Forum FAQ
By Michael Dunn

A list of frequently-asked questions taken from the C++ forum. 
 Beginner
 VC 4-6, Win95-98, NT4, W2K
 Posted 16 Jul 2001
 Updated 25 Jul 2001
Articles by this author
Send to a friend
Printer friendly version
[This is an unedited reader contribution] [Modify this article] [Delete this article]
Home Latest updates Submit your article About Us Advertise on the Code Project Contact us Discussion Forums
Navigation bar
16 users have rated this article. result:
4.75 out of 5.

About This FAQ

Welcome to the FAQ for the CodeProject Visual C++ forum. This FAQ is a compilation of the most-often asked questions in the forum, and covers several C++ programming subjects. It is not a full-fledged C++ or Windows programming FAQ (there are plenty of those already), but rather it's meant to cover the topics that CodeProject readers ask about the most.

If you think of any questions that you feel should be covered in this FAQ, email me with the question and the answer.

NOTE: Please do not email me directly to ask individual questions. I can't be everyone's personal consultant. Also, don't post programming questions in the message area of this article. Use the CodeProject forums to ask your questions; that's what they're there for!

Thanks to Tim Deveaux, Anders Molin, and Christian Graus for their contributions to this FAQ, along with all the folks who have posted suggestions in the comments area and via email!

Contents

CodeProject forum questions

1.1: What's the best way to ask a question about code, so that I get a good answer?

1.2: Why don't my #include lines or template parameters show up right in the forum?

Compiling and linking questions

2.1: I'm trying to use cout and cin, but the compiler gives an undeclared identifier error (C2065) on those names. Why?

2.2: I'm trying to call a Windows API, but the compiler gives an undeclared identifier error (C2065). Why?

2.3: Why do I get an unresolved external error (LNK2001) on main() when I make a release build of my ATL project?

2.4: I added some source files I got from someone else into my project and the compiler gives the error "C1010: unexpected end of file while looking for precompiled header directive." Why?

2.4a: Thanks. Now, what's a precompiled header?

Debugging questions

3.1: What does a failed debug assert mean?

Windows UI questions

4.1: How can I save and load JPGs, PNGs, or other graphics formats?

4.2: How do I change the background color of a dialog, or draw a picture as the background?

4.3: I have a dialog that does some lengthy processing, and I need to have a Cancel button so the user can abort the processing. How do I get the Cancel button to work?

4.4: How do I change the cursor when it's in my window?

4.5: How do I show or hide a window?

4.6: How do I enable or disable a dialog control (button, edit box, etc.)?

4.7: How do I keep a window on top of all other windows?

Console program questions

5.1: How do I clear the screen in a console program?

5.2: With other compilers, I used to use gotoxy() to position the cursor in a console program. How do I do this in Visual C++?

5.3: How can I output text in different colors in a console application?

5.4: I've allocated a console window in my GUI program, but if the user closes the console, my program closes too. What to do?

5.5: I've allocated a console in my GUI program. When I try to close the console window, it hangs around for a while. Why?

General C++ questions

6.1: Why can't I use a member function as a callback?

6.2: How do I share a global variable among my .CPP files?

6.3: I have the string representation of a number, say "10235". How do I convert that to an integer?

MFC questions

7.1: In my MFC program, I'm trying to disable a menu item with EnableMenuItem(), but it doesn't have any effect on the menu. Why?

Links to other Resources

MFC FAQs

Books about programming

CodeProject forum questions

1.1: What's the best way to ask a question about code, so that I get a good answer? (top)

First off, don't just say, "My program doesn't work. What's wrong?" as that will never get an answer. At the very minimum, explain what you want to do, what is going wrong, and post the code that isn't working right.

Also, when you include code in your post, enclose the code in a <pre>...</pre> block so that your indentation is preserved. If you don't do this, all groups of spaces are reduced down to one space per HTML rules, and the result is impossible to read.

Here's an example of a good post:

I'm working on a simple dialog-based app that should show the drives on the computer and each volume label. I have a list control with two columns, the first column for the drive letter and the second for the volume label. But I can't get anything to appear in the second column. Anyone have a clue what I'm doing wrong? Here's how I'm trying to add items to the control:

   m_DriveList.InsertItem ( 1, szDriveLetter );
   m_DriveList.InsertItem ( 2, szVolumeLabel );

And so on, continuing on with items 3, 4, etc. Nothing ever shows up in the second column.

If you just post with "why doesn't my program work?", the forum readers then have to play 20 questions until they finally know enough to answer you. Providing all that info up front will make everyone happy and get you an answer sooner.

1.2: Why don't my #include lines or template parameters show up right in the forum? (top)

The forum allows you to use HTML tags in posts, for example <b> to make text bold. When you write:

  #include <iostream>

the "<iostream>" part looks like an HTML tag, so it doesn't appear in the post. You must use the HTML code for "<" and ">", which is "&lt;" and "&gt;" respectively. So the above include line should be entered as:

  #include &lt;iostream&gt;

Note that you have to do this for if, for, and while expressions as well, such as:

  for ( i = 0; i &lt; max; i++ ) { ... }

If you write "i < max" the < symbol will cause the same problem.

And by the way, if you want an ampersand (&) in your post, you must write it as "&amp;"

Compiling and linking questions

2.1: I'm trying to use cout and cin, but the compiler gives an undeclared identifier error (C2065) on those names. Why? (top)

The standard C++ library classes are separated into the std namespace. When referring to classes and functions in that namespace, you must preface them with std:: For example:

  std::cout << "Salut, tout le monde!" << std::endl;

Alternatively, you can put this line at the top of your .CPP file:

  using namespace std;

which makes the compiler treat everything in the std namespace as if it weren't in a namespace, which means you don't have to type std:: everywhere.

2.2: I'm trying to call a Windows API, but the compiler gives an undeclared identifier error (C2065). Why? (top)

The Windows header files can be used to build programs for any version of Windows starting with Windows 95 and NT 3.51. Since not all APIs are present in all versions of Windows, there is a system that prevents you from using APIs that aren't available in the Windows version you are targeting.

This system uses preprocessor symbols to selectively include API prototypes. The symbols are:

By default, you can only use functions in Windows 95, NT 3.51, and pre-IE3 common controls. To use APIs introduced in later versions of Windows or the common controls, you need to #define the above symbols correctly before including any Windows headers.

As of this writing, here is the current list of values you can use for the above symbols.

2.3: Why do I get an unresolved external error (LNK2001) on main() when I make a release build of my ATL project? (top)

Release builds of ATL projects contain an optimization whereby the project does not link with the C runtime library (CRT) in order to reduce the size of your binary. If you use any functions from the CRT (for example, string manipulation functions) or classes from the C++ library, you need to link with the CRT.

In your project options, go to the C/C++ tab and select the Preprocessor category. Remove the symbol _ATL_MIN_CRT from the preprocessor defines, which will turn off this optimization.

Search MSDN for "lnk2001 atl" for more details.

2.4: I added some source files I got from someone else into my project and the compiler gives the error "C1010: unexpected end of file while looking for precompiled header directive." Why? (top)

By default, Visual C++ projects use precompiled headers. This is a system whereby the large Windows headers are compiled only once when you build stdafx.cpp. Every other .CPP file in your project needs to #include "stdafx.h" as the first #include in order to build. The compiler specifically looks for the name "stdafx.h" to know when to insert the precompiled header information.

If you received the source for an entire program from someone else, and you want to build it as a Visual C++ project, you can turn off precompiled headers instead. In your project options, go to the C/C++ tab and select the Precompiled headers category. Click the Not using precompiled headers radio button, then click OK.

2.4a: Thanks. Now, what's a precompiled header? (top)

After the headers included by stdafx.cpp are processed, the preprocessor saves a snapshot of its internal state, which includes all the function prototypes and #defines in the Windows headers, along with anything else you added to stdafx.h. This snapshot is saved in a .PCH file. Since processing all those headers takes a long time, when the compiler compiles the other .CPP files, it reloads the preprocessor state from the .PCH file instead of processing all the headers again.

The preprocessor looks for an #include "stdafx.h" line or a #pragma hdrstop directive to tell when it should read the .PCH file. If neither of those lines is present, you'll get error C1010.

Debugging questions

3.1: What does a failed debug assert mean? (top)

Simply put, it means you have a bug in your code. Asserts check for some condition that must always be true, and if the condition is ever false, it indicates a bug in the calling code (yours).

A full description of asserts is beyond the scope of this FAQ, but when a library such as MFC gives an assert failure message, it means the library detected that you are incorrectly using it or calling one of its functions with bad parameters.

For example, this MFC code will assert:

BOOL CYourDlg::OnInitDialog()
{
CListCtrl wndList;

    wndList.InsertColumn ( 0, "abcdef" );
}

CListCtrl::InsertColumn() contains this check:

  ASSERT(::IsWindow(m_hWnd));

which fails because the wndList object wasn't attached to a real list view control.

Asserts that aren't trivial like the above example will (usually) have comments that can help you understand what the assert was checking for.

Windows UI questions

4.1: How can I save and load JPGs, PNGs, or other graphics formats? (top)

Use GDI+ or a third-party library like paintlib, ImageMagick, or ImageLibrary.

See Also: Christian Graus's GDI+ articles in the .NET section; Peter Hendrix's article "Simple class for drawing pictures."

4.2: How do I change the background color of a dialog, or draw a picture in the background of my window? (top)

Handle the WM_ERASEBKGND message. For dialogs, do not handle WM_PAINT; WM_ERASEBKGND is the message designed for just this purpose.

Search MSDN for "WM_ERASEBKGND" and you'll find several pages on this topic.

4.3: I have a dialog that does some lengthy processing, and I need to have a Cancel button so the user can abort the processing. How do I get the Cancel button to work? (top)

First off, the reason the UI doesn't respond to the mouse is that your program is single-threaded, which means it is not pumping messages in the dialog's message queue while the thread is busy doing the processing.

You have two choices, either move the processing to a worker thread, or keep the dialog single-threaded and periodically poll your message queue during your processing. Multithreading is beyond the scope of this FAQ, but see the Threads, Processes & Inter-Process Communication section of CodeProject for more info. As to the second solution, here is MFC code that will pump any messages waiting in your message queue:

void ProcessMessages()
{
CWinApp* pApp = AfxGetApp();
MSG msg;

  while ( PeekMessage ( &msg, NULL, 0, 0, PM_NOREMOVE ))
      pApp->PumpMessage();
}

Call ProcessMessages() periodically in the code that does the lengthy processing.

See Also: Several articles on threads.

4.4: How do I change the cursor when it's in my window? (top)

Handle the WM_SETCURSOR message, and call the SetCursor() function to change the cursor. Note that your window receives this message every time the mouse is moved, so be sure your WM_SETCURSOR handler executes quickly. (That is, don't do slow operations like file access.)

4.5: How do I show or hide a window? (top)

To show a window:

  ShowWindow ( hwndYourWindow, SW_SHOW );

To hide it:

  ShowWindow ( hwndYourWindow, SW_HIDE );

There are many more flags that control minimizing and maximizing windows, among other things. See the ShowWindow() page in MSDN for more details.

4.6: How do I enable or disable a dialog control (button, edit box, etc.)? (top)

To enable a control:

  EnableWindow ( hwndYourControl, TRUE );

To disable it:

  EnableWindow ( hwndYourControl, FALSE );

4.7: How do I keep a window on top of all other windows? (top)

To make your window topmost:

  SetWindowPos ( hwndYourWindow, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE );

To revert back to normal:

  SetWindowPos ( hwndYourWindow, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE );

Console program questions

5.1: How do I clear the screen in a console program? (top)

This is covered in the Knowledge Base article Q99261, "HOWTO: Performing Clear Screen (CLS) in a Console Application."

Essentially, the procedure is to get information on the size of the console output buffer, then fill it with spaces using FillConsoleOutputCharacter() and FillConsoleOutputAttribute().

Before you can use this method, however, you need to get a HANDLE to the console screen buffer, like so:

HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);

    if ( hConsole != INVALID_HANDLE_VALUE )
        {
        // do stuff...
        ...
        }

Now you are set to call this and several other Win32 console functions. Search MSDN for "console reference" to learn more about the console-related structures and functions.

5.2: With other compilers, I used to use gotoxy() to position the cursor in a console program. How do I do this in Visual C++? (top)

Output to a console is essentially controlled by the console screen buffer's current settings, and each position in the buffer is addressable with a COORD structure. This code uses SetConsoleCursorPosition() to move the current output location to row 11, column 32:

#include <windows.h>
#include <stdio.h>
 
int main ( int argc, char** argv )
{
HANDLE hConsole = GetStdHandle ( STD_OUTPUT_HANDLE );

    if ( INVALID_HANDLE_VALUE != hConsole )
        {
        COORD pos = {32, 11};
        SetConsoleCursorPosition ( hConsole, pos );
        printf ( "Hello World!\n" );
        }
 
    return 0;
}

Also, code that outputs to cout will respect the buffer settings as well.

5.3: How can I output text in different colors in a console program? (top)

Each location in the console screen buffer has text attributes as well as a character associated with it, and the Win32 console functions can affect these in two ways. SetConsoleTextAttribute() affects subsequent characters written to the buffer, while FillConsoleOutputAttribute() directly changes the attributes of an existing block of text.

The following functions might be used for normal, bold, and reverse text (this assumes that the class has a handle to the console, through a call to GetStdHandle()):

void CMyConsoleClass::SetTextNormal()
{
    // white on black - the default
    SetConsoleTextAttribute ( m_hConsole,
                              FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE );
}

void CMyConsoleClass::SetTextBold()
{
    // hi-white on black 
    SetConsoleTextAttribute ( m_hConsole,
                              FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE |
                                FOREGROUND_INTENSITY );
}

void CMyConsoleClass::SetTextReverse()
{
    // black on white
   SetConsoleTextAttribute ( m_hConsole, 
                             BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE );
}

Note that there are no settings for blink or underline, so you will need to be a bit creative if you try to emulate ANSI or VT100 terminal text modes with this method.

5.4: I've allocated a console window in my GUI program, but if the user closes the console, my program closes too. What to do? (top)

One method that works well is to disable the close menu option. After the console has been allocated with AllocConsole(), you can do this if you can find the console window's handle.

void DisableClose() 
{
char buf[100];

    wsprintf ( buf, _T("some crazy but unique string that will ID our window - maybe a GUID and process ID") );

    SetConsoleTitle ( (LPCTSTR) buf );

    // Give this a chance - it may fail the first time through.
HWND hwnd = NULL;

    while ( NULL == hwnd )
        {
        hwnd = ::FindWindowEx ( NULL, NULL, NULL, (LPCTSTR) buf );
        }

    SetConsoleTitle ( _T("whatever") );  // reset old title - we'd normally save it with GetConsoleTitle...

    // Remove the Close menu item. This will also disable the [X] button in the title bar.
HMENU hmenu = GetSystemMenu ( hwnd, FALSE );

    DeleteMenu ( hmenu, SC_CLOSE, MF_BYCOMMAND );
}

5.5: I've allocated a console in my GUI program. When I try to close the console window, it hangs around for a while. Why? (top)

While only one console can be associated with a process, its possible for more than one process to share the same console. When you call FreeConsole(), Windows detaches your app from the console, and will close it if no other processes are using it. There is a difference between NT and 9x in when the close is performed. NT seems to check the status immediately and close the console. Windows 9x seems to take more of a "garbage collection" approach, preferring to wait until some action is performed on the console widow before checking if it's time to get rid of it.

One trick that helps is to minimize the window before calling FreeConsole(); check the previous FAQ entry for a tip on getting the window handle needed to do this.

  CloseHandle ( hConsole );

  // This helps kill the window quickly.
  ShowWindow ( console_hwnd, SW_HIDE );

  console_hwnd = NULL;

  FreeConsole();

Note: Don't call SendMessage(console_hwnd, WM_SYSCOMMAND, SC_CLOSE, 0) as this will terminate your entire process!

General C++ questions

6.1: Why can't I use a member function as a callback? (top)

Member functions receive the this pointer as their first parameter (even though you don't write it that way), so a member function can never match the required prototype of a callback function. There are two solutions.

First, you can make the member function static. Doing so removes the this parameter, but then you cannot access non-static data or functions in the class.

Second, you can keep the member function as-is, use a global function as the actual callback, and pass the global function the this pointer yourself. The global function then calls the member function using the passed-in this pointer. Windows APIs that use a callback function have a void* parameter that you can use for whatever purpose you like. Windows sends that void* parameter along to the callback function. So, you use that parameter to pass the this pointer.

Here is an example:

class CCallback
{
public:
    void DoWork();
    BOOL MyCallback();

protected:
    // ...data members that the callback function needs to access...
};

void CCallback::DoWork()
{
    SomeAPIThatHasACallback ( 
      GlobalCallback,           // your callback function
      (void*) this );           // 'this' pointer
}

BOOL CCallback::MyCallback()
{
    // Do your callback processing here...
}

BOOL CALLBACK GlobalCallback ( void* pv )
{
// pv is the same as the 2nd parameter to SomeAPIThatHasACallback() above.
CCallback* pThis = reinterpret_cast<CCallback*>(pv);  

    return pThis->MyCallback();
}

void main()
{
CCallback cbk;

    cbk.DoWork();
}

Note that this technique of passing the this pointer can also be used if you make the callback a static member function.

See Also: Daniel Lohmann's article "Use member functions for C-style callbacks and threads - a general solution."

6.2: How do I share a global variable among my .CPP files? (top)

First, in one of your .CPP files (and only one) declare the variable at global scope (that is, outside of all function and class definitions). For example:

  int g_volume;

Then in a header file that is included in all .CPP files - such as stdafx.h - add an extern declaration:

  extern int g_volume;

The extern keyword tells the compiler that g_volume is an int declared in some other .CPP file. If you forget the first step, the linker will give an unresolved external error.

6.3: I have the string representation of a number, say "10235". How do I convert that to an integer? (top)

Use the atoi() or atol() functions, or if the number is floating-point, atof():

char* szNumber = "10235";
int iNum = atoi ( szNumber );     // integer
long lNum = atol ( szNumber );    // long integer
double dNum = atof ( szNumber );  // floating-point

If you need more flexibility, especially if your string is a base other than decimal, use the strtol(), strtoul(), or strtod() functions. Along with accepting strings in any base up to 36, they return a pointer to the first non-number character found, which is helpful if you're parsing a long input string.

char* szNumber = "F33DF4CE~!";
char* pszStopPoint;
long lNum = strtol ( szNumber, &pszStopPoint, 16 );
unsigned long ulNum = strtoul ( szNumber, &pszStopPoint, 16 );
double dNum = strtod ( szNumber, &pszStopPoint, 16 );

After each of those functions, pszStopPoint points at the '~' which was the first non-hexadecimal character found.

MFC questions

7.1: In my MFC program, I'm trying to disable a menu item with EnableMenuItem(), but it doesn't have any effect on the menu. Why? (top)

MFC uses its own system for enabling and disabling menu items and toolbar buttons, which overrides any calls you make to EnableMenuItem(). If you look in the message map of your CMainFrame class, you may see some ON_UPDATE_COMMAND_UI() macros. Those macros control when menu items and toolbar buttons are enabled and disabled.

To add a macro for the menu item you want to disable, go to ClassWizard and click the Message Maps tab. In the Class name combo box, select the class where you want to add the handler (usually CMainFrame is a good choice, but for items that relate to data stored in your document, pick your CDocument-derived class instead). In the Object IDs list, select the command ID of the menu item, then in the Messages list, double-click UPDATE_COMMAND_UI.

In the update handler, call:

  pCmdUI->Enable ( FALSE );

to disable the menu item. Note that if you have a toolbar button with the same command ID, that button will be disabled as well.

See the MSDN pages on CCmdUI and ON_UPDATE_COMMAND_UI for more details.

Links to other FAQs

MFC FAQs

Stingray MFC FAQ

Books about programming

CodeProject article - "Useful Reference Books"

About Michael Dunn

Michael lives in sunny Los Angeles, California, and is so spoiled by the weather that he will probably never be able to live anywhere else. He graduated from UCLA with a math degree in 1995, and immediately landed a job as a QA engineer at Symantec, working on the Norton AntiVirus team. He pretty much taught himself Windows and MFC programming, and in 1999 he designed and coded a new interface for Norton AntiVirus 2000.

He also enjoys his hobbies of playing pinball, bike riding, and the occasional PlayStation or Dreamcast game. (Game currently in the PSX: Wipeout 3.) He is also trying not to forget the languages he's studied: French, Mandarin Chinese, and Japanese.

Click here to visit Michael Dunn's homepage.

[Top] Sign in to vote for this article:     PoorExcellent  

View our sponsorsClick here for Whole Tomato Software - Home of Visual AssistAdvertise on the CodeProject

Hint: For improved responsiveness, use Internet Explorer 4 (or above) with Javascript enabled, choose 'Use DHTML' from the View dropdown and hit 'Set Options'.
 Keyword Filter
 View   Per page   Messages since
New threadMessages 1 to 20 of 20 (Total: 20)[First] [Prev] [Next] [Last]
Subject 
Author 
Date 
  about microsoft agent 2.0 ActiveX
Unconfirmed/Anonymous posting liuchuan 3:17 23 Jul 01 
  Re: about microsoft agent 2.0 ActiveX
 Michael Dunn 3:27 23 Jul 01 
  for e: about microsoft agent 2.0 ActiveX
Unconfirmed/Anonymous posting Anonymous 3:55 23 Jul 01 
  Re: for e: about microsoft agent 2.0 ActiveX
 Michael Dunn 17:48 24 Jul 01 
  learn visual c++
Unconfirmed/Anonymous posting itai 17:01 22 Jul 01 
  Re: learn visual c++
 Christian Graus 22:27 22 Jul 01 
  Re: learn visual c++
 ChrisA 21:44 30 Jul 01 
  STL bugs(?)
Unconfirmed/Anonymous posting bar-cochva 16:30 20 Jul 01 
  Re: STL bugs(?)
 Michael Dunn 17:48 20 Jul 01 
  Links to related articles
 Daniel Lohmann 19:40 17 Jul 01 
  Re: Links to related articles
 Michael Dunn 20:27 17 Jul 01 
  8. How can I save and load JPGs, PNGs, or other graphics formats?
 Uwe Keim 2:56 16 Jul 01 
  Re: 8. How can I save and load JPGs, PNGs, or other graphics formats?
 Serge Weinstock 11:34 16 Jul 01 
  Re: 8. How can I save and load JPGs, PNGs, or other graphics formats?
 Christian Graus 19:42 16 Jul 01 
  Re: 8. How can I save and load JPGs, PNGs, or other graphics formats?
 Serge Weinstock 3:57 17 Jul 01 
  Re: 8. How can I save and load JPGs, PNGs, or other graphics formats?
 Chris Losinger 12:29 16 Jul 01 
  Re: 8. How can I save and load JPGs, PNGs, or other graphics formats?
 Christian Graus 19:46 16 Jul 01 
  Re: 8. How can I... - FreeImage
 Andreas 3:24 18 Jul 01 
  Include Stingray's MFC FAQ?
 Uwe Keim 2:50 16 Jul 01 
  Re: Include Stingray's MFC FAQ?
 Michael Dunn 13:07 16 Jul 01 
Last Visit: 12:00 Friday 1st January, 1999[First] [Prev] [Next] [Last]
Home >> C++ / MFC / STL >> Unedited Reader Contributions
Advertise on The Code Project
Article content copyright Michael Dunn, 2001
everything else © CodeProject, 1999-2001.