Boletín Pascal #16
Los ejemplos completos de código fuente de este número están disponibles para descargar.
![]() |
![]() |
Boletín Pascal #16 - 09-FEB-2001 INDICE 1. UNAS PALABRAS DEL EDITOR 2. FORMAS NO RECTANGULARES - Parte II - INTRODUCCION - IMPLANTACION BASICA DE "SKINS" - EL FONDO - LA FORMA - PASO A PASO - LOS CONTROLES - MAS ALLA - LO QUE OTROS HACEN 3. FORMAS GRISES CASI INDISTINGUIBLES EN ELEMENTOS DE MENU INHABILITADOS 4. COLOR BUTTON 5. TALLER 6. LICENCIA DE KYLIX 7. ENLACES ________________________________________________________________________ 1. UNAS PALABRAS DEL EDITOR En este número me complace presentar la tan esperada segunda parte del artículo FORMAS NO RECTANGULARES de Alirio Gavidia, cuya primera parte fuera publicada en el boletín #13: http://www.latiumsoftware.com/es/pascal/0013.php Aprovecho para recordar a los suscriptores que el sorteo de la Librería JfControls sigue en marcha. Si no lo han hecho aún, observen la demo y verán que no es ninguna baratija lo que se sortea, sino un producto de alta calidad que implementa un concepto innovador y que les ayudará a hacer aplicaciones visualmente atrayentes en un santiamén, además que está desarrollado por gente de habla hispana que merece nuestro apoyo. Participar es gratis. Todo lo que tienen que hacer es descargar e instalar la versión de evaluación de la librería (disponible tanto para Delphi como para C++ Builder, ambos en versiones 3, 4 y 5) para así obtener el Key Number (un número único que identifica cada instalación de la librería) con el que podrán llenar el formulario de inscripción. Si no quieren instalar la versión de evaluación de la librería, la última versión de JfSetup le dará el Key Number si instala sólo la demo (vale la pena verla y no se requiere que la librería esté instalada para correr el ejecutable). Para más información sobre el sorteo: http://www.latiumsoftware.com/jfcontrols/index.php?lang=es A partir del próximo número, este boletín será publicado con los ejemplos de código fuente adjuntos o "attacheados" que por lo general tienen menos de 30K. Saludos, Ernesto De Spirito eds2004 @ latiumsoftware.com ________________________________________________________________________ JfControls Lib. Multilenguaje. Multiapariencia. Skins. Privilegios. Más de 40 componentes integrados y personalizables. Múltiples problemas de programación resueltos. Administración centralizada de recursos. Para Delphi 3-7 y C++ Builder 3-6. http://www.jfactivesoft.com/spindex.htm ________________________________________________________________________ 2. FORMAS NO RECTANGULARES - Parte II Copyright (c) 2001 Alirio Gavidia <alirio@gavidia.org> Para ver más de mis artículos visite: Programación Orientada en Delphi http://www.gavidia.org/pod/ INTRODUCCION ------------ Esta es la segunda parte de un artículo orientado a la utilización de formas no rectangulares con Delphi bajo Windows. En la parte anterior se le dio forma no rectangular a un formulario creando un reloj de agujas como ejemplo. En esta parte se pretende poder crear formularios cuyas formas se definan desde algún archivo externo a la aplicación. Tal comportamiento corresponde al muy difundido uso de "Skins". Como ejemplo "Windows Media Player". IMPLANTACION BASICA DE "SKINS" ------------------------------ La primera aproximación que aquí presentamos no sólo nos permite definir el fondo sino además la figura del formulario. En el mercado existe un componente VCL que hace este trabajo y más. El referido componente VCL hace uso de dos archivos BMP, el primero con la figura en blanco y negro y el segundo con el fondo a todo color. Para el presente ensayo se combinan estas dos características en un sólo archivo, simplemente tomando el color del primer pixel como color transparente, en realidad como color que permite definir el límite de la figura (hay una pequeña diferencia). El resto del dibujo, dentro de la figura, se toma como fondo del formulario. Nota: El uso de BMP tiene muchos contras. Los principales: tamaño y escalabilidad. Del primero quizás la alternativa sería un JPG, pero el proceso de compresión altera la frontera de la figura generando colores intermedios y la consecuencia es un frontera difuminada. Por otro lado están los GIF, pero han sido desterrados de mis rutinas, librerías y funciones debido a que cierta empresa pretende ahora cobrar derechos por el uso de los algoritmos de compresión presentes en los archivos tipo GIF. En cuanto a la escalabilidad, una alternativa es el uso de Metafile, mejor aún sospecho que los metafiles son definiciones de regiones completamente análogas a las que se utilizan aquí. Sin embargo dejaré el estudio de Metafiles para otra ocasión. Una versión completa de un "Skinner" requiere poder definir el dibujo de fondo del formulario, su figura así como el de cada control presente. Nos concentraremos en el formulario dejando de lado los controles. EL FONDO -------- En problema del dibujo de fondo es enfrentable de dos maneras a mi entender. Una es interceptando algún mensaje de Windows para dibujar sobre el canvas de fondo (como lo hacen algunos controles VCL para colocar fondos en formularios MDI y No-MDI) y la otra es colocando un control tipo TImage como el último control en el área cliente del formulario. Optaré por la última forma porque además será posible hacer uso de algunos eventos del TImage. LA FORMA -------- El problema de la figura reside básicamente en crear un región de determinada forma. La forma determinante que he asumido es dada a través de un bitmap. Así que por ejemplo un bitmap consistente en un círculo azul en un fondo blanco debe generarme un formulario visible como un círculo. La figura puede ser casi cualquier cosa como el rostro de Mickey Mouse o la silueta de una araña. Por ello se leerá el bitmap para generar a partir de él una forma poligonal, eso nos da libertad, pero elimina en mucho las posibilidades de escalamiento. PASO A PASO ----------- En principio el algoritmo va así: 1.- Se ajusta el formulario a las dimensiones del archivo BMP. Esto es simple. Para ello bastan las siguientes líneas de código: // Ajustar el área / to Ajust the area ClientWidth := Image1.Width; ClientHeight:= Image1.Height; 2.- Se lee el primer punto del formulario y se toma como "transparente". 3.- Se busca el primer punto no "transparente" y a partir de allí se genera un polígono con la silueta de la parte no "transparente" (ver GenRegion en el archivo ffigura.pas). 4.- Eliminamos la barra de título (si aún nos estorba). Para ello: BorderStyle := bsNone; // Titulo estorba / no Title 5.- Cambiamos la figura del formulario conforme al polígono. Para ello hacemos uso ahora de la rutina "CreatePolygonRgn" y "SetWindowRgn" (ver ActiveSkin en ffigura.pas). A diferencia del ejemplo de la primera parte de este artículo, ya no definimos una región elíptica (circular). 6.- Establecemos desde el TImage los eventos necesarios para el arrastre de formularios como se hizo en el ejemplo del primer artículo. Excepto por el tercer punto nada parece en extremo difícil. Para generar la región poligonal sólo se busca la frontera de la figura, luego se avanza por toda la orilla de la figura hasta estar en el punto inicial (o acabar con la memoria, en este caso 1024 puntos). Esta serie de puntos definen un polígono para generar un región con la función "CreatePolygonRgn". Luego se utiliza "SetWindowRgn" y ya se tiene el formulario con la silueta dada. Funciona pero tiene limitaciones: nuestra figura debe tener una sola frontera, por ello no puede ser una figura con un agujero en el medio (en todo caso el algoritmo ignorará el agujero en el medio). Como de costumbre este artículo va acompañado con un ejemplo para ilustrar los puntos aquí referidos. Nota: El algoritmo que sigue la silueta dada en el bitmap es relati- vamente lento y tosco, sin embargo es mantenible y realiza una cierta optimización con figuras no muy complejas. Hay un límite dado que se genera un arreglo en memoria cuando aún no se conoce cuantos puntos definirán la figura. Queda al usuario el variar este límite a su conveniencia. LOS CONTROLES ------------- El ejemplo adjunto a este artículo contiene además botones con forma. En modo de diseño son cuadrados pues son de tipo TBitBtn, pero en el evento OnCreate del formulario se le aplica a cada botón la forma del gráfico que contiene, de la misma manera que usamos para el formulario en el procedimiento ActiveSkin: procedure TForm1.FormCreate(Sender: TObject); Var hRegion : Thandle; Par : Array [0..1024] of TPoint; // Data -> region Cnt : Integer; begin Cnt := GenRegion(Par, BitBtn1.Glyph, (BitBtn1.Width - BitBtn1.Glyph.Width+1) div 2, (BitBtn1.Height - BitBtn1.Glyph.Height+1) div 2); hRegion := CreatePolygonRgn(Par, Cnt, ALTERNATE); SetWindowRgn(BitBtn1.handle, hRegion, true); ... Esto demuestra que la definición de regiones funciona más allá de las ventanas. MAS ALLA -------- El problema del tamaño del BMP sigue latente, pero prodríamos empaquetar el BMP y usarlo empaquetado como hace Winamp. Para este enfoque hay dos vías: podríamos usar algún algoritmo casi propietario semi-secreto o poco común (inevitablemente pienso en el Windows Media Player) o algo como el Zip. Esta última opción tiene la ventaja de que no estamos restringidos en cuanto a su uso. Pueden encontrar información para saber como manejarla en el sitio web de Latium Software: Boletín Pascal #5 http://www.latiumsoftware.com/es/pascal/0005.php http://www.latiumsoftware.com/descarga/p0005.zip (código fuente) Boletín Pascal #6 http://www.latiumsoftware.com/es/pascal/0006.php http://www.latiumsoftware.com/descarga/p0006.zip (código fuente) Si las imágenes son simples, como las que usé en el ejemplo, puede guardarlas usando 16 colores con compresión RLE 4 (esto puede hacerse por ejemplo con el viejo y querido Borland Resource Workshop que viene en el CD de instalación de Delphi). LO QUE OTROS HACEN ------------------ Deberíamos separar las áreas del formulario en cliente y no cliente, así como considerar los captions. Eventualmente podríamos usar semi-transpa- rencias, lo que será cada vez más común (gracias a Steve Jobs por los favores recibidos, aunque no utilicemos todos una Mac ;) Por allí hay una librería que considera sombras, animación, morphing y hasta un lenguaje de scripts, pero van más allá del objetivo de este artículo. -------------------------- El código fuente que acompaña este artículo puede descargarse desde: http://www.latiumsoftware.com/descarga/p0016.zip ________________________________________________________________________ 3. FORMAS GRISES CASI INDISTINGUIBLES EN ELEMENTOS DE MENU INHABILITADOS Por Vladimir S. <shvetadvipa@mtu-net.ru> Si desea ver consejos y trucos Delphi interesantes vaya con su navegador a http://www.webmachine.ru/delphi donde encontrará el archivo KULIBA.CHM por Valentin Ozerov que contiene más de 1.500 trucos y consejos (en ruso). Ozerov recolectó soluciones de programadores de Rusia y de todo el mundo, entre las que se encuentran algunas de mis soluciones también. En una de ellas describo como superar una falla para ciertos elementos de menú inhabilitados, que es el objeto de este artículo. Probablemente haya notado que cuando usa imágenes en elementos de menú y botones en barras de herramientas, éstas se ven como figuras grises casi indistinguibles cuando dichos componentes están inhabilitados (vea bmf.gif y btf.gif en el archivo que acompaña este boletín). Una posible solución a este problema es moficar el código fuente de la VCL (necesita tener la Edición Empresarial de Delphi para esto). Antes que nada, busque el fichero ImgList.pas, habitualmente ubicado en la carpeta ${Delphi}\Source\Vcl donde ${Delphi} es el camino donde instaló Delphi, como por ejemplo C:\Archivos de programa\Borland\Delphi5 Luego ubique la implementación del método TCustomImageList.DoDraw. Coméntela (para mantener la versión original por si acaso) y copie el siguiente código: procedure TCustomImageList.DoDraw(Index: Integer; Canvas: TCanvas; X, Y: Integer; Style: Cardinal; Enabled: Boolean); procedure ScrambleBitmap(var BMP: TBitmap); const RMask = $0000FF; RAMask = $FFFF00; GMask = $00FF00; GAMask = $FF00FF; BMask = $FF0000; BAMask = $00FFFF; var R,C: integer; Color: LongWord; begin with Bmp.Canvas do begin for C:= 0 to Bmp.Height - 1 do for R:= 0 to Bmp.Width - 1 do begin Color:= Pixels[R,C]; if (Color = 0) or (Color = $FFFFFF) then Continue; if (Color and RMask > $7F) and (Color and RAMask > $0) or (Color and GMask > $7F00) and (Color and GAMask > $0) or (Color and BMask > $7F000) and (Color and BAMask > $0) then Pixels[R,C]:= $FFFFFF else Pixels[R,C]:= 0; end; end; end; const ROP_DSPDxax = $00E20746; var R: TRect; DestDC, SrcDC: HDC; begin if HandleAllocated then begin if Enabled then ImageList_DrawEx(Handle, Index, Canvas.Handle, X, Y, 0, 0, GetRGBColor(BkColor), GetRGBColor(BlendColor), Style) else begin if FMonoBitmap = nil then begin FMonoBitmap:= TBitmap.Create; with FMonoBitmap do begin // Monochrome:= True; commented!!! Width:= Self.Width; Height:= Self.Height; end; end; { Store masked version of image temporarily in FBitmap } FMonoBitmap.Canvas.Brush.Color:= clWhite; FMonoBitmap.Canvas.FillRect(Rect(0, 0, Self.Width, Self.Height)); ImageList_DrawEx(Handle, Index, FMonoBitmap.Canvas.Handle, 0, 0, 0, 0, CLR_DEFAULT, 0, ILD_NORMAL); ScrambleBitmap(FMonoBitmap); // call patch R:= Rect(X, Y, X+Width, Y+Height); SrcDC:= FMonoBitmap.Canvas.Handle; BitBlt(SrcDC, 0, 0, Width, Height, SrcDC, 0, 0, DSTINVERT); // add!!! { Convert Black to clBtnHighlight } Canvas.Brush.Color:= clBtnHighlight; DestDC:= Canvas.Handle; Windows.SetTextColor(DestDC, clWhite); Windows.SetBkColor(DestDC, clBlack); BitBlt(DestDC, X+1, Y+1, Width, Height, SrcDC, 0, 0, ROP_DSPDxax); { Convert Black to clBtnShadow } Canvas.Brush.Color:= clBtnShadow; DestDC:= Canvas.Handle; Windows.SetTextColor(DestDC, clWhite); Windows.SetBkColor(DestDC, clBlack); BitBlt(DestDC, X, Y, Width, Height, SrcDC, 0, 0, ROP_DSPDxax); end; end; end; Ahora debe compilar esta unidad. Esto normalmente se hace copiando el archivo ImgList.pas en el directorio donde reside su proyecto y luego compilando el proyecto, produciendo así el archivo ImgList.dcu que debe mover por ejemplo a la carpeta ${Delphi}\Lib para que aplique a todas las aplicaciones que compile en el futuro. Los gráficos que resultan con este parche se ven muchísimo mejor (vea bmr.gif y btr.gif en el archivo que acompaña este boletín). ________________________________________________________________________ 4. COLOR BUTTON Por Vladimir S. <shvetadvipa@mtu-net.ru> Cuando lee libros de Charlie Calvert, Tom Swan y otros, puede encontrar algo como esto "... no puede cambiar el color de un Button o un BitBtn porque Windows lo dibuja". Bueno... no puede hacerlo, pero si desea muy mucho hacerlo, sí puede! Desarrollé un componente ColorBtn. Puede usar cualquier color que quiera (vea colorbtn.gif en el archivo zip que acompaña este boletín). Aquí está el código: unit ColorBtn; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Buttons; type TColorBtn = class(TButton) private IsFocused: boolean; FCanvas: TCanvas; F3DFrame: boolean; FButtonColor: TColor; procedure Set3DFrame(Value: boolean); procedure SetButtonColor(Value: TColor); procedure CNDrawItem(var Message: TWMDrawItem); message CN_DRAWITEM; procedure WMLButtonDblClk(var Message: TWMLButtonDblClk); message WM_LBUTTONDBLCLK; procedure DrawButtonText(const Caption: string; TRC: TRect; State: TButtonState; BiDiFlags: Longint); procedure CalcuateTextPosition(const Caption: string; var TRC: TRect; BiDiFlags: Longint); protected procedure CreateParams(var Params: TCreateParams); override; procedure SetButtonStyle(ADefault: boolean); override; public constructor Create(AOwner: TComponent); override; destructor Destroy; override; published property ButtonColor: TColor read FButtonColor write SetButtonColor default clBtnFace; property Frame3D: boolean read F3DFrame write Set3DFrame default False; end; procedure Register; implementation { TColorBtn } constructor TColorBtn.Create(AOwner: TComponent); begin Inherited Create(AOwner); FCanvas:= TCanvas.Create; FButtonColor:= clBtnFace; F3DFrame:= False; end; destructor TColorBtn.Destroy; begin FCanvas.Free; Inherited Destroy; end; procedure TColorBtn.CreateParams(var Params: TCreateParams); begin Inherited CreateParams(Params); with Params do Style := Style or BS_OWNERDRAW; end; procedure TColorBtn.Set3DFrame(Value: boolean); begin if F3DFrame <> Value then F3DFrame:= Value; end; procedure TColorBtn.SetButtonColor(Value: TColor); begin if FButtonColor <> Value then begin FButtonColor:= Value; Invalidate; end; end; procedure TColorBtn.WMLButtonDblClk(var Message: TWMLButtonDblClk); begin Perform(WM_LBUTTONDOWN, Message.Keys, Longint(Message.Pos)); end; procedure TColorBtn.SetButtonStyle(ADefault: Boolean); begin if IsFocused <> ADefault then IsFocused:= ADefault; end; procedure TColorBtn.CNDrawItem(var Message: TWMDrawItem); var RC: TRect; Flags: Longint; State: TButtonState; IsDown, IsDefault: Boolean; DrawItemStruct: TDrawItemStruct; begin DrawItemStruct:= Message.DrawItemStruct^; FCanvas.Handle:= DrawItemStruct.HDC; RC:= ClientRect; with DrawItemStruct do begin IsDown:= ItemState and ODS_SELECTED <> 0; IsDefault:= ItemState and ODS_FOCUS <> 0; if not Enabled then State:= bsDisabled else if IsDown then State:= bsDown else State:= bsUp; end; Flags:= DFCS_BUTTONPUSH or DFCS_ADJUSTRECT; if IsDown then Flags:= Flags or DFCS_PUSHED; if DrawItemStruct.ItemState and ODS_DISABLED <> 0 then Flags:= Flags or DFCS_INACTIVE; if IsFocused or IsDefault then begin FCanvas.Pen.Color:= clWindowFrame; FCanvas.Pen.Width:= 1; FCanvas.Brush.Style:= bsClear; FCanvas.Rectangle(RC.Left, RC.Top, RC.Right, RC.Bottom); InflateRect(RC, -1, -1); end; if IsDown then begin FCanvas.Pen.Color:= clBtnShadow; FCanvas.Pen.Width:= 1; FCanvas.Rectangle(RC.Left, RC.Top, RC.Right, RC.Bottom); InflateRect(RC, -1, -1); if F3DFrame then begin FCanvas.Pen.Color:= FButtonColor; FCanvas.Pen.Width:= 1; DrawFrameControl(DrawItemStruct.HDC, RC, DFC_BUTTON, Flags); end; end else DrawFrameControl(DrawItemStruct.HDC, RC, DFC_BUTTON, Flags); FCanvas.Brush.Color:= FButtonColor; FCanvas.FillRect(RC); InflateRect(RC, 1, 1); if IsFocused then begin RC:= ClientRect; InflateRect(RC, -1, -1); end; if IsDown then OffsetRect(RC, 1, 1); FCanvas.Font:= Self.Font; DrawButtonText(Caption, RC, State, 0); if IsFocused and IsDefault then begin RC:= ClientRect; InflateRect(RC, -4, -4); FCanvas.Pen.Color:= clWindowFrame; Windows.DrawFocusRect(FCanvas.Handle, RC); end; FCanvas.Handle:= 0; end; procedure TColorBtn.CalcuateTextPosition(const Caption: string; var TRC: TRect; BiDiFlags: Integer); var TB: TRect; TS, TP: TPoint; begin with FCanvas do begin TB:= Rect(0, 0, TRC.Right + TRC.Left, TRC.Top + TRC.Bottom); DrawText(Handle, PChar(Caption), Length(Caption), TB, DT_CALCRECT or BiDiFlags); TS := Point(TB.Right - TB.Left, TB.Bottom - TB.Top); TP.X := ((TRC.Right - TRC.Left) - TS.X + 1) div 2; TP.Y := ((TRC.Bottom - TRC.Top) - TS.Y + 1) div 2; OffsetRect(TB, TP.X + TRC.Left, TP.Y + TRC.Top); TRC:= TB; end; end; procedure TColorBtn.DrawButtonText(const Caption: string; TRC: TRect; State: TButtonState; BiDiFlags: Integer); begin with FCanvas do begin CalcuateTextPosition(Caption, TRC, BiDiFlags); Brush.Style:= bsClear; if State = bsDisabled then begin OffsetRect(TRC, 1, 1); Font.Color:= clBtnHighlight; DrawText(Handle, PChar(Caption), Length(Caption), TRC, DT_CENTER or DT_VCENTER or BiDiFlags); OffsetRect(TRC, -1, -1); Font.Color:= clBtnShadow; DrawText(Handle, PChar(Caption), Length(Caption), TRC, DT_CENTER or DT_VCENTER or BiDiFlags); end else DrawText(Handle, PChar(Caption), Length(Caption), TRC, DT_CENTER or DT_VCENTER or BiDiFlags); end; end; procedure Register; begin RegisterComponents('Samples', [TColorBtn]); end; end. Como puede ver no es muy difícil. Nota: Windows dibuja el botón y ColorBtn lo pinta. ________________________________________________________________________ 5. TALLER En la última edición mostré una forma simple de poner casillas de verificación para campos lógicos en un DBGrid sin crear un nuevo componente. Ahora, a todos aquellos que están aprendiendo sobre creación de componentes y tienen algo de tiempo para esto, me gustaría proponerles como ejercicio que escriban un descendiente de TDBGrid que maneje campos lógicos. Incluiré todas las soluciones que reciba en el archivo adjunto de la primera edición de Marzo de este boletín. ________________________________________________________________________ 6. LICENCIA DE KYLIX Escribo este artículo porque algunos expresaron cierta preocupación por la licencia dual de CLX, pensando que para distribuir aplicaciones comercialmente deberían pagar una licencia comercial de CLX aparte de la licencia de Kylix. Antes de continuar quisiera agradecer a Thomas J. Theobald (Gerente de Producto - Herramientas RAD - Borland Software Corporation) por muy amablemente responder mis preguntas acerca de esta cuestión. De acuerdo con el CLUF (Contrato de Licencia para el Usuario Final, o EULA: End-User License Agreement) de la Open Edition de Kylix, todas las aplicaciones, bibliotecas, paquetes, componentes, etc. que haga con esta edición deberán ser distribuidos bajo la Licencia Pública General (o GPL: General Public License). La CLX que vendrá con esta edición de Kylix también será GPL. Puede encontrar más información sobre esta licencia en el sitio web de la Free Software Foundation: http://www.fsf.org/copyleft/gpl.html También hay disponible una traducción no oficial al español en: http://lucas.hispalinux.es/Otros/gples/gples.html Por otra parte, la CLX que viene con Kylix Desktop Developer Edition y Kylix Server Developer Edition se distribuye bajo una licencia dual. Con estas ediciones uno podrá distribuir sus aplicaciones, bibliotecas, paquetes, componentes, etc. bajo la GPL o bajo sus propios términos de licencia (comercial, shareware, beerware, freeware, adware, etc.) sin tener que pagar ninguna licencia adicional aparte de la licencia de la edición Desktop o Server de Kylix (U$S 999 y U$S 1,999 respectivamente) puesto que éstas ya incluyen el precio de la licencia comercial de CLX. Kylix será licenciado por desarrollador, significando ésto que puede tener Kylix instalado en muchos ordenadores en tanto que usted sea el único que use Kylix. Si por ejemplo dos desarrolladores pretenden usar Kylix, aún si está instalado en la misma máquina y que no hagan uso simultáneo, tendrán que adquirir dos licencias. He escuchado a muchos argüir que los precios de las ediciones comerciales de Kylix son bastante altos, y creo que lo son (para mí por lo menos), pero tenemos que considerar tres cosas: 1) Debemos entender que Borland tiene que cubrir el costo de desarrollo de Kylix que llevó mucho más trabajo y tiempo del esperado, o mejor dicho del originalmente estimado, porque no puede decirse que la demora sea totalmente inesperada considerando que estamos hablando de casi todo un desarrollo nuevo en un entorno nuevo como Linux... 2) El precio aún es bueno considerando que con esta herramienta RAD se podrá entrar a todo un nuevo mercado. 3) La Open Edition estará disponible para descargar gratuitamente (o por tan sólo U$S 99 por el CD y la documentación impresa) y es bastante apta para los contratistas independientes que desarrollan soluciones a medida. El hecho de que tenga que entregar el código fuente y permitir uso libre del software (copias, modificaciones, etc.) no le impide cobrar por él. Software libre no es necesariamente software gratis. Si alguien nos pide que desarrolle o que le haga cambios a una aplicación GPL, esto no significa que debamos hacerlo gratis! Podemos cobrar por nuestro trabajo tanto como podamos. También podemos cobrar por empacar y despachar software GPL, aún si éste no es nuestro (por ejemplo las distribuciones Linux hacen esto). Además, distribuir su software como GPL puede ayudarlo a vender sus servicios como desarrollador independiente porque las compañías ven con buenos ojos al software GPL dado que no quieren estar atadas a tarifas de mantenimiento ni verse forzadas a acudir al desarrollador original si necesitan hacer cambios o agregados al programa. ¿Qué pasaría si usted ya no tiene más tiempo para esas cosas? Las compañías quieren la libertad de elegir quién mantendrá y hará posteriores desarrollos del software que compran. No obstante ello, es bastante probable que requieran esos servicios de usted, puesto que nadie conocerá una aplicación mejor que aquel que la desarrolló. Fundamentalmente lo que quieren es la seguridad de que no dependen de usted, y que eventual- mente pueden reemplazarlo si alguna vez decide moverse a otras cosas, o si algo le sucede, o si sienten que les cobra muy caros sus servicios, o lo que sea... Personalmente, creo que habrá un antes y un después del lanzamiento de Kylix... Mi primer pensamiento es que muy pronto Linux se poblará de aplicaciones de interfaz gráfica muy buenas distribuidas bajo los términos de la GPL. Principalmente utilidades de configuración y administración del sistema, y herramientas básicas que harán que Linux sea más amistoso con el usuario. El software comercial posiblemente tarde más en llegar, pero supongo que tarde o temprano también estará allí. La frase "no hay aplicaciones para Linux" será parte del pasado. Mi segundo pensamiento es que debido a que Linux es gratis, y que la Kylix Open Edition también será gratis, y dado que la GPL es adecuada para propósitos educativos, puedo ver ahora mismo la presión de estudiantes y profesores en el próximo año para incluir la combinación Linux + Kylix en los planes y programas de estudios de escuelas, colegios, politécnicos y universidades. Creo que si Kylix no ayuda a llevar a Linux al siguiente nivel y no consigue más adeptos al lenguaje Pascal, nada lo hará. Bueno, el tiempo dirá... ________________________________________________________________________ 7. ENLACES * Scalabium Un sitio bien diseñado con muchos trucos Delphi, ejemplos de código fuente, componentes, artículos y tutoriales. (En inglés) http://www.scalabium.com/ ________________________________________________________________________ ¡TÚ PUEDES AYUDARNOS! Necesitamos tu ayuda para que este boletín pueda continuar y crecer. Una forma en que puedes ayudarnos es enviando este enlace a tus amigos: http://www.latiumsoftware.com/es/pascal/index.php Otra forma es votándonos en alguno de estos rankings para darle más visibilidad a nuestro sitio web y aumentar así el número de suscrip- ciones al boletín, que esperamos en el futuro se traduzca también en un mayor número de colaboraciones de artículos, trucos, etc.: http://www.sandbrooksoftware.com/cgi-bin/TopSite2/rankem.cgi?id=latium http://news.optimax.com/topdelphi/links.exe/click?id=70C517ECAE6E http://www.programmingpages.com/?r=latiumsoftwarecomenpascal http://www.top219.org/cgi-bin/vote.cgi?delphi&83 http://top100borland.com/in.php?who=20 http://top200.jazarsoft.com/delphi/rank.php3?id=latium http://213.65.224.200/cgi-bin/toplist.cgi/hits?Id=80 http://www.programacion.net/votar-enlace.php?id=474 http://www.lawebdelprogramador.com/buscar/enlace.php?id=615 Por favor vota. Son sólo unos segundos para ti que REALMENTE pueden hacer la diferencia. Necesitamos tu ayuda para poder continuar. ________________________________________________________________________ Si no has recibido el archivo con el código fuente completo de los ejemplos que se presentan en este boletín, puedes descargarlo de la siguiente dirección: http://www.latiumsoftware.com/descarga/p0016.zip ________________________________________________________________________ Página principal: http://www.latiumsoftware.com/es/pascal/index.php Página del grupo: http://espanol.groups.yahoo.com/group/boletin-pascal/ Para suscribirse / apuntarse: boletin-pascal-subscribe@gruposyahoo.com Para cancelar / removerse: boletin-pascal-unsubscribe@gruposyahoo.com Para reportar problemas con la suscripción: eds2004 @ latiumsoftware.com ________________________________________________________________________ Este boletín se provee "TAL Y COMO ESTA", sin garantía de ninguna clase. Su uso implica la aceptación de nuestros términos de licencia y de la ausencia de garantía que puedes leer en nuestro sitio web. Allí también encontrarás una nota sobre marcas registradas. Te animamos a que redis- tribuyas este boletín, siempre y cuando lo hagas en forma completa (incluyendo la información de copyright), sin modificaciones y de manera gratuita. Los artículos son copyright de sus respectivos autores y se reproducen aquí con el permiso de los mismos. ________________________________________________________________________ Latium Software http://www.latiumsoftware.com/es/index.php Copyright (c) 2001 por Ernesto De Spirito. Todos los derechos reservados ________________________________________________________________________ |
Los ejemplos completos de código fuente de este número están disponibles para descargar.
![]() bmf.gif |
![]() bmr.gif |
![]() btf.gif ![]() btr.gif |
||
![]() colorbtn.gif |
||||
![]() |
¿Errores? ¿Omisiones? ¿Comentarios? Por favor contáctanos!











