/***************************************************
***********PAINT XY*********************************
***********AUTORE: DANY****************************
***********DATA: 13/06/2012************************
***********ORE: 14:41******************************
***********VERSIONE: 1.2***************************/
//Dichiarazione Header
#include <windows.h>
#include <Windowsx.h>
#include <commctrl.h>
#include <cmath>
#include <stack>
#include <fstream>
#include <cstring>
//Dichiarazione librerie:
#include "funzioni.h"
//Dichiarazioni per visual style (grafica win 7)
#pragma comment( lib, "comctl32.lib")
#pragma comment(linker, "/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
//Fine Dichiarazioni... //prima della p--> \
//Namespace:
using namespace std;
//Dichiarazione variabili globali:
//Class Name delle finestre
static char g_szClassName[] = "MainWindow",name[]="CurveWindow",name2[]="FunctionWindow",name3[]="SettingWindow";
static HINSTANCE g_hInst = NULL;
//Timer per la WM_Timer nella mainWindows
const UINT idTimer1 = 1;
UINT nTimerDelay = 1;
//Bitmap
HBITMAP hbmBall, hbmMask,griglia,maskgri;
BITMAP bm;
//Coordinate Punto funzione
int ballX, ballY;
//Variabile che indica se è stato cliccato il tasto disegna nella finestra delle curve
int agg=0;
//Font dei Caratteri:
RECT rect;
HFONT hfont;
LOGFONT lf;
//Precisione nel disegno delle funzioni
float prec=100;
float preprec; //Se si clicca annulla nella setting window ripristina il valore precedente di prec.
//Progress Bar in Curve Window
HWND prog;
//Progress Bar in function windows
HWND prog2;
//stringa che in function window contiene la funzione in notazione polacca inversa.
string rpn;
//Variabile che indica se il pulsante disegna in function window è stato premuto.
int funpress=0;
//Stringa che se nella function windows viene digitata una funzione correttamente, ne assume il contenuto.
char funzione[100]="";
//Per ridisegno funzioni in caso di copertura:
string cache[20]; int cachenum=0;
//Dichiarazione della WndProc Della MainWindow
LRESULT CALLBACK WndProc(HWND hwnd ,UINT Message, WPARAM wParam, LPARAM lParam);
//Disegna il punto utilizzato nelle rappresentazioni di cruve e funzioni.
void DrawBall(HDC hdc)
{
HDC hdcMemory;
hdcMemory = CreateCompatibleDC(hdc);
SelectObject(hdcMemory, hbmMask);
BitBlt(hdc, ballX, ballY, bm.bmWidth, bm.bmHeight, hdcMemory, 0, 0, SRCAND);
SelectObject(hdcMemory, hbmBall);
BitBlt(hdc, ballX, ballY, bm.bmWidth, bm.bmHeight, hdcMemory, 0, 0, SRCPAINT);
DeleteDC(hdcMemory);
}
//Disegna la griglia di sfondo
void DrawGriglia(HDC hdc)
{
HDC hdcMemory;
hdcMemory=CreateCompatibleDC(hdc);
SelectObject(hdcMemory, maskgri);
BitBlt(hdc, 0, 0, 1000, 1000, hdcMemory, 0, 0, SRCAND);
SelectObject(hdcMemory, griglia);
BitBlt(hdc, 0, 0, 1000, 1000, hdcMemory, 0, 0, SRCPAINT);
DeleteDC(hdcMemory);
}
//Converte le ascisse in coordinate x per la finestra
int conx(double s)
{
int con;
con=int(500+(s*50));
return con;
}
//Converte le ordinate in coordinate y per la finestra
int cony(double s)
{
int con;
con=int(500-(s*50));
return con;
}
//Controlla se il carattere nello stack è una funzione
int chkfun (char a)
{
if ((a=='s')||(a=='c')||(a=='t')||(a=='a')||(a=='b')||(a=='d')||(a=='h')||(a=='i')||(a=='j')||
(a=='L')||(a=='N')||(a=='D')||
(a=='A')||(a=='I')||(a=='P')||(a=='!')||(a=='V')||
(a=='R')||(a=='C')||(a=='Q'))
{
return 1;
}
else
return 2;
}
//Controlla se (nella Function Window) nella conversione RPN, un carattere è una costante (o una variabile) o un'operatore
int chkchar(char a)
{
if ((('0'<=a)&&(a<='9'))||(a=='x')||(a=='X')||(a=='p')||(a=='e')) //Il carattere è una cifra, una costante o la variabile x.
{
return 1;
}
if ((a=='+')||(a=='-')||(a=='*')||(a=='/')||(a=='^')||(a=='%')) //Il carattere è un operatore
{
return 2;
}
else
return 3;
}
//Controlla la precedenza tra 2 operatori
bool precedence(char op1, char op2)
{
int first=0;
if ((op1=='+')||(op1=='-'))
{
first=1;
}
if ((op1=='*')||(op1=='/')||(op1=='%'))
{
first=2;
}
if ((op1=='^')||(chkfun(op1)==1))
{
first=3;
}
/*******************/
int second=0;
if ((op2=='+')||(op2=='-'))
{
second=1;
}
if ((op2=='*')||(op2=='/')||(op2=='%'))
{
second=2;
}
if ((op2=='^')||(chkfun(op2)==1))
{
second=3;
}
if ((first == second)||( first < second))
return false;
else
return true;
}
//Conta le cifre di un numero intero
float numcif (int a)
{
double aa=a;
if (a<0)
{
aa=-a;
}
double b;
float c;
b=log10(aa);
c=ceil(b);
if (c==b)
{
c++;
}
if (a==0)
{
c=1;
}
return c;
}
/*************************************************************************************************************/
//Dichiarazione variabili in WndProc
//Variabili disegno funzione
double i,x,y;
double inc=0.01; /* 1/standard inc */
//Variabili Menu:
HMENU file,hfile,info,hinfo,modifica,hmodifica;
int MENU_FILE_EXIT=0; //Valore ritorno se si clicca su "Esci"
int MENU_FILE_CURV=1; //Valore ritorno se si clicca su "Disegna curve"
int MENU_FILE_FUNZ=2; //Valore ritorno se si clicca su "Disegna funzione"
int MENU_FILE_ABOU=3; //Valore ritorno se si clicca su "Informazioni su "Paint XY"
int MENU_FILE_CLEA=6; //Valore ritorno se si clicca su "Pulisci"
int MENU_FILE_SETT=7; //Valore ritorno se si clicca su "Opzioni"
//Variabile che specificano il tipo di curva scelto.
int curva; //retta=1,parabola=2,ellisse=3,iperbole=4,circonferenza=5,parabola(x)=6
//Variabili di lettura degli edit nella finestra delle curve...
char numa[5],numb[5],numc[5];
//...e di converzione di questi:
double a,b,c;
/*Array necessari per ridisegnare le curve nel caso si riduce a icona la finestra...
Gli array memorizzano i vari coefficienti per ogni curva e vengono letti per ridisegnarle.*/
double ca[20],cb[20],cc[20];
double da[20],db[20],dc[20];
double ea[20],eb[20],ec[20];
double fa[20],fb[20],fc[20];
double ga[20],gb[20],gc[20];
double ha[20],hb[20],hc[20];
//Variabili contatrici
int k=0,l=0,l2=0,l3=0,l4=0,l5=0,l6=0;
/*Variabile che indica se si è già tentato di disegnare la funzione:
Per non rendere troppo pesante l'avvio del programma, il prog inizierà a
ridisegnare le funzioni (se la finestra viene ridotta e riaperta) solo dopo
aver premuto il tasto "disegna" nella CurveWindow.*/
int bo=0;
/*Variabile contatrice di array di string che contengono rpn*/
int lo=0;
/*Variabili posizione mouse*/
HWND lex,ley;
float cox=0,coy=0;
char coox[4],cooy[4];
/*WNDPROC DELLA MAIN*/
LRESULT CALLBACK WndProc(HWND hwnd ,UINT Message, WPARAM wParam, LPARAM lParam)
{
InitCommonControls (); //Applicazione visual style
switch(Message)
{
case WM_CREATE:
//Nella finestra principale:
//Inizializzazione delle immagini BMP
hbmBall = LoadBitmap(g_hInst, "BALLBMP");
griglia = LoadBitmap(g_hInst, "gri");
hbmMask = LoadBitmap(g_hInst, "MASKBMP");
maskgri = LoadBitmap(g_hInst, "maskgri");
if(!hbmBall || !hbmMask)
{
MessageBox(hwnd, "Load of resources failed.", "Error",MB_OK | MB_ICONEXCLAMATION);
return -1;
}
GetObject(hbmBall, sizeof(bm), &bm);
//Timer:
SetTimer(hwnd, idTimer1, nTimerDelay, NULL);
//Menu:
//Dichiarazione Menu:
file=CreateMenu();
hfile=CreatePopupMenu();
info=CreateMenu();
hinfo=CreatePopupMenu();
modifica=CreateMenu();
hmodifica=CreatePopupMenu();
//Creazione Menu:
/*File*/
AppendMenu(file,MF_STRING|MF_POPUP,(UINT_PTR) hfile,TEXT("File"));
AppendMenu(hfile,MF_STRING,MENU_FILE_SETT,TEXT("Impostazioni"));
AppendMenu(hfile,MF_STRING,MENU_FILE_EXIT,TEXT("Esci"));
/*Modifica*/
AppendMenu(file,MF_STRING|MF_POPUP,(UINT_PTR) hmodifica,TEXT("Grafico"));
AppendMenu(hmodifica,MF_STRING,MENU_FILE_CURV,TEXT("Disegna Curve"));
AppendMenu(hmodifica,MF_STRING,MENU_FILE_FUNZ,TEXT("Disegna Funzione"));
AppendMenu(hmodifica,MF_STRING,MENU_FILE_CLEA,TEXT("Pulisci"));
/*Info*/
AppendMenu(file,MF_STRING|MF_POPUP,(UINT_PTR) hinfo,TEXT("Info"));
AppendMenu(hinfo,MF_STRING,MENU_FILE_ABOU,TEXT("Informazioni su Paint XY"));
//Rende visibile i menu
SetMenu(hwnd,file);
//Piccolo edit che scrive la posizione del mouse nella finestra:
lex=CreateWindow("edit","",WS_CHILD|WS_VISIBLE|ES_READONLY|WS_BORDER,5,5,50,20,hwnd,(HMENU)100,0,0);
ley=CreateWindow("edit","",WS_CHILD|WS_VISIBLE|ES_READONLY|WS_BORDER,60,5,50,20,hwnd,(HMENU)100,0,0);
/****SETTO I CARATTERI DA UTILIZZARE: FONT, DIMENSIONI ECC...**/
GetObject (GetStockObject(DEFAULT_GUI_FONT), sizeof(LOGFONT), &lf);
hfont = CreateFont (20,0,0,0, 500, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_OUTLINE_PRECIS,
CLIP_DEFAULT_PRECIS, CLEARTYPE_QUALITY, VARIABLE_PITCH, TEXT ("Monotype Corsiva"));
SendMessage (lex, WM_SETFONT, (WPARAM) hfont, true);
SendMessage (ley, WM_SETFONT, (WPARAM) hfont, true);
break;
case WM_TIMER:
if(hbmBall && hbmMask)
{
HDC hdcWindow;
hdcWindow = GetDC(hwnd);
//Disegno Curve***********************************************************************
if (agg>0) //Se è stato cliccato il tasto 'disegna' nella finestra delle curve
{
agg=0; //reimposta il tasto
i=-10;
while(i<=10)
{
i=i+inc; //inc è l'incremento, modificabile nella setting window
x=i;
SendMessage(prog, PBM_SETPOS,WPARAM ((i+10)*100/20), 0); //Setto la progressBar
if (curva==1) //(retta)
{
a=atof(numa);
b=atof(numb);
c=atof(numc);
if (b!=0)
y=((-c-(a*x))/b);
else //se la retta è parallela all'asse y
{
x=c/a;
y=i;
}
//Converte i numeri in coordinate in pixel:
ballX=conx(x);
ballY=cony(y);
DrawBall(hdcWindow);
}
if (curva==2) //(parabola con asse parallelo all'asse delle y)
{
a=atof(numa);
b=atof(numb);
c=atof(numc);
y=(a*x*x)+(b*x)+c;
//Converte i numeri in coordinate in pixel:
ballX=conx(x);
ballY=cony(y);
DrawBall(hdcWindow);
}
if (curva==3) //(Ellisse)
{
a=atof(numa);
b=atof(numb);
y=sqrt(b*b*(a*a-x*x)/(a*a));
//Converte i numeri in coordinate in pixel:
ballX=conx(x);
ballY=cony(y);
DrawBall(hdcWindow);
y=-sqrt(b*b*(a*a-x*x)/(a*a));
//Converte i numeri in coordinate in pixel:
ballX=conx(x);
ballY=cony(y);
DrawBall(hdcWindow);
}
if (curva==4) //(Iperbole)
{
a=atof(numa);
b=atof(numb);
y=sqrt(b*b*(x*x-a*a)/(a*a));
//Converte i numeri in coordinate in pixel:
ballX=conx(x);
ballY=cony(y);
DrawBall(hdcWindow);
y=-sqrt(b*b*(x*x-a*a)/(a*a));
//Converte i numeri in coordinate in pixel:
ballX=conx(x);
ballY=cony(y);
DrawBall(hdcWindow);
}
if (curva==5) //(Circonferenza)
{
a=atof(numa);
b=atof(numb);
c=atof(numc);
y=b+sqrt((c*c)-((x-a)*(x-a)));
//Converte i numeri in coordinate in pixel:
ballX=conx(x);
ballY=cony(y);
DrawBall(hdcWindow);
y=-b-sqrt((c*c)-((x-a)*(x-a)))+2*b;
//Converte i numeri in coordinate in pixel:
ballX=conx(x);
ballY=cony(y);
DrawBall(hdcWindow);
}
if (curva==6) //(Parabola con asse parallelo all'asse delle x)
{
a=atof(numa);
b=atof(numb);
c=atof(numc);
y=(-b+sqrt(b*b-4*a*c+4*a*x))/2;
//Converte i numeri in coordinate in pixel:
ballX=conx(x);
ballY=cony(y);
DrawBall(hdcWindow);
y=-(-b+sqrt(b*b-4*a*c+4*a*x)+2*b)/2;
//Converte i numeri in coordinate in pixel:
ballX=conx(x);
ballY=cony(y);
DrawBall(hdcWindow);
}
}
}
//Disegno Funzioni:***************************************************************************************************************
if (funpress>0) //Se è stato cliccato il pulsante disegna nella funciton windows:
{
funpress=0; //riazzero il contatore che indica che è stato premuto il tasto disegna.
/*Apro il file, lo pulisco e scrivo di che funzione si tratta:*/
fstream f;
system ("del Tab.txt");
f.open("Tab.txt",ios::out|ios::app);
f <<"Funzione:"<<endl;
f <<"y="<<funzione<<endl;
f <<"------------------------------------"<<endl;
f <<"X Y"<<endl;
/***********************************/
for (i=-10;i<=10;i=i+inc)
{
x=i;
SendMessage(prog2, PBM_SETPOS, WPARAM(((i+10)*100/20)+1), 0); //Setto la progressBar
stack <float> numbers;
string longNumber = "";
float result=0,prev=0,postv=0;
int chkop=0;
for (unsigned int h = 0; h < rpn.size(); h++)
{
/* Il carattere letto e' un numero. Questo numero viene memorizzato
* nella stringa di appoggio.
* Se il prossimo carattere e' un numero,vuol dire che nella
* stringa c'e un numero lungo perche' nella funzione di conversione
* dopo ogni numero inserito nella stringa di output veniva messo anche
* il simbolo di spazio. La prossima cifra del numero sara' aggiunta
* alla fine della stringa di appoggio all'aumentare dell'indice.
* Se il prossimo carattere non e' un numero, la stringa d'appoggio
* viene convertita in un numero vero e memorizzata nello stack. */
if(chkchar(rpn[h])==1)
{
if (isdigit(rpn[h]))
{
longNumber += rpn[h];
}
if ((rpn[h]=='x')||(rpn[h]=='X')) //sostitusco alla x nell'espressione il valore effettivo della x
{
numbers.push(x);
}
if (rpn[h]=='e') //sostituisco alla e nell'espressione il valore della costante
{
numbers.push(2.71828);
}
if (rpn[h]=='p') //sostituisco alla ? nell'espressione il valore della costante
{
numbers.push(3.14159);
}
//Se il carattere successivo non è una cifra e è diverso dalla virgola:
if((!isdigit(rpn[h + 1]))&& (rpn[h+1]!='.')&&(rpn[h]!='x')&&(rpn[h]!='X')&&(rpn[h]!='e')&&(rpn[h]!='p'))
{
numbers.push(atof(longNumber.c_str()));
longNumber = "";
}
if (rpn[h+1]=='.') //Se il carattere successivo è la virgola:
{
numbers.push(atof(longNumber.c_str())); //legge la parte precedente a questa (la parte intera )
longNumber = "";
prev = numbers.top();
numbers.pop();
int count=2;
while (isdigit(rpn[count+h])) //Legge la parte successiva e la memorizza come numero
{
longNumber += rpn[h+count];
count++;
}
h=h+count;
postv=(atof(longNumber.c_str()));
longNumber="";
/*somma la parte precedente a quella successiva
fratto 10^il numero di cifre che ha es:
2.985 prev=2 postv=985
985 ha tre cifre quindi 985/10^3=0.985
li sommo e ottengo 2.985*/
numbers.push(prev+(postv/pow(10,numcif(postv))));
postv=0;prev=0;
}
}
if (chkchar(rpn[h])==2) //Il carattere è un operatore:
{
chkop++; //Controlla se vi è un operatore
result = numbers.top();
numbers.pop();
if (numbers.empty()) //se c'è un operatore all'inizio, è come se ci fosse lo 0 (es.-6=0-6)
{ //pertanto aggiungo lo 0
numbers.push(0.0);
}
/*****OPERATORS****************************************/
switch(rpn[h])
{
case '+':
result = numbers.top() + result ;
break;
case '-':
result = numbers.top() - result ;
break;
case '*':
result = numbers.top() * result ;
break;
case '/':
result = numbers.top() / result ;
break;
case '^':
result = pow(numbers.top() , result) ;
break;
case '%': //Operatore modulo
result =int(numbers.top()) % int(result) ;
break;
}
numbers.pop();
numbers.push(result);
}
if (chkfun(rpn[h])==1) //Se c'è un carattere che corrisponde a una funzione:
{
/*La funzione 'Fun', dato un carattere
*corrispondente a una funzione e un valore
*float, ne calcola la funzione corrispondente.*/
result=Fun(rpn[h],numbers.top()); //Fun è dichiarata in 'funzioni.h'
numbers.pop();
numbers.push(result);
}
}
if (chkop==0) //Se nell'espressione non vi è alcun operatore, allora vi deve essere un solo numero, perciò lo si associa a result.
{ //infatti chkop si incrementa se il carattere è un operatore(vedi sopra)
result= numbers.top();
}
/*Rappresento il punto in coordinate (x;result)*/
ballX=conx(x);
ballY=cony(result);
DrawBall(hdcWindow);
/*Creo La tabella caratteri*/
f <<x<<" "<<result<<endl;
}
f.close();
}
ReleaseDC(hwnd, hdcWindow);
}
break;
case WM_COMMAND: /***************************************MENU*****************************************************/
if (LOWORD(wParam)==MENU_FILE_EXIT)
{
DestroyWindow(hwnd); //Chiudo la finestra
}
if (LOWORD(wParam)==MENU_FILE_CURV)
{
//Crea e visualizza la finestra delle curve
MSG messages2;
HWND hwnd2 = CreateWindowEx (0,name,"Curve:",WS_SYSMENU|WS_MINIMIZEBOX|WS_VISIBLE,400,400,400,300,hwnd, NULL, g_hInst,NULL);
ShowWindow (hwnd2, 1);
while (GetMessage (&messages2, NULL, 0, 0))
{
TranslateMessage(&messages2);
DispatchMessage(&messages2);
}
}
if (LOWORD(wParam)==MENU_FILE_ABOU)
{
MessageBox(hwnd,"Paint XY - Versione 1.2","By Dany",MB_OK|MB_ICONINFORMATION);
}
if (LOWORD(wParam)==MENU_FILE_CLEA)
{
/*Se nel menu clicchi su 'pulisci' allora la finestra 'scomparirà ' (ncmdshow=0)
e ricomparirà (ncmdshow=1) ma 'bo' e 'cachefun' saranno uguali a 0 e perciò
il prog non avrà il "permesso" di ridisegnare le curve/funzioni*/
curva=0;
bo=0;
cachenum=0;
ShowWindow(hwnd,0);
ShowWindow(hwnd,1);
/*Azzerando le variabili contatrici degli array, dopo aver pulito la finestra,
se ridisegnano nuove curve, verranno sovrascritte a quelle vecchie che non
verranno mai più ridisegnate :'(*/
l=0;l2=0;l3=0;l4=0;l5=0;l6=0; //Azzero le variabili contatrici degli array
/*Azzero l'array delle string contenenti gli rpn delle varie funzioni disegnate
così da non ridisegnarle*/
for (int N=0;N<=20;N++)
cache[N]="";
}
if (LOWORD(wParam)==MENU_FILE_SETT)
{
//Crea e visualizza la finestra
MSG messages4;
HWND hwnd4 = CreateWindowEx (0,name3,"Impostazioni:",WS_SYSMENU|WS_MINIMIZEBOX|WS_VISIBLE,400,400,390,200,hwnd, NULL, g_hInst,NULL);
ShowWindow (hwnd4, 1);
while (GetMessage (&messages4, NULL, 0, 0))
{
TranslateMessage(&messages4);
DispatchMessage(&messages4);
}
preprec=prec; //Il cursore della trackbar assume l'ultima posizione.
}
if (LOWORD(wParam)==MENU_FILE_FUNZ)
{
//Crea e visualizza la finestra
MSG messages5;
HWND hwnd5 = CreateWindowEx (0,name2,"Funzioni:",WS_SYSMENU|WS_MINIMIZEBOX|WS_VISIBLE,400,400,400,250,hwnd, NULL, g_hInst,NULL);
ShowWindow (hwnd5, 1);
while (GetMessage (&messages5, NULL, 0, 0))
{
TranslateMessage(&messages5);
DispatchMessage(&messages5);
}
}
break;
case WM_PAINT:
if(hbmBall && hbmMask)
{
PAINTSTRUCT ps;
HDC hdcWindow;
hdcWindow = BeginPaint(hwnd, &ps);
DrawGriglia(hdcWindow);
/*******RIDISEGNA LE FUNZIONI SE LA FINESTRA VIENE RIDOTTA/COPERTA*****/
if (bo>0) //Se il prog NON è stato appena pulito (o non è stato appena aperto)
/*In pratica col ciclo passo tutte le 6 curve e per ognuna esamino gli array che contengono
i parametri da me inseriti precedentemente, così per ridisegnarle basta ricaricare nei coefficient a,b,c
i valori negli array ca,da,ea ecc...*/
for (curva=1;curva<=6;curva++) //Ciclo con tutti i tipi di curva
for (i=-10;i<=10;i=i+inc)
{
x=i;
if (curva==1) //(retta)
{
if (l>0) //Se la curva non è mai stata disegnata, salta il ciclo
for (k=0;k<=l-1;k++) //Verifica tutte le posizioni dell'array e le usa per ridisegnare la funzione
{
a=ca[k];
b=cb[k];
c=cc[k];
if (b!=0)
y=((-c-(a*x))/b);
else //RETTA PARALLELA ALL'ASSE DELLE X
{
x=c/a;
y=i;
}
//Converte i numeri in coordinate in pixel:
ballX=conx(x);
ballY=cony(y);
DrawBall(hdcWindow);
}
}
if (curva==2) //(parabola con asse parallelo all'asse delle y)
{
if (l2>0) //Se la curva non è mai stata disegnata, salta il ciclo
for(k=0;k<=l2-1;k++) //Verifica tutte le posizioni dell'array e le usa per ridisegnare la funzione
{
a=da[k];
b=db[k];
c=dc[k];
y=(a*x*x)+(b*x)+c;
//Converte i numeri in coordinate in pixel:
ballX=conx(x);
ballY=cony(y);
DrawBall(hdcWindow);
}
}
if (curva==3) //(Ellisse)
{
if (l3>0) //Se la curva non è mai stata disegnata, salta il ciclo
for(k=0;k<=l3-1;k++) //Verifica tutte le posizioni dell'array e le usa per ridisegnare la funzione
{
a=ea[k];
b=eb[k];
y=sqrt(b*b*(a*a-x*x)/(a*a));
//Converte i numeri in coordinate in pixel:
ballX=conx(x);
ballY=cony(y);
DrawBall(hdcWindow);
y=-sqrt(b*b*(a*a-x*x)/(a*a));
//Converte i numeri in coordinate in pixel:
ballX=conx(x);
ballY=cony(y);
DrawBall(hdcWindow);
}
}
if (curva==4) //(Iperbole)
{
if (l4>0) //Se la curva non è mai stata disegnata, salta il ciclo
for(k=0;k<=l4-1;k++) //Verifica tutte le posizioni dell'array e le usa per ridisegnare la funzione
{
a=fa[k];
b=fb[k];
y=sqrt(b*b*(x*x-a*a)/(a*a));
//Converte i numeri in coordinate in pixel:
ballX=conx(x);
ballY=cony(y);
DrawBall(hdcWindow);
y=-sqrt(b*b*(x*x-a*a)/(a*a));
//Converte i numeri in coordinate in pixel:
ballX=conx(x);
ballY=cony(y);
DrawBall(hdcWindow);
}
}
if (curva==5) //(Circonferenza)
{
if (l5>0) //Se la curva non è mai stata disegnata, salta il ciclo
for(k=0;k<=l5-1;k++) //Verifica tutte le posizioni dell'array e le usa per ridisegnare la funzione
{
a=ga[k];
b=gb[k];
c=gc[k];
y=b+sqrt((c*c)-((x-a)*(x-a)));
//Converte i numeri in coordinate in pixel:
ballX=conx(x);
ballY=cony(y);
DrawBall(hdcWindow);
y=-b-sqrt((c*c)-((x-a)*(x-a)))+2*b;
//Converte i numeri in coordinate in pixel:
ballX=conx(x);
ballY=cony(y);
DrawBall(hdcWindow);
}
}
if (curva==6) //(Parabola con asse parallelo all'asse delle x)
{
if (l6>0) //Se la curva non è mai stata disegnata, salta il ciclo
for(k=0;k<=l6-1;k++) //Verifica tutte le posizioni dell'array e le usa per ridisegnare la funzione
{
a=ha[k];
b=hb[k];
c=hc[k];
y=(-b+sqrt(b*b-4*a*c+4*a*x))/2;
//Converte i numeri in coordinate in pixel:
ballX=conx(x);
ballY=cony(y);
DrawBall(hdcWindow);
y=-(-b+sqrt(b*b-4*a*c+4*a*x)+2*b)/2;
//Converte i numeri in coordinate in pixel:
ballX=conx(x);
ballY=cony(y);
DrawBall(hdcWindow);
}
}
}
/*RIDISEGNO FUNZIONI***********************************************************************/
/*Sempre se il prog NON è stato ripulito o appena aperto,
cioè se è stato solo coperto o ridotto a icona per farla semplice*/
if (cachenum>0)
//Ciclo che tramite 'lo' scorre l'array 'cache' ricaricando tutte le funzioni in rpn
//disegnate prima che coprissi la finestra.
for (lo=1;lo<=cachenum;lo++)
for (i=-10;i<=10;i=i+inc)
{
x=i;
stack <float> numbers;
string longNumber = "";
float result=0,prev=0,postv=0;
for (unsigned int h = 0; h < cache[lo].size(); h++)
{
/* Il carattere letto e' un numero. Questo numero viene memorizzato
* nella stringa di appoggio.
* Se il prossimo carattere e' un numero,vuol dire che nella
* stringa c'e un numero lungo perche' nella funzione di conversione
* dopo ogni numero inserito nella stringa di output veniva messo anche
* il simbolo di spazio. La prossima cifra del numero sara' aggiunta
* alla fine della stringa di appoggio all'aumentare dell'indice.
* Se il prossimo carattere non e' un numero, la stringa d'appoggio
* viene convertita in un numero vero e memorizzata nello stack. */
if(chkchar(cache[lo][h])==1)
{
if (isdigit(cache[lo][h]))
{
longNumber += cache[lo][h];
}
if ((cache[lo][h]=='x')||(cache[lo][h]=='X')) //sostitusco alla x nell'espressione il valore effettivo della x
{
numbers.push(x);
}
if (cache[lo][h]=='e') //sostituisco alla e nell'espressione il valore della costante
{
numbers.push(2.71828);
}
if (cache[lo][h]=='p') //sostituisco alla ? nell'espressione il valore della costante
{
numbers.push(3.14159);
}
//Se il carattere successivo non è una cifra e è diverso dalla virgola:
if((!isdigit(cache[lo][h + 1]))&& (cache[lo][h+1]!='.')&&(cache[lo][h]!='x')&&(cache[lo][h]!='X')&&(cache[lo][h]!='e')&&(cache[lo][h]!='p'))
{
numbers.push(atof(longNumber.c_str()));
longNumber = "";
}
if (cache[lo][h+1]=='.') //Se il carattere successivo è la virgola:
{
numbers.push(atof(longNumber.c_str())); //legge la parte precedente a questa (la parte intera )
longNumber = "";
prev = numbers.top();
numbers.pop();
int count=2;
while (isdigit(cache[lo][count+h])) //Legge la parte successiva e la memorizza come numero
{
longNumber += cache[lo][h+count];
count++;
}
h=h+count;
postv=(atof(longNumber.c_str()));
longNumber="";
/*somma la parte precedente a quella successiva
fratto 10^il numero di cifre che ha es:
2.985 prev=2 postv=985
985 ha tre cifre quindi 985/10^3=0.985
li sommo e ottengo 2.985*/
numbers.push(prev+(postv/pow(10,numcif(postv))));
postv=0;prev=0;
}
}
result=numbers.top();
if (chkchar(cache[lo][h])==2)
{
result = numbers.top();
numbers.pop();
if (numbers.empty()) //se c'è un operatore all'inizio, è come se ci fosse lo 0 (es.-6=0-6)
{
numbers.push(0.0);
}
/*****OPERATORS****************************************/
switch(cache[lo][h])
{
case '+':
result = numbers.top() + result ;
break;
case '-':
result = numbers.top() - result ;
break;
case '*':
result = numbers.top() * result ;
break;
case '/':
result = numbers.top() / result ;
break;
case '^':
result = pow(numbers.top() , result) ;
break;
case '%':
result =int(numbers.top()) % int(result) ;
break;
}
numbers.pop();
numbers.push(result);
}
if (chkfun(cache[lo][h])==1) //Se c'è una funzione:
{
result=Fun(cache[lo][h],numbers.top());
numbers.pop();
numbers.push(result);
}
}
/*Rappresento il punto in coordinate (x;result)*/
ballX=conx(x);
ballY=cony(result);
DrawBall(hdcWindow);
}
EndPaint(hwnd, &ps);
}
break;
case WM_MOUSEMOVE:
/*Coordinate mouse nella finestra
*In pratica Grazie a GET_X_LPARAM (lParam); e a GET_Y_LPARAM (lParam);
*Ottengo le coordinate in pixel dentro la finestra, per poi convertirle
*In coordinate reali.*/
cox = GET_X_LPARAM (lParam);
coy = GET_Y_LPARAM (lParam);
cox=(cox-500)/50;
coy=(500-coy)/50;
sprintf(coox, "%6.2f", cox); //Converto da float a *char
sprintf(cooy, "%6.2f", coy); //Converto da float a *char
SetWindowText(lex,coox); //Imposto nell'edit le coordinate x
SetWindowText(ley,cooy); //Imposto nell'edit le coordinate y
break;
case WM_CLOSE:
if(MessageBox(hwnd,"Vuoi davvero uscire?","Messaggio",MB_YESNO|MB_ICONQUESTION)==IDYES)
DestroyWindow(hwnd);
break;
case WM_DESTROY:
KillTimer(hwnd, idTimer1);
DeleteObject(hbmBall);
DeleteObject(hbmMask);
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, Message, wParam, lParam);
}
return 0;
}
//WndProc della finestra per rappresentare le curve
//HBIMAP del pulsante di disegno
HBITMAP bmp=(HBITMAP)LoadImage(0,"draw.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
//HWND DEL PULSANTE DI DISEGNO
HWND paint;
//Variabili HWND:
HWND radpar,radipe,radell,radret,radcir,radparx;
HWND edita,editb,editc,sintax;
//Variabili controllo radiobutton in finestra di disegno curve
int selret=0,selpar=0,selipe=0,selell=0,selcir=0,selparx=0;
//Tooltipe
TOOLINFO ti;
HWND hwtoll;
LRESULT CALLBACK WindowProcedure2 (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
InitCommonControls (); //Applicazione visual style
switch (message)
{
case WM_PAINT:
PAINTSTRUCT ps;
HDC hdcWindow;
hdcWindow = BeginPaint(hwnd, &ps);
/****SETTO I CARATTERI DA UTILIZZARE: FONT, DIMENSIONI ECC...**/
hfont = CreateFont (20,0,0,0, 500, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_OUTLINE_PRECIS,
CLIP_DEFAULT_PRECIS, CLEARTYPE_QUALITY, VARIABLE_PITCH, TEXT ("Monotype Corsiva"));
SelectObject (hdcWindow, hfont);
SetRect (& rect, 100,100,700,200);
SetTextColor (hdcWindow, RGB (0,0,0));
TextOut(hdcWindow,0,0,"Selezionare il tipo di curva ed inserire i parametri.",55);
TextOut(hdcWindow,5,190,"Coefficiente A:",15);
TextOut(hdcWindow,5,215,"Coefficiente B:",15);
TextOut(hdcWindow,5,240,"Coefficiente C:",15);
TextOut(hdcWindow,5,150,"L'equazione è del tipo:",23);
EndPaint(hwnd,&ps);
break;
case WM_CREATE:
//ProgressBar
prog=CreateWindowEx(NULL, PROGRESS_CLASS, NULL, WS_CHILD|WS_VISIBLE, 215,200, 150, 30, hwnd, NULL, NULL, 0);
//Crea radio-button per decidere il tipo di curva:
radret=CreateWindow("Button","Retta",WS_CHILD|WS_VISIBLE|BS_AUTORADIOBUTTON,0,20,55,20,hwnd,(HMENU) 1,NULL,NULL);
radpar=CreateWindow("Button","Parabola (y)",WS_CHILD|WS_VISIBLE|BS_AUTORADIOBUTTON,0,45,100,20,hwnd,(HMENU) 2,NULL,NULL);
radipe=CreateWindow("Button","Iperbole",WS_CHILD|WS_VISIBLE|BS_AUTORADIOBUTTON,0,70,80,20,hwnd,(HMENU) 3,NULL,NULL);
radell=CreateWindow("Button","Ellisse",WS_CHILD|WS_VISIBLE|BS_AUTORADIOBUTTON,0,95,70,20,hwnd,(HMENU) 4,NULL,NULL);
radcir=CreateWindow("Button","Circonferenza",WS_CHILD|WS_VISIBLE|BS_AUTORADIOBUTTON,0,120,100,20,hwnd,(HMENU) 5,NULL,NULL);
radparx=CreateWindow("Button","Parabola (x)",WS_CHILD|WS_VISIBLE|BS_AUTORADIOBUTTON,120,45,100,20,hwnd,(HMENU) 6,NULL,NULL);
//Crea EditBox per inserire i parametri
edita=CreateWindow("Edit","",WS_CHILD|WS_VISIBLE|WS_BORDER,150,190,50,20,hwnd,NULL,NULL,NULL);
editb=CreateWindow("Edit","",WS_CHILD|WS_VISIBLE|WS_BORDER,150,215,50,20,hwnd,NULL,NULL,NULL);
editc=CreateWindow("Edit","",WS_CHILD|WS_VISIBLE|WS_BORDER,150,240,50,20,hwnd,NULL,NULL,NULL);
//Crea EditBox per mostrare la sintassi di una cura selezionata
sintax=CreateWindow("Edit","",WS_CHILD|WS_VISIBLE|WS_BORDER|ES_READONLY,200,150,190,20,hwnd,NULL,NULL,NULL);
//Crea il pulsante che permette di disegnare la curva selezionata.
paint=CreateWindow("Button","",WS_VISIBLE|WS_CHILD|BS_BITMAP|WS_BORDER,295,35,83,83,hwnd,(HMENU) 7, NULL,NULL);
SendMessage(paint,BM_SETIMAGE,IMAGE_BITMAP,(LPARAM)bmp);
/****SETTO I CARATTERI DA UTILIZZARE: FONT, DIMENSIONI ECC...**/
GetObject (GetStockObject(DEFAULT_GUI_FONT), sizeof(LOGFONT), &lf);
hfont = CreateFont (20,0,0,0, 500, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_OUTLINE_PRECIS,
CLIP_DEFAULT_PRECIS, CLEARTYPE_QUALITY, VARIABLE_PITCH, TEXT ("Monotype Corsiva"));
SendMessage (edita, WM_SETFONT, (WPARAM) hfont, true);
SendMessage (editb, WM_SETFONT, (WPARAM) hfont, true);
SendMessage (editc, WM_SETFONT, (WPARAM) hfont, true);
SendMessage (radret, WM_SETFONT, (WPARAM) hfont, true);
SendMessage (radpar, WM_SETFONT, (WPARAM) hfont, true);
SendMessage (radipe, WM_SETFONT, (WPARAM) hfont, true);
SendMessage (radell, WM_SETFONT, (WPARAM) hfont, true);
SendMessage (radcir, WM_SETFONT, (WPARAM) hfont, true);
SendMessage (radparx, WM_SETFONT, (WPARAM) hfont, true);
SendMessage (sintax, WM_SETFONT, (WPARAM) hfont, true);
/*TOOLTIP*/
hwtoll=CreateWindowEx(NULL, TOOLTIPS_CLASS, NULL,WS_POPUP | TTS_NOPREFIX | TTS_ALWAYSTIP,0,0,0,0,paint, NULL, NULL,NULL);
SetWindowPos (hwtoll, HWND_TOPMOST, 0, 0, 0, 0,SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
GetClientRect (paint, &rect);
////////////////////////////////// FORMATTAZIONE TOOLTIP
ti.cbSize = sizeof(TOOLINFO);
ti.uFlags = TTF_SUBCLASS;
ti.hwnd = paint;
ti.hinst = NULL;
ti.uId = 0;
ti.lpszText = "Disegna!";
ti.rect.left = rect.left;
ti.rect.top = rect.top;
ti.rect.right = rect.right;
ti.rect.bottom = rect.bottom;
//////////////////////////////////
SendMessage(hwtoll, TTM_ADDTOOL, 0, (LPARAM) (LPTOOLINFO) &ti);
break;
case WM_COMMAND:
if (LOWORD(wParam)==1)
{
SetWindowText(sintax,"Ax+By+C=0"); //Mostro la sintassi della curva
Edit_Enable(editc,TRUE); //Abilita l'edit relativo al coefficiente C poichè contenuto nella sintassi dell'equazione
}
if (LOWORD(wParam)==2)
{
SetWindowText(sintax,"Ax²+Bx+C=y"); //Mostro la sintassi della curva
Edit_Enable(editc,TRUE);
}
if (LOWORD(wParam)==3)
{
SetWindowText(sintax,"(x²/A²)-(y²/B²)=1"); //Mostro la sintassi della curva
Edit_Enable(editc,FALSE); //DisAbilita l'edit relativo al coefficiente C poichè Non contenuto nella sintassi dell'equazione
}
if (LOWORD(wParam)==4)
{
SetWindowText(sintax,"(x²/A²)+(y²/B²)=1"); //Mostro la sintassi della curva
Edit_Enable(editc,FALSE);
}
if (LOWORD(wParam)==5)
{
SetWindowText(sintax,"(x-A)²+(y-B)²=C²"); //Mostro la sintassi della curva
Edit_Enable(editc,TRUE);
}
if (LOWORD(wParam)==6)
{
SetWindowText(sintax,"Ay²+By+C=x"); //Mostro la sintassi della curva
Edit_Enable(editc,TRUE);
}
if (LOWORD(wParam)==7)
{
bo++; //Incremento 'bo' il che indica che se la finestra viene coperta oridotta a icona
//le curve verranno disegnate
//Controllo stato radiobutton
selret=SendMessage(radret,BM_GETCHECK,0,0);
selpar=SendMessage(radpar,BM_GETCHECK,0,0);
selell=SendMessage(radell,BM_GETCHECK,0,0);
selipe=SendMessage(radipe,BM_GETCHECK,0,0);
selcir=SendMessage(radcir,BM_GETCHECK,0,0);
selparx=SendMessage(radparx,BM_GETCHECK,0,0);
//Nel caso sia selezionato il radiobutton....
if (selret==BST_CHECKED)
{
agg++; //Incremento la variabile che permette alla WM_TIMER in MainWindow di disegnare la curva
GetWindowText(edita,numa,5); //Leggi il valore del paramtero a
GetWindowText(editb,numb,5); //Leggi il valore del paramtero b
GetWindowText(editc,numc,5); //Leggi il valore del paramtero c
curva=1; //Curva 1 Vuol dire retta
//Memorizza nell'array i vari valori dei coefficianti così da ridisegnarli
ca[l]=atof(numa);
cb[l]=atof(numb);
cc[l]=atof(numc);
l++;
}
if (selpar==BST_CHECKED)
{
agg++; //Incremento la variabile che permette alla WM_TIMER in MainWindow di disegnare la curva
GetWindowText(edita,numa,5); //Leggi il valore del paramtero a
GetWindowText(editb,numb,5); //Leggi il valore del paramtero b
GetWindowText(editc,numc,5); //Leggi il valore del paramtero c
curva=2; //Curva 2 Vuol dire parabola
//Memorizza nell'array i vari valori dei coefficianti così da ridisegnarli
da[l2]=atof(numa);
db[l2]=atof(numb);
dc[l2]=atof(numc);
l2++;
}
if (selell==BST_CHECKED)
{
agg++; //Incremento la variabile che permette alla WM_TIMER in MainWindow di disegnare la curva
GetWindowText(edita,numa,5); //Leggi il valore del paramtero a
GetWindowText(editb,numb,5); //Leggi il valore del paramtero b
curva=3; //Curva 3 Vuol dire ellisse
//Memorizza nell'array i vari valori dei coefficianti così da ridisegnarli
ea[l3]=atof(numa);
eb[l3]=atof(numb);
l3++;
}
if (selipe==BST_CHECKED)
{
agg++; //Incremento la variabile che permette alla WM_TIMER in MainWindow di disegnare la curva
GetWindowText(edita,numa,5); //Leggi il valore del paramtero a
GetWindowText(editb,numb,5); //Leggi il valore del paramtero b
curva=4; //Curva 4 Vuol dire iperbole
//Memorizza nell'array i vari valori dei coefficianti così da ridisegnarli
fa[l4]=atof(numa);
fb[l4]=atof(numb);
l4++;
}
if (selcir==BST_CHECKED)
{
agg++; //Incremento la variabile che permette alla WM_TIMER in MainWindow di disegnare la curva
GetWindowText(edita,numa,5); //Leggi il valore del paramtero a
GetWindowText(editb,numb,5); //Leggi il valore del paramtero b
GetWindowText(editc,numc,5); //Leggi il valore del paramtero c
curva=5; //Curva 5 Vuol dire circonferenza
//Memorizza nell'array i vari valori dei coefficianti così da ridisegnarli
ga[l5]=atof(numa);
gb[l5]=atof(numb);
gc[l5]=atof(numc);
l5++;
}
if (selparx==BST_CHECKED)
{
agg++; //Incremento la variabile che permette alla WM_TIMER in MainWindow di disegnare la curva
GetWindowText(edita,numa,5); //Leggi il valore del paramtero a
GetWindowText(editb,numb,5); //Leggi il valore del paramtero b
GetWindowText(editc,numc,5); //Leggi il valore del paramtero c
curva=6; //Curva 6 Vuol dire parabola con asse parallello all'asse x
//Memorizza nell'array i vari valori dei coefficianti così da ridisegnarli
ha[l6]=atof(numa);
hb[l6]=atof(numb);
hc[l6]=atof(numc);
l6++;
}
if((selret!=BST_CHECKED) && (selpar!=BST_CHECKED) && (selipe!=BST_CHECKED) && (selell!=BST_CHECKED) && (selcir!=BST_CHECKED) && (selparx!=BST_CHECKED)) //Se non è selezionata alcuna curva:
{
MessageBox(hwnd,"Selezionare una curva","Avviso!",MB_OK);
}
}
break;
case WM_KEYDOWN:
if (LOWORD(wParam)==VK_RETURN) //Se si preme invio: è come se si clicca su :paint.
{
SendMessage(paint,BM_CLICK,NULL,NULL); //simulare pressione tasto...
}
break;
case WM_DESTROY:
PostQuitMessage (0);
break;
default:
return DefWindowProc (hwnd, message, wParam, lParam);
}
return 0;
}
//Function Window
//Variabile del ciclo
int h;
//Variabili HWND
HWND edfun,tabb,drf,gui;
//Variabile bitmap
HBITMAP bmp2=(HBITMAP)LoadImage(0,"draw.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
HBITMAP bmp3=(HBITMAP)LoadImage(0,"tab.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
//Window Procedure della Function Window
LRESULT CALLBACK WindowProcedure3 (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
InitCommonControls (); //Applicazione visual style
switch(message)
{
case WM_CREATE:
/****SETTO I CARATTERI DA UTILIZZARE: FONT, DIMENSIONI ECC...**/
GetObject (GetStockObject(DEFAULT_GUI_FONT), sizeof(LOGFONT), &lf);
hfont = CreateFont (20,0,0,0, 500, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_OUTLINE_PRECIS,
CLIP_DEFAULT_PRECIS, CLEARTYPE_QUALITY, VARIABLE_PITCH, TEXT ("Monotype Corsiva"));
//Progress Bar
prog2=CreateWindowEx(NULL, PROGRESS_CLASS, NULL, WS_CHILD|WS_VISIBLE, 5,180, 380, 30, hwnd, NULL, NULL, 0);
//Edit
edfun=CreateWindow("edit","<Scrivere quì la funzione>",WS_VISIBLE|WS_CHILD|WS_BORDER|ES_AUTOHSCROLL,40,30,350,20,hwnd,NULL,NULL,NULL);
//Pulsanti
tabb=CreateWindow("button","",WS_VISIBLE|WS_CHILD|BS_BITMAP,10,70,80,80,hwnd,(HMENU) 1,NULL,NULL);
drf=CreateWindow("button","",WS_VISIBLE|WS_CHILD|BS_BITMAP,105,70,80,80,hwnd,(HMENU) 2,NULL,NULL);
gui=CreateWindow("button","Guida",WS_VISIBLE|WS_CHILD|BS_BITMAP,230,70,110,80,hwnd,(HMENU) 3,NULL,NULL);
//Applico le bitmap
SendMessage(drf,BM_SETIMAGE,IMAGE_BITMAP,(LPARAM)bmp2);
SendMessage(tabb,BM_SETIMAGE,IMAGE_BITMAP,(LPARAM)bmp3);
//Setto i caratteri
SendMessage (edfun, WM_SETFONT, (WPARAM) hfont, true);
SendMessage (gui, WM_SETFONT, (WPARAM) hfont, true);
/*TOOLTIP*/
hwtoll=CreateWindowEx(NULL, TOOLTIPS_CLASS, NULL,WS_POPUP | TTS_NOPREFIX | TTS_ALWAYSTIP,0,0,0,0,drf, NULL, NULL,NULL);
SetWindowPos (hwtoll, HWND_TOPMOST, 0, 0, 0, 0,SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
GetClientRect (drf, &rect);
////////////////////////////////// FORMATTAZIONE TOOLTIP
ti.cbSize = sizeof(TOOLINFO);
ti.uFlags = TTF_SUBCLASS;
ti.hwnd = drf;
ti.hinst = NULL;
ti.uId = 0;
ti.lpszText = "Disegna!";
ti.rect.left = rect.left;
ti.rect.top = rect.top;
ti.rect.right = rect.right;
ti.rect.bottom = rect.bottom;
//////////////////////////////////
SendMessage(hwtoll, TTM_ADDTOOL, 0, (LPARAM) (LPTOOLINFO) &ti);
/*TOOLTIP*/
hwtoll=CreateWindowEx(NULL, TOOLTIPS_CLASS, NULL,WS_POPUP | TTS_NOPREFIX | TTS_ALWAYSTIP,0,0,0,0,tabb, NULL, NULL,NULL);
SetWindowPos (hwtoll, HWND_TOPMOST, 0, 0, 0, 0,SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
GetClientRect (tabb, &rect);
////////////////////////////////// FORMATTAZIONE TOOLTIP
ti.cbSize = sizeof(TOOLINFO);
ti.uFlags = TTF_SUBCLASS;
ti.hwnd = tabb;
ti.hinst = NULL;
ti.uId = 0;
ti.lpszText = "Visualizza la tabella dell'ultima funzione disegnata.";
ti.rect.left = rect.left;
ti.rect.top = rect.top;
ti.rect.right = rect.right;
ti.rect.bottom = rect.bottom;
//////////////////////////////////
SendMessage(hwtoll, TTM_ADDTOOL, 0, (LPARAM) (LPTOOLINFO) &ti);
break;
case WM_PAINT:
PAINTSTRUCT ps;
HDC hdcWindow;
hdcWindow = BeginPaint(hwnd, &ps);
/****SETTO I CARATTERI DA UTILIZZARE: FONT, DIMENSIONI ECC...**/
hfont = CreateFont (20,0,0,0, 500, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_OUTLINE_PRECIS,
CLIP_DEFAULT_PRECIS, CLEARTYPE_QUALITY, VARIABLE_PITCH, TEXT ("Monotype Corsiva"));
SelectObject (hdcWindow, hfont);
SetRect (& rect, 100,100,700,200);
SetTextColor (hdcWindow, RGB (0,0,0));
TextOut(hdcWindow,0,0,"Digitare la funzione:",21);
TextOut(hdcWindow,8,30,"y=",2);
EndPaint(hwnd,&ps);
break;
case WM_COMMAND:
if (LOWORD(wParam)==1)
{
system ("start Tab.txt");
}
if (LOWORD(wParam)==2)
{
funpress++; //Indica che è stato premuto il tasto disegna...servirà poi nella mainwindow per disegnare la funzione
cachenum++; //Variabile contatrice dell'array di memoria delle funzioni in rpn
//azzero "rpn"
rpn="";
stack <char> operators; //Dichiaro stack che conterrà gli operatori:
char in[100]=""; //Memorizza array contenente la funzione
GetWindowText(edfun,in,100); //Acquisisco stringa in notazione infissa
/*****************************************************************************/
//CONVERTO LA STRINGA IN NOTAZIONE INFISSA IN RPN
for (h=0;h<=sizeof(in);h++)
{
/* Se il carattere e' un numero, questo viene aggiunto alla fine
* della stringa di output. Se il prossimo carattere non e' un
* numero, viene aggiunto il simbolo di spazio per la migliore
* leggibilita' dell'espressione in output */
if (chkchar(in[h])==1)
{
/*Nel caso la 'e' o la 'p' siano parte di una funzione (lne o prm), non le scrivo.*/
if (((in[h]=='e')&&(in[h-1]=='n')&&(in[h-2]=='l'))||((in[h]=='p')&&(in[h-1]=='r')&&(in[h-2]=='m')))
{}
else
rpn+=in[h];
if ((!isdigit(in[h + 1]))&&(in[h+1]!='.')&&(in[h+1]!=','))
{
rpn+=" ";
}
if ((in[h+1]=='.')||(in[h+1]==','))
{
rpn+=".";
}
}
/* Il carattere letto e' un operatore.
* Se lo stack per gli operatori e' vuoto o il carattere
* precedente era la parentesi aperta o l'operatore letto ha
* una precedenza minore rispetto a quella dell'operatore inserito
* prima, l'operatore letto viene inserito normalmente nello stack.
* Altrimenti se l'operatore letto ha una precedenza maggiore
* rispetto a quella dell'operatore inserito prima, dallo stack
* viene tolto l'operatore con la precedenza maggiore e viene messo
* nella stringa di output. */
if (chkchar(in[h])==2)
{
bool usc=false;
while (usc==false)
{
if ((operators.empty())||(operators.top()=='(')||(precedence(in[h],operators.top())))
{
if ((chkchar(in[h-1])==1)||(in[h-1]==')'))
operators.push(in[h]);
usc=true;
}
else if (!precedence(in[h], operators.top()))
{
rpn+=operators.top();
rpn +=" ";
operators.pop();
}
}
}
/* Se il carattere è la s, il successivo è la i e quello ancora è la n, allora c'è la funzione sin: ecc.....
La funzione 'charfun': data una serie di tre caratteri, se corrispondono a una funzione, copia il carattere corrispondente
alla funzione nello stack*/
char chf=charfun(in[h],in[h+1],in[h+2]);
if (chf!=0)
operators.push(chf);
/* Se il carattere letto e' una parentesi aperta, questa viene
* messa nello stack.
* Se e' una parentesi chiusa, vuol dire che tutti gli operatori
* rimasti nello stack fino alla parentesi aperta vanno copiati nella
* stringa di output. La parentesi aperta viene cancellata dallo stack
* e dopo si contunua a leggere la stringa di input */
if (in[h]=='(')
{
operators.push(in[h]);
}
/*Se il carattere è il meno e precedentemente non vi è alcun valore, vuol dire che si intende
*il negartivo di un valore es:-5, allora sostituisco al '-' ----> '0-' */
if ((in[h]=='-')&&(chkchar(in[h-1])!=1))
{
rpn+='0';
rpn+=' ';
operators.push('-');
}
if(in[h] == ')')
{
while(operators.top() != '(') //In pratica scorre nello stack verso sinistra copiando gli operatori incontrati.
{
rpn+=operators.top();
rpn+=" ";
operators.pop();
}
operators.pop(); //Cancella la parentesi aperta
}
}
/* Tutti gli operatori rimasti nello stack vanno copiati nella
stringa di output e poi cancellati dallo stack */
while(!operators.empty())
{
rpn+=operators.top();
rpn+=" ";
operators.pop();
}
//////////////////Eventuale break point per verificare rpn.
strcpy(funzione,in); //Copio la funzione in 'funzione'
cache[cachenum]=rpn; //Copio nella posizione dell'array, la stringa rpn;
}
if (LOWORD(wParam)==3)
{
system("start Funzioni.bmp");
}
break;
case WM_KEYDOWN:
if (LOWORD(wParam)==VK_RETURN) //Se si preme invio: è come se si clicca su :drf.
{
SendMessage(drf,BM_CLICK,NULL,NULL); //simulare pressione tasto...
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd,message,wParam,lParam);
}
return 0;
}
//VARIABILI:
//HWND della finestra:
HWND hwndTrack,sinistra,destra,save,cancel;
//WndProc della finestra delle Impostazioni.
LRESULT CALLBACK WindowProcedure4 (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
InitCommonControls (); //Applicazione visual style
switch(message)
{
case WM_CREATE:
//Salva-Annulla
save=CreateWindow("Button","Salva",WS_VISIBLE|WS_CHILD,10,140,80,30,hwnd,(HMENU) 5,NULL,NULL);
cancel=CreateWindow("Button","Annulla",WS_VISIBLE|WS_CHILD,300,140,80,30,hwnd,(HMENU) 6,NULL,NULL);
//TrackBar
hwndTrack = CreateWindowEx(0,TRACKBAR_CLASS,"Trackbar Control",WS_CHILD|WS_VISIBLE|TBS_AUTOTICKS|TBS_ENABLESELRANGE,
100,25,120,30,hwnd,(HMENU)3,NULL,NULL);
//Static
sinistra=CreateWindow("STATIC", "Approssimativo", WS_CHILD | WS_VISIBLE,0, 0, 100, 30,hwnd, (HMENU)1, NULL, NULL);
destra=CreateWindow("STATIC", "Preciso", WS_CHILD | WS_VISIBLE,0, 0, 80, 30,hwnd, (HMENU)2, NULL, NULL);
//Configuro la TrackBar
SendMessage(hwndTrack, TBM_SETRANGE, TRUE, MAKELONG(100, 1000)); //Gradazione
SendMessage(hwndTrack, TBM_SETPAGESIZE, 0, 20);
SendMessage(hwndTrack, TBM_SETTICFREQ, 100, (LPARAM)0); //DensitÃ
SendMessage(hwndTrack, TBM_SETPOS, FALSE, (LPARAM)prec); //Posizione iniziale
SendMessage(hwndTrack, TBM_SETBUDDY, TRUE, (LPARAM) sinistra); //Static di riferimento sinistro
SendMessage(hwndTrack, TBM_SETBUDDY, FALSE, (LPARAM) destra); //Static di riferimento destro
/****SETTO I CARATTERI DA UTILIZZARE: FONT, DIMENSIONI ECC...**/
GetObject (GetStockObject(DEFAULT_GUI_FONT), sizeof(LOGFONT), &lf);
hfont = CreateFont (20,0,0,0, 500, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_OUTLINE_PRECIS,
CLIP_DEFAULT_PRECIS, CLEARTYPE_QUALITY, VARIABLE_PITCH, TEXT ("Monotype Corsiva"));
SendMessage(save,WM_SETFONT,(WPARAM) hfont,true);
SendMessage(cancel,WM_SETFONT,(WPARAM) hfont,true);
SendMessage(sinistra,WM_SETFONT,(WPARAM) hfont,true);
SendMessage(destra,WM_SETFONT,(WPARAM) hfont,true);
break;
case WM_PAINT:
PAINTSTRUCT ps;
HDC hdcWindow;
hdcWindow = BeginPaint(hwnd, &ps);
/****SETTO I CARATTERI DA UTILIZZARE: FONT, DIMENSIONI ECC...**/
hfont = CreateFont (22,0,0,0, 500, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_OUTLINE_PRECIS,
CLIP_DEFAULT_PRECIS, CLEARTYPE_QUALITY, VARIABLE_PITCH, TEXT ("Monotype Corsiva"));
SelectObject (hdcWindow, hfont);
SetRect (& rect, 100,100,700,200);
SetTextColor (hdcWindow, RGB (0,0,0));
TextOut(hdcWindow,10,70,"Regolare l'accuratezza delle funzioni.",38);
TextOut(hdcWindow,10,100,"Più è accurato, più punti vengono disegnati.",45);
EndPaint(hwnd,&ps);
break;
case WM_COMMAND:
if (LOWORD(wParam)==5)
{
prec=float(SendMessage(hwndTrack,TBM_GETPOS,NULL,NULL)); //Carico l'ultima posizione
inc=1/prec; //calcolo l'incremento
DestroyWindow(hwnd); //Chiudo la finestra
}
if (LOWORD(wParam)==6)
{
prec=preprec; //Annullo una eventuale modifica
DestroyWindow(hwnd); //Chiudo la finestra
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd,message,wParam,lParam);
}
return 0;
}
//Creazione finestra principale/Dichiarazione di hinstance per le altre finestre.
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow)
{
InitCommonControls (); //Applicazione visual style
WNDCLASSEX WndClass,WndClass2,WndClass3,WndClass4;
HWND hwnd;
MSG Msg;
g_hInst = hInstance;
//Main Window
WndClass.cbSize = sizeof(WNDCLASSEX);
WndClass.style = 0;
WndClass.lpfnWndProc = WndProc;
WndClass.cbClsExtra = 0;
WndClass.cbWndExtra = 0;
WndClass.hInstance = g_hInst;
WndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
WndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
WndClass.hbrBackground = (HBRUSH)(COLOR_BTNFACE+1);
WndClass.lpszMenuName = NULL;
WndClass.lpszClassName = g_szClassName;
WndClass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
//Curve Window
WndClass2.cbSize = sizeof(WNDCLASSEX);
WndClass2.style = 0;
WndClass2.lpfnWndProc = WindowProcedure2;
WndClass2.cbClsExtra = 0;
WndClass2.cbWndExtra = 0;
WndClass2.hInstance = hInstance;
WndClass2.hIcon = LoadIcon(NULL, IDI_APPLICATION);
WndClass2.hCursor = LoadCursor(NULL, IDC_ARROW);
WndClass2.hbrBackground = (HBRUSH)(COLOR_BTNFACE+1);
WndClass2.lpszMenuName = NULL;
WndClass2.lpszClassName = name;
WndClass2.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
//FunctionWindow
WndClass3.cbSize = sizeof(WNDCLASSEX);
WndClass3.style = 0;
WndClass3.lpfnWndProc = WindowProcedure3;
WndClass3.cbClsExtra = 0;
WndClass3.cbWndExtra = 0;
WndClass3.hInstance = hInstance;
WndClass3.hIcon = LoadIcon(NULL, IDI_APPLICATION);
WndClass3.hCursor = LoadCursor(NULL, IDC_ARROW);
WndClass3.hbrBackground = (HBRUSH)(COLOR_BTNFACE+1);
WndClass3.lpszMenuName = NULL;
WndClass3.lpszClassName = name2;
WndClass3.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
//Setting Window
WndClass4.cbSize = sizeof(WNDCLASSEX);
WndClass4.style = 0;
WndClass4.lpfnWndProc = WindowProcedure4;
WndClass4.cbClsExtra = 0;
WndClass4.cbWndExtra = 0;
WndClass4.hInstance = hInstance;
WndClass4.hIcon = LoadIcon(NULL, IDI_APPLICATION);
WndClass4.hCursor = LoadCursor(NULL, IDC_ARROW);
WndClass4.hbrBackground = (HBRUSH)(16);
WndClass4.lpszMenuName = NULL;
WndClass4.lpszClassName = name3;
WndClass4.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
//Main Window
if(!RegisterClassEx(&WndClass))
{
MessageBox(0, "Window1 Registration Failed!", "Error!",
MB_ICONEXCLAMATION | MB_OK | MB_SYSTEMMODAL);
return 0;
}
//Second Window
if(!RegisterClassEx(&WndClass2))
{
MessageBox(0, "Window2 Registration Failed!", "Error!",
MB_ICONEXCLAMATION | MB_OK | MB_SYSTEMMODAL);
return 0;
}
//Third Window
if(!RegisterClassEx(&WndClass3))
{
MessageBox(0, "Window3 Registration Failed!", "Error!",
MB_ICONEXCLAMATION | MB_OK | MB_SYSTEMMODAL);
return 0;
}
//Fourt Window
if(!RegisterClassEx(&WndClass4))
{
MessageBox(0, "Window4 Registration Failed!", "Error!",
MB_ICONEXCLAMATION | MB_OK | MB_SYSTEMMODAL);
return 0;
}
//CREAZIONE:
//Main Window
hwnd = CreateWindowEx(WS_EX_CLIENTEDGE,g_szClassName,"Paint XY",
WS_SYSMENU|WS_MINIMIZEBOX|WS_VISIBLE,
175, 0, 1011, 1070,NULL, NULL, g_hInst, NULL);
if (hwnd == NULL)
{
MessageBox(0, "Window Creation Failed!", "Error!",
MB_ICONEXCLAMATION | MB_OK | MB_SYSTEMMODAL);
return 0;
}
//Visualizza Main Window
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
//Messaggio da Main Window
while(GetMessage(&Msg, NULL, 0, 0))
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return Msg.wParam;
}