Page 3 of 3

Re: Desktop Alerts

PostPosted: Thu Mar 10, 2016 10:15 pm
by Silvio.Falconi
Antonio,
pls see the METHOD DesktopAlertSettings .
it not save the new ntrasparency value ( data ::nlevel) and on button Preview not refresh the desktopalert window

a Question when I edit on DesktopAlertSettings and finish the ::ntimer it close the obj . How I can make to deactivate de timer and reactivate the timer wjen I exit from this dialog ?


New code

I add the possibility to insert a user menupopup easy with

oAlert:aMnuUser := { {"Option1", { || MsgInfo("1") } },;
{"Option2", { || MsgInfo("2") } } }

first the class create the user menuitems then the menupopup procedure add a internal item desktopAlert settings


the new code


Code: Select all  Expand view

 
#include "fivewin.ch"
#include "Slider.ch"
#include "constant.ch"


#define CW_USEDEFAULT      32768
#define SRCCOPY 13369376

#define DT_TOP              0x00000000
#define DT_LEFT             0x00000000
#define DT_CENTER           0x00000001
#define DT_RIGHT            0x00000002
#define DT_VCENTER          0x00000004
#define DT_BOTTOM           0x00000008
#define DT_WORDBREAK        0x00000010
#define DT_SINGLELINE       0x00000020
#define DT_EXPANDTABS       0x00000040
#define DT_TABSTOP          0x00000080
#define DT_NOCLIP           0x00000100
#define DT_EXTERNALLEADING  0x00000200
#define DT_CALCRECT         0x00000400
#define DT_NOPREFIX         0x00000800
#define DT_INTERNAL         0x00001000

#define CS_DROPSHADOW       0x00020000


//=========================================================================
//
// File:    test6
// Created:
//
// Project: desktop Alert
//
//=========================================================================



#include "FiveWin.ch"

//----------------------------------------------------------------------------//

function Main()

   local oWnd

   DEFINE WINDOW oWnd TITLE "Click me for a desktop notification"

   ACTIVATE WINDOW oWnd ;
          ON CLICK ShowAlert()

return nil

//----------------------------------------------------------------------------//

function ShowAlert( oWnd )

   local oAlert := TDesktopAlert():New( 100, 100, 250, 250, oWnd, .T., CLR_HRED, CLR_WHITE )

   oAlert:cHeader  = "Desktop alert"
   oAlert:cBody    = "This a sample text area."+CRLF+"This a sample text area."
   oAlert:cFoot    = "this is the footer area"

   oAlert:cBmpHeader = "C:\work\fwh\bitmaps\16x16\help.bmp"
   oAlert:cBmpFoot   = "C:\work\fwh\bitmaps\16x16\help.bmp"
   oAlert:cBmpLeft   = "C:\work\fwh\bitmaps\16x16\mail.bmp"

   oAlert:lLineHeader = .T.
   oAlert:lBorder     = .T.

   // These are not working yet
   oAlert:lBtnClose   = .T.
   oAlert:lBtnDown    = .T.
   oAlert:lSplitHdr   = .T.

  oAlert:aMnuUser  := {  {"Option1", { || MsgInfo("1") } },;
                         {"Option2", { || MsgInfo("2") } }   }



return nil




//----------------------------------------------------------------------------//
//----------------------------------------------------------------------------//

CLASS TDesktopAlert FROM TWindow  //from c5Tooltip

      CLASSDATA lRegistered AS LOGICAL

      DATA lSplitHdr    AS LOGICAL INIT .f.
      DATA lLeft        AS LOGICAL INIT .f.

      DATA lLineHeader  AS LOGICAL INIT .f.
      DATA lLineFoot    AS LOGICAL INIT .F.
      DATA lBorder      AS LOGICAL INIT .t.


      DATA cHeader      AS CHARACTER INIT  ""
      DATA cBmpLeft     AS CHARACTER INIT  ""
      DATA cBody        AS CHARACTER INIT  ""
      DATA cBmpFoot     AS CHARACTER INIT  ""
      DATA cFoot        AS CHARACTER INIT  ""
      DATA lRightAlignBody AS LOGICAL INIT .F.

      DATA cLibHeader
      DATA cBmpHeader
      DATA cLibLeft
      DATA cLibFoot
      DATA cTumbNail    AS CHARACTER INIT ""
      DATA cHeader2     AS CHARACTER INIT  space(255)

      DATA nClrPane2
      DATA nClrBorder   AS NUMERIC INIT 0
      DATA nClrSepara1  AS NUMERIC INIT RGB(157,188,219)
      DATA nClrSepara2  AS NUMERIC INIT CLR_WHITE

      DATA nClrTextHeader
      DATA nClrTextBody
      DATA nClrTextFoot

      DATA oFontHdr
      DATA oFontHdr2
      DATA oFontBody
      DATA oFontPie

      DATA aHeader   AS ARRAY INIT {0,0,0,0}
      DATA aHeader2  AS ARRAY INIT {0,0,0,0}
      DATA aBody     AS ARRAY INIT {0,0,0,0}
      DATA aLeft     AS ARRAY INIT {0,0,0,0}
      DATA aRight    AS ARRAY INIT {0,0,0,0}
      DATA aFoot     AS ARRAY INIT {0,0,0,0}
      DATA aBtnClose AS ARRAY INIT {0,0,0,0}

      DATA nWRadio
      DATA nHRadio
      DATA nGetColor

      DATA aOldPos, nOldRow, nOldCol
      DATA hRgn
      DATA nMResize

      DATA bBmpLeft

      DATA nFixWidth
      DATA nFixHeight

      DATA bOwnerDraw

      DATA oTimer, nTimer

      DATA lBtnClose       AS LOGICAL INIT .t.
      DATA aBtnClose       AS ARRAY INIT {0,0,0,0}
      DATA lOverClose      AS LOGICAL INIT .F.
      DATA lOverDown        AS LOGICAL INIT .F.
      DATA aBtndown        AS ARRAY INIT {0,0,0,0}
      DATA lBtnDown        AS LOGICAL INIT .f.

      DATA nOver
      DATA lAlert          AS LOGICAL INIT .t.
      DATA nOption
      DATA bAction


      DATA aItems
      DATA aCoors
      DATA nLevel
      DATA nDuration
      DATA aMnuUser      AS ARRAY


      METHOD New( nTop, nLeft, nWidth, nHeight, oWnd, lDisenio, nClrPane, ;
                  nClrPane2, nClrText, nWRadio, nHRadio,aItems,nLevel,aMnuUser) CONSTRUCTOR
      METHOD Default ()
      METHOD Destroy()  INLINE ::oFontHdr :End(),;
                               ::oFontHdr2:End(),;
                               ::oFontBody:End(),;
                               ::oFontPie :End(),;
                               DeleteObject( ::hRgn ),;
                               ::Super:Destroy()
      METHOD EndPaint() INLINE ::nPaintCount--,EndPaint( ::hWnd, ::cPS ), ::cPS := nil, ::hDC := nil, 0
      METHOD Display()  INLINE ::BeginPaint(),::Paint(),::EndPaint(),0
      METHOD Paint   ()
      METHOD PaintHdr ( hDC, rc )
      METHOD PaintHdr2( hDC, rc )
      METHOD PaintBody( hDC, rc )
      METHOD PaintFoot( hDC, rc )

      METHOD HandleEvent( nMsg, nWParam, nLParam )
      METHOD ReSize( nSizeType, nWidth, nHeight )
      METHOD lHeader() INLINE !empty( ::cHeader )
      METHOD lFoot()   INLINE !empty( ::cFoot )
      METHOD GetSize()
      METHOD SetSize( nWidth, nHeight ) INLINE ::Super:SetSize( nWidth, nHeight, .t. )

      METHOD BtnDown( hDC,nTop,nLeft )
      METHOD BtnClose( hDC,nTop,nLeft )
      METHOD LButtonDown( nRow, nCol, nFlags )
      METHOD MouseMove  ( nRow, nCol, nFlags )
      METHOD LButtonUp  ( nRow, nCol, nFlags )
      METHOD GetItems()
      METHOD SetItems( aItems )
      METHOD PopMenu( nRow, nCol, nKey )  // PopUp menu options
      METHOD DesktopAlertSettings

ENDCLASS

//----------------------------------------------------------------------------//

METHOD New( nTop, nLeft, nWidth, nHeight, oWnd, lDisenio, nClrPane, nClrPane2,;
            nClrText, nWRadio, nHRadio,aItems,nLevel,aMnuUser) CLASS TDesktopAlert

   DEFAULT nClrPane  := CLR_WHITE
   DEFAULT nClrPane2 := nClrPane
   DEFAULT nClrText  := 0
   DEFAULT nWRadio   := 2
   DEFAULT nHRadio   := 2
   DEFAULT nLevel      := 160

   DEFAULT aItems    := {"close","Down"}

  ::SetItems( aItems )

   ::oWnd       = oWnd
   ::nStyle     = nOR( WS_POPUP, WS_VISIBLE )
   ::nTop       = nTop
   ::nLeft      = nLeft
   ::nBottom    = nTop + nHeight
   ::nRight     = nLeft + nWidth

   ::nClrPane   = nClrPane
   ::nClrPane2  = nClrPane2
   ::nClrText   = nClrText
   ::nClrBorder = RGB( 118,118,118 )
   ::nWRadio    = nWRadio
   ::nHRadio    = nHRadio

   ::nTimer     = 5000
   ::nLevel     = nLevel

   ::aBtnClose      := {}
   ::aBtnDown       := {}
   ::aCoors         := {}

   ::aMnuUser       := {}


   DEFINE FONT ::oFontHdr   NAME "Verdana"  SIZE 0, -11 BOLD
   DEFINE FONT ::oFontHdr2  NAME "Verdana"  SIZE 0, -11
   DEFINE FONT ::oFontBody  NAME "Segoe UI" SIZE 0, -11
   DEFINE FONT ::oFontPie   NAME "Verdana"  SIZE 0, -11 BOLD

   ::Register( nOR( CS_VREDRAW, CS_HREDRAW, CS_DROPSHADOW ) ) //, 131072

   ::Create()

   ::cTitle = "Desktop Alert"
   ::hRgn   = nil
   ::nOver        := -1

   ::nOption:= 1

   ::Default( .T. )

   ::Shadow()

   SetTransparent( self, ::nLevel )

return Self

//----------------------------------------------------------------------------//

METHOD GetSize() CLASS TDesktopAlert

   local rc        := 0
   local aSize     := { 0, 0 }
   local hBmp      := 0
   local hDC       := 0
   local hOldFont  := 0
   local n         := 0
   local nHBmp     := 0
   local nHText    := 0
   local nHeight   := 0
   local nLen      := 0
   local nW        := 0
   local nW2       := 0
   local nWB       := 0
   local nWBmp     := 0
   local nWBodyTxt := 227
   local nWF       := 0
   local nWH       := 0
   local nWidth    := 0

     if ::nFixWidth != nil .and. ::nFixHeight != nil
        return {::nFixWidth, ::nFixHeight}
     endif

     rc        := GetClientRect(::hWnd)
     nWidth    := nWBodyTxt

     // Header
     if ! Empty( ::cHeader )
        nHeight += 31
        nWH = GetTextWidth( 0, ::cHeader, ::oFontHdr:hFont ) + 16
     endif

     // Left side image
     if ! Empty( ::cBmpLeft )
        hBmp := LoadImageEx( ::cBmpLeft )
     else
       if ::bBmpLeft != nil
          hBmp = Eval( ::bBmpLeft, self )
       endif
     endif

     if hBmp != 0
        nWBmp := BmpWidth ( hBmp )
        nHBmp := BmpHeight( hBmp )
        nWidth += ( 14 + nWBmp )
        DeleteObject( hBmp )
     endif

     if Empty( ::cHeader ) .and. Empty( ::cFoot )
        nWidth = 13 + If( nWBmp != 0, ( nWBmp + 13 ), 0 ) + ;
                 GetTextWidth( 0, ::cBody, ::oFontBody:hFont ) + 26

     endif

     if ! Empty( ::cFoot )
        nHeight += 30
        nWF = GetTextWidth( 0, ::cFoot, ::oFontPie:hFont ) + 22
     endif

     nWidth = Max( Max( nWidth, nWH ), nWF )

     if Empty( ::cHeader ) .and. Empty( ::cFoot )
        nWidth = Min( nWidth, 227 )
     endif

     // if there is text in the body
     if ! Empty( ::cBody )
        hDC      = CreateDC( "DISPLAY",0,0,0)
        hOldFont = SelectObject( hDC, ::oFontBody:hFont )//
        nHText   = DrawText( hDC, AllTrim( ::cBody ),;
                             { 0, 12 + nWBmp + 12 + 10, 20, nWidth },;
                             nOr( DT_WORDBREAK, 8192, DT_CALCRECT ) )
        SelectObject( hDC, hOldFont )
        DeleteDC( hDC )
        nHeight += nHText
        nHeight +=8
     endif

     nHeight = Max( nHeight, nHBmp )

     aSize := { nWidth, nHeight }

return aSize

//----------------------------------------------------------------------------//

METHOD Default( lShowDlg ) CLASS TDesktopAlert

   local rc := {0, 0, ::nHeight, ::nWidth}
   Local hRgn
   Local hRgn2
   Local hRgn3
   local o := self

DEFAULT lShowDlg := .F.

     o:SetPos( ScreenHeight() - rc[ 3 ], ScreenWidth( 0 ) - rc[ 4 ]-10 )

   ::hRgn = CreateRoundRectRgn( rc[ 2 ], rc[ 1 ], rc[ 4 ], rc[ 3 ], ::nWRadio,;
                                ::nHRadio )

   SetWindowRgn( ::hWnd, ::hRgn, .T. )

   DeleteObject( ::hRgn )

return 0

//----------------------------------------------------------------------------//

METHOD HandleEvent( nMsg, nWParam, nLParam ) CLASS TDesktopAlert

   if nMsg == 20
      return 1
   endif

return ::Super:HandleEvent( nMsg, nWParam, nLParam )

//----------------------------------------------------------------------------//

METHOD ReSize( nSizeType, nWidth, nHeight ) CLASS TDesktopAlert

   ::Default()
   ::Refresh()

return ::Super:ReSize( nSizeType, nWidth, nHeight )

//----------------------------------------------------------------------------//

METHOD Paint() CLASS TDesktopAlert

  local hDCMem   := CreateCompatibleDC( ::hDC )
  local rc       := GetClientRect( ::hWnd )
  local hBmpMem  := CreateCompatibleBitmap( ::hDC, rc[ 4 ] - rc[ 2 ],;
                                            rc[ 3 ] - rc[ 1 ] )
  local hOldBmp  := SelectObject( hDCMem, hBmpMem )
  local nWRadio  := ::nWRadio
  local nHRadio  := ::nHRadio
  local nClrText := SetTextColor( hDCMem, ::nClrText )
  local hBrush
  local hRgn     := CreateRoundRectRgn( rc[ 2 ], rc[ 1 ], rc[ 4 ], rc[ 3 ],;
                                        ::nWRadio, ::nHRadio )

  local nLen
  local nH

  nLen := len( ::aItems )

             ::aCoors := array(nLen)
         for n := 1 to nLen
             ::aCoors[n] :={0,0,0,0}
           next




   if ::oTimer != nil
      ::oTimer:Deactivate()
      ::oTimer:End()
   endif

    IF ::lAlert

   DEFINE TIMER ::oTimer INTERVAL ::nTimer ACTION ::Hide() OF Self

   ACTIVATE TIMER ::oTimer

   Endif



   rc[ 3 ]--; rc[ 4 ]--
   nWRadio += 2
   nHRadio += 2

  VerticalGradient( hDCMem, { rc[ 1 ] - 1, rc[ 2 ], rc[ 3 ], rc[ 4 ] },;
                    ::nClrPane, ::nClrPane2 )

  if ::bOwnerDraw == nil
     ::PaintHdr( hDCMem, rc )
     ::PaintFoot( hDCMem, rc )
     ::PaintBody( hDCMem, rc )
  else
     Eval( ::bOwnerDraw, hDCMem )
  endif



  hBrush = CreateSolidBrush( ::nClrBorder )

  if ::lBorder
     FrameRgn( hDCMem, hRgn, hBrush, 1, 1 )
  endif

    nH      := rc[1]+20

   if ::lBtnClose
      ::BtnClose( hDCMem, (nH/2), rc[4]-12, ::lOverClose )
   endif

   if ::lBtnDown
      ::BtnDown( hDCMem, (nH/2), rc[4]-26, ::lOverDown )
   endif


  DeleteObject( hBrush )
  DeleteObject( hRgn )

  SetTextColor( hDCMem, nClrText )

  BitBlt( ::hDC, 0, 0, rc[ 4 ] - rc[ 2 ], rc[ 3 ] - rc[ 1 ], hDCMem, 0, 0, SRCCOPY )

  SelectObject( hDCMem, hOldBmp )
  DeleteDC    ( hDCMem )
  DeleteObject( hBmpMem )

return 0

//----------------------------------------------------------------------------//

METHOD PaintHdr( hDC, rc ) CLASS TDesktopAlert

   local hBmpHdr
   local nWBmpHdr := 0
   local hOldFont
   local nClrText
   local lIcon := .f.
   local nTop
   local nMode

   local nWBmpClose := 0
   local hBmpClose

   // 25 pixels
   if ::lHeader

      ::aHeader = { rc[ 1 ], rc[ 2 ], rc[ 1 ] + 25, rc[ 4 ] }

      if ::lLineHeader
         Line( hDC, ::aHeader[ 3 ], ::aHeader[ 2 ] + 5, ::aHeader[ 3 ],;
               ::aHeader[ 4 ] - 5, ::nClrSepara1 )
         Line( hDC, ::aHeader[ 3 ] + 1, ::aHeader[ 2 ] + 5, ::aHeader[ 3 ] + 1,;
               ::aHeader[ 4 ] - 5, ::nClrSepara2 )
      endif



     if ! Empty( ::cBmpHeader )
         hBmpHdr = LoadImageEx( ::cBmpHeader )
         if hBmpHdr  != 0
            nWBmpHdr = BmpWidth( hBmpHdr )
            nTop     = ( ::aHeader[ 1 ] + ;
                       ( ::aHeader[ 3 ] - ::aHeader[ 1 ] ) / 2 ) - ;
                       BmpHeight( hBmpHdr ) / 2
            nTop     = Max( nTop, 5 )
            DrawMasked( hDC, hBmpHdr, nTop, 5 )
            DeleteObject( hBmpHdr )
         endif
      endif




      hOldFont = SelectObject( hDC, ::oFontHdr:hFont )

      if ::nClrTextHeader != nil
         nClrText = SetTextColor( hDC, ::nCLrTextHeader )
      endif
      nMode = SetBkMode( hDC, 1 )

      DrawText( hDC, ::cHeader, { ::aHeader[ 1 ], ::aHeader[ 2 ] + 10 + ;
                If( hBmpHdr != 0, nWBmpHdr, 0 ), ::aHeader[ 3 ],;
                ::aHeader[ 4 ] - 10 }, nOr( DT_VCENTER, DT_SINGLELINE, 8192 ) )

      SetBkMode( hDC, nMode )

      if ::nClrTextHeader != nil
         SetTextColor( hDC, nClrText )
      endif

      SelectObject( hDC, hOldFont )
   else
      ::aHeader  := {rc[1],rc[2],rc[1],rc[4]}
   endif

return 0

//----------------------------------------------------------------------------//

METHOD PaintHdr2( hDC, rc ) CLASS TDesktopAlert

   local hOldFont
   local nClrText

   ::aHeader2 = { ::aHeader[ 3 ], rc[ 2 ], ::aHeader[ 3 ], rc[ 4 ] }

   if ::lHeader

      if ::lSplitHdr
         ::aHeader2 = { ::aHeader[ 3 ], rc[ 2 ], ::aHeader[ 3 ] + 25, rc[ 4 ] }
      endif

      if ::lLineHeader
         Line( hDC, ::aHeader2[ 3 ], ::aHeader2[ 2 ] + 5, ::aHeader2[ 3 ],;
               ::aHeader2[ 4 ] - 5, ::nClrSepara1 )
         Line( hDC, ::aHeader2[ 3 ] + 1, ::aHeader2[ 2 ] + 5, ::aHeader2[ 3 ] + 1,;
               ::aHeader2[ 4 ] - 5, ::nClrSepara2 )
      endif

      hOldFont = SelectObject( hDC, ::oFontHdr2:hFont )

      if ::nClrTextHeader != nil
         nClrText := SetTextColor( hDC, ::nCLrTextHeader )
      endif

      if ::lSplitHdr .and. ! Empty( ::cHeader2 )
         DrawText( hDC, ::cHeader2, { ::aHeader2[ 1 ] + 1, ::aHeader2[ 2 ] + 20,;
                   ::aHeader2[ 3 ], ::aHeader2[ 4 ] - 2 }, nOR( DT_WORDBREAK, 8192 ) )
      endif

      if ::nClrTextHeader != nil
         SetTextColor( hDC, nClrText )
      endif

      SelectObject( hDC, hOldFont )
  endif

return 0

//----------------------------------------------------------------------------//

METHOD PaintBody( hDC, rc ) CLASS TDesktopAlert

   local hOldFont
   local nWBmp := 0
   local nClrText
   local lIcon := .f.
   local nMode
   local hBmpLeft := 0
   local n
   local nLen
   local nW
   local nW2
   local aLeft

   ::aLeft = { 0, 0, 0, 0 }

   ::aBody = { ::aHeader[ 3 ] + If( ::lLineHeader, 5, 0 ), rc[ 2 ],;
               ::aFoot[ 1 ], rc[ 4 ] }

   if Empty( ::cBmpLeft )
      ::aLeft = { ::aBody[ 1 ], rc[ 2 ], ::aBody[ 3 ],;
                  If( ::lLeft, ( rc[ 4 ] - rc[ 2 ] ) * 0.33, rc[ 2 ] ) }
   else
      hBmpLeft = LoadImageEx( ::cBmpLeft )
      if hBmpLeft != 0
         nWBmp = BmpWidth( hBmpLeft )
         ::aLeft = { ::aBody[ 1 ], rc[ 2 ], ::aBody[ 3 ], 12 + nWBmp + 12 }
      endif
   endif

   if ::bBmpLeft != nil
      hBmpLeft = Eval( ::bBmpLeft, self )
      if hBmpLeft != 0
         nWBmp = BmpWidth( hBmpLeft )
         ::aLeft = { ::aBody[ 1 ], rc[ 2 ], ::aBody[ 3 ], 12 + nWBmp + 12 }
      endif
   endif

   ::aRight = { ::aBody[ 1 ] + 3, ::aLeft[ 4 ] + 20, ::aBody[ 3 ] - 3, rc[ 4 ] - 10 }

   hOldFont = SelectObject( hDC, ::oFontBody:hFont )

   nMode = SetBkMode( hDC, 1 )

   DrawText( hDC, AllTrim( ::cBody ), ::aRight,;
             nOr( If( ::lRightAlignBody, DT_RIGHT, DT_LEFT ), DT_WORDBREAK ) )

   SetBkMode( hDC, nMode )

   SelectObject( hDC, hOldFont )

   if hBmpLeft != 0
      DrawMasked( hDC, hBmpLeft, ::aLeft[ 1 ] + 5, ::aLeft[ 2 ] + 12 )
      DeleteObject( hBmpLeft )
   endif

return 0

//----------------------------------------------------------------------------//

METHOD PaintFoot( hDC, rc ) CLASS TDesktopAlert

   local hOldFont, hBmpFoot
   local nWFoot := 0
   local nClrText
   local lIcon := .f.
   local nMode

   if ::lFoot
      ::aFoot = { rc[ 3 ] - 30, rc[ 2 ], rc[ 3 ], rc[ 4 ] }
      if ! Empty( ::cBmpFoot )
         ::aFoot = { rc[ 3 ] - 30, rc[ 2 ], rc[ 3 ], rc[ 4 ] }
      endif
      hBmpFoot = LoadImageEx( ::cBmpFoot )
      if hBmpFoot != 0
         nWFoot = BmpWidth( hBmpFoot )
         ::aFoot = { rc[ 3 ] - 30, rc[ 2 ], rc[ 3 ], rc[ 4 ] }
         DrawMasked( hDC, hBmpFoot,;
                     ( ::aFoot[ 1 ] + ( ::aFoot[ 3 ] - ::aFoot[ 1 ] ) / 2 ) - ;
                     BmpHeight( hBmpFoot ) / 2, 5 )
         DeleteObject( hBmpFoot )
      endif
    else
       ::aFoot = { rc[ 3 ], rc[ 2 ], rc[ 3 ], rc[ 4 ] }
    endif

    if ::lFoot
       hOldFont = SelectObject( hDC, ::oFontPie:hFont )
       if ::nClrTextFoot != nil
          nClrText = SetTextColor( hDC, ::nClrTextFoot )
       endif
       nMode = SetBkMode( hDC, 1 )
       DrawText( hDC, ::cFoot, { ::aFoot[ 1 ], ::aFoot[ 2 ] + 10 + nWFoot,;
                 ::aFoot[ 3 ], ::aFoot[ 4 ] }, nOr( DT_VCENTER, DT_SINGLELINE, 8192 ) )
       SetBkMode( hDC, nMode )
       if ::nClrTextFoot != nil
          SetTextColor( hDC, nClrText )
       endif
      SelectObject( hDC, hOldFont )
   endif

   Line( hDC, ::aFoot[ 1 ], ::aFoot[ 2 ] + 5, ::aFoot[ 1 ], ::aFoot[ 4 ] - 5,;
         ::nClrSepara1 )
   Line( hDC, ::aFoot[ 1 ] + 1, ::aFoot[ 2 ] + 5, ::aFoot[ 1 ] + 1,;
         ::aFoot[ 4 ] - 5, ::nClrSepara2 )

   return 0


//----------------------------------------------------------------------------//
METHOD BtnClose( hDC,nTop,nLeft ) CLASS TDesktopAlert

::aBtnClose := closebutton( hDC, nTop, nLeft, ::lOverClose )
::aItems[1,3] := ::aBtnClose
  return 0

//----------------------------------------------------------------------------//
METHOD BtnDown( hDC,nTop,nLeft ) CLASS TDesktopAlert

::aBtndown := DropDownbutton( hDC, nTop, nLeft, ::lOverDown )
::aItems[2,3] := ::aBtndown
return 0

//----------------------------------------------------------------------------//
 METHOD LButtonDown( nRow, nCol, nFlags ) CLASS TDesktopAlert

    if ::lOverClose
       ::End()
    endif

      if ::lOverDown
            ::PopMenu( nRow, nCol, nFlags )
      endif

    return 0

//----------------------------------------------------------------------------//

METHOD MouseMove  ( nRow, nCol, nFlags ) CLASS TDesktopAlert

local nOver := ::nOver
local n
local nLen := len(::aCoors)
local lFindclose := .f.
local lFindDown := .f.

for n := 1 to nLen

    if PtInRect( nRow, nCol, ::aBtnClose )
       lFindClose := .t.
       ::nOver := 1
       if nOver != 1
          //::Refresh(.f.)
       endif
       exit
    endif


     if PtInRect( nRow, nCol, ::aBtnDown )
       lFindDown := .t.
       ::nOver := 2
       if nOver != 2
          //::Refresh(.f.)
       endif
       exit
    endif


next

::lOverClose := ::nOver > 0 .and. PtInRect( nRow, nCol, ::aItems[1,3] )

::lOverDown := ::nOver > 0 .and. PtInRect( nRow, nCol, ::aItems[2,3] )

if lFindClose    .or. lFindDown

   if ::lOverClose  .or. ::lOverDown
      CursorHand()
   else
      CursorArrow()
   endif

else
   ::nOver := -1
   CursorArrow()
endif

if nOver != ::nOver
   ::Refresh(.f.)
endif


return 0
//----------------------------------------------------------------------------//

   METHOD LButtonUp  ( nRow, nCol, nFlags ) CLASS TDesktopAlert

/*if ::nOver > 0
   if ::lOverClose
      ::aItems[1,2] := .t.
   else
      ::nOption := ::nOver
      if ::bAction != nil
         eval(::bAction, ::nOption, ::aItems[::nOption,1])
      endif
   endif
   ::Refresh()
endif
*/


return 0


//----------------------------------------------------------------------------//

METHOD PopMenu( nRow, nCol, nKey ) CLASS TDesktopAlert
   LOCAL oPopup
   local i
   local nLen := len( ::aMnuUser )



   MENU oPopUp POPUP

  IF nLen >0
       For i := 1 to nLen
            bAction :=  ::aMnuUser[i][2]
           MENUITEM RTrim(::aMnuUser[i][1]) BLOCK bAction
        Next i
        SEPARATOR
     endif


       MENUITEM "Desktop Alert Settimgs" ACTION ::DeskTopAlertSettings()
   ENDMENU


   ACTIVATE POPUP oPopup OF Self AT nRow, nCol


   return nil








//----------------------------------------------------------------------------//

 METHOD SetItems( aItems ) CLASS TDesktopAlert

    local n
    local nLen

    if len(aItems) != 0

       ::aItems := {}

       for n := 1 to len(aItems)
           aadd(::aItems, {aItems[n], .f.,{0,0,0,0}} )
       next

    endif

return 0

//----------------------------------------------------------------------------//


  METHOD GetItems() CLASS TDesktopAlert

local n
local nLen := len(::aItems)
local aItems := {}

for n := 1 to nLen
    if ::aItems[n,2]
       aadd(aItems, ::aItems[n,1] )
    endif
next

return aItems
//----------------------------------------------------------------------------//

METHOD DesktopAlertSettings  CLASS TDesktopAlert
   Local oDlgSettings
   Local nDuration := ::nTimer
   Local ntransparency := ::nLevel
   local oDuration,oTrans
   Local cText_Duration:= FWString("How long should the desktop alert appear ?" )
   local cText_transparency:= FWString("How transparency should the desktop be ?")
   local obtn[3]
   local oGrp[2]
   local oSay[4]
   Local nBottom   := 20
   Local nRight    := 62
   Local nWidth :=  Max( nRight * DLG_CHARPIX_W, 180 )
   Local nHeight := nBottom * DLG_CHARPIX_H
   local oThis := self




   DEFINE DIALOG oDlgSettings  SIZE nWidth, nHeight   PIXEL TITLE FWString( "DesktopAlert Settings" )
   oDlgSettings:lTruePixel := .f.


@ 0, 2 GROUP oGrp[1] PROMPT FWString("Duration ( 0 - 5 seconds )") OF oDlgSettings SIZE 210,48
@ 4, 2 GROUP oGrp[2] PROMPT FWString("Transparency") OF oDlgSettings SIZE 210,51

@ 0.5, 6 SAY oSay[1] PROMPT cText_Duration OF oDlgSettings   SIZE 180,10
@ 4.2, 6 SAY oSay[2] PROMPT cText_transparency OF oDlgSettings SIZE 180,10


@ 22, 20 SLIDER oDuration VAR nDuration OF oDlgSettings ;
               HORIZONTAL ;
               RIGHT DIRECTION ;
               RANGE 1000, 5000 ;  // 0 = NO close
               MARKS 6;
               EXACT;
               ON CHANGE  oSay[3]:settext(str(nDuration)+FWString("seconds")) ;
               SIZE 200, 12 PIXEL

 @ 38, 96 SAY oSay[3] PROMPT  str(nDuration)+FWString("seconds") OF oDlgSettings   SIZE 120,10 pixel


@ 80, 20 SLIDER oTrans VAR ntransparency OF oDlgSettings ;
               HORIZONTAL ;
               RIGHT DIRECTION ;
               RANGE 100, 300 ;
               MARKS 11;
               EXACT;
               ON CHANGE   oSay[4]:settext(str(ntransparency)+FWString(" trasparency level")) ;
               SIZE 200, 12 PIXEL

@ 96, 96 SAY oSay[4] PROMPT  str(ntransparency)+FWString(" trasparency level")  OF oDlgSettings SIZE 120,10      pixel



@ 118, 14 BUTTON obtn[1] PROMPT FWString("&Preview") SIZE 45,12  OF oDlgSettings PIXEL   action (::nLevel := ntransparency,oThis:Display())
@ 118, 94 BUTTON obtn[2] PROMPT FWString("&Ok") SIZE 45,12  OF oDlgSettings PIXEL       action  oDlgSettings:End(IDOK)
@ 118, 164 BUTTON obtn[3] PROMPT FWString("&Cancel") SIZE 45,12  OF oDlgSettings PIXEL  action  oDlgSettings:End(IDCANCEL)



ACTIVATE DIALOG oDlgSettings CENTERED

IF oDlgSettings:nresult == IDOK

 *  msginfo( "Transp. : " + STR( ::nLevel), "Seconds : " + STR( ::nTimer ) )

       ::nTimer := nDuration
       ::nLevel := ntransparency


Endif




return nil

















       ACTIVATE DIALOG oDlgSettings CENTERED
return nil





//----------------------------------------------------------------------------//
// Functions
//----------------------------------------------------------------------------//

static function Line( hDC, nTop, nLeft, nBottom, nRight, nColor, nWidth )

   local hPen, hOldPen

   DEFAULT nColor := CLR_BLACK, nWidth := 1

   hPen = CreatePen( PS_SOLID, nWidth, nColor )
   hOldPen = SelectObject( hDC, hPen )

   MoveTo( hDC, nLeft, nTop )
   LineTo( hDC, nRight, nTop )

   SelectObject( hDC, hOldPen )
   DeleteObject( hPen )

return 0

//----------------------------------------------------------------------------//

Static Function DropDownbutton( hDC, nTop, nLeft, lOver )
local oFont, hOldFont
local aRect
local nMode

// create a  arrow down button

DEFAULT lOver := .f.

  nMode    := SetBkMode( hDC, 1 )
  oFont := TFont():New( "Marlett", 0, -10, .f.,.f.,,,,.f.,.f.,.f., 1 )
  hOldFont := SelectObject( hDC, oFont:hFont )
  aRect := {nTop,nLeft,nTop+10,nLeft+ 9}
  TextOut( hDC, aRect[1]+1, aRect[2], "u" )
  SelectObject( hDC, hOldFont  )
  oFont:End()
  SetBkMode( hDC, nMode )
  if lOver
     Box(hDC,aRect)
  endif
  return aRect

//---------------------------------------------------------------------------//

Static Function closebutton( hDC, nTop, nLeft, lOver )
local oFont, hOldFont
local aRect
local nMode

// create a X button

DEFAULT lOver := .f.

  nMode    := SetBkMode( hDC, 1 )
  oFont := TFont():New( "Marlett", 0, -10, .f.,.f.,,,,.f.,.f.,.f., 1 )
  hOldFont := SelectObject( hDC, oFont:hFont )
  aRect := {nTop,nLeft,nTop+10,nLeft+ 9}
  TextOut( hDC, aRect[1]+1, aRect[2], "r" )
  SelectObject( hDC, hOldFont  )
  oFont:End()
  SetBkMode( hDC, nMode )
  if lOver
     Box(hDC,aRect)
  endif
  return aRect
//---------------------------------------------------------------------------//


    #define GWL_EXSTYLE   -20
    #define WS_EX_LAYERED 524288

static function SetTransparent( oDlg,nLevel )

   DEFAULT   nLevel := 160

       SetWindowLong( oDlg:hWnd, GWL_EXSTYLE, nOr( GetWindowLong( oDlg:hWnd, GWL_EXSTYLE ), WS_EX_LAYERED ) )

       SetLayeredWindowAttributes( oDlg:hWnd, 0, nLevel, 2 )

    return nil

//---------------------------------------------------------------------------//




 

Re: Desktop Alerts

PostPosted: Fri Mar 11, 2016 7:33 am
by Antonio Linares
Silvio,

This seems to work fine:

Code: Select all  Expand view
ACTIVATE DIALOG oDlgSettings CENTERED

IF oDlgSettings:nresult == IDOK

       ::nTimer := nDuration
       ::nLevel := ntransparency

   msginfo( "Transp. : " + STR( ::nLevel), "Seconds : " + STR( ::nTimer ) )

Endif

Re: Desktop Alerts

PostPosted: Fri Mar 11, 2016 7:34 am
by Antonio Linares
Use oTimer:Deactivate() and oTimer:Activate()

Re: Desktop Alerts

PostPosted: Fri Mar 11, 2016 9:25 am
by Silvio.Falconi
Antonio,
I wish Whenthe final user click Preview Button it refresh the desktopalert transparency changing the sliderobject oTrans

Code: Select all  Expand view

    METHOD DesktopAlertSettings  CLASS TDesktopAlert
       Local oDlgSettings
       Local nDuration := ::nTimer
       Local ntransparency := ::nLevel
       local oDuration,oTrans
       Local cText_Duration:= FWString("How long should the desktop alert appear ?" )
       local cText_transparency:= FWString("How transparency should the desktop be ?")
       local obtn[3]
       local oGrp[2]
       local oSay[4]
       Local nBottom   := 20
       Local nRight    := 62
       Local nWidth :=  Max( nRight * DLG_CHARPIX_W, 180 )
       Local nHeight := nBottom * DLG_CHARPIX_H
       local oThis := self


      ::oTimer:Deactivate()

       DEFINE DIALOG oDlgSettings  SIZE nWidth, nHeight   PIXEL TITLE FWString( "DesktopAlert Settings" )
       oDlgSettings:lTruePixel := .f.


    @ 0, 2 GROUP oGrp[1] PROMPT FWString("Duration ( 0 - 5 seconds )") OF oDlgSettings SIZE 210,48
    @ 4, 2 GROUP oGrp[2] PROMPT FWString("Transparency") OF oDlgSettings SIZE 210,51

    @ 0.5, 6 SAY oSay[1] PROMPT cText_Duration OF oDlgSettings   SIZE 180,10
    @ 4.2, 6 SAY oSay[2] PROMPT cText_transparency OF oDlgSettings SIZE 180,10


    @ 22, 20 SLIDER oDuration VAR nDuration OF oDlgSettings ;
                   HORIZONTAL ;
                   RIGHT DIRECTION ;
                   RANGE 1000, 5000 ;  // 0 = NO close
                   MARKS 6;
                   EXACT;
                   ON CHANGE  oSay[3]:settext(str(nDuration)+FWString("seconds")) ;
                   SIZE 200, 12 PIXEL

     @ 38, 96 SAY oSay[3] PROMPT  str(nDuration)+FWString("seconds") OF oDlgSettings   SIZE 120,10 pixel


    @ 80, 20 SLIDER oTrans VAR ntransparency OF oDlgSettings ;
                   HORIZONTAL ;
                   RIGHT DIRECTION ;
                   RANGE 100, 300 ;
                   MARKS 11;
                   EXACT;
                   ON CHANGE   oSay[4]:settext(str(ntransparency)+FWString(" trasparency level")) ;
                   SIZE 200, 12 PIXEL

    @ 96, 96 SAY oSay[4] PROMPT  str(ntransparency)+FWString(" trasparency level")  OF oDlgSettings SIZE 120,10      pixel



    @ 118, 14 BUTTON obtn[1] PROMPT FWString("&Preview") SIZE 45,12  OF oDlgSettings PIXEL   action (::nLevel := ntransparency,oThis:Display())
    @ 118, 94 BUTTON obtn[2] PROMPT FWString("&Ok") SIZE 45,12  OF oDlgSettings PIXEL       action  oDlgSettings:End(IDOK)
    @ 118, 164 BUTTON obtn[3] PROMPT FWString("&Cancel") SIZE 45,12  OF oDlgSettings PIXEL  action  oDlgSettings:End(IDCANCEL)





        ACTIVATE DIALOG oDlgSettings CENTERED

    IF oDlgSettings:nresult == IDOK

           ::nTimer := nDuration
           ::nLevel := ntransparency

       msginfo( "Transp. : " + STR( ::nLevel), "Seconds : " + STR( ::nTimer ) )

    Endif


    ::oTimer:Activate()

    return nil

Re: Desktop Alerts

PostPosted: Fri Mar 11, 2016 1:00 pm
by Silvio.Falconi
Antonio,
I add ::MoveTask(4) Method for create the animation from bottom to up
as my sample http://forums.fivetechsupport.com/viewtopic.php?f=3&t=32082

it run but on window I cannot see none only the X button why ?

see METHOD MoveTask(ntime)

I insert it On New method but I tried also to default method


New code

Code: Select all  Expand view


    #include "fivewin.ch"
    #include "Slider.ch"
    #include "constant.ch"


    #define CW_USEDEFAULT      32768
    #define SRCCOPY 13369376

    #define DT_TOP              0x00000000
    #define DT_LEFT             0x00000000
    #define DT_CENTER           0x00000001
    #define DT_RIGHT            0x00000002
    #define DT_VCENTER          0x00000004
    #define DT_BOTTOM           0x00000008
    #define DT_WORDBREAK        0x00000010
    #define DT_SINGLELINE       0x00000020
    #define DT_EXPANDTABS       0x00000040
    #define DT_TABSTOP          0x00000080
    #define DT_NOCLIP           0x00000100
    #define DT_EXTERNALLEADING  0x00000200
    #define DT_CALCRECT         0x00000400
    #define DT_NOPREFIX         0x00000800
    #define DT_INTERNAL         0x00001000

    #define CS_DROPSHADOW       0x00020000


    //=========================================================================
    //
    // File:    test6
    // Created:
    //
    // Project: desktop Alert
    //
    //=========================================================================



    #include "FiveWin.ch"

    //----------------------------------------------------------------------------//

    function Main()

       local oWnd

       DEFINE WINDOW oWnd TITLE "Click me for a desktop notification"

       ACTIVATE WINDOW oWnd ;
              ON CLICK ShowAlert()

    return nil

    //----------------------------------------------------------------------------//

    function ShowAlert( oWnd )

       local oAlert := TDesktopAlert():New( 100, 100, 250, 250, oWnd, .T., CLR_HRED, CLR_WHITE )

       oAlert:cHeader  = "Desktop alert"
       oAlert:cBody    = "This a sample text area."+CRLF+"This a sample text area."
       oAlert:cFoot    = "this is the footer area"

       oAlert:cBmpHeader = "C:\work\fwh\bitmaps\16x16\help.bmp"
       oAlert:cBmpFoot   = "C:\work\fwh\bitmaps\16x16\help.bmp"
       oAlert:cBmpLeft   = "C:\work\fwh\bitmaps\16x16\mail.bmp"

       oAlert:lLineHeader = .T.
       oAlert:lBorder     = .T.

       // These are not working yet
       oAlert:lBtnClose   = .T.
       oAlert:lBtnDown    = .T.
       oAlert:lSplitHdr   = .T.

      oAlert:aMnuUser  := {  {"Option1", { || MsgInfo("1") } },;
                             {"Option2", { || MsgInfo("2") } }   }



    return nil




    //----------------------------------------------------------------------------//
    //----------------------------------------------------------------------------//

    CLASS TDesktopAlert FROM TWindow  //from c5Tooltip

          CLASSDATA lRegistered AS LOGICAL

          DATA lSplitHdr    AS LOGICAL INIT .f.
          DATA lLeft        AS LOGICAL INIT .f.

          DATA lLineHeader  AS LOGICAL INIT .f.
          DATA lLineFoot    AS LOGICAL INIT .F.
          DATA lBorder      AS LOGICAL INIT .t.


          DATA cHeader      AS CHARACTER INIT  ""
          DATA cBmpLeft     AS CHARACTER INIT  ""
          DATA cBody        AS CHARACTER INIT  ""
          DATA cBmpFoot     AS CHARACTER INIT  ""
          DATA cFoot        AS CHARACTER INIT  ""
          DATA lRightAlignBody AS LOGICAL INIT .F.

          DATA cLibHeader
          DATA cBmpHeader
          DATA cLibLeft
          DATA cLibFoot
          DATA cTumbNail    AS CHARACTER INIT ""
          DATA cHeader2     AS CHARACTER INIT  space(255)

          DATA nClrPane2
          DATA nClrBorder   AS NUMERIC INIT 0
          DATA nClrSepara1  AS NUMERIC INIT RGB(157,188,219)
          DATA nClrSepara2  AS NUMERIC INIT CLR_WHITE

          DATA nClrTextHeader
          DATA nClrTextBody
          DATA nClrTextFoot

          DATA oFontHdr
          DATA oFontHdr2
          DATA oFontBody
          DATA oFontPie

          DATA aHeader   AS ARRAY INIT {0,0,0,0}
          DATA aHeader2  AS ARRAY INIT {0,0,0,0}
          DATA aBody     AS ARRAY INIT {0,0,0,0}
          DATA aLeft     AS ARRAY INIT {0,0,0,0}
          DATA aRight    AS ARRAY INIT {0,0,0,0}
          DATA aFoot     AS ARRAY INIT {0,0,0,0}
          DATA aBtnClose AS ARRAY INIT {0,0,0,0}

          DATA nWRadio
          DATA nHRadio
          DATA nGetColor

          DATA aOldPos, nOldRow, nOldCol
          DATA hRgn
          DATA nMResize

          DATA bBmpLeft

          DATA nFixWidth
          DATA nFixHeight

          DATA bOwnerDraw

          DATA oTimer, nTimer

          DATA lBtnClose       AS LOGICAL INIT .t.
          DATA aBtnClose       AS ARRAY INIT {0,0,0,0}
          DATA lOverClose      AS LOGICAL INIT .F.
          DATA lOverDown        AS LOGICAL INIT .F.
          DATA aBtndown        AS ARRAY INIT {0,0,0,0}
          DATA lBtnDown        AS LOGICAL INIT .f.

          DATA nOver
          DATA lAlert          AS LOGICAL INIT .t.
          DATA nOption
          DATA bAction


          DATA aItems
          DATA aCoors
          DATA nLevel
          DATA nDuration
          DATA aMnuUser      AS ARRAY


          METHOD New( nTop, nLeft, nWidth, nHeight, oWnd, lDisenio, nClrPane, ;
                      nClrPane2, nClrText, nWRadio, nHRadio,aItems,nLevel,aMnuUser) CONSTRUCTOR
          METHOD Default ()
          METHOD Destroy()  INLINE ::oFontHdr :End(),;
                                   ::oFontHdr2:End(),;
                                   ::oFontBody:End(),;
                                   ::oFontPie :End(),;
                                   DeleteObject( ::hRgn ),;
                                   ::Super:Destroy()
          METHOD EndPaint() INLINE ::nPaintCount--,EndPaint( ::hWnd, ::cPS ), ::cPS := nil, ::hDC := nil, 0
          METHOD Display()  INLINE ::BeginPaint(),::Paint(),::EndPaint(),0
          METHOD Paint   ()
          METHOD PaintHdr ( hDC, rc )
          METHOD PaintHdr2( hDC, rc )
          METHOD PaintBody( hDC, rc )
          METHOD PaintFoot( hDC, rc )

          METHOD HandleEvent( nMsg, nWParam, nLParam )
          METHOD ReSize( nSizeType, nWidth, nHeight )
          METHOD lHeader() INLINE !empty( ::cHeader )
          METHOD lFoot()   INLINE !empty( ::cFoot )
          METHOD GetSize()
          METHOD SetSize( nWidth, nHeight ) INLINE ::Super:SetSize( nWidth, nHeight, .t. )

          METHOD BtnDown( hDC,nTop,nLeft )
          METHOD BtnClose( hDC,nTop,nLeft )
          METHOD LButtonDown( nRow, nCol, nFlags )
          METHOD MouseMove  ( nRow, nCol, nFlags )
          METHOD LButtonUp  ( nRow, nCol, nFlags )
          METHOD GetItems()
          METHOD SetItems( aItems )
          METHOD PopMenu( nRow, nCol, nKey )  // PopUp menu options
          METHOD DesktopAlertSettings

          METHOD MoveTask(ntime)


    ENDCLASS

    //----------------------------------------------------------------------------//

    METHOD New( nTop, nLeft, nWidth, nHeight, oWnd, lDisenio, nClrPane, nClrPane2,;
                nClrText, nWRadio, nHRadio,aItems,nLevel,aMnuUser) CLASS TDesktopAlert

       DEFAULT nClrPane  := CLR_WHITE
       DEFAULT nClrPane2 := nClrPane
       DEFAULT nClrText  := 0
       DEFAULT nWRadio   := 2
       DEFAULT nHRadio   := 2
       DEFAULT nLevel      := 160

       DEFAULT aItems    := {"close","Down"}

      ::SetItems( aItems )

       ::oWnd       = oWnd
       ::nStyle     = nOR( WS_POPUP, WS_VISIBLE )
       ::nTop       = nTop
       ::nLeft      = nLeft
       ::nBottom    = nTop + nHeight
       ::nRight     = nLeft + nWidth

       ::nClrPane   = nClrPane
       ::nClrPane2  = nClrPane2
       ::nClrText   = nClrText
       ::nClrBorder = RGB( 118,118,118 )
       ::nWRadio    = nWRadio
       ::nHRadio    = nHRadio

       ::nTimer     = 5000
       ::nLevel     = nLevel

       ::aBtnClose      := {}
       ::aBtnDown       := {}
       ::aCoors         := {}

       ::aMnuUser       := {}


       DEFINE FONT ::oFontHdr   NAME "Verdana"  SIZE 0, -11 BOLD
       DEFINE FONT ::oFontHdr2  NAME "Verdana"  SIZE 0, -11
       DEFINE FONT ::oFontBody  NAME "Segoe UI" SIZE 0, -11
       DEFINE FONT ::oFontPie   NAME "Verdana"  SIZE 0, -11 BOLD

       ::Register( nOR( CS_VREDRAW, CS_HREDRAW, CS_DROPSHADOW ) ) //, 131072



       ::Create()



       ::cTitle = "Desktop Alert"
       ::hRgn   = nil
       ::nOver        := -1

       ::nOption:= 1



       ::Shadow()

         SetTransparent( self, ::nLevel )


       ::Default( .T. )

         ::MoveTask(4)

    return Self

    //----------------------------------------------------------------------------//

    METHOD GetSize() CLASS TDesktopAlert

       local rc        := 0
       local aSize     := { 0, 0 }
       local hBmp      := 0
       local hDC       := 0
       local hOldFont  := 0
       local n         := 0
       local nHBmp     := 0
       local nHText    := 0
       local nHeight   := 0
       local nLen      := 0
       local nW        := 0
       local nW2       := 0
       local nWB       := 0
       local nWBmp     := 0
       local nWBodyTxt := 227
       local nWF       := 0
       local nWH       := 0
       local nWidth    := 0

         if ::nFixWidth != nil .and. ::nFixHeight != nil
            return {::nFixWidth, ::nFixHeight}
         endif

         rc        := GetClientRect(::hWnd)
         nWidth    := nWBodyTxt

         // Header
         if ! Empty( ::cHeader )
            nHeight += 31
            nWH = GetTextWidth( 0, ::cHeader, ::oFontHdr:hFont ) + 16
         endif

         // Left side image
         if ! Empty( ::cBmpLeft )
            hBmp := LoadImageEx( ::cBmpLeft )
         else
           if ::bBmpLeft != nil
              hBmp = Eval( ::bBmpLeft, self )
           endif
         endif

         if hBmp != 0
            nWBmp := BmpWidth ( hBmp )
            nHBmp := BmpHeight( hBmp )
            nWidth += ( 14 + nWBmp )
            DeleteObject( hBmp )
         endif

         if Empty( ::cHeader ) .and. Empty( ::cFoot )
            nWidth = 13 + If( nWBmp != 0, ( nWBmp + 13 ), 0 ) + ;
                     GetTextWidth( 0, ::cBody, ::oFontBody:hFont ) + 26

         endif

         if ! Empty( ::cFoot )
            nHeight += 30
            nWF = GetTextWidth( 0, ::cFoot, ::oFontPie:hFont ) + 22
         endif

         nWidth = Max( Max( nWidth, nWH ), nWF )

         if Empty( ::cHeader ) .and. Empty( ::cFoot )
            nWidth = Min( nWidth, 227 )
         endif

         // if there is text in the body
         if ! Empty( ::cBody )
            hDC      = CreateDC( "DISPLAY",0,0,0)
            hOldFont = SelectObject( hDC, ::oFontBody:hFont )//
            nHText   = DrawText( hDC, AllTrim( ::cBody ),;
                                 { 0, 12 + nWBmp + 12 + 10, 20, nWidth },;
                                 nOr( DT_WORDBREAK, 8192, DT_CALCRECT ) )
            SelectObject( hDC, hOldFont )
            DeleteDC( hDC )
            nHeight += nHText
            nHeight +=8
         endif

         nHeight = Max( nHeight, nHBmp )

         aSize := { nWidth, nHeight }

    return aSize

    //----------------------------------------------------------------------------//

    METHOD Default( lShowDlg ) CLASS TDesktopAlert

       local rc := {0, 0, ::nHeight, ::nWidth}
       Local hRgn
       Local hRgn2
       Local hRgn3
       local o := self

    DEFAULT lShowDlg := .F.

         ::MoveTask(4)

         o:SetPos( ScreenHeight() - rc[ 3 ], ScreenWidth( 0 ) - rc[ 4 ]-10 )



       ::hRgn = CreateRoundRectRgn( rc[ 2 ], rc[ 1 ], rc[ 4 ], rc[ 3 ], ::nWRadio,;
                                    ::nHRadio )

       SetWindowRgn( ::hWnd, ::hRgn, .T. )

       DeleteObject( ::hRgn )



    return 0

    //----------------------------------------------------------------------------//

    METHOD HandleEvent( nMsg, nWParam, nLParam ) CLASS TDesktopAlert

       if nMsg == 20
          return 1
       endif

    return ::Super:HandleEvent( nMsg, nWParam, nLParam )

    //----------------------------------------------------------------------------//

    METHOD ReSize( nSizeType, nWidth, nHeight ) CLASS TDesktopAlert

       ::Default()
       ::Refresh()

    return ::Super:ReSize( nSizeType, nWidth, nHeight )

    //----------------------------------------------------------------------------//

    METHOD Paint() CLASS TDesktopAlert

      local hDCMem   := CreateCompatibleDC( ::hDC )
      local rc       := GetClientRect( ::hWnd )
      local hBmpMem  := CreateCompatibleBitmap( ::hDC, rc[ 4 ] - rc[ 2 ],;
                                                rc[ 3 ] - rc[ 1 ] )
      local hOldBmp  := SelectObject( hDCMem, hBmpMem )
      local nWRadio  := ::nWRadio
      local nHRadio  := ::nHRadio
      local nClrText := SetTextColor( hDCMem, ::nClrText )
      local hBrush
      local hRgn     := CreateRoundRectRgn( rc[ 2 ], rc[ 1 ], rc[ 4 ], rc[ 3 ],;
                                            ::nWRadio, ::nHRadio )

      local nLen
      local nH

      nLen := len( ::aItems )

                 ::aCoors := array(nLen)
             for n := 1 to nLen
                 ::aCoors[n] :={0,0,0,0}
               next




       if ::oTimer != nil
          ::oTimer:Deactivate()
          ::oTimer:End()
       endif

        IF ::lAlert

       DEFINE TIMER ::oTimer INTERVAL ::nTimer ACTION ::Hide() OF Self

       ACTIVATE TIMER ::oTimer

       Endif



       rc[ 3 ]--; rc[ 4 ]--
       nWRadio += 2
       nHRadio += 2

      VerticalGradient( hDCMem, { rc[ 1 ] - 1, rc[ 2 ], rc[ 3 ], rc[ 4 ] },;
                        ::nClrPane, ::nClrPane2 )

      if ::bOwnerDraw == nil
         ::PaintHdr( hDCMem, rc )
         ::PaintFoot( hDCMem, rc )
         ::PaintBody( hDCMem, rc )
      else
         Eval( ::bOwnerDraw, hDCMem )
      endif



      hBrush = CreateSolidBrush( ::nClrBorder )

      if ::lBorder
         FrameRgn( hDCMem, hRgn, hBrush, 1, 1 )
      endif

        nH      := rc[1]+20

       if ::lBtnClose
          ::BtnClose( hDCMem, (nH/2), rc[4]-12, ::lOverClose )
       endif

       if ::lBtnDown
          ::BtnDown( hDCMem, (nH/2), rc[4]-26, ::lOverDown )
       endif


      DeleteObject( hBrush )
      DeleteObject( hRgn )

      SetTextColor( hDCMem, nClrText )

      BitBlt( ::hDC, 0, 0, rc[ 4 ] - rc[ 2 ], rc[ 3 ] - rc[ 1 ], hDCMem, 0, 0, SRCCOPY )

      SelectObject( hDCMem, hOldBmp )
      DeleteDC    ( hDCMem )
      DeleteObject( hBmpMem )

    return 0

    //----------------------------------------------------------------------------//

    METHOD PaintHdr( hDC, rc ) CLASS TDesktopAlert

       local hBmpHdr
       local nWBmpHdr := 0
       local hOldFont
       local nClrText
       local lIcon := .f.
       local nTop
       local nMode

       local nWBmpClose := 0
       local hBmpClose

       // 25 pixels
       if ::lHeader

          ::aHeader = { rc[ 1 ], rc[ 2 ], rc[ 1 ] + 25, rc[ 4 ] }

          if ::lLineHeader
             Line( hDC, ::aHeader[ 3 ], ::aHeader[ 2 ] + 5, ::aHeader[ 3 ],;
                   ::aHeader[ 4 ] - 5, ::nClrSepara1 )
             Line( hDC, ::aHeader[ 3 ] + 1, ::aHeader[ 2 ] + 5, ::aHeader[ 3 ] + 1,;
                   ::aHeader[ 4 ] - 5, ::nClrSepara2 )
          endif



         if ! Empty( ::cBmpHeader )
             hBmpHdr = LoadImageEx( ::cBmpHeader )
             if hBmpHdr  != 0
                nWBmpHdr = BmpWidth( hBmpHdr )
                nTop     = ( ::aHeader[ 1 ] + ;
                           ( ::aHeader[ 3 ] - ::aHeader[ 1 ] ) / 2 ) - ;
                           BmpHeight( hBmpHdr ) / 2
                nTop     = Max( nTop, 5 )
                DrawMasked( hDC, hBmpHdr, nTop, 5 )
                DeleteObject( hBmpHdr )
             endif
          endif




          hOldFont = SelectObject( hDC, ::oFontHdr:hFont )

          if ::nClrTextHeader != nil
             nClrText = SetTextColor( hDC, ::nCLrTextHeader )
          endif
          nMode = SetBkMode( hDC, 1 )

          DrawText( hDC, ::cHeader, { ::aHeader[ 1 ], ::aHeader[ 2 ] + 10 + ;
                    If( hBmpHdr != 0, nWBmpHdr, 0 ), ::aHeader[ 3 ],;
                    ::aHeader[ 4 ] - 10 }, nOr( DT_VCENTER, DT_SINGLELINE, 8192 ) )

          SetBkMode( hDC, nMode )

          if ::nClrTextHeader != nil
             SetTextColor( hDC, nClrText )
          endif

          SelectObject( hDC, hOldFont )
       else
          ::aHeader  := {rc[1],rc[2],rc[1],rc[4]}
       endif

    return 0

    //----------------------------------------------------------------------------//

    METHOD PaintHdr2( hDC, rc ) CLASS TDesktopAlert

       local hOldFont
       local nClrText

       ::aHeader2 = { ::aHeader[ 3 ], rc[ 2 ], ::aHeader[ 3 ], rc[ 4 ] }

       if ::lHeader

          if ::lSplitHdr
             ::aHeader2 = { ::aHeader[ 3 ], rc[ 2 ], ::aHeader[ 3 ] + 25, rc[ 4 ] }
          endif

          if ::lLineHeader
             Line( hDC, ::aHeader2[ 3 ], ::aHeader2[ 2 ] + 5, ::aHeader2[ 3 ],;
                   ::aHeader2[ 4 ] - 5, ::nClrSepara1 )
             Line( hDC, ::aHeader2[ 3 ] + 1, ::aHeader2[ 2 ] + 5, ::aHeader2[ 3 ] + 1,;
                   ::aHeader2[ 4 ] - 5, ::nClrSepara2 )
          endif

          hOldFont = SelectObject( hDC, ::oFontHdr2:hFont )

          if ::nClrTextHeader != nil
             nClrText := SetTextColor( hDC, ::nCLrTextHeader )
          endif

          if ::lSplitHdr .and. ! Empty( ::cHeader2 )
             DrawText( hDC, ::cHeader2, { ::aHeader2[ 1 ] + 1, ::aHeader2[ 2 ] + 20,;
                       ::aHeader2[ 3 ], ::aHeader2[ 4 ] - 2 }, nOR( DT_WORDBREAK, 8192 ) )
          endif

          if ::nClrTextHeader != nil
             SetTextColor( hDC, nClrText )
          endif

          SelectObject( hDC, hOldFont )
      endif

    return 0

    //----------------------------------------------------------------------------//

    METHOD PaintBody( hDC, rc ) CLASS TDesktopAlert

       local hOldFont
       local nWBmp := 0
       local nClrText
       local lIcon := .f.
       local nMode
       local hBmpLeft := 0
       local n
       local nLen
       local nW
       local nW2
       local aLeft

       ::aLeft = { 0, 0, 0, 0 }

       ::aBody = { ::aHeader[ 3 ] + If( ::lLineHeader, 5, 0 ), rc[ 2 ],;
                   ::aFoot[ 1 ], rc[ 4 ] }

       if Empty( ::cBmpLeft )
          ::aLeft = { ::aBody[ 1 ], rc[ 2 ], ::aBody[ 3 ],;
                      If( ::lLeft, ( rc[ 4 ] - rc[ 2 ] ) * 0.33, rc[ 2 ] ) }
       else
          hBmpLeft = LoadImageEx( ::cBmpLeft )
          if hBmpLeft != 0
             nWBmp = BmpWidth( hBmpLeft )
             ::aLeft = { ::aBody[ 1 ], rc[ 2 ], ::aBody[ 3 ], 12 + nWBmp + 12 }
          endif
       endif

       if ::bBmpLeft != nil
          hBmpLeft = Eval( ::bBmpLeft, self )
          if hBmpLeft != 0
             nWBmp = BmpWidth( hBmpLeft )
             ::aLeft = { ::aBody[ 1 ], rc[ 2 ], ::aBody[ 3 ], 12 + nWBmp + 12 }
          endif
       endif

       ::aRight = { ::aBody[ 1 ] + 3, ::aLeft[ 4 ] + 20, ::aBody[ 3 ] - 3, rc[ 4 ] - 10 }

       hOldFont = SelectObject( hDC, ::oFontBody:hFont )

       nMode = SetBkMode( hDC, 1 )

       DrawText( hDC, AllTrim( ::cBody ), ::aRight,;
                 nOr( If( ::lRightAlignBody, DT_RIGHT, DT_LEFT ), DT_WORDBREAK ) )

       SetBkMode( hDC, nMode )

       SelectObject( hDC, hOldFont )

       if hBmpLeft != 0
          DrawMasked( hDC, hBmpLeft, ::aLeft[ 1 ] + 5, ::aLeft[ 2 ] + 12 )
          DeleteObject( hBmpLeft )
       endif

    return 0

    //----------------------------------------------------------------------------//

    METHOD PaintFoot( hDC, rc ) CLASS TDesktopAlert

       local hOldFont, hBmpFoot
       local nWFoot := 0
       local nClrText
       local lIcon := .f.
       local nMode

       if ::lFoot
          ::aFoot = { rc[ 3 ] - 30, rc[ 2 ], rc[ 3 ], rc[ 4 ] }
          if ! Empty( ::cBmpFoot )
             ::aFoot = { rc[ 3 ] - 30, rc[ 2 ], rc[ 3 ], rc[ 4 ] }
          endif
          hBmpFoot = LoadImageEx( ::cBmpFoot )
          if hBmpFoot != 0
             nWFoot = BmpWidth( hBmpFoot )
             ::aFoot = { rc[ 3 ] - 30, rc[ 2 ], rc[ 3 ], rc[ 4 ] }
             DrawMasked( hDC, hBmpFoot,;
                         ( ::aFoot[ 1 ] + ( ::aFoot[ 3 ] - ::aFoot[ 1 ] ) / 2 ) - ;
                         BmpHeight( hBmpFoot ) / 2, 5 )
             DeleteObject( hBmpFoot )
          endif
        else
           ::aFoot = { rc[ 3 ], rc[ 2 ], rc[ 3 ], rc[ 4 ] }
        endif

        if ::lFoot
           hOldFont = SelectObject( hDC, ::oFontPie:hFont )
           if ::nClrTextFoot != nil
              nClrText = SetTextColor( hDC, ::nClrTextFoot )
           endif
           nMode = SetBkMode( hDC, 1 )
           DrawText( hDC, ::cFoot, { ::aFoot[ 1 ], ::aFoot[ 2 ] + 10 + nWFoot,;
                     ::aFoot[ 3 ], ::aFoot[ 4 ] }, nOr( DT_VCENTER, DT_SINGLELINE, 8192 ) )
           SetBkMode( hDC, nMode )
           if ::nClrTextFoot != nil
              SetTextColor( hDC, nClrText )
           endif
          SelectObject( hDC, hOldFont )
       endif

       Line( hDC, ::aFoot[ 1 ], ::aFoot[ 2 ] + 5, ::aFoot[ 1 ], ::aFoot[ 4 ] - 5,;
             ::nClrSepara1 )
       Line( hDC, ::aFoot[ 1 ] + 1, ::aFoot[ 2 ] + 5, ::aFoot[ 1 ] + 1,;
             ::aFoot[ 4 ] - 5, ::nClrSepara2 )

       return 0


    //----------------------------------------------------------------------------//
    METHOD BtnClose( hDC,nTop,nLeft ) CLASS TDesktopAlert

    ::aBtnClose := closebutton( hDC, nTop, nLeft, ::lOverClose )
    ::aItems[1,3] := ::aBtnClose
      return 0

    //----------------------------------------------------------------------------//
    METHOD BtnDown( hDC,nTop,nLeft ) CLASS TDesktopAlert

    ::aBtndown := DropDownbutton( hDC, nTop, nLeft, ::lOverDown )
    ::aItems[2,3] := ::aBtndown
    return 0

    //----------------------------------------------------------------------------//
     METHOD LButtonDown( nRow, nCol, nFlags ) CLASS TDesktopAlert

        if ::lOverClose
           ::End()
        endif

          if ::lOverDown
                ::PopMenu( nRow, nCol, nFlags )
          endif

        return 0

    //----------------------------------------------------------------------------//

    METHOD MouseMove  ( nRow, nCol, nFlags ) CLASS TDesktopAlert

    local nOver := ::nOver
    local n
    local nLen := len(::aCoors)
    local lFindclose := .f.
    local lFindDown := .f.

    for n := 1 to nLen

        if PtInRect( nRow, nCol, ::aBtnClose )
           lFindClose := .t.
           ::nOver := 1
           if nOver != 1
              //::Refresh(.f.)
           endif
           exit
        endif


         if PtInRect( nRow, nCol, ::aBtnDown )
           lFindDown := .t.
           ::nOver := 2
           if nOver != 2
              //::Refresh(.f.)
           endif
           exit
        endif


    next

    ::lOverClose := ::nOver > 0 .and. PtInRect( nRow, nCol, ::aItems[1,3] )

    ::lOverDown := ::nOver > 0 .and. PtInRect( nRow, nCol, ::aItems[2,3] )

    if lFindClose    .or. lFindDown

       if ::lOverClose  .or. ::lOverDown
          CursorHand()
       else
          CursorArrow()
       endif

    else
       ::nOver := -1
       CursorArrow()
    endif

    if nOver != ::nOver
       ::Refresh(.f.)
    endif


    return 0
    //----------------------------------------------------------------------------//

       METHOD LButtonUp  ( nRow, nCol, nFlags ) CLASS TDesktopAlert

    /*if ::nOver > 0
       if ::lOverClose
          ::aItems[1,2] := .t.
       else
          ::nOption := ::nOver
          if ::bAction != nil
             eval(::bAction, ::nOption, ::aItems[::nOption,1])
          endif
       endif
       ::Refresh()
    endif
    */


    return 0


    //----------------------------------------------------------------------------//

    METHOD PopMenu( nRow, nCol, nKey ) CLASS TDesktopAlert
       LOCAL oPopup
       local i
       local nLen := len( ::aMnuUser )



       MENU oPopUp POPUP

      IF nLen >0
           For i := 1 to nLen
                bAction :=  ::aMnuUser[i][2]
               MENUITEM RTrim(::aMnuUser[i][1]) BLOCK bAction
            Next i
            SEPARATOR
         endif


           MENUITEM "Desktop Alert Settimgs" ACTION ::DeskTopAlertSettings()
       ENDMENU


       ACTIVATE POPUP oPopup OF Self AT nRow, nCol


       return nil








    //----------------------------------------------------------------------------//

     METHOD SetItems( aItems ) CLASS TDesktopAlert

        local n
        local nLen

        if len(aItems) != 0

           ::aItems := {}

           for n := 1 to len(aItems)
               aadd(::aItems, {aItems[n], .f.,{0,0,0,0}} )
           next

        endif

    return 0

    //----------------------------------------------------------------------------//


      METHOD GetItems() CLASS TDesktopAlert

    local n
    local nLen := len(::aItems)
    local aItems := {}

    for n := 1 to nLen
        if ::aItems[n,2]
           aadd(aItems, ::aItems[n,1] )
        endif
    next

    return aItems
    //----------------------------------------------------------------------------//

    METHOD DesktopAlertSettings  CLASS TDesktopAlert
       Local oDlgSettings
       Local nDuration := ::nTimer
       Local ntransparency := ::nLevel
       local oDuration,oTrans
       Local cText_Duration:= FWString("How long should the desktop alert appear ?" )
       local cText_transparency:= FWString("How transparency should the desktop be ?")
       local obtn[3]
       local oGrp[2]
       local oSay[4]
       Local nBottom   := 20
       Local nRight    := 62
       Local nWidth :=  Max( nRight * DLG_CHARPIX_W, 180 )
       Local nHeight := nBottom * DLG_CHARPIX_H
       local oThis := self


      ::oTimer:Deactivate()

       DEFINE DIALOG oDlgSettings  SIZE nWidth, nHeight   PIXEL TITLE FWString( "DesktopAlert Settings" )
       oDlgSettings:lTruePixel := .f.


    @ 0, 2 GROUP oGrp[1] PROMPT FWString("Duration ( 0 - 5 seconds )") OF oDlgSettings SIZE 210,48
    @ 4, 2 GROUP oGrp[2] PROMPT FWString("Transparency") OF oDlgSettings SIZE 210,51

    @ 0.5, 6 SAY oSay[1] PROMPT cText_Duration OF oDlgSettings   SIZE 180,10
    @ 4.2, 6 SAY oSay[2] PROMPT cText_transparency OF oDlgSettings SIZE 180,10


    @ 22, 20 SLIDER oDuration VAR nDuration OF oDlgSettings ;
                   HORIZONTAL ;
                   RIGHT DIRECTION ;
                   RANGE 1000, 5000 ;  // 0 = NO close
                   MARKS 6;
                   EXACT;
                   ON CHANGE  oSay[3]:settext(str(nDuration)+FWString("seconds")) ;
                   SIZE 200, 12 PIXEL

     @ 38, 96 SAY oSay[3] PROMPT  str(nDuration)+FWString("seconds") OF oDlgSettings   SIZE 120,10 pixel


    @ 80, 20 SLIDER oTrans VAR ntransparency OF oDlgSettings ;
                   HORIZONTAL ;
                   RIGHT DIRECTION ;
                   RANGE 100, 300 ;
                   MARKS 11;
                   EXACT;
                   ON CHANGE   oSay[4]:settext(str(ntransparency)+FWString(" trasparency level")) ;
                   SIZE 200, 12 PIXEL

    @ 96, 96 SAY oSay[4] PROMPT  str(ntransparency)+FWString(" trasparency level")  OF oDlgSettings SIZE 120,10      pixel



    @ 118, 14 BUTTON obtn[1] PROMPT FWString("&Preview") SIZE 45,12  OF oDlgSettings PIXEL   action (::nLevel := ntransparency,oThis:Display())
    @ 118, 94 BUTTON obtn[2] PROMPT FWString("&Ok") SIZE 45,12  OF oDlgSettings PIXEL       action  oDlgSettings:End(IDOK)
    @ 118, 164 BUTTON obtn[3] PROMPT FWString("&Cancel") SIZE 45,12  OF oDlgSettings PIXEL  action  oDlgSettings:End(IDCANCEL)





        ACTIVATE DIALOG oDlgSettings CENTERED

    IF oDlgSettings:nresult == IDOK

           ::nTimer := nDuration
           ::nLevel := ntransparency

       msginfo( "Transp. : " + STR( ::nLevel), "Seconds : " + STR( ::nTimer ) )

    Endif


    ::oTimer:Activate()

    return nil


  //----------------------------------------------------------------------------//

     METHOD MoveTask(ntime) CLASS TDesktopAlert

     Local  oDlgheight := GetSysMetrics(1)
     Local  oTask:=self

  default ntime := 4



     SndPlaySound( "C:\Work\fwh\sounds\alert.wav", 0 )

   for i = 1 to 20
        oDlgheight :=  oDlgheight - i
       oTask:Move(  oDlgheight, 100, 200, 200, .t. )
       SysWait(.02)
   next
   SysWait(ntime)
   for i = 1 to 20
        oDlgheight :=  oDlgheight + i
       otask:Move(  oDlgheight, 100, 200, 200, .t. )
       SysWait(.02)
   next
   otask:end()
  return nil






    //----------------------------------------------------------------------------//
    // Functions
    //----------------------------------------------------------------------------//

    static function Line( hDC, nTop, nLeft, nBottom, nRight, nColor, nWidth )

       local hPen, hOldPen

       DEFAULT nColor := CLR_BLACK, nWidth := 1

       hPen = CreatePen( PS_SOLID, nWidth, nColor )
       hOldPen = SelectObject( hDC, hPen )

       MoveTo( hDC, nLeft, nTop )
       LineTo( hDC, nRight, nTop )

       SelectObject( hDC, hOldPen )
       DeleteObject( hPen )

    return 0

    //----------------------------------------------------------------------------//

    Static Function DropDownbutton( hDC, nTop, nLeft, lOver )
    local oFont, hOldFont
    local aRect
    local nMode

    // create a  arrow down button

    DEFAULT lOver := .f.

      nMode    := SetBkMode( hDC, 1 )
      oFont := TFont():New( "Marlett", 0, -10, .f.,.f.,,,,.f.,.f.,.f., 1 )
      hOldFont := SelectObject( hDC, oFont:hFont )
      aRect := {nTop,nLeft,nTop+10,nLeft+ 9}
      TextOut( hDC, aRect[1]+1, aRect[2], "u" )
      SelectObject( hDC, hOldFont  )
      oFont:End()
      SetBkMode( hDC, nMode )
      if lOver
         Box(hDC,aRect)
      endif
      return aRect

    //---------------------------------------------------------------------------//

    Static Function closebutton( hDC, nTop, nLeft, lOver )
    local oFont, hOldFont
    local aRect
    local nMode

    // create a X button

    DEFAULT lOver := .f.

      nMode    := SetBkMode( hDC, 1 )
      oFont := TFont():New( "Marlett", 0, -10, .f.,.f.,,,,.f.,.f.,.f., 1 )
      hOldFont := SelectObject( hDC, oFont:hFont )
      aRect := {nTop,nLeft,nTop+10,nLeft+ 9}
      TextOut( hDC, aRect[1]+1, aRect[2], "r" )
      SelectObject( hDC, hOldFont  )
      oFont:End()
      SetBkMode( hDC, nMode )
      if lOver
         Box(hDC,aRect)
      endif
      return aRect
    //---------------------------------------------------------------------------//


        #define GWL_EXSTYLE   -20
        #define WS_EX_LAYERED 524288

    static function SetTransparent( oDlg,nLevel )

       DEFAULT   nLevel := 160

           SetWindowLong( oDlg:hWnd, GWL_EXSTYLE, nOr( GetWindowLong( oDlg:hWnd, GWL_EXSTYLE ), WS_EX_LAYERED ) )

           SetLayeredWindowAttributes( oDlg:hWnd, 0, nLevel, 2 )

        return nil

    //---------------------------------------------------------------------------//

 

Re: Desktop Alerts

PostPosted: Sun Mar 19, 2017 8:11 pm
by devtuxtla
Hello Antonio

How can we associate the alert, relative to the window to which it belongs, so that if the window is contracted, the alert message is associated with the relative position of the window that called it?

I tried with the example but it always shows it in a position relative to the screen and not to the window that I call it.

Do you have any idea how to do it?

Thank you

Re: Desktop Alerts

PostPosted: Sat Oct 07, 2017 2:31 pm
by Busmatic_wpb
Buenos Dias Estimados.

Mi pregunta es la siguiente. Es posible hacer el llamdo desde cualquier dialogo o window sin necesidad de definir
DEFINE WINDOW como primera instancia.
Lo que deseo hacer es llamar al thedesktop Alert desde cualquier parte de mi programa para mostrar alertas o sucesos.
alguien lo ha echo.. gracias

Muy agradecido.

Re: Desktop Alerts

PostPosted: Tue Apr 10, 2018 4:24 am
by ronaldo
nPathTemp
function MsgFancy(oWnd, cTexto, aPos, oCor, lAguarda, lTransparente)
local oDlg
local oBtnClose, aTexto
local oSay, lCenter
local oImage, oLbx
local lSaida:=.F., nCorFundoHTML := "#ffffcc" //azul claro

lCenter := aPos == NIL

//DEFAULT
oCor := nrgb(255,255,255)
DEFAULT aPos := {0,0}
DEFAULT lAguarda := .F.
DEFAULT lTransparente := .T.


atexto := "<html>"
atexto += "<style type='text/css'>"
atexto += "body {"
atexto += " margin:5;"
atexto += "}"
atexto += "</style>"
atexto += "<body scroll='auto' bgcolor='" + nCorFundoHTML + "'>"
atexto += "<div style='float:left; width:38px;margim-right:30px;'>"
atexto += "<img src='" + nexecutavel+"\img\information-icon.png" + "'style=width:32px;height:32px'>"
atexto += "</div>"

atexto += "<div style=float:left>"
aTexto += strtran(cTexto, CRLF, "<br/>")

atexto += "</div>"

atexto += "</body>"
atexto += "</html>"

ferase( curdir() + "\aviso.html" )
memowrit(curdir() + "\aviso.html", aTexto)



DEFINE DIALOG oDlg FROM 1,1 TO 150,490 STYLE nOr( WS_POPUP, WS_BORDER ) PIXEL OF oWnd

@ -3, 235 BTNBMP oBtnClose RESOURCE 0xFD ;
SIZE 14, 14 OF oDlg ACTION (lSaida:=.T.,odlg:end())PIXEL TRANSPARENT NOBORDER
oBtnClose:cToolTip := "Fechar!"


oDlg:bStart:={||;
oLbx := TActiveX():New( oDlg, "Shell.Explorer.2",-3,-2,oDlg:nWidth-20,178 ),;
oLbx:Do( "Navigate", curdir() + "\aviso.html"),;
if(lCenter, WndCenter( oDlg:hWnd),)}


if lAguarda
ACTIVATE DIALOG oDlg ON INIT (oDlg:Move(aPos[1],aPos[1]), ;
oDlg:SetColor(CLR_WHITE, oCor),;
if(lTransparente, SetTransparent( oDlg ),"")) ;
VALID lSaida
else
ACTIVATE DIALOG oDlg ON INIT (oDlg:Move(aPos[1],aPos[1]), ;
oDlg:SetColor(CLR_WHITE, oCor),;
if(lTransparente, SetTransparent( oDlg ),"")) ;
NOWAIT ;
VALID lSaida
endif




return(.T.)

Re: Desktop Alerts

PostPosted: Wed Apr 11, 2018 9:39 am
by Silvio.Falconi
??????

Re: Desktop Alerts

PostPosted: Thu Apr 12, 2018 3:10 pm
by ronaldo
É um exemplo de DesktopAlert, utilizando códigos de HTML. para executar utilize assim:

MsgFancy(Memvar->oDlg,"Acesso negado!!! <br/><br/> Não é permitido modificar lançamentos quando já baixado (Repassado).",nil, CLR_YELLOW,.T.,.F.)


coloque junto esta função...

#define LWA_ALPHA 2
#define GWL_EXSTYLE -20
#define WS_EX_LAYERED 524288
Function SetTransparent( oDlg )

SetWindowLong( oDlg:hWnd, GWL_EXSTYLE, nOr( GetWindowLong( oDlg:hWnd, GWL_EXSTYLE ), WS_EX_LAYERED ) )

SetLayeredWindowAttributes( oDlg:hWnd, 0, 160, 2 )

return nil