NGrok - Compartilhando seu localhost no Windows

Olá, nesta semana me deparei com uma situação em que eu precisava fazer um teste forçando um retorno do backend para avaliar como o frontend iria se comportar e acabei conhecendo por outros devs a ferramenta NGrok, o que foi muito legal, pois nem conhecia esse tipo de ferramenta.

Pois bem, o que é o NGrok?

NGrok é um serviço "gratuito" disponível para a criação de túneis seguros de seu localhost para um link externo.

Por exemplo, subo minha API backend em http://localhost:6868/ e com o NGrok consigo um link externo http://a805a1723952.ngrok.io

Pego este link e utilizo em um sistema de frontend ou disponibilizo essa API para alguém testar com Postman ou algo do tipo.

E como utilizo?

Pois bem, para utilizar no Windows, é só acessar a página de download do NGrok e seguir as instruções dela.

Um exemplo de uso. No console, digite:

ngrok http localhost:6868 -host-header="localhost:6868"

Dica: Quando utilizamos o NGrok sem criar uma conta e registrar ela, o serviço fica disponível por 2 horas. Mas, se criar a conta e registrar, esse limite não ocorrerá.

Not using the local TSLint version found - VSCode

 Olá, hoje me deparei com a seguinte mensagem no VSCode após mudar de Workspace:

"Not using the local TSLint version found for 'C:/meuprojeto/teste.component.ts' To enable code execution from the current workspace you must enable workspace library execution".

Para resolver isso, faça o seguinte:

No VSCode, aperte Ctrl + Shift + P (Command Palette)

Digite: "TSLint: Manage workspace library execution" e aperte Enter

Em seguida, escolha a opção "Enable workspace library execution"

Exemplo de como criar e ler um arquivo json em C#

Pré-requisito: Possuir uma classe que represente o seu Json.


public class ArquivoJson
{
  private static ArquivoJson instancia;

  public string Config1 { get; set; }
  public string Config2 { get; set; }

  public static ArquivoJson PegarInstancia()
  {
    if (instancia == null)
    {
      instancia = new ArquivoJson();
    }
    return instancia;
  }
}

Neste exemplo, ao inicializar o sistema, verifico se o arquivo "config.json" existe na raíz do sistema e se não existir, é criado este arquivo.

Caso o arquivo já exista, carrega-o.


namespace AppExemplo
{
  public partial class MainWindow
  {
    ArquivoJson arquivoJson;

    private void InicializarSistema(object sender, RoutedEventArgs e)
    {
      if (!File.Exists("config.json"))
      {
        CriarArquivoJson();
      }

      string jsonString = File.ReadAllText("config.json");

      arquivoJson = ArquivoJson.PegarInstancia();
      arquivoJson = JsonSerializer.Deserialize(jsonString);

      // Agora sua classe arquivoJson já está carregada e pronta para uso
      textConfig1.Text = arquivoJson.Config1;
    }

    private void CriarArquivoJson()
    {
      arquivoJson = ArquivoJson.PegarInstancia();
      arquivoJson.Config1 = "exemplo1";

      GravarJson();
    }

    private void GravarJson()
    {
      var opcoesJson = new JsonSerializerOptions
      {
        WriteIndented = true
      };

      string jsonString = JsonSerializer.Serialize(arquivoJson, opcoesJson);
      File.WriteAllText("config.json", jsonString);
    }
  }
}

Delphi: Formulário "ToolTip"

Bem... hoje vou mostrar como criar um formulário no estilo ToolTip, como se fosse um balão com informações (Hint), que é exibido quando passamos o mouse sobre um objeto de nossa escolha. No meu caso, escolhi um TImage.

Ao passar o mouse sobre o TImage, o formulário ToolTip é exibido. E quando o mouse sai dos limites do formulário, o ToolTip é fechado.

E fiz isso da seguinte forma:
Criei a classe TMeuToolTip e o método que quero destacar aqui é o CMMouseLeave, que fará com que o formulário seja fechado.
type
  TMeuToolTip = class(TForm)
  private
    FMemo: TMemo;
    procedure CMMouseLeave(var Msg: TMessage); message CM_MOUSELEAVE;
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  end;

{ TMeuToolTip }

procedure TMeuToolTip.CMMouseLeave(var Msg: TMessage);
begin
  Self.Close;
end;
E a chamada do formulário é realizada através do evento MouseMove do TImage.
procedure TfrmPrincipal.ImageInfoMouseMove(Sender: TObject; Shift: TShiftState;
  X, Y: Integer);
begin
  if Assigned(frmMeuToolTip) and frmMeuToolTip.Visible then
    Exit;

  {Criar o formulário ToolTip}
  frmMeuToolTip := TMeuToolTip.CreateNew(frmPrincipal);
  frmMeuToolTip.Name := 'frmMeuToolTip';
  {Removemos as bordas}
  frmMeuToolTip.BorderStyle := bsNone;
  {Designamos a sua posição}
  frmMeuToolTip.Position := poDesigned;
  frmMeuToolTip.Left := frmPrincipal.Left + ImageInfo.Left;
  frmMeuToolTip.Top := frmPrincipal.Top + ImageInfo.Top + ImageInfo.Height;

  {Aplico um AlphaBlend para exemplificar}
  frmMeuToolTip.AlphaBlendValue := 200;
  frmMeuToolTip.AlphaBlend := True;

  {Evento que libera o formulário da memória}
  frmMeuToolTip.OnClose := frmMeuToolTip.FormClose;

  {Criando um texto de exemplo}
  frmMeuToolTip.FMemo := TMemo.Create(frmMeuToolTip);
  frmMeuToolTip.FMemo.Parent := frmMeuToolTip;
  frmMeuToolTip.FMemo.Visible := True;
  frmMeuToolTip.FMemo.Align := alClient;
  frmMeuToolTip.FMemo.Lines.Add('Texto de exemplo');
  frmMeuToolTip.FMemo.Lines.Add('abcdef abcdef abcdef abcdef abcdef' +
    'abcdef abcdef abcdef abcdef abcdef abcdef abcdef abcdef');
  frmMeuToolTip.FMemo.WordWrap := True;
  frmMeuToolTip.FMemo.HideSelection := True;
  frmMeuToolTip.FMemo.ReadOnly := True;
  frmMeuToolTip.FMemo.Color := clYellow;

  frmMeuToolTip.Show;
end;
Para não ter que ficar criando os objetos em tempo de execução, aconselho criar o formulário ToolTip em outra unit, isso facilitará e agilizará todo o trabalho. :)

Código completo:
unit Unit2;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs,
  Commctrl, Menus, StdCtrls, Grids, Vcl.ExtCtrls;

type
  TMeuToolTip = class(TForm)
  private
    FMemo: TMemo;
    procedure CMMouseLeave(var Msg: TMessage); message CM_MOUSELEAVE;
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  end;

  TfrmPrincipal = class(TForm)
    ImageInfo: TImage;
    procedure ImageInfoMouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
  private
    frmMeuToolTip: TMeuToolTip;
  end;

var
  frmPrincipal: TfrmPrincipal;

implementation

{$R *.dfm}

{ TMeuToolTip }

procedure TMeuToolTip.CMMouseLeave(var Msg: TMessage);
begin
  Self.Close;
end;

procedure TMeuToolTip.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  FreeAndNil(Self);
end;

procedure TfrmPrincipal.ImageInfoMouseMove(Sender: TObject; Shift: TShiftState;
  X, Y: Integer);
begin
  if Assigned(frmMeuToolTip) and frmMeuToolTip.Visible then
    Exit;

  {Criar o formulário ToolTip}
  frmMeuToolTip := TMeuToolTip.CreateNew(frmPrincipal);
  frmMeuToolTip.Name := 'frmMeuToolTip';
  {Removemos as bordas}
  frmMeuToolTip.BorderStyle := bsNone;
  {Designamos a sua posição}
  frmMeuToolTip.Position := poDesigned;
  frmMeuToolTip.Left := frmPrincipal.Left + ImageInfo.Left;
  frmMeuToolTip.Top := frmPrincipal.Top + ImageInfo.Top + ImageInfo.Height;

  {Aplico um AlphaBlend para exemplificar}
  frmMeuToolTip.AlphaBlendValue := 200;
  frmMeuToolTip.AlphaBlend := True;

  {Evento que libera o formulário da memória}
  frmMeuToolTip.OnClose := frmMeuToolTip.FormClose;

  {Criando um texto de exemplo}
  frmMeuToolTip.FMemo := TMemo.Create(frmMeuToolTip);
  frmMeuToolTip.FMemo.Parent := frmMeuToolTip;
  frmMeuToolTip.FMemo.Visible := True;
  frmMeuToolTip.FMemo.Align := alClient;
  frmMeuToolTip.FMemo.Lines.Add('Texto de exemplo');
  frmMeuToolTip.FMemo.Lines.Add('abcdef abcdef abcdef abcdef abcdef' +
    'abcdef abcdef abcdef abcdef abcdef abcdef abcdef abcdef');
  frmMeuToolTip.FMemo.WordWrap := True;
  frmMeuToolTip.FMemo.HideSelection := True;
  frmMeuToolTip.FMemo.ReadOnly := True;
  frmMeuToolTip.FMemo.Color := clYellow;

  frmMeuToolTip.Show;
end;

end.