Julio 26, 2007

CopyFileEx. API Win32

Bueno, en un proyecto he tenido que copiar un fichero de un sitio a otro,
si bueno teniamos la funcion MyCopyFile() que teniamos implementada en
Fivewin de la siguiente manera:
Code:

DLL32 FUNCTION MYCOPYFILE( lpExistingFileName AS STRING, lpNewFileName AS STRING, bFailIfExists AS LONG) AS LONG;
PASCAL FROM "CopyFileA" LIB "kernel32.dll"


Dicha función, para copiar ficheros de 1 o 2 megas, funciona muy bien, porque
da tiempo a nuestra aplicación que no se vuelva con un '( No responde )'.

Si no lo crees, muy simple, intenta copiar un fichero de 100 Megas, y me cuentas Wink

Básicamente, es porque nosotros HEMOS PERDIDO TOTALMENTE el control sobre nuestra
aplicación, y no podemos recibir/enviar mensajes a Window en que punto estamos.

Esto tiene fácil solución, nos hacemos nuestra propia función CopyFile().
El mayor inconveniente es que tenemos que hacerla Wink, y eso, es un paso atrás.

¿ Como podemos hacerlo entonces ? Muy simple usando la función CopyFileEx(), disponible en el API win32.

Dicha función no funciona bajo los Windows 98 o similares, estáis advertidos, o eso dicen las malas lenguas.

Bien, sin más dilaciones vamos a realizar la implementación, y eso si,
aqui vamos a usar C, por cuestión de velocidad.

Nuestro prototipo
CopyFileEx( Fichero_Origen, Fichero_Destino, bCodeblock ) --> nResult
Fichero_Origen y Fichero_Destino no necesitan explicación.
bCodeblock , es un bloque de código que nos va a pasar ;
{ |nPorcentaje, nTotal, nTransferido | MyFunction( nPorcentaje, nTotal, nTransferido ) }

Un ejemplo de llamada;
Code:

if ( COPYFILEEX ( cFile_Path_MDB , cFile_Path_Repara+"\TPVMAL.MDB", {|x,y,z| pasa(x,y,z) } ) == 0 )
? "MAL"
endif


Ah!, Ahora puedes ver, que encima vamos a poder montar una progressbar ,
por ejemplo, para ir mostrando el % que va quedando, es el primer parámetro,
que simplemente resulta de ;
nPorcentaje = nTransferido * 100 / nTotal

Lo he pasado como parámetro al codeblock, porque de esta manera, ya lo tienes
calculado a nivel de C, no perdiendo más tiempo.

Lo importante es que puedes crear una funcion como;

Code:
STATIC s_lCancel := .F.

#define PROGRESS_CONTINUE 0
#define PROGRESS_CANCEL 1

STATIC FUNCTION PASA( nPorcentaje, nTotal, nTransferido )
static nPasa := 0

if nPasa > 10
SysRefresh()
nPasa := 0
endif
nPasa++
oProgress:SetPos( nPorcentaje )

return( if( s_lCancel, PROGRESS_CANCEL, PROGRESS_CONTINUE ) )


Uy! ¿ Pero que ven tus ojitos!! ? Si , PUEDES CANCELAR también lo que
estas copiando, Wink , muy útil si quieres cancelar un archivo de 500 Megas,
por ejemplo, créeme.

En este caso, por ejemplo, puedes poner un botón similar a esto;
REDEFINE BUTTON oBtn ACTION ( s_lCancel := .T. ) ID 110 OF oWnd

El cambiar el estado de la variable static s_lCancel, simplemente hará
que cuando el codeblock se vuelva a ejecutar, lo cancelará.

Ahora bien, todo esto no es posible sin el codigo fuente de C, asi
que dejo paso al codigo fuente;
Code:

#pragma BEGINDUMP
#include
#include
#include "hbapi.h"
#include "item.api"
#include "hbapiitm.h"
#include "hbvm.h"
#include "hbapiitm.h"

/*
Convertimos un valor LARGE_INTEGER a double
*/
double clarge2int( DWORD Lo, DWORD Hi )
{
double dblLo, dblHi;
double ret;

if( Lo < 0 ){
dblLo = 2 ^ 32 + Lo ;
} else {
dblLo = Lo;
}

if( Hi < 0 ) {
dblHi = 2 ^ 32 + Hi;
} else {
dblHi = Hi;
}

ret = ( dblLo + dblHi);

return( ret );
}

DWORD CALLBACK CopyProgressRoutine(
LARGE_INTEGER TotalFileSize,
LARGE_INTEGER TotalBytesTransferred,
LARGE_INTEGER StreamSize,
LARGE_INTEGER StreamBytesTransferred,
DWORD dwStreamNumber,
DWORD dwCallbackReason,
HANDLE hSourceFile,
HANDLE hDestinationFile,
LPVOID pCallback_Progress
)
{
double TotalSize = clarge2int( TotalFileSize.u.LowPart, TotalFileSize.u.HighPart );
double TotalBytesTrans = clarge2int( TotalBytesTransferred.u.LowPart, TotalBytesTransferred.u.HighPart );
double percent = TotalBytesTrans * 100 / TotalSize ;

if( pCallback_Progress ) {
hb_vmPushSymbol( &hb_symEval );
hb_vmPush( pCallback_Progress );
hb_vmPushDouble( percent,1 );
hb_vmPushDouble( TotalSize,1 );
hb_vmPushDouble( TotalBytesTrans,1 );
hb_vmSend( 3 );
return( hb_parni( -1 ) );
}

return PROGRESS_CONTINUE;
}


HB_FUNC( COPYFILEEX )
{
LPCTSTR lpExistingFileName = hb_parc( 1 );
LPCTSTR lpNewFileName = hb_parc( 2 );
LPPROGRESS_ROUTINE lpProgressRoutine = ( void * )CopyProgressRoutine ;
LPBOOL pbCancel = NULL;
DWORD dwCopyFlags;
BOOL ret;
PHB_ITEM pCallback_Progress;

if( ! ISNIL( 3 ) ) {
pCallback_Progress = hb_itemNew( hb_param( 3, HB_IT_ANY ) );
}

ret = CopyFileEx( lpExistingFileName, lpNewFileName, lpProgressRoutine, pCallback_Progress, pbCancel, NULL );
hb_retni( ret );
hb_itemRelease( (PHB_ITEM) pCallback_Progress );

}

#pragma ENDDUMP

Lo que más me a costado no a sido la implementación de la funcion en si
misma, si no, convertir un LARGE_INTEGER en un valor double.

No es una función portable del API de Windows para Harbour, es una adaptación
a una necesidad en concreto, si lo queréis hacer compatible con el API de
Windows, ahí tenéis un punto de partida, por mi parte no pienso mejorarla
más, simplemente necesitaba esa funcionalidad y el APi de Window me la proporciona.

Escrito por Rafa Carmona a las Julio 26, 2007 12:15 AM | TrackBack
Comentarios

Gracias por la info pero la verdad no creo que me sirva de mucho. Pero ya que estoy comento algo.

Escrito por Caren a las Julio 26, 2007 01:39 PM

强烈推荐:最好的翻译公司在上海,提供日语翻译英语翻译韩语翻译等多语种的语言翻译服务。上海翻译公司在行业翻译领域如经济翻译法律翻译等颇有建树,公司还具体提供澳大利亚移民的证件翻译服务。

Escrito por kimi a las Octubre 17, 2007 10:20 AM

网络营销软件
网络营销软件
网络营销软件
群发软件
群发软件
---
群发软件
博客群建软件
网络营销软件
论坛群发软件
网站排名软件
群发软件
推广小助手破解版
论坛群发
网站排名软件
群发软件
推荐给你很好的群发软件信息群发软件和供求群发软件
推荐给你很好的群发软件信息群发软件和供求群发软件博客群发软件网络营销软件网络营销软件
网站排名软件网站排名软件网站优化软件信息群发软件信息群发软件信息群发软件论坛群发软件网站推广软件网站推广软件博客群发软件博客群发软件
群发软件
网络营销软件
论坛群发
网站推广软件
群发软件群发软件博客群发软件论坛群发软件网络营销软件论坛群发软件
信息群发软件推广软件网站推广软件网络营销软件网站推广软件群发软件网站排名软件网站推广软件博客群发软件论坛群发软件群发软件网站排名软件网站推广软件博客群发软件论坛群发软件
网站排名软件
群发软件
博客群发软件
网站排名软件
网站推广软件
群发软件信息群发软件
免费论坛群发软件
论坛群发软件
网站排名软件
免费博客群发软件
网站推广软件

群发软件
博客群发软件
网站排名软件
网站推广软件
群发软件信息群发软件
免费论坛群发软件
论坛群发软件
网站排名软件
免费博客群发软件
博客群发软件
信息群发软件
论坛群发软件
信息群发软件
博客群发软件
qq群发软件
邮件群发软件
博客群建软件
企业名录搜索软件
信息群发软件
邮件群发软件
论坛群发软件
博客群发软件
网站推广软件
网络营销软件
全能营销破解版
网络营销软件
论坛群发软件
论坛群发软件
论坛群发软件
网络营销软件
信息群发软件
信息群发软件
信息群发软件
群发软件
论坛群发软件

Escrito por 群发软件 a las Febrero 10, 2008 01:25 PM

上海华苑电子有限公司成立于1994年,是国内较早从事卡片生产、销售的[url=http://www.cardhy.com]上海制卡[/url]公司,产品主要包括有[url=http://www.cardhy.com]智能卡[/url],RFID电子标签[url=http://www.cardhy.com/show_products]考勤卡[/url],[url=http://www.cardhy.com/show_products]读卡器[/url],[url=http://www.cardhy.com/products]积分卡[/url],[url=http://www.cardhy.com/products]会员卡[/url], [url=http://www.cardhy.com]射频卡[/url],印刷卡,[url=http://www.cardhy.com]贵宾卡[/url]等产品,欢迎浏览公司网站 [url=http://www.cardhy.com]www.cardhy.com[/url]。

Escrito por stvqin a las Abril 2, 2008 03:12 PM

上海华苑电子有限公司成立于1994年,是国内较早从事卡片生产、销售的上海制卡公司,产品主要包括有智能卡,RFID电子标签考勤卡,读卡器,积分卡,会员卡, 射频卡,印刷卡,贵宾卡等产品,欢迎浏览公司网站 www.cardhy.com

Escrito por steve a las Abril 2, 2008 03:17 PM

谁能为我推荐一家可以做搜索引擎优化网站优化网络营销公司?急!谢谢!
图书翻译公司

Escrito por maggie a las Abril 3, 2008 11:45 AM

开化龙顶
自攻螺丝
塑料模具
木门
木门
波纹管

Escrito por gg a las Abril 10, 2008 06:11 AM

中国知名的租赁服务供应商,可提供电脑租赁、办公设备租赁、会议设备租赁、舞台设备租赁、金融租赁融资租赁人才租赁通讯设备租赁、健身器材租赁、乐器租赁、宴会用品租赁等。名宏中国租赁城提供租赁业全面解决综合的解决方案。租赁服务热线02165151202
我们这里为你提供你寻找的BB霜,隔离霜,眼影,唇彩,对繁忙而追求美丽的女性朋友迅速改善皮肤问题,我们这里代理韩国化妆品BB霜,隔离霜,眼影,唇彩等等。
上海嘉迪国际货运公司是经中国民航总局批准,工商局核准的企业,航空公司一级代理商,本上海空运公司主要承办空运进出口货物的国际运输代理业务。还有报关,清关,转关,报验业务,竭诚为广大客户献上最真诚的服务。服务热线13585896404
本空运公司服务理念:订舱前拼的是价格,订舱后凭的是服务
本公司优势:空运价格低,空运服务好

Escrito por zulin a las Abril 20, 2008 09:13 PM
Escribir un comentario









¿Recordar informacion personal?