/*---------------------------------------------------------------------------- MINIGUI - Harbour Win32 GUI library source code Copyright 2002-2010 Roberto Lopez <harbourminigui@gmail.com> http://harbourminigui.googlepages.com/ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this software; see the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA (or visit the web site http://www.gnu.org/). As a special exception, you have permission for additional uses of the text contained in this release of Harbour Minigui. The exception is that, if you link the Harbour Minigui library with other files to produce an executable, this does not by itself cause the resulting executable to be covered by the GNU General Public License. Your use of that executable is in no way restricted on account of linking the Harbour-Minigui library code into it. Parts of this project are based upon: "Harbour GUI framework for Win32" Copyright 2001 Alexander S.Kresin <alex@belacy.belgorod.su> Copyright 2001 Antonio Linares <alinares@fivetech.com> www - http://harbour-project.org "Harbour Project" Copyright 1999-2012, http://harbour-project.org/ "WHAT32" Copyright 2002 AJ Wos <andrwos@aust1.net> "HWGUI" Copyright 2001-2009 Alexander S.Kresin <alex@belacy.belgorod.su> ---------------------------------------------------------------------------*/ #ifndef CINTERFACE #define CINTERFACE #endif #define _WIN32_IE 0x0500 #ifdef __POCC__ #define _WIN32_WINNT 0x0500 #else #define _WIN32_WINNT 0x0400 #endif #include <windows.h> #include <commctrl.h> #include "olectl.h" #include "hbapi.h" #include "hbapiitm.h" #include "hbinit.h" #include "hbvm.h" HBITMAP loadolepicture ( char *filename, int width, int height, HWND handle, int scalestrech, int whitebackground, int transparent ); LRESULT APIENTRY PictSubClassFunc ( HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam ); static WNDPROC LabelOldWndProc; static BOOL read_image ( char *filename, DWORD *nFileSize, HGLOBAL *hMem ); static BOOL read_image_rsrc ( HINSTANCE hInstance, HRSRC hResInfo, HGLOBAL *hMem ); static void calc_rect ( HWND handle, int width, int height, int scalestrech, LONG lWidth, LONG lHeight, RECT *rect, RECT *rect2 ); HB_FUNC( INITIMAGE ) { HWND wndhandle; HWND wndparent = ( HWND ) hb_parnl( 1 ); int Style = WS_CHILD | SS_BITMAP; if( !hb_parl( 5 ) ) Style |= WS_VISIBLE; if( hb_parl( 6 ) || hb_parl( 7 ) ) Style |= SS_NOTIFY; wndhandle = CreateWindowEx( 0, "static", NULL, Style, hb_parni( 3 ), hb_parni( 4 ), 0, 0, wndparent, ( HMENU ) hb_parni( 2 ), GetModuleHandle( NULL ), NULL ); if( hb_parl( 7 ) ) LabelOldWndProc = ( WNDPROC ) SetWindowLong( wndhandle, GWL_WNDPROC, ( LONG ) PictSubClassFunc ); hb_retnl( ( LONG ) wndhandle ); } HB_FUNC( C_SETPICTURE ) { HBITMAP hBitmap; if( hb_parclen( 2 ) == 0 ) hb_retnl( ( LONG ) NULL ); hBitmap = loadolepicture( ( char * ) hb_parc( 2 ), hb_parni( 3 ), hb_parni( 4 ), ( HWND ) hb_parnl( 1 ), hb_parni( 5 ), hb_parni( 6 ), hb_parni( 7 ) ); if( hBitmap != NULL ) SendMessage( ( HWND ) hb_parnl( 1 ), ( UINT ) STM_SETIMAGE, ( WPARAM ) IMAGE_BITMAP, ( LPARAM ) hBitmap ); hb_retnl( ( LONG ) hBitmap ); } #define _OLD_STYLE 0 LRESULT APIENTRY PictSubClassFunc ( HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam ) { TRACKMOUSEEVENT tme; static PHB_SYMB pSymbol = NULL; static BOOL bMouseTracking = FALSE; long int r = 0; #if _OLD_STYLE BOOL bCallUDF = FALSE; #endif if( Msg == WM_MOUSEMOVE || Msg == WM_MOUSELEAVE ) { if( Msg == WM_MOUSEMOVE ) { if( bMouseTracking == FALSE ) { tme.cbSize = sizeof( TRACKMOUSEEVENT ); tme.dwFlags = TME_LEAVE; tme.hwndTrack = hWnd; tme.dwHoverTime = HOVER_DEFAULT; if( _TrackMouseEvent( &tme ) == TRUE ) { #if _OLD_STYLE bCallUDF = TRUE; #endif bMouseTracking = TRUE; } #if _OLD_STYLE } else { bCallUDF = FALSE; #endif } } else { #if _OLD_STYLE bCallUDF = TRUE; #endif bMouseTracking = FALSE; } #if _OLD_STYLE if( bCallUDF == TRUE ) { #endif if( !pSymbol ) pSymbol = hb_dynsymSymbol( hb_dynsymGet( "OLABELEVENTS" ) ); if( pSymbol ) { hb_vmPushSymbol( pSymbol ); hb_vmPushNil(); hb_vmPushLong( ( LONG ) hWnd ); hb_vmPushLong( Msg ); hb_vmPushLong( wParam ); hb_vmPushLong( lParam ); hb_vmDo( 4 ); r = hb_parnl( -1 ); } #if _OLD_STYLE } #endif return ( r != 0 ) ? r : CallWindowProc( LabelOldWndProc, hWnd, 0, 0, 0 ); } return CallWindowProc( LabelOldWndProc, hWnd, Msg, wParam, lParam ); } #undef _OLD_STYLE HBITMAP loadolepicture ( char *filename, int width, int height, HWND handle, int scalestrech, int whitebackground, int transparent ) { UINT fuLoad = ( transparent == 0 ) ? LR_CREATEDIBSECTION : LR_CREATEDIBSECTION | LR_LOADMAP3DCOLORS | LR_LOADTRANSPARENT; IStream *iStream; IPicture *iPicture = NULL; HGLOBAL hMem = ( HGLOBAL ) NULL; HRSRC hResInfo; HRESULT hr; DWORD nFileSize = 0; RECT rect, rect2; BITMAP bm; HBITMAP bitmap, bitmap2; LONG lWidth, lHeight; // TODO HINSTANCE hInstance = GetModuleHandle( NULL ); /* MSDN: An application must not delete a DC whose handle was obtained * by calling the GetDC function. * Instead, it must call the ReleaseDC function to free the DC */ HDC imgDC = GetDC( handle ); HDC tmpDC; HDC tmp2DC = ( HDC ) NULL; bitmap2 = ( HBITMAP ) LoadImage( hInstance, filename, IMAGE_BITMAP, 0, 0, fuLoad ); if( bitmap2 == NULL ) bitmap2 = ( HBITMAP ) LoadImage( NULL, filename, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | fuLoad ); if( bitmap2 == NULL ) { hResInfo = FindResource( hInstance, filename, "JPG" ); if( hResInfo == NULL ) hResInfo = FindResource( hInstance, filename, "GIF" ); if( hResInfo == NULL ) { if( read_image( filename, &nFileSize, &hMem ) == FALSE ) { ReleaseDC( handle, imgDC ); return NULL; } } else if( read_image_rsrc( hInstance, hResInfo, &hMem ) == FALSE ) { ReleaseDC( handle, imgDC ); return NULL; } hr = CreateStreamOnHGlobal( hMem, TRUE, &iStream ); if( hr != S_OK || iStream == NULL ) { GlobalFree( hMem ); ReleaseDC( handle, imgDC ); return NULL; } #if defined( __cplusplus ) hr = OleLoadPicture( iStream, nFileSize, FALSE, IID_IPicture, ( LPVOID * ) &iPicture ); iStream->Release(); #else hr = OleLoadPicture( iStream, nFileSize, FALSE, &IID_IPicture, ( LPVOID * ) &iPicture ); iStream->lpVtbl->Release( iStream ); #endif if( hr != S_OK || iPicture == NULL ) { GlobalFree( hMem ); ReleaseDC( handle, imgDC ); return NULL; } iPicture->lpVtbl->get_Width( iPicture, &lWidth ); iPicture->lpVtbl->get_Height( iPicture, &lHeight ); } else { GetObject( bitmap2, sizeof( BITMAP ), &bm ); lWidth = bm.bmWidth; lHeight = bm.bmHeight; tmp2DC = CreateCompatibleDC( imgDC ); SelectObject( tmp2DC, bitmap2 ); } calc_rect( handle, width, height, scalestrech, lWidth, lHeight, &rect, &rect2 ); tmpDC = CreateCompatibleDC( imgDC ); bitmap = CreateCompatibleBitmap( imgDC, width, height ); SelectObject( tmpDC, bitmap ); if( whitebackground == 1 ) FillRect( tmpDC, &rect2, ( HBRUSH ) GetStockObject( WHITE_BRUSH ) ); else FillRect( tmpDC, &rect2, ( HBRUSH ) GetSysColorBrush( COLOR_BTNFACE ) ); if( iPicture != NULL ) { iPicture->lpVtbl->Render( iPicture, tmpDC, rect.left, rect.top, rect.right, rect.bottom, 0, lHeight, lWidth, -lHeight, NULL ); iPicture->lpVtbl->Release( iPicture ); GlobalFree( hMem ); } else { StretchBlt( tmpDC, rect.left, rect.top, rect.right, rect.bottom, tmp2DC, 0, 0, lWidth, lHeight, SRCCOPY ); DeleteDC( tmp2DC ); DeleteObject( bitmap2 ); } ReleaseDC( handle, imgDC ); DeleteDC( tmpDC ); return bitmap; } static BOOL read_image ( char *filename, DWORD *nFileSize, HGLOBAL *hMem ) { HANDLE hFile; LPVOID lpDest; DWORD nSize, nRead; hFile = CreateFile( filename, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); if( hFile == INVALID_HANDLE_VALUE ) return FALSE; nSize = GetFileSize( hFile, NULL ); if( nSize == INVALID_FILE_SIZE || ( *hMem = GlobalAlloc( GHND, nSize ) ) == NULL ) { CloseHandle( hFile ); return FALSE; } *nFileSize = nSize; lpDest = GlobalLock( *hMem ); if( lpDest == NULL ) { GlobalFree( *hMem ); CloseHandle( hFile ); return FALSE; } if( ReadFile( hFile, lpDest, nSize, &nRead, NULL ) == FALSE ) { GlobalUnlock( *hMem ); GlobalFree( *hMem ); CloseHandle( hFile ); return FALSE; } GlobalUnlock( *hMem ); CloseHandle( hFile ); return TRUE; } static BOOL read_image_rsrc ( HINSTANCE hInstance, HRSRC hResInfo, HGLOBAL *hMem ) { HGLOBAL hRes; DWORD nSize; LPVOID lpRes, lpDest; hRes = LoadResource( hInstance, hResInfo ); if( hRes == NULL ) return FALSE; nSize = SizeofResource( hInstance, hResInfo ); lpRes = LockResource( hRes ); if( lpRes == NULL || ( *hMem = GlobalAlloc( GHND, nSize ) ) == NULL ) { FreeResource( hRes ); return FALSE; } lpDest = GlobalLock( *hMem ); if( lpDest == NULL ) { GlobalFree( *hMem ); FreeResource( hRes ); return FALSE; } CopyMemory( lpDest, lpRes, ( SIZE_T ) nSize ); GlobalUnlock( *hMem ); FreeResource( hRes ); return TRUE; } static void calc_rect ( HWND handle, int width, int height, int scalestrech, LONG lWidth, LONG lHeight, RECT *rect, RECT *rect2 ) { if( ( width == 0 ) & ( height == 0 ) ) GetClientRect( handle, rect ); else SetRect( rect, 0, 0, width, height ); SetRect( rect2, 0, 0, rect->right, rect->bottom ); if( scalestrech == 0 ) { if( ( int ) lWidth * rect->bottom / lHeight <= rect->right ) rect->right = ( int ) lWidth * rect->bottom / lHeight; else rect->bottom = ( int ) lHeight * rect->right / lWidth; } rect->left = ( int ) ( width - rect->right ) / 2; rect->top = ( int ) ( height - rect->bottom ) / 2; }
|