On-line: i3t4j6, гостей 1. Всего: 2 [подробнее..]
АвторСообщение
moderator




Пост N: 458
Зарегистрирован: 11.02.10
ссылка на сообщение  Отправлено: 29.03.13 11:07. Заголовок: Требуется помощь при освобождении ресурсов GdiPlus


Вниманию Петра, Павла и всех, кто работал с библиотекой GdiPlus

Я переписал модуль c_image.c для поддержки вывода PNG, TIF и ICO в элементе управления Image, основываясь на адаптации GdiPlus, выполненной Клаудио Сото для официального релиза HMG 3.1.1

Все заявленное работает, но при этом происходит утечка Bitmap-ресурсов при каждом изменении картинки в программе.

Для освобождения Bitmap-ресурсов я использовал GdiPlus-функцию GdipDisposeImage(), но это не помогло

Поэтому требуется помощь знатоков

Загрузить модуль c_image.c для проверки можно отсюда

Спасибо: 0 
ПрофильЦитата Ответить
Ответов - 5 [только новые]


постоянный участник




Пост N: 2774
Зарегистрирован: 12.09.06
ссылка на сообщение  Отправлено: 03.04.13 22:03. Заголовок: gfilatov2002 пишет: ..


gfilatov2002 пишет:

 цитата:
Вниманию Петра, Павла и всех, кто работал с библиотекой GdiPlus



Народ ! Помогите пожалуйста Григорию !!!
Уж очень хочется нормальных картинок в МиниГуи...

Спасибо: 0 
ПрофильЦитата Ответить





Пост N: 177
Зарегистрирован: 16.12.08
ссылка на сообщение  Отправлено: 04.04.13 14:27. Заголовок: Григорий, выставите ..


Григорий, выставите ещё раз исходник и если есть тестовый пример.
Спасибо.

Спасибо: 0 
ПрофильЦитата Ответить
moderator




Пост N: 459
Зарегистрирован: 11.02.10
ссылка на сообщение  Отправлено: 04.04.13 16:02. Заголовок: santy пишет: выстав..


santy пишет:

 цитата:
выставите ещё раз исходник и если есть тестовый пример


Загрузить модуль c_image.c для проверки можно отсюда
Простой пример ниже показывает утечку ресурсов при обновлении PNG картинки в цикле
Скрытый текст

Я уже написал об этой проблеме автору этой модификации и он подтвердил наличие этой проблемы для PNG-файлов

Спасибо: 0 
ПрофильЦитата Ответить





Пост N: 178
Зарегистрирован: 16.12.08
ссылка на сообщение  Отправлено: 04.04.13 16:41. Заголовок: ошибка при скачивани..


ошибка при скачивании : Ошибка 404. Документ не найден.

Спасибо: 0 
ПрофильЦитата Ответить
moderator




Пост N: 460
Зарегистрирован: 11.02.10
ссылка на сообщение  Отправлено: 04.04.13 17:11. Заголовок: santy пишет: ошибка..


santy пишет:

 цитата:
ошибка при скачивании


Поскольку файл c_image.c небольшой по размеру, выложил его здесь

 цитата:
/*---------------------------------------------------------------------------- 
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;
}



Спасибо: 0 
ПрофильЦитата Ответить
Ответ:
1 2 3 4 5 6 7 8 9
большой шрифт малый шрифт надстрочный подстрочный заголовок большой заголовок видео с youtube.com картинка из интернета картинка с компьютера ссылка файл с компьютера русская клавиатура транслитератор  цитата  кавычки моноширинный шрифт моноширинный шрифт горизонтальная линия отступ точка LI бегущая строка оффтопик свернутый текст

показывать это сообщение только модераторам
не делать ссылки активными
Имя, пароль:      зарегистрироваться    
Тему читают:
- участник сейчас на форуме
- участник вне форума
Все даты в формате GMT  3 час. Хитов сегодня: 127
Права: смайлы да, картинки да, шрифты да, голосования нет
аватары да, автозамена ссылок вкл, премодерация откл, правка нет