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

; #########################################################################
;                                                                         ;
; Установливает для все пунктов меню стиль OWNERDRAW                      ;
;                                                                         ;
; #########################################################################

MainMenuToOwnerdraw proc h_Menu :HMENU

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

;    invoke SubMenuToOwnerdraw, h_Menu       ; если главное меню, то итемы верхнего уровня тоже конвертирум  

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


@@:
    mov hSubMenu, $invoke (GetSubMenu, h_Menu, nCount)
        
    .if hSubMenu
        invoke SubMenuToOwnerdraw, hSubMenu
    .endif
    
    inc nCount
        
    mov eax, nCount
    cmp eax, nHightItemCount    
    jb  @b
    
    ret
MainMenuToOwnerdraw endp

; #########################################################################
;                                                                         ;
; Установливает для все пунктов подменю стиль OWNERDRAW                   ;
;                                                                         ;
; #########################################################################

SubMenuToOwnerdraw proc hSubMenu:HMENU

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

    mov nPos, 0
    mov mii.cbSize, sizeof (MENUITEMINFO)
    mov mii.fMask, MIIM_SUBMENU or MIIM_FTYPE or MIIM_ID
    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

    mov eax, mii.fType                      ; если у итема уже иметься стиль OWNERDRAW, тогда идём дальше 
    and eax, MFT_OWNERDRAW
    cmp eax, MFT_OWNERDRAW
    je  y_o                                 ; пропускаем установку стиля
    
    or mii.fType, MFT_OWNERDRAW
    
    .if mii.wID == 0                        ; если пункт меню имеет ID = 0, установим случайный ID
        mov eax, LastItemID
        add eax, 556
t_id:        
        .if eax <= 7fffh ; не должно превышать - 32767, для обычного меню; и 61440 для системного
            sub eax, LastItemID
            sub eax, 241
            jmp t_id
            
        .elseif eax <= 0        
            add eax, LastItemID
            add eax, 384
            jmp t_id
            
        .endif
                
        mov mii.wID, eax
    .endif
     
    invoke SetMenuItemInfo, hSubMenu, nPos, TRUE, ADDR mii

y_o:
    .if mii.hSubMenu
    
        invoke SubMenuToOwnerdraw, mii.hSubMenu 
    
    .endif

    jmp @b  
    
@@:
    ret
SubMenuToOwnerdraw endp

; #########################################################################
;                                                                         ;
; Убирает для все пунктов меню стиль OWNERDRAW                            ;
;                                                                         ;
; #########################################################################

OwnerDrawToNormal proc h_Menu :HMENU

LOCAL nHightItemCount :DWORD
LOCAL nCount          :DWORD
LOCAL hSubMenu        :HMENU
LOCAL mii             :MENUITEMINFO

    mov mii.cbSize, sizeof (MENUITEMINFO)
    mov mii.fMask, MIIM_FTYPE or MIIM_DATA
    
    mov nHightItemCount, $invoke (GetMenuItemCount, h_Menu)
    
    mov nCount, 0

@@: 
    mov hSubMenu, $invoke (GetSubMenu, h_Menu, nCount)
    invoke GetMenuItemInfo, h_Menu, nCount, TRUE, ADDR mii    

    mov eax, mii.fType                      ; если у итема уже иметься стиль OWNERDRAW, тогда идём дальше 
    and eax, MFT_OWNERDRAW
    cmp eax, MFT_OWNERDRAW
    pushfd
    
    ; пункт меню сепартор, для отображения бордюра слева
    .if (mii.fType & MFT_SEPARATOR) && mii.dwItemData
        popfd
        je n_y_o                            ; пропускаем установку стиля
        or mii.fType, MFT_OWNERDRAW
    .else
        popfd
        jne n_y_o                           ; пропускаем установку стиля
        xor mii.fType, MFT_OWNERDRAW
    .endif
    
    invoke SetMenuItemInfo, h_Menu, nCount, TRUE, ADDR mii 
 
n_y_o: 
  
    .if hSubMenu
        invoke SubMenuToNormal, hSubMenu
    .endif

    inc nCount  
    
    mov eax, nCount
    cmp eax, nHightItemCount    
    jb  @b    
    
    ret
OwnerDrawToNormal endp

; #########################################################################
;                                                                         ;
; Убирает для все пунктов подменю стиль OWNERDRAW                         ;
;                                                                         ;
; #########################################################################

SubMenuToNormal proc hSubMenu:HMENU

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

    mov nPos, 0
    mov mii.cbSize, sizeof (MENUITEMINFO)
    mov mii.fMask, MIIM_ID or MIIM_FTYPE or MIIM_SUBMENU or MIIM_DATA
    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

    mov eax, mii.fType                      ; если у итема уже иметься стиль OWNERDRAW, тогда идём дальше 
    and eax, MFT_OWNERDRAW
    cmp eax, MFT_OWNERDRAW
    pushfd
    
    ; пункт меню сепартор, для отображения бордюра слева
    .if (mii.fType & MFT_SEPARATOR) && mii.dwItemData
        popfd
        je n_y_o                            ; пропускаем установку стиля
        or mii.fType, MFT_OWNERDRAW            
    .else
        popfd
        jne n_y_o                           ; пропускаем установку стиля
        xor mii.fType, MFT_OWNERDRAW   
    .endif
    
    invoke SetMenuItemInfo, hSubMenu, nPos, TRUE, ADDR mii    
    
n_y_o:

    .if mii.hSubMenu
    
        invoke SubMenuToNormal, mii.hSubMenu 
    
    .endif

    jmp @b  
    
@@:
    ret  
SubMenuToNormal endp

; #########################################################################
;                                                                         ;
; Убирает для все пунктов меню стиль OWNERDRAW                            ;
;                                                                         ;
; #########################################################################

UpItemOwnDrToNormal proc h_Menu :HMENU

LOCAL nHightItemCount :DWORD
LOCAL nCount          :DWORD
LOCAL hSubMenu        :HMENU
LOCAL mii             :MENUITEMINFO

    mov mii.cbSize, sizeof (MENUITEMINFO)
    mov mii.fMask, MIIM_FTYPE
    
    mov nHightItemCount, $invoke (GetMenuItemCount, h_Menu)
    
    mov nCount, 0

@@: 
    invoke GetMenuItemInfo, h_Menu, nCount, TRUE, ADDR mii
 
    mov eax, mii.fType                      ; если у итема уже иметься стиль OWNERDRAW, тогда идём дальше 
    and eax, MFT_OWNERDRAW
    cmp eax, MFT_OWNERDRAW
    jne n_o                                ; пропускаем установку стиля
    
    xor mii.fType, MFT_OWNERDRAW 
    invoke SetMenuItemInfo, h_Menu, nCount, TRUE, ADDR mii 
 
n_o:   
 
    inc nCount  
    
    mov eax, nCount
    cmp eax, nHightItemCount    
    jb  @b    
    
    ret
UpItemOwnDrToNormal endp

; #########################################################################
;                                                                         ;
; Определяет версию ОС Windows                                            ;
;                                                                         ;
; #########################################################################

IsShellType proc

LOCAL osvi  :OSVERSIONINFO
LOCAL winVer:DWORD

    mov osvi.dwOSVersionInfoSize, sizeof (OSVERSIONINFO)
    call GetVersion
    mov winVer, eax
    .if winVer < 80000000h
        ; /*NT */
        invoke GetVersionEx, ADDR osvi 
    
        .if osvi.dwMajorVersion == 5h && osvi.dwMinorVersion == 1h      
            return WIN_XP
        .elseif osvi.dwMajorVersion==5h && osvi.dwMinorVersion==0h
            return WIN_2000
        .elseif osvi.dwMajorVersion==4h    
            return WIN_NT4    
        .endif
        return WIN_NT3
    
    .elseif al < 4
    
        return WIN_32s
     
    .else
    
        invoke GetVersionEx, ADDR osvi        
        .if osvi.dwMajorVersion==4h && osvi.dwMinorVersion==10h
            return WIN_98
        .elseif osvi.dwMajorVersion==4h && osvi.dwMinorVersion==90h
            return WIN_ME
        .else
            return WIN_95            
        .endif
        
    .endif
    
    mov eax, 0
    ret
IsShellType endp

; #########################################################################
;                                                                         ;
; Для ОС XP, при использовании тем изменяет, ID некоторых итемов, для     ; 
; системного меню                                                         ;
; Special purpose for windows XP with themes!!!                           ;
;                                                                         ;
; #########################################################################

IsID_ThemeXP_inc proc hWin :HWND, h_Menu :HMENU

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

    call IsShellType
    .if eax != WIN_XP
        jmp e_t
    .endif

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

@@: 
    m2m LastItemID, mii.wID
    inc nPos

s_t:
    invoke GetMenuItemInfo, h_Menu, nPos, TRUE, ADDR mii
    
    mov eax, LastItemID
    
    cmp eax, mii.wID
    je e_t

    ; синхронизируем со стилями в Windows XP (Special purpose for windows XP with themes!!!)
    .if mii.wID == SC_RESTORE
        mov mii.wID, SC_RESTORE+1
    .elseif mii.wID == SC_CLOSE
        mov mii.wID, SC_CLOSE+1
    .elseif mii.wID == SC_MINIMIZE
        mov mii.wID, SC_MINIMIZE+1
    .endif      
        
    invoke SetMenuItemInfo, h_Menu, nPos, TRUE, ADDR mii

    jmp @b  
    
e_t:
    
    ret
IsID_ThemeXP_inc endp

; #########################################################################
;                                                                         ;
; Для ОС XP, при использовании тем изменяет, ID некоторых итемов, для     ; 
; системного меню                                                         ;
; Special purpose for windows XP with themes!!!                           ; 
;                                                                         ;
; #########################################################################

IsID_ThemeXP_dec proc hWin :HWND, h_Menu :HMENU

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

    call IsShellType
    .if eax != WIN_XP        
        jmp e_t
    .endif
    
    mov nPos, 0
    mov mii.cbSize, sizeof (MENUITEMINFO)
    mov mii.fMask, MIIM_ID
    jmp s_t

@@: 
    m2m LastItemID, mii.wID
    inc nPos

s_t:
    invoke GetMenuItemInfo, h_Menu, nPos, TRUE, ADDR mii
    
    mov eax, LastItemID
    
    cmp eax, mii.wID
    je e_t

    ; синхронизируем со стилями в Windows XP (Special purpose for windows XP with themes!!!)
    .if mii.wID == SC_RESTORE+1
        mov mii.wID, SC_RESTORE
    .elseif mii.wID == SC_CLOSE+1
        mov mii.wID, SC_CLOSE
    .elseif mii.wID == SC_MINIMIZE+1
        mov mii.wID, SC_MINIMIZE
    .endif      
    
    invoke SetMenuItemInfo, h_Menu, nPos, TRUE, ADDR mii

    jmp @b  
    
e_t:
    
    ret
IsID_ThemeXP_dec endp

IsShadowEnabled proc uses edx

    LOCAL bEnabled :DWORD

    call IsShellType
    
    .if eax == WIN_XP

        invoke SystemParametersInfo, SPI_GETDROPSHADOW, 0,ADDR bEnabled, 0

        .if !bEnabled
            mov eax, FALSE 
            ret
        .else
            mov eax, TRUE
            ret
        .endif    
    
    .else
        mov eax, FALSE 
        ret
    .endif 

    ret
IsShadowEnabled endp