If you compile SHOWDIB after all of the previous changes, you'll find that, although the menus work, the menu items are not properly updated. For example, clipboard-related commands are all enabled, and a number of toggle commands at the top of the Options menu should be checked but aren't.
The problem stems from the original decision to override WindowProc in the view class. That was the correct decision, since other steps towards MFC will be much easier than if the override was done in another class, such as the main frame window class. But the view's WindowProc currently contains handler code for the WM_INITMENU message, although, as shown by the Spy++ tool (with Visual C++), the view window never receives that message; the main frame window does, since it owns the menus.
Various approaches are possible (as is often the case under the great flexibility of MFC). The easiest way is to also override WindowProc for class CMainFrame, just to handle this one message case. While it's a bit ugly to have to do multiple function overrides just to get all of SHOWDIB's message handling code to work minimally (you already have OnDraw and OnCmdMsg, as well as the first WindowProc), it's the quickest solution, so it's the one shown here.
For SHOWDIB, override CWnd::WindowProc in class CMainFrame. Then copy all of the code for the WM_INITMENU case into this override.
The CMainFrame::WindowProc override looks like this:
LRESULT CMainFrame::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
// TODO: Add your specialized code here and/or call the base class
if (message == WM_INITMENU)
{
// TODO: Add your message handler code here
/* check/uncheck menu items depending on state of related
* flags
*/
::CheckMenuItem((HMENU)wParam, IDM_UPDATECOL,
(bUpdateColors ? MF_CHECKED : MF_UNCHECKED));
::CheckMenuItem((HMENU)wParam, IDM_TRANSPARENT,
(wTransparent == TRANSPARENT ? MF_CHECKED : MF_UNCHECKED));
::CheckMenuItem((HMENU)wParam, IDM_DIBSCREEN,
(bDIBToDevice ? MF_CHECKED : MF_UNCHECKED));
::CheckMenuItem((HMENU)wParam, IDM_NOUGLY,
(bNoUgly ? MF_CHECKED : MF_UNCHECKED));
::CheckMenuItem((HMENU)wParam, IDM_MEMORYDIB, MF_CHECKED);
::EnableMenuItem((HMENU)wParam, IDM_PASTEDIB,
::IsClipboardFormatAvailable(CF_DIB)?MF_ENABLED:MF_GRAYED);
::EnableMenuItem((HMENU)wParam, IDM_PASTEDDB,
::IsClipboardFormatAvailable(CF_BITMAP)?MF_ENABLED:MF_GRAYED);
::EnableMenuItem((HMENU)wParam, IDM_PASTEPAL,
::IsClipboardFormatAvailable(CF_PALETTE)?MF_ENABLED:MF_GRAYED);
::EnableMenuItem((HMENU)wParam, IDM_PRINT,
bLegitDraw ? MF_ENABLED : MF_GRAYED);
::EnableMenuItem((HMENU)wParam, IDM_SAVE,
bLegitDraw ? MF_ENABLED : MF_GRAYED);
::EnableMenuItem((HMENU)wParam, IDM_COPY,
bLegitDraw ? MF_ENABLED : MF_GRAYED);
::EnableMenuItem((HMENU)wParam, IDM_ANIMATE0,
bLegitDraw ? MF_ENABLED : MF_GRAYED);
::EnableMenuItem((HMENU)wParam, IDM_ANIMATE5,
bLegitDraw ? MF_ENABLED : MF_GRAYED);
::EnableMenuItem((HMENU)wParam, IDM_ANIMATE50,
bLegitDraw ? MF_ENABLED : MF_GRAYED);
::EnableMenuItem((HMENU)wParam, IDM_ANIMATE100,
bLegitDraw ? MF_ENABLED : MF_GRAYED);
::EnableMenuItem((HMENU)wParam, IDM_ANIMATE200,
bLegitDraw ? MF_ENABLED : MF_GRAYED);
::EnableMenuItem((HMENU)wParam, IDM_ANIMATE201,
bLegitDraw ? MF_ENABLED : MF_GRAYED);
::EnableMenuItem((HMENU)wParam, IDM_STEALCOL,
bLegitDraw ? MF_ENABLED : MF_GRAYED);
}
return CFrameWnd::WindowProc(message, wParam, lParam);
}
Notice that the Windows API calls have been disambiguated with the scope resolution operator. There's no need for calls to GetSafeHwnd or GetSafeHdc because none of the function calls pass an HWND or an HDC. You also need the following include directive in file MAINFRM.CPP:
#include "showdib.h"
This approach preserves your investment in the original SHOWDIB code and takes only a moment using ClassWizard and a bit of cut and paste. The better, but more time-consuming, alternative is to go all the way and use MFC's mechanism for updating menu commands, as described in Using MFC Menu Update Handlers.