comment $
//-----------------------------------------------------------------------------------//
//  Source code                                                                      //
//                                                                                   //
//  Written      by  Chib, Alexm			       		     //
//                                                                                   //
//  FileName   : XXMenu.asm                                                          //
//  Description: example for libraries of functions for work with menu               //
//  Version    : 1.00.000, December 1, 2004                                          //
//-----------------------------------------------------------------------------------//
$
; #########################################################################

      .486                    ; create 32 bit code
      .model flat, stdcall    ; 32 bit memory model
      option casemap :none    ; case sensitive

      include SDI.inc         ; local includes for this file

.code

; #########################################################################

start:

    ; ------------------
    ; set global values
    ; ------------------
      mov hInstance, $invoke (GetModuleHandle, NULL)      
      mov hCursor, $invoke (LoadCursor,NULL,IDC_ARROW)
      call Main
      invoke ExitProcess,eax

; #########################################################################

Main proc

    STRING szClassMain,"SDI_MENU_XX"

  ; --------------------------------------------
  ; register class name for CreateWindowEx call
  ; --------------------------------------------
    invoke RegisterWinClass,ADDR WndProc,ADDR szClassMain,
                       NULL,hCursor,COLOR_BTNFACE+1
 
  ; -------------------------------------------------
    mov hMenu, $invoke ( LoadMenuA , hInstance, MAINMENU)
    mov hContextMenu, $invoke (GetSubMenu, hMenu, 1)   ; get handle context menu
    invoke CreateWindowEx,WS_EX_STATICEDGE,
                          ADDR szClassMain,
                          ADDR szXXMenu,
                          WS_OVERLAPPEDWINDOW,
                          CW_USEDEFAULT,0,CW_USEDEFAULT,0,
                          NULL,hMenu,
                          hInstance,NULL
    mov hWnd,eax

    invoke ShowWindow,hWnd, SW_SHOWNORMAL 
    invoke UpdateWindow,hWnd

    mov h_Accel, $invoke (LoadAccelerators, hInstance, ACC)

    call MsgLoop
    ret

Main endp

; #########################################################################

RegisterWinClass proc lpWndProc:DWORD, lpClassName:DWORD,
                      Icon:DWORD, Cursor:DWORD, bColor:DWORD

    LOCAL wc:WNDCLASSEX

    mov wc.cbSize,         sizeof WNDCLASSEX
    mov wc.style,          CS_BYTEALIGNCLIENT or \
                           CS_BYTEALIGNWINDOW
    m2m wc.lpfnWndProc,    lpWndProc
    mov wc.cbClsExtra,     NULL
    mov wc.cbWndExtra,     NULL
    m2m wc.hInstance,      hInstance
    m2m wc.hbrBackground,  bColor
    mov wc.lpszMenuName,   NULL
    m2m wc.lpszClassName,  lpClassName
    m2m wc.hIcon,          Icon
    m2m wc.hCursor,        Cursor
    m2m wc.hIconSm,        Icon

    invoke RegisterClassEx, ADDR wc

    ret

RegisterWinClass endp

; ########################################################################

MsgLoop proc

  ; ------------------------------------------
  ; The following 4 equates are available for
  ; processing messages directly in the loop.
  ; m_hWnd - m_Msg - m_wParam - m_lParam
  ; ------------------------------------------

    LOCAL msg:MSG

    StartLoop:
      invoke GetMessage,ADDR msg,NULL,0,0
      cmp eax, 0
      je ExitLoop
      invoke TranslateAccelerator, hWnd, h_Accel, ADDR msg
      cmp eax, 0
      jne StartLoop
      invoke TranslateMessage, ADDR msg
      invoke DispatchMessage,  ADDR msg
      jmp short StartLoop
    ExitLoop:

    mov eax, msg.wParam
    ret

MsgLoop endp

; #########################################################################

WndProc proc hWin :HWND, uMsg :UINT, wParam :WPARAM, lParam :LPARAM

    LOCAL StyleMenu	  :DWORD
    LOCAL buffer1[128]:BYTE  ; these are two spare buffers
    LOCAL buffer2[128]:BYTE  ; for text manipulation etc..
    LOCAL hBmp1       :HBITMAP
    
    WM_CASE uMsg, <CREATE, COMMAND, CONTEXTMENU, DESTROY, SYSCOMMAND, SIZE, SYSCOLORCHANGE>     

@@end:    
    invoke DefWindowProc,hWin,uMsg,wParam,lParam
    ret
    
@@CREATE: 

    invoke Do_ToolBar,hWin
    invoke Do_Status,hWin

    ; create image list  (for extract icon), (<-Standart WinAPI)
    mov hImageList, $invoke (ImageList_Create, 16, 16, ILC_COLOR or ILC_MASK, 19,0)
    mov hBmp1, $invoke (LoadBitmap, hInstance, IDB_BITMAP1)
    RGB 192, 192, 192
    
    invoke ImageList_AddMasked, hImageList, hBmp1, eax
    invoke DeleteObject, hBmp1

    ; Set icon to menu. (<-XXMenu function)
    invoke SetMenuIcon, hMenu, hImageList, nmnubtns, ADDR mnubtns	; set icon for item menu
    invoke RedrawMenu, hWin, hMenu, STYLE_XNET  
  
    ; check current style (<-Standart WinAPI)
    invoke CheckMenuRadioItem, hMenu, IDM_VIEW_THEME_DEFAULT, IDM_VIEW_THEME_XNET, IDM_VIEW_THEME_XNET, MF_BYCOMMAND

    ; change system menu 	
    mov hSysMenu, $invoke ( GetSystemMenu, hWin, FALSE )   ; get handle system menu
    invoke AppendMenu, hSysMenu, MF_SEPARATOR, 0, 0        ; add separator
    ; add system menu about item
    invoke GetMenuString, hMenu, IDM_HELP_ABOUT_MENU_XX, ADDR buffer1, 127, MF_BYCOMMAND    ; get string
    invoke AppendMenu, hSysMenu, MF_STRING, IDM_HELP_ABOUT_MENU_XX, ADDR buffer1    
    ; set icon about item, in system menu (<-XXMenu function)
    invoke SetMenuItemIcon, hSysMenu, IDM_HELP_ABOUT_MENU_XX, $invoke (ImageList_GetIcon, hImageList, 12, ILD_NORMAL)

    invoke RedrawMenu, hWin, hSysMenu, STYLE_XNET	; function change SysMenu style, and redraw
    ; select gray item -> uncoment -> compile, link -> select gray item
    ; this is function change view gray item  
    ;invoke SetDisableSelect, TRUE	; FALSE - not show "gray - disable" item menu, TRUE - show...
    
    ; add left border to file and system menu
    invoke GetSubMenu, hMenu, 0	;(<-Standart WinAPI)
    mov hFileMenu, eax
    invoke AddLeftBorder, hFileMenu, ADDR DrawBorderProc, TRUE	; (<-XXMenu function)
    invoke AddLeftBorder, hSysMenu, ADDR DrawBorderProc, TRUE
    
    ; create image list big icon menu (for extract icon), (<-Standart WinAPI)
    mov hImageListBig, $invoke (ImageList_Create, 32, 32, ILC_COLOR or ILC_MASK, 4,0)
    mov hBmp1, $invoke (LoadBitmap, hInstance, IDB_BITMAP2)
    RGB 192, 192, 192
    invoke ImageList_AddMasked, hImageListBig, hBmp1, eax
    invoke DeleteObject, hBmp1

    ; set icon
    invoke SetMenuItemIcon, hMenu, IDM_32_BIG1, $invoke (ImageList_GetIcon, hImageListBig, 0, ILD_NORMAL)
    invoke SetMenuItemIcon, hMenu, IDM_32_BIG2, $invoke (ImageList_GetIcon, hImageListBig, 1, ILD_NORMAL)
    invoke SetMenuItemIcon, hMenu, IDM_32_BIG3, $invoke (ImageList_GetIcon, hImageListBig, 2, ILD_NORMAL)
    
    jmp @@end
@@COMMAND:

    ;======== menu commands ========
    mov eax, wParam
    
        .if ax == IDM_FILE_APP_EXIT
        
            invoke	SendMessage,hWin,WM_SYSCOMMAND,SC_CLOSE,NULL
        
        .elseif ax == IDM_VIEW_TOOLBARS_STANDARD
              
reverse:        
            invoke GetMenuState, hMenu, wParam, MF_BYCOMMAND            
            and eax, MF_CHECKED
            
            .if eax == MF_CHECKED
                invoke CheckMenuItem,hMenu, wParam, MF_BYCOMMAND or MF_UNCHECKED                        
            .else                           
                invoke CheckMenuItem,hMenu, wParam, MF_BYCOMMAND or MF_CHECKED             
            .endif
            
        .elseif ax == IDM_VIEW_TOOLBARS_THEME           
 
            invoke GetMenuState, hMenu, wParam, MF_BYCOMMAND            
            and eax, MF_CHECKED
            
            .if eax == MF_CHECKED
                invoke CheckMenuItem,hMenu, wParam, MF_BYCOMMAND or MF_UNCHECKED
                invoke ShowWindow, hToolBar, SW_HIDE                        
            .else                           
                invoke CheckMenuItem,hMenu, wParam, MF_BYCOMMAND or MF_CHECKED
                invoke ShowWindow, hToolBar, SW_SHOWNORMAL
            .endif
                                 
        .elseif ax == IDM_VIEW_TOOLBARS_CUSTOMIZE
             
        .elseif ax == IDM_VIEW_SATATUSBAR        

            invoke GetMenuState, hMenu, wParam, MF_BYCOMMAND            
            and eax, MF_CHECKED
            
            .if eax == MF_CHECKED
                invoke CheckMenuItem,hMenu, wParam, MF_BYCOMMAND or MF_UNCHECKED
                invoke ShowWindow, hStatus, SW_HIDE                       
            .else                           
                invoke CheckMenuItem,hMenu, wParam, MF_BYCOMMAND or MF_CHECKED
                invoke ShowWindow, hStatus, SW_SHOWNORMAL             
            .endif
                            
        .elseif ax == IDM_VIEW_THEME_DEFAULT
            mov StyleMenu, STYLE_DEFAULT
            invoke SendMessage, hToolBar, TB_CHECKBUTTON, IDM_VIEW_THEME_DEFAULT, TRUE   ; ToolBar button check 
            jmp radio_check
            
        .elseif ax == IDM_VIEW_THEME_OFFICE_2000
            mov StyleMenu, STYLE_OFFICE_2000
            invoke SendMessage, hToolBar, TB_CHECKBUTTON, IDM_VIEW_THEME_OFFICE_2000, TRUE; ToolBar button check 
            jmp radio_check
             
        .elseif ax == IDM_VIEW_THEME_OFFICE_XP
            invoke SendMessage, hToolBar, TB_CHECKBUTTON, IDM_VIEW_THEME_OFFICE_XP, TRUE  ; ToolBar button check 
            mov StyleMenu, STYLE_OFFICE_XP
            jmp radio_check

        .elseif ax == IDM_VIEW_THEME_XNET
            invoke SendMessage, hToolBar, TB_CHECKBUTTON, IDM_VIEW_THEME_XNET, TRUE  ; ToolBar button check 
            mov StyleMenu, STYLE_XNET            
     
radio_check:

	  invoke RedrawMenu, hWin, hSysMenu, StyleMenu 	; function change menu style, and redraw
	  invoke RedrawMenu, hWin, hMenu, StyleMenu
            invoke CheckMenuRadioItem, hMenu, IDM_VIEW_THEME_DEFAULT, IDM_VIEW_THEME_XNET, wParam, MF_BYCOMMAND                                        


        .elseif ax == IDM_SHOW_DISABLED
        
            invoke GetMenuState, hMenu, wParam, MF_BYCOMMAND            
            and eax, MF_CHECKED
            
            .if eax == MF_CHECKED
                invoke CheckMenuItem,hMenu, wParam, MF_BYCOMMAND or MF_UNCHECKED
                invoke SetDisableSelect, FALSE                        
            .else                           
                invoke CheckMenuItem,hMenu, wParam, MF_BYCOMMAND or MF_CHECKED
                invoke SetDisableSelect, TRUE
            .endif
            
        .elseif ax == IDM_SHOW_BORDER

            invoke GetMenuState, hMenu, wParam, MF_BYCOMMAND            
            and eax, MF_CHECKED
            
            .if eax == MF_CHECKED
                invoke CheckMenuItem,hMenu, wParam, MF_BYCOMMAND or MF_UNCHECKED
                invoke RemoveLeftBorder, hFileMenu                        
            .else
                invoke CheckMenuItem,hMenu, wParam, MF_BYCOMMAND or MF_CHECKED                           
                invoke AddLeftBorder, hFileMenu, ADDR DrawBorderProc, TRUE
            .endif
        
        .elseif ax == IDM_HELP_ABOUT_MENU_XX        ; create Dlg "About XXControls", XXAbout

            invoke CreateXXAboutDlg, hWin
            
        .else

            invoke GetMenuString, hMenu, wParam, ADDR buffer1, 128, MF_BYCOMMAND
            
            mov eax, wParam
            xor edx, edx
            mov dx, ax            
            invoke dwtoa, edx, ADDR buffer2            
            invoke MessageBox, hWin, ADDR buffer1, ADDR buffer2, MB_OK
            
        .endif
        
    ;====== end menu commands ======
        jmp @@end
@@CONTEXTMENU:
        push 0
        push hWin       ; Handle to the window
        push 0        
        HIWORD lParam   ; vert position menu
        push eax
        LOWORD lParam   ; horiz position menu
        push eax
        push 0
        push hContextMenu
        call TrackPopupMenu

        jmp @@end

@@SYSCOMMAND:        

        mov eax, wParam    
        .if ax == IDM_HELP_ABOUT_MENU_XX        ; create Dlg "About XXControls", XXAbout
            invoke CreateXXAboutDlg, hWin            
        .endif
        
        jmp @@end

@@SIZE:        
        invoke SendMessage,hToolBar,TB_AUTOSIZE,0,0
        invoke MoveWindow,hStatus,0,0,0,0,TRUE
        
        jmp @@end
        
@@SYSCOLORCHANGE:

        invoke Do_ToolBar,hWin                        
        jmp @@end
        
@@DESTROY:    
        invoke ImageList_Destroy, hImageList
        invoke ImageList_Destroy, hImageListBig
        invoke PostQuitMessage,NULL
        return 0

WndProc endp

; ########################################################################

DrawBorderProc proc uses ebx h_Menu:HMENU, hDC:HDC, lpRect:DWORD

    LOCAL hFont :HFONT
    LOCAL Rct   :RECT
    LOCAL lenStr:DWORD
    LOCAL nX    :DWORD
    LOCAL nY    :DWORD

    invoke IsMenu, h_Menu
    .if !eax
        return 0
    .endif
    
    .if hDC && lpRect        
        
        call NumColorBits
        .if eax > 8
            mov ebx, $invoke ( GetSysColor, COLOR_MENU )
            invoke LightenColor, 128, ebx
            invoke Gradient_Fill, hDC, lpRect, eax, ebx, RECT_H
        .else
            invoke FillRect, hDC, lpRect, COLOR_MENU+1
        .endif
        
        invoke GetSysColor, COLOR_GRAYTEXT
        invoke SetTextColor, hDC, eax
        mov eax, h_Menu
        .if eax == hSysMenu
          mov hFont, $invoke ( CreateFontIndirect, ADDR lf_small )
        .elseif eax == hFileMenu        
        	mov hFont, $invoke ( CreateFontIndirect, ADDR lf )
        .endif
        
        invoke SelectObject, hDC, hFont
        mov hFont, eax
        
        mov eax, h_Menu
        .if eax == hSysMenu
        	invoke szLen, ADDR szSysMenu
        .elseif eax == hFileMenu
          invoke szLen, ADDR szXXControls
        .endif
        mov lenStr, eax
        
        mov edx, lpRect
        m2m nX, [edx].RECT.left
        m2m nY, [edx].RECT.bottom
        
        sub nY, 3

        mov eax, h_Menu        
        .if eax == hSysMenu
        	lea eax, szSysMenu
        .elseif eax == hFileMenu
        	lea eax, szXXControls
        .endif
        
        invoke TextOut, hDC, nX, nY, eax, lenStr
        
        invoke SelectObject, hDC, hFont
        invoke DeleteObject, eax

        mov eax, FALSE
    
    .else
        mov eax, h_Menu 
        .if eax == hSysMenu        
        	mov eax, 5
        .elseif eax == hFileMenu
	mov eax, 8 
        .endif	
    
    .endif    

    ret
DrawBorderProc endp

end start