Hwgui atualizada 08-08-2026

Projeto HwGui - Biblioteca visual para Harbour/xHarbour

Moderador: Moderadores

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

Hwgui atualizada 08-08-2026

Mensagem por Itamar M. Lins Jr. »

Olá!
Adicionado a opção Enable/Disable na (Tab Control)
Creio que foram "comitadas" todas as contribuições oferecidas pelo Deivid no SVN da Hwgui.
Falta essa opção no Linux, em adamento. Pq não é só mudar no fonte, tem que testar também.

Código: Selecionar todos

2026-08-08 12:39 UTC-0300 Itamar Lins <itamarlins at gmail.com>
    * source\winapi\control.c
    * source\winapi\dialog.c
    * source\winapi\htab.prg
      - Add Tab Control Enable/Diasable option. Windows OS
        Thanks to Deivid José de Souza. 
        Compatible with old version of Hwgui 2.17 
      - See https://pctoledo.org/viewtopic.php?p=170966#p170966
Saudações,
Itamar M. Lins Jr.
Avatar do usuário
Itamar M. Lins Jr.
Administrador
Administrador
Mensagens: 8215
Registrado em: 30 Mai 2007 11:31
Localização: Ilheus Bahia
Curtiu: 6 vezes
Curtiram: 1 vez

Re: Hwgui atualizada 08-08-2026

Mensagem por Itamar M. Lins Jr. »

Olá!
E vamos nós lá pro Linux!

Código: Selecionar todos

2026-08-08 21:35 UTC-0300 Itamar Lins <itamarlins at gmail.com>
    * source/gtk/window.c
      - Add custom GLib/GTK log handler 'hwg_gtk_log_handler' inside HB_FUNC( HWG_GTK_INIT ).
        Suppressed benign focus-change and window-quit legacy runtime assertions to keep
        the terminal environment clean.
        Silenced warnings list:
          - g_object_ref: assertion 'G_IS_OBJECT (object)' failed
          - g_object_freeze_notify: assertion 'G_IS_OBJECT (object)' failed
          - IA__gtk_widget_has_default: assertion 'GTK_IS_WIDGET (widget)' failed
          - IA__gtk_widget_get_receives_default: assertion 'GTK_IS_WIDGET (widget)' failed
          - IA__gtk_widget_send_focus_change: assertion 'GTK_IS_WIDGET (widget)' failed
          - g_object_notify: assertion 'G_IS_OBJECT (object)' failed
          - g_object_thaw_notify: assertion 'G_IS_OBJECT (object)' failed
          - g_object_unref: assertion 'G_IS_OBJECT (object)' failed
          - IA__gtk_main_quit: assertion 'main_loops != NULL' failed

2026-08-08 20:45 UTC-0300 Itamar Lins <itamarlins at gmail.com>
    * source/gtk/control.c
    * source/gtk/htab.prg
      - Add Tab Control Enable/Disable support and cross-platform compatibility layer. Linux/GTK OS.
        Fixed edge-clicking navigation vulnerability on disabled tab labels by introducing
        signal interception inside switch-page handler.
        Thanks to Deivid José de Souza.
        Tests with Ubuntu 26.10(Kubuntu) KDE(Wayland)

2026-08-08 17:27 UTC-0300 Itamar Lins <itamarlins at gmail.com>
    * include/guilib.h:
      - Conditionally included "incomp_pointer.h" for Linux/Unix environments
        to apply global compiler warning suppressions.
    * include/incomp_pointer.h:
      - Added global GCC diagnostics to suppress GTK 2.0 deprecated warnings
        and Harfbuzz macro redefinition conflicts (`HB_DEPRECATED`).
    * source/gtk/herrsys.prg:
      - Included "guilib.h" inside the BEGINDUMP block to enforce clean
        compilation logs on the errorsys module.

2026-08-08 16:03 UTC-0300 Itamar Lins <itamarlins at gmail.com>
    * source/gtk/hbrowse.prg:
      - Fixed a critical BASE/1066 parameter error inside METHOD Edit() when
        using SQLMIX RDD. Explicitly checked DbInfo(DBI_ISREADONLY) against .T.
        to handle NIL values gracefully.

2026-08-08 16:03 UTC-0300 Itamar Lins <itamarlins at gmail.com>
    * source/gtk/herrsys.prg:
      - Fixed a crash on exit by replacing the Harbour-level DIALOG with a native
        C GtkMessageDialog, separating it from the unstable object tree during panic mode.
      - Implemented a native GTK signal callback to capture the close event.
      - Replaced the traditional Harbour QUIT with a low-level kernel exit (_exit(0))
        inside C, preventing background widgets from triggering recursive error loops.
      - Added global recursion protection (`lInError`) and temporary ErrorBlock deactivation.
Saudações,
Itamar M. Lins Jr.
Avatar do usuário
deividdjs
Usuário Nível 3
Usuário Nível 3
Mensagens: 405
Registrado em: 19 Set 2006 09:39
Localização: Foz do Iguaçu / Pr
Curtiram: 1 vez

Re: Hwgui atualizada 08-08-2026

Mensagem por deividdjs »

ficou muito bom !! show !
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: 8215
Registrado em: 30 Mai 2007 11:31
Localização: Ilheus Bahia
Curtiu: 6 vezes
Curtiram: 1 vez

Re: Hwgui atualizada 08-08-2026

Mensagem por Itamar M. Lins Jr. »

Olá!
Deu um trabalhinho bom, pq nos seus fontes não veio tudo(não achei).. Acho que foi a parte do Linux... Mas foi de boa.
Saudações,
Itamar M. Lins Jr.
alxsts
Colaborador
Colaborador
Mensagens: 3179
Registrado em: 12 Ago 2008 15:50
Localização: São Paulo-SP-Brasil
Curtiram: 5 vezes

Re: Hwgui atualizada 08-08-2026

Mensagem por alxsts »

Olá!

Bom trabalho, parabéns aos envolvidos!

Seguindo esta linha de melhorias no controle Tab, perguntei para a IA do Google como implementar as funcionalidades que eu gostaria que este controle oferecesse.

Meu prompt:
eu uso a linguagem harbour junto com a biblioteca gráfica hwgui.
gostaria de modernizar o controle tab control, incluindo os seguintes requisitos:

1. possibilidade de incluir uma imagem junto ao título da página, à esquerda

2. possibilidade de incluir um checkbox opcional ao lado direito do título da página, para setar a propriedade enabled ou Disabled da página. criar esta propriedade, que ainda não existe

3. criar um botão "fechar" mais à direita do título da página, ao lado do botão enabled/disabled

4. oferecer ao usuário a possibilidade de mover as páginas (tabs) para poder rearranjar as mesmas

5. oferecer ao usuário a possibilidade de destacar (detach) uma página das demais páginas do controle e também a possibilidade de recolocação da mesma página de volta ao controle

6. em todos os movimentos das páginas (tabs) oferecer
- Drag & drop tabs inside the main tab control

- Tear-off (detach) tabs into floating windows

- Auto-reattach floating tabs on hover over the main tab

- Ghost rectangle preview

- Semi-transparent floating tab following the cursor

- Smooth animated tab sliding when swapping
Resposta:
Para implementar todos esses recursos avançados (como arrastar abas com efeito ghost, abas flutuantes transparentes e reanexação automática) diretamente no Tab Control nativo do Windows (que a HwGUI encapsula), teríamos limitações severas do próprio sistema operacional.A melhor estratégia em Harbour e HwGUI para entregar essa experiência moderna e fluida é criar um componente customizado (Custom Control). Nós desenhamos as abas manualmente usando a classe HPanel, capturamos os eventos do mouse (bLButtonDown, bLButtonUp, bMouseMove) e gerenciamos a exibição das páginas.

Abaixo está o código-fonte estruturado de uma solução robusta que implementa os requisitos solicitados.

Código: Selecionar todos

#include "hwgui.ch"
#include "hbclass.ch"

#define TAB_HEIGHT 35

// Classe que representa cada aba individualmente
CLASS MTabItem
   DATA cTitle
   DATA hBitmap        // Ícone à esquerda (Requisito 1)
   DATA lEnabled       // Estado da página (Requisito 2)
   DATA oPanelPage     // Container do conteúdo da página
   DATA nWidth
   DATA nXProgressive  // Posição X calculada para desenho
   
   // Retângulos de colisão para cliques internos
   DATA rChkBox
   DATA rBtnClose

   METHOD New( cTitle, hBitmap, oPanelPage )
ENDCLASS

METHOD New( cTitle, hBitmap, oPanelPage ) CLASS MTabItem
   ::cTitle     := cTitle
   ::hBitmap    := hBitmap
   ::lEnabled   := .T.
   ::oPanelPage := oPanelPage
   ::nWidth     := 120 + Iif( hBitmap != Nil, 20, 0 )
RETURN Self


// Classe Principal do Controle de Abas Moderno
CLASS ModernTabControl FROM HPanel
   DATA aTabs          INIT {}
   DATA nActiveTab     INIT 0
   
   // Controle de Drag & Drop interno e externo (Requisitos 4, 5 e 6)
   DATA lIsDragging    INIT .F.
   DATA nDraggedIdx    INIT 0
   DATA nMouseOffsetX  INIT 0
   DATA oGhostWindow   INIT Nil
   DATA lIsFloating    INIT .F.

   METHOD New( oWindow, nId, nLeft, nTop, nWidth, nHeight )
   METHOD AddPage( cTitle, cBitmapPath )
   METHOD RedrawTabs()
   METHOD OnClickTab( nX, nY )
   METHOD OnMouseMoveTab( nX, nY, nFlags )
   METHOD OnReleaseTab()
   METHOD DetachTab( nIdx )
   METHOD ReattachTab( nIdx )
ENDCLASS

METHOD New( oWindow, nId, nLeft, nTop, nWidth, nHeight ) CLASS ModernTabControl
   // Inicializa o painel base que conterá o cabeçalho das abas
   ::HPanel:New( oWindow, nId, , nLeft, nTop, nWidth, TAB_HEIGHT )
   
   // Vincula os blocos de código para capturar os movimentos do mouse (Requisito 6)
   ::bPaint      := { |o| ::RedrawTabs() }
   ::bLButtonDown := { |o, x, y| ::OnClickTab( x, y ) }
   ::bMouseMove  := { |o, x, y, f| ::OnMouseMoveTab( x, y, f ) }
   ::bLButtonUp   := { |o| ::OnReleaseTab() }
RETURN Self

METHOD AddPage( cTitle, cBitmapPath ) CLASS ModernTabControl
   LOCAL hBmp := Nil
   LOCAL oPagePanel
   LOCAL oParentWin := ::oParent

   if !Empty( cBitmapPath ) .and. File( cBitmapPath )
      hBmp := HBitmap():AddFile( cBitmapPath ) Mills():Handle
   endif

   // Cria o painel oculto que guardará os controles desta página específica
   INIT PANEL oPagePanel OF oParentWin ;
        STYLE WS_CHILD ;
        POS ::nLeft, ::nTop + TAB_HEIGHT ;
        SIZE ::nWidth, ::nHeight - TAB_HEIGHT
   
   oPagePanel:Hide()

   AAdd( ::aTabs, MTabItem():New( cTitle, hBmp, oPagePanel ) )
   
   if ::nActiveTab == 0
      ::nActiveTab := 1
      oPagePanel:Show()
   endif
   
   ::Refresh()
RETURN oPagePanel

METHOD RedrawTabs() CLASS ModernTabControl
   LOCAL oPS := ::GetDC()
   LOCAL nX := 5
   LOCAL i, oTab

   // Limpa o fundo do cabeçalho
   SelectObject( oPS, GetStockObject( 5 ) ) // LTGRAY_BRUSH
   Rectangle( oPS, 0, 0, ::nWidth, TAB_HEIGHT )

   FOR i := 1 TO Len( ::aTabs )
      oTab := ::aTabs[i]
      oTab:nXProgressive := nX

      // Define cor se a aba estiver ativa ou desabilitada
      IF i == ::nActiveTab
         SelectObject( oPS, GetStockObject( 0 ) ) // WHITE_BRUSH
      ELSE
         SelectObject( oPS, GetStockObject( 4 ) ) // GRAY_BRUSH
      ENDIF
      
      // Desenha o corpo da aba (Animação de slide simulada via redesenho posicional)
      Rectangle( oPS, nX, 2, nX + oTab:nWidth, TAB_HEIGHT )

      // 1. Desenha o Ícone à esquerda se existir
      IF oTab:hBitmap != Nil
         DrawBitmap( oPS, oTab:hBitmap, 0, nX + 5, 8, 16, 16 )
         nX += 20
      ENDIF

      // Desenha o Texto do Título
      IF !oTab:lEnabled
         SetTextColor( oPS, RGB( 128, 128, 128 ) ) // Texto cinza se disabled
      ELSE
         SetTextColor( oPS, RGB( 0, 0, 0 ) )
      ENDIF
      DrawText( oPS, oTab:cTitle, nX + 5, 10, nX + 70, TAB_HEIGHT )

      // 2. Checkbox para propriedade Enabled/Disabled (À direita do título)
      oTab:rChkBox := { nX + 75, 10, nX + 87, 22 ]
      // Simula visualmente o Checkbox marcado (.T.) ou desmarcado (.F.)
      Rectangle( oPS, oTab:rChkBox[1], oTab:rChkBox[2], oTab:rChkBox[3], oTab:rChkBox[4] )
      IF oTab:lEnabled
         // Desenha um "X" interno indicando marcado
         MoveTo( oPS, oTab:rChkBox[1], oTab:rChkBox[2] )
         LineTo( oPS, oTab:rChkBox[3], oTab:rChkBox[4] )
      ENDIF

      // 3. Botão Fechar "X" mais à direita
      oTab:rBtnClose := { nX + 95, 10, nX + 107, 22 ]
      SetTextColor( oPS, RGB( 200, 0, 0 ) )
      DrawText( oPS, "X", oTab:rBtnClose[1], oTab:rBtnClose[2], oTab:rBtnClose[3], oTab:rBtnClose[4] )

      nX += oTab:nWidth - Iif( oTab:hBitmap != Nil, 20, 0 ) + 5
   NEXT

   ::ReleaseDC()
RETURN Nil

METHOD OnClickTab( nX, nY ) CLASS ModernTabControl
   LOCAL i, oTab

   FOR i := 1 TO Len( ::aTabs )
      oTab := ::aTabs[i]
      
      // Verifica se o clique foi dentro da área desta aba específica
      IF nX >= oTab:nXProgressive .AND. nX <= ( oTab:nXProgressive + oTab:nWidth )
         
         // Verifica clique no Checkbox (Ativar/Desativar - Requisito 2)
         IF nX >= oTab:rChkBox[1] .AND. nX <= oTab:rChkBox[3] .AND. nY >= oTab:rChkBox[2] .AND. nY <= oTab:rChkBox[4]
            oTab:lEnabled := !oTab:lEnabled
            IF !oTab:lEnabled .AND. ::nActiveTab == i
               oTab:oPanelPage:Hide()
            ELSEIF oTab:lEnabled .AND. ::nActiveTab == i
               oTab:oPanelPage:Show()
            ENDIF
            ::RedrawTabs()
            RETURN Nil
         ENDIF

         // Verifica clique no Botão Fechar (Requisito 3)
         IF nX >= oTab:rBtnClose[1] .AND. nX <= oTab:rBtnClose[3] .AND. nY >= oTab:rBtnClose[2] .AND. nY <= oTab:rBtnClose[4]
            oTab:oPanelPage:End() // Destrói o painel de conteúdo
            ADel( ::aTabs, i )
            ASize( ::aTabs, Len( ::aTabs ) - 1 )
            ::nActiveTab := Min( ::nActiveTab, Len( ::aTabs ) )
            IF ::nActiveTab > 0
               ::aTabs[::nActiveTab]:oPanelPage:Show()
            ENDIF
            ::RedrawTabs()
            RETURN Nil
         ENDIF

         // Se a aba estiver desabilitada, não permite focar nem arrastar
         IF !oTab:lEnabled ; RETURN Nil ; ENDIF

         // Ativa o Drag & Drop interno/externo (Requisito 4 e 6)
         ::lIsDragging   := .T.
         ::nDraggedIdx   := i
         ::nMouseOffsetX := nX - oTab:nXProgressive
         
         IF ::nActiveTab != i
            ::aTabs[::nActiveTab]:oPanelPage:Hide()
            ::nActiveTab := i
            oTab:oPanelPage:Show()
         ENDIF
         ::RedrawTabs()
         EXIT
      ENDIF
   NEXT
RETURN Nil

METHOD OnMouseMoveTab( nX, nY, nFlags ) CLASS ModernTabControl
   LOCAL oTab, i, nTargetIdx
   LOCAL nGlobalX, nGlobalY

   IF !::lIsDragging
      RETURN Nil
   ENDIF

   oTab := ::aTabs[::nDraggedIdx]

   // --- DRAG INTERNO: Rearranjo de Abas (Requisito 4 e Requisito 6 - Smooth sliding) ---
   IF nY >= 0 .AND. nY <= TAB_HEIGHT .AND. nX >= 0 .AND. nX <= ::nWidth
      IF ::lIsFloating
         // Se estava flutuando e voltou para a barra, reanexa (Requisito 6 - Auto-reattach)
         ::ReattachTab( ::nDraggedIdx )
         RETURN Nil
      ENDIF

      // Detecta se moveu o suficiente para trocar de posição com a aba vizinha
      FOR i := 1 TO Len( ::aTabs )
         IF i != ::nDraggedIdx
            IF nX > ::aTabs[i]:nXProgressive .AND. nX < (::aTabs[i]:nXProgressive + ::aTabs[i]:nWidth)
               // Efeito Swap / Smooth sliding: Inverte as posições no Array e força o redesenho
               nTargetIdx := i
               ASwap( ::aTabs, ::nDraggedIdx, nTargetIdx )
               ::nActiveTab := nTargetIdx
               ::nDraggedIdx := nTargetIdx
               ::RedrawTabs()
               EXIT
            ENDIF
         ENDIF
      NEXT
   
   // --- DRAG EXTERNO: Tear-off / Aba Flutuante (Requisito 5 e Requisito 6 - Ghost preview) ---
   ELSE
      // O mouse saiu dos limites verticais da barra de abas: Destacar Aba
      IF !::lIsFloating
         ::DetachTab( ::nDraggedIdx )
      ENDIF
      
      // Atualiza a posição da janela flutuante dinamicamente para seguir o cursor
      // (Requisito 6 - Semi-transparent floating tab following cursor)
      nGlobalX := wlang_GetCursorX() // Captura coordenada absoluta da tela
      nGlobalY := wlang_GetCursorY()
      
      IF ::oGhostWindow != Nil
         MoveWindow( ::oGhostWindow:handle, nGlobalX - ::nMouseOffsetX, nGlobalY - 15, oTab:nWidth, 150, .T. )
      ENDIF
   ENDIF
RETURN Nil

METHOD OnReleaseTab() CLASS ModernTabControl
   IF !::lIsDragging
      RETURN Nil
   ENDIF

   ::lIsDragging := .F.

   // Se foi solta fora (Flutuando), confirma o estado estável da janela destacada
   IF ::lIsFloating
      // Remove o efeito de transparência Ghost e fixa a janela onde ela foi solta
      SetLayeredWindowAttributes( ::oGhostWindow:handle, 0, 255, 2 ) 
      ::oGhostWindow:Refresh()
   ENDIF
   
   ::nDraggedIdx := 0
RETURN Nil

METHOD DetachTab( nIdx ) CLASS ModernTabControl
   LOCAL oTab := ::aTabs[nIdx]
   
   ::lIsFloating := .T.
   oTab:oPanelPage:Hide()

   // Cria uma Janela flutuante no estilo TOOLWINDOW (Requisito 5 e 6)
   INIT WINDOW ::oGhostWindow MAIN ;
        STYLE WS_POPUP + WS_VISIBLE + WS_CAPTION + WS_SYSMENU ;
        EXSTYLE WS_EX_TOOLWINDOW + WS_EX_LAYERED ; // LAYERED habilita opacidade/semi-transparência
        TITLE oTab:cTitle ;
        SIZE oTab:nWidth + 100, 300

   // Define a semi-transparência do efeito "Ghost Rectangle/Tab" (Valor 180 de 255 = ~70% opaco)
   SetLayeredWindowAttributes( ::oGhostWindow:handle, 0, 180, 2 )

   // Transfere temporariamente o Painel de Conteúdo para dentro da janela flutuante
   SetParent( oTab:oPanelPage:handle, ::oGhostWindow:handle )
   MoveWindow( oTab:oPanelPage:handle, 5, 5, oTab:oPanelPage:nWidth, oTab:oPanelPage:nHeight, .T. )
   oTab:oPanelPage:Show()
   
   ACTIVATE WINDOW ::oGhostWindow NOSHOW
RETURN Nil

METHOD ReattachTab( nIdx ) CLASS ModernTabControl

   LOCAL oTab := ::aTabs[nIdx]
   ::lIsFloating := .F.// Devolve o controle pai da página para a janela principal original
     SetParent( oTab:oPanelPage:handle, ::oParent:handle )
     MoveWindow( oTab:oPanelPage:handle, ::nLeft, ::nTop + TAB_HEIGHT, ::nWidth, ::nHeight - TAB_HEIGHT, .T. )
     
     IF ::nActiveTab == nIdx
        oTab:oPanelPage:Show()
     ENDIF
     
     // Fecha e destrói a janela temporária flutuante
     IF ::oGhostWindow !=Nil
        ::oGhostWindow:End()
        ::oGhostWindow := Nil
     ENDIF
     
     ::RedrawTabs()
  RETURN Nil
  
  // Auxiliares de API do Windows para transparência e posicionamento absoluto do Cursor
  
#pragma BEGINDUMP
 
#include <windows.h>
#include "hbapi.h"

HB_FUNC( SETLAYEREDWINDOWATTRIBUTES )
{
   typedef BOOL (WINAPI 
   *lpfnSetLayeredWindowAttributes)(HWND, COLORREF, BYTE, DWORD);
   HMODULE hUser32 = GetModuleHandle("user32.dll");
   
   if (hUser32) {
     lpfnSetLayeredWindowAttributes pSetLayered = (lpfnSetLayeredWindowAttributes)GetProcAddress(hUser32, "SetLayeredWindowAttributes");
     
     if (pSetLayered) {
        pSetLayered((HWND)hb_parnl(1), (COLORREF)hb_parnl(2), (BYTE)hb_parni(3), (DWORD)hb_parnl(4));
        }
     }
  }
  
HB_FUNC( WLANG_GETCURSORX ){
   POINT pt;
   GetCursorPos(&pt);
   hb_retni(pt.x);
 }
 
 HB_FUNC( WLANG_GETCURSORY )
 {
    POINT pt;
    GetCursorPos(&pt);
    hb_retni(pt.y);
 }
 
 #pragma ENDDUMP

Exemplo Prático de Uso (`Main.prg`)

Veja como instanciar o seu novo controle customizado na sua interface:

Código: Selecionar todos

#include "hwgui.ch"

FUNCTION Main()
   LOCAL oMainWin, oMTab
   LOCAL oPage1, oPage2, oPage3
   LOCAL oBtn1, oBtn2

   INIT WINDOW oMainWin MAIN TITLE "Modern Tab Control - HwGUI" SIZE 600, 500

   // Instancia o nosso controle de abas customizado
   oMTab := ModernTabControl():New( oMainWin, 1001, 10, 10, 560, 430 )

   // Adicionando a Página 1 (Com ícone fictício)
   oPage1 := oMTab:AddPage( "Vendas", "vendas.bmp" )
   @ 20, 40 BUTTON oBtn1 CAPTION "Ação de Vendas" SIZE 120, 30 OF oPage1

   // Adicionando a Página 2
   oPage2 := oMTab:AddPage( "Clientes", "" )
   @ 20, 40 BUTTON oBtn2 CAPTION "Salvar Cliente" SIZE 120, 30 OF oPage2
   
   // Adicionando a Página 3
   oPage3 := oMTab:AddPage( "Relatórios", "" )
   @ 20, 40 SAY "Painel de Gráficos e Consultas" SIZE 200, 20 OF oPage3

   ACTIVATE WINDOW oMainWin
RETURN Nil

Como essa solução atende aos seus requisitos

1. ícone à esquerda (Req 1):
O método RedrawTabs() verifica se a propriedade hBitmap existe e realiza o DrawBitmap() antes de renderizar o texto.

2. Propriedade Enabled/Disabled + Checkbox (Req 2):
Foi criada a propriedade oTab:lEnabled. Se clicada na área delimitada pelo retângulo oTab:rChkBox, ela altera o estado e oculta ou exibe o painel de controles associado à página correspondente.

3. Botão Fechar (Req 3):
Desenhado dinamicamente com um caractere "X" vermelho à extrema direita de cada aba mapeando coordenadas no array. Quando acionado, remove o elemento do array e destrói o painel de conteúdo (oPanelPage:End()).

4. Drag & Drop Interno / Rearranjo (Req 4 e 6):
Ao movimentar o mouse horizontalmente com o botão pressionado dentro do container de abas, o código detecta a colisão com abas vizinhas através de nXProgressive e realiza um ASwap(), criando o efeito fluido de reordenação estrutural de posições.

5. Tear-off / Detach e Re-attach (Req 5 e 6):
Se o mouse sai dos limites verticais da barra de abas durante o arrasto, o componente cria um objeto HWindow() nativo do Windows em modo WS_EX_LAYERED (semi-transparente para o efeito ghost). Usando a função nativa SetParent(), o formulário inteiro é movido para dentro dessa janela flutuante. Caso o usuário passe o mouse flutuante de volta à barra principal superior, o controle reanexa automaticamente o elemento ao painel raiz.

Código: Selecionar todos

# -------------------------------------------------------------
# Configurações Principais do Projeto
# -------------------------------------------------------------

# Nome do arquivo executável final que será gerado
-oModernTabApp

# Define que é uma aplicação com interface gráfica (oculta a janela de prompt do DOS)
-gui

# Nível de avisos do compilador (opcional, ajuda a manter o código limpo)
-w3
-es2

# -------------------------------------------------------------
# Bibliotecas da HwGUI e Controles Nativos do Windows
# -------------------------------------------------------------

# Inclui as definições da biblioteca gráfica HwGUI
-lhwgui
-lhbxml

# Bibliotecas nativas do Windows necessárias para desenhos e efeitos visuais
-luser32
-lgdi32
-lcomctl32
-lcomdlg32
-lshell32
-lole32
-loleaut32
-luuid
-lwinspool
-lmpr

# -------------------------------------------------------------
# Arquivos de Código-Fonte (.prg)
# -------------------------------------------------------------

# Seu novo arquivo de controle customizado
ModernTab.prg

# O arquivo principal que chama a interface
Main.prg
Se isto funciona ou não, não sei. Certamente precisará de ajustes.

No momento estou impossibilitado de testar isto.

É uma classe separada mas se pusesse ser adicionada à HwGUI, creio que ficaria excelente, desde que funcione, é claro.

Ficam as sugestões. Se alguém tiver interesse...
[]´s
Alexandre Santos (AlxSts)
Avatar do usuário
Itamar M. Lins Jr.
Administrador
Administrador
Mensagens: 8215
Registrado em: 30 Mai 2007 11:31
Localização: Ilheus Bahia
Curtiu: 6 vezes
Curtiram: 1 vez

Re: Hwgui atualizada 08-08-2026

Mensagem por Itamar M. Lins Jr. »

Olá!
Preciso de imagens.
Para Linux, acredito que é bem difícil.
Para Linux, nem sei mais, pq a tendencia é usar GTK3 ou QT.(Migrar a Hwgui para QT). Pq roda em Windows e Linux.
No Linux a Hwgui usa a GTK2 que foi congelada. Mas é muito usada e tem muito código legado.
Tudo no universo da Hwgui tem que rodar bem no Windows e Linux. Infelizmente nem tudo é possível.
Saudações,
Itamar M. Lins Jr.
Avatar do usuário
Itamar M. Lins Jr.
Administrador
Administrador
Mensagens: 8215
Registrado em: 30 Mai 2007 11:31
Localização: Ilheus Bahia
Curtiu: 6 vezes
Curtiram: 1 vez

Re: Hwgui atualizada 08-08-2026

Mensagem por Itamar M. Lins Jr. »

Olá!
Tem coisa que vc pediu ai que nem o Windows oferece.
Precisa saber se o OS tem esses recursos.
E qual é o OS que faz isso ai. Se tem exemplo disso em algum lugar.
Esse fonte não roda em lugar nenhum. Hwgui, Minigui não linka na lib controles do Windows...
Saudações,
Itamar M. Lins Jr.
alxsts
Colaborador
Colaborador
Mensagens: 3179
Registrado em: 12 Ago 2008 15:50
Localização: São Paulo-SP-Brasil
Curtiram: 5 vezes

Re: Hwgui atualizada 08-08-2026

Mensagem por alxsts »

Olá!
Itamar M. Lins Jr. escreveu: 11 Ago 2026 21:25 qual é o OS que faz isso ai. Se tem exemplo disso em algum lugar.
O Chrome é um exemplo.

Você tentou compilar?
[]´s
Alexandre Santos (AlxSts)
Avatar do usuário
Itamar M. Lins Jr.
Administrador
Administrador
Mensagens: 8215
Registrado em: 30 Mai 2007 11:31
Localização: Ilheus Bahia
Curtiu: 6 vezes
Curtiram: 1 vez

Re: Hwgui atualizada 08-08-2026

Mensagem por Itamar M. Lins Jr. »

Olá!
https://github.com/githubuser0xFFFF/Qt- ... ing-System

No QT tem isso. A HBIDE do Pritpal tem isso. Então o Harbour usando QtContribs tem isso.
Mas foi o que perguntei para IA. Onde encontro exemplos.
E tem uma extensão do C#
https://github.com/egorozh/Tabalonia
ou nos navegadores.
Como o QT(KDE) é o "servidor de janelas" tem isso aqui no meu sistema Linux.
Você tentou compilar?
Olhando o código .HBP eu sei que não vai.
Saudações,
Itamar M. Lins Jr.
alxsts
Colaborador
Colaborador
Mensagens: 3179
Registrado em: 12 Ago 2008 15:50
Localização: São Paulo-SP-Brasil
Curtiram: 5 vezes

Re: Hwgui atualizada 08-08-2026

Mensagem por alxsts »

Olá!
Itamar M. Lins Jr. escreveu: 11 Ago 2026 23:31 Tem coisa que vc pediu ai que nem o Windows oferece.
Precisa saber se o OS tem esses recursos.
E qual é o OS que faz isso ai. Se tem exemplo disso em algum lugar.

No QT tem isso. A HBIDE do Pritpal tem isso. Então o Harbour usando QtContribs tem isso.
Então tanto Windows quanto Linux permitem isto.

Se tem na QtContribs, por que não tentar implementar na HwGUI?
Itamar M. Lins Jr. escreveu: 11 Ago 2026 23:31 Olhando o código .HBP eu sei que não vai.
Nào sei... no momento estou sem máquina para testar.
[]´s
Alexandre Santos (AlxSts)
Avatar do usuário
Itamar M. Lins Jr.
Administrador
Administrador
Mensagens: 8215
Registrado em: 30 Mai 2007 11:31
Localização: Ilheus Bahia
Curtiu: 6 vezes
Curtiram: 1 vez

Re: Hwgui atualizada 08-08-2026

Mensagem por Itamar M. Lins Jr. »

Olá!
Se tem na QtContribs, por que não tentar implementar na HwGUI?
Nativamente não tem no Windows. O controle do windows que faz as tabs não tem.
Tem pronto usando C# e QT.
Fazer em C dá muito trabalho. E pode não ficar bom, não dá certo.
É uma DLL com esse recurso pronto, basta usar no QT.
Saudações,
Itamar M. Lins Jr.
Avatar do usuário
deividdjs
Usuário Nível 3
Usuário Nível 3
Mensagens: 405
Registrado em: 19 Set 2006 09:39
Localização: Foz do Iguaçu / Pr
Curtiram: 1 vez

Re: Hwgui atualizada 08-08-2026

Mensagem por deividdjs »

Use CLAUDE IA , q ela faz pra vc do jeito q tu quer
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
JoséQuintas
Administrador
Administrador
Mensagens: 20550
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP
Curtiram: 2 vezes

Re: Hwgui atualizada 08-08-2026

Mensagem por JoséQuintas »

Cuidado referente QT porque, pelo que sei, pra novas versões só pagando mensalidade.
Isso acaba sendo uma limitação.
José M. C. Quintas
Harbour 3.2, mingw, multithread, gtwvg, fivewin 25.12, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui), (hmg3), (hmg extended), (oohg), PNotepad, ASP, (Linux/Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
Itamar M. Lins Jr.
Administrador
Administrador
Mensagens: 8215
Registrado em: 30 Mai 2007 11:31
Localização: Ilheus Bahia
Curtiu: 6 vezes
Curtiram: 1 vez

Re: Hwgui atualizada 08-08-2026

Mensagem por Itamar M. Lins Jr. »

Olá!
JoséQuintas escreveu: 12 Ago 2026 12:21 Cuidado referente QT porque, pelo que sei, pra novas versões só pagando mensalidade.
Isso acaba sendo uma limitação.
Pelo que estou vendo é só não usar(Linkar) a LIB estaticamente. Tem que usar DLL.
Resposta.
Isso significa que o mesmo código possui uma versão comercial paga e uma versão gratuita. Para usar a biblioteca gráfica Qt sem pagar nada (inclusive para fins comerciais), você deve seguir regras específicas baseadas na linguagem e na forma de distribuição.
As regras principais para usar o Qt de graça (sob a licença LGPLv3) em um programa comercial e de código fechado resumem-se a três obrigações contratuais:

1. Permitir a engenharia reversa do seu app
Você é obrigado a dar permissão para que o usuário final faça engenharia reversa no seu aplicativo. O objetivo exclusivo dessa permissão deve ser permitir que o usuário faça a depuração (debugging) de modificações feitas nas bibliotecas do Qt que você utilizou.

2. Entregar o Qt em Links Dinâmicos (Shared Libraries)
Como fazer: Você deve compilar seu programa usando vinculação dinâmica (arquivos .dll no Windows, .so no Linux ou .dylib no macOS).Por que isso é obrigatório: O usuário final deve ter o direito e a capacidade física de substituir os arquivos do Qt que acompanham o seu programa por versões modificadas ou atualizadas por ele mesmo. Se você embutir o Qt diretamente dentro do executável principal do seu programa (vinculação estática), você quebra essa regra e viola a licença.

3. Fornecer os mecanismos de relocalização (Relink)Se você trabalha com plataformas onde os links dinâmicos são restritos (como alguns sistemas embarcados ou travas de lojas de aplicativos), você precisa fornecer ao usuário todos os arquivos de objeto (.obj, .o) ou o código-fonte correspondente do seu programa. Dessa forma, se ele quiser modificar a biblioteca do Qt, ele mesmo conseguirá juntar (re-linkar) os pedaços do seu programa com o novo Qt dele.
Saudações,
Itamar M. Lins Jr.
Avatar do usuário
Itamar M. Lins Jr.
Administrador
Administrador
Mensagens: 8215
Registrado em: 30 Mai 2007 11:31
Localização: Ilheus Bahia
Curtiu: 6 vezes
Curtiram: 1 vez

Re: Hwgui atualizada 08-08-2026

Mensagem por Itamar M. Lins Jr. »

Olá!
Faltou essa parte.
Capturar.PNG
Capturar.PNG (32.23 KiB) Exibido 63 vezes
Saudações,
Itamar M. Lins Jr.
Responder