;	mov1 macro a, b
;		mov eax, b
;		mov a, eax
;	endm
;
;	xora macro
;		xor eax, eax
;	endm
;
;	xorb macro
;		xor ebx, ebx
;	endm
;
;	xord macro
;		xor edx, edx
;	endm

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

; #########################################################################
;                                                                         ;
; Процедура рисования тени (градиентов) в меню - стиль XP                 ;                           ;
;  
;hDC:HDC         - контекст устройства где будет рисоваться тень (градиент)
;lpRect:DWORD    - указатель на прямоугольник тени (градиентта)
;AlignWidth:BYTE - устанавливает где будет находиться тёмная сторона
;                тени (градиентта) по горизонтали, может принимать значения
;                DARK_LEFT   - слева - направо (слева темнее)
;                DARK_RIGHT  - справа - налево (справа темнее)
;                DARK_NONE   - нет горизонтальной состовляющей градиента.
;AlignHeight:BYTE - устанавливает где будет находиться тёмная сторона
;                тени (градиентта) по вертекали, может принимать значения
;                DARK_UP     - сверху - вниз (сверху темнее)
;                DARK_DOWN   - снизу - вверх (снизу темнее)
;                DARK_NONE   - нет вертикальной состовляющей градиента.
;nHorizDark:BYTE - степень затемнения по горизонтпли (~ 0 -  (max)). !?!
;nVertDark:BYTE  - степень затемнения по вертекали (~ 0 -  (max)). !?!
;
; #########################################################################

DrawShade proc uses ebx hDC :HDC, lpRect:DWORD, AlignWidth :BYTE, AlignHeight :BYTE, 
                             nHorizDark :BYTE, nVertDark :BYTE

    LOCAL X1, Y1            :DWORD
    LOCAL nWidth, nHeight   :DWORD
    LOCAL cnWidth, cnHeight   :DWORD
    LOCAL tClr              :COLORREF
        
        
        mov ebx, lpRect
        
        m2m nWidth, [ebx].RECT.right
        mov eax, [ebx].RECT.left
        sub nWidth, eax                 ; ширина градиента
        m2m cnWidth, nWidth 
        
        m2m nHeight, [ebx].RECT.bottom
        mov eax, [ebx].RECT.top
        sub nHeight, eax                ; высота градиента
        m2m cnHeight, nHeight
        
  
        .while nHeight
 
            m2m Y1, [ebx].RECT.bottom
            mov eax, nHeight 
            sub Y1, eax
  
            push nWidth
            .while nWidth
            
                m2m X1, [ebx].RECT.right
                mov eax, nWidth
                sub X1, eax
                mov tClr, $invoke ( GetPixel, hDC, X1, Y1 )
                ; направление горизонтальной состовляющей градиента
                .if AlignWidth == DARK_LEFT                         ; слева - направо (слева темнее)
                    mov eax, nWidth
                .elseif AlignWidth == DARK_RIGHT                    ; справа - налево (справа темнее)
                    mov eax, cnWidth
                    sub eax, nWidth                    
                .elseif AlignWidth == DARK_NONE                     ; нет горизонтальной состовляющей градиента
                    jmp @f               
                .endif                
                
                invoke IntMul, eax, DWORD PTR nHorizDark    ; степень затемнения по горизонтпли (~ 0 - 15 (max)).
                invoke DarkenColor, eax, tClr
                mov tClr, eax
                
@@:
                ; направление вертикальной состовляющей градиента
                .if AlignHeight == DARK_UP                          ; сверху - вниз (сверху темнее)
                    mov eax, nHeight                    
                .elseif AlignHeight == DARK_DOWN                    ; снизу - вверх (снизу темнее)
                    mov eax, cnHeight 
                    sub eax, nHeight
                .elseif AlignHeight == DARK_NONE                    ; нет вертикальной состовляющей градиента
                    jmp @f    
                .endif                
                
                invoke IntMul, eax, DWORD PTR nVertDark     ; степень затемнения по вертекали (~ 0 - 15 (max)).
                invoke DarkenColor, eax, tClr            
                mov tClr, eax
@@:
            
                invoke SetPixel, hDC, X1, Y1, tClr
                         
                dec nWidth
            
            .endw
            pop nWidth
  
         dec nHeight        
        .endw  
  
    ret
DrawShade endp

Gradient_Fill proc uses edi ebx hDC:HDC, pRect:DWORD, StartColor:COLORREF, EndColor:COLORREF, dwMode:BOOLEAN

    LOCAL vert[2]	:TRIVERTEX
    LOCAL Index		:GRADIENT_RECT

	mov edi, pRect
	    
    m2m vert.x, [edi].RECT.left
	m2m vert.y, [edi].RECT.top
	GetRValue StartColor
	shl eax, 8     ; ax  * 2^4 (256)
	mov DWORD PTR vert.Red, eax
	GetGValue StartColor
	shl eax, 8     ; ax  * 2^4 (256)
	mov DWORD PTR vert.Green, eax
	GetBValue StartColor
	shl eax, 8     ; ax  * 2^4 (256)
	mov DWORD PTR vert.Blue, eax
	mov vert.Alpha, 0
	
	mov ebx, sizeof TRIVERTEX
	
	m2m vert[ebx].x, [edi].RECT.right
	m2m vert[ebx].y, [edi].RECT.bottom
	GetRValue EndColor
	shl eax, 8     ; eax  * 2^4 (256)
	mov DWORD PTR vert[ebx].Red, eax
	GetGValue EndColor
	shl eax, 8     ; eax  * 2^4 (256)
	mov DWORD PTR vert[ebx].Green, eax
	GetBValue EndColor
	shl eax, 8     ; eax  * 2^4 (256)
	mov vert[ebx].Blue, ax
	mov vert[ebx].Alpha, 0
	
	mov Index.UpperLeft, 0
	mov Index.LowerRight, 1	
	
	.if dwMode
	   mov eax, GRADIENT_FILL_RECT_V
	.else
	   mov eax, GRADIENT_FILL_RECT_H
	.endif
	
	   invoke GradientFill, hDC, ADDR vert, 2, ADDR Index, 1, eax
    
    return 0
Gradient_Fill endp