#pragma once #include "akGraph/akGraphLinker.h" #include "akGraph/akMemDC.h" #include "akGraph/akGraphStruct.h" #include "akGraph/akSyncObject.h" #include "akSTL/akStruct.h" // akGraphBase #define AKGRAPH_BUTTONDOWN WM_USER+0x1001 #define AKGRAPH_MOUSEMOVE WM_USER+0x1002 #include class AFX_EXT_CLASS CakGraphThreadDraw; class AFX_EXT_CLASS CakGraphBase : public CWnd, public CakSyncObject { DECLARE_DYNAMIC(CakGraphBase) public: CakGraphBase(); virtual ~CakGraphBase(); protected: DECLARE_MESSAGE_MAP() CakMouseState m_MouseState; public: virtual BOOL CreateGraph(CWnd* pParent, CRect rect); virtual void RenderBegin(CDC* pDC, CRect rectDC); virtual void RenderGrid(Graphics* grfx, CDC* pDC){}; virtual void RenderDataArea(Graphics* grfx, CDC* pDC); //µ¥ÀÌÅÍ ¿µ¿ª ±×¸®±â virtual void RenderSeries(Graphics* grfx, CDC* pDC){}; //µ¥ÀÌÅÍ ¼±/¹Ù ±×¸®±â virtual void RenderLegend(Graphics* grfx, CDC* pDC){}; //¹ü·Ê virtual void RenderAxis(Graphics* grfx, CDC* pDC); //Ãà ¿µ¿ª ±×¸®±â virtual void RenderTitle(Graphics* grfx, CDC* pDC); //Á¦¸ñ ¿µ¿ª ±×¸®±â virtual void RenderLabel(Graphics* grfx, CDC* pDC){}; //ÇØ´ç Ãà¿¡ ƽ±×¸®±â, µ¥ÀÌÅÍ ¿µ¿ª ¿Ü°¢¼± ±×¸®±â virtual void RenderEnd(Graphics* grfx, CDC* pDC); //±×¸®´Â ºÎºÐ ¸¶Áö¸·¿¡ Ãß°¡(Redraw false ÇÒ¶§µµ ±×¸²) virtual void RenderClossLine(CDC* pDC); //¸¶¿ì½º Å©·Î½º ¶óÀÎ ±×¸®±â [±èÅÂÇö 2018/9/7] virtual void RenderMouseHoverInfo(CDC* pDC){}; //¸¶¿ì½º ¿Ã·ÁÁ® ÀÖÀ» °æ¿ì µ¥ÀÌÅÍÇ¥½Ã ±×¸®±â [±èÅÂÇö 2018/9/7] virtual void RenderPerformance(Graphics* grfx, CDC* pDC); virtual void GetRenderFrame(CDC* pDC, CRect rect); virtual void ReDraw(bool bReDrawALL = true); virtual void SetAutoScale(){}; //ÀÌ·±°Ç ±âº»ÀûÀ¸·Î ÀÖ¾î¾ßµÊ!! virtual void SetTitle(char* titlename); virtual char* GetTitle(); virtual void SetAxisXTitle(char* titlename){m_AxisX.m_strTitle = titlename;}; virtual void SetAxisYTitle(char* titlename){m_AxisY.m_strTitle = titlename;}; virtual void OnKeyInput(int key, int mode); //mode 0==keyup, mode 1==keydown //Űº¸µå ÀÔ·Â À̺¥Æ® ó¸® virtual void OnMouseInput(akMouseEvent mouseevent, CPoint point); //¸¶¿ì½º ÀÔ·Â À̺¥Æ®Ã³¸® virtual void MouseInput(CakMouseState mousestate){}; //¸¶¿ì½º »óÅÂó¸® virtual void OnSystemKeyInput(int key, int mode); //mode 0==keyup, mode 1==keydown //Űº¸µå ÀÔ·Â À̺¥Æ® ó¸® virtual void EnableThreadDrawMode(int nSleepTime = 30, int nSleepTimeMin = 1);//Çѹø Ű¸é ³¡ void SetDragStyle(akDragStyle style){m_DragStyle = style;} ; //0Àº ²ô±â, 1Àº ¾çÂʸðµÎ, 2Àº ¼¼·Î¼±¸¸, 3´Â °¡·Î¼±¸¸ akDragStyle GetDragStyle(){return m_DragStyle;}; CPoint GetMousePos(){return m_MouseState.Point;}; void SetWindowSize(int x, int y, int width, int height, UINT flag = NULL, bool reDraw = true); void SetWindowSize(int width, int height, UINT flag = NULL, bool reDraw = true); void GetWindowSize(int* width, int* height); inline CakRect GetDataArea(){return m_rectData;}; inline CakRect GetTitleArea(){return m_rectTitle;}; inline CakRect GetAxisXArea(){return m_rectAxisX;}; inline CakRect GetAxisYArea(){return m_rectAxisY;}; void SetTitleSize(int height);//ŸÀÌÆ²¹Ù ¼¼·ÎÃà Å©±â void SetAxisXSize(int height);//xÃà ¼¼·Î Å©±â void SetAxisYSize(int width);//yÃà °¡·Î Å©±â void SetSaveImage(char* strFilepathname); void SetClossLine(bool flag = true){m_bClossLine = flag;}; //¸¶¿ì½º Á¦¾î ¸ðµå(0:¿ìŬ¸¯ À̵¿¸ðµå, 1:ÁÂŬ¸¯ À̵¿¸ðµå) [±èÅÂÇö 2018/8/22] void SetMouseControlMode(int nType){m_nMouseControlMode = nType;}; inline void SetID(int nID); inline int GetID(); virtual void FuncThreadDraw(); protected: virtual void CaculatorGraphSize(); virtual void getLbuttonDragPoint(int* px1, int* py1, int* px2, int* py2); private: public: int m_nID;//¸Þ¼¼Áö º¸³¾¶§ °°ÀÌ º¸³»Áָ鼭.. ÀνºÅϽº¸¦ ±¸ºÐÇÑ´Ù. CAxis m_AxisX; CAxis m_AxisY; CAxis m_AxisY2;//¿À¸¥ÂÊ y°ø°£ CTitle m_Title; CMouseMoveInfo m_MouseMoveInfo;//¸¶¿ì½º ¿òÁ÷ÀÓ¿¡ µû¶ó È­¸é¿¡ Ç¥½ÃµÇ´Â ³»¿ë CakRectd m_AutoScaleMarginRate;//ÀÚµ¿½ºÄÉÀÏ ¾ç¿· ¾Æ·¡,À§ ¿©¹é ºñÀ² ¼³Á¤ CakRect m_rectLabelAdjust; bool m_bCheckDC; //¿Ã¹Ù¸¥ DCÀΰ¡ È®ÀÎ ÀýÂ÷¸¦ »ý·«ÇÒ °ÍÀÎÁö ¿©ºÎ bool m_bClossLine; int m_nMouseControlMode; CakGraphThreadDraw* m_pThreadDraw; protected: CWnd* m_pParent; //ºÎ¸ð À©µµ¿ì Ŭ·¡½º //¸Þ¸ð¸® µð¾¾~ CDC m_GraphDC; CBitmap m_GraphBitmap, *m_pGraphOldBitmap; CRect m_rectGraphBitmap; //±×·¡ÇÁ ´Ù½Ã ±×·Á¾ß ÇÒ¶§ bool m_bReRender; //±×¸®´Â ºÎºÐ ¿µ¿ª Å©±â int m_nWindowSizeWidth, m_nWindowSizeHeight; //±×¸®´Â ¿µ¿ª °¢°¢ÀÇ Å©±â(¸Å¹ø CaculatorGraphSize() ÇÔ¼ö¿¡ ÀÇÇØ °è»êÀÌ µÈ´Ù) CakRect m_rectData; //¼ø¼öÇÏ°Ô ±×·¡ÇÁ ±×¸®´Â ºÎºÐ ¿µ¿ª CakRect m_rectChartMargin; //µ¥ÀÌÅÍ ±×¸®´Â ºÎºÐ ¿À¸¥ÂÊ ¿©¹é CakRect m_rectAxisX; CakRect m_rectAxisY; CakRect m_rectTitle; CFont m_fontData; //µ¥ÀÌÅÍ ÆùÆ® bool m_bRenderState; bool m_bHover; public: COLORREF m_colorBack; //¹è°æ»ö COLORREF m_colorDataArea; //µ¥ÀÌÅÍ ±×¸®´ÂºÎºÐ ¹è°æ»ö protected: akDragStyle m_DragStyle; private: CFont m_fontWaterMake; ULONG_PTR m_gdiplusToken; //GDI+ ÅäÅ« CString m_strSaveFilePath; //¼º´É üũ °ü·Ã private: int m_nShowPerformance; int m_nTimeRenderTotal; int m_nTimeRenderDraw1stBuffer; int m_nTimeRenderDraw2ndBuffer; int m_nTimeTempTotal; int m_nTimeTempDraw1stBuffer; int m_nTimeTempDraw2ndBuffer; int m_nTimeRenderCount; int m_nTimerRenderTotalMax; int m_nTimerRenderTotalMin; public: static bool m_bAK; static void setAK(){CakGraphBase::m_bAK = false;}; afx_msg void OnPaint(); afx_msg void OnSize(UINT nType, int cx, int cy); virtual BOOL PreTranslateMessage(MSG* pMsg); afx_msg void OnShowWindow(BOOL bShow, UINT nStatus); afx_msg BOOL OnEraseBkgnd(CDC* pDC); //int m_DataState; //afx_msg void OnTimer(UINT nIDEvent); afx_msg void OnTimer(UINT_PTR nIDEvent); }; class AFX_EXT_CLASS CakGraphThreadDraw { public: CakGraphThreadDraw() { m_bThreadDrawMode = FALSE; m_bDrawByThread = FALSE; m_nThreadDrawFlag = 0; m_nThreadDrawSleepTimeMin = 1; m_nThreadDrawSleepTime = 30; InitializeCriticalSection(&m_csThreadDraw); }; virtual ~CakGraphThreadDraw() { if(GetThreadDrawMode()) { m_nThreadDrawFlag = 2; int nReTryCount = 10; while (m_nThreadDrawFlag != 0 && nReTryCount--) { Sleep(1); } } }; public: virtual BOOL CreateThreadDraw(CakGraphBase* pBase) { if(pBase == NULL) return FALSE; //if(GetThreadDrawMode()) { m_nThreadDrawFlag = 1; //_beginthread(threadThreadDraw, NULL, this); AfxBeginThread(threadThreadDraw, this, NULL); m_pGraphBase = pBase; m_bDrawByThread = TRUE; } return TRUE; } void SetDrawByThread(BOOL bFlag){m_bDrawByThread = bFlag;}; void SetThreadDrawMode(BOOL bFlag){m_bThreadDrawMode = bFlag;}; BOOL GetThreadDrawMode(){return m_bThreadDrawMode;}; CRITICAL_SECTION* GetCriticalSection(){return &m_csThreadDraw;}; void SleepMsg(IN DWORD dwMilliseconds) { DWORD dwStart = 0; MSG msg = {0,}; dwStart = GetTickCount(); while (GetTickCount() - dwStart < dwMilliseconds) { while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { TranslateMessage(&msg); DispatchMessage(&msg); } // Lower CPU Usage ::Sleep(1); } } public: int m_nThreadDrawSleepTime; int m_nThreadDrawSleepTimeMin; protected: BOOL m_bThreadDrawMode; //CDC m_ThreadDrawDC; //CBitmap m_ThreadDrawBitmap; //CRect m_rectThreadDrawBitmap; int m_nThreadDrawFlag; BOOL m_bDrawByThread; CRITICAL_SECTION m_csThreadDraw; CakGraphBase* m_pGraphBase; protected: //static void threadThreadDraw(void* arg) static UINT threadThreadDraw(LPVOID arg) { CakGraphThreadDraw* pThis = (CakGraphThreadDraw*)arg; while (pThis->m_nThreadDrawFlag == 1) { DWORD dwTimeStart = GetTickCount(); if(pThis->m_bDrawByThread) { pThis->m_bDrawByThread = FALSE; pThis->funcThreadDraw(); } else { } int nSleepTimeDynamic = pThis->m_nThreadDrawSleepTime-(GetTickCount()-dwTimeStart); nSleepTimeDynamic = max(nSleepTimeDynamic, pThis->m_nThreadDrawSleepTimeMin); nSleepTimeDynamic = pThis->m_nThreadDrawSleepTime; Sleep(nSleepTimeDynamic); //pThis->SleepMsg(nSleepTimeDynamic); } pThis->m_nThreadDrawFlag = 0; return TRUE; }; virtual void funcThreadDraw() { m_pGraphBase->FuncThreadDraw(); }; };