Home > Articles > Programming > Windows Programming

Frequently Asked Questions: Visual C++ .NET

Davis Chapman answers frequently asked questions about Visual C++ .NET, including how to change the title on the message box, how the debugger works, and how to customize toolbars.
This article is derived from Sams Teach Yourself Visual C++ .NET in 21 Days, by Davis Chapman (Sams Publishing, 2001).
This chapter is from the book

Question: How can I change the title on the message box instead of using the application name?

Answer: By default, the message box window uses the application name as the window title. You can change this by adding a second text string to the MessageBox function call. The first string is always the message to be displayed, and the second string is used as the window title. For example, the OnClickedHello function would look like:

// Say hello to the user
MessageBox("Hello. This is my first Visual C++ Application!", 
      "My First Application");

Question: How does the debugger work? How does it know where in my code the application execution is?

Answer: In a debug build, the compiler adds extra information that doesn't get executed when running the application. This information is mixed in with the executable code. The information specifies what source code file and line of code each set of machine instructions correlates to. It also contains information about each of the variables in the code and where each of them is stored in memory while the application is running. This is all information that the debugger uses to display the correct code as you are stepping through your application.

Question: I don't want my breakpoint to be triggered each time that my application hits it. Is there some way of getting it to trigger only when certain values are reached?

Answer: If you open the Breakpoints pane, you can view the properties of each of your breakpoints. Within the Breakpoint Properties dialog box, you can place conditions on the breakpoint, such as stopping only when a certain variable is equal to a specific value.

Question: When I specified the object IDs of the controls on the window, three controls had the same ID—IDC_STATIC. These controls were the text at the top of the window and the two group boxes. The other two static text controls started out with this same ID until I changed them. How can these controls have the same ID, and why did I have to change the ID on the two static texts where I did change them?

Answer: All controls that don't normally have any user interaction, such as static text and group boxes, are, by default, given the same object ID. This works fine as long as your application doesn't need to perform any actions on these controls. If you do need to interact with one of these controls, as you did with the static text prompts for the edit box and the combo box, you need to give that control a unique ID. In this case, you needed the unique ID to be able to retrieve the control object so that you could enable or disable and show or hide the control. You also need to assign it a unique ID if you want to attach a variable to the control so that you can dynamically alter the text on the control.

The application behaves in a somewhat unpredictable way if you try to alter any of the static controls that share the same ID. As a general rule of thumb, you can allow static controls to share the same object ID if you aren't going to alter the controls at all. If you need to perform any interaction with the controls, you need to assign each one a unique object ID.

Question: Is there any way to manipulate the controls other than retrieving the control objects using their object IDs?

Answer: Using the Add Member Variable Wizard, you can declare variables for your controls by specifying Control for the variable category. This basically gives you an variable that is the control's MFC class, providing you with a direct way of altering and interacting with the control. You can then call all CWnd class functions on the control, as you did to enable or disable and show or hide the controls in your application. Or, you can call the control class methods, enabling you to do things in the code that are specific to that type of control. For example, if you add another variable to the combo box control and specify that it's a Control category variable, you can use it to add items to the drop-down list on the control.

Question: How can you tell whether the Shift or Ctrl keys are being held down when you receive the WM_KEYDOWN message?

Answer: You can call another function, ::GetKeyState, with a specific key code to determine whether that key is being held down. If the return value of the ::GetKeyState function is negative, the key is being held down. If the return value is not negative, the key isn't being held down. For instance, if you want to determine whether the Shift key is being held down, you can use this code:

if (::GetKeyState(VK_SHIFT) < 0)
  MessageBox("Shift key is down!");

A number of virtual key codes are defined in Windows for all the special keys. These codes let you look for special keys without worrying about OEM scan codes or other key sequences. You can use these virtual key codes in the ::GetKeyState function and pass them to the OnKeyDown function as the nChar argument. Refer to the Visual C++ documentation for a list of the virtual key codes.

Question: What's the interval range that I can set for timers in my applications?

Answer: The available range that you can set for timers in your applications is around 55 milliseconds on the short end to 232 – 1 milliseconds, or around 49 1/2 days, on the long end.

Question: Is there any way to trigger my application to perform some work when it's idle rather than use a timer to trigger the work when I think my app might be idle?

Answer: Yes, there is. All Windows applications have an OnIdle function that can be used to trigger idle processing.

Question: What happens if I specify two or more button combinations in the same MessageBox function call?

Answer: Your application compiles just fine, but when the MessageBox function is called, sometimes nothing happens and sometimes one of the button combinations selected is displayed. Keep in mind that only one set of buttons will be displayed, so there is no reason to OR two or more sets of buttons together.

Question: How can I integrate the File Open dialog box into my application where it opens in a specific directory that I specify?

Answer: The CFileDialog class has a public property called m_ofn. This property is a structure that contains numerous attributes of the File Open dialog box, including the initial directory. This structure is defined as the OPENFILENAME structure in Listing 1.

Listing 1: The OPENFILENAME Structure

typedef struct tagOFN { // ofn 
  DWORD     lStructSize; 
  HWND     hwndOwner; 
  HINSTANCE   hInstance; 
  LPCTSTR    lpstrFilter; 
  LPTSTR    lpstrCustomFilter; 
  DWORD     nMaxCustFilter; 
  DWORD     nFilterIndex; 
  LPTSTR    lpstrFile; 
  DWORD     nMaxFile; 
  LPTSTR    lpstrFileTitle; 
  DWORD     nMaxFileTitle; 
  LPCTSTR    lpstrInitialDir; 
  LPCTSTR    lpstrTitle; 
  DWORD     Flags; 
  WORD     nFileOffset; 
  WORD     nFileExtension; 
  LPCTSTR    lpstrDefExt; 
  DWORD     lCustData; 
  LPOFNHOOKPROC lpfnHook; 
  LPCTSTR    lpTemplateName; 
} OPENFILENAME; 

You can set any of these attributes before calling the DoModal class method to control the behavior of the File Open dialog box. For instance, if you set the starting directory to C:\Temp before calling the DoModal method, as in Listing 2, the File Open dialog box opens in that directory.

Listing 2: The Revised OnBnClickedBfileopen Function

void CDialogsDlg::OnBnClickedBfileopen(void)
{
  // TODO: Add your control notification handler code here
  CFileDialog ldFile(TRUE);

  // Set the current directory
  ldFile.m_ofn.lpstrInitialDir = "C:\\Temp\\";
  // Show the File Open dialog and capture the result
  if (ldFile.DoModal() == IDOK)
  {
    // Get the file name selected
    m_strResults = ldFile.GetFileName();
    // Update the dialog
    UpdateData(FALSE);
  }
}

Question: Do I have to give my menu items the same names that everyone else uses? For example, a lot of applications use File and Help. Can I name my menus something else?

Answer: You can name your top-level menus anything you want. However, there are accepted menu name conventions that place all file-oriented functionality under a menu labeled File and all help-related functionality under a menu labeled Help. If you have a menu with entries such as Broccoli, Corn, and Carrots, you will probably want to call the menu Vegetables, although an equally valid label would be Food or Plants. In general, if you want to make your application easy for your users to learn, you will want to use menu labels that make sense for the entries on the pull-down portion of the menu.

Question: How can I limit the fonts in my list to just the TrueType fonts?

Answer: You can check the nFontType argument to your callback function to determine the font type. For instance, if you want to include only TrueType fonts in your list of fonts, you modify your callback function to mask the nFontType argument with the TRUETYPE_FONTTYPE constant and check to see if the resulting value equals the TRUETYPE_FONTTYPE value, as in the following listing:

int CALLBACK EnumFontFamProc(LPENUMLOGFONT lpelf,
LPNEWTEXTMETRIC lpntm, DWORD nFontType, long lParam)
{
  // Create a pointer to the dialog window
  CTextFontsDlg* pWnd = (CTextFontsDlg*) lParam;

  // Limit the list to TrueType fonts
  if (nFontType & TRUETYPE_FONTTYPE)
  {
    // Add the font name to the list box
    pWnd->m_ctlFontList.AddString(
            lpelf->elfLogFont.lfFaceName);
  }
  // Return 1 to continue font enumeration
  return 1;
}

Question: Why do I need to specify both a pen and a brush if I want to display just one?

Answer: You are always drawing with both when you draw any object that's filled in. The pen draws the outline, and the brush fills in the interior. You can't choose to use one or the other; you have to use both. If you only want to display one, you need to take special steps.

Question: Why do all of the pen styles become solid when I increase the pen width above 1?

Answer: When you increase the pen width, you are increasing the size of the dot that's used to draw with. When you first try to draw by capturing each spot that the mouse covers, all you draw are a bunch of dots. Well, after you increase the size of the dots that you are drawing the line with, the gaps between the dots are filled in from both sides, providing an unbroken line.

Question: In some applications, toolbars have the option of showing text, as in Internet Explorer. How can I add text to my toolbar buttons?

Answer: Unfortunately, the toolbar designer provides no way of adding text to the toolbar buttons. This means that you have to add the text to the buttons in your application code, similar to specifying that all the color toolbar buttons should behave as radio buttons. Use the SetButtonText function to set the text on each toolbar button individually. This function takes two arguments: the button's index number and the button's text. If you really want to place text on the toolbar buttons, you also have to resize the toolbar to allow room for the text to be displayed.

Question: How can I set the text in the first section of the status bar, other than by using menu and toolbar prompts?

Answer: You can use SetWindowText to set the text in the first pane of the status bar. As a default setting, the first pane is a separator that automatically expands to fill the width of the status bar with the other panes right-justified on the bar. The SetWindowText function, called on the status bar variable, sets the text in the first pane only. If you want to set the text in any other pane, at any time other than in the ON_UPDATE_COMMAND_UI event handler, you can use the SetPaneText function. There are two ways that you can set the text in the main part of the status bar. The first is:

CString myString = "This is my string"
m_wndStatusBar.SetWindowText(myString);

The other method is:

CString myString = "This is my string"
m_wndStatusBar.SetPaneText(0, myString);

Question: Why do I need to change the version number in the IMPLEMENT_SERIAL macro if I change the Serialize function in the record custom class?

Answer: Whether you need to increment the version number depends on the type of change you make. For example, if you add a calculated field in the record class and you add the code to calculate this new variable from the values that you read in the variables from the CArchive object, you don't really need to increment the version number because the variables and order of the variables that you are writing to and reading from the archive didn't change. However, if you add a new field to the record class and add the new field into the I/O stream being written to and read from the CArchive object, what you are writing to and reading from the archive will have changed, and you do need to increment the version number. If you don't increment the version number, reading files created using the previous version of your application will result in an "Unexpected File Format" message instead of the file being read. Once you increment the version number and you read a file written with the old version number, you get the same message, but you have the option of writing your own code to handle the exception and redirecting the archive to a conversion routine to convert the file to the new file format.

Question: When do I need to recompile the applications that use my DLLs?

Answer: Whenever you change any exported function calls. Changing, adding, or removing arguments to any of these functions would mean that you need to recompile the applications that use the DLL. If you are working with an MFC extension DLL, the applications that uses the DLL needs to be recompiled if the public interface for the exported classes changes or a new function or variable is added or removed. It doesn't matter that the application isn't using any changed functions; it's still good practice to recompile the applications, just to be sure.

Question: Why is Print Preview not included on the default menus when I choose CHtmlView as the base class for my view class?

Answer: The printing for the CHtmlView class is performed by the browser, not the view class. You don't have Print Preview because the browser doesn't support it.

Question: How can I get the HTML source code from the browser so that I can see or edit it?

Answer: The CHtmlView class has a member function, GetSource, that takes a CString variable as its only parameter. This CString parameter is populated with the HTML source code.

Question: How do Internet applications work?

Answer: Most Internet applications have a script of messages that are passed back and forth. The messages consist of a command and the data that needs to accompany that command. The server reads the command and processes the data appropriately, sending back a status code to let the client know the success or failure of the command. If you want to learn more about how Internet applications do this, several books cover this subject area in detail. You can also find the RFC documents that specify the communication protocol for various standardized applications at the Web site for the Internet Engineering Task Force at http://www.ietf.org. RFC documents are the specification documents for various applications, file formats, and other standards that are used throughout the Internet.

Question: How does a server application handle a large number of simultaneous connections from clients?

Answer: With a full-strength server, connection sockets aren't declared as class variables. The server instead uses some sort of dynamic allocation of sockets in an array or link list to create sockets for the clients as the connection requests come in. Another approach often taken by servers is to spin off a separate thread for each connection request. This allows the application to have a single socket connection per thread, making it much easier to keep track of the sockets. In any case, server applications don't normally have a single connection socket variable. Keep in mind, however, that if too many threads are running, the number of context switches will degrade server performance significantly, so the separate thread per connection may not be an appropriate approach for a heavy-load server application.

Question: How can I mix managed and unmanaged C++ in my applications?

Answer: In the same way that you use the project properties to mark the entire MFC project to be compiled for the CLR, you can mark individual files in the project. This enables you to mix parts of your application, marking some components to be managed while keeping others as unmanaged. Usually, you'll want to add wrapper components in separate managed files, providing access to the unmanaged components by other CLR objects and applications.

Question: When adding the parameters for the COM interface method, what were the check boxes (in, out, retval) above where the parameters were added used for?

Answer: Those check boxes added the direction for each parameter in the IDL definition of the COM interface. If you examine the IDL language in the header file for the COM interface class, you'll find that the interface definition of the method contains [in] in front of the parameters that you checked the in box on, and [out] on the parameters that you checked the out box on. This specifies the direction and purpose for each of these parameters in the method. [in] specifies that a parameter is passed in to the method. [out] specifies that the parameter is replaced with a result value in the method that needs to be returned to the calling function. You can have both [in] and [out] specified for a parameter, signaling that the parameter's value is imported both when the method is being called and when returning from the method. If you checked the retval box, this parameter signals that this parameter will be returned as the method result instead of the success or failure indicator.

Question: In the unmanaged C++ client, why couldn't I put the __gc modifier on the managed class?

Answer: The managed class in an unmanaged client has to be accessible by the unmanaged code in the application. When a managed class is marked for garbage collection, it can't be accessed by any unmanaged code. The reverse situation is seen when you have a managed, garbage-collected class accessing an unmanaged class. It seems that managed, garbage-collected objects can reach outside the managed sandbox to access unmanaged objects. It's just that the garbage-collected objects are located on the CLR-managed heap, which can't be accessed from the outside. But objects on the managed CLR heap can use non–garbage-collected pointers to access objects on the outside.

InformIT Promotional Mailings & Special Offers

I would like to receive exclusive offers and hear about products from InformIT and its family of brands. I can unsubscribe at any time.

Overview


Pearson Education, Inc., 221 River Street, Hoboken, New Jersey 07030, (Pearson) presents this site to provide information about products and services that can be purchased through this site.

This privacy notice provides an overview of our commitment to privacy and describes how we collect, protect, use and share personal information collected through this site. Please note that other Pearson websites and online products and services have their own separate privacy policies.

Collection and Use of Information


To conduct business and deliver products and services, Pearson collects and uses personal information in several ways in connection with this site, including:

Questions and Inquiries

For inquiries and questions, we collect the inquiry or question, together with name, contact details (email address, phone number and mailing address) and any other additional information voluntarily submitted to us through a Contact Us form or an email. We use this information to address the inquiry and respond to the question.

Online Store

For orders and purchases placed through our online store on this site, we collect order details, name, institution name and address (if applicable), email address, phone number, shipping and billing addresses, credit/debit card information, shipping options and any instructions. We use this information to complete transactions, fulfill orders, communicate with individuals placing orders or visiting the online store, and for related purposes.

Surveys

Pearson may offer opportunities to provide feedback or participate in surveys, including surveys evaluating Pearson products, services or sites. Participation is voluntary. Pearson collects information requested in the survey questions and uses the information to evaluate, support, maintain and improve products, services or sites, develop new products and services, conduct educational research and for other purposes specified in the survey.

Contests and Drawings

Occasionally, we may sponsor a contest or drawing. Participation is optional. Pearson collects name, contact information and other information specified on the entry form for the contest or drawing to conduct the contest or drawing. Pearson may collect additional personal information from the winners of a contest or drawing in order to award the prize and for tax reporting purposes, as required by law.

Newsletters

If you have elected to receive email newsletters or promotional mailings and special offers but want to unsubscribe, simply email information@informit.com.

Service Announcements

On rare occasions it is necessary to send out a strictly service related announcement. For instance, if our service is temporarily suspended for maintenance we might send users an email. Generally, users may not opt-out of these communications, though they can deactivate their account information. However, these communications are not promotional in nature.

Customer Service

We communicate with users on a regular basis to provide requested services and in regard to issues relating to their account we reply via email or phone in accordance with the users' wishes when a user submits their information through our Contact Us form.

Other Collection and Use of Information


Application and System Logs

Pearson automatically collects log data to help ensure the delivery, availability and security of this site. Log data may include technical information about how a user or visitor connected to this site, such as browser type, type of computer/device, operating system, internet service provider and IP address. We use this information for support purposes and to monitor the health of the site, identify problems, improve service, detect unauthorized access and fraudulent activity, prevent and respond to security incidents and appropriately scale computing resources.

Web Analytics

Pearson may use third party web trend analytical services, including Google Analytics, to collect visitor information, such as IP addresses, browser types, referring pages, pages visited and time spent on a particular site. While these analytical services collect and report information on an anonymous basis, they may use cookies to gather web trend information. The information gathered may enable Pearson (but not the third party web trend services) to link information with application and system log data. Pearson uses this information for system administration and to identify problems, improve service, detect unauthorized access and fraudulent activity, prevent and respond to security incidents, appropriately scale computing resources and otherwise support and deliver this site and its services.

Cookies and Related Technologies

This site uses cookies and similar technologies to personalize content, measure traffic patterns, control security, track use and access of information on this site, and provide interest-based messages and advertising. Users can manage and block the use of cookies through their browser. Disabling or blocking certain cookies may limit the functionality of this site.

Do Not Track

This site currently does not respond to Do Not Track signals.

Security


Pearson uses appropriate physical, administrative and technical security measures to protect personal information from unauthorized access, use and disclosure.

Children


This site is not directed to children under the age of 13.

Marketing


Pearson may send or direct marketing communications to users, provided that

  • Pearson will not use personal information collected or processed as a K-12 school service provider for the purpose of directed or targeted advertising.
  • Such marketing is consistent with applicable law and Pearson's legal obligations.
  • Pearson will not knowingly direct or send marketing communications to an individual who has expressed a preference not to receive marketing.
  • Where required by applicable law, express or implied consent to marketing exists and has not been withdrawn.

Pearson may provide personal information to a third party service provider on a restricted basis to provide marketing solely on behalf of Pearson or an affiliate or customer for whom Pearson is a service provider. Marketing preferences may be changed at any time.

Correcting/Updating Personal Information


If a user's personally identifiable information changes (such as your postal address or email address), we provide a way to correct or update that user's personal data provided to us. This can be done on the Account page. If a user no longer desires our service and desires to delete his or her account, please contact us at customer-service@informit.com and we will process the deletion of a user's account.

Choice/Opt-out


Users can always make an informed choice as to whether they should proceed with certain services offered by InformIT. If you choose to remove yourself from our mailing list(s) simply visit the following page and uncheck any communication you no longer want to receive: www.informit.com/u.aspx.

Sale of Personal Information


Pearson does not rent or sell personal information in exchange for any payment of money.

While Pearson does not sell personal information, as defined in Nevada law, Nevada residents may email a request for no sale of their personal information to NevadaDesignatedRequest@pearson.com.

Supplemental Privacy Statement for California Residents


California residents should read our Supplemental privacy statement for California residents in conjunction with this Privacy Notice. The Supplemental privacy statement for California residents explains Pearson's commitment to comply with California law and applies to personal information of California residents collected in connection with this site and the Services.

Sharing and Disclosure


Pearson may disclose personal information, as follows:

  • As required by law.
  • With the consent of the individual (or their parent, if the individual is a minor)
  • In response to a subpoena, court order or legal process, to the extent permitted or required by law
  • To protect the security and safety of individuals, data, assets and systems, consistent with applicable law
  • In connection the sale, joint venture or other transfer of some or all of its company or assets, subject to the provisions of this Privacy Notice
  • To investigate or address actual or suspected fraud or other illegal activities
  • To exercise its legal rights, including enforcement of the Terms of Use for this site or another contract
  • To affiliated Pearson companies and other companies and organizations who perform work for Pearson and are obligated to protect the privacy of personal information consistent with this Privacy Notice
  • To a school, organization, company or government agency, where Pearson collects or processes the personal information in a school setting or on behalf of such organization, company or government agency.

Links


This web site contains links to other sites. Please be aware that we are not responsible for the privacy practices of such other sites. We encourage our users to be aware when they leave our site and to read the privacy statements of each and every web site that collects Personal Information. This privacy statement applies solely to information collected by this web site.

Requests and Contact


Please contact us about this Privacy Notice or if you have any requests or questions relating to the privacy of your personal information.

Changes to this Privacy Notice


We may revise this Privacy Notice through an updated posting. We will identify the effective date of the revision in the posting. Often, updates are made to provide greater clarity or to comply with changes in regulatory requirements. If the updates involve material changes to the collection, protection, use or disclosure of Personal Information, Pearson will provide notice of the change through a conspicuous notice on this site or other appropriate way. Continued use of the site after the effective date of a posted revision evidences acceptance. Please contact us if you have questions or concerns about the Privacy Notice or any objection to any revisions.

Last Update: November 17, 2020