Newsgroup: it.comp.lang.vo-clipper
Titolo: [VO2] Subclassing ShellWindow

Riprendendo un esempio trovato non so dove, ho costruito una classe che
deriva dalla ShellWindow ed aggiunge alcune funzionalità (sfondo bitmap,
aree attive selezionabili ecc.)
Per tali funzioni devo intercettare anche il messaggio  WM_ERASEBKGND
direttamente da un mia WindowProc.
Ho dovuto quindi subclassare la ShellWindow come segue...
// classe da cui ineritare la StandardShellWindow
CLASS MaxShell INHERIT SHELLWINDOW
....
METHOD Init(oParent,uExtra) CLASS MaxShell
 LOCAL oldstyle AS LONG
 SUPER:Init(oParent,uExtra)
 pfnOldFunc := PTR(_CAST, SetWindowLong(SELF:handle( 4), GWL_WNDPROC,
LONG(_CAST,@NewClientProc ())) )
.............
/* NewClientProc è la nuova WindowProc
FUNCTION NewClientProc(hwnd AS PTR, uMsg AS DWORD, wParam AS DWORD,lParam AS
LONG) AS LONG _WINCALL
 LOCAL LRet AS LONG
 LRet := CallWindowProc(pfnOldFunc,hWnd,uMsg,wParam,lParam)
 IF ( oShell != NULL_OBJECT )
  DO CASE
   CASE uMsg == WM_LBUTTONDOWN
    oShell:ShellMouseInside(LParam)
   CASE  uMsg == WM_MOUSEMOVE
    oShell:ShellMouseMoveInside(Lparam)
   CASE  uMsg ==  WM_ERASEBKGND
    ValidateRect ( hWnd, 0 )
    DrawBackGround ( hWnd , ShellWindowBackGroundImage )
    oShell:UpdateText()
  END
 ENDIF
 RETURN LRet
....
Funziona quasi tutto, lo sfondo viene generato correttamente, le aree attive
della shell rispondono al mouse ma... l'imput focus mi scompare sempre dalle
finestre child che appaiono come disattivate. Per accedere ai controlli
delle finestre child e ai dialoghi modali devo cliccare numerose volte.
Qualcuno ha mai provato a subclassare la Shell utilizzando le procedure
CALLBACK come si faceva in Windows?
Bye.



Questa e' la funzione che uso io:
FUNCTION FCClientWinProc( hWnd AS PTR, Msg AS WORD, wParam AS WORD,
lParam AS LONG ) AS LONG _WINCALL	
	// Funzione di gestione messaggi della Shell Window
	LOCAL liRetVal 				AS LONGINT
	LOCAL hDC 					AS PTR
	LOCAL ps					IS _WINPAINTSTRUCT
	LOCAL lpfnDefaultProc 		AS PTR
	LOCAL STATIC hBitMap		AS WORD
	LOCAL STATIC siWhichToPaint AS SHORTINT
	LOCAL STATIC pszText		AS PSZ
 
	// Memorizza la funzione di VO di gestione degli eventi
	lpfnDefaultProc :=  PTR( _CAST, GetClassLong( WORD(_CAST, hWnd),
GCL_WNDPROC ))
	DO CASE
	// WM_USER
	CASE Msg == WM_USER + 1
		// Legge la stringa da visualizzare come sfondo
		PszText := PSZ( _CAST, lParam )
		siWhichToPaint := 1
		RETURN  0L
 
	CASE Msg == WM_USER + 2
		// Handle del bitmap
		hBitMap := WORD( _CAST, lParam )
		siWhichToPaint := 2
		RETURN  0L
 
	CASE Msg == WM_USER + 3
		// Legge la stringa da visualizzare come sfondo
		PszText := PSZ( _CAST, lParam )
		siWhichToPaint := 2
		RETURN 0L
	// I tre messaggi seguenti vanno gestiti per il repaint, gli altri
vengono getiti da VO
	CASE Msg == WM_PAINT
		hDC := BeginPaint( hWnd, @ps )
		IF siWhichToPaint == 1
			GradientFill( WORD(_CAST, hWnd), WORD(_CAST, hDC ))
			PEDrawText( WORD(_CAST, hWnd), WORD(_CAST, hDC), PszText
)	
		ELSEIF  siWhichToPaint == 2
 
			DrawShellBitMap( WORD(_CAST, hWnd), WORD(_CAST, hDC),
hBitMap )
			PEDrawText( WORD(_CAST, hWnd), WORD(_CAST, hDC), PszText
)							
		ENDIF
		EndPaint( hWnd, @ps )
		RETURN 0L
 
	CASE Msg == WM_SIZE
		// Forza un repaint completo
		InvalidateRect( hWnd, NULL_PTR, TRUE )
		liRetVal := CallWindowProc(  lpfnDefaultProc , hWnd, Msg,
wParam, lParam )		
	CASE Msg == WM_ERASEBKGND
		RETURN 0L
 
	OTHERWISE
		// Passa la gestione del messaggio a VO
		liRetVal := CallWindowProc(  lpfnDefaultProc , hWnd, Msg,
wParam, lParam )
	ENDCASE
 
	RETURN  liRetVal
 
Fabio		
-----------------------------
Fabio Cresta
EDP Consultant & VO/Jasmine developer ITALY
President of Clipper/Visual Objects/Jasmine User Group Italy
e-mail: 
fcr...@tin.it
 
fcr...@windevs.com
web: 
http://www.windevs.com
------------------------------