FiveTech Support Forums

FiveWin / Harbour / xBase community
Board index FiveWin para Harbour/xHarbour ejemplo c5Tooltip
Posts: 389
Joined: Wed Nov 29, 2006 01:51 PM
Re: ejemplo c5Tooltip
Posted: Sat Sep 14, 2013 08:35 AM

Antonio,
entiendo, gracias por responder.
Salu2, Ariel.

Posts: 44158
Joined: Thu Oct 06, 2005 05:47 PM
Re: ejemplo c5Tooltip
Posted: Sat Sep 14, 2013 08:52 AM
Silvio,

I like your idea, thanks! :-)

I have modified it this way:
Code (fw): Select all Collapse
   if ::oTimer != nil
      ::oTimer:Deactivate()
      ::oTimer:End()
   endif

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


Now we need to figure how a easy way to relate a tooltip with a control
regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 44158
Joined: Thu Oct 06, 2005 05:47 PM
Re: ejemplo c5Tooltip
Posted: Sat Sep 14, 2013 11:21 AM
Ok, I have cleaned the Class, reformatted it, removed the not needed code, and here you have it:

I have also added shadow support.



Code (fw): Select all Collapse
#include "fivewin.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

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

CLASS TC5Tooltip FROM TWindow

聽 聽 聽 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 lBtnClose 聽 聽AS LOGICAL INIT .f.

聽 聽 聽 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

聽 聽 聽 METHOD New( nTop, nLeft, nWidth, nHeight, oWnd, lDisenio, nClrPane, ;
聽 聽 聽 聽 聽 聽 聽 聽 聽 nClrPane2, nClrText, nWRadio, nHRadio ) 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. )

ENDCLASS

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

METHOD New( nTop, nLeft, nWidth, nHeight, oWnd, lDisenio, nClrPane, nClrPane2,; 
聽 聽 聽 聽 聽 聽 nClrText, nWRadio, nHRadio ) CLASS TC5ToolTip

聽 聽DEFAULT nClrPane 聽:= CLR_WHITE
聽 聽DEFAULT nClrPane2 := nClrPane
聽 聽DEFAULT nClrText 聽:= 0
聽 聽DEFAULT nWRadio 聽 := 2
聽 聽DEFAULT nHRadio 聽 := 2

聽 聽::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

聽 聽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 = "Undefined"
聽 聽::hRgn 聽 = nil

聽 聽::Default( .T. )

return Self

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

METHOD GetSize() CLASS TC5ToolTip

聽 聽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 TC5ToolTip

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

聽 聽DEFAULT lShowDlg := .F.

聽 聽::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 TC5Tooltip

聽 聽if nMsg == 20
聽 聽 聽 return 1
聽 聽endif

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

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

METHOD ReSize( nSizeType, nWidth, nHeight ) CLASS TC5Tooltip

聽 聽::Default()
聽 聽::Refresh()

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

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

METHOD Paint() CLASS TC5ToolTip

聽 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 )

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

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

聽 聽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 )
聽 // FrameRgn( hDCMem, hRgn, hBrush, 1, 1 )
聽 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 TC5ToolTip

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

聽 聽// 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 TC5ToolTip

聽 聽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 TC5ToolTip

聽 聽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 TC5ToolTip

聽 聽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

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

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

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


And here you have an example of use:
Code (fw): Select all Collapse
// C5 Tooltips demo

#include "FiveWin.ch"

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

function Main()

聽 聽local oWnd

聽 聽DEFINE WINDOW oWnd

聽 聽ACTIVATE WINDOW oWnd ;
聽 聽 聽 ON INIT 聽ShowToolTip() ;
聽 聽 聽 ON CLICK ShowTooltip()

return nil 聽 

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

function ShowToolTip( oWnd )

聽 聽local oTT := TC5Tooltip():New( 100, 100, 250, 150, oWnd, .T., CLR_CYAN, CLR_WHITE )
聽 聽
聽 聽oTT:cHeader 聽= "header"
聽 聽oTT:cBody 聽 聽= "this is the body of the tooltip" + CRLF + "It looks nice"
聽 聽oTT:cFoot 聽 聽= "this is the footer"
聽 聽oTT:cBmpFoot = "..\bitmaps\16x16\help.bmp"
聽 聽oTT:cBmpLeft = "..\bitmaps\16x16\mail.bmp"

聽 聽oTT:lLineHeader = .T.
聽 聽// These are not working yet
聽 聽oTT:lBtnClose 聽 = .T.
聽 聽oTT:lSplitHdr 聽 = .T. 
聽 聽oTT:lBorder 聽 聽 = .T.

return nil

//----------------------------------------------------------------------------//
regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 44158
Joined: Thu Oct 06, 2005 05:47 PM
Re: ejemplo c5Tooltip
Posted: Sat Sep 14, 2013 11:27 AM
In Method Paint() this provides support to DATA lBorder:

Code (fw): Select all Collapse
  hBrush = CreateSolidBrush( ::nClrBorder )
  if ::lBorder
     FrameRgn( hDCMem, hRgn, hBrush, 1, 1 )
  endif   
  DeleteObject( hBrush )
  DeleteObject( hRgn )
regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 44158
Joined: Thu Oct 06, 2005 05:47 PM
Re: ejemplo c5Tooltip
Posted: Sat Sep 14, 2013 11:52 AM
Enhanced version:

Code (fw): Select all Collapse
#include "fivewin.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

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

CLASS TC5Tooltip FROM TWindow

      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 lBtnClose    AS LOGICAL INIT .F.

      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

      METHOD New( nTop, nLeft, nWidth, nHeight, oWnd, lDisenio, nClrPane, ;
                  nClrPane2, nClrText, nWRadio, nHRadio ) 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. )

ENDCLASS

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

METHOD New( nTop, nLeft, nWidth, nHeight, oWnd, lDisenio, nClrPane, nClrPane2,; 
            nClrText, nWRadio, nHRadio ) CLASS TC5ToolTip

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

   ::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

   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 = "Undefined"
   ::hRgn   = nil

   ::Default( .T. )

return Self

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

METHOD GetSize() CLASS TC5ToolTip

   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 TC5ToolTip

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

   DEFAULT lShowDlg := .F.

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

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

   DeleteObject( ::hRgn )

return 0

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

METHOD HandleEvent( nMsg, nWParam, nLParam ) CLASS TC5Tooltip

   if nMsg == 20
      return 1
   endif

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

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

METHOD ReSize( nSizeType, nWidth, nHeight ) CLASS TC5Tooltip

   ::Default()
   ::Refresh()

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

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

METHOD Paint() CLASS TC5ToolTip

  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[ 1 ], rc[ 2 ], rc[ 3 ], rc[ 4 ] },;
                                        ::nWRadio, ::nHRadio )

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

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

   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   
  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 TC5ToolTip

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

   // 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 TC5ToolTip

   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 TC5ToolTip

   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 TC5ToolTip

   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

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

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

//----------------------------------------------------------------------------//
regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 44158
Joined: Thu Oct 06, 2005 05:47 PM
Re: ejemplo c5Tooltip
Posted: Sat Sep 14, 2013 11:55 AM

Una diferencia entre el c贸digo de C5 y el de FWH es que la funci贸n CreateRoundRectRgn() de FWH espera un primer par谩metro array que contiene las coordenadas en formato nTop, nLeft, nBottom y nRight.

En C5 se sigue la sintaxis del API de Windows (nLeft, nTop, nWidth, nHeight), pero para FWH es mucho m谩s c贸modo permitir ese array, pues lo devuelven m茅todos como GetRect() de FWH y asi nos evita tener que manipular las coordenadas.

Podemos intentar compatibilizar ambos...

regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 44158
Joined: Thu Oct 06, 2005 05:47 PM
Re: ejemplo c5Tooltip
Posted: Sat Sep 14, 2013 12:00 PM
Aqui est谩 la funci贸n CreateRoundRectRgn() compatible tanto con FWH como con el API de Windows y con C5 :-)

Code (fw): Select all Collapse
HB_FUNC( CREATEROUNDRECTRGN )
{
聽 聽HRGN hRgn;

聽 聽if( hb_pcount() > 3 ) // C5 format
聽 聽 聽 hRgn = CreateRoundRectRgn( hb_parni( 1 ), hb_parni( 2 ), hb_parni( 3 ),
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽hb_parnl( 4 ), hb_parni( 5 ), hb_parni( 6 ) );
聽 聽else
聽 聽 聽 hRgn = CreateRoundRectRgn( hb_parvni( 1, 2 ), hb_parvni( 1, 1 ), 
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽hb_parvni( 1, 4 ), hb_parvni( 1, 3 ),
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽hb_parni( 2 ), hb_parni( 3 ) ); 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽聽 聽 

聽 聽RegisterResource( hRgn, "REGION" );
聽 聽 
聽 聽#ifndef _WIN64
聽 聽 聽 hb_retnl( ( LONG ) hRgn );
聽 聽#else 聽 
聽 聽 聽 hb_retnll( ( LONGLONG ) hRgn );
聽 聽#endif
}
regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 44158
Joined: Thu Oct 06, 2005 05:47 PM
Re: ejemplo c5Tooltip
Posted: Sat Sep 14, 2013 12:06 PM
Reevisando la Clase de C5 veo que Paco contempl贸 el mostrar un bot贸n de cierre del tooltip (DATA lBtnClose), pero viendo im谩genes en google im谩genes no veo tooltips con ese bot贸n de cierre.

Supongo que la idea viene m谩s de los notifications balloons:
http://msdn.microsoft.com/en-us/library/windows/desktop/aa511497.aspx

Se los a帽adimos ? Y en tal caso, que bitmap usamos para el cierre ? La cruz gris ?
regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 6755
Joined: Wed Feb 15, 2012 08:25 PM
Re: ejemplo c5Tooltip
Posted: Sat Sep 14, 2013 12:12 PM
Una propuesta

Cristobal Navarro

Hay dos tipos de personas: las que te hacen perder el tiempo y las que te hacen perder la noci贸n del tiempo

El secreto de la felicidad no est谩 en hacer lo que te gusta, sino en que te guste lo que haces
Posts: 44158
Joined: Thu Oct 06, 2005 05:47 PM
Re: ejemplo c5Tooltip
Posted: Sat Sep 14, 2013 12:16 PM

Cristobal,

Pero ese bot贸n de cierre no parece estandard. No me suena haberlo visto nunca...

regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 44158
Joined: Thu Oct 06, 2005 05:47 PM
Re: ejemplo c5Tooltip
Posted: Sat Sep 14, 2013 06:55 PM
Bueno, pues gracias a la feliz idea de Silvio de que el timer perteneciese al propio objeto tooltip, ya tenemos los tooltips de C5 funcionando! :-)

La idea es que ahora todas las ventanas, controles, di谩logos tienen la DATA oToolTip y si ahi asignamos un objeto TC5ToolTip pues se pone en funcionamiento.

He tenido que modificar cosas en la Clase TWindow y en la Clase TC5Tooltip. Aqui teneis una demo con el c贸digo fuente:
https://code.google.com/p/fivewin-contributions/downloads/detail?name=c5tooltip_demo.zip

Si copiais el EXE a la carpeta SAMPLES de FWH vereis ademas como usa los bitmaps :-)

Si no le veis objecciones, podemos incluirlos en FWH 13.08
regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 555
Joined: Wed Jul 31, 2013 01:14 PM
Re: ejemplo c5Tooltip
Posted: Sat Sep 14, 2013 07:15 PM

Excelente trabajo Antonio.

Muchas gracias a Ud. y a Paco.

Saludos

Dario Fernandez

Dario Fernandez

FWH 2501, Harbour, MVS2022 Community, MySql & MariaDB, Dbf/Cdx VSCode.

Maldonado - Uruguay
Posts: 44158
Joined: Thu Oct 06, 2005 05:47 PM
Re: ejemplo c5Tooltip
Posted: Sat Sep 14, 2013 07:18 PM
Una peque帽a correcci贸n al ejemplo anterior. Se calculaban mal las coordenadas relativas, ahora esta bien :-)

https://code.google.com/p/fivewin-contributions/downloads/detail?name=c5tooltip_demo_2.zip
regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 7317
Joined: Thu Oct 18, 2012 07:17 PM
Re: ejemplo c5Tooltip
Posted: Sun Sep 15, 2013 09:03 AM

Antonio,
If you decide to insert the new Tooltip class on window ( and on all controls) I think you must create a selection for this

type
x,y SAY ..... TOOLTIP NORMAL " BLABLABLABLABLA"

  1. oldTooltip ( one line and yellow) TOOLTIP NORMAL
  2. Baloon TOOLTIP BALLOONS
  3. the new tooltip ( supertooltip) TOOLTIP SUPER

JUST AND iDEA

also you can insert to windows class

CLASSDATA oToolTip
CLASSDATA lSuperTooltips

and when you create the tooltip on METHOD ShowToolTip

If :: lSuperTooltips
::oToolTip := TC5Tip():New( ............... )

else

DEFINE WINDOW ::oToolTip FROM 0, 0 TO 1, 5 ;
STYLE nOr( WS_POPUP, WS_BORDER ) ;
COLOR 0, RGB( 255, 255, 225 ) OF Self

Since from 1991/1992 ( fw for clipper Rel. 14.4 - Momos)

I use : FiveWin for Harbour March-April 2024 - Harbour 3.2.0dev (harbour_bcc770_32_20240309) - Bcc7.70 - xMate ver. 1.15.3 - PellesC - mail: silvio[dot]falconi[at]gmail[dot]com
Posts: 7317
Joined: Thu Oct 18, 2012 07:17 PM
Re: ejemplo c5Tooltip
Posted: Sun Sep 15, 2013 09:07 AM
Antonio Linares wrote:Cristobal,

Pero ese bot贸n de cierre no parece estandard. No me suena haberlo visto nunca...




I'm thinking the button close is no need !!!
Since from 1991/1992 ( fw for clipper Rel. 14.4 - Momos)

I use : FiveWin for Harbour March-April 2024 - Harbour 3.2.0dev (harbour_bcc770_32_20240309) - Bcc7.70 - xMate ver. 1.15.3 - PellesC - mail: silvio[dot]falconi[at]gmail[dot]com