comment $
//-----------------------------------------------------------------------------------//
//  Source code                                                                      //
//                                                                                   //
//  Written      by  Chib, amdtm                     http://www.xxcontrols.com       //
//                                                                                   //
//  FileName   : XXMenu.asm                                                          //
//  Description: libraries of functions for work with menu                           //
//  Version    : 1.00.000, January 1, 2004                                           //
//-----------------------------------------------------------------------------------//
$ 

    include XXMenu.inc
    
;--------------------------------------------------------------------------
.code

; #########################################################################
;                                                                         ;
; Процедура субкласирования для окна использующего меню                   ;
;                                                                         ;
; #########################################################################    

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

LOCAL OldhMenu  :HMENU
LOCAL OldWndProc :DWORD

    invoke GetProp, hWin, ADDR szProp_OldWndProc
    mov OldWndProc, eax

    .if uMsg == WM_INITMENUPOPUP    
            
;        PrintDec wParam, "WM_INITMENUPOPUP"

        ; !!! ВНИМАНИЕ !!!
        ; ИСПОЛЬЗОВАНИЕ ФУНКЦИИ RedrawMenu В ОБРАБОТЧИКЕ СООБЩЕНИЯ WM_INITMENUPOPUP
        ; УМЕНЬШИТ БЫСТРОДЕЙСТВИЕ ВАШЕЙ ПРОГРАММЫ.


        ; приходиться вызывать стандартную обработку сообщения, здесь
        ; т.к. возможно использование функции, RedrawMenu в WM_INITMENUPOPUP        ; 

        invoke CallWindowProc,OldWndProc,hWin,uMsg,wParam,lParam    ; d_c
                     
          .if !hMenu && !fAccel
          
                m2m hMenu, wParam             
                mov fPopup, TRUE    
            
            invoke GetStyleMenu, hMenu  ; сделаем меню плоским если стиль требует
            .if eax == STYLE_OFFICE_XP || eax == STYLE_OFFICE_2000 || eax == STYLE_XNET
                invoke SubMenuToOwnerdraw, hMenu       ; Присвоем всем пунктам меню стиль OWNERDRAW            
            .endif
             
            HIWORD lParam   ; системное меню?
            .if eax              
                invoke IsID_ThemeXP_inc, hWin, hMenu  ; Special purpose for windows XP with themes!!!
            .endif
                
          .endif    
          
;        jmp  d_c           |?| - |?|

    .elseif uMsg == WM_UNINITMENUPOPUP
       
;       PrintDec wParam, "WM_UNINITMENUPOPUP"       
        
          mov eax, wParam
          .if hMenu == eax && !fAccel
            mov hMenu, 0            
            HIWORD lParam
            .if eax == MF_SYSMENU               
                invoke IsID_ThemeXP_dec, hWin, wParam  ; Special purpose for windows XP with themes!!!
            .endif             
          .endif
                
        jmp  d_c
        
    .elseif uMsg == WM_MEASUREITEM

     .if !wParam    ; MENU? (wParam == 0 - only menu)     

        m2m OldhMenu, hMenu             ; Это нужно что бы потом, распознать хендл при оброботке "WM_UNINITMENUPOPUP"

        .if !hMenu                      ; установим флаги в соответствии с тем какое меню (main - popup)
            invoke GetMenu, hWin
            mov hMenu, eax
            mov fPopup, FALSE
        .else
            mov fPopup, TRUE    
        .endif
        
        invoke IsMenu, hMenu            ; если не хендл, зачем прорисовывать
        .if !eax                
            jmp no_measure
        .endif
                   
        invoke MeasureItem_Menu, lParam
        
no_measure:
        m2m hMenu, OldhMenu
        mov fPopup, TRUE            
                
     .endif
     
        jmp  d_c          
 
    .elseif uMsg == WM_DRAWITEM
    
     .if !wParam    ; MENU? (wParam == 0 - only menu)     
   
        m2m OldhMenu, hMenu         ; Это нужно что бы потом, распознать хендл при оброботке "WM_UNINITMENUPOPUP"
   
        .if !hMenu                  ; установим флаги в соответствии с тем какое меню (main - popup)
@@:
            invoke GetMenu, hWin
            mov hMenu, eax
            mov fPopup, FALSE
        .else
        
            .if fAccel
                jmp @b
            .else
                mov fPopup, TRUE
            .endif
                        
        .endif
        
        invoke IsMenu, hMenu        ; если не хендл, зачем прорисовывать
        .if !eax                
            jmp no_DrawItem_Menu
        .endif   
   
        invoke DrawItem_Menu, lParam
        
no_DrawItem_Menu:

        m2m hMenu, OldhMenu
        mov fPopup, TRUE
        
     .endif
     
        jmp  d_c     

    .elseif uMsg == WM_ENTERMENULOOP
    
;        PrintDec wParam, "WM_ENTERMENULOOP"
        mov fAccel, FALSE
        jmp  d_c     

    .elseif uMsg == WM_EXITMENULOOP
    
;        PrintDec wParam, "WM_EXITMENULOOP"
        mov fAccel, TRUE
        jmp  d_c

;    .elseif uMsg == WM_SYSCOLORCHANGE
;
;        PrintDec wParam, "WM_SYSCOLORCHANGE"
        
    .elseif uMsg == WM_DESTROY
        invoke RemoveProp, hWin, ADDR szProp_OldWndProc        
        invoke SetWindowLong, hWin, GWL_WNDPROC, OldWndProc        
        jmp  d_c
    .else

d_c:        
        invoke CallWindowProc,OldWndProc,hWin,uMsg,wParam,lParam
        ret
    .endif           
 
    xor eax,eax
    ret
WndProc_Menu endp

; #########################################################################
;                                                                         ;
; Установливает для данного меню (всех подменю), заданный стиль.          ;
;                                                                         ;
; #########################################################################

SetStyleMenu proc h_Menu :HMENU, dwStyle :DWORD

    invoke ChangeStyle, h_Menu, dwStyle

    ret
SetStyleMenu endp

; #########################################################################
;                                                                         ;
; Установливает для данного меню (всех подменю), заданный стиль.          ;
;                                                                         ;
; #########################################################################

ChangeStyle proc  h_Menu :HMENU, dwStyle :DWORD

LOCAL nHightItemCount :DWORD
LOCAL nCount          :DWORD
LOCAL hSubMenu        :HMENU    

    invoke MenuToStyle, h_Menu, dwStyle 
    mov nHightItemCount, $invoke (GetMenuItemCount, h_Menu)
    
    mov nCount, 0

@@: 
    mov hSubMenu, $invoke (GetSubMenu, h_Menu, nCount)
    
    .if hSubMenu
        invoke SubMenuToStyle, hSubMenu, dwStyle
    .endif
    
    inc nCount  
    
    mov eax, nCount
    cmp eax, nHightItemCount    
    jb  @b
    
e_t:    
    ret
ChangeStyle endp

; #########################################################################
;                                                                         ;
; Рекурсивная процедура установки стиля меню, перебирает все итемы в      ;
; подменю и устанавливает стиль для всех меню (выпадающих)                ;
;                                                                         ;
; #########################################################################

SubMenuToStyle proc hSubMenu:HMENU, dwStyle :DWORD

    LOCAL nPos        :DWORD
    LOCAL LastItemID  :UINT
    LOCAL mii         :MENUITEMINFO

    invoke MenuToStyle, hSubMenu, dwStyle

    mov nPos, 0
    mov mii.cbSize, sizeof (MENUITEMINFO)
    mov mii.fMask, MIIM_ID or MIIM_SUBMENU
    jmp s_t

@@: 
    m2m LastItemID, mii.wID
    inc nPos

s_t:   
    invoke GetMenuItemInfo, hSubMenu, nPos, TRUE, ADDR mii
    
    mov eax, LastItemID
    
    cmp eax, mii.wID
    je @f

    .if mii.hSubMenu
    
        invoke SubMenuToStyle, mii.hSubMenu, dwStyle 
    
    .endif

    jmp @b  
    
@@:
    ret
SubMenuToStyle endp

; #########################################################################
;                                                                         ;
; Устанвливает стиль для данного меню.                                    ;
; Возвращает предыдущий стиль.                                            ;  
;                                                                         ;
; #########################################################################

MenuToStyle proc h_Menu :HMENU, dwStyle :DWORD
 
LOCAL mi    :MENUINFO    

    invoke GetStyleMenu, h_Menu
    cmp eax, dwStyle
    je  e_t
    
    push eax                                ; сохраним предыдущий стиль
    mov mi.cbSize, sizeof (MENUINFO)
    mov mi.fMask, MIM_MENUDATA
    m2m mi.dwMenuData, dwStyle
    invoke SetMenuInfo, h_Menu, ADDR mi
    pop eax

e_t:    
    ret
MenuToStyle endp

; #########################################################################
;                                                                         ;
; Процедура обработки сообщения WM_MeasureItem_Menu.                           ;
;                                                                         ;
; #########################################################################

MeasureItem_Menu proc uses ebx ecx lParam:LPARAM

    LOCAL mii         :MENUITEMINFO
;    LOCAL mi          :MENUINFO
    LOCAL ddbinfo     :BITMAP
    LOCAL szBuff[128] :BYTE
    LOCAL hDC         :HDC
    LOCAL StrSize     :SIZEL
    LOCAL RctText     :RECT
    LOCAl TextItemLen :DWORD
    LOCAL ncinfo      :NONCLIENTMETRICS
    LOCAL hfontMenu   :HFONT
    LOCAL iconinfo   :ICONINFO
    LOCAL bmp        :BITMAP

    mov ebx, lParam
    assume ebx: ptr MEASUREITEMSTRUCT
        
       .if [ebx].CtlType == ODT_MENU

                mov mii.cbSize, SIZEOF mii
                mov mii.fMask, MIIM_TYPE or MIIM_DATA or MIIM_STATE
                invoke GetMenuItemInfo,hMenu,[ebx].itemID,FALSE,ADDR mii        
                
                mov eax, mii.fType
                and eax, MFT_SEPARATOR or MFT_STRING or MFT_BITMAP
                
                .if eax == MFT_SEPARATOR
                
                .if fPopup  ; popup
                
                    .if mii.dwItemData
                        mov [ebx].itemHeight, 5 ; не принципиально

                        push 0
                        push 0
                        push hMenu
                        call mii.dwItemData
                        .if eax
                            mov [ebx].itemWidth, eax
                        .else
                            m2m [ebx].itemWidth, LeftBmpWidth
                        .endif                       
                    .else
                        mov [ebx].itemHeight, 6
                        mov [ebx].itemWidth, 8
                    .endif
                                                        
                .else       ; main                
                    mov [ebx].itemHeight, 8
                    mov [ebx].itemWidth, 8                     
                .endif
                    
                .elseif eax == MFT_STRING || [ebx].itemID
                
                    invoke GetMenuString, hMenu, [ebx].itemID, ADDR szBuff, 128, MF_BYCOMMAND
                    mov TextItemLen, eax    
                    mov hDC, $invoke ( GetDC, NULL )
                    
                    
                    mov ncinfo.cbSize, sizeof(NONCLIENTMETRICS)           ; обязательно размер структуры
                    invoke SystemParametersInfo,SPI_GETNONCLIENTMETRICS,\
                                sizeof(NONCLIENTMETRICS),\
                                addr ncinfo, 0                                      ; взять параметры, в том числе Фонта
                                
                    .if eax
                        invoke CreateFontIndirect,  ADDR ncinfo.lfMenuFont         ; создать фонт
                        mov   hfontMenu, eax                                       ; дескриптор  фонта                        
                    .else
                        invoke GetStockObject, DEFAULT_GUI_FONT
                    .endif                    
                    
                    invoke SelectObject, hDC, eax
                    push eax
                    
                    invoke DrawText, hDC, ADDR szBuff, TextItemLen, ADDR RctText, DT_CALCRECT
                    mov eax, RctText.left
                    mov ecx, RctText.right
                    sub ecx, eax
                    mov StrSize.x, ecx
                    mov eax, RctText.top
                    mov ecx, RctText.bottom
                    sub ecx, eax
                    mov StrSize.y, ecx
                  
                    push hDC
                    call SelectObject               ; востановим шрифт
                    invoke DeleteObject, hfontMenu                   
                    invoke ReleaseDC, NULL, hDC
 
                    invoke memfill, ADDR bmp, sizeof(BITMAP), 0
                    .if mii.dwItemData                        
                        ; высота и ширина иконки
                        invoke GetIconInfo, mii.dwItemData,ADDR iconinfo
                        invoke GetObject, iconinfo.hbmColor, sizeof(BITMAP), ADDR bmp
                        invoke DeleteObject, iconinfo.hbmMask
                        invoke DeleteObject, iconinfo.hbmColor                    
                    .endif
                     
                    mov eax, StrSize.y
                    add eax, 7
                    mov ecx, bmp.bmHeight
                    add ecx, 4              ; 2 на кнопку, по 1 для иконки.
                    
                    .if ecx > eax
                        sub ecx, eax
                        add eax, ecx 
                    .endif                                                            
                    mov [ebx].itemHeight, eax       ; высота итема
     
                    mov HeightBorder, eax           ; высота бордюра
                    mov WidthBorder, eax            ; ширина бордюра   

                    .if fPopup  ; popup
                        add [ebx].itemHeight, 2         ; расширим, но закрашивать это не будем
                                        
                        mov eax, WidthBorder
                        add eax, 10           ; сделаем отступы   
                        add StrSize.x, eax    ; увеличим для пункта иконки
                        
                        ; Special case for system menu                        
                        .if [ebx].itemID >= SC_SIZE && [ebx].itemID <= SC_HOTKEY
                            add StrSize.x, 35
                        .endif
                        
                    .else
                        add StrSize.x, 8    ; сделаем отступы по краям, текст по центру 
                    .endif
                    
                    .if TextItemLen
                        ; ВНИМАНИЕ!!! Разобраться с шириной символа TAB в данном шрифте
                        
                        cld                         ; поиск вперёд по строке
                        lea edi, szBuff             ; адрес строки
                        mov al, 09h                 ; искомый символ
                        mov ecx, TextItemLen        ; длина строки
                        repne scasb                 ; поиск символа '\t' в строке
                        jne no_tab                  ; символ '\t' в строке не найден
                        
                        ; сместим ни символ ТАБ
                        mov eax, WidthBorder
                        shr eax, 1
                        add eax, 15                 
                        add StrSize.x, eax          ; смещение от правого края если есть символ Tab
                    
no_tab:             
                    .endif
                    m2m [ebx].itemWidth, StrSize.x  ; ширина итема                    
                    
                                   
                .elseif eax == MFT_BITMAP
                
                    ; retrieve DDB information
                    invoke GetObject, mii.dwTypeData, sizeof(BITMAP), ADDR ddbinfo                
                    m2m [ebx].itemWidth, ddbinfo.bmWidth
                    m2m [ebx].itemHeight, ddbinfo.bmHeight
                
                .endif
                                
        .endif   

    assume ebx: nothing
    ret
MeasureItem_Menu endp

; #########################################################################
;                                                                         ;
; Процедура установки размеров бордюра в левой строне итема (учитываем размер иконки);                           ;
;                                                                         ;
; #########################################################################

SetSizeBorder proc lpTextItem:DWORD, TextItemLen:DWORD, hIcon:DWORD 

    LOCAL hDC         :HDC
    LOCAL StrSize     :SIZEL
    LOCAL RctText     :RECT
    LOCAL ncinfo      :NONCLIENTMETRICS
    LOCAL hfontMenu   :HFONT
    LOCAL iconinfo   :ICONINFO
    LOCAL bmp        :BITMAP

    mov hDC, $invoke ( GetDC, NULL )    
    
    mov ncinfo.cbSize, sizeof(NONCLIENTMETRICS)           ; обязательно размер структуры
    invoke SystemParametersInfo,SPI_GETNONCLIENTMETRICS,\
                sizeof(NONCLIENTMETRICS),\
                addr ncinfo, 0                                      ; взять параметры, в том числе Фонта
                
    .if eax
        invoke CreateFontIndirect,  ADDR ncinfo.lfMenuFont         ; создать фонт
        mov   hfontMenu, eax                                       ; дескриптор  фонта                        
    .else
        invoke GetStockObject, DEFAULT_GUI_FONT
    .endif                    
    
    invoke SelectObject, hDC, eax
    push eax
    
    invoke DrawText, hDC, lpTextItem, TextItemLen, ADDR RctText, DT_CALCRECT
    mov eax, RctText.left
    mov ecx, RctText.right
    sub ecx, eax
    mov StrSize.x, ecx
    mov eax, RctText.top
    mov ecx, RctText.bottom
    sub ecx, eax
    mov StrSize.y, ecx
    
    push hDC
    call SelectObject               ; востановим шрифт
    invoke DeleteObject, hfontMenu                   
    invoke ReleaseDC, NULL, hDC
    
    invoke memfill, ADDR bmp, sizeof(BITMAP), 0
    .if hIcon                  
        ; высота и ширина иконки
        invoke GetIconInfo, hIcon,ADDR iconinfo
        invoke GetObject, iconinfo.hbmColor, sizeof(BITMAP), ADDR bmp
        invoke DeleteObject, iconinfo.hbmMask
        invoke DeleteObject, iconinfo.hbmColor                   
    .endif    
                    
    mov eax, StrSize.y
    add eax, 7
    mov ecx, bmp.bmHeight
    add ecx, 4              ; 2 на кнопку, по 1 для иконки.
    
    .if ecx > eax
        sub ecx, eax
        add eax, ecx 
    .endif                                                            
    mov HeightBorder, eax           ; высота бордюра
    mov WidthBorder, eax            ; ширина бордюра

	ret
SetSizeBorder endp

; #########################################################################
;                                                                         ;
; Процедура обработки сообщения WM_DrawItem.                              ;
;                                                                         ;
; #########################################################################

DrawItem_Menu proc uses ebx lParam:LPARAM

mov ebx, lParam
assume ebx: ptr DRAWITEMSTRUCT

    invoke IsMenu, hMenu
    .if !eax
        jmp e_t
    .endif

  .if [ebx].CtlType == ODT_MENU

    invoke SaveDC, [ebx].hdc
    invoke SetBkMode, [ebx].hdc, TRANSPARENT
    
    invoke GetStyleMenu, hMenu
    
    .if eax == STYLE_OFFICE_XP              ; СТИЛЬ МЕНЮ OFFICE XP
        call DrawItem_MenuXP ;, lParam           ; метод обработки
    .elseif eax == STYLE_OFFICE_2000        ; СТИЛЬ МЕНЮ OFFICE 2000    
        call DrawItem_Menu2000 ;, lParam         ; метод обработки
    .elseif eax == STYLE_XNET               ; СТИЛЬ МЕНЮ OFFICE 2000     
        call DrawItem_MenuXNET
    .elseif eax == STYLE_DEFAULT            ; Default - только с "битмап слева"     
        call DrawItem_MenuDefault        
    .endif
    
    invoke RestoreDC, [ebx].hdc, -1  
  
  .endif  
    
e_t:

assume ebx: nothing
    mov eax,1
    ret
DrawItem_Menu endp

; #########################################################################
;                                                                         ;
; Процедура рисования битмапа в меню (подходит только для системного меню);
;                                                                         ;
; #########################################################################

DrawBmp proc uses ebx hDC:HDC, lpRect:DWORD, hBmp:HBITMAP, uFlags:BYTE

    LOCAL RctBmp                :RECT
    LOCAL GlyphArray[2]         :BYTE
    LOCAL hGlyphFont            :HFONT
    LOCAL OldFont               :HFONT
    LOCAL OldClr                :COLORREF
    LOCAL ncinfo                :NONCLIENTMETRICS
   
        mov ebx, lpRect

        .if hBmp == HBMMENU_POPUP_MINIMIZE  
        
            mov GlyphArray, 30h          
        
        .elseif hBmp == HBMMENU_POPUP_MAXIMIZE
        

            mov GlyphArray, 31h
        
        .elseif hBmp == HBMMENU_POPUP_CLOSE
        
            mov GlyphArray, 72h
            
        .elseif hBmp == HBMMENU_POPUP_RESTORE
            
            mov GlyphArray, 32h
            
        .else        
        
            jmp exit_
        .endif

   ; Шрифт для прорисовки галочки CheckItema.   
   
        mov ncinfo.cbSize, sizeof(NONCLIENTMETRICS)           ; обязательно размер структуры
        invoke SystemParametersInfo,SPI_GETNONCLIENTMETRICS,\
                                  sizeof(NONCLIENTMETRICS),\
                                  addr ncinfo, 0                                      ; взять параметры, в том числе Фонта
        
        
;        .if ncinfo.lfMenuFont.lfHeight > -15
;            mov ncinfo.lfMenuFont.lfHeight, -15
;        .endif
        
        ;   mov ncinfo.lfMenuFont.lfWidth, 14
        
        mov ncinfo.lfMenuFont.lfCharSet, DEFAULT_CHARSET
        
        invoke memfill, ADDR ncinfo.lfMenuFont.lfFaceName, LF_FACESIZE, 0
        invoke szCopy, ADDR szGlyphFont, ADDR ncinfo.lfMenuFont.lfFaceName                             
        invoke CreateFontIndirect,  ADDR ncinfo.lfMenuFont
        mov hGlyphFont, eax

        invoke GetTextColor,hDC
        mov OldClr, eax

        invoke SetBkMode,hDC,TRANSPARENT
        invoke SelectObject, hDC, hGlyphFont
        mov OldFont, eax
        
        xor eax, eax                    ; состояние вывода
        mov al, uFlags 
        and al, SELECT or UNSELECT
        
        .if al == GRAY

            invoke DarkenColor, 8, $invoke ( GetSysColor, COLOR_GRAYTEXT )   ; запрещённый
            invoke SetTextColor, hDC, eax
            mov OldClr, eax
            jmp @f
        
        .elseif al == UNSELECT
@@:
            mov eax, [ebx].RECT.left        ;  прямоугольник галочки
            mov RctBmp.left, eax
            mov eax, [ebx].RECT.top
            mov RctBmp.top, eax
            mov eax, [ebx].RECT.left
            add eax, WidthBorder       
            mov RctBmp.right, eax
            mov eax, [ebx].RECT.bottom
            mov RctBmp.bottom, eax        
            
        .elseif al == SELECT

            invoke DarkenColor, 8, $invoke ( GetSysColor, COLOR_GRAYTEXT )   ; запрещённый
            invoke SetTextColor, hDC, eax
            mov OldClr, eax
             
            mov eax, [ebx].RECT.left        ;  прямоугольник галочки
            inc eax
            mov RctBmp.left, eax
            mov eax, [ebx].RECT.top
            inc eax
            mov RctBmp.top, eax            
            mov eax, [ebx].RECT.left
            add eax, WidthBorder
            inc eax
            mov RctBmp.right, eax            
            mov eax, [ebx].RECT.bottom
            inc eax
            mov RctBmp.bottom, eax                   
           
            invoke DrawText, hDC, ADDR GlyphArray, 1, ADDR RctBmp, DT_CENTER or DT_VCENTER or DT_SINGLELINE
            
            mov eax, [ebx].RECT.left        ;  прямоугольник галочки
            dec eax
            mov RctBmp.left, eax
            mov eax, [ebx].RECT.top
            dec eax
            mov RctBmp.top, eax
            mov eax, [ebx].RECT.left            
            add eax, WidthBorder
            dec eax       
            mov RctBmp.right, eax
            mov eax, [ebx].RECT.bottom
            dec eax
            mov RctBmp.bottom, eax
            invoke SetTextColor,hDC, OldClr
                                
        .endif
                      
        invoke DrawText, hDC, ADDR GlyphArray, 1, ADDR RctBmp, DT_CENTER or DT_VCENTER or DT_SINGLELINE
        invoke SelectObject,hDC, OldFont           ; востановим прежний шрифт
        invoke DeleteObject, hGlyphFont
        invoke SetTextColor,hDC, OldClr       
        
exit_:

        
    ret
DrawBmp endp

; =========================================================================
;               Экспортируеме функции управления меню
;
; #########################################################################
;                                                                         ;
; Процедура перебирает изменившееся в теле программы меню, и изменяет     ;  
; стиль на OWNERDRAW итемов если они были добавлены.                      ;
;                                                                         ;
; #########################################################################

PUBLIC RedrawMenu

RedrawMenu proc uses ebx hWin :HWND, h_Menu :HMENU, dwStyle :DWORD
    
    invoke IsWindow, hWin
    mov ebx, eax
    invoke IsMenu, h_Menu
    .if !ebx || !eax
        return FALSE
    .endif

    .if dwStyle == STYLE_DEFAULT
;        call UnInstallHook
        ;invoke SetOldWndProc, hWin
        invoke OwnerDrawToNormal, h_Menu    ; то уберём со всех итемов стиль OWNERDRAW
;        je  @f
    .elseif dwStyle == STYLE_OFFICE_2000 || dwStyle == STYLE_XNET
;        call UnInstallHook
        invoke UpItemOwnDrToNormal, h_Menu        
        invoke MainMenuToOwnerdraw, h_Menu     ; Присвоем всем пунктам меню стиль OWNERDRAW, кроме итемов верхнего уровня
    
    .elseif dwStyle == STYLE_OFFICE_XP
        
        call IsShellType
        .if eax ==  WIN_2000 || eax == WIN_XP
            invoke SubMenuToOwnerdraw, h_Menu      ; Присвоем всем пунктам меню стиль OWNERDRAW
        .else
            invoke MainMenuToOwnerdraw, h_Menu     ; Присвоем всем пунктам меню стиль OWNERDRAW, кроме итемов верхнего уровня        
        .endif
            
    .endif

    invoke SetNewWndProc, hWin, ADDR WndProc_Menu    

;@@:

    invoke SetStyleMenu, h_Menu, dwStyle    
    invoke GetMenu, hWin    
    .if eax == h_Menu
        invoke DrawMenuBar, hWin
    .endif
    
    mov eax, TRUE
    ret
RedrawMenu endp

; #########################################################################
;                                                                         ;
; Выберает стиль установленный для данного меню.                          ;  
;                                                                         ;
; #########################################################################

PUBLIC GetStyleMenu

GetStyleMenu proc h_Menu :HMENU

LOCAL mi    :MENUINFO 
    
    mov mi.cbSize, sizeof (MENUINFO)
    mov mi.fMask, MIM_MENUDATA    
    invoke GetMenuInfo, h_Menu, ADDR mi
        
    mov eax, mi.dwMenuData 
   
    ret
GetStyleMenu endp

; #########################################################################
;                                                                         ;
; Процедура установки иконки для определённых итемов.                     ;
;                                                                         ;
; #########################################################################

PUBLIC SetMenuItemIcon

SetMenuItemIcon proc h_Menu:HMENU, ItemID:DWORD, hIcon:HICON

   LOCAL mii      :MENUITEMINFO
   
    mov mii.cbSize, sizeof (MENUITEMINFO)
    mov mii.fMask, MIIM_DATA   
    m2m mii.dwItemData, hIcon
    invoke SetMenuItemInfo, h_Menu, ItemID, FALSE, ADDR mii

    ret
SetMenuItemIcon endp

; #########################################################################
;                                                                         ;
; Процедура установки иконки для групы пунктов меню.                     ;
;                                                                         ;
; #########################################################################

PUBLIC SetMenuIcon

SetMenuIcon proc h_Menu:HMENU, hImageList:HIMAGELIST, uNumButtons:DWORD, lpButtons:DWORD 

mov ebx, lpButtons

    .while uNumButtons
       
        invoke ImageList_GetIcon, hImageList, [ebx].MNUBUTTON.nIcon, ILD_NORMAL
        invoke SetMenuItemIcon, h_Menu, [ebx].MNUBUTTON.idItem, eax
        add ebx, sizeof (MNUBUTTON)
        dec uNumButtons

    .endw

    ret
SetMenuIcon endp

; #########################################################################
;                                                                         ;
; Процедура установки иконки для определённых итемов.                     ;
;                                                                         ;
; #########################################################################

PUBLIC SetDisableSelect

SetDisableSelect proc uses edx bShow:BYTE

    xor eax, eax
    mov al, fSelection
    mov dl, bShow
    mov fSelection, dl

    ret
SetDisableSelect endp

;; #########################################################################
;;                                                                         ;
;; Процедура установки фонового bmp для всплывающих меню.                  ;
;;                                                                         ;
;; #########################################################################
;
;PUBLIC SetBmpBackground
;
;SetBmpBackground proc hBmp:HBITMAP, dwStyle:DWORD
;    .if hBmp
;        .if dwStyle
;            m2m StyleBackground, dwStyle
;        .endif
;        m2m hBmpBackground, hBmp
;    .else
;        mov hBmpBackground, 0
;    .endif
;
;    ret
;SetBmpBackground endp

; #########################################################################
;                                                                         ;
; Процедура установки бордюра в левой строне всплывающего меню            ;
;                                                                         ;
; #########################################################################

PUBLIC AddLeftBorder

AddLeftBorder proc h_Menu:HMENU, DrawBorderProc:DWORD, Break:BOOLEAN

    LOCAL mii   :MENUITEMINFO
    
    invoke IsMenu, h_Menu
    .if !eax
        return 0
    .endif
    
    mov mii.cbSize, SIZEOF mii
    mov mii.fMask, MIIM_FTYPE or MIIM_ID or MIIM_DATA    
    mov mii.fType, MFT_SEPARATOR or MFT_OWNERDRAW
    mov mii.wID, 0
    m2m mii.dwItemData, DrawBorderProc
    invoke InsertMenuItem, h_Menu, 0, TRUE, ADDR mii 

;    invoke memfill, ADDR mii, sizeof(MENUITEMINFO), 0

    mov mii.fMask, MIIM_FTYPE
    invoke GetMenuItemInfo, h_Menu, 1, TRUE, ADDR mii 

    .if Break
        or mii.fType, MFT_MENUBARBREAK
    .else
        or mii.fType, MFT_MENUBREAK
    .endif
    invoke SetMenuItemInfo, h_Menu, 1, TRUE, ADDR mii

    ret
AddLeftBorder endp

; #########################################################################
;                                                                         ;
; Процедура удаления бордюра в левой строне всплывающего меню             ;
;                                                                         ;
; #########################################################################

PUBLIC RemoveLeftBorder

RemoveLeftBorder proc h_Menu:HMENU

    LOCAL mii   :MENUITEMINFO
     
    invoke IsMenu, h_Menu
    .if !eax
        return 0
    .endif 
        
    mov mii.cbSize, SIZEOF mii
    mov mii.fMask, MIIM_FTYPE or MIIM_DATA 
    invoke GetMenuItemInfo, h_Menu, 0, TRUE, ADDR mii 
    
    .if mii.fType & MFT_SEPARATOR && mii.dwItemData   
        invoke RemoveMenu, h_Menu, 0, MF_BYPOSITION
        
        mov mii.fMask, MIIM_FTYPE
        invoke GetMenuItemInfo, h_Menu, 0, TRUE, ADDR mii
        .if mii.fType & MFT_MENUBARBREAK
            xor mii.fType, MFT_MENUBARBREAK
        .else
            xor mii.fType, MFT_MENUBREAK
        .endif     
        
        invoke SetMenuItemInfo, h_Menu, 0, TRUE, ADDR mii
    .else
        return 0
    .endif
    
    ret
RemoveLeftBorder endp


include ToOwnerMenu.inc
;include Color.inc
;include Gradient.inc
include Office_xp.inc
include Office_2000.inc
include XNET.inc
include Default.inc
;include Hook.inc