       

             Windows:  . 
    4,      ,   
 ,  ,    .   
    ,     
  ,     .  , 
        Windows,   
Windows 95.          
     . 

    395 

             : 
  .      
      . ,     
  ,       , 
  MFC.      ,   
     .    
    . 

        

          .  
MFC-    ,    
,    ,      . 
      ,    
.         
,  :     .  1 
           i 
   .  ,    
- i .  ,     
        . 
    ,  ,  ,       
  ,         MFC.  
:       ,   
MFC.       ,    
 ;     .    
  ;      .  , 
    |   MFC.      
 - | ,      
  .        ; 

         

           
WM_INITMENUPOPUP.     MFC  
     .   
,        .  
 -      ,   
 . 
      ,   MFC,  
,     .    
 :    ,     
   ON_COMMAND(),  ,   
,     ,  .  
  ,    :    
        - 
 ON_COMMAND(),      .  
,  ,     ,   
    . 

    396                                    MFC:   

     ,   ,   ,  
    ,    
    . ,  - 
      ,     
,          
ON_COMMAND().        
  ,    ,     . 
           .  
     m_pAutoMenuEnable  
CFrameWnd  FALSE.   ,     , 
  .  ,     
    .     
,    ,  ,   . 

       

         .   
   .      , 
  ,      
ON_UPDATE_COMMAND_UI().     . 
     ON_UPDATE_COMMAND_UI()   : 

    ON_UPDATE_COMMAND_UI{ID, Handler} 

      ID     . 
 Handler     .  
     : 

    afx_msg void Handler(CCmdUI *UIOb}; 

            CCmdUI. CCmdUI   
 ,       
   .       MFC, ..  
   CObject.       
   .  CCmdUI   , 
    .      
().   : 

    virtual void CCmdUI::Enable(BOOL OnOff=TRUE) ; 

         .   On Off 
  ,    .  ,   On Off 
 ,    . 
     CCmdUI   ,    
         .  
    . 
           ,   
    .    
       . 

    15.                                             397 

    ,         
 .    ,     ,  
   ,   MFC. 
    :        
ON_COMMAND()    .    
,    .     
  . 

      

        Windows-     
  ,       
          
,    . ,    
  File    ,     
- j  .        
 - '' ,   ,        C++. 
,  ;       , 
  ; .    ,   
   |   ,   
  .        ' 
     Windows   API-,    . 
     .    ;  
MFC    .      ; . 

        

              
 InsertMenuO,   : 
    BOOL CMenu::InsertMenu(UINT Where, UINT Flags, UINT ID^O, LPCSTR 
ItemName=-NULL) ; 
     Where     ,    
 .  ID    .  
    ItemName.     
Where, ID  [temName,    ,    
Flags (. 15.1). 

     15.1.   Flags  InsertMenuO 

                  

    MF_BYCOMMAND       Where    
  .     . 
    MF_BYPOSITION        Where    ,  
   .    .   
      Where   -1. 

    398                                     MFC:   

                  

    MF_CHECKED               . 
    MF_DISABLED           . 
    MF_ENABLED           .     . 
    MF_GRAYED                . 
    MF_HILITE              . 
    MF_MENUBARBREAK           
   .        
 .      . 
    MF_MENUBREAK      To ,   MF_MENUBARBREAK,   
  . 
    MF_OWNERDRAW         . 
    MF_POPL)P                .    
 ID    . 
    MF_SEPARATOR           .    
 ID  ItemName  . 
    MF_STRING                 .   
      IlemName,   ID  
 . 
    MF_UNCHECKED       ,     , . 
    MF_UNHILITE            .    
    . 
    ,    MenuOb     2   
"New Item"   244,    InsertMenu()  
   : 

    MenuOb.InsertMenu(2, MF_BYPOSITION | MF_STRING, 244, "New Item"); 

     InsertMenu()       
     . 
        MFJENABLED  MF_DISABLED (. 15.1).  
,       .    
,      MFC    
. ,      (/), 
     ,    
 CCmdUl::Enable(). 
    :     InsertMenuf),  
     .    
       CMenu::AppendMenu(). 

    75.                                              399 


                                 ' 

           DeleteMenu(),  
i  :                                                          i 

    BOOL CMenu::DeleteMenu(UINT ID, UINT How};                          \ 

        ID.  How   
,      ID.   How 
 MF_BYPOSITION,   ID     
, i        , 
  i     0.   How  
MF_BYCOMMAND, '  ID   .  
DeleteItemQ ,          
 .     ' 

        

           ,   
     .      
  GetMeniiItemCoiintO,   : 

    UINT CMenu::GetMenuItemCount() const; 

          -1   . 

        

     CMenu   ,    
.      EiiableMenuItem(),   
     (/).  
    ,      
    . ,     
  -   ,    
    ,  ,     
  ON_COMMAND().      
        
     ,    
 CCmdUI::Enable(). 
    , , ,   EnableMenuItem()  
,      .   
  .       
 ,      .       
    ,    . 

      CMenu 

          -  CMenu,   
         CMenu,  
 .        .  
       .    
   CMenu    : 

    CMenu(); 

    400                                    MFC:   

        ,       
    . (       
  .) 

         

     ,         
.      (    ) 
 -    ,    .  
          GetMenuQ, 
  : 

    CMenu *CWnd::GetMenu() const.

     ,       CWnd.  
      .    
(      )  NULL. ,  
 GetMenuQ,  ,      
      . 
              
   ,    .    
  GetSubMenuO,    : 

    CMenu *CMenu::GetSubMenu(int Index) const; 

      Index      . 
(    .)      
  NULL   .     . 

        

    ,       ,   
    .      
  .        
,    9.       . 
  Options,   Graphics.   Options  , 
    .   Graphics   
   .    
        
    Options.    Reset,    
     .    
  . 15.1. 

    15.                                             401 


    . 15.1.       

         : 
    ; DYNMENU.RC 
    #include <afxres.h> 
    #include "ids.h" 
    DynMenu MENU 
    { 
    POPUP "SOptions" 
    { 
    MENUITEM "SAdd Item\tF2", IDM_ADDITEM 
    MENUITEM "&Delete Item\tF3", IDM_DELITEM 
    MENUITEM "E&xit\tF7", IDM_EXIT 
    } 
    POPUP "SGraphics" 
    ( 
    MENUITEM "&Lines\tF4", IDM_LINES 
    MENUITEM "SRectangles\tF5", IDM_RECTANGLES 
    MENUITEM "&Ellipses\tF6", IDM_ELLIPSES 
    ) 
    MENUITEM "SHelp", IDM_HELP 
    } 
    DynMenu ACCELERATORS 
    ( 


    402                                    MFC:   


    VK_F1, IDM_HELP, VIRTKEY 
    VK_F2, IDM_ADDITEM, VIRTKEY 
    VK__F3, IDM_DELITEM, VIRTKEY 
    VK_F4, IDM_LINES, VIRTKEY 
    VK_F5, IDM_RECTANGLES, VIRTKEY 
    VK_F6, IDM_ELLIPSES, VIRTKEY 
    VK_F7, IDM_EXIT, VIRTKEY 
    ) 
       4'> IDS.H: 
    // IDS.H 
    ftdefine IDM_LINES       100 
    ftdefine IDM_RECTANGLES 101 
    #define IDM_ELLIPSES    102 
    #define IDM_ADDITEM     103 
    ftdefine IDM_DELITEM     104 
    ftdefine IDM_HELP        105 
    ftdefine IDM_EXIT        106 
    ftdefine IDM_RESET       107 
    ftdefine IDM_DSTINVERT   108 
    ftdefine IDM_SHOWTEXT    109 
       DYNMENU.H,    : 
    // DYNMENU.H 
    //       
    class CMainWin : public CFrameWnd 
    ( 
    CDC m memDC; //  ,   
    //   
    CBitmap m bmp; //    
    CBrush m bkbrush; //     
    //   
    CPen m_RedPen, m_YellowPen, m_GreenPen, m_BluePen; 
    CPen m_01dPen; 
    //     Add Item  Delete Item 
    int m AddActive, m DelActive; 
    public: 
    CMainWin() ; 
    afx msg void OnPaintO; 
    //     
    afx_msg void CMainWin::OnUIAdd(CCmdUI *UI) ; 
    afx_msg void CMainWin::OnUIDel(CCmdUI *UI); 
    afx_msg void OnLinesO; 


    15.                                             403 


    afx_msg void OnRectangles(); 
    afx msg void OnEllipses() ; 
    afx msg void OnReset(); 
    afx msg void OnAddO; 
    afx_msg void OnDeleteO; 
    afx msg void OnExitO; 
    afx msg void OnHelpO; 
    DECLARE_MESSAGE_MAP() 
    }; 
    
    //      
    class CApp : public CWinApp 
    ( 
    public: 
    BOOL Initlnstance () ; 
    }; 
        : 
    //     
    #include <afxwin.h> 
    ^include "dynmenu.h" 
    ^include "ids.h" 
    int maxX, maxY; //   
    CMainWin::CMainWin() 
    { 
    Create (NULL, "Demonstrate Dynamic Menus", 
    WSJ3VERLAPPEDWINDOW, rectDefault, 
    NULL, "DynMenu"); 
    //     
    if(!LoadAccelTable("DynMenu")) 
    MessageBox ("Cannot Load Accelerators", "Error"); 
    maxX = GetSystemMetrics(SM_CXSCREEN) ; 
    maxY = GetSystemMetrics(SM_CYSCREEN) ; 
    CClientDC DC(this); 
    
    //     
    m_memDC.CreateCompatibleDC(&DC) ; 
    m_bmp.CreateCompatibleBitmap(&DC, maxX, maxY) ; 
    m memDC.SelectObject(&m bmp) ; 
    
    //    
    m_bkbrush.CreateStockObject(WHITE_BRUSH) ; 
    m memDC.SelectObject(&m bkbrush) ; 
    
    //     
    m_memDC.PatBlt(0, 0, maxX, maxY, PATCOPY) ; 


    404                                    MFC:   


    //   
    m_RedPen.CreatePen(PS_SOLID, 1, RGB(255, 0, 0)) ; 
    m_GreenPen.CreatePen(PS_SOLID, 2, RGB(0, 255, 0) ) ; 
    m_BluePen.CreatePen(PS_SOLID, 3, RGB(0, 0, 255)); 
    m__YeilowPen.CreatePen(PS_SOLID, 4, RGB(255, 255, 0)) ; 
    m_01dPen.CreateStockObj ect(BLACK_PEN) ; 
    m AddActive =1; //   
    m DelActive = 0; 
    \ 
    II   
    300L ::Initlnstance() 
    m_pMainWnd = new CMainWin; 
    m pMainWnd->ShowWindow(m nCmdShow); 
    m_pMainHnd->UpdateWindow(); 
    return TRUE; 
    ) 
    //     
    BEGIN_MESSAGE_MAP(CMainWin, CFrameWnd) 
    ON_WM_PAINT() 
    ON_UPDATE_COMMAND_UI(IDM_ADDITEM, OnUIAdd) 
    ON_UPDATE_COMMAND_UI(IDM_DELITEM, OnUIDel) 
    ON_COMMAND(IDM_LINES, OnLines) 
    ON_COMMAND(IDM_RECTANGLES, OnRectangles) 
    ON_COMMAND(IDM_ELLIPSES, OnEllipses) 
    ON_COMMAND(IDM_RESET, OnReset) 
    ON_COMMAND(IDM_ADDITEM, OnAdd) 
    ON_COMMAND(IDM_DELITEM, OnDelete) 
    ON_COMMAND(IDM_EXIT, OnExit) 
    ON_COMMAND(IDM_HELP, OnHelp) 
    END_MESSAGE_MAP() 
    //       
    afx msq void CMainHin::OnPaint () 
    ( 
    CPaintDC DC(this) ; 
    DC.BitBlt(0, 0, maxX, maxY, &m_memDC, , , SRCCOPY) ; 
    //   IDM EXIT 
    afx msq void CMainWin::OnExit() 
    ( 
    int response; 
    response = MessageBox("Quit the Program?", "Exit", MB_YESNO) ; 


    15.                                             405 


    if (response == IDYES)                                               
    SendMessage(WM_CLOSE); //                  
    
    //   IDM_HELP                                      
    afx msg void CMainWin::OnHelp()                                      f 
    ( 
    MessageBox("Dynamic Menus", "Help"); 
    } 
    
    //     
    afx msg void CMainWin::OnLines() 
    ( 
    //   
    m_memDC.SetPixel(40, 14, RGB(255, 0, 0) ) ; 
    m_memDC.SetPixel (41, 14, RGB(0, 255, 0)); 
    m_memDC.SetPixel (42, 14, RGB(0, 0, 255)); 
    m_memDC.SetPixel (43, 14, RGB(0, 0, 0)) ; 
    m_memDC.LineTo(100, 50); 
    m_niemDC.MoveTo (100, 50); 
    
    //      
    m memDC.SelectObject(&m GreenPen); 
    m_memDC.LineTo(200, 100); 
    
    //      
    m_memDC.SelectObject(&m_YellowPen) ; 
    m_memDC.LineTo(0, 200); 
    
    //      
    m memDC.SelectObject(&m BluePen) ; 
    m_memDC.LineTo(200, 200); 
    
    //      
    m_memDC.SelectObject(&m_RedPen) ; 
    m_memDC.LineTo(0, 0) ; 
    m_memDC.LineTo(100, 50); 
    m_memDC.MoveTo(0, 0) ; 
    m_memDC.LineTo(100, 250); 
    m_memDC.MoveTo(0, 0) ; 
    m_memDC.LineTo(100, 350); 
    
    //    
    m_memDC.SelectObject(&m_01dPen) ; 
    m_memDC.Arc(, , 300, 300, 0, 50, 200, 0) ; 
    
    //  ,    
    m_memDC.MoveTo(150, 150); 
    m_memDC.LineTo(0, 50); 
    m_memDC.MoveTo(150, 150); 


    406                                    MFC:   


    m_memDC.LineTo(200, 0) ; 
    InvalidateRect(NULL) ; 
    'i 
    //   
    afx msg void CMainWin::OnRectangles() 
    { 
    CBrush HollowBrush; 
    
    //  ""  
    HollowBrush.CreateStockObject(HOLLOW_BRUSH) ; 
    m_memDC.SelectObject (&HollowBrush) ; 
    
    //    
    m_memDC.Rectangle(50, 50, 300, 300); 
    m_memDC.RoundRect(125, 125, 220, 240, 15, 13); 
    
    //    
    m_memDC.SelectObject(&m_RedPen) ; 
    m_memDC.Rectangle(100, 100, 200, 200); 
    m_memDC.SelectObject(&m_01dPen); //    
    
    //    
    m memDC.SelectObject(&m bkbrush) ; 
    InvalidateRect(NULL) ; 
    ) 
    //   
    afx msg void CMainWin::OnEllipses () 
    ( 
    CBrush Brush; 
    
    //    
    Brush.CreateSolidBrush(RGB(0, 0, 255)); 
    m_memDC.SelectObject(SBrush) ; 
    
    //  ,    
    m_inemDC. Ellipse (50, 200, 100, 280); 
    m_memDC.Ellipse(75, 25, 280, 100); 
    
    //    
    m_memDC.SelectObject(&m_RedPen) ; 
    //    
    Brush.DeleteObject (); //    
    Brush.CreateSolidBrush(RGB(0, 255, 0) ) ; 
    
    m_memDC.SelectObject(&Brush); //    
    m_memDC.Ellipse(100, 100, 200, 200); 
    //   


    15.                                               407 


    mJ-nemDC.Pie (200, 200, 340, 340, 225, 200, 200, 250);              | 
    
    m_memDC.SelectObject(&m_01dPen); //    
    m_memDC.SelectObject(&m_bkbrush); //    
    InvalidateRect(NULL) ; 
    } 
    //   
    afx msg void CMainWin::OnReset() 
    {                                                                          
                                                     I 
    m_memDC.PatBlt(0, 0, maxX, maxY, PATCOPY); 
    InvalidateRect(NULL) ; 
    | 
    
    //     
    afx_msg void CMainWin::OnAdd() 
    ( 
    CMenu *m MainMenu; //      
    CMenu *SubMenu; //     
    unsigned count; 
    
    //       
    m MainMenu = GetMenu(); 
    
    //        
    SubMenu = m MainMenu->GetSubMenu(0); 
    
    //      
    count = SubMenu->GetMenuItemCount(); 
    
    //   
    SubMenu->InsertMenu(count, MF_BYPOSITION | MF_SEPARATOR); 
    //     
    
    SubMenu->InsertMenu(count+l, MF_BYPOSITION I MF_STRING, 
    IDM_RESET, "SReset"); 
    
    //    
    m_AddActive = 0; 
    m_DelActive = 1; 
    } 
    //     
    afx msg void CMainWin::OnDelete() 
    ( 
    CMenu *m MainMenu; //      
    CMenu *SubMenu; //     
    unsigned count; 
    //       
    m_MainMenu = GetMenu(); 


    408                                     MFC:   


    //        
    SubMenu = m MainMenu->GetSubMenu(0); 
    
    //      
    count = SubMenu->GetMenuItemCount (); 
    
    //    
    SubMenu->DeleteMenu(count-1, MF_BYPOSITION) ; 
    
    //   
    SubMenu->DeleteMenu(count-2, MF_BYPOSITION) ; 
    
    //    
    m_AddActive =1; 
    m_DelActive = 0; 
    } 
    //   Add Item 
    afx_msg void CMainWin::OnUIAdd(CCmdUI *UI) 
    ( 
    UI->Enable(m_AddActive) ; 
    ) 
    
    //   Delete Item 
    afx_msg void CMainWin::OnUIDel(CCmdUI *UI) 
    { 
    UI->Enable(m_DelActive) ; 
    } 
    CApp App; //    


        

       ,   Options    
: Add Item, Delete Item  Exit.   Delete Item 
 , ,    .      
 Reset,   Add Item.   Reset , 
  Delete Item,   Add Item  .  
  Delete Item  Reset   ,  Add Item 
 ,   Delete Item   .   
  ,        
  . 
      Add Item  Delete Item     
 ,      .   
   m_AddActive  m_DelActive  
CMainWin,      . 
         OnAddQ.  ,  
       Options.   
  GetMenuQ     , ,  
 ,    .     
GetSubMenuQ      , ..  Options. 

    75.                                              409 

           .  
      ,    
 .  ,         
   .        
 j    .     
Insertltem()  i        
Reset,                   i 


        

           ,  
    . (..    
     .)    ,   
   .      
  CreatePopupMenu(),   : 

    BOOL CMenu::CreatePopupMenu(); 

         .    ( 
         .              ' 
      ,         ; 
    InsertMenu().         , 
  \     InsertMenu().    
  MFJPOPUP        
 .     ,     
  | m_hMenu  CMenu.                                           
    ,     CreatePopupMenu(),   
   .     ,    
.        
Deleteltem().  ,         
 DestroyMenu(). 

         

          
.      ,   
: Reset, Invert  Show Text.    Invert   
.      PatBItQ   
 DSTINVERT.    Show Text      
  "Sample Text".     ,  
         Options. 
           IDS.H,    
 .     : 

    ; DYNMENU2.RC 
    ^include <afxres.h> 
    ftinclude "ids.h" 
    DynMenu MENU 
    ( 


    410                                    MFC:   


    POPUP "SOptions" 
    ( 
    MENUITEM "&Add Pop-up\tF2", IDM_ADDITEM 
    MENUITEM "SDelete Pop-up\tF3", IDM_DELITEM 
    MENUITEM "E&xit\tF7", IDM_EXIT 
    > 
    POPUP "SGraphics" 
    ( 
    MENUITEM "&Lines\tF4", IDM_LINES 
    MENUITEM "&Rectangles\tF5", IDM_RECTANGLES 
    MENUITEM "&Ellipses\tF6", IDM_ELLIPSES 
    } 
    MENUITEM "SHelp", IDM_HELP 
    } 
    DynMenu ACCELERATORS 
    { 
    VK_F1, IDM_HELP, VIRTKEY 
    VK_F2, IDM_ADDITEM, VIRTKEY 
    VK_F3, IDM_DELITEM, VIRTKEY 
    VK_F4, IDM_LINES, VIRTKEY 
    VK_F5, IDM_RECTANGLES, VIRTKEY 
    VK_F6, IDM_ELLIPSES, VIRTKEY 
    VK_F7, IDM_EXIT, VIRTKEY 

       DYNMENU2.H,    : 

    // DYNMENU2.H 
    //       
    class CMainMin : public CFrameWnd 
    ( 
    
    CDC m memDC; //  ,   
    //   
    CBitmap m bmp; //    
    CBrush m bkbrush; //     
    
    //   
    CPen m_RedPen, m YellowPen, m GreenPen, m BluePen; 
    CPen m_01dPen; 
    CMenu *m_MainMenu; //      
    
    //     Add Pop-up  Delete Pop-up 
    int m AddActive, m DelActive; 
    
    CMenu m Popup; //    
    public: 
    CMainWinO ; 
    afx msg void OnPaintO; 


    15.                                              411 


    //                                       f 
    afx_msg void CMainWin::OnUIAdd(CCmdUI *UI); 
    afx_msg void CMainWin::OnUIDel(CCmdOl *UI); 
    afx_msg void OnLinesO; 
    afx msg void OnRectangles(); 
    afx_msg void OnEllipses () ; 
    afx_msg void OnResetO;                                           | 
    afx_msg void OnAdd();                                              
    afx_nisg void OnDeleteO;                                           
    afx_msg void OnDstInvert();                                       | 
    afx_msg void OnShowText();                                         | 
    afx msg void OnExitO; 
    afx msg void OnHelp(); 
    DECLARE_MESSAGE_MAP() 
    }; 
    //      
    class CApp : public CWinApp                                         ' 
    ( 
    public: 
    BOOL Initlnstance ();                                               i 
    }; 
        : 
    //    
    
    #include <afxwin.h> 
    ^include "dynmenu2.h" 
    #include "ids.h" 
    int maxX, maxY; //                                      i 
    
    CMainWin::CMainWin() 
    ( 
    
    Create(NULL, "Demonstrate Dynamic Pop-up Menus",                   I 
    WS_OVERLAPPEDWINDOW, rectDefault, 
    NULL, "DynMenu") ; 
    
    //     
    if(!LoadAccelTable("DynMenu")) 
    MessageBox("Cannot Load Accelerators", "Error"); 
    maxX = GetSystemMetrics(SM_CXSCREEN) ; 
    maxY = GetSystemMetrics(SM_CYSCREEN) ; 
    CClientDC DC(this); 
    
    //     
    m_memDC.CreateCompatibleDC(&DC) ; 


    412                                    MFC:   


    m bmp.CreateCompatibleBitmap(&DC, maxX, maxY); 
    m memDC.SelectObject(&m bmp); 
    
    //    
    m_bkbrush.CreateStockObject(WHITE_BRUSH) ; 
    m_memDC.SelectObject(&m_bkbrush) ; 
    
    //     
    m_memDC.PatBlt(0, 0, maxX, maxY, PATCOPY); 
    
    //   
    m^RedPen.CreatePen(PS_SOLID, 1, RGB(255, 0, 0)) ; 
    m_GreenPen.CreatePen(PS_SOLID, 2, RGB(0, 255, 0) ) ; 
    m_BluePen.CreatePen(PS_SOLID, 3, RGB(, , 255)); 
    m_YellowPen.CreatePen(PS_SOLID, 4, RGB(255, 255, 0)) ; 
    m_01dPen.CreateStockObject(BLACK_PEN) ; 
    
    m AddActive =1; //   
    m DelActive = 0; 
    t 
    
    //   
    BOOL CApp::Initlnstance() 
    ( 
    m_pMainWnd = new CMainWin; 
    m_pMainWnd->ShowWindow(m_nCmdShow) ; 
    m_pMainWnd->UpdateWindow() ; 
    return TRUE; 
    } 
    
    //     
    BEGIN_MESSAGE_MAP(CMainWin, CFrameWnd) 
    ON_WM_PAINT() 
    ON_UPDATE_COMMAND_UI(IDM_ADDITEM, OnUIAdd) 
    ON_UPDATE_COMMAND_UI(IDM_DELITEM, OnUIDel) 
    ON_COMMAND(IDM_LINES, OnLines) 
    ON_COMMAND(IDM_RECTANGLES, OnRectangles) 
    ON_COMMAND(IDM__ELLIPSES, OnEllipses) 
    ON_COMMAND(IDM_RESET, OnReset) 
    ON_COMMAND(IDM__ADDITEM, OnAdd) 
    ON_COMMAND(IDM__DELITEM, OnDelete) 
    ON_COMMAND(IDM_DSTINVERT, OnDstInvert) 
    ON_COMMAND(IDM_SHOWTEXT, OnShowText) 
    ON_COMMAND(IDM_EXIT, OnExit) 
    
    ON_COMMAND(IDM_HELP, OnHelp) 
    END_MESSAGE_MAP() 
    
    //       
    afx msg void CMainWin::OnPaint() 
    { 


    15.                                             413 


    CPaintDC DC(this); 
    DC.BitBlt(0, 0, maxX, maxY, &m_memDC, , , SRCCOPY); 
    ) 
    //   IDM_EXIT 
    afx_msg void CMainWin::OnExit () 
    { 
    int response; 
    response = MessageBox("Quit the Program?", "Exit", MB YESNO); 
    if (response == IDYES) 
    SendMessage(WM_CLOSE); //   
    ) 
    
    //   IDM HELP 
    afx_msg void CMainWin::OnHelp() 
    ( 
    MessageBox("Dynamic Pop-up Menus", "Help"); 
    } 
    
    //     
    afx msg void CMainWin::OnLines() 
    { 
    //   
    m_memDC.SetPixel(40, 14, RGB(255, 0, 0)); 
    m_memDC.SetPixel(41, 14, RGB(0, 255, 0) ) ; 
    m_memDC.SetPixel(42, 14, RGB(0, 0, 255)); 
    m_memDC.SetPixel(43, 14, RGB(0, 0, 0)); 
    { 
    m_memDC.LineTo(100, 50);                                           '' 
    m_memDC.MoveTo(100, 50);                                           I 
    
    //                                      { 
    m_memDC.SelectObject(&m_GreenPen);                                 ', 
    m_memDC.LineTo(200, 100); 
    
    //      
    m memDC.SelectObject(&m YellowPen) ; 
    m_memDC.LineTo(0, 200); 
    
    //      
    m_memDC.SelectObject(&m_BluePen) ; 
    m_memDC.LineTo(200, 200); 
    
    //      
    m_memDC.SelectObject(&m_RedPen) ; 
    m_memDC.LineTo(0, 0) ; 
    m_memDC.LineTo(100, 50); 
    m_memDC.MoveTo(0, 0) ; 


    414                                    MFC:   


    m_memDC.LineTo(100, 250); 
    m memDC.MoveTo(0, 0) ; 
    m__memDC.LineTo(100, 350); 
    
    //    
    m_memDC.SelectObject(&m_01dPen) ; 
    m_memDC.Arc(0, 0, 300, 300, 0, 50, 200, 0) ; 
    
    //  ,    
    m_mernDC .MoveTo (150, 150); 
    m_memDC.LineTo(0, 50); 
    m_memDC.MoveTo(150, 150); 
    m_memDC.LineTo(200, 0) ; 
    InvalidateRect(NULL) ; 
    } 
    II   
    afx msg void CMainWin::OnRectangles () 
    ( 
    CBrush HollowBrush; 
    
    //  ""  
    HollowBrush.CreateStockObject(HOLLOW_BRUSH) ; 
    m_memDC.SelectObject(sHollowBrush) ; 
    
    //    
    m_memDC.Rectangle(50, 50, 300, 300); 
    m__memDC.RoundRect(125, 125, 220, 240, 15, 13); 
    
    //    
    m_meniDC. SelectObject (&m_RedPen) ; 
    m_memDC.Rectangle(100, 100, 200, 200); 
    m memDC.SelectObject(&m OldPen); //    
    
    //    
    m_memDC.SelectObject(&m_bkbrush) ; 
    InvalidateRect(NULL) ; 
    //   
    afx msg void CMainWin::OnEllipses() 
    ( 
    CBrush Brush; 
    
    //    
    Brush.CreateSolidBrush(RGB(0, 0, 255)); 
    m_memDC.SelectObject(SBrush) ; 
    
    //  ,    
    m_memDC.Ellipse (50, 200, 100, 280); 


    15.                                             415 


    m_memDC.Ellipse(75, 25, 280, 100); 
    
    //    
    m_meinDC. SelectObject(&m_RedPen) ; 
    //    
    Brush.DeleteObject(); //    
    Brush.CreateSolidBrush(RGB(0, 255, 0)) ; 
    
    m memDC.SelectObject(&Brush); //    
    mJ-nernDC.Ellipse (100, 100, 200, 200); 
    
    //   
    m_memDC.Pie(200, 200, 340, 340, 225, 200, 200, 250); 
    
    m_inernDC . SelectObject (&m_01dPen) ; //    
    m memDC.SelectObject(&m bkbrush); //    
    InvalidateRect(NULL) ; 
    ) 
    //   
    afx_msg void CMainWin::OnReset() 
    < 
    m_memDC.PatBlt (0, 0, maxX, maxY, PATCOPY); 
    InvalidateRect(NULL) ; 
    //     
    afx msg void CMainWin::OnShowText() 
    { 
    m_memDC.TextOut (1, 1, "Sample Text", 11); 
    InvalidateRect(NULL) ; 
    ) 
    //                                      ; 
    afx_msg void CMainWin::OnDstInvert() 
    (                                                                     ' 
    m_memDC.PatBlt(0, 0, maxX, maxY, DSTINVERT) ; 
    InvalidateRect(NULL) ; 
    } 
    
    //     
    afx msg void CMainWin::OnAdd() 
    ( 
    CMenu *m MainMenu; //      
    CMenu *SubMenu; //     
    unsigned count; 
    
    //       
    m_MainMenu = GetMenuO; 
    
    //        
    SubMenu = m MainMenu->GetSubMenu(0) ; 


    416                                     MFC:   


    //      
    count = SubMenu->GetMenuItemCount(); 
    
    //     
    m Popup.CreatePopupMenu(); 
    
    //       
    m_Popup.InsertMenu(, MF_BYPOSITION | MF_STRING, 
    IDM_RESET, "bReset"); 
    m_Popup.InsertMenu(1, MF_BYPOSITION | MF_STRING, 
    IDM_DSTINVERT, "Sinvert Window"); 
    m_Popup.InsertMenu(2, MF_BYPOSITION | MF_STRING, 
    IDM_SHOWTEXT, "&Show Text"); 
    
    //   
    SubMenu->InsertMenu (count, MF_BYPOSITION | MF_SEPARATOR); 
    
    //      Options 
    SubMenu->InsertMenu(count+1, MF_POPUP I MF_BYPOSITION, 
    (unsigned)m Popup.m hMenu, "&New Options"); 
    
    //    
    m AddActive = 0; 
    m_DelActive = 1; 
    //     
    afx msg void CMainMin::OnDelete() 
    { 
    CMenu *m MainMenu; //      
    CMenu *SubMenu; //     
    unsigned count; 
    
    //       
    m MainMenu = GetMenuO; 
    
    //        
    SubMenu = m MainMenu->GetSubMenu(0); 
    
    //      
    count = SubMenu->GetMenuItemCount() ; 
    
    //    
    SubMenu->DeleteMenu(count-1, MF_BYPOSITION) ; 
    
    //   
    SubMenu->DeleteMenu(count-2, MF_BYPOSITION) ; 
    
    //    
    m AddActive = 1; 
    m DelActive = 0; 
    ) 
    //   Add Pop-up 


    15.                                               417 


    afx_msg void CMainWin::OnUIAdd(CCmdUI *UI) 
    ( 
    UI->Enable(m_AddActive) ; 
    ) 
    
    //   Delete Pop-up 
    afxJnsg void CMainWin::OnUIDel(CCmdUI *UI) 
    ( 
    UI->Enable(m_DelActive) ; 
    ) 
    CApp App; //    

         . 15.2. 

    . 15.2.      

         .   , , 
  .    ,     
Options    InsertMenu().     
MFJPOPUP,         
 .   ,      
m_hMenu  CMenu. ,      unsigned 
  ,       
 . 

    418                                     MFC:   


       

     ,  ,  ,    
 ,   Windows,     
      .    
    .     
 ,        
  Windows 95  Windows NT. ,     
        .   
        ,  
 ,    .      
    . 

       

          TrackPopupMenu().  
 : 

    BOOL CMenu::TrackPopupMenu(UINT Flags, int X, int , 
    CWnd *0wner, RECT * Limit s=WLL) ; 

     Flags     (..   
 )  ,     . 15.2. 

     15.2.   Flags  Track Popup () 

    _______________________________________ 

    TPM_CENTERALIGN         
  
    TPM_LEFTALIGN            
  (   ) 
    TPM_LEFTBUTTON            
    (   ) 
    TPM_RIGHTALIGN           
  
    TPM_RIGHTBUTTON          
   ____________ 

        Flags   0.    
   . 
     ,      
,       ,    
   ,    ,    
  .        
   CWnd::ClientToScreen()   
CWnd::ScreenToClient().    TrackPopupMenu ()  
   ,          
,    Y.     Flags 
   . 
       ,    , 
   Owner. 
       ,    
    ,  .     


    75.                                              419 


        .     
,       RECT,    
 Limits.    NULL (  ),     
           . 

      

            , 
     (    
),     .     
 LoadMenuQ,   : 

    BOOL CMenu::LoadMenu(LPCSTR IpszMenuName); 
    BOOL CMenu::LoadMenu(UINT MenuID); 

      IpszMenuName    ,   
.        ,  
  MenuID.       
      .   ,   
     CMenu. 
     ,     ,   
   CMenu::Destroy(),    . 

                             j 

        Graphics     \ 
  .  ,       
       .     
  ,    .    
  . 15.3. 

    . 5.3.    . 

    420                                          MFC:   

           1DS.H,   . 
    . ,    Graphics  
   .  ,       
 . 

    ; DYNMENU3.RC 
    #include <afxres.h> 
    #include "ids.h" 
    DynMenu MENU 
    < 
    POPUP "{.Options" 
    ( 
    MENUITEM "&Add Pop-up\tF2", IDM_ADDITEM 
    MENUITEM "SDelete Pop-up\tF3", IDM_DELITEM 
    MENUITEM "E?xit\tF7", IDM_EXIT 
    } 
    
    MENUITEM "&Help", IDM_HELP 
    ) 
    ;     
    GraphMenu MENU 
    ( 
    POPUP "SGraphics" 
    
    MENUITEM "&Lines\tF4", IDM_LINES 
    MENUITEM "&Rectangles\tF5", IDM_RECTANGLES 
    MENUITEM "&Ellipses\tF6", IDM_ELLIPSES 
    } 
    DynMenu ACCELERATORS 
    ( 
    VK_F1, IDM_HELP, VIRTKEY 
    VK_F2, IDM_ADDITEM, VIRTKEY 
    VK_F3, IDM_DELITEM, VIRTKEY 
    VK_F4, IDM_LINES, VIRTKEY 
    VK_F5, IDM_RECTANGLES, VIRTKEY 
    VK_F6, IDM_ELLIPSES, VIRTKEY 
    VK_F7, IDM_EXIT, VIRTKEY 
    } 
       DYNMENLJ3.H,    : 
    // DYNMENU3.H 
    //       
    class CMainWin : public CFrameWnd 
    { 
    CDC m_memDC; //  ,   
    //   


    15.                                             421 


    CBitmap m_bmp; //    
    CBrush m_bkbrush; //     
    
    //   
    CPen m_RedPen, m_YellowPen, m_GreenPen, m_BluePen; 
    CPen m_01dPen; 
    CMenu *m_MainMenu; //      
    
    //     Add Pop-up  Delete Pop-up 
    int m AddActive, m DelActive; 
    
    CMenu m_Popup; //    
    CMenu m_FloatMenu; //    
    public: 
    CMainWin() ; 
    afx msg void OnPaintO; 
    afx_msg void OnRButtonDown(UINT Flags, CPoint Loc) ; 
    
    //     
    afx_msg void CMainWin::OnUIAdd(CCmdUI *UI) ; 
    afx_msg void CMainWin::OnUIDel(CCmdUI *UI) ; 
    afx_msg void OnLinesO; 
    afx_msg void OnRectangles(); 
    afx msg void OnEllipses (); 
    afx msg void OnReset(); 
    afx msg void OnAdd() ; 
    afx_msg void OnDelete() ; 
    afx msg void OnDstInvert() ; 
    afx msg void OnShowText(); 
    afx_msg void OnExitO; 
    afx msg void OnHelpO; 
    DECLARE_MESSAGE_MAP() 
    }; 
    
    //      
    class CApp : public CWinApp 
    { 
    public: 
    BOOL Initlnstance () ; 
    ); 
       : 
    //    
    #include <afxwin.h> 
    #include "dynmenu3.h" 
    #include "ids.h" 


    422                                    MFC:   


    int maxX, maxY; //   
    CMainWin::CMainWin() 
    ( 
    Create(NULL, "Demonstrate Floating Pop-up Menus", 
    WS_OVERLAPPEDWINDOW, rectDefault, 
    NULL, "DynMenu"); 
    
    //     
    if(!LoadAccelTable("DynMenu")) 
    MessageBox("Cannot Load Accelerators", "Error"); 
    maxX = GetSystemMetrics(SM_CXSCREEN); 
    maxY = GetSystemMetrics(SM_CYSCREEN); 
    CClientDC DC(this) ; 
    
    //     
    m_memDC.CreateCompatibleDC(&DC) ; 
    m bmp.CreateCompatibleBitmap(&DC, maxX, maxY); 
    m memDC.SelectObject(&m bmp) ; 
    
    //    
    m_bkbrush.CreateStockObject(MHITE_BRUSH) ; 
    m memDC.SelectObject(&m bkbrush); 
    
    //     
    m_memDC.PatBlt(0, 0, maxX, maxY, PATCOPY); 
    
    //   
    m_RedPen.CreatePen(PS_SOLID, I, RGB(255, 0, 0) ) ; 
    m_GreenPen.CreatePen(PS_SOLID, 2, RGB(0, 255, 0)) ; 
    m_BluePen.CreatePen(PS_SOLID, 3, RGB(0, 0, 255)); 
    m_YellowPen.CreatePen(PS_SOLID, 4, RGB(255, 255, 0)); 
    m_01dPen.CreateStockObject(BLACK_PEN) ; 
    m AddActive =1; //   
    m DelActive = 0; 
    1 
    
    //   
    BOOL CApp::Initlnstance () 
    ( 
    m pMainWnd = new CMainWin; 
    m_pMainWnd->ShowWindow(m_nCmdShow) ; 
    m pMainWnd->UpdateWindow() ; 
    return TRUE; 
    1 
    
    //     
    BEGIN_MESSAGE_MAP(CMainWin, CFrameWnd) 


    75.                                              423 


    ON_WM_PAINT () 
    ON_WM_RBUTTONDOWN() 
    
    ON_UPDATE_COMMAND_UI(IDM_ADDITEM, OnUIAdd) 
    ON_UPDATE_COMMAND_UI(IDM_DELITEM, OnUIDel) 
    ON_COMMAND(IDM_LINES, OnLines) 
    ON_COMMAND(IDM_RECTANGLES, OnRectangleS) 
    ON_COMMAND(IDM_ELLIPSES, OnEllipses) 
    ON_COMMAND(IDM_RESET, OnReset) 
    ON_COMMAND(IDM_ADDITEM, OnAdd) 
    ON_COMMAND(IDM_DELITEM, OnDelete) 
    ON_COMMAND(IDM_DSTINVERT, OnDstInvert) 
    ON_COMMAND(IDM_SHOWTEXT, OnShowText) 
    ON_COMMAND(IDM_EXIT, OnExit) 
    ON_COMMAND(IDM_HELP, OnHelp) 
    END_MESSAGE_MAP() 
    
    //       
    afx msg void CMainWin::OnPaint () 
    i 
    CPaintDC DC(this) ; 
    DC.BitBltfO, 0, maxX, maxY, &m_memDC, , , SRCCOPY); 
    ) 
    
    //   IDM_EXIT 
    afx msg void CMainWin::OnExit() 
    (  -                                                               ! 
    int response; 
    response = MessageBox ("Quit the Program?", "Exit", MB_YESNO); 
    if(response == IDYES)                                             ' 
    SendMessage(WM CLOSE); //   
    i 
    //   IDM_HELP                                     ; 
    afx_msg void CMainWin::OnHelp()                                      [ 
    ( 
    MessageBox("Floating Pop-up Menus", "Help"); 
    } 
    
    //                                            i 
    afx msg void CMainWin::OnLines()                                    ' 
    { 
    //   
    m_memDC.SetPixel (40, 14, RGB(255, 0, 0)) ; 
    m_memDC.SetPixel(41, 14, RGB(0, 255, 0)) ; 
    m_memDC.SetPixel (42, 14, RGB(0, 0, 255)); 
    m_memDC.SetPixel (43, 14, RGB(0, 0, 0)) ; 
    m_memDC.LineTo(100, 50); 
    m_memDC.MoveTo(100, 50); 
    //      


    424                                     MFC:   


    m_memDC.Select0bject(&m Green Pen); 
    ni_memDC.LineTo(200, 100); 
    
    //      
    m memDC.SelectObject(Srn YellowPen); 
    m_memDC.LineTo(0, 200) ;~ 
    
    //      
    rn_memDC.SelectObject(&m_BluePen) ; 
    m_memDC.LineTo(200, 200); 
    
    //      
    m_memDC.SelectObject<&m_RedPen) ; 
    m_memDC.LineTo(, 0); 
    m_memDC.LineTo(100, 50); 
    m_memDC.MoveTo(0, 0) ; 
    m_memDC.LineTo(100, 250); 
    m_memDC.MoveTo(, ); 
    m_memDC.LineTo(100, 350); 
    
    //    
    m_memDC.SelectObject(&m_01dPen) ; 
    m_memDC.Arc(0, 0, 300, 300, 0, 50, 200, 0) ; 
    
    //  ,    
    m_memDC.MoveTo(150, 150); 
    m_memDC.LineTo(0, 50); 
    m_memDC.MoveTo(150, 150); 
    m_memDC.LineTo(200, 0) ; 
    InvalidateRect(NULL) ; 
    ) 
    
    //   
    afx_msg void CMainWin::OnRectangles() 
    ( 
    CBrush HollowBrush; 
    
    //  ""  
    HollowBrush.CreateStockObject(HOLLOW_BRUSH) ; 
    m_memDC.SelectObject(SHollowBrush) ; 
    
    //    
    m_memDC.Rectangle(50, 50, 300, 300); 
    m_memDC.RoundRect(125, 125, 220, 240, 15, 13); 
    
    //    
    m_memDC.SelectObject(&m_RedPen) ; 
    m_memDC.Rectangle(100, 100, 200, 200); 
    m memDC.SelectObject(&m OldPen); //    


    15.                                              425 


    //    
    m_memDC.SelectObject(&m_bkbrush) ; 
    InvalidateRect(NULL) ; 
    }                                                                          
                                                     ] 
    //   
    afx_msg void CMainWin::OnEllipses0 
    ( 
    CBrush Brush; 
    
    //    
    Brush.CreateSolidBrush(RGB (0, 0, 255)); 
    m_memDC.SelectObject(SBrush) ; 
    
    //  ,    
    m_memDC.Ellipse(50, 200, 100, 280); 
    m_memDC.Ellipse(75, 25, 280, 100); 
    
    //    
    m_memDC.SelectObject(&m_RedPen) ; 
    //    
    Brush.DeleteObject(); //    
    Brush.CreateSolidBrush(RGB(0, 255, 0)) ; 
    
    m_memDC.SelectObject(&Brush); //    
    m_memDC.Ellipse(100, 100, 200, 200); 
    
    //   
    m_memDC.Pie(200, 200, 340, 340, 225, 200, 200, 250); 
    
    m_memDC.SelectObject(&m_01dPen); //    
    m_memDC.SelectObject(&m_bkbrush); //    
    InvalidateRect(NULL) ; 
    ) 
    //   
    afx msg void CMainWin::OnReset() 
    { 
    m_memDC.PatBlt(0, 0, maxX, maxY, PATCOPY) ; 
    InvalidateRect(NULL) ; 
    ) 
    
    //     
    afx_msg void CMainWin::OnShowText() 
    ( 
    m_memDC.TextOut(1, 1, "Sample Text", 11); 
    InvalidateRect(NULL) ; 
    ) 
    //    


    426                                     MFC:   


    afx_msg void CMainWin::OnDstInvert() ( 
    m_memDC.PatBlt(0, 0, maxX, maxY, DSTINVERT); 
    InvalidateRect(NULL) ; 
    } 
    
    //     
    afx msg void CMainWin::OnAdd() 
    ( 
    CMenu *m MainMenu; //      
    CMenu *SubMenu; //     
    unsigned count; 
    
    //       
    m MainMenu = GetMenuf); 
    
    //        
    SubMenu = m__MainMenu->GetSubMenu(0); 
    
    //      
    count = SubMenu->GetMenuItemCount() ; 
    
    //     
    m_Popup.CreatePopupMenu() ; 
    
    //       
    m_Popup.InsertMenu(0, MF_BYPOSITION | MF_STRING, 
    IDM_RESET, "SReset"); 
    m_Popup.InsertMenu(l, MF_BYPOSITION | MF_STRING, 
    IDM_DSTINVERT, "&Invert Window"); 
    m_Popup.InsertMenu(2, MP_BYPOSITION | MF_STRING, 
    IDM_SHOWTEXT, "SShow Text"); 
    
    //   
    SubMenu->InsertMenu(count, MF_BYPOSITION | MF_SEPARATOR) ; 
    
    //      Options 
    SubMenu->InsertMenu(count+1, MF_POPUP | MF_BYPOSITION, 
    (unsigned)m Popup.m hMenu, "&New Options"); 
    
    //    
    m AddActive = 0; 
    m DelActive =1; 
    } 
    //     
    afx msg void CMainWin::OnDelete() 
    { 
    CMenu *m MainMenu; //      
    CMenu *SubMenu; //     
    unsigned count; 


    15.                                             427 


    //       
    m MainMenu = GetMenu(); 
    
    //        
    SubMenu = m MainMenu->GetSubMenu(0); 
    
    //      
    count = SubMenu->GetMenuItemCount(); 
    
    //    
    SubMenu->DeleteMenu(count-l, MF_BYPOSITION) ; 
    
    //   
    SubMenu->DeleteMenu(count-2, MF_BYPOSITION) ; 
    
    //    
    m AddActive = 1; 
    m_DelActive = 0; 
    
    //   Add Pop-up 
    afx_msq void CMainWin::OnUIAdd(CCmdUI *UI) 
    ( 
    UI->Enable(m_AddActive) ; 
    ( 
    
    //   Delete Pop-up 
    afx_msg void CMainWin::OnUIDel(CCmdUI *UI) 
    { 
    UI->Enable(m_DelActive) ; 
    //    
    afx_msg void CMainWin : .-OnRButtonDown (UINT Flags, CPoint Loc) 
    { 
    CMenu *SubMenu; //     
    ClientToScreen(&Loc) ; 
    m FloatMenu.LoadMenu("GraphMenu") ; 
    SubMenu = m_FloatMenu.GetSubMenu(0) ; 
    SubMenu->TrackPopupMenu(0, Loc.x, Loc.y, this); 
    m_FloatMenu.DestroyMenu() ; 
    CApp App; //    


    428                                     MFC:   


        

            .  
      OnRButtonDown().   
    Graphics,     
,        ,    
  .   ,    
TrackPopupMenu(),     ,    
      ( 
    )   ,    
 ClientToScreen().         
 LoadMenuQ,        ( 
)  .    , 
  . 

       

           ,    
 .          
. , ,      
  CCmdUI::SetRadio().     
   TrackPopupMenuO      
 . 
        .       
Reset      Option      
 .      .  
       . ,   
 (   ),    Reset,   
  -  ,  .   
  ,   Reset .  
  Reset  ,     
  . 
       -       
Windows,  -    . , 
,  ,     ,     
 .        
 . 
      ,         
Windows,     Windows 95      
   .    
,  ,        . 

    15.                                              429