Re: Desktop Alerts
Posted: Thu Mar 10, 2016 10:15 pm
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
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
//---------------------------------------------------------------------------//