How to debug menu options

Hello,

I created a test program in Visual Studio 2010 C++ MFC Application solution using the wizard and selected the Context-sensitive Help (HTML) option on the Advanced Features tab.

When I Start with debugging, how do I stop in the debugger right after when the "Help/Help Topics" is selected?

I would like to stop it right after the selection is made so that I can see what it does from then on.

Any help would be gratefully appreciated.

Thanks,
Tony
closed account (E0p9LyTq)
Before you start your debug session you set a breakpoint at the source code line you want the debugger to stop at:

https://blogs.msdn.microsoft.com/visualstudio/2015/08/11/introduction-to-debugging/
Hello FurryGuy.

Thanks for your reply.

I didn't know that you had made this reply until today. I can't find the option for these forums to be notified when someone replies to my posts.

I guess I didn't explain my problem with the proper detail. I do know how to set breakpoints.

I am specifically looking for exactly where to put the breakpoint in my program to debug the statements executed when a menu option is selected by the user.

Thanks,
Tony
My crystal ball is broken, but I would say somewhere after the user enters his/her selection, then single step through the area in question.

That's my problem.

Where in the program does the code get executed right after a user selection is made?

Thanks,
Tony
closed account (E0p9LyTq)
You can see your source code, we can't.

Where I would set a breakpoint is in the MFC function that processes the WM_COMMAND message for the menu selection.
I just did a search of the entire solution for "WM_COMMAND" and it did not find anything.

Thanks,
Tony
closed account (E0p9LyTq)
WM_COMMAND is a Win32 message, not something in MFC. MFC encapsulates the mundane details of Win32 in C++ classes.

I don't know of any online tutorials for learning MFC, there is one book (it's old but still good) I could recommend to assist you in learning MFC:

Programming Windows with MFC, Second Edition
https://www.amazon.com/Programming-Windows-Second-Jeff-Prosise/dp/1572316950/
That looks like a good book. I will probably buy it.

However, I don't think it's going to explain where to set a breakpoint in my program to debug a help menu selection option.

Thanks,
Tony
closed account (E0p9LyTq)
When you understand the basics of how MFC does GUI app management, including menus and menu selection, setting a breakpoint and debugging will become almost a "oh, DUH" thing.

Just me, but if you don't have even a basic grasp of how an "old school" Win32 C SDK program works, trying to learn/understand MFC can be much more difficult. MFC wraps the Win32 API in C++ classes and functions, but only as a very thin layer in many respects.

You understand this?:
1
2
3
4
5
6
#include <iostream>

int main()
{
   std::cout << "Hello World!\n";
}


Adding a Win32 GUI requires this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
/* a minimal Windows API application skeleton */

#include <windows.h>
#include <tchar.h>

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
   const TCHAR szWinClass[] = TEXT("WinSkeleton");
   const TCHAR szAppTitle[] = TEXT("Skeletal Windows API Application");

   HWND       hwnd;
   MSG        msg;
   WNDCLASSEX wc;

   wc.cbSize = sizeof(WNDCLASSEX);
   wc.hInstance     = hInstance;
   wc.lpszClassName = szWinClass;
   wc.lpfnWndProc   = WndProc;
   wc.style         = CS_HREDRAW | CS_VREDRAW;
   wc.hIcon         = (HICON) LoadImage(NULL, IDI_APPLICATION, IMAGE_ICON, 0, 0, LR_SHARED);
   wc.hIconSm       = NULL;
   wc.hCursor       = (HCURSOR) LoadImage(NULL, IDC_ARROW, IMAGE_CURSOR, 0, 0, LR_SHARED);
   wc.lpszMenuName  = NULL;
   wc.cbClsExtra    = 0;
   wc.cbWndExtra    = 0;
   wc.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);

   if (0 == RegisterClassEx(&wc))
   {
      MessageBox(NULL, TEXT("Couldn't Register the Window Class!"), TEXT("ERROR"), MB_OK | MB_ICONERROR);
      return FALSE;
   }

   hwnd = CreateWindow(szWinClass, szAppTitle,
                       WS_OVERLAPPEDWINDOW,
                       CW_USEDEFAULT, CW_USEDEFAULT,
                       CW_USEDEFAULT, CW_USEDEFAULT,
                       NULL, NULL, hInstance, NULL);

   if (NULL == hwnd)
   {
      MessageBox(NULL, TEXT("Couldn't Create the Main Window!"), TEXT("ERROR"), MB_OK | MB_ICONERROR);
      return FALSE;
   }

   ShowWindow(hwnd, nShowCmd);
   UpdateWindow(hwnd);

   while (GetMessage(&msg, NULL, 0, 0) != 0)
   {
      TranslateMessage(&msg);
      DispatchMessage(&msg);
   }

   return (int) msg.wParam;
}


LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
   HDC         hdc;
   PAINTSTRUCT ps;
   RECT        rect;
   TCHAR       test[] = TEXT("Hello World! From a Windows App!");

   switch (message)
   {
   case WM_PAINT:
      hdc = BeginPaint(hwnd, &ps);
      GetClientRect(hwnd, &rect);
      DrawText(hdc, test, -1, &rect, DT_SINGLELINE | DT_NOCLIP | DT_CENTER | DT_VCENTER);
      EndPaint(hwnd, &ps);
      return 0;

   case WM_DESTROY:
      PostQuitMessage(0);
      return 0;
   }

   return DefWindowProc(hwnd, message, wParam, lParam);
}


The MFC method:
MFC.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// MFC.h : main header file for the MFC application
//
#pragma once

// derive the necessary classes

// this is the application class
class CTheApp : public CWinApp
{
public:
   virtual BOOL InitInstance();
};


class CMainWnd : public CFrameWnd
{
public:
   CMainWnd();

protected:
   afx_msg void OnPaint();
   DECLARE_MESSAGE_MAP()
};

extern CTheApp  theApp;


MFC.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
// MFC.cpp : Defines the class behaviors for the application.
//
#include "stdafx.h"
#include "MFC.h"

// instantiate the application
CTheApp  theApp;


// initialize the application
BOOL CTheApp::InitInstance()
{
   m_pMainWnd = new CMainWnd;

   m_pMainWnd->ShowWindow(m_nCmdShow);
   m_pMainWnd->UpdateWindow();

   return TRUE;
}


// construct the main window
CMainWnd::CMainWnd()
{
   Create(NULL, _T("The MFC Hello Application"));
}


// the application's message map
BEGIN_MESSAGE_MAP(CMainWnd, CFrameWnd)
   ON_WM_PAINT()
END_MESSAGE_MAP()


void CMainWnd::OnPaint()
{
   CPaintDC dc(this);

   CRect rect;
   GetClientRect(&rect);

   dc.DrawText(_T("Hello, MFC!!!"), -1, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
}
You have to look for sth. like this:
1
2
3
BEGIN_MESSAGE_MAP(CMFCApplication1App, CWinApp)
	ON_COMMAND(ID_APP_ABOUT, &CMFCApplication1App::OnAppAbout)
END_MESSAGE_MAP()


and also for a class derived from CWinApp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class CMFCApplication1App : public CWinApp
{
public:
	CMFCApplication1App();


// Overrides
public:
	virtual BOOL InitInstance();
	virtual int ExitInstance();

// Implementation

public:
	afx_msg void OnAppAbout();
	DECLARE_MESSAGE_MAP()
};


The example was created with the app wizard and implements the menu About command. Help should be similar probably called afx_msg void OnHtmlHelp();
Thomas,

Yes, I have this in my HasHelp.cpp file:

1
2
3
4
5
6
7
8
BEGIN_MESSAGE_MAP(CHasHelpApp, CWinAppEx)
	ON_COMMAND(ID_APP_ABOUT, &CHasHelpApp::OnAppAbout)
	// Standard file based document commands
	ON_COMMAND(ID_FILE_NEW, &CWinAppEx::OnFileNew)
	ON_COMMAND(ID_FILE_OPEN, &CWinAppEx::OnFileOpen)
	// Standard print setup command
	ON_COMMAND(ID_FILE_PRINT_SETUP, &CWinAppEx::OnFilePrintSetup)
END_MESSAGE_MAP()


and this in my MainFrm.cpp file:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWndEx)
	ON_WM_CREATE()
	// Global help commands
	ON_COMMAND(ID_HELP_FINDER, &CMDIFrameWndEx::OnHelpFinder)
	ON_COMMAND(ID_HELP, &CMDIFrameWndEx::OnHelp)
	ON_COMMAND(ID_CONTEXT_HELP, &CMDIFrameWndEx::OnContextHelp)
	ON_COMMAND(ID_DEFAULT_HELP, &CMDIFrameWndEx::OnHelpFinder)
	ON_COMMAND(ID_WINDOW_MANAGER, &CMainFrame::OnWindowManager)
	ON_COMMAND(ID_VIEW_CUSTOMIZE, &CMainFrame::OnViewCustomize)
	ON_REGISTERED_MESSAGE(AFX_WM_CREATETOOLBAR, &CMainFrame::OnToolbarCreateNew)
	ON_COMMAND_RANGE(ID_VIEW_APPLOOK_WIN_2000, ID_VIEW_APPLOOK_WINDOWS_7, &CMainFrame::OnApplicationLook)
	ON_UPDATE_COMMAND_UI_RANGE(ID_VIEW_APPLOOK_WIN_2000, ID_VIEW_APPLOOK_WINDOWS_7, &CMainFrame::OnUpdateApplicationLook)
	ON_WM_SETTINGCHANGE()
END_MESSAGE_MAP()


and this in the HasHelp.h file:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
// HasHelp.h : main header file for the HasHelp application
//
#pragma once

#ifndef __AFXWIN_H__
	#error "include 'stdafx.h' before including this file for PCH"
#endif

#include "resource.h"       // main symbols


// CHasHelpApp:
// See HasHelp.cpp for the implementation of this class
//

class CHasHelpApp : public CWinAppEx
{
public:
	CHasHelpApp();


// Overrides
public:
	virtual BOOL InitInstance();
	virtual int ExitInstance();

// Implementation
	UINT  m_nAppLook;
	BOOL  m_bHiColorIcons;

	virtual void PreLoadState();
	virtual void LoadCustomState();
	virtual void SaveCustomState();

	afx_msg void OnAppAbout();
	DECLARE_MESSAGE_MAP()
};

extern CHasHelpApp theApp;


Also, I did a find in the entire solution and it did not find "OnHtmlHelp" anywhere.

Thanks,
Tony
closed account (E0p9LyTq)
Your derived CMainFrame class has nothing to do with how your application processes any of your app's menu items, that is done by your derived CWinApp class.

You wrote no class function to call the Windows HtmlHelp function. You can't debug a function/class method you haven't written.

The MFC wizard doesn't add that menu item, you have to add it yourself.
closed account (E0p9LyTq)
Just my opinion:

Using the Visual Studio wizards are only helpful when you already have a good grasp of how to program, be it C/C++ console apps, Win32 GUI or MFC apps. If you are using the wizards to help you learn, it will be quite a roadblock to you understanding.
FurryGuy,

The menu option "Help/Help Topics" works. When I click on it, it gives a HTML help screen.

I just need to know where in my program can I put a breakpoint to figure out what it is doing.

Thanks,
Tony
closed account (E0p9LyTq)
Your OnHelp() method in your CMainFrm.cpp file.

Posting the code in that method here might be helpful so others could help you, if it isn't too long.

Putting OnHelp() might work in your CMainFrame derived class, but it isn't the best place to put that functionality.
FurryGuy,

There is no "OnHelp" method anywhere in the solution.

Thanks,
Tony
closed account (E0p9LyTq)
and this in my MainFrm.cpp file:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWndEx)
	ON_WM_CREATE()
	// Global help commands
	ON_COMMAND(ID_HELP_FINDER, &CMDIFrameWndEx::OnHelpFinder)
	ON_COMMAND(ID_HELP, &CMDIFrameWndEx::OnHelp)
	ON_COMMAND(ID_CONTEXT_HELP, &CMDIFrameWndEx::OnContextHelp)
	ON_COMMAND(ID_DEFAULT_HELP, &CMDIFrameWndEx::OnHelpFinder)
	ON_COMMAND(ID_WINDOW_MANAGER, &CMainFrame::OnWindowManager)
	ON_COMMAND(ID_VIEW_CUSTOMIZE, &CMainFrame::OnViewCustomize)
	ON_REGISTERED_MESSAGE(AFX_WM_CREATETOOLBAR, &CMainFrame::OnToolbarCreateNew)
	ON_COMMAND_RANGE(ID_VIEW_APPLOOK_WIN_2000, ID_VIEW_APPLOOK_WINDOWS_7, &CMainFrame::OnApplicationLook)
	ON_UPDATE_COMMAND_UI_RANGE(ID_VIEW_APPLOOK_WIN_2000, ID_VIEW_APPLOOK_WINDOWS_7, &CMainFrame::OnUpdateApplicationLook)
	ON_WM_SETTINGCHANGE()
END_MESSAGE_MAP()


All of your Help functionality is being passed back to the MFC framework for default processing. There is nothing to debug, at least no code in your program you can set a breakpoint.
OK. So it can't be done.

I'm sorry for putting you through all this. I learned that a help menu option can't be debugged.

Thanks for all of your help.

Tony
closed account (E0p9LyTq)
Don't be sorry, I learned something I didn't know previously. :)

This version of MFC does add HTMLHelp functionality, just very BASIC help. The last time I did any MFC app creation was back with Visual Studio 6.0. Then you had to add any Help menu item functionality on your own as I recall.

I don't use MFC much, I prefer using the Win32 API.
Topic archived. No new replies allowed.