#include #include #include #include "resource.h" #include #include #include /************************************Constants*******************************************/ //Resolution for drawing the exponential #define RESEXP 300 //Number of bits of the DAC #define NBBITS 20 //Screen resolution #define LENGTH 1080 #define WIDTH 1920 //Margin #define MARGIN 20 //Divides the screen resolution to choose the area of the square buttons #define SCALE 5 //Number of buttons to choose the type of signals #define NBBUTTONS 4 //Trackbars dimensions for signal selections #define TBWIDTH 350 #define TBHEIGHT 50 //Edit inputs dimensions for signal selections #define EDITWIDTH 40 #define EDITHEIGHT 20 //Edit inputs dimensions for signal selections #define GENWIDTH 100 #define GENHEIGHT 30 //Font size for police #define FONTSIZE 16 /*************************************Prototypes**************************************************/ LRESULT CALLBACK MainWndProc(HWND, UINT, WPARAM, LPARAM); void paint(void); void setupSquareEnvironment(void); void destroySquareEnvironment(void); int generateSquare(void); void convertTime(float * time, char unit); int * convertSignal(float * signal, int * signalConv, int nbPoints, float AMIN, float AMAX); void stringToFloat(char string[7], float * conv, char * unit); /*******************************Global Variables***********************************************/ //Handles and other useful variables HINSTANCE hinstanceG; int nCmdShowG; HWND hWndG; HWND hSquareTB, hSquareEdit1, hSquareEdit2, hSquareEdit3, hSquareGenerate; WNDCLASS wcG; //Drawing linked to buttons int interspace; int pos[NBBUTTONS][2]; int squareDim[2]; int trapezeDim[2]; int expDim[2]; //Square selection int posSquareTB = 0; int squareSelDim[2] = {WIDTH/2, LENGTH/2}; int TBDim[2] = {TBWIDTH, TBHEIGHT}; bool squareOn = FALSE; char * textSquareTB = "Duty Cycle"; char * textSquareEdit1 = "Amin (V)"; char * textSquareEdit2 = "Amax (V)"; char * textSquareEdit3 = "Period"; /***************************************Main function**********************************************/ int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { //Declarations HWND hWnd; MSG msg; WNDCLASS wc; //For the edit menu that we create in the window procedure hinstanceG = hinstance; nCmdShowG = nCmdShow; InitCommonControls(); //loads common control's DLL //Define the parameters of our window class wc.style = 0; wc.lpfnWndProc = MainWndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hinstance; wc.hIcon = LoadIcon(hinstance,MAKEINTRESOURCE(1)); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = (HBRUSH)(COLOR_3DFACE + 1); wc.lpszMenuName = "Menu"; wc.lpszClassName = "MyClass"; if(!RegisterClass(&wc)) return FALSE; else wcG = wc; //Create the main window hWnd = CreateWindow("MyClass", "Signal Construction", WS_OVERLAPPEDWINDOW | WS_TABSTOP, CW_USEDEFAULT, CW_USEDEFAULT, WIDTH, LENGTH, NULL, NULL, hinstance, NULL); if (!hWnd) return FALSE; ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); //Message-Processing loop while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam; } /**********************Window procedure********************************/ LRESULT CALLBACK MainWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { hWndG = hWnd; switch (uMsg) { static HWND hButton, hButton2, hButton3; //control handle for buttons //create a children window for typing text within the main window case WM_CREATE: hButton= CreateWindow( "button", // Predefined class; Unicode assumed "Square/Rectangle", // Button text WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON, // Styles MARGIN, // x position LENGTH - MARGIN, // y position 0, // Button width 0, // Button height hWnd, // Parent window (HMENU)PUSH1, // No menu. hinstanceG, // Instance handle NULL); // Pointer not needed ShowWindow(hButton, nCmdShowG); hButton2 = CreateWindow( "button", // Predefined class; Unicode assumed "Trapeze/Triangle", // Button text WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON, // Styles MARGIN, // x position MARGIN, // y position 0, // Button width 0, // Button height hWnd, // Parent window (HMENU)PUSH2, // No menu. hinstanceG, // Instance handle NULL); // Pointer not needed ShowWindow(hButton2, nCmdShowG); hButton3 = CreateWindow( "button", // Predefined class; Unicode assumed "Exponential", // Button text WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON, // Styles MARGIN, // x position MARGIN, // y position 0, // Button width 0, // Button height hWnd, // Parent window (HMENU)PUSH3, // No menu. hinstanceG, // Instance handle NULL); // Pointer not needed ShowWindow(hButton3, nCmdShowG); return 0; //Applies the changes of size of the main window to the children window as well case WM_SIZE: interspace = (LOWORD(lParam) - NBBUTTONS*LOWORD(lParam)/SCALE - 40) / (NBBUTTONS - 1); MoveWindow(hButton, MARGIN, HIWORD(lParam) - HIWORD(lParam)/SCALE - MARGIN, LOWORD(lParam)/SCALE, HIWORD(lParam)/SCALE, TRUE); pos[0][0] = MARGIN; pos[0][1] = HIWORD(lParam) - HIWORD(lParam)/SCALE - MARGIN; squareDim[0] = LOWORD(lParam)/SCALE/3; squareDim[1] = HIWORD(lParam)/SCALE; if(squareOn == TRUE) { squareSelDim[0] = LOWORD(lParam)/2; squareSelDim[1] = HIWORD(lParam)/2; TBDim[0] = TBWIDTH * ((float)LOWORD(lParam)/(float)WIDTH); TBDim[1] = TBHEIGHT * ((float)HIWORD(lParam)/(float)LENGTH); MoveWindow(hSquareTB, LOWORD(lParam) - TBDim[0] - MARGIN, MARGIN, TBDim[0], TBDim[1], TRUE); MoveWindow(hSquareEdit1, (2*squareSelDim[0]) - TBDim[0] - MARGIN, TBDim[1] + 2*MARGIN, EDITWIDTH, EDITHEIGHT, TRUE); MoveWindow(hSquareEdit2, (2*squareSelDim[0]) - 2*((float)TBDim[0]/3.0) - MARGIN, TBDim[1] + 2*MARGIN, EDITWIDTH, EDITHEIGHT, TRUE); MoveWindow(hSquareEdit3, (2*squareSelDim[0]) - ((float)TBDim[0]/3.0) - MARGIN, TBDim[1] + 2*MARGIN, EDITWIDTH, EDITHEIGHT, TRUE); MoveWindow(hSquareGenerate, (2*squareSelDim[0]) - TBDim[0] - MARGIN, TBDim[1] + 3*MARGIN + EDITHEIGHT, GENWIDTH, GENHEIGHT, TRUE); } MoveWindow(hButton2, MARGIN + LOWORD(lParam)/SCALE + interspace, HIWORD(lParam) - HIWORD(lParam)/SCALE - MARGIN, LOWORD(lParam)/SCALE, HIWORD(lParam)/SCALE, TRUE); pos[1][0] = MARGIN + LOWORD(lParam)/SCALE + interspace; pos[1][1] = HIWORD(lParam) - HIWORD(lParam)/SCALE - MARGIN; trapezeDim[0] = LOWORD(lParam)/SCALE/5; trapezeDim[1] = HIWORD(lParam)/SCALE; MoveWindow(hButton3, MARGIN + 2*(LOWORD(lParam)/SCALE + interspace), HIWORD(lParam) - HIWORD(lParam)/SCALE - MARGIN, LOWORD(lParam)/SCALE, HIWORD(lParam)/SCALE, TRUE); pos[2][0] = MARGIN + 2*(LOWORD(lParam)/SCALE + interspace); pos[2][1] = HIWORD(lParam) - HIWORD(lParam)/SCALE - MARGIN; expDim[0] = LOWORD(lParam)/SCALE; expDim[1] = HIWORD(lParam)/SCALE; RedrawWindow(hWnd, NULL, NULL, RDW_FRAME | RDW_INVALIDATE | RDW_ERASE | RDW_INTERNALPAINT); return 0; //Processes message s from the controls case WM_COMMAND: if(LOWORD(wParam) == QUIT) PostMessage(hWnd, WM_CLOSE,0,0); if(LOWORD(wParam) == ABOUT) MessageBox(hWnd,"Mon beau programme !","A propos !",0); if(LOWORD(wParam) == PUSH1) { if(squareOn == TRUE) destroySquareEnvironment(); setupSquareEnvironment(); RedrawWindow(hWnd, NULL, NULL, RDW_FRAME | RDW_INVALIDATE | RDW_ERASE | RDW_INTERNALPAINT); } if(LOWORD(wParam) == PUSH2) ; if(LOWORD(wParam) == PUSH3) ; if(LOWORD(wParam) == SQUAREGENERATE) generateSquare(); return 0; //Scroll case, like trackbar for instance case WM_HSCROLL: posSquareTB = SendMessage(hSquareTB, TBM_GETPOS, 0, 0); RedrawWindow(hWnd, NULL, NULL, RDW_FRAME | RDW_INVALIDATE | RDW_ERASE | RDW_INTERNALPAINT); return 0; //Painting procedure case WM_PAINT: paint(); return 0; case WM_CLOSE: if(MessageBox(hWnd,"Le texte a été modifié.\r\nEtes vous sûr de vouloir fermer l'application ?","Question ?",MB_YESNO | MB_ICONQUESTION ) == IDYES) DestroyWindow(hWnd); return 0; case WM_QUIT: return 0; //Destruction procedure case WM_DESTROY: PostQuitMessage(0); return 0; default: return DefWindowProc(hWnd, uMsg, wParam, lParam); } } /*****************************Painting signals function**********************************************/ void paint() { static HDC hdc; //peripheric handle for painting/drawing static PAINTSTRUCT ps; //painting structure for painting/drawing static HPEN hPen; //Pen for drawing static int i; static float a; a = (1.0/(float)expDim[0])*log((float)expDim[1]); //Initializations and selections of painting objects hdc = BeginPaint(hWndG, &ps); SetBkMode(hdc, TRANSPARENT); hPen = CreatePen(PS_SOLID, 4, 0xFF000000); SelectObject(hdc,hPen); //Square painting MoveToEx(hdc, pos[0][0], pos[0][1] - MARGIN, NULL); LineTo(hdc, pos[0][0] + squareDim[0], pos[0][1] - MARGIN); MoveToEx(hdc, pos[0][0] + squareDim[0], pos[0][1] - MARGIN, NULL); LineTo(hdc, pos[0][0] + squareDim[0], pos[0][1] - MARGIN - squareDim[1]); MoveToEx(hdc, pos[0][0] + squareDim[0], pos[0][1] - MARGIN - squareDim[1], NULL); LineTo(hdc, pos[0][0] + 2*squareDim[0], pos[0][1] - MARGIN - squareDim[1]); MoveToEx(hdc, pos[0][0] + 2*squareDim[0], pos[0][1] - MARGIN - squareDim[1], NULL); LineTo(hdc, pos[0][0] + 2*squareDim[0], pos[0][1] - MARGIN); MoveToEx(hdc, pos[0][0] + 2*squareDim[0], pos[0][1] - MARGIN, NULL); LineTo(hdc, pos[0][0] + 3*squareDim[0], pos[0][1] - MARGIN); //Trapeze painting MoveToEx(hdc, pos[1][0], pos[1][1] - MARGIN, NULL); LineTo(hdc, pos[1][0] + trapezeDim[0], pos[1][1] - MARGIN); MoveToEx(hdc, pos[1][0] + trapezeDim[0], pos[1][1] - MARGIN, NULL); LineTo(hdc, pos[1][0] + 2*trapezeDim[0], pos[1][1] - MARGIN - trapezeDim[1]); MoveToEx(hdc, pos[1][0] + 2*trapezeDim[0], pos[1][1] - MARGIN - trapezeDim[1], NULL); LineTo(hdc, pos[1][0] + 3*trapezeDim[0], pos[1][1] - MARGIN - trapezeDim[1]); MoveToEx(hdc, pos[1][0] + 3*trapezeDim[0], pos[1][1] - MARGIN - trapezeDim[1], NULL); LineTo(hdc, pos[1][0] + 4*trapezeDim[0], pos[1][1] - MARGIN); MoveToEx(hdc, pos[1][0] + 4*trapezeDim[0], pos[1][1] - MARGIN, NULL); LineTo(hdc, pos[1][0] + 5*trapezeDim[0], pos[1][1] - MARGIN); //Exponential painting for(i = 0; i < expDim[0]; i++) { MoveToEx(hdc, pos[2][0] + i, pos[2][1] - MARGIN + 1 - exp(a*i), NULL); LineTo(hdc, pos[2][0] + (i + 1), pos[2][1] - MARGIN + 1 - exp(a*(i + 1))); } MoveToEx(hdc, pos[2][0] + i + 1, pos[2][1] - MARGIN + 1 - exp(a*(i + 1)), NULL); LineTo(hdc, pos[2][0] + (i + 1), pos[2][1] - MARGIN); //Square painting if selected if(squareOn == TRUE) { //Painting of the square static HBRUSH hBrushErase; //Brush for painting hBrushErase = CreateSolidBrush((COLORREF)wcG.hbrBackground); static RECT eraseRect; if(posSquareTB != 0 && posSquareTB != 100) { MoveToEx(hdc, MARGIN, squareSelDim[1], NULL); LineTo(hdc, MARGIN, squareSelDim[1] - squareSelDim[1] + MARGIN); } else { eraseRect.left = MARGIN; eraseRect.top = squareSelDim[1] - 1; eraseRect.right = MARGIN; eraseRect.bottom = squareSelDim[1] - squareSelDim[1] + MARGIN; SelectObject(hdc,hBrushErase); FillRect(hdc, &eraseRect, hBrushErase); SelectObject(hdc,hPen); } MoveToEx(hdc, MARGIN, squareSelDim[1] - squareSelDim[1] + MARGIN, NULL); LineTo(hdc, MARGIN + ((float)posSquareTB/100.0) * squareSelDim[0], squareSelDim[1] - squareSelDim[1] + MARGIN); if(posSquareTB != 100 && posSquareTB != 0) { MoveToEx(hdc, MARGIN + ((float)posSquareTB/100.0) * squareSelDim[0], squareSelDim[1] - squareSelDim[1] + MARGIN, NULL); LineTo(hdc, MARGIN + ((float)posSquareTB/100.0) * squareSelDim[0], squareSelDim[1]); } else { eraseRect.left = MARGIN + squareSelDim[0]; eraseRect.top = squareSelDim[1] + 1; eraseRect.right = MARGIN + squareSelDim[0]; eraseRect.bottom = squareSelDim[1] - squareSelDim[1] + MARGIN; SelectObject(hdc,hBrushErase); FillRect(hdc, &eraseRect, hBrushErase); SelectObject(hdc,hPen); DeleteObject(hBrushErase); } MoveToEx(hdc, MARGIN + ((float)posSquareTB/100.0) * squareSelDim[0], squareSelDim[1], NULL); LineTo(hdc, MARGIN + squareSelDim[0], squareSelDim[1]); //Text display HFONT font; LOGFONT lf; ZeroMemory(&lf, sizeof(LOGFONT)); lstrcpy(lf.lfFaceName,"Times New Roman"); lf.lfHeight = FONTSIZE; font = CreateFontIndirect(&lf); SelectObject(hdc, font); SetTextColor(hdc, 0xFF000000); TextOut(hdc, (2*squareSelDim[0]) - TBDim[0] - MARGIN, 0, textSquareTB, lstrlen(textSquareTB)); TextOut(hdc, (2*squareSelDim[0]) - TBDim[0] - MARGIN, TBDim[1] + MARGIN, textSquareEdit1, lstrlen(textSquareEdit1)); TextOut(hdc, (2*squareSelDim[0]) - 2*((float)TBDim[0]/3.0) - MARGIN, TBDim[1] + MARGIN, textSquareEdit2, lstrlen(textSquareEdit2)); TextOut(hdc, (2*squareSelDim[0]) - ((float)TBDim[0]/3.0) - MARGIN, TBDim[1] + MARGIN, textSquareEdit3, lstrlen(textSquareEdit3)); DeleteObject(font); } //Destructions DeleteObject(hPen); EndPaint(hWndG, &ps); } /******************************Square signal selection functions*********************************************/ void setupSquareEnvironment(void) { //Sets flag squareOn = TRUE; //Creation and setup of the trackbar hSquareTB = CreateWindow( TRACKBAR_CLASS, // Predefined class; Unicode assumed "Duty Cycle selection", // Button text WS_TABSTOP | WS_VISIBLE | WS_CHILD | TBS_HORZ | TBS_NOTICKS // Styles | TBS_DOWNISLEFT | TBS_TOOLTIPS, WIDTH - TBDim[0] - MARGIN, // x position MARGIN, // y position TBDim[0], // Button width TBDim[1], // Button height hWndG, // Parent window (HMENU)SQUARETB, // No menu. hinstanceG, // Instance handle NULL); // Pointer not needed SendMessage( hSquareTB, TBM_SETRANGE, (WPARAM) TRUE, // redraw flag (LPARAM) MAKELONG(0, 100)); // min. & max. positions SendMessage( hSquareTB, TBM_SETPAGESIZE, 0, (LPARAM) 100); SendMessage( hSquareTB, TBM_SETSEL, (WPARAM) FALSE, (LPARAM) MAKELONG(0, 100)); SendMessage( hSquareTB, TBM_SETPOS, (WPARAM) FALSE, (LPARAM) 50); ShowWindow(hSquareTB, nCmdShowG); //Creation of the edit controls hSquareEdit1 =CreateWindow( "edit", NULL, WS_CHILD | WS_VISIBLE, WIDTH - TBDim[0] - MARGIN, TBDim[1] + 2*MARGIN, EDITWIDTH, EDITHEIGHT, hWndG, NULL, hinstanceG, NULL); ShowWindow(hSquareEdit1, nCmdShowG); hSquareEdit2 =CreateWindow( "edit", NULL, WS_CHILD | WS_VISIBLE, WIDTH - 2*((float)TBDim[0]/3.0) - MARGIN, TBDim[1] + 2*MARGIN, EDITWIDTH, EDITHEIGHT, hWndG, NULL, hinstanceG, NULL); ShowWindow(hSquareEdit2, nCmdShowG); hSquareEdit3 =CreateWindow( "edit", NULL, WS_CHILD | WS_VISIBLE, WIDTH - ((float)TBDim[0]/3.0) - MARGIN, TBDim[1] + 2*MARGIN, EDITWIDTH, EDITHEIGHT, hWndG, NULL, hinstanceG, NULL); ShowWindow(hSquareEdit3, nCmdShowG); //Generate button hSquareGenerate= CreateWindow( "button", // Predefined class; Unicode assumed "Generate", // Button text WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON, // Styles WIDTH - TBDim[0] - MARGIN, TBDim[1] + 3*MARGIN + EDITHEIGHT, GENWIDTH, // Button width GENHEIGHT, // Button height hWndG, // Parent window (HMENU)SQUAREGENERATE, // No menu. hinstanceG, // Instance handle NULL); // Pointer not needed ShowWindow(hSquareGenerate, nCmdShowG); } void destroySquareEnvironment(void) { DestroyWindow(hSquareTB); DestroyWindow(hSquareEdit1); DestroyWindow(hSquareEdit2); DestroyWindow(hSquareEdit3); DestroyWindow(hSquareGenerate); } int generateSquare(void) { float conv, AMIN, AMAX; float signal[2]; int * signalConv; char edit[20]; char unit; FILE * output; output = fopen("square.txt", "w"); if(output == NULL) return -1; Edit_GetText(hSquareEdit1, edit, 6); edit[strlen(edit)] = '\n'; edit[strlen(edit) + 1] = '\0'; fputs (edit, output); stringToFloat(edit, &AMIN, NULL); Edit_GetText(hSquareEdit2, edit, 6); edit[strlen(edit)] = '\n'; edit[strlen(edit) + 1] = '\0'; fputs (edit, output); stringToFloat(edit, &AMAX, NULL); signal[0] = AMIN; signal[1] = AMAX; Edit_GetText(hSquareEdit3, edit, 6); edit[strlen(edit)] = '\n'; edit[strlen(edit) + 1] = '\0'; stringToFloat(edit, &conv, &unit); convertTime(&conv, unit); sprintf(edit, "%.12f", conv); fputs(edit, output); edit[0] = '\n'; edit[1] = '\0'; fputs(edit, output); edit[0] = '\0'; sprintf(edit, "%d", posSquareTB); fputs(edit, output); edit[0] = '\n'; edit[1] = '\0'; fputs(edit, output); signalConv = convertSignal(signal, signalConv, 2, AMIN, AMAX); edit[0] = '\0'; sprintf(edit, "%d", *signalConv); fputs(edit, output); edit[0] = '\n'; edit[1] = '\0'; fputs(edit, output); edit[0] = '\0'; sprintf(edit, "%d", *(signalConv + 1)); fputs(edit, output); edit[0] = '\n'; edit[1] = '\0'; fputs(edit, output); fclose(output); destroySquareEnvironment(); } /******************************Signal generation functions*********************************************/ void convertTime(float * time, char unit) { switch(unit) { case 'h' : *time *= 3600; break; case 'M' : *time *= 60; break; case 's' : break; case 'm' : *time /= pow(10,3); break; case 'u' : *time /= pow(10,6); break; case 'n' : *time /= pow(10,9); break; default : printf("Unit not recognised, time left as is\n"); } } int * convertSignal(float * signal, int * signalConv, int nbPoints, float AMIN, float AMAX) { signalConv = malloc(nbPoints * sizeof(int)); int i; int j; for(i = 0; i < nbPoints; i++) { (*(signalConv + i)) = ( ((float)(pow(2,NBBITS) - 1)/(float)(AMAX - AMIN)) * *(signal + i) ) + (-AMIN * ((float)(pow(2,NBBITS) - 1)/(float)(AMAX - AMIN))); //printf("%d\n", (*(signalConv + i))); for(j = 0; j < NBBITS; j++) { if((*(signalConv + i)) & (1 << (NBBITS - j - 1))) ;//printf("1 "); else ;//printf("0 "); } //printf("\n"); } return signalConv; } void stringToFloat(char string[7], float * conv, char * unit) { int i, j, k; int left = 0, right = 0; *conv = 0; for(i = 0; i < 7 && string[i] != '\n' && string[i] != '.' && !(string[i] >= 0x41 && string[i] <= 0x7A); i++); for(j = i - 1; j >= 0; j--) { left += (string[j] - 0x30)*(pow(10, -j + i - 1)); } for(k = i + 1; string[k] != '\n' && !(string[k] >= 0x41 && string[k] <= 0x7A); k++); if(string[k] >= 0x41 && string[k] <= 0x7A && unit != NULL) *unit = string[k]; k -= i + 1; for(j = i + 1; string[j] != '\n' && !(string[j] >= 0x41 && string[j] <= 0x7A); j++) { right += (string[j] - 0x30)*(pow(10,k - (j - i - 1))); }; *conv = left + (right * pow(10, i - j)); }