Ir ao conteúdo

_FBO_

Membro Júnior
  • Posts

    10
  • Cadastrado em

  • Última visita

  1. No visual studio estou tentando fazer a chamada de uma função de um form em outro form mas não está dando certo. Criei uma aplicação Windows Forms App (.NET Framework) e criei dois forms. No primeiro form eu criei uma lista de uma struct e uma função que recebe um parâmetro correspondente a um item da struct pra receber o outro. Mas o segundo Form não consegue encontrar a função definida no primeiro form: //Form1.cs using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace CS_Teste { public struct Valor { public string nome; public int valor; public Valor(String name, int value) { nome = name; valor = value; } } public partial class Form1 : Form { List<Valor> valores = new List<Valor>(); public Form1() { InitializeComponent(); valores.Add(new Valor("ABC",1)); valores.Add(new Valor("DEF", 2)); valores.Add(new Valor("GHI", 3)); } public int EncontraValorPeloNome(string nome) { for (int i = 0; i < valores.Count; i++) { if (valores[i].nome.Equals(nome)) { return valores[i].valor; } } return -1; } } } //------------------------------------------------------------------// //Form2.cs using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace CS_Teste { public partial class Form2 : Form { public Form2() { InitializeComponent(); } private void Form2_Load(object sender, EventArgs e) { Form1.EncontraValorPeloNome("ABC"); // *** erro *** } } } Obs.: sei que este código por enquanto não tem nada útil mas a partir do momento em que conseguir avançar na questão apontada aqui, poderei fazer coisas realmente uteis Encontrei a resposta. No arquivo Program.cs eu tenho que criar um objeto do form1 pra depois poder acessar no form2: //Program.cs using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using System.Windows.Forms; namespace CS_Teste { internal static class Program { public static Form1 form1; //<------- declaração da instancia /// <summary> /// The main entry point for the application. /// </summary> [STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); form1 = new Form1(); //<------- deve ser criado depois de "Application.SetCompatibleTextRenderingDefault(false);" Application.Run(form1); //<------- chama o form } } } //------------------------------------- // Agora pode ser usado no Form2 //------------------------------------- //Form2.cs using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace CS_Teste { public partial class Form2 : Form { public Form2() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { label1.Text = Program.form1.EncontraValorPeloNome("ABC").ToString(); //<--- chama a função através do comando "Program.form1.xxxx" } } }
      • 1
      • Obrigado
  2. _FBO_

    C++ Callback em C++ como no delphi

    Era isso mesmo o que eu estava querendo saber: como vincular uma função de fora do contexto da classe de modo que a classe pudesse chamá-la em sua rotina. Esse seu exemplo de passar como parâmetro ou atribuir a função diretamente à propriedade da instancia da classe era o que eu não estava conseguindo fazer. No final das contas eu vou programar em C++ numa IDE própria de um microcontrolador que será montado num hardware que tem teclas e um display. O objetivo é poder apresentar campos digitáveis na tela, em que eu possa pegar os valores que o usuario digita e colocá-los em variáveis que serão usadas para controlar o comportamento do sistema. Muito obrigado a todos que ajudaram
  3. _FBO_

    C++ Callback em C++ como no delphi

    Deu certo, muito obrigado pela sua ajuda e paciência. Segue o codigo funcionando: //Edit1.h class Edit; typedef void (*TNotifyEvent)(Edit* sender); typedef void (*TOnKeyPress )(Edit* sender, char Key); class Edit{ private: char lastKey; string buff; public: Edit(); virtual ~Edit(); void CheckKeys(); string text; TOnKeyPress OnKeyPress; TNotifyEvent OnEditingDone; }; //Edit.cpp #include "Edit.h" Edit::Edit() { text.clear(); buff.clear(); lastKey= '\0'; OnKeyPress = NULL; OnEditingDone = NULL; } Edit::~Edit() { } void Edit::CheckKeys() { if((GetAsyncKeyState(48) < 0)&&(lastKey != '0')){ buff+= '0'; lastKey= '0'; } if((GetAsyncKeyState(49) < 0)&&(lastKey != '1')){ buff+= '1'; lastKey= '1'; } if((GetAsyncKeyState(50) < 0)&&(lastKey != '2')){ buff+= '2'; lastKey= '2'; } if((GetAsyncKeyState(51) < 0)&&(lastKey != '3')){ buff+= '3'; lastKey= '3'; } if((GetAsyncKeyState(52) < 0)&&(lastKey != '4')){ buff+= '4'; lastKey= '4'; } if((GetAsyncKeyState(53) < 0)&&(lastKey != '5')){ buff+= '5'; lastKey= '5'; } if((GetAsyncKeyState(54) < 0)&&(lastKey != '6')){ buff+= '6'; lastKey= '6'; } if((GetAsyncKeyState(55) < 0)&&(lastKey != '7')){ buff+= '7'; lastKey= '7'; } if((GetAsyncKeyState(56) < 0)&&(lastKey != '8')){ buff+= '8'; lastKey= '8'; } if((GetAsyncKeyState(57) < 0)&&(lastKey != '9')){ buff+= '9'; lastKey= '9'; } if(GetAsyncKeyState(13) < 0) { lastKey = '\0'; text = buff; buff.clear(); if(this->OnEditingDone != NULL) { this->OnEditingDone(this); } } else { if(this->OnKeyPress != NULL) { this->OnKeyPress(this, lastKey); } } } //Main.cpp #include "Edit.h" #include <stdio.h> #include <windows.h> using namespace std; Edit* edit1; void Edit1_OnKeyPress(Edit* Sender, char Key) { printf("OnKeyPress chamado: %c", Key); } void Edit1_OnEditingDone(Edit* Sender) { printf("OnEditingDone chamado: %s", Sender->text); } int main() { edit1 = new Edit; edit1->OnKeyPress = Edit1_OnKeyPress; edit1->OnEditingDone = Edit1_OnEditingDone; while(1) { edit1->CheckKeys(); } delete edit1; return 0; }
  4. _FBO_

    C++ Callback em C++ como no delphi

    A logica eu vou refinar depois, é mais o conceito que estou tentando acertar. Poderia fazer um exemplo de como eu indico pra uma instancia de uma classe qual função ela deve chamar quando ocorrer uma determinada ação? Por exemplo no caso de um campo de texto, quando o usuario terminar de editar, quero que ele chame uma função que foi apontada pra receber o evento "OnEditingDone". Poderia fazer um exemplo pra mim por favor de como eu declaro isso na classe e como eu passo a função pra instancia dessa classe? Exemplo: //Edit.h Classe Edit{ private: //declarações privadas public: //declarações publicas OnEditingDone(Edit* sender); // <------- como fica a declaração na classe? }; //main.cpp #include <stdio> #include <Edit.h> Edit* edit; void Edit_OnEditDone(Edit* sender) { printf("Evento OnEditingDone chamado!"); } int main() { edit = new Edit; edit->SetOnEditDone(&Edit_OnEditDone); // <------ como indicar a função que quero que seja executada? while(1) { //... } }
  5. _FBO_

    C++ Callback em C++ como no delphi

    Sim a questão é que o que eu quero fazer é um ponteiro pra função pra ser usada como callback. Tentei fazer como o código abaixo mas dá erro, não compila... Eu dei uma pesquisada em algo que usa a biblioteca <Functionals> e usa Bind ou Lamba mas não entendi nada kkk //Edit.h using namespace std; class Edit; //forward declaration typedef void (*NotifyEvent)(void* Edit); typedef void (*OnKeyPress)(void* Edit, char key); class Edit{ private: char lastKey; string text; string buff; public: OnKeyPress OnKeyPress; // *** erro *** NotifyEvent OnEditingDone; // *** erro *** Edit(); virtual ~Edit(); void CheckKeys(); }; //Edit.cpp Edit::Edit() { lastKey= '\0'; text.Clear(); buff.Clear(); OnKeyPress = nullptr; OnEditingDone = nullptr; } Edit::~Edit() { } void Edit::CheckKeys() { if((GetAsyncKeyState(48) < 0)&&(lastKey != '0')){ buff+= '0'; lastKey= '0'; } if((GetAsyncKeyState(49) < 0)&&(lastKey != '1')){ buff+= '1'; lastKey= '1'; } if((GetAsyncKeyState(50) < 0)&&(lastKey != '2')){ buff+= '2'; lastKey= '2'; } if((GetAsyncKeyState(51) < 0)&&(lastKey != '3')){ buff+= '3'; lastKey= '3'; } if((GetAsyncKeyState(52) < 0)&&(lastKey != '4')){ buff+= '4'; lastKey= '4'; } if((GetAsyncKeyState(53) < 0)&&(lastKey != '5')){ buff+= '5'; lastKey= '5'; } if((GetAsyncKeyState(54) < 0)&&(lastKey != '6')){ buff+= '6'; lastKey= '6'; } if((GetAsyncKeyState(55) < 0)&&(lastKey != '7')){ buff+= '7'; lastKey= '7'; } if((GetAsyncKeyState(56) < 0)&&(lastKey != '8')){ buff+= '8'; lastKey= '8'; } if((GetAsyncKeyState(57) < 0)&&(lastKey != '9')){ buff+= '9'; lastKey= '9'; } if(GetAsyncKeyState(13) < 0) { lastKey= '\0'; Text= buff; buff.Clear(); if(OnEditingDone != nullptr) { OnEditingDone(this); } } if(OnKeyPress != nullptr) { OnKeyPress(this, lastKey); } }
  6. Olá. Será que é possível fazer um sistema de callback em C++ semelhante ao delphi (linguagem pascal)? Meu objetivo é usar em microcontroladores, no qual vou mostrar num display uns campos editaveis. Por exemplo, no delphi eu declaro os tipos de funções que serão usadas como callback e coloco como se fosse uma variavel numa classe: //declaração dos tipos dos eventos type TNotifyEvent = procedure(Sender: TObject) of object; type TKeyPressEvent = procedure(Sender: TObject; Key: char) of object; //definição da classe "MyEdit" TMyEdit = class private lastKey: char; Text: string; buff: string; public OnEditingDone: TNotifyEvent; //declaração de um callback do tipo TNotifyEvent OnKeyPress: TKeyPressEvent; //declaração de um callback do tipo TKeyPressEvent constructor Create; destructor Destroy; override; procedure CheckKeys(); end; implementation { TMyEdit } constructor TMyEdit.Create; begin buff:= ''; lastKey:= #0; OnEditingDone:= nil; OnKeyPress:= nil; end; destructor TMyEdit.Destroy; begin end; procedure TMyEdit.CheckKeys; begin if(GetAsyncKeyState(48) < 0)and(lastKey <> '0')then begin buff:= buff + '0'; lastKey:= '0'; end; if(GetAsyncKeyState(49) < 0)and(lastKey <> '1')then begin buff:= buff + '1'; lastKey:= '1'; end; if(GetAsyncKeyState(50) < 0)and(lastKey <> '2')then begin buff:= buff + '2'; lastKey:= '2'; end; if(GetAsyncKeyState(51) < 0)and(lastKey <> '3')then begin buff:= buff + '3'; lastKey:= '3'; end; if(GetAsyncKeyState(52) < 0)and(lastKey <> '4')then begin buff:= buff + '4'; lastKey:= '4'; end; if(GetAsyncKeyState(53) < 0)and(lastKey <> '5')then begin buff:= buff + '5'; lastKey:= '5'; end; if(GetAsyncKeyState(54) < 0)and(lastKey <> '6')then begin buff:= buff + '6'; lastKey:= '6'; end; if(GetAsyncKeyState(55) < 0)and(lastKey <> '7')then begin buff:= buff + '7'; lastKey:= '7'; end; if(GetAsyncKeyState(56) < 0)and(lastKey <> '8')then begin buff:= buff + '8'; lastKey:= '8'; end; if(GetAsyncKeyState(57) < 0)and(lastKey <> '9')then begin buff:= buff + '9'; lastKey:= '9'; end; if(GetAsyncKeyState(13) < 0)then begin lastKey:= #0; Text:= buff; buff:= ''; if(Assigned(OnEditingDone))then begin OnEditingDone(self); end; end; if(Assigned(OnKeyPress))then begin OnKeyPress(self, lastKey); end; end; //------------------------------------------------------------------------------// // no Formulario: type { TForm1 } TForm1 = class(TForm) TimerProcess: TTimer; procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure TimerProcessTimer(Sender: TObject); private public edit1: TMyEdit; procedure Edit1_EditingDone(Sender: TObject); end; implementation procedure TForm1.FormCreate(Sender: TObject); begin edit1:= TMyEdit.Create; edit1.OnEditingDone:= @Edit1_EditingDone; //define a função a ser chamada no callback TimerProcess.Period:= 100; //mS TimerProcess.Enabled:= True; end; procedure TForm1.FormDestroy(Sender: TObject); begin TimerProcess.Enabled:= False; end; procedure TForm1.TimerProcessTimer(Sender: TObject); begin edit1.CheckKeys(); end; procedure TForm1.Edit1_EditingDone(Sender: TObject); begin ShowMessage('Callback EditingDone chamado!'); end; Tem como fazer algo semelhante no C++? Se não tiver, como funciona a questão de eventos no C++? Muito obrigado
  7. Muito interessante, é uma nova maneira em que eu não havia pensado. Vou fazer desta maneira. E muito obrigado pelas considerações que me ajudam a melhorar cada vez mais. Abraço
  8. Certo vou tentar explicar melhor o que estou tentando fazer: ter um código generico, que eu possa reutilizar em varios programas, pra fazer interface de acesso a leitura/edição de variaveis. Pra isso eu gero vetores de uma estrutura para categorizar um grupo de variaveis. Vou apresentar um exemplo: um sistema que faz o controle de uma impressora 3D. Este sistema possui parametros de ajustes genericos como velocidade de execução, temperatura da mesa e da extrusora e parametros de cada motor. Para categorizar esses parametros utilizando meu codigo seria algo como: typedef struct{ char *descricao; void *variavel; char tipo; }params_t; //tela de parametros genericos (veja obsevacao ao termino da definição do vetor "Params0") params_t Params0[]={ {"Tempo restante (seg)", &tempo_restante, FLOAT}, {"Velocidade de execucao (mm/min)", &feed_rate, FLOAT}, {"Temperatura da mesa (graus)", &temper_mesa, FLOAT}, {"Temperatura da extrusora (graus)", &temper_extrusora, FLOAT}, {NULL,NULL,NULL} }; //osb: o campo "Tempo restante (seg)" é atualizado automaticamente em outro trecho do programa, permitindo que o usuario fique monitorando seu valor enquanto permanece com o vetor "Params0" carregado como sendo o vetor em uso. Os demais campos servem como edição para configurar o comportamento da maquina. //parametros do eixo X params_t Params1[]{ {"Posicao atual (mm)", &medida_x, FLOAT}, {"Ajuste de medida", &steps_per_mm_x, FLOAT}, {"Velocidade maxima (mm/min)", &max_speed_x, UINT}, {"Limite eletrônico (mm)", &lim_x, UINT}, {NULL,NULL,NULL} }; //osb: o campo "Posicao atual (mm)" é atualizado automaticamente em outro trecho do programa, permitindo que o usuario fique monitorando seu valor enquanto permanece com o vetor "Params1" carregado como sendo o vetor em uso. Os demais campos servem como edição para configurar o comportamento da maquina. //parametros do eixo Y params_t Params2[]{ {"Posicao atual (mm)", &medida_y, FLOAT}, {"Ajuste de medida", &steps_per_mm_y, FLOAT}, {"Velocidade maxima (mm/min)", &max_speed_y, UINT}, {"Limite eletrônico (mm)", &lim_y, UINT}, {NULL,NULL,NULL} }; //osb: o campo "Posicao atual (mm)" é atualizado automaticamente em outro trecho do programa, permitindo que o usuario fique monitorando seu valor enquanto permanece com o vetor "Params2" carregado como sendo o vetor em uso. Os demais campos servem como edição para configurar o comportamento da maquina. Veja que tenho campos utilizados para leitura, que podem ser atualizados a qualquer momento em outros trechos do programa, que devem ser apresentados constantemente para o usuario e tenho também campos que somente são alterados por entrada de valor do usuário, não necessitando ser apresentado constantemente. Com isso eu daria um refresh na apresentação de todo o conteudo do vetor em uso apenas quando o usuario selecionar qual o vetor quer colocar em uso e daria refresh constantemente apenas do conteúdo que foi alterado. Aí que entra o "truque" que quero implementar: ter um espelho do vetor em uso para que eu possa comparar e ver quais os campos que foram alterados para fazer o refresh seletivo, a fim de poupar tempo de execução. Seria algo como essa sequencia: 1. espera usuario selecionar um vetor de parametros para visualizar/editar 2. apresenta o conteúdo do vetor selecionado (seja num display, via comunicação serial, etc) 3. carrega o conteúdo do vetor selecionado para um vetor espelho (alocação dinâmica) 4. monitora quais valores do vetor selecionado apresentam diferença em relação aos valores do vetor espelho (faz um "for" comparando os valores do vetor selecionado com o vetor espelho). 5. atualiza para o usuario os campos que sofreram alteração, seja num display, via comunicação serial, etc) 6. carrega o valor do campo alterado no vetor selecionado para o valor correspondente no vetor espelho para novas comparações durante o monitoramento 7. repete passos 4 a 6 enquanto o usuario não selecionar outro vetor diferente. Note que o conteúdo dos vetores de parametros podem ter campos com diferentes informações de texto, diferentes variaveis relacionadas e de diferentes tipos. Com este código posso facilmente acrescentar/remover novos parametros e assim reutilizar este código em outras aplicações que seguem o mesmo modelo de categorias de parametros
  9. Agradeço as considerações. Realmente faltou eu explicar algo: este aplicativo que apresentei foi com o intuito de exemplificar o problema que tenho em um programa embarcado. Então eu extraí trechos do código e montei este aplicativo de exemplo para que possam visualizar o problema principal: ter um espelho do conteúdo do vetor da estrutura apontada pela variável "item". E no vetor pode ter variaveis que em outro trecho do programa terão seu valor alterado por leitura de periféricos como sensores. O objetivo final é utilizar as estruturas como a interface central, onde posso apenas acrescentar uma nova linha referenciando uma variavel que poderá ser utilizada para apresentar ao usuario a leitura de algum sensor ou permitir que o usuario altere o valor de variaveis. Porém, por ser um sistema embarcado, não quero ficar reapresentando toda a tabela para o usuario se não houver atualização, posso enviar apenas as variaveis que tiveram seus valores modificados, seja por propria entrada do usuario ou seja por atualização proveniente de outras partes do programa. Com isso planejo economizar tempo de processamento do sistema. Eu não quero tambem consumir memória desnecessaria fazendo um espelho de todos os vetores de "estrutura_t" que posso ter. Neste exemplo eu apresentei apenas 2 vetores instanciados em "item_tab", mas posso ter vários vetores, cada um contendo várias entradas do tipo "estrutura_t". Por isso que, ao pegar o ponteiro de um vetor (variavel "item"), quero criar um espelho neste momento apenas do vetor apontado por "item", liberando da memória o espelho anterior antes de alocar um novo espelho
  10. Olá. Estou com dificuldade num código e preciso de ajuda... Tenho vetores de structs e um ponteiro para o vetor que está em uso (variavel "item" no codigo abaixo). Estou com essas dificuldades: 1. contar quantos itens tem em cada estrutura (veja variavel "qtd_items" no codigo abaixo) 2. como gerar um vetor clone (veja variavel "mirror" no codigo abaixo) que serve para monitorar alterações nas variaveis do vetor de "estrutura_t". Talvez pense: "mas dá pra saber quando o usuario faz alguma alteração de valores no código então não precisa ter um clone dos valores pra isso". Mas na verdade essas alterações não vão se limitar a operações de usuario, podem vir por causas externas (imagine que uma variavel apontada em uma das estruturas seja uma variavel de leitura de um sinal de sensor ou um contador de eventos de interrupção do sistema, então não dá pra saber quando houve alteração então por isso preciso de um clone da estrutura em uso para monitorar quando houver alterações pra poder salvar). 3. melhorias para a estrutura "item_t" também são bem-vindas, não sei se preciso dela para indicar qual vetor de "estrutura_t" está em uso, tentei de outra maneira mas não consegui compilar... Muito obrigado #include <stdio.h> #include <stdlib.h> #include <math.h> //definicoes #define UINT 0 #define ULONG 1 #define FLOAT 3 //declaracao de estruturas typedef struct{ char *descricao; void *variavel; char tipo; }estrutura_t; typedef struct{ estrutura_t *estrutura; char dummy; }item_t; union FloatBytes{ float f; unsigned char bytes[4]; }; //declaracao de variaveis unsigned int uint1,uint2,uint3; unsigned long ulong1,ulong2,ulong3; float float1,float2,float3; item_t *item; //ponteiro que indica a estrutura em uso item_t *mirror; //variavel que contem uma copia da estrutura em uso int qtd_items,current_index; //declaracao e inicializacao de vetores estrutura_t estrutura0[4]= { {"primeiro item", &uint1, UINT}, {"segundo item", &uint2, UINT}, {"terceito item", &float1, FLOAT}, {NULL,NULL,NULL} }; estrutura_t estrutura1[6]= { {"descricao da linha 1", &ulong1, ULONG}, {"conteudo da linha 2", &float2, FLOAT}, {"qualquer conteudo aqui", &uint3, UINT}, {"texto informativo", &ulong2, ULONG}, {"quinta linha", &uint3, UINT}, {NULL,NULL,NULL} }; item_t item_tab[2]={ {estrutura0,0}, {estrutura1,0}, }; void load_values(void) { int i,j; FILE *fp; char filename[10]; unsigned char buffer[4]; for(i=0; i<2; i++) { item= &item_tab[i]; //descobre quantos itens tem no vetor de estrutura apontado por "item" //aqui eu precisava de um jeito melhor de descobrir a quantidade de itens qtd_items=0; for(j=0; j<100; j++) { if(item->estrutura[j].descricao != NULL) qtd_items++; else break; } //agora carrega o arquivo que contem os valores das estruturas sprintf(filename,"file_%d.bin", i); fp= fopen(filename, "rb"); if(fp != NULL) { for(j=0; j<qtd_items; j++) { if(item->estrutura[j].tipo == UINT) { unsigned int temp_word; fread(buffer,2,1,fp); temp_word= buffer[0] << 8 | buffer[1]; *(unsigned int*)item->estrutura[j].variavel= temp_word; } else if(item->estrutura[j].tipo == ULONG) { unsigned long temp_long; fread(buffer,4,1,fp); temp_long= buffer[0] << 24 | buffer[1] << 16 | buffer[2] << 8 | buffer[3]; *(unsigned long*)item->estrutura[j].variavel= temp_long; } else if(item->estrutura[j].tipo == FLOAT) { union FloatBytes fb; fread(fb.bytes,4,1,fp); *(float*)item->estrutura[j].variavel= fb.f; } } fclose(fp); } } } void printa(void) //printa a estrutura em uso { int i; for(i=0; i<qtd_items; i++) { if(item->estrutura[i].tipo == UINT) printf("\r\n[%d] %s= %u", i, item->estrutura[i].descricao, *(unsigned int*)item->estrutura[i].variavel); else if(item->estrutura[i].tipo == ULONG) printf("\r\n[%d] %s= %lu", i, item->estrutura[i].descricao, *(unsigned long*)item->estrutura[i].variavel); else if(item->estrutura[i].tipo == FLOAT) printf("\r\n[%d] %s= %f", i, item->estrutura[i].descricao, *(float*)item->estrutura[i].variavel); } } void gerencia_alteracoes(void) { int number; do{ printf("\r\nDeseja alterar qual variavel? (Insira -1 para cancelar): "); scanf("%d", &number); if(number == -1) return; }while(number < 0 || number > qtd_items); if(item->estrutura[number].tipo == UINT) { printf("\r\n[%d] %s= %u", number, item->estrutura[number].descricao, *(unsigned int*)item->estrutura[number].variavel); printf("\r\nInsira o novo valor: "); scanf("%u",(unsigned int*)item->estrutura[number].variavel); } else if(item->estrutura[number].tipo == ULONG) { printf("\r\n[%d] %s= %lu", number, item->estrutura[number].descricao, *(unsigned long*)item->estrutura[number].variavel); printf("\r\nInsira o novo valor: "); scanf("%lu",(unsigned long*)item->estrutura[number].variavel); } else if(item->estrutura[number].tipo == FLOAT) { printf("\r\n[%d] %s= %f", number, item->estrutura[number].descricao, *(float*)item->estrutura[number].variavel); printf("\r\nInsira o novo valor: "); scanf("%f",(float*)item->estrutura[number].variavel); } } void salva_alteracoes(void) { int i; char changed= 0; for(i=0; i<qtd_items; i++) { if(item->estrutura[i].tipo == UINT) { unsigned int ui1= *(unsigned int*)item->estrutura[i].variavel; unsigned int ui2= *(unsigned int*)mirror->estrutura[i].variavel; if(ui1 != ui2) { *(unsigned int*)mirror->estrutura[i].variavel= ui1; changed= 1; break; } } else if(item->estrutura[i].tipo == ULONG) { unsigned long ul1= *(unsigned long*)item->estrutura[i].variavel; unsigned long ul2= *(unsigned long*)mirror->estrutura[i].variavel; if(ul1 != ul2) { *(unsigned long*)mirror->estrutura[i].variavel= ul1; changed= 1; break; } } else if(item->estrutura[i].tipo == FLOAT) { float f1= *(float*)item->estrutura[i].variavel; float f2= *(float*)mirror->estrutura[i].variavel; if(fabs(f1 - f2) < 0.001) { *(float*)mirror->estrutura[i].variavel= f1; changed= 1; break; } } } if(changed) { FILE *fp; char filename[10]; unsigned char buffer[4]; sprintf(filename, "file_%d.bin", current_index); fp= fopen(filename,"wb"); for(i=0; i<qtd_items; i++) { if(item->estrutura[i].tipo == UINT) { buffer[0]= *(unsigned int*)item->estrutura[i].variavel >> 8; buffer[1]= *(unsigned int*)item->estrutura[i].variavel & 0xFF; fwrite(buffer,1,2,fp); } else if(item->estrutura[i].tipo == ULONG) { buffer[0]= *(unsigned long*)item->estrutura[i].variavel >> 24; buffer[1]= *(unsigned long*)item->estrutura[i].variavel >> 16; buffer[2]= *(unsigned long*)item->estrutura[i].variavel >> 8; buffer[3]= *(unsigned long*)item->estrutura[i].variavel & 0xFF; fwrite(buffer,1,4,fp); } else if(item->estrutura[i].tipo == FLOAT) { union FloatBytes fb; fb.f= *(float*)item->estrutura[i].variavel; fwrite(fb.bytes,1,4,fp); } } fclose(fp); } } void main(void) { int i; //carrega dados armazenados em arquivo para os vetores de "estrutura_t" load_values(); while(1) { //permite selecionar uma estrutura para visualizar/alterar do{ printf("\r\nQual menu deseja visualizar (0 ou 1)? Insira -1 para sair: "); scanf("%d", &current_index); if(current_index == -1) { free(mirror); return; } }while(current_index < 0 || current_index > 1); //usuario selecionou uma estrutura, carrega-a item= &item_tab[current_index]; qtd_items= 0; for(i=0; i<100; i++) { if(item->estrutura[i].descricao != NULL) qtd_items++; else break; } //aqui preciso criar a copia mas não sei como pois o conteudo é variavel free(mirror); mirror= (item_t*)malloc(sizeof(???)); memcpy(mirror,item,sizeof(???)); //apresenta o conteudo da estrutura em uso printa(); //permite alterar o valor das variaveis da estrutura em uso gerencia_alteracoes(); //compara se houver alteração em relação ao mirror e salva salva_alteracoes(); } }

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...