DESATIVAR TAB HWGUI 2.23 B8

Projeto HwGui - Biblioteca visual para Harbour/xHarbour

Moderador: Moderadores

Avatar do usuário
Itamar M. Lins Jr.
Administrador
Administrador
Mensagens: 8028
Registrado em: 30 Mai 2007 11:31
Localização: Ilheus Bahia
Curtiu: 2 vezes
Curtiram: 1 vez

Re: DESATIVAR TAB HWGUI 2.23 B8

Mensagem por Itamar M. Lins Jr. »

deividdjs escreveu: 16 Jan 2026 21:23 ok .. me passa umas dicas de como eu uso a gtk e como eu posso usar meu sistema de forma mista .. q vou instalar um computador aqui com o linux e faço os testes nos dois quando mudar alguma coisa na lib .. qual distribuicao do linux vc usa??

Abraço!
Uso Ubuntu, mas com KDE. Kubuntu.
Pq gosto do KDE... Pode usar o Ubuntu mesmo é até melhor que vem com GTK.
Lembrando que Hwgui no Linux roda com GTK 2.0
Meu CPU(Desktop) resolveu dar problema, estou no Notebook...
Saudações,
Itamar M. Lins Jr.
Avatar do usuário
deividdjs
Usuário Nível 3
Usuário Nível 3
Mensagens: 401
Registrado em: 19 Set 2006 09:39
Localização: Foz do Iguaçu / Pr
Curtiram: 1 vez

Re: DESATIVAR TAB HWGUI 2.23 B8

Mensagem por deividdjs »

Blz .. vou testar fazer meu sistema híbrido … vamos falando ! Vou instalar o Linux
Saludos,
Deivid José de Souza
Windows 11 + Harbour 3.4 + MINGW64 gcc 14.1.0 + Visual Lib + GTWVG + LETODBF WINDOWNS/LINUX
hwgui 2.23 b8
Avatar do usuário
deividdjs
Usuário Nível 3
Usuário Nível 3
Mensagens: 401
Registrado em: 19 Set 2006 09:39
Localização: Foz do Iguaçu / Pr
Curtiram: 1 vez

Re: DESATIVAR TAB HWGUI 2.23 B8

Mensagem por deividdjs »

uma duvida .. sabe porque tento entrar no fórum antigo e diz q eu não estou autorizado a ver as mensagem ?? ... tem bastante coisas lá q não tem aqui parar tirar duvidas .. porem me ajudar ??

Abraço!
Saludos,
Deivid José de Souza
Windows 11 + Harbour 3.4 + MINGW64 gcc 14.1.0 + Visual Lib + GTWVG + LETODBF WINDOWNS/LINUX
hwgui 2.23 b8
Avatar do usuário
Itamar M. Lins Jr.
Administrador
Administrador
Mensagens: 8028
Registrado em: 30 Mai 2007 11:31
Localização: Ilheus Bahia
Curtiu: 2 vezes
Curtiram: 1 vez

Re: DESATIVAR TAB HWGUI 2.23 B8

Mensagem por Itamar M. Lins Jr. »

Olá!
Foi copiado 100% era o mesmo forum na época.
Agora aqui tem as msg novas e as antigas.
Saudações,
Itamar M. Lins Jr.
Avatar do usuário
deividdjs
Usuário Nível 3
Usuário Nível 3
Mensagens: 401
Registrado em: 19 Set 2006 09:39
Localização: Foz do Iguaçu / Pr
Curtiram: 1 vez

Re: DESATIVAR TAB HWGUI 2.23 B8

Mensagem por deividdjs »

Então .. eu tento buscar as mensagem antigas aqui e não traz .. estranho !
Saludos,
Deivid José de Souza
Windows 11 + Harbour 3.4 + MINGW64 gcc 14.1.0 + Visual Lib + GTWVG + LETODBF WINDOWNS/LINUX
hwgui 2.23 b8
Avatar do usuário
Itamar M. Lins Jr.
Administrador
Administrador
Mensagens: 8028
Registrado em: 30 Mai 2007 11:31
Localização: Ilheus Bahia
Curtiu: 2 vezes
Curtiram: 1 vez

Re: DESATIVAR TAB HWGUI 2.23 B8

Mensagem por Itamar M. Lins Jr. »

Olá!
Captura de imagem_20260121_222407.png
Captura de imagem_20260121_222407.png (25.74 KiB) Exibido 48 vezes
Captura de imagem_20260121_222437.png
Captura de imagem_20260121_222437.png (14.6 KiB) Exibido 48 vezes
Saudações,
Itamar M. Lins Jr.
Avatar do usuário
deividdjs
Usuário Nível 3
Usuário Nível 3
Mensagens: 401
Registrado em: 19 Set 2006 09:39
Localização: Foz do Iguaçu / Pr
Curtiram: 1 vez

Re: DESATIVAR TAB HWGUI 2.23 B8

Mensagem por deividdjs »

Boa noite prezados ...

consegui o mesmo efeito WINDOWS / LINUX .. ficou legal !!

quem quiser compilar em linux .. está funcionando com letodbf

Código: Selecionar todos

#include "hwgui.ch"
#include "rddleto.ch"

REQUEST LETO
REQUEST DBFCDX
REQUEST DBFFPT

// =====================================================
// CADASTRO DE USUÁRIOS (PSW) + LOGIN (GTK/Linux)
// - Versão SEM ADDPROPERTY() (compatível com seu build)
// - Estado do formulário em STATICs: g_cModo, g_nRecno, g_cUsuOrig
// =====================================================

// -------------------------------------------------
// Objetos/controles principais
// -------------------------------------------------
STATIC ThisForm
STATIC oTab, oBrw, oEdBusca
STATIC oEdUsuario, oEdSenhaOld, oEdSenhaNew, oEdSenhaConf
STATIC oBtnInclui, oBtnAltera, oBtnExcluir, oBtnSalvar, oBtnCancelar, oBtnSair

// -------------------------------------------------
// Buffers do formulário
// -------------------------------------------------
STATIC cUsuarioForm
STATIC cSenhaOldForm
STATIC cSenhaNewForm
STATIC cSenhaConfForm
STATIC cBusca

// -------------------------------------------------
// “Propriedades” do formulário (substitui ADDPROPERTY)
// -------------------------------------------------
STATIC g_cModo    := "view"
STATIC g_nRecno   := 0
STATIC g_cUsuOrig := ""

// -------------------------------------------------
// Estado de login (opcional)
// -------------------------------------------------
STATIC g_cOperador := ""
STATIC g_nPswRec   := 0

// Fonte padrão
PUBLIC oFontPSW

PUBLIC cPathLeto
PUBLIC CONEXAO_LETO

// =====================================================
// PONTO DE ENTRADA
// =====================================================
PROCEDURE MAIN()

   LOCAL cIP := "127.0.0.1"
   LOCAL cPort := "2830"
   LOCAL nTimeOut := 10000
   LOCAL nConectarLeto, nRes

   // Fonte padrão
   PUBLIC oFontPSW

   // monta string de conexão
   cPathLeto := "//" + cIP + ":" + cPort + "/"
   CONEXAO_LETO := ""

   // conecta
   nConectarLeto := leto_Connect( cPathLeto ,,, nTimeOut )

   IF nConectarLeto == -1

      nRes := leto_Connect_Err()

      IF nRes == LETO_ERR_LOGIN
         hwg_MsgStop( "Falla al logarse", "Conexión" )
      ELSEIF nRes == LETO_ERR_RECV
         hwg_MsgStop( "Erro al conectarse: " + Str(nConectarLeto), "Conexión" )
      ELSEIF nRes == LETO_ERR_SEND
         hwg_MsgStop( "Erro de envio", "Conexión" )
      ELSE
         hwg_MsgStop( "Servidor no encontrado! ", cIP + ":" + cPort )
      ENDIF

      QUIT
   ENDIF

   CONEXAO_LETO := LETO_GETCURRENTCONNECTION()

   // cria/abre PSW no servidor + garante índice
   IF ! EnsurePSW_LETO()
      hwg_MsgStop( "No se pudo crear/abrir PSW en el servidor.", "Error" )
      QUIT
   ENDIF

   // (Opcional) LOG local
    EnsureLOG()

   // (Opcional) cria usuário padrão
   CRIAUSUARIOPADRAOPSW()

   IF TELA_LOGIN( NIL )
      CAD_USUARIO()
   ENDIF

RETURN


// =====================================================
// EnsurePSW_LETO()
// - Cria PSW.DBF no servidor se não existir
// - Abre PSW via RDD LETO
// - Garante CDX/TAGs (pswcx_01 / pswcx_02)
// - Deixa ORDER ativo em pswcx_01 (necessário p/ DBSEEK)
// =====================================================
STATIC FUNCTION EnsurePSW_LETO()

   LOCAL aStru := {}
   LOCAL lOk := .T.

   IF Empty( cPathLeto )
      RETURN .F.
   ENDIF

   BEGIN SEQUENCE

      // 1) cria DBF se não existir
      IF ! leto_file( cPathLeto + "psw.dbf" )

         AAdd( aStru, { "USUARIO", "C", 10, 0 } )
         AAdd( aStru, { "SENHA",   "C", 10, 0 } )
         AAdd( aStru, { "GRUPO",   "C", 20, 0 } )
         AAdd( aStru, { "ACESSO",  "C", 200,0 } )
         AAdd( aStru, { "CODLOJ",  "C", 2,  0 } )
         AAdd( aStru, { "CAIXA",   "C", 4,  0 } )

         dbCreate( cPathLeto + "psw.dbf", aStru, "LETO" )
      ENDIF

      // 2) abre PSW (sempre via LETO)
      IF ! Used( "PSW" )
         USE ( cPathLeto + "psw" ) VIA "LETO" SHARED NEW ALIAS "PSW"
      ELSE
         DbSelectArea( "PSW" )
      ENDIF

      // 3) garante CDX/TAGs (se não existir, cria)
      IF ! leto_file( cPathLeto + "psw" + indexext() )

         INDEX ON USUARIO TAG pswcx_01
         INDEX ON SENHA   TAG pswcx_02

      ENDIF

      // 4) garante ORDER ativo
      SET ORDER TO TAG pswcx_01

   RECOVER
      lOk := .F.
   END SEQUENCE

RETURN lOk


// =====================================================
// EnsureLOG() - (opcional) cria/abre LOG.DBF local
// =====================================================
STATIC FUNCTION ensurelog()

   LOCAL cDbf := hb_DirBase() + "log.dbf"
   LOCAL aStru

   IF ! hb_FileExists( cDbf )

      aStru := {}
      AAdd( aStru, { "CD_DATA",   "D", 8, 0 } )
      AAdd( aStru, { "CC_TIME",   "C", 8, 0 } )
      AAdd( aStru, { "CC_USUARIO","C", 20, 0 } )
      AAdd( aStru, { "CC_OPERAC", "C", 60, 0 } )

      BEGIN SEQUENCE
         DbCreate( cDbf, aStru, "DBFCDX" )
      RECOVER
         RETURN .F.
      END SEQUENCE
   ENDIF

   IF Select( "LOG" ) == 0
      BEGIN SEQUENCE
         USE ( cDbf ) ALIAS "LOG" NEW SHARED VIA "DBFCDX"
      RECOVER
         RETURN .F.
      END SEQUENCE
   ENDIF

RETURN .T.


// =====================================================
// CAD_USUARIO()
// =====================================================
FUNCTION CAD_USUARIO()

   LOCAL oDlg

   // Buffers do formulário
   cUsuarioForm   := Space(10)     // PSW->USUARIO é C(10)
   cSenhaOldForm  := ""
   cSenhaNewForm  := ""
   cSenhaConfForm := ""
   cBusca         := Space(40)

   IF Select("PSW") == 0
      hwg_MsgStop( "PSW no está abierto.", "Error" )
      RETURN NIL
   ENDIF

   // Estado inicial
   g_cModo    := "view"
   g_nRecno   := 0
   g_cUsuOrig := ""

   INIT DIALOG oDlg ;
      TITLE "Mantenimiento de Usuários" ;
      AT 0,0 ;
      SIZE 720, 460 ;
      STYLE WS_POPUP + WS_CAPTION + WS_SYSMENU + DS_CENTER ;
      FONT oFontPSW ;
      CLIPPER NOEXIT ;
      ON INIT {|| ;
         ThisForm := oDlg, ;
         OnDlgInitCad(), ;
         BrwInitPSW(), ;
         AtualizaTela(), ;
         SetInitialFocus( oBrw ),;
         oTab:bChange := { |o,nPage| IIF( g_cModo $ "novo|editar", .F., TabChangePSW( nPage ) ) } ;
      }

   ThisForm := oDlg

   // ESC global do diálogo
   hwg_SetDlgKey( oDlg, 0, 27, {|| CadUsuario_OnEsc( oDlg ) }, .F. )

   // BARRA DE BOTÕES
   @ 15,11 BUTTON oBtnInclui CAPTION "Nuevo" SIZE 90,30 OF oDlg ;
      ON CLICK {|| Habilitar("novo") }

   @ 110,11 BUTTON oBtnAltera CAPTION "Editar" SIZE 90,30 OF oDlg ;
      ON CLICK {|| Habilitar("editar") }

   @ 205,11 BUTTON oBtnExcluir CAPTION "Eliminar" SIZE 90,30 OF oDlg ;
      ON CLICK {|| ExcluirRegistro() }

   @ 300,11 BUTTON oBtnSalvar CAPTION "Guardar" SIZE 90,30 OF oDlg ;
      ON CLICK {|| Gravar("salvar") }

   @ 395,11 BUTTON oBtnCancelar CAPTION "Cancelar" SIZE 90,30 OF oDlg ;
      ON CLICK {|| Gravar("cancelar") }

   @ 490,11 BUTTON oBtnSair CAPTION "Salir" SIZE 90,30 OF oDlg ;
      ON CLICK {|| hwg_EndDialog( oDlg:handle ) }

   // TAB
   @ 10,50 TAB oTab ITEMS { } SIZE 690,360 OF oDlg ;
      ON CHANGE { |o,nPage| IIF( g_cModo $ "novo|editar", .F., TabChangePSW( nPage ) ) } ;
      STYLE 0

   // ABA CONSULTA
   BEGIN PAGE "Consulta" OF oTab

      @ 15,50 BROWSE oBrw DATABASE OF oTab SIZE 650,210 ;
         STYLE WS_BORDER + WS_VSCROLL + WS_HSCROLL + WS_TABSTOP ;
         FONT HFont():Add( "Courier New", 0, -13, 400 )

      @ 15,310 SAY "&Buscar:" SIZE 60,16 OF oTab TRANSPARENT

      @ 80,308 GET oEdBusca VAR cBusca PICTURE "@!" SIZE 200,22 OF oTab ;
         VALID {|| PesquisaUsuarios( oEdBusca:GetText(), oBrw ), SetInitialFocus( oBrw ), .T. }

      // GET fantasma (stub)
      AddPhantomGet( oTab )

   END PAGE OF oTab

   // ABA DADOS
   BEGIN PAGE "Datos" OF oTab

      @ 10,25 GROUPBOX "Datos del Usuario" SIZE 520,200 OF oTab

      @ 20,60  SAY "Usuario:"    SIZE 90,18 OF oTab TRANSPARENT
      @ 115,58 GET oEdUsuario   VAR cUsuarioForm   PICTURE "@!" SIZE 360,22 OF oTab ;
         STYLE WS_DISABLED ;
         VALID {|| ValidUsuario() }

      @ 20,95	  SAY "Anterior:"   SIZE 90,18 OF oTab TRANSPARENT
      @ 115,93 GET oEdSenhaOld  VAR cSenhaOldForm  PICTURE "@!" SIZE 240,22 OF oTab ;
         STYLE WS_DISABLED

      @ 20,130 SAY "Nueva:"      SIZE 90,18 OF oTab TRANSPARENT
      @ 115,128 GET oEdSenhaNew  VAR cSenhaNewForm  PICTURE "@!" SIZE 240,22 OF oTab ;
         STYLE WS_DISABLED

      @ 20,165 SAY "Confirmar:"  SIZE 90,18 OF oTab TRANSPARENT
      @ 115,163 GET oEdSenhaConf VAR cSenhaConfForm PICTURE "@!" SIZE 240,22 OF oTab ;
         STYLE WS_DISABLED

   END PAGE OF oTab

   // BROWSE – EVENTOS
   oBrw:Alias := "PSW"
   oBrw:bKeyDown     := { |o, k| BrwKeyDownPSW( oDlg, k ) }
   oBrw:bPosChanged  := {|| BrwSyncFromBrowse() }

   ACTIVATE DIALOG oDlg CENTER

RETURN NIL


STATIC FUNCTION CadUsuario_OnEsc( oDlg )

   IF g_cModo == "novo" .OR. g_cModo == "editar"

      IF hwg_MsgYesNo( "¿Desea abandonar sin guardar?", "Confirmar" )
         Gravar( "cancelar" )
      ENDIF

      RETURN .T.
   ENDIF

   hwg_EndDialog( oDlg:handle )

RETURN .T.


STATIC FUNCTION BrwKeyDownPSW( oDlg, k )

   HB_SYMBOL_UNUSED( oDlg )

   DO CASE
   CASE k == Asc("n") .OR. k == Asc("N")
      Habilitar( "novo" )
      RETURN .F.

   CASE k == Asc("e") .OR. k == Asc("E")
      Habilitar( "editar" )
      RETURN .F.

   CASE k == Asc("r") .OR. k == Asc("R")
      ExcluirRegistro()
      RETURN .F.

   CASE k == Asc("b") .OR. k == Asc("B")
      cBusca := ""
      SafeSetText( oEdBusca, "" )
      SafeSetFocus( oEdBusca )
      RETURN .F.
   ENDCASE

RETURN .T.


STATIC FUNCTION OnDlgInitCad()

   LOCAL nOld := Select()

   DbSelectArea( "PSW" )

   // garante ordem “real” antes de montar filtros temporários
   __PSW_GARANTE_ORDEM()

   BrwFiltroBasePSW( PSW->( RecNo() ) )

   IF PSW->( LastRec() ) > 0
      PSW->( DbGoTop() )
      g_nRecno := PSW->( RecNo() )
   ENDIF

   DbSelectArea( nOld )

RETURN NIL


STATIC FUNCTION BrwInitPSW()

   oBrw:Alias := "PSW"
   oBrw:aColumns := {}
   oBrw:AddColumn( HColumn():New( "Usuário", FieldBlock("USUARIO"), "C", 10, 0 ) )

   oBrw:oStyleHead := HStyle():New( ;
      { 0x003A3A3A, 0x005E5E5E }, ;
      1,, ;
      0.4, ;
      0x00EDEDED )

   oBrw:headColor := 16777215
   oBrw:Refresh()

RETURN NIL


STATIC FUNCTION BrwSyncFromBrowse()

   LOCAL nOld := Select()

   IF g_cModo == "novo" .OR. g_cModo == "editar"
      RETURN NIL
   ENDIF

   DbSelectArea( "PSW" )
   IF ! PSW->( EOF() )
      g_nRecno := PSW->( RecNo() )
   ENDIF
   DbSelectArea( nOld )

   AtualizaTela()

RETURN NIL


STATIC FUNCTION TabChangePSW( nPage )

   LOCAL nOld := Select()

   IF g_cModo $ "novo|editar"
      RETURN NIL
   ENDIF

   DbSelectArea( "PSW" )

   DO CASE
   CASE nPage == 1
      SetInitialFocus( oBrw )

   CASE nPage == 2

      IF PSW->( LastRec() ) > 0 .AND. ! PSW->( EOF() )
         cUsuarioForm := PSW->USUARIO
      ELSE
         cUsuarioForm := ""
      ENDIF

      SafeSetText( oEdUsuario, cUsuarioForm )
      SafeRefresh( oEdUsuario )

      cSenhaOldForm  := ""
      cSenhaNewForm  := ""
      cSenhaConfForm := ""

      SafeSetText( oEdSenhaOld,  "" )  ; SafeRefresh( oEdSenhaOld )
      SafeSetText( oEdSenhaNew,  "" )  ; SafeRefresh( oEdSenhaNew )
      SafeSetText( oEdSenhaConf, "" )  ; SafeRefresh( oEdSenhaConf )
   ENDCASE

   DbSelectArea( nOld )

RETURN NIL


STATIC FUNCTION AtualizaTela()

   LOCAL nOld := Select()
   LOCAL lTemReg := .F.

   DbSelectArea( "PSW" )
   lTemReg := ( PSW->( LastRec() ) > 0 .AND. ! PSW->( EOF() ) )

   IF g_cModo <> "novo" .AND. g_cModo <> "editar"
      g_cModo := "view"
   ENDIF
   
   oTab:Page(1):Enable()

   IF lTemReg
      cUsuarioForm := PSW->USUARIO
   ELSE
      cUsuarioForm := ""
   ENDIF

   cSenhaOldForm  := ""
   cSenhaNewForm  := ""
   cSenhaConfForm := ""

   SafeSetText( oEdSenhaOld,  "" ) ; SafeRefresh( oEdSenhaOld )
   SafeSetText( oEdSenhaNew,  "" ) ; SafeRefresh( oEdSenhaNew )
   SafeSetText( oEdSenhaConf, "" ) ; SafeRefresh( oEdSenhaConf )

   SafeDisable( oEdUsuario )
   SafeDisable( oEdSenhaOld )
   SafeDisable( oEdSenhaNew )
   SafeDisable( oEdSenhaConf )

   SetBtnEnabled( oBtnInclui,   .T. )
   SetBtnEnabled( oBtnAltera,   lTemReg )
   SetBtnEnabled( oBtnExcluir,  lTemReg )
   SetBtnEnabled( oBtnSalvar,   .F. )
   SetBtnEnabled( oBtnCancelar, .F. )
   SetBtnEnabled( oBtnSair,     .T. )

   DbSelectArea( nOld )

   SetTabPage( oTab, 1 )

RETURN NIL


STATIC FUNCTION Habilitar( cModo )

   LOCAL nOld := Select()

   DbSelectArea( "PSW" )

   __PSW_GARANTE_ORDEM()

   IF cModo == "editar" .AND. ( PSW->( LastRec() ) <= 0 .OR. PSW->( EOF() ) )
      DbSelectArea( nOld )
      RETURN NIL
   ENDIF

   IF cModo == "editar" .AND. Upper(AllTrim(PSW->USUARIO)) == "CONTROLE"
      DbSelectArea( nOld )
      hwg_MsgStop( "El usuario del sistema no puede ser modificado.", "Atención" )
      RETURN NIL
   ENDIF

   g_cModo  := cModo
   g_nRecno := IIF( PSW->( LastRec() ) > 0 .AND. !PSW->( EOF() ), PSW->( RecNo() ), 0 )
   
   oTab:Page(1):Disable()

   cSenhaOldForm  := ""
   cSenhaNewForm  := ""
   cSenhaConfForm := ""

   SafeSetText( oEdSenhaOld,  "" )  ; SafeRefresh( oEdSenhaOld )
   SafeSetText( oEdSenhaNew,  "" )  ; SafeRefresh( oEdSenhaNew )
   SafeSetText( oEdSenhaConf, "" )  ; SafeRefresh( oEdSenhaConf )

   SafeEnable( oEdUsuario )

   ForceGetPassword( oEdSenhaOld,  "*", 10 )
   ForceGetPassword( oEdSenhaNew,  "*", 10 )
   ForceGetPassword( oEdSenhaConf, "*", 10 )

   IF cModo == "novo"

      g_cUsuOrig := ""

      SafeDisable( oEdSenhaOld )
      SafeEnable(  oEdSenhaNew )
      SafeEnable(  oEdSenhaConf )

      cUsuarioForm := ""

      SafeSetText( oEdUsuario, cUsuarioForm )
      SafeRefresh( oEdUsuario )

   ELSE

      g_cUsuOrig := Upper( AllTrim( PSW->USUARIO ) )

      SafeEnable( oEdSenhaOld )
      SafeEnable( oEdSenhaNew )
      SafeEnable( oEdSenhaConf )

      cUsuarioForm := PSW->USUARIO

      SafeSetText( oEdUsuario, cUsuarioForm )
      SafeRefresh( oEdUsuario )

   ENDIF

   SetTabPage( oTab, 2 )
   SafeSetFocus( oEdUsuario )

   SetBtnEnabled( oBtnInclui,   .F. )
   SetBtnEnabled( oBtnAltera,   .F. )
   SetBtnEnabled( oBtnExcluir,  .F. )
   SetBtnEnabled( oBtnSalvar,   .T. )
   SetBtnEnabled( oBtnCancelar, .T. )
   SetBtnEnabled( oBtnSair,     .F. )

   DbSelectArea( nOld )

RETURN NIL


STATIC FUNCTION Gravar( cAcao )

   LOCAL nOld := Select()
   LOCAL cUsu, cOld, cNew, cConf
   LOCAL nRecSalvo := 0

   DbSelectArea( "PSW" )

   __PSW_GARANTE_ORDEM()

   IF cAcao == "cancelar"

      IF g_nRecno > 0 .AND. PSW->( LastRec() ) > 0
         PSW->( DbGoTo( g_nRecno ) )
      ELSEIF PSW->( LastRec() ) > 0
         PSW->( DbGoTop() )
      ENDIF

      BrwFiltroBasePSW( PSW->( RecNo() ) )

      DbSelectArea( nOld )

      g_cModo := "view"

      AtualizaTela()
      oBrw:Refresh()
      SetInitialFocus( oBrw )

      RETURN NIL
   ENDIF

   cUsu  := Upper( AllTrim( cUsuarioForm ) )
   cOld  := AllTrim( cSenhaOldForm )
   cNew  := AllTrim( cSenhaNewForm )
   cConf := AllTrim( cSenhaConfForm )

   IF " " $ cUsu
      DbSelectArea( nOld )
      hwg_MsgStop( "El usuario no puede contener espacios.", "Error" )
      SafeSetFocus( oEdUsuario )
      RETURN NIL
   ENDIF

   IF Empty( cUsu )
      DbSelectArea( nOld )
      hwg_MsgStop( "El usuario no puede quedar vacío.", "Error" )
      SafeSetFocus( oEdUsuario )
      RETURN NIL
   ENDIF

   IF cUsu == "CONTROLE"
      DbSelectArea( nOld )
      hwg_MsgStop( "El usuario CONTROLE está reservado para el sistema.", "Atención" )
      SafeSetFocus( oEdUsuario )
      RETURN NIL
   ENDIF

   // SENHA
   IF g_cModo == "novo"

      IF Empty( cNew )
         DbSelectArea( nOld )
         hwg_MsgStop( "La contraseña no puede quedar vacía.", "Error" )
         SafeSetFocus( oEdSenhaNew )
         RETURN NIL
      ENDIF

      IF Empty( cConf )
         DbSelectArea( nOld )
         hwg_MsgStop( "Confirme la contraseña.", "Error" )
         SafeSetFocus( oEdSenhaConf )
         RETURN NIL
      ENDIF

      IF cNew <> cConf
         DbSelectArea( nOld )
         hwg_MsgStop( "Las contraseñas no coinciden.", "Error" )
         cSenhaConfForm := ""
         SafeSetText( oEdSenhaConf, "" )
         SafeRefresh( oEdSenhaConf )
         SafeSetFocus( oEdSenhaConf )
         RETURN NIL
      ENDIF

   ELSEIF g_cModo == "editar"

      IF ! Empty( cOld ) .OR. ! Empty( cNew ) .OR. ! Empty( cConf )

         IF Empty( cOld )
            DbSelectArea( nOld )
            hwg_MsgStop( "Informe la contraseña anterior.", "Error" )
            SafeSetFocus( oEdSenhaOld )
            RETURN NIL
         ENDIF

         IF Empty( cNew )
            DbSelectArea( nOld )
            hwg_MsgStop( "Informe la nueva contraseña.", "Error" )
            SafeSetFocus( oEdSenhaNew )
            RETURN NIL
         ENDIF

         IF Empty( cConf )
            DbSelectArea( nOld )
            hwg_MsgStop( "Confirme la nueva contraseña.", "Error" )
            SafeSetFocus( oEdSenhaConf )
            RETURN NIL
         ENDIF

         IF cNew <> cConf
            DbSelectArea( nOld )
            hwg_MsgStop( "Las contraseñas no coinciden.", "Error" )
            cSenhaConfForm := ""
            SafeSetText( oEdSenhaConf, "" )
            SafeRefresh( oEdSenhaConf )
            SafeSetFocus( oEdSenhaConf )
            RETURN NIL
         ENDIF

         IF Empty( g_cUsuOrig )
            g_cUsuOrig := Upper( AllTrim( PSW->USUARIO ) )
         ENDIF

         IF ! PswCheck( g_cUsuOrig, cOld, PSW->SENHA )
            DbSelectArea( nOld )
            hwg_MsgStop( "Contraseña anterior inválida.", "Error" )
            cSenhaOldForm := ""
            SafeSetText( oEdSenhaOld, "" )
            SafeRefresh( oEdSenhaOld )
            SafeSetFocus( oEdSenhaOld )
            RETURN NIL
         ENDIF

      ENDIF

   ENDIF

   // duplicidade (usa ordem correta)
   IF UsuarioDuplicadoPSW( cUsu, IIF( g_cModo == "editar", g_nRecno, 0 ) )
      hwg_MsgStop( "Ya existe un usuario con ese nombre.", "Atención" )
      SafeSetFocus( oEdUsuario )
      DbSelectArea( nOld )
      RETURN NIL
   ENDIF

   // Gravação
   IF g_cModo == "novo"

      PSW->( DbAppend() )

      IF ! RLOCK()
         PSW->( DbDelete() )
         DbSelectArea( nOld )
         RETURN NIL
      ENDIF

      PSW->USUARIO := PadR( cUsu, Len( PSW->USUARIO ) )
      PSW->SENHA   := PswHash( cUsu, cNew, Len( PSW->SENHA ) )

      nRecSalvo := PSW->( RecNo() )
      g_nRecno := nRecSalvo

      DBUNLOCK()

   ELSE

      IF g_nRecno > 0
         PSW->( DbGoTo( g_nRecno ) )
      ENDIF

      IF ! RLOCK()
         DbSelectArea( nOld )
         RETURN NIL
      ENDIF

      PSW->USUARIO := PadR( cUsu, Len( PSW->USUARIO ) )

      IF ! Empty( cOld ) .OR. ! Empty( cNew ) .OR. ! Empty( cConf )
         PSW->SENHA := PswHash( cUsu, cNew, Len( PSW->SENHA ) )
      ENDIF

      nRecSalvo := PSW->( RecNo() )
      g_nRecno := nRecSalvo

      DBUNLOCK()

   ENDIF

   PSW->( dbCommit() )
   PSW->( dbCommitAll() )

   BrwFiltroBasePSW( nRecSalvo )

   DbSelectArea( nOld )

   g_cModo := "view"
   AtualizaTela()

   oBrw:Refresh()
   SetInitialFocus( oBrw )

RETURN NIL


STATIC FUNCTION ExcluirRegistro()

   LOCAL nOld := Select()
   LOCAL nRecAtual := 0
   LOCAL cKeyAtual := ""
   LOCAL lDel := .F.

   DbSelectArea( "PSW" )

   __PSW_GARANTE_ORDEM()

   IF PSW->( LastRec() ) <= 0 .OR. PSW->( EOF() )
      DbSelectArea( nOld )
      RETURN NIL
   ENDIF

   IF Upper( AllTrim( PSW->USUARIO ) ) == "CONTROLE"
      DbSelectArea( nOld )
      hwg_MsgStop( "El usuario del sistema no puede ser eliminado.", "Atención" )
      RETURN NIL
   ENDIF

   nRecAtual := PSW->( RecNo() )
   cKeyAtual := PSW->USUARIO

   IF hwg_MsgYesNo( "¿Desea eliminar este usuario?", "Confirmar" )

      IF RLOCK()
         DBDELETE()
         DBUNLOCK()

         PSW->( dbCommit() )
         PSW->( dbCommitAll() )

         lDel := .T.
      ENDIF

   ENDIF

   BrwFiltroBasePSW( PSW->( RecNo() ) )

   IF PSW->( LastRec() ) > 0

      __PSW_GARANTE_ORDEM()

      IF ! Empty( cKeyAtual )
         DBSEEK( cKeyAtual, .T. )
      ENDIF

      IF ! lDel
         IF nRecAtual > 0 .AND. PSW->( LastRec() ) >= nRecAtual
            PSW->( DbGoTo( nRecAtual ) )
         ENDIF
      ENDIF

      IF PSW->( EOF() )
         PSW->( DbGoBottom() )
      ENDIF

   ENDIF

   DbSelectArea( nOld )

   AtualizaTela()
   oBrw:Refresh()

RETURN NIL


FUNCTION PesquisaUsuarios( cFiltro, oBrw )

   LOCAL cQuery := "", cParte := "", nParte := 0, aList
   STATIC nIndiceOriginal := 0
   LOCAL nOld := Select()

   DbSelectArea( "PSW" )

   __PSW_GARANTE_ORDEM()

   IF ! Empty( AllTrim( cFiltro ) )

      IF nIndiceOriginal == 0
         nIndiceOriginal := PSW->( OrdNumber() )
      ENDIF

      aList := hb_RegExSplit( " ", AllTrim( cFiltro ) )

      FOR EACH cParte IN aList
         cParte := AllTrim( cParte )
         IF Empty( cParte )
            LOOP
         ENDIF

         IF ++nParte > 1
            cQuery += " .AND. "
         ENDIF

         cQuery += " ( '" + Upper( cParte ) + "' $ Upper(USUARIO) )"
      NEXT

      IF ! Empty( cQuery )
         cQuery := "(" + cQuery + ") .AND. Upper(AllTrim(USUARIO)) <> 'CONTROLE'"
      ELSE
         cQuery := "Upper(AllTrim(USUARIO)) <> 'CONTROLE'"
      ENDIF

      IF PSW->( OrdNumber( "TMPFILTRO_PSW" ) ) > 0
         PSW->( OrdDestroy( "TMPFILTRO_PSW" ) )
      ENDIF

      INDEX ON USUARIO TAG TMPFILTRO_PSW FOR &cQuery TEMPORARY

   ELSE
      BrwLimpaPesquisaPSW( oBrw )
      DbSelectArea( nOld )
      RETURN .T.
   ENDIF

   PSW->( DbGoTop() )
   oBrw:Refresh()

   DbSelectArea( nOld )

RETURN .T.


STATIC FUNCTION ValidUsuario()

   LOCAL cU := AllTrim( cUsuarioForm )

   IF Empty( cU )
      RETURN .F.
   ENDIF

   IF " " $ cU
      hwg_MsgStop( "El usuario no puede contener espacios.", "Error" )
      cUsuarioForm := StrTran( cU, " ", "" )
      SafeSetText( oEdUsuario, cUsuarioForm )
      SafeRefresh( oEdUsuario )
      SafeSetFocus( oEdUsuario )
      RETURN .F.
   ENDIF

RETURN .T.


STATIC FUNCTION UsuarioDuplicadoPSW( cUsu, nRecAtual )

   LOCAL nOldSel := Select()
   LOCAL nOldOrd := 0
   LOCAL lDup    := .F.
   LOCAL cKey    := Upper( AllTrim( cUsu ) )
   LOCAL nLenUser := 10

   IF Empty( cKey )
      RETURN .F.
   ENDIF

   DbSelectArea( "PSW" )

   BEGIN SEQUENCE
      nOldOrd := PSW->( OrdNumber() )
   RECOVER
      nOldOrd := 0
   END SEQUENCE

   BEGIN SEQUENCE
      nLenUser := FieldLen( "USUARIO" )
   RECOVER
      nLenUser := 10
   END SEQUENCE
   IF nLenUser <= 0
      nLenUser := 10
   ENDIF

   __PSW_GARANTE_ORDEM()

   IF PSW->( DBSEEK( PadR( cKey, nLenUser ), .T. ) )
      IF Upper( AllTrim( PSW->USUARIO ) ) == cKey
         IF PSW->( RecNo() ) <> nRecAtual
            lDup := .T.
         ENDIF
      ENDIF
   ENDIF

   IF nOldOrd > 0
      BEGIN SEQUENCE
         PSW->( OrdSetFocus( nOldOrd ) )
      RECOVER
      END SEQUENCE
   ENDIF

   DbSelectArea( nOldSel )

RETURN lDup


STATIC FUNCTION BrwFiltroBasePSW( nRecPos )

   Hb_Default( @nRecPos, 0 )

   IF nRecPos <= 0
      nRecPos := PSW->( RecNo() )
   ENDIF

   IF PSW->( OrdNumber( "TMP_NO_CONTROLE" ) ) > 0
      PSW->( OrdDestroy( "TMP_NO_CONTROLE" ) )
   ENDIF

   INDEX ON USUARIO TAG TMP_NO_CONTROLE ;
      FOR Upper( AllTrim( USUARIO ) ) <> "CONTROLE" TEMPORARY

   BEGIN SEQUENCE
      SET ORDER TO TAG TMP_NO_CONTROLE
   RECOVER
   END SEQUENCE

   IF nRecPos > 0 .AND. PSW->( LastRec() ) >= nRecPos
      PSW->( DbGoTo( nRecPos ) )
   ENDIF

   IF PSW->( EOF() ) .AND. PSW->( LastRec() ) > 0
      PSW->( DbGoBottom() )
   ENDIF

RETURN NIL


STATIC FUNCTION BrwLimpaPesquisaPSW( oBrw )

   IF PSW->( OrdNumber( "TMPFILTRO_PSW" ) ) > 0
      PSW->( OrdDestroy( "TMPFILTRO_PSW" ) )
   ENDIF

   BrwFiltroBasePSW( PSW->( RecNo() ) )
   oBrw:Refresh()

RETURN NIL


// =====================================================
// Garantia central de ORDER p/ evitar LETO/1201
// =====================================================
STATIC FUNCTION __PSW_GARANTE_ORDEM()

   IF ! Used( "PSW" )
      ensurePSW_LETO()
      RETURN NIL
   ENDIF

   BEGIN SEQUENCE
      SET ORDER TO TAG pswcx_01
   RECOVER
      EnsurePSW_LETO()
      BEGIN SEQUENCE
         SET ORDER TO TAG pswcx_01
      RECOVER
      END SEQUENCE
   END SEQUENCE

RETURN NIL


FUNCTION SETDLGKEY( hDlg, nKey, bAction )
   HB_SYMBOL_UNUSED( hDlg )
   HB_SYMBOL_UNUSED( nKey )
   HB_SYMBOL_UNUSED( bAction )
RETURN .F.


FUNCTION CRIAUSUARIOPADRAOPSW()

   LOCAL nOldArea := Select()
   LOCAL nOldRec  := 0
   LOCAL nOldOrd  := 0
   LOCAL lOk      := .T.

   LOCAL cUsuPadrao   := "CONTROLE"
   LOCAL cSenhaPadrao := "CTRL"
   LOCAL cHashNovo
   LOCAL nLenUser := 10

   IF ! Used( "PSW" )
      RETURN .F.
   ENDIF

   DbSelectArea( "PSW" )

   BEGIN SEQUENCE
      nLenUser := FieldLen( "USUARIO" )
   RECOVER
      nLenUser := 10
   END SEQUENCE
   IF nLenUser <= 0
      nLenUser := 10
   ENDIF

   nOldRec := PSW->( RecNo() )
   BEGIN SEQUENCE
      nOldOrd := OrdNumber()
   RECOVER
      nOldOrd := 0
   END SEQUENCE

   __PSW_GARANTE_ORDEM()

   cHashNovo := PswHash( cUsuPadrao, cSenhaPadrao, Len( PSW->SENHA ) )

   IF ! DBSEEK( PadR( cUsuPadrao, nLenUser ), .T. )

      PSW->( DbAppend() )

      IF RLOCK()
         PSW->USUARIO := PadR( cUsuPadrao, Len( PSW->USUARIO ) )
         PSW->SENHA   := cHashNovo
         DBUNLOCK()

         PSW->( dbCommit() )
         PSW->( dbCommitAll() )
      ELSE
         lOk := .F.
      ENDIF

   ELSE

      IF AllTrim( PSW->SENHA ) <> AllTrim( cHashNovo )

         IF RLOCK()
            PSW->SENHA := cHashNovo
            DBUNLOCK()

            PSW->( dbCommit() )
            PSW->( dbCommitAll() )
         ELSE
            lOk := .F.
         ENDIF

      ENDIF

   ENDIF

   IF nOldRec > 0
      PSW->( DbGoTo( nOldRec ) )
   ENDIF

   IF nOldOrd > 0
      BEGIN SEQUENCE
         OrdSetFocus( nOldOrd )
      RECOVER
      END SEQUENCE
   ENDIF

   DbSelectArea( nOldArea )

RETURN lOk


FUNCTION TELA_LOGIN( oMainWnd )

   LOCAL oLoginWnd, oBmp
   LOCAL oGetUsuario, oGetSenha
   LOCAL oBtnEntrar, oBtnCancelar
   LOCAL oPhantom
   LOCAL cPhantom := ""

   LOCAL nLenUser := 10
   LOCAL cUsuario := ""
   LOCAL cSenha   := ""
   LOCAL lOK      := .F.

   HB_SYMBOL_UNUSED( oMainWnd )
   HB_SYMBOL_UNUSED( cPhantom )

   BEGIN SEQUENCE
      nLenUser := FieldLen( "USUARIO" )
   RECOVER
      nLenUser := 10
   END SEQUENCE
   IF nLenUser <= 0
      nLenUser := 10
   ENDIF

   cUsuario := PadR( ULTIMOUSUARIO_GET(), nLenUser )

   INIT DIALOG oLoginWnd ;
      TITLE "Inicio de sesión" ;
      AT 0,0 ;
      SIZE 351, 190 ;
      FONT oFontPSW ;
      STYLE WS_POPUP + WS_CAPTION + WS_SYSMENU + DS_CENTER ;
      CLIPPER NOEXIT

   BEGIN SEQUENCE
      oBmp := HBitmap():AddFile( "lock.bmp" )
      @ 20, 20 BITMAP oBmp OF oLoginWnd SIZE 72, 87 TRANSPARENT
   RECOVER
   END SEQUENCE

   @ 110, 20 SAY "Nombre de usuario" OF oLoginWnd SIZE 200, 15 TRANSPARENT

   @ 110, 40 GET oGetUsuario VAR cUsuario PICTURE "@!" ;
      SIZE 200, 20 MAXLENGTH nLenUser OF oLoginWnd ;
      VALID {|| ;
         IF( hwg_GetFocus() == oBtnCancelar:handle, .T., ;
            IF( EMPTY( ALLTRIM( cUsuario ) ), ;
               ( oGetUsuario:SetFocus(), .F. ), ;
               ( oGetSenha:SetFocus(), .T. ) ) ) }

   @ 110, 70 SAY "Contraseña" OF oLoginWnd SIZE 150, 15 TRANSPARENT

   @ 110, 90 GET oGetSenha VAR cSenha ;
   PASSWORD;
      SIZE 150, 20 OF oLoginWnd ;
      VALID {|| ;
         IF( hwg_GetFocus() == oBtnCancelar:handle, .T., ;
            ( ;
              IF( __objHasMsg( oBtnEntrar, "bClick" ) .AND. ;
                  ValType( oBtnEntrar:bClick ) == "B", ;
                  Eval( oBtnEntrar:bClick ), ;
                  NIL ), ;
              .T. ) ) }

   oPhantom := AddPhantomGet( oLoginWnd )
   HB_SYMBOL_UNUSED( oPhantom )

   @ 60, 140 BUTTON oBtnEntrar CAPTION "Ingresar" SIZE 100, 28 OF oLoginWnd ;
      ON CLICK {|| ;
         IF( VER_SENHA( ALLTRIM( cUsuario ), ALLTRIM( cSenha ), oMainWnd ), ;
            ( LOG_ACESSO_SISTEMA( ALLTRIM( cUsuario ) ), ;
              lOK := .T., ;
              hwg_EndDialog( oLoginWnd:handle ), ;
              .T. ), ;
            ( hwg_MsgStop( "Usuario o contraseña inválidos.", "Inicio de sesión" ), ;
              cSenha := "", ;
              SafeSetText( oGetSenha, "" ), ;
              SafeRefresh( oGetSenha ), ;
              SelTextoGet( oGetUsuario, cUsuario, .T. ), ;
              .F. ) ) }

   @ 190, 140 BUTTON oBtnCancelar CAPTION "Cancelar" SIZE 100, 28 OF oLoginWnd ;
      ON CLICK {|| lOK := .F., hwg_EndDialog( oLoginWnd:handle ), .T. }

   oLoginWnd:bInit := {|| ;
      cSenha := "", ;
      SafeSetText( oGetSenha, "" ), ;
      SafeRefresh( oGetSenha ), ;
      ArmGetSenha( oGetSenha ), ;
      SelTextoGet( oGetUsuario, @cUsuario, .T. ) }

   ACTIVATE DIALOG oLoginWnd CENTER

RETURN lOK


FUNCTION ULTIMOUSUARIO_GET()

   LOCAL cFile := hb_DirBase() + "lastuser.ini"
   LOCAL cUser := ""

   IF hb_FileExists( cFile )
      cUser := AllTrim( MemoRead( cFile ) )
   ENDIF

RETURN Upper( cUser )


FUNCTION ULTIMOUSUARIO_SET( cUser )

   LOCAL cFile := hb_DirBase() + "lastuser.ini"
   LOCAL cOut  := Upper( AllTrim( cUser ) )

   IF Empty( cOut )
      RETURN .F.
   ENDIF

   MemoWrit( cFile, cOut )

RETURN .T.


FUNCTION VER_SENHA( cUsuario, cSenha, oMainWnd )

   LOCAL cNome     := Upper( AllTrim( cUsuario ) )
   LOCAL cPass     := AllTrim( cSenha )
   LOCAL lOk       := .F.
   LOCAL nOldSel   := Select()
   LOCAL nOldRec   := 0
   LOCAL lOldSoft  := Set( _SET_SOFTSEEK )
   LOCAL nOldOrd   := 0
   LOCAL nLenUser  := 10
   LOCAL cKeySeek  := ""

   HB_SYMBOL_UNUSED( oMainWnd )

   IF Empty( cNome ) .OR. Empty( cPass )
      RETURN .F.
   ENDIF

   IF ! Used( "PSW" )
      hwg_MsgStop( "El archivo PSW no está abierto.", "Inicio de sesión" )
      RETURN .F.
   ENDIF

   DbSelectArea( "PSW" )

   nOldRec := IIF( RecCount() > 0, RecNo(), 0 )

   BEGIN SEQUENCE
      nOldOrd := OrdNumber()
   RECOVER
      nOldOrd := 0
   END SEQUENCE

   BEGIN SEQUENCE
      nLenUser := FieldLen( "USUARIO" )
   RECOVER
      nLenUser := 10
   END SEQUENCE
   IF nLenUser <= 0
      nLenUser := 10
   ENDIF

   cKeySeek := PadR( cNome, nLenUser )

   BEGIN SEQUENCE

      // GARANTE ORDEM ANTES DO DBSEEK (resolve LETO/1201)
      __PSW_GARANTE_ORDEM()

      SET SOFTSEEK OFF

      IF ! DBSEEK( cKeySeek, .F. )
         BREAK
      ENDIF

      IF ! Found()
         BREAK
      ENDIF

      IF PadR( Upper( AllTrim( PSW->USUARIO ) ), nLenUser ) <> cKeySeek
         BREAK
      ENDIF

      IF PswCheck( cNome, cPass, PSW->SENHA )
         lOk := .T.
         g_cOperador := RTrim( PSW->USUARIO )
         g_nPswRec   := RecNo()
         ULTIMOUSUARIO_SET( cNome )
      ENDIF

   END SEQUENCE

   IF lOldSoft
      SET SOFTSEEK ON
   ELSE
      SET SOFTSEEK OFF
   ENDIF

   IF nOldRec > 0 .AND. nOldRec <= RecCount()
      DbGoTo( nOldRec )
   ENDIF

   BEGIN SEQUENCE
      IF nOldOrd > 0
         OrdSetFocus( nOldOrd )
      ENDIF
   RECOVER
   END SEQUENCE

   DbSelectArea( nOldSel )

RETURN lOk


FUNCTION log_acesso_sistema( cUsuario )

   LOCAL nOldSel := Select()

   cUsuario := Upper( AllTrim( cUsuario ) )
   IF Empty( cUsuario )
      RETURN .F.
   ENDIF

   IF ! Used( "LOG" )
      DbSelectArea( nOldSel )
      RETURN .F.
   ENDIF

   DbSelectArea( "LOG" )

   BEGIN SEQUENCE

      ADIC_REG()

      IF ! Bloq_reg()
         BREAK
      ENDIF

      REPLACE cd_data    WITH Date(), ;
              cc_time    WITH Time(), ;
              cc_usuario WITH cUsuario, ;
              cc_operac  WITH "Acessou o Sistema"

      DBCOMMIT()
      UNLOCK

   END SEQUENCE

   DbSelectArea( nOldSel )

RETURN .T.


// =====================================================
// ---------------- STUBS / HELPERS --------------------
// =====================================================

// =====================================================
// AddPhantomGet()
// Cria um GET fantasma (0,0 tamanho 0) para destravar ENTER
// no "último GET" (ex: campo Buscar).
// Retorna o objeto GET.
// =====================================================
FUNCTION AddPhantomGet( oOwner )

   LOCAL oPhantom
   LOCAL cPhantom := ""

   IF ValType( oOwner ) <> "O"
      RETURN NIL
   ENDIF

   // OF pode ser oTab (page) ou oDlg — use o mesmo "OF" do seu GET
   @ 0,0 GET oPhantom VAR cPhantom SIZE 0,0 OF oOwner

   RETURN oPhantom

// =====================================================
// Foco inicial genérico (ideal para usar no ON INIT)
// Prioridade: lInfocus -> SetFocus() -> hwg_SetFocus(handle)
// =====================================================
FUNCTION SetInitialFocus( oCtrl )

   IF ValType( oCtrl ) <> "O"
      RETURN .F.
   ENDIF

   // 1) HWGUI (muito estável no ON INIT)
   IF __objHasMsg( oCtrl, "lInfocus" )
      oCtrl:lInfocus := .T.
      RETURN .T.
   ENDIF

   // 2) Método SetFocus
   IF __objHasMethod( oCtrl, "SetFocus" )
      oCtrl:SetFocus()
      RETURN .T.
   ENDIF

   // 3) Fallback pelo handle
   IF __objHasMsg( oCtrl, "handle" ) .AND. ! Empty( oCtrl:handle )
      hwg_SetFocus( oCtrl:handle )
      RETURN .T.
   ENDIF

RETURN .F.

// =====================================================
// Troca aba do TAB (compatível com HWGUI antigas e novas)
// Uso: SetTabPage( oTab, 1 )
// =====================================================
FUNCTION SetTabPage( oTb, nPage )

   #ifndef TCM_SETCURSEL
      #define TCM_SETCURSEL 0x130C
   #endif

   IF ValType( oTb ) <> "O"
      RETURN NIL
   ENDIF

   // Algumas builds possuem DATA nTab
   IF __objHasMsg( oTb, "nTab" )
      oTb:nTab := nPage
      RETURN NIL
   ENDIF

   // Outras usam método SetTab()
   IF __objHasMethod( oTb, "SetTab" )
      oTb:SetTab( nPage )
      RETURN NIL
   ENDIF

   // Outras usam método SetPage()
   IF __objHasMethod( oTb, "SetPage" )
      oTb:SetPage( nPage )
      RETURN NIL
   ENDIF

   // Fallback WinAPI (funciona sempre)
   IF __objHasMsg( oTb, "handle" ) .AND. ! Empty( oTb:handle )
      hwg_SendMessage( oTb:handle, TCM_SETCURSEL, nPage - 1, 0 )
      hwg_InvalidateRect( oTb:handle, 0, .T. )
   ENDIF

RETURN NIL

// ===============================
// Habilita/Desabilita OWNERBUTTON com cor diferente
// ===============================
FUNCTION SetBtnEnabled( oBtn, lEnable )

   IF ValType( oBtn ) <> "O"
      RETURN NIL
   ENDIF

   IF lEnable
      oBtn:Enable()

      // Use SetHStyles (plural) - mais compatível
      IF __objHasMethod( oBtn, "SetHStyles" )
         oBtn:SetHStyles( oStyleNormal, oStylePressed, oStyleOver )
      ENDIF

   ELSE
      oBtn:Disable()

      // Para “desabilitado”, repete o mesmo estilo nas 3 posições
      IF __objHasMethod( oBtn, "SetHStyles" )
         oBtn:SetHStyles( oStyleDisabled, oStyleDisabled, oStyleDisabled )
      ENDIF

   ENDIF

   oBtn:Refresh()

RETURN NIL	



#define EM_SETPASSWORDCHAR   0x00CC
#define EM_LIMITTEXT         0x00C5

FUNCTION ForceGetPassword( oGet, cMaskChar, nMax )

   LOCAL hEd
   LOCAL nChar

   IF ValType( oGet ) <> "O" .OR. Empty( oGet:handle )
      RETURN .F.
   ENDIF

   hEd := oGet:handle

   IF ValType( cMaskChar ) <> "C" .OR. Empty( cMaskChar )
      cMaskChar := "*"
   ENDIF
   nChar := Asc( Left( cMaskChar, 1 ) )

   IF ValType( nMax ) <> "N" .OR. nMax <= 0
      nMax := 15
   ENDIF

   hwg_SendMessage( hEd, EM_LIMITTEXT, nMax, 0 )
   hwg_SendMessage( hEd, EM_SETPASSWORDCHAR, nChar, 0 )

   oGet:SetText( "" )
   oGet:Refresh()

RETURN .T.

// Wrapper opcional (pra ficar padrão no sistema)
FUNCTION ArmGetSenha( oGet )
   RETURN ForceGetPassword( oGet, "*", 15 )


//---------------------------------------------------//
FUNCTION SelTextoGet( oGet, cTexto, lSetFocus )
//---------------------------------------------------//
   LOCAL hEd, nLen

   Hb_Default( @lSetFocus, .T. )

   IF ValType( oGet ) <> "O"
      RETURN .F.
   ENDIF

   // Se não passar cTexto, tenta pegar do próprio controle
   IF ValType( cTexto ) <> "C"
      BEGIN SEQUENCE
         cTexto := oGet:GetText()
      RECOVER
         cTexto := ""
      END SEQUENCE
   ENDIF

   nLen := Len( RTrim( cTexto ) )

   IF lSetFocus
      oGet:SetFocus()
   ENDIF

   hEd := oGet:handle
   IF Empty( hEd )
      RETURN .F.
   ENDIF

   // Seleciona somente o que tem texto (sem área vazia)
   hwg_SendMessage( hEd, EM_SETSEL, 0, nLen )

   RETURN .T.



STATIC FUNCTION safesettext( oObj, cTxt )
   IF ValType( oObj ) == "O"
      BEGIN SEQUENCE
         oObj:SetText( cTxt )
      RECOVER
      END SEQUENCE
   ENDIF
RETURN NIL

STATIC FUNCTION SafeRefresh( oObj )
   IF ValType( oObj ) == "O"
      BEGIN SEQUENCE
         oObj:Refresh()
      RECOVER
      END SEQUENCE
   ENDIF
RETURN NIL

STATIC FUNCTION SafeSetFocus( oObj )
   IF ValType( oObj ) == "O"
      BEGIN SEQUENCE
         oObj:SetFocus()
      RECOVER
      END SEQUENCE
   ENDIF
RETURN NIL

STATIC FUNCTION SafeEnable( oObj )
   IF ValType( oObj ) == "O"
      BEGIN SEQUENCE
         oObj:Enable()
      RECOVER
         BEGIN SEQUENCE
            oObj:Enabled := .T.
         RECOVER
         END SEQUENCE
      END SEQUENCE
   ENDIF
RETURN NIL

STATIC FUNCTION SafeDisable( oObj )
   IF ValType( oObj ) == "O"
      BEGIN SEQUENCE
         oObj:Disable()
      RECOVER
         BEGIN SEQUENCE
            oObj:Enabled := .F.
         RECOVER
         END SEQUENCE
      END SEQUENCE
   ENDIF
RETURN NIL

STATIC FUNCTION Bloq_reg()
RETURN RLOCK()

STATIC FUNCTION ADIC_REG()
   DbAppend()
RETURN NIL


// =====================================================
// HASH SIMPLES (teste)
// =====================================================
FUNCTION PswHash( cUsu, cSenha, nLenCampo )
   LOCAL cBase := Upper(AllTrim(cUsu)) + ":" + AllTrim(cSenha)
   LOCAL nCrc  := hb_Crc32( cBase )
   LOCAL cOut  := StrZero( nCrc, 10 )
   Hb_Default( @nLenCampo, 10 )
   cOut := PadR( cOut, nLenCampo )
RETURN cOut

FUNCTION PswCheck( cUsu, cSenha, cHashDBF )
   LOCAL cCalc := PswHash( cUsu, cSenha, Len( cHashDBF ) )
RETURN ( AllTrim( cCalc ) == AllTrim( cHashDBF ) )

hwgui_linux.rar
hwgui_linux.rar
(5.07 MiB) Baixado 3 vezes
tela linux aba desativada.jpg
tela linux aba desativada.jpg
tela linux aba desativada.jpg (49.88 KiB) Exibido 25 vezes
tela windows aba desativada.jpg
tela windows aba desativada.jpg
tela windows aba desativada.jpg (54.62 KiB) Exibido 25 vezes
letodbf-1.tar.gz
leto dbf linux utilizando porta 2030
(2.89 MiB) Baixado 3 vezes
testem ai .. o comando é o mesmo para ambas plataformas ..

oTab:Page(1):Enable()

oTab:Page(1):Disable()
Saludos,
Deivid José de Souza
Windows 11 + Harbour 3.4 + MINGW64 gcc 14.1.0 + Visual Lib + GTWVG + LETODBF WINDOWNS/LINUX
hwgui 2.23 b8
Responder