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 ( 497, 12 );
this->button1->Name = L"button1";
this->button1->Size = System::Drawing::Size ( 75, 23 );
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 ( 497, 41 );
this->button2->Name = L"button2";
this->button2->Size = System::Drawing::Size ( 75, 23 );
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 ( 497, 70 );
this->textBox1->Name = L"textBox1";
this->textBox1->Size = System::Drawing::Size ( 75, 20 );
this->textBox1->TabIndex = 2;
//
// label1
//
this->label1->Location = System::Drawing::Point ( 514, 97 );
this->label1->Name = L"label1";
this->label1->Size = System::Drawing::Size ( 0, 13 );
this->label1->TabIndex = 3;
//
// button3
//
this->button3->Location = System::Drawing::Point ( 497, 97 );
this->button3->Name = L"button3";
this->button3->Size = System::Drawing::Size ( 75, 23 );
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 ( 497, 126 );
this->button4->Name = L"button4";
this->button4->Size = System::Drawing::Size ( 75, 23 );
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 ( 514, 162 );
this->label2->Name = L"label2";
this->label2->Size = System::Drawing::Size ( 0, 13 );
this->label2->TabIndex = 6;
//
// Form1
//
this->AutoScaleDimensions = System::Drawing::SizeF ( 6, 13 );
this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
this->BackColor = System::Drawing::SystemColors::Control;
this->ClientSize = System::Drawing::Size ( 600, 340 );
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 ( 350, 100 );
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 X, int Y, int W, int H, String^ st ) {
this->textBox1->Margin = System::Windows::Forms::Padding ( 4, 5, 4, 5 );
//this->textBox1->UseVisualStyleBackColor = true;
this->textBox1->AutoSize = true;
this->textBox1->Focus ( );
this->textBox1->Font = ( gcnew System::Drawing::Font ( L"Times New Roman",
10.25F, System::Drawing::FontStyle::Italic, System::Drawing::GraphicsUnit::Point,
static_cast< System::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 X, int Y, int W, int H, String^ st ) {
this->label1->Font = ( gcnew System::Drawing::Font ( L"Times New Roman",
10.25F, System::Drawing::FontStyle::Italic, System::Drawing::GraphicsUnit::Point,
static_cast< System::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 X, int Y, int W, int H, String^ st ) {
this->label2->Font = ( gcnew System::Drawing::Font ( L"Times New Roman",
10.25F, System::Drawing::FontStyle::Italic, System::Drawing::GraphicsUnit::Point,
static_cast< System::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 X, int Y, int W, int H, String^ st ) {
this->button1->Margin = System::Windows::Forms::Padding ( 4, 5, 4, 5 );
this->button1->UseVisualStyleBackColor = true;
this->button1->AutoSize = false;
this->button1->Font = ( gcnew System::Drawing::Font ( L"Times New Roman",
10.25F, System::Drawing::FontStyle::Italic, System::Drawing::GraphicsUnit::Point,
static_cast< System::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 X, int Y, int W, int H, String^ st ) {
this->button2->Margin = System::Windows::Forms::Padding ( 4, 5, 4, 5 );
this->button2->UseVisualStyleBackColor = true;
this->button2->AutoSize = false;
this->button2->Font = ( gcnew System::Drawing::Font ( L"Times New Roman",
10.25F, System::Drawing::FontStyle::Italic, System::Drawing::GraphicsUnit::Point,
static_cast< System::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 X, int Y, int W, int H, String^ st ) {
this->button3->Margin = System::Windows::Forms::Padding ( 4, 5, 4, 5 );
this->button3->UseVisualStyleBackColor = true;
//this->button3->AutoSize = true;
this->button3->Font = ( gcnew System::Drawing::Font ( L"Times New Roman",
10.25F, System::Drawing::FontStyle::Italic, System::Drawing::GraphicsUnit::Point,
static_cast< System::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 X, int Y, int W, int H, String^ st ) {
this->button4->Margin = System::Windows::Forms::Padding ( 4, 5, 4, 5 );
this->button4->UseVisualStyleBackColor = true;
//this->button4->AutoSize = true;
this->button4->Font = ( gcnew System::Drawing::Font ( L"Times New Roman",
10.25F, System::Drawing::FontStyle::Italic, System::Drawing::GraphicsUnit::Point,
static_cast< System::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::Object^ sender,
System::Windows::Forms::PaintEventArgs^ e ) {
CallDll InvokDll;
Graphics^ g = e->Graphics;
IntPtr hdc = g->GetHdc ( );
IntPtr hwnd = Process::GetCurrentProcess ( )->MainWindowHandle;
InvokDll.Gradiente ( hwnd, 0, 255, 255, 255, 0, 255 );
InvokDll.Moldura ( hdc, 5, 5, 590, 330, 10, 255, 0, 0, 255 );
InvokDll.TextOut_4 = ( int ( WINAPI* ) ( IntPtr hdc, char* text [ ], int xpos, int ypos ) )
GetProcAddress ( InvokDll.hDll, "TextOut_4" );
InvokDll.SetBkColorA ( hdc, RGB ( 123, 234, 255 ) );
InvokDll.SetTextColorA ( hdc, ( 25, 25, 112 ) );
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, 15, 0, 0, FW_REGULAR, 0, 0, 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 * 27, 40 + i * 20 );
}
}
InvokDll.Text_Designer ( hdc, 390, 60, 255, 75, 0, 130, L"POR :",
0.0, L"Arial", FontStyle::Italic, 48, 4, 135, 206, 250, 10, 173, 255, 47 );
InvokDll.Text_Designer ( hdc, 360, 120, 255, 75, 0, 130, L"SAMUEL",
0.0, L"Arial", FontStyle::Italic, 48, 4, 135, 206, 250, 10, 173, 255, 47 );
InvokDll.Text_Designer ( hdc, 390, 180, 255, 75, 0, 130, L"LIMA",
0.0, L"Arial", FontStyle::Italic, 48, 4, 135, 206, 250, 10, 173, 255, 47 );
g->ReleaseHdc ( hdc );
}
//====================================================================================
//Embaralhando a matriz
private: System::Void button1_Click ( System::Object^ sender, System::EventArgs^ e ) {
label2->Text = "";
Label_2 ( 90, 13, 260, 17, "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, 15, 0, 0, FW_REGULAR, 0, 0, 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 * 27, 33 + r * 20, 35, 30, " ",
RGB ( 240, 240, 240 ), RGB ( 0, 0, 0 ) );
snprintf ( c, sizeof ( int ), "%d", V [ r ][ y ] );
InvokDll.SetBkColorA ( hdc, RGB ( 123, 234, 255 ) );
InvokDll.SetTextColorA ( hdc, ( 25, 25, 112 ) );
InvokDll.TextOut_4 ( hdc, &c, 80 + y * 27, 40 + 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 ( 500, 500 );
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, 15, 0, 0, FW_REGULAR, 0, 0, FALSE, FALSE, FALSE, L"alarm clock" );
InvokDll.SetBkColorA ( hdc, RGB ( 123, 234, 255 ) );
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 ( 255, 0, 255 ) );
InvokDll.TextOut_4 ( hdc, &c, 80 + j * 27, 40 + i * 20 );
} else {
snprintf ( c, sizeof ( int ), "%d", V [ i ][ j ] );
InvokDll.SetBkColorA ( hdc, RGB ( 123, 234, 255 ) );
InvokDll.SetTextColorA ( hdc, ( 25, 25, 112 ) );
InvokDll.TextOut_4 ( hdc, &c, 80 + j * 27, 40 + i * 20 );
}
}
}
if ( Result < 100 || Result > 0 ) {
Beep ( 500, 500 );
textBox1->Focus ( );
//limpa o campo do TextBox a cada novo click do botão
textBox1->Clear ( );
return;
}
g->ReleaseHdc ( hdc );
}
//====================================================================================
void Arm_Temp ( int& x, int& 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 ( 90, 13, 260, 17, "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, 15, 0, 0, FW_REGULAR, 0, 0, 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 * 27, 33 + i * 20, 35, 30, " ",
RGB ( 240, 240, 240 ), RGB ( 0, 0, 0 ) );
snprintf ( c, sizeof ( int ), "%d", V [ i ][ j ] );
printf ( "%3d", V [ i ][ j ] );
InvokDll.SetBkColorA ( hdc, RGB ( 123, 234, 255 ) );
InvokDll.SetTextColorA ( hdc, ( 25, 25, 112 ) );
InvokDll.TextOut_4 ( hdc, &c, 80 + j * 27, 40 + 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 ( 90, 13, 260, 17, "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, 15, 0, 0, FW_REGULAR, 0, 0, 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 * 27, 33 + i * 20, 35, 30, " ",
RGB ( 240, 240, 240 ), RGB ( 0, 0, 0 ) );
snprintf ( c, sizeof ( int ), "%d", V [ i ][ j ] );
printf ( "%3d", V [ i ][ j ] );
InvokDll.SetBkColorA ( hdc, RGB ( 123, 234, 255 ) );
InvokDll.SetTextColorA ( hdc, ( 25, 25, 112 ) );
InvokDll.TextOut_4 ( hdc, &c, 80 + j * 27, 40 + i * 20 );
}
}
g->ReleaseHdc ( hdc );
}
//====================================================================================
private: System::Void Form1_Shown ( System::Object^ sender, System::EventArgs^ e ) {
Label_2 ( 90, 13, 220, 17, "Abaixo a impressão normal da matriz" );
Label_1 ( 80, 245, 115, 20, "Digite um número" );
TextBox_1 ( 80, 268, 80, 20, " " );
Button_1 ( 265, 245, 80, 20, "Embaralha" );
Button_2 ( 218, 300, 130, 20, "Ordena descendente" );
Button_3 ( 266, 271, 80, 20, "Procurar" );
Button_4 ( 80, 300, 130, 20, "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;
}
//====================================================================================