Вы находитесь на странице: 1из 12

PowerBuilder Tip #10: ¿Cómo Mostrar Imágenes

TIFF en PowerBuilder?

En la actualidad, PowerBuilder no ofrece soporte nativo a imágenes en formato TIFF. Hay dos
soluciones para visualizar imágenes TIFF en PowerBuilder:

1. Usar un OCX para ver la imagen TIFF (por ejemplo, Kodak Image Edit Control)

2. Convertir primero la imagen TIFF a un Bitmap (u otro formato soportado por PowerBuilder)
usando una herramienta de terceros.

Para usar el Kodak Image Edit Control:

1. En PowerBuilder, ir a Insert -> Control -> OLE...


2. En la pestaña Insert Control, seleccione Kodak Image Edit Control y de click en OK.
3. En su ventana, haga click en la ubicación en donde desea crear este control.
4. Para ver las propiedades y funciones disponibles, haga click en el Browser Painter (Tools
-> Browser); vaya a la pestaña OLE y expanda OLE Custom Controls; por último
ubique el control.

Si el control Kodak Image Edit Control no aparece en la lista del paso 2, usted debe ubicar
manualmente el archivo OCX (por ejemplo,C:\Windows\System32\imgedit.ocx) y registrarlo
manualmente antes de poder crear el objeto, usando la opción 'Register New...' que aparece en
la pestaña'Insert Control' del paso 2.

La siguiente porción de código (que se puede usar en el evento 'clicked' de un botón) permite abrir
una imagen TIFF y mostrarla en la ventana (ole_1 es el nombre del objeto):

string ls_title, ls_fullpathname, ls_filename, ls_extension,


ls_filter
int li_rc

ls_title = "Select a .TIF file"


ls_extension = "TIF"
ls_filter = "TIF Files (*.TIF),*.TIF"

li_rc = GetFileOpenName ( ls_title, ls_fullpathname, ls_filename,


ls_extension, ls_filter)

ole_1.object.ClearDisplay()
ole_1.object.Image = ls_filename
ole_1.object.Display()

Finalmente, estas dos líneas de código le permiten ver las dimenciones de la imagen:
MessageBox("Alto:", string(ole_1.object.ImageHeight))
MessageBox("Ancho:", string(ole_1.object.ImageWidth))

Trabajar con imágenes en los reportes


Como accedo a un control picture que se encuentra en la sección del reporte header; para
poder cambiar la imagen.

O sea tengo una ventana con un botón reporte, que al hacer click sobre este abre una nueva
ventana en la que se encuentra el datawindows con el reporte. Pero no se como puedo
acceder al control picture en tiempo de ejecución. Para poder poner la imagen que yo quiera
en tiempo de ejecución.

Yo se que con la siguiente sentencia cambio una imagen p_1.picturename, pero no se como
referenciar al control que se encuentra en la otra ventena en el evento clicked del botón
reporte.

Experto

Todos los controles integrados en el datawindow object incluyendo las propiedades de este,
pueden ser modificadas de 2 maneras,

1 - por medio de la función MODIFY()

2 - por medio de invocación directa.

Por ejemplo:

Para modificar la imagen que se encuentra dentro de un objecto picture el código es el


siguiente

Invocación directa:

<datawindow control>.Object.<picture object>.Filename = "<fichero imagen>"

invocacion por funcion

<datawindow control>.Modify("<picture control>.Filename='fichero imagen'")


En cualquiera de los 2 casos funciona bien

La forma de modificar las propiedades de los objetos incluidos en un datawindow es por medio
del prefijo object.

Cambiar un ancho

<datawindow>.object.<control>.width = <valor>

Una explicación más profunda de cada uno de las posibilidades de cambio por objeto, la
puedes encontrar en la ayuda online de pb. busca DESCRIBE

encontraras varias lineas con relación

Selecciona

Describe DataWindow expression function

Y luego has click en "Controls in a DataWindow and their properties".

En la siguiente pantalla obtendrás la información por cada uno de los objetos, con los 2
métodos de modificación

Notas:

La función para cambiar los valores es MODIFY()

Y para retraer los valores actuales DESCRIBE()

Con esta ultima la forma de retraer los valores, puedes conocer la manera de asignarle
valores a la propiedad pues lo único que hacer falte es el signo de igual y su valor.
Hola con todos, podrian ayudarme porfavor con este pequeño programilla:

1. Creamos una tabla llamada 'alumnos_fotos' con 2 campos: 'cod_alumno' de tipo char(2) y
foto_alumno de tipo image(16),
al campo cod_alumno lo ponemos como Clave Principal.
a esta tabla le agregamos 3 registros con los codigos: '01', '02', y '03'

2. Creamos una Window con los siguientes objetos:


un Picture Control, llamado 'p_foto'
dos Command Button, llamados 'cb_cargar_foto' y 'cb_ver_foto' y
un Single Line Edit, llamado 'sle_cod_alumno'

3. En el evento clicked de 'cb_cargar_foto' poner el siguiente codigo:

STRING ls_pathname, ls_filename, ls_filtro, ls_cod_alumno


LONG ll_File
BLOB lbl_data, lbl_temp

ls_filtro = "JPEG Files (*.jpg),*.jpg," + "GIFF Files (*.gif),*.gif,"


IF GetFileOpenName ( "Archivo de Imagen: ", ls_pathname, ls_filename , "jpg", ls_filtro) = 0 THEN
RETURN

p_foto.picturename = ls_pathname
ls_cod_alumno = trim(sle_cod_alumno.text)

ll_File = FileOpen(ls_pathname, StreamMode!)


DO WHILE FileRead(ll_file,lbl_temp) > 0
lbl_data += lbl_temp
LOOP
FileClose(ll_file)

IF ll_File <> -1 THEN


FileRead(ll_file, lbl_data)
FileClose(ll_file)
SQLCA.AutoCommit = True
UPDATEBLOB alumnos_fotos SET foto_alumno = :lbl_data WHERE cod_alumno = :ls_cod_alumno;
SQLCA.AutoCommit = False
ELSE
messagebox('Error','Falló el FileOpen')
END IF

IF SQLCA.SQLNRows > 0 THEN


COMMIT;
messagebox('OK: ' + ls_cod_alumno,'Se guardó la foto del alumno')
ELSE
messagebox('Error','Falló el UPDATEBLOB')
END IF
FileClose(ll_file)

4. En el evento clicked de cb_ver_foto, copiar el codigo:

Blob lb_imagen
STRING ls_cod_alumno
ls_cod_alumno = trim(sle_cod_alumno.text)

SELECTBLOB foto_alumno INTO :lb_imagen FROM alumnos_fotos WHERE cod_alumno =


:ls_cod_alumno ;

p_foto.SetPicture(lb_imagen)

5. Ejecutar y probar:
escribimos el codigo '01' en sle_cod_alumno, le damos click en cb_cargar_foto y seleccionamos el
archivo que
se va a guardar en la DB. Repetimos este paso para los demas codigos '02' y '03'. Luego, probamos
el boton cb_ver_foto, para cada codigo.

al ejecutar y seleccionar la foto me muestra este error: " fallo el updateblob", me podrían ayudar
a mi parecer todo esta bien no m explico porque no graba, Gracias

compañero, que flojera leer todo lo que pusiste, te dire lo que yo hago ok,, espero y te sirva...

//CON ESTO AGREGAS LA FOTO DESDE UN DIRECTORIO


integer li_regresa

li_regresa = GetFileOpenName ( "Busque y seleccione la foto de la Turbina", is_path, ls_name ,


"bmp" ,"Fotos Turbinas (*.bpm),*.bmp" ,"W:\Catalogo\GM IMAGENES" )
If li_regresa = 1 Then
this.PictureName = is_path // IS_PATH lo guardas en la tabla en un campo string
End if

despues en una variable string sacas el valor del campo imagen ( el campo donde metiste la
direccion de is_path) yo la guarde en is_image

y haces esto p_1.picturename = is_image

si te fijas utilise un picture control ... suerte...

nota .. las imagenes estaran guardadas en una carpeta de c:

Describe & Modify Functions


To read and change the attributes of a DataWindow object, we
call describe() andmodify() function. Describe() returns the value of
the specified attribute. For example, the following statement returns
whether the DataWindow is in the query mode or not.

String ls_QueryModeCheck
ls_QueryModeCheck = &
dw_product.Describe( "datawindow.querymode" )
The first value in the argument is the object name and the second one is
the attribute name. There are few attributes that are applicable for
whole DataWindow object. For example, querymode, printpreview. In
that case, the first argument is literally "DataWindow". Say, you want to
find whether the font for the "product_description" field is italic or not,
then we need to replace "DataWindow" with the column name,
"product_description" in the above code.

String ls_FontItalicCheck
ls_FontItalicCheck = dw_product.Describe( &
"product_description.font.italic" )

While dealing with the column, you can specify the column number
instead of column name. For example, in the "dw_product" DataWindow
control, the second column is "product_description", the function call
would be:

String ls_FontItalicCheck
ls_FontItalicCheck = &
dw_product.Describe( "#2.font.italic" )

When you use the column number, you need to prefix the column
number with pound sign as shown in the above example. The return
value of Describe() is always a string datatype. So, when you are
expecting a numeric or other datatype, you need to convert it into the
desired datatype.

The correctness of the argument is not checked at compile time. If there


is anything wrong with the argument, Describe returns "!".

We use Modify() function to change the value of an attribute. The


following code sets the DataWindow in the query mode:

dw_product.Modify( "DataWindow.QueryMode=yes" )

The following code changes the product_balance field:

dw_product.Modify("product_balance.Format='[red] &
$#,###,##0.00'")

The following code sets the retrieval argument of a nested report.

ls_Arg = ".Nest_Arguments=((~"" + &string( lEmpIdToPrint ) + "~"))"


dw_print.Modify( "r_emp_details" + lStrArg )
dw_print.Modify( "r_emp_vacations" + lStrArg )
dw_print.Modify( "r_emp_wages" + lStrArg )
dw_print.Modify( "r_emp_docs" + lStrArg )

The above example is taken from the Payroll project. In the employee
data entry window we have four DataWindows. Since we can't print all
those four DataWindows together as we see on the window, we are
using a composite DataWindow which has four DataWindows. Each of
the DataWindow has a retrieval argument of the employee id.

The retrieval argument of a nested DataWindow can't be specified with a


normalRetrieve() function. So, we need to use Modify() function to
set the retrieval argument of each of the nested DataWindow. To do
this, we need to specify the nested DataWindow object name and
".Nest_Arguments" property and the value. We are use tilde sign "~"
to use special characters in the quotations. For example, if you want to
use a tab character, you need to use "~t". Similarly to represent a
double quotation in a double quotation, you need to use "~"" tilde
before the quotation.

You are not limited to using a constant value in the Modify() function.
You can assign a value through an expression that PowerBuilder
evaluates during execution, instead of having to directly assign a value.
The following is the syntax:

' DefaultValue ~t DataWindowExpression '

DefaultValueThe value to assign the property if DataWindowExpression


doesn't return a valid value. Please note that, you should separate the
default value and DataWindow expression with a tab character.

dw_product.Modify( "product_balance.Color = '0 ~t &


if( " product_balance < product_reorder_level,255,0)'")

The above statement changes the color of product_balance to red if the


balance is less than the reorder level, otherwise, the color is set to
black.

dw_wages.Modify( "effective_date.TabSequence=0" )

In the above example, we are setting the tab sequence of effective_date


column to zero. That means user can't edit that field. That's fine. But, If
you want to allow the user to edit the field in the new records, but want
to protect in the existing records, the above statement won't work. We
need to use an expression.

dw_wages.Modify("gross_wages.Protect='1~tIf( &IsRowNew(),0,1)'")

When you set the tab sequence of a field, it applies to the field in all
records. Instead, if you use protect attribute, you can apply at a record
level. In the above example, we are protecting the field if it's not a new
record. The above two examples would be useful for you in the
upcoming project "Payroll Project", which you need to code from
beginning.

dw_product.Modify( "product_balance.Color = '0 ~t " + &"if(product_balance <


product_reorder_level,255,0)'" + &
"product_balance.Font.Weight = '400 ~t " + &
"if(product_balance < product_reorder_level, &
700,400)'" + & "product_balance.Alignment = '1 ~t" + &
"if(product_balance < product_reorder_level,0,1)'")

You are not limited to one expression per Modify() function. You can
use multiple expressions separated by a single space between each
expression. In the above statement we are setting the product_balance
to red color with bold font and left aligned. We have used three
expressions separated by a single space.

Datawindow after Multiple expressions Modify() function.

You can also use CREATE statement to add objects to the DataWindow
at run-time. The following example is taken from the help, which adds
an ellipse to the DataWindow.

dw_1.Modify( "CREATE ellipse(band=detail x='1229' " + &


" y='0' height='112' width='739' brush.hatch='6' " + &
" name=oval2 "brush.color='65535' pen.style='0' " + &
" pen.width='10' pen.color='0' background.mode='1' " )
You can also destory the elements from the DataWindow using
DESTORY statement.

dw_1.Modify("DESTROY oval2")

Destroying a column by name does not remove the column data from
the buffer. It just removes the column from the display.

dw_1.Modify("DESTROY emp_id")

If you want to remove the column's data also from the buffer, include
the keyword COLUMN.

dw_1.Modify("DESTROY COLUMN emp_id")

Modify
Respuesta de
agdsys
a
marcediaz
06/10/2003
Usuario
Hola Agdsys!
Mira, creo que estoy cayendo con lo que me escribiste. Hice todo dentro de un solo DW.
Estuve probando, me salen todavía algunos errores, pero me distraje con otra parte del
programa. Como ya conoces más o menos del tema(ojala te acuerdes el tema de campos,
parcelas y árboles), te sigo contando. Tengo dos tablas muy importantes: Árbol y
Mediciones.
La tabla árbol :Id_campo, Parcela, Id_arbol, distanciamiento, especie etc .
Donde: Id_campo+ Parcela+ Id_arbol forman una clave compuesta que me va a identificar
unívocamente a cada arbol. Debe ser compuesta pues los nombres de parcelas pueden
repetirse en cada campo, y los arboles van de 1 a 25 en cada parcela.

La tabla Mediciones: Id_campo, Parcela, Id_arbol, Anio_medicion, diámetro, alt_fuste etc.


Donde: : Id_campo+ Parcela+ Id_arbol+Anio_medicion forman clave compuesta. Así las
identifico pues cada año se toman mediciones de lo árboles muestreados.

Ahora bien: Cuando se miden arboles por primera vez, en ese momento se incorporan nuevos
árboles a la base de datos. Esto quiere decir que debo hacer la actualización de dos tablas a
la vez, o sea de la tabla Árbol y de la tabla Mediciones. Me encuentro entonces con el
problema de actualizar dos tablas en un DW. Así que he buscado en la ayuda la sintaxis de
Modify, siguiendo un ejemplo que esta allí.
Al crear el DW puse a árbol como updatable. Escribí el código que creo correspondiente, hice
unas pruebas y me salio este error:
SQLSTATE = S0022
[Microsoft][Controlador ODBC Microsoft Access] La instrucción INSERT INTO contiene el
siguiente nombre de campo desconocido: 'distanciamiento'. Asegúrese de que ha escrito
correctamente el nombre y vuelva a intentar la operación.
Distanciameiento es de la tabla Árbol! ¿Qué paso? Te resumo un poco el código, solo quito
algunos campos para que no sea tan extenso:
integer rc
string err
//actualiza arbol
rc=dw_1.update(true, false)
If rc= 1 then
//deshabilita actualizacion de las columnas de arbol
dw_1.Modify("arbol_id_campo.update =no")
dw_1.Modify("arbol_parcela.update=no")
dw_1.Modify("arbol_id_arbol.update=no")

dw_1.Modify("arbol_id_campo.key =no")
dw_1.Modify("arbol_parcela.key=no")
dw_1.Modify("arbol_id_arbol.key=no")

dw_1.Modify("arbol_distanciamiento=no") // y asi con mas campos de arbol

//Hace updatable mediciones


dw_1.Modify("Datawindow.Table.UpdateTable=~"mediciones~"")

//Habilita la actualizacon de las columnas deseadas de mediciones


dw_1.Modify("mediciones_id_campo.UPDATE=yes")
dw_1.Modify("mediciones_parcela.UPDATE=yes")
dw_1.Modify("mediciones_id_arbol.UPDATE=yes")
dw_1.Modify("mediciones_anio.UPDATE=yes")

dw_1.Modify("mediciones_id_campo.key=yes")
dw_1.Modify("mediciones_parcela.key=yes")
dw_1.Modify("mediciones_id_arbol.key=yes")
dw_1.Modify("mediciones_anio.key=yes")

dw_1.Modify("mediciones_id_empleado.update=yes")// y asi con mas campos de mediciones

//Actualiza la tabla mediciones


rc=dw_1.update()
If rc=1 then
commit using sqlca;
Messagebox("Estado", +"Grabación correcta")
else
rollback using sqlca;
Messagebox("Estado", +"Falla en la actualización de la tala mediciones.")
end if
else
rollback using sqlca;
Messagebox("Estado", +"Falla en actualización de la tabla arbol.")
end if

Вам также может понравиться