Prev: U++ 2232 released
Next: SwapBuffers()
From: Jimbo on 16 Mar 2010 04:49 Hello have a graph application that draws a graph onto the client area. It is supposed to draw 2 lines. One line from the closest x axis value to the mouse & another line from the closest y axis value to the mouse. But these lines are not drawn & I am having an incredibly difficult time figuring out why? Can you help me fix this. I have supplied my code but I think that for someone to help me figure out whats wrong that you will probably need to see every function of my app so I have all my code here( its abit long). So I will list the functions that are responsible for drawing the lines to make it as easy as possible: [b]conGraph.cpp[/b] Control Class implementation file - void drawFocus(HDC hdc); - void eraseFocus(HWND hwnd); - bool findInstanceNearest(HWND hwnd, UINT msg, int mouse_x, int mouse_y); conGraph.cpp [source] #include <windows.h> #include <iostream> #include <algorithm> #include <cmath> #include <vector> #include <stdio.h> #include <stdlib.h> #include <stdio.h> #include <io.h> #include <fcntl.h> using namespace std; #include "conGraph.h" controller::controller() { // Set default values m = 2; b = -4; operand = '+'; xMin = INT_MAX; yMin = INT_MAX; xMax = INT_MIN; yMax = INT_MIN; xZero = 20; yZero = 450; minCellDim = 10; cellWidth = minCellDim; cellHeight = minCellDim; precision = 1; xBegin = -25; xEnd = 5; range = int(xEnd-xBegin); xCellNum = int((xMax-xMin)/precision); yCellNum = int((yMax-yMin)/precision); // Set default strokes xBorder = CreatePen(PS_SOLID,1,RGB(255,0,0)); yBorder = CreatePen(PS_SOLID,1,RGB(255,0,0)); functionLine = CreatePen(PS_SOLID,2,RGB(0,220,40)); intervalLine = CreatePen(PS_SOLID,1,RGB(255,255,255)); graphRgn = CreateRectRgn(0,0,1,1); focusRgn = CreateRectRgn(0,0,1,1); } void controller::createGUI(HWND hwnd, HINSTANCE gInstance, UINT controlMsg[]) { // Post: Create GUI to alter graph RECT rRect = {0}; GetClientRect(hwnd,&rRect); HFONT hfDefault = (HFONT)GetStockObject(DEFAULT_GUI_FONT); int dataCB[4] = {43,45,42,47}; int GUIx = 0; int GUIy = rRect.bottom-100; HWND stBorder = CreateWindowEx(0,"Static","",WS_BORDER| WS_CHILD| WS_VISIBLE,//| SS_GRAYRECT, GUIx,GUIy,rRect.right,100,hwnd, (HMENU)controlMsg[3],gInstance,NULL); HWND stfunctionLabel = CreateWindowEx(0,"Static","",WS_BORDER| WS_CHILD| WS_VISIBLE, GUIx+10,GUIy+15,150,33,hwnd, (HMENU)controlMsg[4],gInstance,NULL); HWND styLabel = CreateWindowEx(0,"Static"," y = ",WS_CHILD| WS_VISIBLE, GUIx+13,GUIy+18,25,20,hwnd, (HMENU)controlMsg[5],gInstance,NULL); HWND edMValue = CreateWindowEx(0,"Edit","m",WS_BORDER| WS_CHILD| WS_VISIBLE| ES_NUMBER| ES_CENTER, GUIx+42,GUIy+15,20,22,hwnd, (HMENU)controlMsg[0],gInstance,NULL); HWND stxLabel = CreateWindowEx(0,"Static","x",WS_CHILD| WS_VISIBLE, GUIx+65,GUIy+18,10,20,hwnd, (HMENU)controlMsg[6],gInstance,NULL); HWND cbOperand = CreateWindowEx(0,"Combobox","",WS_BORDER| WS_CHILD| WS_VISIBLE| CBS_DROPDOWNLIST, GUIx+76,GUIy+15,40,100,hwnd, (HMENU)controlMsg[1],gInstance,NULL); HWND edBValue = CreateWindowEx(0,"Edit","b",WS_BORDER| WS_CHILD| WS_VISIBLE| ES_NUMBER| ES_CENTER, GUIx+116,GUIy+15,20,22,hwnd, (HMENU)controlMsg[2],gInstance,NULL); HWND btDrawGrph = CreateWindowEx(0,"Button","Draw Graph",WS_BORDER|WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON, rRect.right-87,rRect.bottom-40,80,33,hwnd, (HMENU)controlMsg[7],gInstance,NULL); HWND stLimitsLabel = CreateWindowEx(0,"Static","",WS_BORDER| WS_CHILD|WS_VISIBLE,GUIx+10,GUIy+50,150,44, hwnd, (HMENU)controlMsg[8],gInstance,NULL); HWND stXMin = CreateWindowEx(0,"Static","x min=",WS_CHILD| WS_VISIBLE,GUIx+13,GUIy+52,50,20, hwnd, (HMENU)controlMsg[9],gInstance,NULL); HWND edXMin = CreateWindowEx(0,"Edit","0",WS_BORDER|WS_CHILD| WS_VISIBLE|ES_RIGHT,GUIx+48,GUIy+50,30,18, hwnd, (HMENU)controlMsg[10],gInstance,NULL); HWND stRange = CreateWindowEx(0,"Static","Range=",WS_CHILD| WS_VISIBLE,GUIx+83,GUIy+52,50,20, hwnd, (HMENU)controlMsg[11],gInstance,NULL); HWND edRange = CreateWindowEx(0,"Edit","10",WS_BORDER|WS_CHILD| WS_VISIBLE|ES_NUMBER|ES_RIGHT,GUIx+125,GUIy+50,30,18, hwnd, (HMENU)controlMsg[12],gInstance,NULL); HWND stPrec = CreateWindowEx(0,"Static","Precision=",WS_CHILD| WS_VISIBLE,GUIx+72,GUIy+72,50,17, hwnd, (HMENU)controlMsg[13],gInstance,NULL); HWND edPrec = CreateWindowEx(0,"Edit","1",WS_BORDER|WS_CHILD| WS_VISIBLE|ES_NUMBER|ES_RIGHT,GUIx+125,GUIy+70,30,18, hwnd, (HMENU)controlMsg[14],gInstance,NULL); HWND stFocusPnt = CreateWindowEx(0,"Static","X = 0 Y = 0",WS_BORDER|WS_CHILD|WS_VISIBLE|SS_CENTER, rRect.right-100,GUIy +10,90,45,hwnd,(HMENU)controlMsg[15],gInstance,NULL); // Set control fonts for(int i=0; i<15; i++) { SendDlgItemMessage(hwnd,controlMsg[i],WM_SETFONT, (WPARAM)hfDefault,MAKELPARAM(FALSE,0)); } // Add operand options to CB cbOperand SendDlgItemMessage(hwnd,controlMsg[1],CB_ADDSTRING,0,(LPARAM)" +"); SendDlgItemMessage(hwnd,controlMsg[1],CB_ADDSTRING,0,(LPARAM)" -"); SendDlgItemMessage(hwnd,controlMsg[1],CB_ADDSTRING,0,(LPARAM)" *"); SendDlgItemMessage(hwnd,controlMsg[1],CB_ADDSTRING,0, (LPARAM)" /"); SendDlgItemMessage(hwnd,controlMsg[1],CB_SETCURSEL,0,0); // select 1st cell of LB } void controller::resizeClientArea(HWND hwnd,UINT controlMsgs[]) { // Post: Reallign controls when client area is resized RECT rRect = {0}; GetClientRect(hwnd,&rRect); int GUIx = 0; int GUIy = rRect.bottom-100; SetWindowPos(GetDlgItem(hwnd,controlMsgs[3]),HWND_TOPMOST,GUIx,GUIy,rRect.right, 100,SWP_NOZORDER); SetWindowPos(GetDlgItem(hwnd,controlMsgs[4]),HWND_TOPMOST,GUIx +10,GUIy+10,150,33,SWP_NOZORDER); SetWindowPos(GetDlgItem(hwnd,controlMsgs[5]),HWND_TOPMOST,GUIx +13,GUIy+18,25,20,SWP_NOZORDER); SetWindowPos(GetDlgItem(hwnd,controlMsgs[0]),HWND_TOPMOST,GUIx +42,GUIy+15,20,22,SWP_NOZORDER); SetWindowPos(GetDlgItem(hwnd,controlMsgs[6]),HWND_TOPMOST,GUIx +65,GUIy+18,10,20,SWP_NOZORDER); SetWindowPos(GetDlgItem(hwnd,controlMsgs[2]),HWND_TOPMOST,GUIx +116,GUIy+15,20,22,SWP_NOZORDER); SetWindowPos(GetDlgItem(hwnd,controlMsgs[7]),HWND_TOPMOST,rRect.right-87,rRect.bottom-40,80,33,SWP_NOZORDER); SetWindowPos(GetDlgItem(hwnd,controlMsgs[8]),HWND_TOPMOST,GUIx +10,GUIy+47,150,44,SWP_NOZORDER); SetWindowPos(GetDlgItem(hwnd,controlMsgs[9]),HWND_TOPMOST,GUIx +13,GUIy+52,50,20,SWP_NOZORDER); SetWindowPos(GetDlgItem(hwnd,controlMsgs[10]),HWND_TOPMOST,GUIx +48,GUIy+50,30,18,SWP_NOZORDER); SetWindowPos(GetDlgItem(hwnd,controlMsgs[11]),HWND_TOPMOST,GUIx +83,GUIy+52,50,20,SWP_NOZORDER); SetWindowPos(GetDlgItem(hwnd,controlMsgs[12]),HWND_TOPMOST,GUIx +125,GUIy+50,30,18,SWP_NOZORDER); SetWindowPos(GetDlgItem(hwnd,controlMsgs[13]),HWND_TOPMOST,GUIx +72,GUIy+72,50,17,SWP_NOZORDER); SetWindowPos(GetDlgItem(hwnd,controlMsgs[14]),HWND_TOPMOST,GUIx +125,GUIy+70,30,18,SWP_NOZORDER); SetWindowPos(GetDlgItem(hwnd,controlMsgs[15]),HWND_TOPMOST,rRect.right-100,GUIy +10,90,45,SWP_NOZORDER); SetWindowPos(GetDlgItem(hwnd,controlMsgs[1]),HWND_TOP,GUIx+76,GUIy +15,40,100,SWP_NOZORDER); precision = 1; // need to reset precision when window is resized } float controller::equation(float xVal) { // Post: Calculate Y value, ie, Determine y = mx(?)b, according to the opperand type/value // Maybe rename function to findYValue(); if (operand=='-') { return ((m*xVal)-b); } else if (operand=='*') { return ((m*xVal)*b); } else if (operand=='/') { return ((m*xVal)/b); } else //if (operand=='+') return ((m*xVal)+b); } void controller::plotActualGraph() { // Post: Create x,y data points for graph // - xScaled = xZero + (x*cellWidth); // - yScaled = yZero - (y*cellHeight); functPnt.clear(); // clear vectors xMax = INT_MIN; yMax = INT_MIN; xMin = INT_MAX; yMin = INT_MAX; // Calculate x,y values & store min & max x,y values for (float xVal=xBegin; xVal<=xEnd; xVal+=1) { //precision) { POINT *p = new POINT; float yVal = equation(xVal); // determine y = mx + b p->x = (LONG)xVal; p->y = (LONG)yVal; functPnt.push_back(p); // store min & max values if (xVal > xMax) { xMax = xVal; } if (yVal > yMax) { yMax = yVal; } if (xVal < xMin) { xMin = xVal; } if (yVal < yMin) { yMin = yVal; } } if (xMax < 0) { xMax = 0; } if (yMax < 0) { yMax = 0; } range = (xMax-xMin); } void controller::plotScaledGraph() { // Pre: Vector variables x & y MUST have been defined & given values // & cell dimensions & min/max values calculated // Post: Create function line scaled to client area scaledPnt.clear(); // clear vectors for (int i=0; i<functPnt.size(); i+=1) { //(int)precision) { // scale x,y values for optimal graphical display POINT *p = new POINT; float xVal = functPnt.at(i)->x; float yVal = functPnt.at(i)->y; float xTemp = xZero + ((xVal-xMin)*cellWidth); float yTemp = yZero - ((yVal-yMin)*cellHeight); p->x = (LONG)xTemp; p->y = (LONG)yTemp; scaledPnt.push_back(p); } } void controller::debugGraph() { // Post: Debugging function cout << "Actual x,y values: \n"; for (int i=0; i<scaledPnt.size(); i++) { //if (i%10 !=0) { cout << endl; } cout << functPnt.at(i)->x << "," << functPnt.at(i)->y << " "; cout << scaledPnt.at(i)->x << "," << scaledPnt.at(i)->y << "\n"; } } void controller::calculateGraphStats(HWND hwnd) { // Post: Using the user specified precision, xBegin & range we calculate the // optimal cell height & width to fit the graph on screen. In some cases // the range may be too large for the graph to fit on the screen. To solve // this, the precision will be overwritten & set to a more optimal number. RECT rRect = {0}; GetClientRect(hwnd,&rRect); // get the client area dimensions plotActualGraph(); // calculate/plot graph x,y values // find optimal cell dimensions int spaceWidth = (rRect.right-rRect.left)-60; int spaceHeight = (rRect.bottom-rRect.top)-140; xCellNum = int((xMax-xMin)/precision); yCellNum = int((yMax-yMin)/precision); cellWidth = int(spaceWidth/xCellNum); cellHeight = int(spaceHeight/yCellNum); // if range is too large for client width OR height while (cellWidth<=minCellDim || cellHeight<=minCellDim) { precision += 1; xCellNum = int((xMax-xMin)/precision); yCellNum = int((yMax-yMin)/precision); cellWidth = int(spaceWidth/xCellNum); cellHeight = int(spaceHeight/yCellNum); } setCentre(hwnd,rRect); // Find if the graph contains x or y negative values plotScaledGraph(); // Plot/fit graph to client area } void controller::setCentre(HWND hwnd, RECT hRect) { // Post: Obtain/Calculate the best position for graph within client area // & set beginning points of x(xXAxis,yXAxis) & y(xYAxis,yYAxis) axis. // Default x,y axis position |__ xZero = (hRect.left)+20; yZero = (hRect.bottom)-120; xXAxis = xZero; yXAxis = yZero; xYAxis = xZero; yYAxis = yZero; // if any x or y values are negative then they require x,y borders to be // moved if (isNegative(functPnt,'x')) { xYAxis += int( abs(cellWidth*(xMin/precision))); } if (isNegative(functPnt,'y')) { yXAxis -= int( abs(cellHeight*(yMin/precision))); } graphRgn = CreateRectRgn(xXAxis,yYAxis,int(xXAxis+ (cellWidth*(xCellNum+0.1))),int(yYAxis-(cellHeight*(yCellNum+0.5)))); } void controller::drawGraph(HDC hdc) { // Pre: Central client area point(xZero,yZero) must be defined otherwise error // Post: Draw graph int graphSize = functPnt.size()-1; float xBeg,yBeg; float xEnd,yEnd; drawIntervals(hdc); drawBorders(hdc); drawText(hdc); /* for (int i=0; i<graphSize; i++) { // Get the lines start point(x,y values) xBeg = scaledPnt.at(i)->x; ybeg = scaledPnt.at(i)->y; // Get the lines end point(x,y values) xEnd = scaledPnt.at(i+1)->x; yEnd = scaledPnt.at(i+1)->y; // Draw line drawLine(hdc,(int)xBeg,(int)yBeg,(int)xEnd, (int)yEnd,functionLine); }*/ // draw function line from start point to end of graphs range drawLine(hdc,int(scaledPnt.at(0)->x),int(scaledPnt.at(0)- >y),int(xXAxis+(cellWidth*xCellNum)),int(yYAxis- (cellHeight*yCellNum)),functionLine); } void controller::drawBorders(HDC hdc) { // Post: draw x scale & y scale lines/borders drawLine(hdc,xXAxis,yXAxis,int(xXAxis+(cellWidth*(xCellNum +0.1))),yXAxis,xBorder); // draw x axis drawLine(hdc,xYAxis,yYAxis,xYAxis,int(yYAxis-(cellHeight*(yCellNum +0.5))),yBorder); // draw y axis } void controller::drawText(HDC hdc) { // Post: Draw intervals labels (1,2,3,5); int xb = xXAxis-3; int yb = yXAxis+5; char num[33]; HFONT hfDefault = (HFONT)GetStockObject(DEFAULT_GUI_FONT); SelectObject(hdc,hfDefault); // select default font SetBkMode(hdc,TRANSPARENT); //SetTextColor(hdc,RGB(255,255,255)); // draw x axis numbers for (float i=xMin; i<=xMax; i+=precision) { itoa((int)i,num,10); TextOut(hdc,xb,yb,(LPCTSTR)num,3); xb += (int)cellWidth; } xb = xYAxis-17; yb = yYAxis-6; // draw y axis numbers for (float i=yMin; i<=yMax; i+=precision) { itoa((int)i,num,10); TextOut(hdc,xb,yb,(LPCTSTR)num,3); yb -= (int)cellHeight; } DeleteObject(hfDefault); // release dynamic data } void controller::drawIntervals(HDC hdc) { // Post: Draws a line/mark at each cell interval along x & y axis int x,y; // draw x axis markers for (int i=0, x=(int)xXAxis, y=(int)yXAxis; i<=xCellNum; i++, x +=(int)cellWidth) { drawLine(hdc,x,y,x,y+4,intervalLine); } // draw y axis markers for (int i=0, x=(int)xYAxis, y=(int)yYAxis; i<=yCellNum; i++, y- =(int)cellHeight) { drawLine(hdc,x,y,x-4,y,intervalLine); } } void controller::drawFocus(HDC hdc) { // Post: - Determine & identify regions above & below function line // - Draw lines from focusPnt to X Axis & focusPnt to the Y Axis HRGN xLine, yLine; POINT xRgn[2]; POINT yRgn[2]; xRgn[0].x = scaledFocusPnt.x-1; xRgn[0].y = scaledFocusPnt.y+1; xRgn[1].x = scaledFocusPnt.x+1; xRgn[1].y = xYAxis; yRgn[0].x = scaledFocusPnt.x-1; yRgn[0].y = scaledFocusPnt.y-1; yRgn[1].x = xYAxis; yRgn[1].y = scaledFocusPnt.y+1; xLine = CreateRectRgn(xRgn[0].x,xRgn[0].y,xRgn[1].x,xRgn[1].y); yLine = CreateRectRgn(yRgn[0].x,yRgn[0].y,yRgn[1].x,yRgn[1].y); CombineRgn(focusRgn,xLine,yLine,RGN_XOR); DeleteObject(xLine); DeleteObject(yLine); // Here I have 2 options to draw the lines, BOTH dont work // Option 1: HBRUSH hb = CreateSolidBrush(RGB(0,220,40)); FillRgn(hdc,focusRgn,(HBRUSH)hb); // Option 2: //drawLine(hdc,xRgn[0].x,xRgn[0].y,xRgn[1].x,xRgn[1].y,xBorder); // Custom function that simply draws a line //drawLine(hdc,yRgn[0].x,yRgn[0].y,yRgn[1].x,yRgn[1].y,xBorder); } void controller::eraseFocus(HWND hwnd) { // Post: Erases focusPnt's lines by invalidating client area InvalidateRgn(hwnd,focusRgn,true); //InvalidateRgn(hwnd,xLine,true); //InvalidateRgn(hwnd,yLine,true); } bool controller::isNegative(vector<POINT*> v,char axis) { // Post: returns true if vector contains negative values if (axis=='x') { for (int i=0; i<v.size(); i++) { POINT *p = v.at(i); // if number is negative if (p->x < 0) { return true; } } return false; // vector contains no positive values } else if (axis=='y') { for (int i=0; i<v.size(); i++) { POINT *p = v.at(i); if (p->y < 0) { return true; } } return false; } else return true; // axis value is invalid } void controller::drawLine(HDC hdc,int xBeg,int yBeg, int xEnd, int yEnd, HPEN hPen) { // Post: draw x,y Line & any other required lines SelectObject(hdc,hPen); // need to add code to check if SelectObject fails MoveToEx(hdc,xBeg,yBeg,NULL); LineTo(hdc,xEnd,yEnd); } bool controller::getValues(HWND hwnd, UINT controlMsg[]) { // Post: Retrives values from GUI controls to calculate & draw graph UINT msgs[] = {controlMsg[0],controlMsg[2],controlMsg[10],controlMsg[12],controlMsg[14]}; int tempVars[5]; for (int i=0; i<5; i++) { BOOL success; tempVars[i] = GetDlgItemInt(hwnd,msgs[i],&success,true); // if control input is invalid if (!success) { MessageBox(hwnd,"One or more input fields are blank or invalid. \nValid input includes numerical data & '-' operand.", "Error",MB_OK|MB_ICONERROR); return false; } } getOpperand(hwnd,controlMsg[1]); // Get operand (+,-,* or /) // Range cannot be <= 0 if (tempVars[3]<=0) { tempVars[3] = 1; } // Precision cannot be <= 0 if (tempVars[4]<=0) { tempVars[4] = 1; } m = tempVars[0]; b = tempVars[1]; xBegin = tempVars[2]; range = tempVars[3]; precision = tempVars[4]; xEnd = (xBegin+range); return true; } void controller::getOpperand(HWND hwnd, UINT msg) { // Post: sets operand according to Combobox selection int cell = SendDlgItemMessage(hwnd,msg,CB_GETCURSEL,0,0); switch(cell) { case 0: operand = '+'; break; case 1: operand = '-'; break; case 2: operand = '*'; break; case 3: operand = '/'; break; default: operand = '+'; break; } } bool controller::collisionRect(int mouse_x, int mouse_y) { // Post: Returns true if mouse collides with Graph region(above or below the // function line) else false if (PtInRegion(graphRgn,mouse_x,mouse_y) != 0) { return true; } else return false; } bool controller::findInstanceNearest(HWND hwnd, UINT msg, int mouse_x, int mouse_y) { // Post: Finds the closest 'function line' point to mouse position & // updates Focus Point(static control text) int xDist = INT_MAX; int yDist = INT_MAX; POINT closestPnt; // find which axis is closest to mouse pos int xAxisDist = abs(yXAxis-mouse_y); int yAxisDist = abs(xYAxis-mouse_x); if (xAxisDist <= yAxisDist) { // if x axis is closest for (int i=0; i<scaledPnt.size(); i++) { POINT *tempP = scaledPnt.at(i); int xTemp = abs(mouse_x-(int)tempP->x); int yTemp = abs(mouse_y-(int)tempP->y); if (xTemp < xDist) { xDist = xTemp; closestPnt.x = (int)functPnt.at(i)->x; closestPnt.y = (int)functPnt.at(i)->y; } } } else { // y axis is closest for (int i=0; i<scaledPnt.size(); i++) { POINT *tempP = scaledPnt.at(i); int xTemp = abs(mouse_x-(int)tempP->x); int yTemp = abs(mouse_y-(int)tempP->y); if (yTemp < yDist) { yDist = yTemp; closestPnt.x = (int)functPnt.at(i)->x; closestPnt.y = (int)functPnt.at(i)->y; } } } // if closestPnt == focusPnt if ((closestPnt.x != focusPnt.x) && (closestPnt.y != focusPnt.y)) { focusPnt = closestPnt; scaledFocusPnt.x = LONG(xZero + ((focusPnt.x-xMin)*cellWidth)); scaledFocusPnt.y = LONG(yZero - ((focusPnt.y-yMin)*cellHeight)); char buf[MAX_PATH]; sprintf(buf,"(%i, %i)",focusPnt.x,focusPnt.y); SendDlgItemMessage(hwnd,msg,WM_SETTEXT,0,(LPARAM)buf); // Display closest pnt coords in Static Control return true; } else return false; // no need to redraw focus because focus pnt hasn't changed } void controller::garbageCollection() { // Post: Delete all dynamically created variables/objects. Release data DeleteObject(xBorder); // delete objects DeleteObject(yBorder); DeleteObject(functionLine); DeleteObject(intervalLine); DeleteObject(graphRgn); DeleteObject(focusRgn); // delete all POINT* objects: while (!functPnt.empty()) { delete functPnt.back(); functPnt.pop_back(); } while (!scaledPnt.empty()) { delete scaledPnt.back(); scaledPnt.pop_back(); } } [/source] winMain.cpp [source] #include <windows.h> #include <iostream> #include <stdio.h> #include <io.h> #include <fcntl.h> #include "conGraph.h" #define IDE_MVALUE 1 #define IDC_OPERAND 2 #define IDE_BVALUE 3 #define IDS_BORDER 4 #define IDS_FUNCTION 5 #define IDS_YLABEL 6 #define IDS_XLABEL 7 #define IDB_DRAWGRAPH 8 #define IDS_BORDER2 9 #define IDS_XMIN 10 #define IDE_XMIN 11 #define IDS_RANGE 12 #define IDE_RANGE 13 #define IDS_PRECISION 14 #define IDE_PRECISION 15 #define IDS_FOCUSPNT 16 const char g_szClassName[] = "myWindowClass"; static HINSTANCE gInstance; controller graphCon; bool drawGraph = true; // do we need to redraw graph bool drawFocus = false; UINT controlMsgs[] = {IDE_MVALUE,IDC_OPERAND,IDE_BVALUE,IDS_BORDER,IDS_FUNCTION,IDS_YLABEL,IDS_XLABEL, IDB_DRAWGRAPH,IDS_BORDER2,IDS_XMIN,IDE_XMIN,IDS_RANGE,IDE_RANGE,IDS_PRECISION, IDE_PRECISION,IDS_FOCUSPNT}; // Functions List // LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); int WINAPI WinMain(HINSTANCE gInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { WNDCLASSEX wc; HWND hwnd; MSG Msg; //Step 1: Registering the Window Class wc.cbSize = sizeof(WNDCLASSEX); wc.style = 0; wc.lpfnWndProc = WndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = gInstance; wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = (HBRUSH)(DKGRAY_BRUSH); wc.lpszMenuName = NULL; wc.lpszClassName = g_szClassName; wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION); // if registration of main class fails if(!RegisterClassEx(&wc)) { MessageBox(NULL, "Window Registration Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK); return 0; } // Step 2: Creating the Window hwnd = CreateWindowEx( WS_EX_CLIENTEDGE, g_szClassName, "Graph Application", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 500, 500, NULL, NULL, gInstance, NULL); if(hwnd == NULL) { MessageBox(NULL, "Window Creation Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK); return 0; } ShowWindow(hwnd, nCmdShow); UpdateWindow(hwnd); // Step 3: The Message Loop while(GetMessage(&Msg, NULL, 0, 0) > 0) { TranslateMessage(&Msg); DispatchMessage(&Msg); } return Msg.wParam; } // Step 4: the Window Procedure LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { //HDC hdc; switch(msg) { case WM_CREATE: graphCon.createGUI(hwnd,gInstance,controlMsgs); graphCon.calculateGraphStats(hwnd); break; case WM_SIZE: // Reallign controls & graph when client window is resized RECT clientR; GetClientRect(hwnd,&clientR); // Check that client area is not less than minimum width & height if (clientR.right >400 && clientR.bottom >400 ) { graphCon.resizeClientArea(hwnd,controlMsgs); graphCon.calculateGraphStats(hwnd); drawGraph = true; InvalidateRect(hwnd,NULL,true); } else MessageBox(hwnd,"Graph cannot be drawn when window is less than 400/400 pixels", "Error",MB_OK|MB_ICONERROR); break; case WM_MOUSEMOVE: { if (graphCon.collisionRect(LOWORD(lParam),HIWORD(lParam))==true) { // if focusPnt has changed if (graphCon.findInstanceNearest(hwnd,IDS_FOCUSPNT,LOWORD(lParam),HIWORD(lParam)) == true) { // find nearest function line pnt to mouse pos drawFocus = true; graphCon.eraseFocus(hwnd); } } } break; case WM_COMMAND: { switch(LOWORD(wParam)) { case IDB_DRAWGRAPH: { // Draw graph // if all input variables are valid if (graphCon.getValues(hwnd,controlMsgs)==true) { graphCon.calculateGraphStats(hwnd); drawGraph = true; InvalidateRect(hwnd,NULL,true); } } break; default: break; } } break; case WM_PAINT: { HDC hdc; PAINTSTRUCT ps; hdc = BeginPaint(hwnd,&ps); if (drawFocus) { graphCon.drawFocus(hdc); drawFocus = false; } if (drawGraph) { graphCon.drawGraph(hdc); drawGraph = false; } EndPaint(hwnd,&ps); } break; case WM_CLOSE: graphCon.garbageCollection(); // release dynamic data DestroyWindow(hwnd); break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hwnd, msg, wParam, lParam); } return 0; } [/source]
|
Pages: 1 Prev: U++ 2232 released Next: SwapBuffers() |