domingo, 6 de fevereiro de 2022

Retornando matriz de string em dll

Passado muitos dias sem programar,
por falta de tempo e por principalmente
por um problema que nos forçou a parar,
resolvi no tempo curto verificar alguns
fóruns de programação, e me vi motivado
por uma pergunta feita por um membro que
pedia um exemplo de retorno de uma matriz
de string para uso em outros arquivos.
Mesmo não respondendo, resolvi criar uma 
versão, mas diferente do que ele pediu,
nesta versão a matriz de string é retornada
numa dll, e o programa usado para criar a dll
foi o Visual studio 2019 na opção:
Biblioteca de Vínculo Dinâmico (DLL).
Mas nós poderíamos usar até mesmo o bloco
de notas para fazer isto e compilar com
uma linha de comando utilizando o gcc.
Segue os códigos para criação da dll,
como para sua chamada no link abaixo,
o que para nós não é nenhuma novidade
para outros que estão iniciando pode ser 
de grande ajuda, então tudo em seu tempo,
porque quem de nós nunca passou por isto?





Códigos para criação da dll:
#include "pch.h"
#include <Windows.h>
#include <iostream>

#define tam 12

using namespace std;

#ifdef RETMATSTRINGDLL_EXPORTS
#define RETMATSTRINGDLL_API extern "C" __declspec(dllexport)
#else
#define RETMATSTRINGDLLDLL_API __declspec(dllimport)
#endif

//===================================================================================
RETMATSTRINGDLL_API const char** Retorna_Matriz_SWtring ( int* len ) {

    CString str_1 = _T ( "" );
    const char** arr;
    arr = ( const char** ) malloc ( tam * sizeof ( const char* ) );

    const char* ve_t [ ] = {
            "No Meio do Caminho",
            "Carlos Drummond de Andrade",
            "No meio do caminho tinha uma pedra",
            "Tinha uma pedra no meio do caminho",
            "Tinha uma pedra",
            "No meio do caminho tinha uma pedra.",
            "Nunca me esquecerei desse acontecimento",
            "Na vida de minhas retinas tão fatigadas.",
            "Nunca me esquecerei que no meio do caminho",
            "Tinha uma pedra teste teste teste",
            "Tinha uma pedra no meio do caminho",
            "No meio do caminho tinha uma pedra." };

    int i, j;

    for ( i = 0; i < tam; i++ ) {
        arr [ i ] = ( char* ) malloc ( tam );
        arr [ i ] = ve_t [ i ];
        *len = *len + 1;
    }
    return arr;
}
//===================================================================================

Códigos para chamar a dll


#include <windows.h>
#include <iostream>
#include <conio.h>

#define tam 12
#define MYDLL "Ret_Mat_String_DLL.dll"

void Janela ( ) {
	 int l, c;
	 for ( l = 1; l <= 30 ; l++ ) {
         for ( c = 1; c < 80 ; c++ ) {
              gotoxy ( c , l );
			  if ( l == 2 ) {
				   cprintf ( " " );
			  }
			  if ( c == 1 ) {
				   cprintf ( "  " );
              }
              if ( c == 79 ) {
				   textattr ( 200 );
				   cprintf ( "  " );
			  }
		 }
	 }
}

//------------------------------------------------------------------------------
void Informe ( ) {
     textbackground ( BLACK );
     textcolor ( LIGHTBLUE );
	 gotoxy ( 26, 19 );
	 cprintf ( "Por: " );
	 textcolor ( LIGHTMAGENTA );
	 cprintf ( "Samuel Lima" );
     textcolor ( WHITE );
	 gotoxy ( 26, 20 );
	 cprintf ( "sa_sp10@hotmail.com" );
     Sleep ( 1800 );
	 textcolor ( LIGHTRED );
	 gotoxy ( 37, 23 );
	 cprintf ( "MUITO OBRIGADO" );
}
//------------------------------------------------------------------------------
int main ( ) {
    system ( "title RETORNANDO MATRIZ DE STRING EM DLL" );
    
     textcolor ( LIGHTRED );
	 gotoxy ( 20 , 3 );
	 cprintf ( "RETORNANDO MATRIZ DE STRING EM DLL" );

    int i, len = 0;
    const char **( WINAPI * Retorna_Matriz_SWtring ) ( int *len );

    HINSTANCE hDll;
    hDll = LoadLibrary ( MYDLL );
    if ( !hDll ) {
        printf ( "Não foi possível carregar a dll" );
        exit ( 1 );
    }
    Retorna_Matriz_SWtring = ( const char ** ( WINAPI* ) ( int *len ) ) GetProcAddress ( hDll, "Retorna_Matriz_SWtring" );

    const char** arr = Retorna_Matriz_SWtring ( &len );
    std::cout << std::endl;

    for ( i = 0; i < len; i++ ) {
        gotoxy ( 20, i + 5 );
        std::cout << arr [ i ] << std::endl;
    }
    
    Janela ( );
    Informe ( );
    
    getche ( );
    
    return 0;
}

//===================================================================================





sábado, 18 de dezembro de 2021

Qt - utilizando streams em C++

Quando precisamos fazer leitura num arquivo de disco 
para extração de dados, a classe ifstream dá suporte
perfeito para isto, tudo o que temos que fazer,
é construir um objeto da classe ifstream e especificar
dados binários ou em modo de texto.
A classe ifstream está entre as três classes
de fluxo de entrada mais importantes do C++,
seguidas pelas classes: istream e istringstream.
Se precisarmos converter números ou qualquer tipo 
com os operadores de fluxos << >> sobrecarregados,
a poderosa biblioteca sstream (fluxos) nos permite
realizar estas operações facilmente com entrada e
saída formatadas, só precisamos incluir o cabeçalho 
#include <sstream> e declarar um objeto da classe stringstream.
Penso comigo mesmo que em C++ esta é a maneira mais fácil de converter
um número em string e ainda imagino que seja o caminho mais curto,
pois em apenas duas etapas se consegue isto facilmente,
o número é enviado para o fluxo e a string e retirada do stream.
Para saber mais, veja entradas e saídas em C++, 
onde streams são devidamente esclarecidos com detalhes.
Neste programa foi isto que fizemos, lemos um arquivo de texto
do disco com ifstream, este arquivo foi criado previamente 
com os dez mil primeiros números naturais ordenados e
copiamos numa string padrão do C++,
em seguida, declaramos um objeto da classe stringstream,
que foi carregada com a variável string padrão.
Agora o que mais me impressionou foi a capacidade
e facilidade destas conversões num array de inteiro
de estilo C de dez mil inteiros, porque até então,
só tínhamos feitos conversões simples, e não esperava
um desempenho tão preciso para as matrizes de inteiros do C.
Como já faz muito tempo que não utilizo o Qt, 
resolvi apresentar estas saídas numa janela gráfica,
e em nada se comportou inferior ao C++ Builder,
e nem ainda ao C++ CLI do Visual Studio.



//====================================================================
void MainWindow :: Pesq_String ( ) {
    ui -> lineEdit -> setFocus ( );
    QString str;
    int a = -1;

    string numeral;
    std::ifstream arq ( "Dez_Mil.txt" );

    if ( arq.is_open ( ) ) {
        while ( !arq.eof ( ) ) {
            getline ( arq, numeral );
        }
        arq.close ( );
    }

    stringstream stream ( numeral );

    while ( stream ) {
        a++;
        stream >> A [ a ];

        str += "    ";
       if ( a % 10 == 0 )
           str += "<p>";

        if ( a >= 0 && a < 10 )
           str += ( "000" );

       if ( a >= 10 && a < 100 )
           str += ( "00" );

       if ( a >= 100 && a < 1000 )
           str += ( "0" );


       str += QString::number (  A [ a ] );
    }
    ui -> textEdit -> setText (  str  );
    ui -> lineEdit -> setFocus ( );
   }
//============================================================

sábado, 20 de novembro de 2021

Chamando funções nativas em dll

Chamar funções nativas do sistema em programas
escritos em linguagens .Net, como esta que 
estou usando neste programa, Visual C++ com CLR,
(Common Language Runtime), pode ser uma saída,
para fugir de conversões de tipos complexos,
E para aumentar as opções de ferramentas  num projeto.
O Visual C++ com .Net permite uma perfeita integração entre 
código gerenciado e não gerenciado num mesmo aplicativo
e até mesmo no mesmo arquivo.
Isso permite que desenvolvedores de Visual C++ com .Net,
não fiquem presos na base nativa do .Net, mas que venha
utilizar seus conhecimentos sólidos adquiridos desde o
princípio de seu aprendizado reutilizando
funções e classes sem nenhum problema.
Uma das opções para chamar funções nativas do sistema
encapsuladas em dll quando estamos em .Net é o Pinvoke,
mas o PInvoke não é apropriado para todas as funções de estilo C em DLLs,
isto porque existem funções com parâmetros de tipos 
que ficam armazenados na memória e de lá nestes casos não se podem excluir.
Está muito claro que não podemos retornar um ponteiro de uma função nativa,
que foi executado como parâmetro para serem chamados com Pinvoke,
certamente teremos problemas de memória ou a corrupção da dll 
no qual a função se encontra, colocando em risco diversos
programas do sistema.
Se o Pinvoke tem seus limites, certamente existem outras opções, 
e no meu caso, criei minha própria opção baseado nos conhecimentos
intermediário que temos nas linguagens, não me assumo avançado,
por enquanto não, mas quem sabe no futuro podemos subir novos degraus.
Criei um projeto de dll utilizando um assistente de dll do Visual Studio,
e neste projeto criei diversas funções em Win32, 
com funções nativas da Api do windows, alterando alguns parâmetros
para se adaptarem as minhas preferências.
Não que o CLI precise disto, mas para facilitar a impressão
de textos sem a necessidade de conversões com marshal.




#include <windows.h>
#include "atlstr.h"
#include <stdio.h>
#include <time.h>
#include "CallDll.h"

#define TAM 10
char* c;
int V [ TAM ][ TAM ];

using namespace System;
using namespace System::ComponentModel;
using namespace System::Collections;
using namespace System::Windows::Forms;
using namespace System::Data;
using namespace System::Drawing;

public ref class Form1 : public System::Windows::Forms::Form {
public:
    Form1 ( void ) {
        InitializeComponent ( );
    }
private: System::Windows::Forms::Button^ button1;
public:
private: System::Windows::Forms::Button^ button2;
private: System::Windows::Forms::TextBox^ textBox1;
private: System::Windows::Forms::Label^ label1;
private: System::Windows::Forms::Button^ button3;
private: System::Windows::Forms::Label^ label2;
private: System::Windows::Forms::Button^ button4;

public:

    void InitializeComponent ( void ) {
        this->button1 = ( gcnew System::Windows::Forms::Button ( ) );
        this->button2 = ( gcnew System::Windows::Forms::Button ( ) );
        this->textBox1 = ( gcnew System::Windows::Forms::TextBox ( ) );
        this->label1 = ( gcnew System::Windows::Forms::Label ( ) );
        this->button3 = ( gcnew System::Windows::Forms::Button ( ) );
        this->button4 = ( gcnew System::Windows::Forms::Button ( ) );
        this->label2 = ( gcnew System::Windows::Forms::Label ( ) );
        this->SuspendLayout ( );
        // 
        // button1
        // 
        this->button1->Location = System::Drawing::Point ( 49712 );
        this->button1->Name = L"button1";
        this->button1->Size = System::Drawing::Size ( 7523 );
        this->button1->TabIndex = 0;
        this->button1->UseVisualStyleBackColor = true;
        this->button1->Click += gcnew System::EventHandler ( this, &Form1::button1_Click );
        // 
        // button2
        // 
        this->button2->Location = System::Drawing::Point ( 49741 );
        this->button2->Name = L"button2";
        this->button2->Size = System::Drawing::Size ( 7523 );
        this->button2->TabIndex = 1;
        this->button2->UseVisualStyleBackColor = true;
        this->button2->Click += gcnew System::EventHandler ( this, &Form1::button2_Click );
        // 
        // textBox1
        // 
        this->textBox1->Location = System::Drawing::Point ( 49770 );
        this->textBox1->Name = L"textBox1";
        this->textBox1->Size = System::Drawing::Size ( 7520 );
        this->textBox1->TabIndex = 2;
        // 
        // label1
        // 
        this->label1->Location = System::Drawing::Point ( 51497 );
        this->label1->Name = L"label1";
        this->label1->Size = System::Drawing::Size ( 013 );
        this->label1->TabIndex = 3;
        // 
        // button3
        // 
        this->button3->Location = System::Drawing::Point ( 49797 );
        this->button3->Name = L"button3";
        this->button3->Size = System::Drawing::Size ( 7523 );
        this->button3->TabIndex = 4;
        this->button3->UseVisualStyleBackColor = true;
        this->button3->Click += gcnew System::EventHandler ( this, &Form1::button3_Click );
        // 
        // button4
        // 
        this->button4->Location = System::Drawing::Point ( 497126 );
        this->button4->Name = L"button4";
        this->button4->Size = System::Drawing::Size ( 7523 );
        this->button4->TabIndex = 5;
        this->button4->UseVisualStyleBackColor = true;
        this->button4->Click += gcnew System::EventHandler ( this, &Form1::button4_Click );
        // 
        // label2
        // 
        this->label2->AutoSize = true;
        this->label2->Location = System::Drawing::Point ( 514162 );
        this->label2->Name = L"label2";
        this->label2->Size = System::Drawing::Size ( 013 );
        this->label2->TabIndex = 6;
        // 
        // Form1
        // 
        this->AutoScaleDimensions = System::Drawing::SizeF ( 613 );
        this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
        this->BackColor = System::Drawing::SystemColors::Control;
        this->ClientSize = System::Drawing::Size ( 600340 );
        this->Controls->Add ( this->label2 );
        this->Controls->Add ( this->button4 );
        this->Controls->Add ( this->button3 );
        this->Controls->Add ( this->label1 );
        this->Controls->Add ( this->textBox1 );
        this->Controls->Add ( this->button2 );
        this->Controls->Add ( this->button1 );
        this->Location = System::Drawing::Point ( 350100 );
        this->Name = L"Form1";
        this->StartPosition = System::Windows::Forms::FormStartPosition::Manual;
        this->Text = L"IMPRIMINDO PESQUISANDO E ORDENANDO MATRIZ DE INTEIROS";
        this->Shown += gcnew System::EventHandler ( this, &Form1::Form1_Shown );
        this->Paint += gcnew System::Windows::Forms::PaintEventHandler ( this, &Form1::Form1_Paint );
        this->ResumeLayout ( false );
        this->PerformLayout ( );

    }
    //===================================================================================
    void TextBox_1 ( int Xint Yint Wint HStringst ) {
        this->textBox1->Margin = System::Windows::Forms::Padding ( 4545 );
        //this->textBox1->UseVisualStyleBackColor = true;
        this->textBox1->AutoSize = true;
        this->textBox1->Focus ( );
        this->textBox1->Font = ( gcnew System::Drawing::Font ( L"Times New Roman",
            10.25FSystem::Drawing::FontStyle::Italic, System::Drawing::GraphicsUnit::Point,
            static_castSystem::Byte >( 0 ) ) );
        this->textBox1->ForeColor = System::Drawing::Color::Black;
        this->textBox1->Location = System::Drawing::Point ( X, Y );
        this->textBox1->Name = L"textBox1";
        this->textBox1->Size = System::Drawing::Size ( W, H );
        this->textBox1->TabIndex = 1;
        this->textBox1->Text += st;
    }
    //===================================================================================
    void Label_1 ( int Xint Yint Wint HStringst ) {
        this->label1->Font = ( gcnew System::Drawing::Font ( L"Times New Roman",
            10.25FSystem::Drawing::FontStyle::Italic, System::Drawing::GraphicsUnit::Point,
            static_castSystem::Byte >( 0 ) ) );
        this->label1->AutoSize = false;
        this->label1->ForeColor = System::Drawing::Color::Black;
        this->label1->BackColor = System::Drawing::Color::LightCoral;
        this->label1->Location = System::Drawing::Point ( X, Y );
        this->label1->Name = L"label1";
        this->label1->Size = System::Drawing::Size ( W, H );
        this->label1->TabIndex = 0;
        label1->Text += st;
    }
    //===================================================================================
    void Label_2 ( int Xint Yint Wint HStringst ) {
        this->label2->Font = ( gcnew System::Drawing::Font ( L"Times New Roman",
            10.25FSystem::Drawing::FontStyle::Italic, System::Drawing::GraphicsUnit::Point,
            static_castSystem::Byte >( 0 ) ) );
        this->label2->AutoSize = false;
        this->label2->ForeColor = System::Drawing::Color::Black;
        this->label2->BackColor = System::Drawing::Color::LightCoral;
        this->label2->Location = System::Drawing::Point ( X, Y );
        this->label2->Name = L"label2";
        this->label2->Size = System::Drawing::Size ( W, H );
        this->label2->TabIndex = 0;
        //this->label2->Text = "";
        this->label2->Text += st;
    }
    //===================================================================================
    void Button_1 ( int Xint Yint Wint HStringst ) {
        this->button1->Margin = System::Windows::Forms::Padding ( 4545 );
        this->button1->UseVisualStyleBackColor = true;
        this->button1->AutoSize = false;
        this->button1->Font = ( gcnew System::Drawing::Font ( L"Times New Roman",
            10.25FSystem::Drawing::FontStyle::Italic, System::Drawing::GraphicsUnit::Point,
            static_castSystem::Byte >( 0 ) ) );
        this->button1->BackColor = System::Drawing::Color::LightGreen;
        this->button1->ForeColor = System::Drawing::Color::Black;
        this->button1->Location = System::Drawing::Point ( X, Y );
        this->button1->Name = L"button1";
        this->button1->Size = System::Drawing::Size ( W, H );
        this->button1->TabIndex = 1;
        this->button1->Text += st;
    }
    //===================================================================================
    void Button_2 ( int Xint Yint Wint HStringst ) {
        this->button2->Margin = System::Windows::Forms::Padding ( 4545 );
        this->button2->UseVisualStyleBackColor = true;
        this->button2->AutoSize = false;
        this->button2->Font = ( gcnew System::Drawing::Font ( L"Times New Roman",
            10.25FSystem::Drawing::FontStyle::Italic, System::Drawing::GraphicsUnit::Point,
            static_castSystem::Byte >( 0 ) ) );
        this->button2->BackColor = System::Drawing::Color::LightBlue;
        this->button2->ForeColor = System::Drawing::Color::Black;
        this->button2->Location = System::Drawing::Point ( X, Y );
        this->button2->Name = L"button2";
        this->button2->Size = System::Drawing::Size ( W, H );
        this->button2->TabIndex = 1;
        this->button2->Text += st;
    }
    //===================================================================================
    void Button_3 ( int Xint Yint Wint HStringst ) {
        this->button3->Margin = System::Windows::Forms::Padding ( 4545 );
        this->button3->UseVisualStyleBackColor = true;
        //this->button3->AutoSize = true;
        this->button3->Font = ( gcnew System::Drawing::Font ( L"Times New Roman",
            10.25FSystem::Drawing::FontStyle::Italic, System::Drawing::GraphicsUnit::Point,
            static_castSystem::Byte >( 0 ) ) );
        this->button3->BackColor = System::Drawing::Color::LightYellow;
        this->button3->ForeColor = System::Drawing::Color::Black;
        this->button3->Location = System::Drawing::Point ( X, Y );
        this->button3->Name = L"button3";
        this->button3->Size = System::Drawing::Size ( W, H );
        this->button3->TabIndex = 1;
        this->button3->Text += st;
    }
    //====================================================================================
    void Button_4 ( int Xint Yint Wint HStringst ) {
        this->button4->Margin = System::Windows::Forms::Padding ( 4545 );
        this->button4->UseVisualStyleBackColor = true;
        //this->button4->AutoSize = true;
        this->button4->Font = ( gcnew System::Drawing::Font ( L"Times New Roman",
            10.25FSystem::Drawing::FontStyle::Italic, System::Drawing::GraphicsUnit::Point,
            static_castSystem::Byte >( 0 ) ) );
        this->button4->BackColor = System::Drawing::Color::LightSlateGray;
        this->button4->ForeColor = System::Drawing::Color::Black;
        this->button4->Location = System::Drawing::Point ( X, Y );
        this->button4->Name = L"button4";
        this->button4->Size = System::Drawing::Size ( W, H );
        this->button4->TabIndex = 1;
        this->button4->Text += st;
    }
    //====================================================================================
    //Imprime a matriz
    System::Void Form1_Paint ( System::Objectsender,
        System::Windows::Forms::PaintEventArgse ) {

        CallDll InvokDll;

        Graphics^ g = e->Graphics;

        IntPtr hdc = g->GetHdc ( );
        IntPtr hwnd = Process::GetCurrentProcess ( )->MainWindowHandle;

        InvokDll.Gradiente ( hwnd, 02552552550255 );
        InvokDll.Moldura ( hdc, 555903301025500255 );

        InvokDll.TextOut_4 = ( int ( WINAPI* ) ( IntPtr hdc, char* text [ ], int xpos, int ypos ) )
            GetProcAddress ( InvokDll.hDll"TextOut_4" );

        InvokDll.SetBkColorA ( hdc, RGB ( 123234255 ) );
        InvokDll.SetTextColorA ( hdc, ( 2525112 ) );

        int i, j = 0, t = 0;

        c = ( char* ) malloc ( 120 );

        //Usar Conjunto de Caracteres Multibyte para mudar o nome da fonte
        InvokDll.Cria_Fonte ( hdc, 1500, FW_REGULAR, 00, FALSE, FALSE, FALSE, L"alarm clock" );

        for ( i = 0; i < TAM; i++ ) {
            for ( j = 0; j < TAM; j++ ) {
                t++;
                V [ i ][ j ] = t;
                snprintf ( c, sizeof ( int ), "%d", V [ i ][ j ] );

                InvokDll.TextOut_4 ( hdc, &c, 80 + j * 2740 + i * 20 );
            }
        }

        InvokDll.Text_Designer ( hdc, 39060255750130L"POR :",
            0.0L"Arial"FontStyle::Italic, 4841352062501017325547 );

        InvokDll.Text_Designer ( hdc, 360120255750130L"SAMUEL",
            0.0L"Arial"FontStyle::Italic, 4841352062501017325547 );

        InvokDll.Text_Designer ( hdc, 390180255750130L"LIMA",
            0.0L"Arial"FontStyle::Italic, 4841352062501017325547 );

        g->ReleaseHdc ( hdc );
    }
    //====================================================================================
    //Embaralhando a matriz
private: System::Void button1_Click ( System::Object^ sender, System::EventArgs^ e ) {

    label2->Text = "";
    Label_2 ( 901326017"Abaixo a impressão da matriz embaralhada" );

    Graphics^ g = this->CreateGraphics ( );

    CallDll InvokDll;

    IntPtr hdc = g->GetHdc ( );

    String^ str_2;

    int a, b, r, y, temp;

    c = ( char* ) malloc ( 100 );

    srand ( time ( NULL ) );
    for ( a = 0; a < TAM; a++ ) {
        for ( b = 0; b < TAM; b++ ) {
            r = rand ( ) % TAM;
            y = rand ( ) % TAM;
            temp = V [ a ][ b ];
            V [ a ][ b ] = V [ r ][ y ];
            V [ r ][ y ] = temp;
        }
    }

    //Usar Conjunto de Caracteres Multibyte para mudar o nome da fonte
    InvokDll.Cria_Fonte ( hdc, 1500, FW_REGULAR, 00, FALSE, FALSE, FALSE, L"alarm clock" );

    this->BackColor = System::Drawing::SystemColors::Control;

    for ( r = 0; r < TAM; r++ ) {
        for ( y = 0; y < TAM; y++ ) {

            InvokDll.ExtTextOutB ( hdc, 73 + y * 2733 + r * 203530"  ",
                RGB ( 240240240 ), RGB ( 000 ) );

            snprintf ( c, sizeof ( int ), "%d", V [ r ][ y ] );
            InvokDll.SetBkColorA ( hdc, RGB ( 123234255 ) );
            InvokDll.SetTextColorA ( hdc, ( 2525112 ) );
            InvokDll.TextOut_4 ( hdc, &c, 80 + y * 2740 + r * 20 );
        }
    }

    g->ReleaseHdc ( hdc );
}
       //====================================================================================
       //Pesquisando na matriz
private: System::Void button3_Click ( System::Object^ sender, System::EventArgs^ e ) {

    Graphics^ g = this->CreateGraphics ( );

    CallDll InvokDll;

    IntPtr hdc = g->GetHdc ( );

    String^ str_1 = textBox1->Text;

    char Str [ 50 ] = { 0 };
    if ( str_1->Length < sizeof ( Str ) )
        sprintf ( Str, "%s", str_1 );

    std::string stl ( Str );
    printf ( "%s", Str );

    int Result = atoi ( stl.c_str ( ) );

    printf ( "%d", Result );

    if ( Result > 100 || Result <= 0 ) {
        Beep ( 500500 );
        textBox1->Focus ( );
        //limpa o campo do TextBox a cada novo click do botão
        textBox1->Clear ( );
        return;
    }

    int i, j;

    c = ( char* ) malloc ( 120 );

    //Usar Conjunto de Caracteres Multibyte para mudar o nome da fonte
    InvokDll.Cria_Fonte ( hdc, 1500, FW_REGULAR, 00, FALSE, FALSE, FALSE, L"alarm clock" );
    InvokDll.SetBkColorA ( hdc, RGB ( 123234255 ) );

    for ( i = 0; i < TAM; i++ ) {
        for ( j = 0; j < TAM; j++ ) {

            if ( V [ i ][ j ] == Result ) {

                snprintf ( c, sizeof ( int ), "%d", V [ i ][ j ] );
                InvokDll.SetBkColorA ( hdc, RGB ( 2550255 ) );
                InvokDll.TextOut_4 ( hdc, &c, 80 + j * 2740 + i * 20 );

            } else {
                snprintf ( c, sizeof ( int ), "%d", V [ i ][ j ] );
                InvokDll.SetBkColorA ( hdc, RGB ( 123234255 ) );
                InvokDll.SetTextColorA ( hdc, ( 2525112 ) );
                InvokDll.TextOut_4 ( hdc, &c, 80 + j * 2740 + i * 20 );
            }
        }
    }
    if ( Result < 100 || Result > 0 ) {
        Beep ( 500500 );
        textBox1->Focus ( );
        //limpa o campo do TextBox a cada novo click do botão
        textBox1->Clear ( );
        return;
    }
    g->ReleaseHdc ( hdc );
}

       //====================================================================================
       void Arm_Temp ( int& xint& y ) {
           int temp = x;
           x = y;
           y = temp;
       }
       //====================================================================================
       //Ordenando a matriz no modo descendente
private: System::Void button2_Click ( System::Object^ sender, System::EventArgs^ e ) {

    label2->Text = "";
    Label_2 ( 901326017"Ordenando a matriz no modo descendente" );

    Graphics^ g = this->CreateGraphics ( );

    CallDll InvokDll;

    IntPtr hdc = g->GetHdc ( );

    int i, k, l, j, tmp;

    for ( i = 0; i < TAM; i++ ) {
        for ( j = 0; j < TAM; j++ ) {
            tmp = V [ i ][ j ];
            l = j + 1;
            for ( k = i; k < TAM; k++ ) {
                while ( l < TAM ) {
                    if ( tmp < V [ k ][ l ] ) {
                        tmp = V [ k ][ l ];
                        V [ k ][ l ] = V [ i ][ j ];
                        V [ i ][ j ] = tmp;
                    }
                    l++;
                }
                l = 0;
            }

        }
    }

    //Usar Conjunto de Caracteres Multibyte para mudar o nome da fonte
    InvokDll.Cria_Fonte ( hdc, 1500, FW_REGULAR, 00, FALSE, FALSE, FALSE, L"alarm clock" );

    this->BackColor = System::Drawing::SystemColors::Control;

    for ( i = 0; i < TAM; i++ ) {
        for ( j = 0; j < TAM; j++ ) {

            InvokDll.ExtTextOutB ( hdc, 73 + j * 2733 + i * 203530"  ",
                RGB ( 240240240 ), RGB ( 000 ) );

            snprintf ( c, sizeof ( int ), "%d", V [ i ][ j ] );
            printf ( "%3d", V [ i ][ j ] );
            InvokDll.SetBkColorA ( hdc, RGB ( 123234255 ) );
            InvokDll.SetTextColorA ( hdc, ( 2525112 ) );
            InvokDll.TextOut_4 ( hdc, &c, 80 + j * 2740 + i * 20 );
        }
    }

    g->ReleaseHdc ( hdc );
}
       //====================================================================================
        //Ordenando a matriz no modo ascendente
private: System::Void button4_Click ( System::Object^ sender, System::EventArgs^ e ) {
    label2->Text = "";
    Label_2 ( 901326017"Ordenando a matriz no modo ascendente" );

    Graphics^ g = this->CreateGraphics ( );

    CallDll InvokDll;

    IntPtr hdc = g->GetHdc ( );

    int i, k, l, tmp, j, m, x;

    for ( k = 0; k < TAM; k++ ) {
        for ( m = 0; m < TAM; m++ ) {
            x = m + 1;
            for ( i = k; i < TAM; i++ ) {
                for ( j = x; j < TAM; j++ ) {
                    if ( V [ k ][ m ] > V [ i ][ j ] )
                        Arm_Temp ( V [ k ][ m ], V [ i ][ j ] );
                }
                x = 0;
            }
        }
    }

    //Usar Conjunto de Caracteres Multibyte para mudar o nome da fonte
    InvokDll.Cria_Fonte ( hdc, 1500, FW_REGULAR, 00, FALSE, FALSE, FALSE, L"alarm clock" );

    this->BackColor = System::Drawing::SystemColors::Control;

    for ( i = 0; i < TAM; i++ ) {
        for ( j = 0; j < TAM; j++ ) {

            InvokDll.ExtTextOutB ( hdc, 73 + j * 2733 + i * 203530"  ",
                RGB ( 240240240 ), RGB ( 000 ) );

            snprintf ( c, sizeof ( int ), "%d", V [ i ][ j ] );
            printf ( "%3d", V [ i ][ j ] );
            InvokDll.SetBkColorA ( hdc, RGB ( 123234255 ) );
            InvokDll.SetTextColorA ( hdc, ( 2525112 ) );
            InvokDll.TextOut_4 ( hdc, &c, 80 + j * 2740 + i * 20 );
        }
    }

    g->ReleaseHdc ( hdc );
}
       //====================================================================================
private: System::Void Form1_Shown ( System::Object^ sender, System::EventArgs^ e ) {
    Label_2 ( 901322017"Abaixo a impressão normal da matriz" );
    Label_1 ( 8024511520"Digite um número" );
    TextBox_1 ( 802688020" " );
    Button_1 ( 2652458020"Embaralha" );
    Button_2 ( 21830013020"Ordena descendente" );
    Button_3 ( 2662718020"Procurar" );
    Button_4 ( 8030013020"Ordena ascendente" );

}
       //====================================================================================
};

//Chamando deste modo abaixo abre o console
//junto com o form.

/*
//====================================================================================
[ STAThreadAttribute ]
int main ( ) {
    Application::Run ( gcnew Form1 ( ) );
    return 0;
}
*/
//====================================================================================
int APIENTRY WinMain ( HINSTANCE hInstance,
    HINSTANCE hPrevInstance,
    LPSTR lpCmdLine,
    int nCmdShow ) {
    Application::Run ( gcnew Form1 ( ) );

    return 0;
}
//====================================================================================