/*---------------------------------------------------------------------------- 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-2013, 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 "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; HB_FUNC( INITIMAGE ) { HWND hWnd; HWND hWndParent = ( 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; hWnd = CreateWindowEx( 0, "static", NULL, Style, hb_parni( 3 ), hb_parni( 4 ), 0, 0, hWndParent, ( HMENU ) hb_parni( 2 ), GetModuleHandle( NULL ), NULL ); if( hb_parl( 7 ) ) LabelOldWndProc = ( WNDPROC ) SetWindowLong( hWnd, GWL_WNDPROC, ( LONG ) PictSubClassFunc ); hb_retnl( ( LONG ) hWnd ); } 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 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_vmRequestReenter() ) { 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 ); hb_vmRequestRestore(); } #if _OLD_STYLE } #endif return ( r != 0 ) ? r : CallWindowProc( LabelOldWndProc, hWnd, 0, 0, 0 ); } bMouseTracking = FALSE; return CallWindowProc( LabelOldWndProc, hWnd, Msg, wParam, lParam ); } #undef _OLD_STYLE /*------------------------------------------------------------------------- The following functions are taken from the graphics library Bos Taurus. Bos Taurus, (c) 2012 by Dr. Claudio Soto <srvet@adinet.com.uy> ---------------------------------------------------------------------------*/ //********************************************************************************************************************* // __bt_LoadFileFromResources (FileName, TypeResource) ---> Return hGlobalAlloc //********************************************************************************************************************* static HGLOBAL __bt_LoadFileFromResources( char * FileName, char * TypeResource ) { HRSRC hResourceData; HGLOBAL hGlobalAlloc, hGlobalResource; LPVOID lpGlobalAlloc, lpGlobalResource; DWORD nFileSize; hResourceData = FindResource( NULL, FileName, TypeResource ); if( hResourceData == NULL ) return NULL; hGlobalResource = LoadResource( NULL, hResourceData ); if( hGlobalResource == NULL ) return NULL; lpGlobalResource = LockResource( hGlobalResource ); if( lpGlobalResource == NULL ) return NULL; nFileSize = SizeofResource( NULL, hResourceData ); hGlobalAlloc = GlobalAlloc( GHND, nFileSize ); if( hGlobalAlloc == NULL ) { FreeResource( hGlobalResource ); return NULL; } lpGlobalAlloc = GlobalLock( hGlobalAlloc ); CopyMemory( lpGlobalAlloc, lpGlobalResource, ( SIZE_T ) nFileSize ); GlobalUnlock( hGlobalAlloc ); FreeResource( hGlobalResource ); return hGlobalAlloc; } //********************************************************************************************************************* // __bt_LoadFileFromDisk (FileName) ---> Return hGlobalAlloc //********************************************************************************************************************* static HGLOBAL __bt_LoadFileFromDisk( char * FileName ) { HGLOBAL hGlobalAlloc; LPVOID lpGlobalAlloc; HANDLE hFile; DWORD nFileSize; DWORD nReadByte; hFile = CreateFile( FileName, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); if( hFile == INVALID_HANDLE_VALUE ) return NULL; nFileSize = GetFileSize( hFile, NULL ); if( nFileSize == INVALID_FILE_SIZE ) { CloseHandle( hFile ); return NULL; } hGlobalAlloc = GlobalAlloc( GHND, nFileSize ); if( hGlobalAlloc == NULL ) { CloseHandle( hFile ); return NULL; } lpGlobalAlloc = GlobalLock( hGlobalAlloc ); ReadFile( hFile, lpGlobalAlloc, nFileSize, &nReadByte, NULL ); GlobalUnlock( hGlobalAlloc ); CloseHandle( hFile ); return hGlobalAlloc; } //************************************************************************************************************* // __bt_LoadGDIPlusPicture (FileName, TypePicture) ---> Return hBitmap (Load GIF, JPG, TIFF and PNG image) //************************************************************************************************************* // Begin GDIPLUS Definitions typedef enum GpStatus { Ok = 0, GenericError = 1, InvalidParameter = 2, OutOfMemory = 3, ObjectBusy = 4, InsufficientBuffer = 5, NotImplemented = 6, Win32Error = 7, WrongState = 8, Aborted = 9, FileNotFound = 10, ValueOverflow = 11, AccessDenied = 12, UnknownImageFormat = 13, FontFamilyNotFound = 14, FontStyleNotFound = 15, NotTrueTypeFont = 16, UnsupportedGdiplusVersion = 17, GdiplusNotInitialized = 18, PropertyNotFound = 19, PropertyNotSupported = 20, ProfileNotFound = 21 } GpStatus; #define WINGDIPAPI __stdcall #define GDIPCONST const typedef void GpBitmap; typedef void * DebugEventProc; typedef struct GdiplusStartupInput { UINT32 GdiplusVersion; DebugEventProc DebugEventCallback; BOOL SuppressBackgroundThread; BOOL SuppressExternalCodecs; } GdiplusStartupInput; typedef GpStatus WINGDIPAPI ( *NotificationHookProc )( ULONG_PTR * token ); typedef VOID WINGDIPAPI ( *NotificationUnhookProc )( ULONG_PTR token ); typedef struct GdiplusStartupOutput { NotificationHookProc NotificationHook; NotificationUnhookProc NotificationUnhook; } GdiplusStartupOutput; typedef ULONG ARGB; typedef GpStatus ( WINGDIPAPI * Func_GdiPlusStartup )( ULONG_PTR *, GDIPCONST GdiplusStartupInput *, GdiplusStartupOutput * ); typedef VOID ( WINGDIPAPI * Func_GdiPlusShutdown )( ULONG_PTR ); typedef GpStatus ( WINGDIPAPI * Func_GdipCreateBitmapFromStream )( IStream *, GpBitmap ** ); typedef GpStatus ( WINGDIPAPI * Func_GdipCreateHBITMAPFromBitmap )( GpBitmap *, HBITMAP *, ARGB ); typedef GpStatus ( WINGDIPAPI * Func_GdipDisposeImage )( GpBitmap * ); // End GDIPLUS Definitions static HBITMAP __bt_LoadGDIPlusPicture( char * FileName, char * TypePictureResource ) { IStream * iStream; HBITMAP hBitmap; HGLOBAL hGlobalAlloc; GpBitmap * pGpBitmap; VOID * GdiPlusHandle; ULONG GdiPlusToken; ARGB BkColor; GdiplusStartupInput GDIPlusStartupInput; Func_GdiPlusStartup GdiPlusStartup; Func_GdiPlusShutdown GdiPlusShutdown; Func_GdipCreateBitmapFromStream GdipCreateBitmapFromStream; Func_GdipCreateHBITMAPFromBitmap GdipCreateHBITMAPFromBitmap; Func_GdipDisposeImage GdipDisposeImage; GdiPlusHandle = LoadLibrary( "GdiPlus.dll" ); if( GdiPlusHandle == NULL ) return NULL; GdiPlusStartup = ( Func_GdiPlusStartup ) GetProcAddress( GdiPlusHandle, "GdiplusStartup" ); GdiPlusShutdown = ( Func_GdiPlusShutdown ) GetProcAddress( GdiPlusHandle, "GdiplusShutdown" ); GdipCreateBitmapFromStream = ( Func_GdipCreateBitmapFromStream ) GetProcAddress( GdiPlusHandle, "GdipCreateBitmapFromStream" ); GdipCreateHBITMAPFromBitmap = ( Func_GdipCreateHBITMAPFromBitmap ) GetProcAddress( GdiPlusHandle, "GdipCreateHBITMAPFromBitmap" ); GdipDisposeImage = ( Func_GdipDisposeImage ) GetProcAddress( GdiPlusHandle, "GdipDisposeImage" ); if( GdiPlusStartup == NULL || GdiPlusShutdown == NULL || GdipCreateBitmapFromStream == NULL || GdipCreateHBITMAPFromBitmap == NULL || GdipDisposeImage == NULL ) { FreeLibrary( GdiPlusHandle ); return NULL; } GDIPlusStartupInput.GdiplusVersion = 1; GDIPlusStartupInput.DebugEventCallback = NULL; GDIPlusStartupInput.SuppressBackgroundThread = FALSE; GDIPlusStartupInput.SuppressExternalCodecs = FALSE; if( GdiPlusStartup( &GdiPlusToken, &GDIPlusStartupInput, NULL ) ) { FreeLibrary( GdiPlusHandle ); return NULL; } if( TypePictureResource != NULL ) hGlobalAlloc = __bt_LoadFileFromResources( FileName, TypePictureResource ); else hGlobalAlloc = __bt_LoadFileFromDisk( FileName ); if( hGlobalAlloc == NULL ) return NULL; iStream = NULL; if( CreateStreamOnHGlobal( hGlobalAlloc, FALSE, &iStream ) == S_OK ) { hBitmap = NULL; BkColor = 0xFF000000UL; GdipCreateBitmapFromStream( iStream, &pGpBitmap ); GdipCreateHBITMAPFromBitmap( pGpBitmap, &hBitmap, BkColor ); GdipDisposeImage( pGpBitmap ); iStream->lpVtbl->Release( iStream ); } GdiPlusShutdown( GdiPlusToken ); FreeLibrary( GdiPlusHandle ); GlobalFree( hGlobalAlloc ); return hBitmap; } //******************************************************************************************************************************** //* loadolepicture() ---> Return hBitmap (Load: BMP, GIF, JPG, TIF, WMF, PNG, ICO, CUR) //******************************************************************************************************************************** HBITMAP loadolepicture( char * filename, int width, int height, HWND handle, int scalestrech, int whitebackground, int transparent ) { IStream * iStream; IPicture * iPicture = NULL; HGLOBAL hGlobalAlloc = ( HGLOBAL ) NULL; RECT rect, rect2; HBITMAP hBitmap_New, hBitmap; BITMAP bm; LONG lWidth, lHeight; HDC hDC, memDC1, memDC2; UINT fuLoad = ( transparent == 0 ) ? LR_CREATEDIBSECTION : LR_CREATEDIBSECTION | LR_LOADMAP3DCOLORS | LR_LOADTRANSPARENT; if( width == 0 && height == 0 ) GetClientRect( handle, &rect ); else SetRect( &rect, 0, 0, width, height ); SetRect( &rect2, 0, 0, rect.right, rect.bottom ); hBitmap = ( HBITMAP ) LoadImage( GetModuleHandle( NULL ), filename, IMAGE_BITMAP, 0, 0, fuLoad ); if( hBitmap == NULL ) hBitmap = ( HBITMAP ) LoadImage( NULL, filename, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | fuLoad ); if( hBitmap == NULL ) { hBitmap = __bt_LoadGDIPlusPicture( filename, "PNG" ); if( hBitmap == NULL ) { hGlobalAlloc = __bt_LoadFileFromResources( filename, "GIF" ); if( hGlobalAlloc == NULL ) hGlobalAlloc = __bt_LoadFileFromResources( filename, "JPG" ); if( hGlobalAlloc == NULL ) hGlobalAlloc = __bt_LoadFileFromResources( filename, "WMF" ); if( hGlobalAlloc == NULL ) hGlobalAlloc = __bt_LoadFileFromResources( filename, "ICO" ); // To load an ICON as an IMAGE from the resourses define in the resources as ICO. // If set to ICON in the resourses can not be loaded as an image. if( hGlobalAlloc == NULL ) hGlobalAlloc = __bt_LoadFileFromResources( filename, "CUR" ); // To load an CURSOR as an IMAGE from the resourses define in the resources as CUR. // If set to CURSOR in the resourses can not be loaded as an image. if( hGlobalAlloc == NULL ) hGlobalAlloc = __bt_LoadFileFromDisk( filename ); if( hGlobalAlloc != NULL ) { CreateStreamOnHGlobal( hGlobalAlloc, TRUE, &iStream ); OleLoadPicture( iStream, 0, TRUE, &IID_IPicture, ( LPVOID * ) &iPicture ); if( iPicture != NULL ) { iPicture->lpVtbl->get_Width( iPicture, &lWidth ); iPicture->lpVtbl->get_Height( iPicture, &lHeight ); } } if( iPicture == NULL ) { if( hGlobalAlloc != NULL ) GlobalFree( hGlobalAlloc ); hBitmap = __bt_LoadGDIPlusPicture( filename, NULL ); } } } if( hBitmap == NULL && iPicture == NULL ) return NULL; hDC = GetDC( handle ); memDC2 = CreateCompatibleDC( hDC ); memDC1 = CreateCompatibleDC( hDC ); if( hBitmap != NULL ) { GetObject( hBitmap, sizeof( BITMAP ), &bm ); lWidth = bm.bmWidth; lHeight = bm.bmHeight; SelectObject( memDC1, hBitmap ); } 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; hBitmap_New = CreateCompatibleBitmap( hDC, width, height ); SelectObject( memDC2, hBitmap_New ); if( whitebackground == 1 ) FillRect( memDC2, &rect2, ( HBRUSH ) GetStockObject( WHITE_BRUSH ) ); else FillRect( memDC2, &rect2, ( HBRUSH ) GetSysColorBrush( COLOR_BTNFACE ) ); if( iPicture != NULL ) { iPicture->lpVtbl->Render( iPicture, memDC2, rect.left, rect.top, rect.right, rect.bottom, 0, lHeight, lWidth, -lHeight, NULL ); iPicture->lpVtbl->Release( iPicture ); GlobalFree( hGlobalAlloc ); } else { SetStretchBltMode( memDC2, COLORONCOLOR ); StretchBlt( memDC2, rect.left, rect.top, rect.right, rect.bottom, memDC1, 0, 0, lWidth, lHeight, SRCCOPY ); DeleteObject( hBitmap ); } DeleteDC( memDC1 ); DeleteDC( memDC2 ); ReleaseDC( handle, hDC ); return hBitmap_New; } |