quarta-feira, março 30, 2005

Windows XP – Habilitando Remote Desktop Connection

A partir do Windows XP, já podemos utilizar o Remote Desktop Connection (uma versão light do Terminal Server), para simularmos uma sessão em uma máquina remota.
Para mim, a desvantagem do Remote Desktop em comparação com outros softwares ( VNC, Netmetting, PcAnyWhere e etc...) é que no momento que você conecta na máquina remota, a mesma é bloqueada, não permitindo que ninguém veja o que está ocorrendo. Por um lado e ruim, mas por outro é bom se levarmos em consideração a segurança.
Para habilitar essa funcionalidade em uma máquina em uma Rede Local, siga os seguintes passos (Em português):
1) Na maquina que será o Host ( Máquina na qual você irá conectar), siga os seguintes passos
a. Clique com o botão direito em Meu Computador e selecione propriedades
b. Vá a pasta Remoto e Habilite os dois CheckBoxes que existem. ( Se exibir uma mensagem, confirme)
c. Se o usuário que vai utilizar o Remote Desktop não for administrador da máquina local, clique no botão Selecionar usuários remotos e insira o usuário desejado.
2) Na máquina Guest ( Máquina que você irá utilizar para conectar a outra máquina ou Terminal Burro), siga os seguintes passos
a. Vá a Todos os Programas à Acessórios à Comunicação à Conexão a área de trabalho Remota ( No Windows Xp, está opção já existe por default. Em outros sistemas operacionais, o software deve ser baixado da Web e instalado http://www.microsoft.com/windowsxp/downloads/tools/rdclientdl.mspx )
Boa Sorte!!

PowerBuilder – Erro no Layout

Em algumas situações, notamos que o PowerBuilder começa a cancelar (Fechar, GPF e etc…) quando abrimos alguns objetos. Muitas vezes, apenas de abrir o PowerBuilder já ocorre erro, isso porque ele tenta abrir o objeto que está causando erro e o mais inacreditável é que o erro só ocorre em uma máquina especifica e muitas vezes, apenas com um usuário específico.
Este problema ocorre porque o Layout do PowerBuilder corrompeu. O Layout é responsável por posicionar os frames de uma janela e armazena a última configuração que foi salva. Além disso, o Layout é especifico de máquina e usuário, por isso, muitas vezes ocorre apenas para um usuário especifico.
Para resolver este problema, você deve resetar o Layout do PowerBuilder. Existem duas formas de fazer isso:
1) Menu View à Layouts à Default
2) Apagar a chave do registry responsável pelo layout (HKEY_CURRENT_USER\Software\Sybase\PowerBuilder\9.0\Layout )

Mas, se mesmo assim o problema continuar ocorrendo, recomendo executar um Full Build e um Optimize nas PBls.

quarta-feira, março 23, 2005

PowerBuilder – Recuperando informações de um Arquivo

A partir do PowerBuilder 8, temos a opção de informar no projeto qual a versão do nosso executável, mas não conseguimos recuperar essa informação de forma fácil.
Abaixo está o código necessário para recuperar as informações ou matadados de um arquivo.



//*****************Declare as seguintes external functions
FUNCTION ulong GetFileVersionInfoSizeA( REF string lpFilename, REF ulong lpdwHandle ) LIBRARY "version.dll"
FUNCTION integer GetFileVersionInfoA( REF string lpFilename, REF ulong lpdwHandle, ulong dwLen, REF string lpData ) LIBRARY "version.dll"
FUNCTION boolean VerQueryValueA( REF string lpBlock, string lpSubBlock, REF long lpBuffer, REF uint puLen ) LIBRARY "version.dll"
SUBROUTINE CopyMemory ( REF string d, long s, long l ) LIBRARY "kernel32.dll" ALIAS FOR RtlMoveMemory

//*******Código utilizado para recuperar o número de versão do produto no executável
string vls_filename, vls_Buff, vls_key
ulong vlul_Handle, vlul_Length
integer vli_rc
long vll_pointer
uint vlui_length

//Busca o tamanho do buffer do aplicativo
vlul_Length = GetFileVersionInfoSizeA( p_nom_executavel, vlul_Handle )
IF vlul_Length <= 0 THEN
return error.of_popula( populateerror(1010, 'Não foi possivel localizar o arquivo para o controle de versão.~n~r' + &
'Nome do executável : ' + p_nom_executavel))
END IF

vls_Buff = Space( vlul_Length )

//Busca o ponteiro para as informações do executavel
vli_rc = GetFileVersionInfoA( p_nom_executavel, vlul_Handle, vlul_Length, vls_Buff )

IF vli_rc = 0 THEN
return error.of_popula( populateerror(1010, 'Ocorreu um erro ao recuperar informação de versão.~n~r' + &
'Nome do executável : ' + p_nom_executavel))
END IF

//Define qual informação sera recurperada
//Onde \StringFileInfo\\
//vls_key = "\StringFileInfo\040904e4\FileVersion"
vls_key = "\StringFileInfo\040904e4\ProductVersion"


IF NOT VerQueryValueA( vls_buff, vls_key, vll_pointer, vlui_length ) OR &
vlul_Length <= 0 THEN
p_versao = ""
return error.of_popula( populateerror(1010, 'Ocorreu um erro ao recuperar o número da vesão.~n~r' + &
'Nome do executável : ' + p_nom_executavel))
ELSE
p_versao = Space( vlui_length )
CopyMemory( p_versao, vll_pointer, vlui_length )
END IF

return 1

segunda-feira, março 21, 2005

PowerBuilder 9 - About libraries

Whenever you save an object, such as a window or menu, in a painter, PowerBuilder stores the object in a library (a PBL file). Similarly, whenever you open an object in a painter, PowerBuilder retrieves the object from the library.
Assigning libraries
PowerScript targets can use as many libraries as you want. Libraries can be on your own PC or workstation or on a server. When you create a target, you specify which libraries it uses. You can also change the library search path for a target at any time during development.
For information about specifying the library search path, see "Specifying the target's library search path".
How the information is saved
Every object is saved in two parts in a library:
Source form This is a syntactic representation of the object, including the script code.
Object form This is a binary representation of the object, similar to an object file in the C and C++ languages. PowerBuilder compiles an object automatically every time you save it.
Using libraries
It is hard to predict the needs of a particular application, so the organization of a target's libraries generally evolves over the development cycle. PowerBuilder lets you reorganize your libraries easily at any time.
About library size
For small applications, you might use only one library, but for larger applications, you should split the application into different libraries.
There are no limits to how large libraries can be, but for performance and convenience, you should follow these guidelines:
Number of objects It is a good idea not to have more than 50 or 60 objects saved in a library. This is strictly for your convenience; the number of objects does not affect performance. If you have many objects in a library, list boxes that list library objects become unmanageable and the System Tree and Library painter become more difficult to use.
Balance Managing a large number of libraries with only a few objects makes the library search path too long and can slow performance by forcing PowerBuilder to look through many libraries to find an object. Try to maintain a balance between the size and number of libraries.
Organizing libraries
You can organize your libraries any way you want. For example, you might put all objects of one type in their own library, or divide your target into subsystems and place each subsystem in its own library.
Sharing objects with others
PowerBuilder provides basic source control using the PBNative check in/check out utility. PBNative allows you to lock the current version of PowerBuilder objects and prevents others from checking out these objects and modifying them while you are working on them.
The project administrator must design a directory hierarchy for the project's workspace. The administrator might create a separate subdirectory for each target in the workspace, or for each PBL in the workspace. After the administrator sets up the project and registers every object in the workspace, individual developers copy a template workspace to their own computers, open the workspace, and connect to source control.
PowerBuilder also provides a direct connection to external SCC-compliant source control systems.
For more about using PBNative and other source control systems, see "Using a source control system with PowerBuilder".

sexta-feira, março 18, 2005

PowerBuilder – Pegando Valores em um ComputedField

Normalmente, pegamos valores em uma coluna na DataWindow e para isso utilizamos o GetItem.
Em algumas situações, precisamos de um valor de um ComputedField, o que também é um processo simples, mas pode se tornar chato se você precisar fazer este processo para vários campos.
A solução que encontrei para este problema é criar uma função que recupera o valor de um computedField.
Abaixo está o código necessário para a criação desta função:

// DESCRIÇÃO:
// * Pega o valor de um campo ComputeField
// * Similar ao GetItem, mas funciona para ComputeFiled
//
// ARGUMENTOS DE ENTRADA:
// adw_controle : DataWidow onde se encontra o Compute
// as_compute : Nome do ComputedField
// al_row : Numero da linha que deseja busca o valor. Se for um compute
// que se encontra no Header ou no
//
// RETORNO:
// * "" : Não conseguiu encontra o valor
// * <> de "" : Valor processado
//
// OBSERVAÇÃO:
//
// CRIADO POR :
// 17/03/2005 - Thiago Campos Pereira
// ALTERADO POR :
//
//========================================================================

string vls_retorno
string vls_expressao
vls_expressao = as_compute + ".Expression"
//Pega a expressão do compute
vls_expressao = adw_controle.Describe(vls_expressao)


//busca o valor
vls_retorno = "evaluate('"+vls_expressao+"', "+string(al_row)+")"
vls_retorno = adw_controle.describe(vls_retorno)
return vls_retorno

terça-feira, março 15, 2005

Oracle – Trabalhando com campos auto-incremental

O campo auto-incremental é o campo um campo numérico onde o valor é gerado automaticamente a partir de algumas informações.
No Oracle, este campo é conhecido como SEQUENCE.
Para trabalhar com este campo no Oracle, devemos seguir os seguintes passos:

1) Criar a tabela com um campo numérico, que será utilizado como auto incremental
create table ATUALIZACAO_LOG
(
SEQ_LOG NUMBER not null,
COD_EMPRESA NUMBER(5) not null,
COD_TELA NUMBER(38) not null,
CHAVE VARCHAR2(300) not null,
INICIO DATE not null,
FIM DATE null ,
TIP_LOG CHAR(1) not null
constraint CKC_TIP_LOG_LOG check (TIP_LOG in ('I','A','E','P')),
SIGLA_USUARIO VARCHAR2(20) not null,
HISTORICO VARCHAR2(300) not null,
constraint PK_ATUALIZACAO_LOG primary key (SEQ_LOG)
)
/
2) Definir um objeto do tipo SEQUENCE, com as suas configurações
CREATE SEQUENCE SEQ_ATUALIZACAO_LOG
START WITH 1
INCREMENT BY 1
NOMINVALUE
NOMAXVALUE
NOCYCLE
CACHE 20
NOORDER
/
Onde:
START WITH : Posição inicial
INCREMENT BY : Valor a ser incrementado.
3) Gerar o próximo valor

select SEQ_ATUALIZACAO_TELA.nextval
into Proximo_valor
from dual

4) Incluir na tabela

insert into ATUALIZACAO_LOG values(Proximo_valor, cod_empresa, cod_tela, upper(:as_chave), dt_now, dt_now, tip_log, upper(sigla_usuario), upper(historico) )