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;
}
//====================================================================================