Código C++:
Ver originalIPictureDisp** ExportPicture(ItemSetConstants ItemSet, short IncludeBackColor, short IncludeBackPick);
Si ExportPicture devuelve un IPictureDisp**, es decir, un puntero doble, no puedes coger ese valor de retorno y convertirlo por arte de magia en un puntero simple:
Código C++:
Ver originalpIPD->operator =((IPictureDisp*)AddFlow1->ExportPicture((afSelectedItems, true, true));
De hecho, si quitas ese cast "(IPictureDisp*)" que tienes, verás que el código da error... y es por algo.
Si
ExportPicture devuelve un puntero doble puede ser porque este método puede devolver una lista de elementos... si tu únicamente necesitas uno, puedes optar por coger el primero:
Código C++:
Ver originalpIPD->operator = *(AddFlow1->ExportPicture(afSelectedItems, true, true);
Lo que pasa es que así estás perdiendo la referencia al puntero doble y, en consecuencia, vas a crear lagunas de memoria.
Lo suyo sería que almacenases en algún sitio el puntero doble y después hicieses la asignación:
Código C++:
Ver originalIPictureDisp** lista = AddFlow1->ExportPicture(afSelectedItems, true, true);
pIPD->operator = *lista /* o lista[ 0 ] */;
En otro orden de cosas:
Código C++:
Ver originaltry
{
pic = new TPicture; //Solicito memoria para el TPicture
__try
{
try
{
// ...
}
catch(...)
{
// ...
}
}
__finally
{
}
}
catch(...)
{
// ...
}
Esta estructura de try-catch es un poco compleja:
El primer try-catch se supone que está para controlar el "new"... en ese caso, capturar todas las excepciones que se produzcan y mostrar siempre el mismo mensaje de error no parece una buena idea. Hay dos opciones:
* Encerrar únicamente el new dentro del try-catch y capturar la excepción concreta:
Código C++:
Ver originaltry
{
pic = new TPicture;
}
catch ( std::bad_alloc& )
{
ShowMessage("No hay memoria suficiente.");
}
Eso sí, ten en cuenta que si no tienes memoria para crear un TPicture, posiblemente tampoco tengas memoria para mostrar el mensaje de error.
Un truco para esto suele ser reservar 1k de memoria (por ejemplo). La idea es liberarlo justo antes de mostrar el mensaje de error para que el sistema encuentre memoria libre. Pero vamos, es un caso crítico que no se suele dar y que si se da vas a perder información fijo.
* Forzar a que el new no pueda dar una excepción
Código C++:
Ver originalpic = new (std::nothrow) TPicture;
if ( pic == 0 )
{
// No se ha podido reservar la memoria
// o se ha producido un fallo en la creación del objeto
}
Este método tiene como ventaja que no provoca excepciones, la desventaja es que si se produce un fallo durante la creación del objeto no lo puedes detectar.
Más cosillas. El bloque _try-__finally: este bloque no tiene sentido básicamente porque dentro tiene otro bloque que ya se encarga de capturar todas las excepciones... y dado que el catch de este segundo bloque no lanza excepciones nuevas, SIEMPRE se va a ejecutar lo que hay en __finally... exista el __try-__finally o no.
Si te quieres quedar más tranquilo, puedes encapsular el objeto en un smart pointer (std::auto_ptr en C++, std::unique_ptr en C++11 o boost::unique_ptr si prefieres usar la librería boost). La ventaja de los smart pointers es que se encargan de liberar la memoria del objeto, por lo que puedes despreocuparte de la liberación de memoria... eso sí, hay que usarlos con cierto criterio:
Código C++:
Ver originalstd::unique_ptr< TPicture > smart_pic{ new TPicture };
try
{
SetOlePicture(smart_pic.get( ), *pIPD); //Paso la imagen del IPictureDisp al TPicture
//Envio la imagen al portapapeles
smart_pic->SaveToClipboardFormat(MyFormat,DataHandle,APalette);
Clipboard()->SetAsHandle(MyFormat,DataHandle);
}catch(...){
ShowMessage("Fallo al copiar la imagen al portapapeles.");
}
Claro que, ya puestos, lo más sencillo sería crear el TPicture en el stack y dejarnos de memoria dinámica que tampoco es necesario:
Código C++:
Ver originalTPicture stack_pic;
try
{
SetOlePicture(&stack_pic, *pIPD); //Paso la imagen del IPictureDisp al TPicture
//Envio la imagen al portapapeles
stack_pic.SaveToClipboardFormat(MyFormat,DataHandle,APalette);
Clipboard()->SetAsHandle(MyFormat,DataHandle);
}catch(...){
ShowMessage("Fallo al copiar la imagen al portapapeles.");
}
Y para rematar... el último try-catch también captura una excepción genérica... no es buena idea este tipo de prácticas porque a tí tampoco te va a permitr identificar el error que se ha producido... dentro de un catch(...) no tienes información sobre la excepción que se ha producido.
Además, tu piensa que al usuario final le tienes que hacer llegar una versión ya depurada, por lo que no debería producirse bajo ningúna circunstancia y salvo casos altamente excepcionales una excepción genérica.
Un saludo.