commit 40d7b08f5580705634f9b14933447cae046164e6 Author: ritoseo Date: Mon Mar 17 10:29:45 2025 +0900 v1.0.0 2023-09-04 최종 수정버전 diff --git a/CRoundButton.cpp b/CRoundButton.cpp new file mode 100644 index 0000000..6c56636 --- /dev/null +++ b/CRoundButton.cpp @@ -0,0 +1,7 @@ +#include "stdafx.h" +#include "CRoundButton.h" + +BOOL CRoundButton::OnEraseBkgnd(CDC* pDC) +{ + return true; +} \ No newline at end of file diff --git a/CRoundButton.h b/CRoundButton.h new file mode 100644 index 0000000..da27d8c --- /dev/null +++ b/CRoundButton.h @@ -0,0 +1,8 @@ +#pragma once +#include "ColorButton.h" +class CRoundButton : + public CColorButton +{ + BOOL OnEraseBkgnd(CDC* pDC); +}; + diff --git a/ColorButton.cpp b/ColorButton.cpp new file mode 100644 index 0000000..b670c0a --- /dev/null +++ b/ColorButton.cpp @@ -0,0 +1,383 @@ +// ColorButton.cpp : implementation file +// +// Written by Marius Bancila (mbancila@yahoo.com) +// Copyright (c) 2004. +// +// This code may be used in compiled form in any way you desire. This +// file may be redistributed unmodified by any means PROVIDING it is +// not sold for profit without the authors written consent, and +// providing that this notice and the authors name is included. If +// the source code in this file is used in any commercial application +// then acknowledgement must be made to the author of this file +// (in whatever form you wish). +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// +// Please use and enjoy. Please let me know of any bugs/mods/improvements +// that you have found/implemented and I will fix/incorporate them into this +// file. + +#include "stdafx.h" +#include "ColorButton.h" + +#include + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +namespace clr +{ + const COLORREF CLR_BTN_WHITE = RGB(255, 255, 255); + const COLORREF CLR_BTN_BLACK = RGB(0, 0, 0); + const COLORREF CLR_BTN_DGREY = RGB(128, 128, 128); + const COLORREF CLR_BTN_GREY = RGB(192, 192, 192); + const COLORREF CLR_BTN_LLGREY = RGB(223, 223, 223); +} + +///////////////////////////////////////////////////////////////////////////// +// CColorButton +CColorButton::CColorButton() +{ + SetColorToWindowsDefault(); +} + +CColorButton::CColorButton(COLORREF text, COLORREF bkgnd) +{ + m_TextColor = text; + m_BkgndColor = bkgnd; + m_DisabledBkgndColor = GetSysColor(COLOR_BTNFACE); + m_Light = GetSysColor(COLOR_3DLIGHT); + m_Highlight = GetSysColor(COLOR_BTNHIGHLIGHT); + m_Shadow = GetSysColor(COLOR_BTNSHADOW); + m_DarkShadow = GetSysColor(COLOR_3DDKSHADOW); +} + +CColorButton::CColorButton(COLORREF text, COLORREF bkgnd, COLORREF disabled) +{ + m_TextColor = text; + m_BkgndColor = bkgnd; + m_DisabledBkgndColor = disabled; + m_Light = GetSysColor(COLOR_3DLIGHT); + m_Highlight = GetSysColor(COLOR_BTNHIGHLIGHT); + m_Shadow = GetSysColor(COLOR_BTNSHADOW); + m_DarkShadow = GetSysColor(COLOR_3DDKSHADOW); +} + +CColorButton::CColorButton(COLORREF text, COLORREF bkgnd, COLORREF disabled, COLORREF light, COLORREF highlight, COLORREF shadow, COLORREF darkShadow) +{ + m_TextColor = text; + m_BkgndColor = bkgnd; + m_DisabledBkgndColor = disabled; + m_Light = light; + m_Highlight = highlight; + m_Shadow = shadow; + m_DarkShadow = darkShadow; +} + +CColorButton::~CColorButton() +{ +} + + +BEGIN_MESSAGE_MAP(CColorButton, CButton) + //{{AFX_MSG_MAP(CColorButton) + ON_WM_CREATE() + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CColorButton message handlers + +void CColorButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) +{ + CDC *pDC; + CRect rcFocus, rcButton, rcText, rcOffsetText; + UINT state; + + pDC = CDC::FromHandle(lpDrawItemStruct->hDC); + state = lpDrawItemStruct->itemState; + + rcFocus.CopyRect(&lpDrawItemStruct->rcItem); + rcButton.CopyRect(&lpDrawItemStruct->rcItem); + + rcText = rcButton; + rcText.OffsetRect(-1, -1); + + rcOffsetText = rcText; + rcOffsetText.OffsetRect(1, 1); + + // Set the focus rectangle to just past the border decoration + rcFocus.left += 4; + rcFocus.right -= 4; + rcFocus.top += 4; + rcFocus.bottom -= 4; + + // Retrieve the button's caption + CString strCaption; + GetWindowText(strCaption); + + if (state & ODS_DISABLED) + { + DrawFilledRect(pDC, rcButton, m_DisabledBkgndColor); + } + else + { + DrawFilledRect(pDC, rcButton, m_BkgndColor); + } + + if (state & ODS_SELECTED) + { + DrawFrame(pDC, rcButton, BUTTON_IN); + } + else + { + if ((state & ODS_DEFAULT) || (state & ODS_FOCUS)) + { + DrawFrame(pDC, rcButton, BUTTON_OUT | BUTTON_BLACK_BORDER); + } + else + { + DrawFrame(pDC, rcButton, BUTTON_OUT); + } + } + + if (state & ODS_DISABLED) + { + DrawButtonText(pDC, rcOffsetText, strCaption, clr::CLR_BTN_WHITE); + DrawButtonText(pDC, rcText, strCaption, clr::CLR_BTN_DGREY); + } + else + { + if (state & ODS_SELECTED) + { + DrawButtonText(pDC, rcOffsetText, strCaption, m_TextColor); + } + else + { + DrawButtonText(pDC, rcText, strCaption, m_TextColor); + } + } + + if (state & ODS_FOCUS) + { + DrawFocusRect(lpDrawItemStruct->hDC, (LPRECT)&rcFocus); + } +} + +void CColorButton::DrawFrame(CDC *pDC, CRect rc, int state) +{ + COLORREF color; + + if (state & BUTTON_BLACK_BORDER) + { + color = clr::CLR_BTN_BLACK; + + DrawLine(pDC, rc.left, rc.top, rc.right, rc.top, color); // Across top + DrawLine(pDC, rc.left, rc.top, rc.left, rc.bottom, color); // Down left + + DrawLine(pDC, rc.left, rc.bottom - 1, rc.right, rc.bottom - 1, color); // Across bottom + DrawLine(pDC, rc.right - 1, rc.top, rc.right - 1, rc.bottom, color); // Down right + + rc.InflateRect(-1, -1); + } + + if (state & BUTTON_OUT) + { + color = m_Highlight; + + DrawLine(pDC, rc.left, rc.top, rc.right, rc.top, color); // Across top + DrawLine(pDC, rc.left, rc.top, rc.left, rc.bottom, color); // Down left + + color = m_DarkShadow; + + DrawLine(pDC, rc.left, rc.bottom - 1, rc.right, rc.bottom - 1, color); // Across bottom + DrawLine(pDC, rc.right - 1, rc.top, rc.right - 1, rc.bottom, color); // Down right + + rc.InflateRect(-1, -1); + + color = m_Light; + + DrawLine(pDC, rc.left, rc.top, rc.right, rc.top, color); // Across top + DrawLine(pDC, rc.left, rc.top, rc.left, rc.bottom, color); // Down left + + color = m_Shadow; + + DrawLine(pDC, rc.left, rc.bottom - 1, rc.right, rc.bottom - 1, color); // Across bottom + DrawLine(pDC, rc.right - 1, rc.top, rc.right - 1, rc.bottom, color); // Down right + } + + if (state & BUTTON_IN) + { + color = m_DarkShadow; + + DrawLine(pDC, rc.left, rc.top, rc.right, rc.top, color); // Across top + DrawLine(pDC, rc.left, rc.top, rc.left, rc.bottom, color); // Down left + DrawLine(pDC, rc.left, rc.bottom - 1, rc.right, rc.bottom - 1, color); // Across bottom + DrawLine(pDC, rc.right - 1, rc.top, rc.right - 1, rc.bottom, color); // Down right + + rc.InflateRect(-1, -1); + + color = m_Shadow; + + DrawLine(pDC, rc.left, rc.top, rc.right, rc.top, color); // Across top + DrawLine(pDC, rc.left, rc.top, rc.left, rc.bottom, color); // Down left + DrawLine(pDC, rc.left, rc.bottom - 1, rc.right, rc.bottom - 1, color); // Across bottom + DrawLine(pDC, rc.right - 1, rc.top, rc.right - 1, rc.bottom, color); // Down right + } +} + +void CColorButton::DrawFilledRect(CDC *pDC, CRect rc, COLORREF color) +{ + CBrush brSolid; + + brSolid.CreateSolidBrush(color); + pDC->FillRect(rc, &brSolid); +} + +void CColorButton::DrawLine(CDC *pDC, long sx, long sy, long ex, long ey, COLORREF color) +{ + CPen newPen; + CPen *oldPen; + + newPen.CreatePen(PS_SOLID, 1, color); + oldPen = pDC->SelectObject(&newPen); + + pDC->MoveTo(sx, sy); + pDC->LineTo(ex, ey); + pDC->SelectObject(oldPen); + + newPen.DeleteObject(); +} + +void CColorButton::DrawButtonText(CDC *pDC, CRect rc, CString strCaption, COLORREF textcolor) +{ + DWORD uStyle = GetWindowLong(this->m_hWnd,GWL_STYLE); + + CArray arLines; + + if((uStyle & BS_MULTILINE) == BS_MULTILINE) + { + int nIndex = 0; + while(nIndex != -1) + { + nIndex = strCaption.Find('\n'); + if(nIndex>-1) + { + CString line = strCaption.Left(nIndex); + arLines.Add(line); + strCaption.Delete(0,nIndex+1); + } + else + arLines.Add(strCaption); + } + } + else + { + arLines.Add(strCaption); + } + + CSize sizeText = pDC->GetOutputTextExtent( strCaption ); + + COLORREF oldColour; + + oldColour = pDC->SetTextColor(textcolor); + pDC->SetBkMode(TRANSPARENT); + + int nStartPos = (rc.Height() - arLines.GetSize()*sizeText.cy)/2-1; + if((uStyle & BS_TOP) == BS_TOP) + nStartPos = rc.top+2; + if((uStyle & BS_BOTTOM) == BS_BOTTOM) + nStartPos = rc.bottom- arLines.GetSize()*sizeText.cy-2; + if((uStyle & BS_VCENTER) == BS_VCENTER) + nStartPos = (rc.Height() - arLines.GetSize()*sizeText.cy)/2-1; + + UINT uDrawStyles = 0; + if((uStyle & BS_CENTER) == BS_CENTER) + uDrawStyles |= DT_CENTER; + else + { + if((uStyle & BS_LEFT) == BS_LEFT) + uDrawStyles |= DT_LEFT; + else + if((uStyle & BS_RIGHT) == BS_RIGHT) + uDrawStyles |= DT_RIGHT; + else + if(uDrawStyles == 0) + uDrawStyles = DT_CENTER|DT_VCENTER | DT_SINGLELINE; + } + + for(int i=0; iDrawText(line, line.GetLength(), textrc, uDrawStyles); + } + + pDC->SetTextColor(oldColour); +} + +void CColorButton::SetColor(COLORREF text, COLORREF bkgnd) +{ + m_TextColor = text; + m_BkgndColor = bkgnd; + + if(m_hWnd != NULL) + Invalidate(); +} + +void CColorButton::SetColor(COLORREF text, COLORREF bkgnd, COLORREF disabled) +{ + m_TextColor = text; + m_BkgndColor = bkgnd; + m_DisabledBkgndColor = disabled; + + if(m_hWnd != NULL) + Invalidate(); +} + +void CColorButton::SetColor(COLORREF text, COLORREF bkgnd, COLORREF disabled, COLORREF light, COLORREF highlight, COLORREF shadow, COLORREF darkShadow) +{ + m_TextColor = text; + m_BkgndColor = bkgnd; + m_DisabledBkgndColor = disabled; + m_Light = light; + m_Highlight = highlight; + m_Shadow = shadow; + m_DarkShadow = darkShadow; + + if(m_hWnd != NULL) + Invalidate(); +} + +void CColorButton::SetColorToWindowsDefault() +{ + m_TextColor = GetSysColor(COLOR_BTNTEXT); + m_BkgndColor = GetSysColor(COLOR_BTNFACE); + m_DisabledBkgndColor = GetSysColor(COLOR_BTNFACE); + m_Light = GetSysColor(COLOR_3DLIGHT); + m_Highlight = GetSysColor(COLOR_BTNHIGHLIGHT); + m_Shadow = GetSysColor(COLOR_BTNSHADOW); + m_DarkShadow = GetSysColor(COLOR_3DDKSHADOW); +} + +int CColorButton::OnCreate(LPCREATESTRUCT lpCreateStruct) +{ + lpCreateStruct->dwExStyle |= BS_OWNERDRAW; + + if (CButton::OnCreate(lpCreateStruct) == -1) + return -1; + + return 0; +} diff --git a/ColorButton.h b/ColorButton.h new file mode 100644 index 0000000..bf23a26 --- /dev/null +++ b/ColorButton.h @@ -0,0 +1,101 @@ +// Written by Marius Bancila (mbancila@yahoo.com) +// Copyright (c) 2004. +// +// This code may be used in compiled form in any way you desire. This +// file may be redistributed unmodified by any means PROVIDING it is +// not sold for profit without the authors written consent, and +// providing that this notice and the authors name is included. If +// the source code in this file is used in any commercial application +// then acknowledgement must be made to the author of this file +// (in whatever form you wish). +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// +// Please use and enjoy. Please let me know of any bugs/mods/improvements +// that you have found/implemented and I will fix/incorporate them into this +// file. + + +#if !defined(AFX_COLORBUTTON_H__EB5FACDB_272F_4883_A997_659DDA42FD38__INCLUDED_) +#define AFX_COLORBUTTON_H__EB5FACDB_272F_4883_A997_659DDA42FD38__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 +// ColorButton.h : header file +// + +///////////////////////////////////////////////////////////////////////////// +// CColorButton window + +class CColorButton : public CButton +{ +private: + enum { BUTTON_IN = 0x01, + BUTTON_OUT = 0x02, + BUTTON_BLACK_BORDER = 0x04,}; + +// Construction +public: + CColorButton(); + CColorButton(COLORREF text, COLORREF bkgnd); + CColorButton(COLORREF text, COLORREF bkgnd, COLORREF disabled); + CColorButton(COLORREF text, COLORREF bkgnd, COLORREF disabled, COLORREF light, COLORREF highlight, COLORREF shadow, COLORREF darkShadow); + +// Attributes +public: + +private: + COLORREF m_TextColor; + COLORREF m_BkgndColor; + COLORREF m_DisabledBkgndColor; + COLORREF m_Light; + COLORREF m_Highlight; + COLORREF m_Shadow; + COLORREF m_DarkShadow; + +// Operations +public: + void SetColor(COLORREF text, COLORREF bkgnd); + void SetColor(COLORREF text, COLORREF bkgnd, COLORREF disabled); + void SetColor(COLORREF text, COLORREF bkgnd, COLORREF disabled, COLORREF light, COLORREF highlight, COLORREF shadow, COLORREF darkShadow); + void SetColorToWindowsDefault(); + +private: + void DrawFrame(CDC *pDC, CRect rc, int state); + void DrawFilledRect(CDC *pDC, CRect rc, COLORREF color); + void DrawLine(CDC *pDC, long sx, long sy, long ex, long ey, COLORREF color); + void DrawButtonText(CDC *pDC, CRect rc, CString strCaption, COLORREF textcolor); + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CColorButton) + public: + virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct); + //}}AFX_VIRTUAL + +// Implementation +public: + virtual ~CColorButton(); + + // Generated message map functions +protected: + //{{AFX_MSG(CColorButton) + afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); + //}}AFX_MSG + + DECLARE_MESSAGE_MAP() +}; + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_COLORBUTTON_H__EB5FACDB_272F_4883_A997_659DDA42FD38__INCLUDED_) diff --git a/LogEdit.cpp b/LogEdit.cpp new file mode 100644 index 0000000..666867c --- /dev/null +++ b/LogEdit.cpp @@ -0,0 +1,214 @@ +// LogEdit.cpp : implementation file +// + +#include "stdafx.h" +#include "LogEdit.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif +/************************************************************************* + FILE : LogEdit.cpp Version 1.0 + + Author : Ranojay Sen (sen_ranojay@email.com) + + Description: CLogEdit is a CEdit derived class and runs on MS-Windows + + CLogEdit class can be used very easily for the + purpose of logging data by any application or any + Hardware. The automatic scrolling and updating the + Cursor position to the end of the line are the main + features of this class. this code can be modified by + profesional programmers to serve their specific needs + + +Copyright(c) 2008 +by Ranojay Sen (sen_ranojay@email.com) + +This code may be used in compiled form in any way you desire. This +file may be redistributed unmodified by any means PROVIDING it is +not sold for profit without the authors written consent, and +providing that this notice and the authors name is included. If +the source code in this file is used in any commercial application +then a simple email to the author would be nice. + +This file is provided "as is" with no expressed or implied warranty. +The author accepts no liability if it causes any damage. + +*************************************************************************/ + +///////////////////////////////////////////////////////////////////////////// +// CLogEdit + +CLogEdit::CLogEdit() +{ + m_maxLineCount = 1000; + flag=1; + PromptStr="Prompt::"; +} + +CLogEdit::~CLogEdit() +{ +} + + +BEGIN_MESSAGE_MAP(CLogEdit, CEdit) + //{{AFX_MSG_MAP(CLogEdit) + ON_WM_SETFOCUS() + ON_WM_CHAR() + ON_WM_LBUTTONDBLCLK() + ON_WM_LBUTTONDOWN() + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CLogEdit message handlers + +int CLogEdit::Trace(TCHAR *szString, ...) +{ + va_list args; + va_start(args, szString); + + int nrs = _Trace(szString, args); + + va_end(args); + return nrs; +} + +int CLogEdit::_Trace(TCHAR *szFormat, va_list args) +{ + int nrs; + DWORD dwWrite=0; + SYSTEMTIME sysTime={0}; + TCHAR szHead[1024*10] = {0,}; + TCHAR szBuffer[1024*10] = {0,}; + + GetLocalTime(&sysTime); + + nrs = _vsntprintf(szBuffer, sizeof szBuffer, szFormat, args); + + if(szBuffer[nrs-1] == 0x0D || szBuffer[nrs-1] == 0x0A) + { + szBuffer[nrs-1] = 0x0D; + szBuffer[nrs] = 0x0A; + szBuffer[++nrs] = 0; + } + + dwWrite = wsprintf(szHead, TEXT("[%d-%02d-%02d %02d:%02d:%02d] %s"), sysTime.wYear, sysTime.wMonth, sysTime.wDay + , sysTime.wHour, sysTime.wMinute, sysTime.wSecond, szBuffer); + + InsertLines(szHead, FALSE); + + return nrs; +} + +void CLogEdit::RemoveTopLine(CString& message) +{ + INT32 pos = message.Find(L"\r\n", 0); + if(pos >= 0) { + message = message.Right(message.GetLength() - (pos + 2)); + } +} + +int CLogEdit::GetLineCountProxy(CString message) +{ + INT32 iStart = 0; + INT32 pos; + INT32 count = 0; + + do { + pos = message.Find(L"\r\n", iStart); + count++; + if(pos >= 0) + iStart = pos + 1; + } while(pos >= 0); + + //TRACE("LINE COUNT : %d\n", count); + + return count; +} + +void CLogEdit::InsertLines(CString Line,BOOL st) +{ + CString wndtext; + //GetWindowText ( wndtext ); + wndtext = m_strLogs; + int text_length = wndtext.GetLength() ; + if( text_length <=1) + { + if(!st) + wndtext = wndtext + Line ; + else + wndtext = wndtext + PromptStr + Line ; + } + else + { + if(!st) + wndtext = wndtext +"\r\n"+ Line ; + else + wndtext = wndtext + "\r\n"+PromptStr + Line ; + } + + int cnt = GetLineCountProxy(wndtext); + if(cnt > m_maxLineCount) + RemoveTopLine(wndtext); + m_strLogs = wndtext; + CWnd *pParent = AfxGetMainWnd(); + if(pParent) + pParent->PostMessage(WM_TBD_UPDATE_LOG, 0, 0); +// SetWindowText ( wndtext ); + +// LineScroll ( GetLineCount(), 0x0 ); +// UpdateCaretPos(); + +} + +void CLogEdit::UpdateLogsToEdit() +{ + SetWindowText(m_strLogs); + LineScroll (GetLineCount(), 0x0); +} + +void CLogEdit::UpdateCaretPos() +{ + for ( int i = 0 ; i < GetLineCount() ; i++ ) + SendMessage( WM_KEYDOWN, VK_DOWN , 0x0 ) ; + for ( int i = 0 ; i < LineLength( GetLineCount() - 1 ) ; i++ ) + SendMessage( WM_KEYDOWN, VK_RIGHT , 0x0 ) ; +} + + + +void CLogEdit::OnSetFocus(CWnd* pOldWnd) +{ + CEdit::OnSetFocus(pOldWnd); + + if(flag==1) + { + flag = 0; + //InsertLines("Log Edit Demo Version 1.0 Feb-2008",FALSE); + } + UpdateCaretPos(); +} + + +void CLogEdit::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) +{ + UpdateCaretPos(); + return; +// CEdit::OnChar(nChar, nRepCnt, nFlags); +} + + +void CLogEdit::OnLButtonDblClk(UINT nFlags, CPoint point) +{ + UpdateCaretPos(); +} + +void CLogEdit::OnLButtonDown(UINT nFlags, CPoint point) +{ + UpdateCaretPos(); + +} diff --git a/LogEdit.h b/LogEdit.h new file mode 100644 index 0000000..b7fa211 --- /dev/null +++ b/LogEdit.h @@ -0,0 +1,91 @@ +#if !defined(AFX_LOGEDIT_H__D1EA82CD_C372_4935_9467_E6FD80C35892__INCLUDED_) +#define AFX_LOGEDIT_H__D1EA82CD_C372_4935_9467_E6FD80C35892__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 +// LogEdit.h : header file +// +/************************************************************************* + FILE : LogEdit.h Version 1.0 + + Author : Ranojay Sen (sen_ranojay@email.com) + + Description: CLogEdit is a CEdit derived class and runs on MS-Windows + + CLogEdit class can be used very easily for the + purpose of logging data by any application or any + Hardware. The automatic scrolling and updating the + Cursor position to the end of the line are the main + features of this class. this code can be modified by + profesional programmers to serve their specific needs + + +Copyright(c) 2008 +by Ranojay Sen (sen_ranojay@email.com) + +This code may be used in compiled form in any way you desire. This +file may be redistributed unmodified by any means PROVIDING it is +not sold for profit without the authors written consent, and +providing that this notice and the authors name is included. If +the source code in this file is used in any commercial application +then a simple email to the author would be nice. + +This file is provided "as is" with no expressed or implied warranty. +The author accepts no liability if it causes any damage. + +*************************************************************************/ + +///////////////////////////////////////////////////////////////////////////// +// CLogEdit window + +class CLogEdit : public CEdit +{ +// Construction +public: + CLogEdit(); + +// Attributes +public: +int flag; +CFont F; +CString PromptStr; +CString m_strLogs; +int m_maxLineCount; +// Operations +public: +void InsertLines(CString Line, BOOL st); +void UpdateCaretPos(); +void UpdateLogsToEdit(); +int Trace(TCHAR *szString, ...); +inline int _Trace(TCHAR *szFormat, va_list args); +void RemoveTopLine(CString& message); +int GetLineCountProxy(CString message); + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CLogEdit) + //}}AFX_VIRTUAL + +// Implementation +public: + virtual ~CLogEdit(); + + // Generated message map functions +protected: + //{{AFX_MSG(CLogEdit) + afx_msg void OnSetFocus(CWnd* pOldWnd); + afx_msg void OnChar(UINT nChar, UINT nRepCnt, UINT nFlags); + afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point); + afx_msg void OnLButtonDown(UINT nFlags, CPoint point); + //}}AFX_MSG + + DECLARE_MESSAGE_MAP() +}; + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_LOGEDIT_H__D1EA82CD_C372_4935_9467_E6FD80C35892__INCLUDED_) diff --git a/OnCastDlg.cpp b/OnCastDlg.cpp new file mode 100644 index 0000000..992620d --- /dev/null +++ b/OnCastDlg.cpp @@ -0,0 +1,83 @@ +// OnCastDlg.cpp : implementation file +// + +#include "stdafx.h" +#include "TouchBoard.h" +#include "OnCastDlg.h" +#include "afxdialogex.h" +#include "TouchBoardDlg.h" + +extern CTouchBoardDlg *g_pMainDlg; +// COnCastDlg dialog + +IMPLEMENT_DYNAMIC(COnCastDlg, CDialogEx) + +COnCastDlg::COnCastDlg(CWnd* pParent /*=NULL*/) + : CDialogEx(COnCastDlg::IDD, pParent) +{ + + EnableAutomation(); + +} + +COnCastDlg::~COnCastDlg() +{ +} + +void COnCastDlg::OnFinalRelease() +{ + // When the last reference for an automation object is released + // OnFinalRelease is called. The base class will automatically + // deletes the object. Add additional cleanup required for your + // object before calling the base class. + + CDialogEx::OnFinalRelease(); +} + +void COnCastDlg::DoDataExchange(CDataExchange* pDX) +{ + CDialogEx::DoDataExchange(pDX); +} + + +BEGIN_MESSAGE_MAP(COnCastDlg, CDialogEx) + ON_WM_PAINT() +END_MESSAGE_MAP() + +BEGIN_DISPATCH_MAP(COnCastDlg, CDialogEx) +END_DISPATCH_MAP() + +// Note: we add support for IID_IOnCastDlg to support typesafe binding +// from VBA. This IID must match the GUID that is attached to the +// dispinterface in the .IDL file. + +// {3BFB7ADB-C3C9-4EDB-8DEE-BB352084EDB3} +static const IID IID_IOnCastDlg = +{ 0x3BFB7ADB, 0xC3C9, 0x4EDB, { 0x8D, 0xEE, 0xBB, 0x35, 0x20, 0x84, 0xED, 0xB3 } }; + +BEGIN_INTERFACE_MAP(COnCastDlg, CDialogEx) + INTERFACE_PART(COnCastDlg, IID_IOnCastDlg, Dispatch) +END_INTERFACE_MAP() + + +// COnCastDlg message handlers + + +void COnCastDlg::OnPaint() +{ + CPaintDC dc(this); // device context for painting + // TODO: Add your message handler code here + // Do not call CDialogEx::OnPaint() for painting messages + + CFont *pOldFont; + dc.SetBkMode( TRANSPARENT ); + pOldFont = dc.SelectObject(&g_pMainDlg->m_topFont); + RECT txtPos; + GetClientRect(&txtPos); + txtPos.top = 70; + txtPos.bottom = 200; + if(m_strMessage.GetLength() > 0) + dc.DrawText(m_strMessage, -1, &txtPos, DT_CENTER); + + dc.SelectObject(pOldFont); +} diff --git a/OnCastDlg.h b/OnCastDlg.h new file mode 100644 index 0000000..959ab7b --- /dev/null +++ b/OnCastDlg.h @@ -0,0 +1,29 @@ +#pragma once + + +// COnCastDlg dialog + +class COnCastDlg : public CDialogEx +{ + DECLARE_DYNAMIC(COnCastDlg) + +public: + CString m_strMessage; + + COnCastDlg(CWnd* pParent = NULL); // standard constructor + virtual ~COnCastDlg(); + + virtual void OnFinalRelease(); + +// Dialog Data + enum { IDD = IDD_ONCAST_DIALOG }; + +protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + + DECLARE_MESSAGE_MAP() + DECLARE_DISPATCH_MAP() + DECLARE_INTERFACE_MAP() +public: + afx_msg void OnPaint(); +}; diff --git a/ReadMe.txt b/ReadMe.txt new file mode 100644 index 0000000..a77fb10 --- /dev/null +++ b/ReadMe.txt @@ -0,0 +1,71 @@ +================================================================================ + MFC 라이브러리 : TouchBoard 프로젝트 개요 +=============================================================================== + +응용 프로그램 마법사에서 이 TouchBoard 응용 프로그램을 만들었습니다. 이 응용 프로그램은 MFC의 기본 사용법을 보여 줄 뿐만 아니라 응용 프로그램을 작성하기 위한 기본 구조를 제공합니다. + +TouchBoard 응용 프로그램을 구성하는 각 파일에 대한 +요약 설명이 포함되어 있습니다. + +TouchBoard.vcxproj + 응용 프로그램 마법사를 사용하여 생성한 VC++ 프로젝트의 기본 프로젝트 파일입니다. 파일을 생성한 Visual C++ 버전에 대한 정보와 응용 프로그램 마법사를 사용하여 선택한 플랫폼, 구성 및 프로젝트 기능에 대한 정보가 포함되어 있습니다. + +TouchBoard.vcxproj.filters + 응용 프로그램 마법사를 사용하여 생성된 VC++ 프로젝트의 필터 파일입니다. 이 파일에는 프로젝트의 파일과 필터 간의 연결 정보가 들어 있습니다. 이러한 연결은 특정 노드에서 유사한 확장명으로 그룹화된 파일을 표시하기 위해 IDE에서 사용됩니다. 예를 들어 ".cpp" 파일은 "소스 파일" 필터와 연결되어 있습니다. + +TouchBoard.h + 해당 응용 프로그램의 기본 헤더 파일입니다. + 여기에는 resource.h를 비롯한 다른 프로젝트별 헤더가 포함되어 있으며 CTouchBoardApp 응용 프로그램 클래스가 선언되어 있습니다. + +TouchBoard.cpp + 이는 응용 프로그램 클래스 CTouchBoardApp가 포함된 기본 응용 프로그램 소스 파일입니다. + +TouchBoard.rc + 프로그램에서 사용하는 모든 Microsoft Windows 리소스의 목록입니다. 여기에는 RES 하위 디렉터리에 저장된 아이콘, 비트맵 및 커서가 포함됩니다. 이 파일은 Microsoft Visual C++에서 직접 편집할 수 있습니다. 프로젝트 리소스는 1042에 있습니다. + +res\TouchBoard.ico + 아이콘 파일이며, 응용 프로그램의 아이콘으로 사용됩니다. 이 아이콘은 기본 리소스 파일인 TouchBoard.rc에 의해 포함됩니다. + +res\TouchBoard.rc2 + 이 파일에는 Microsoft Visual C++ 이외의 다른 도구에서 편집한 리소스가 포함되어 있습니다. 리소스 편집기로 편집할 수 없는 모든 리소스는 이 파일에 넣어야 합니다. + + +///////////////////////////////////////////////////////////////////////////// + +응용 프로그램 마법사에서 대화 상자 클래스 하나를 만듭니다. + +TouchBoardDlg.h, TouchBoardDlg.cpp - 대화 상자 + 이 파일에는 CTouchBoardDlg 클래스가 포함됩니다. 이 클래스는 응용 프로그램의 주 대화 상자에 대한 동작을 정의합니다. 이 대화 상자 템플릿은 TouchBoard.rc에 있으며, Microsoft Visual C++에서 직접 편집할 수 있습니다. + +///////////////////////////////////////////////////////////////////////////// + +기타 기능: + +ActiveX 컨트롤 + 응용 프로그램이 Active X 컨트롤을 지원합니다. + +Windows 소켓 + 응용 프로그램에서 TCP/IP 네트워크를 통한 통신을 구축할 수 있습니다. + +///////////////////////////////////////////////////////////////////////////// + +기타 표준 파일: + +StdAfx.h, StdAfx.cpp + 이 파일은 미리 컴파일된 헤더(PCH) 파일 TouchBoard.pch와 미리 컴파일된 형식(PCT) 파일 StdAfx.obj를 빌드하는 데 사용됩니다. + +Resource.h + 새 리소스 ID를 정의하는 표준 헤더 파일입니다. Microsoft Visual C++에서 이 파일을 읽고 업데이트합니다. + +TouchBoard.manifest + 응용 프로그램 매니페스트 파일은 Windows XP에서 특정 버전의 Side-by-Side 어셈블리에 대한 응용 프로그램 종속성을 설명하는 데 사용됩니다. 로더는 이 정보를 통해 어셈블리 캐시 또는 응용 프로그램의 private에서 적절한 어셈블리를 로드합니다. 응용 프로그램 매니페스트는 응용 프로그램 실행 파일과 같은 폴더에 설치된 외부 .manifest 파일 형태로서 재배포용으로 포함되거나, 리소스 형태로 된 실행 파일에 포함될 수 있습니다. +///////////////////////////////////////////////////////////////////////////// + +기타 참고: + +응용 프로그램 마법사에서 사용하는 "TODO:"는 사용자가 추가하거나 사용자 지정해야 하는 소스 코드 부분을 나타냅니다. + +공유된 DLL에서 MFC를 사용하는 응용 프로그램의 경우 MFC DLL을 재배포할 필요가 없습니다. 응용 프로그램에서 운영 체제의 로캘과 다른 언어를 사용하는 경우 이에 해당하는 지역화된 리소스인 mfc110XXX.DLL도 재배포해야 합니다. +이러한 두 항목에 대한 자세한 내용은 MSDN 설명서에 있는 Visual C++ 응용 프로그램 재배포 섹션을 참조하십시오. + +///////////////////////////////////////////////////////////////////////////// diff --git a/RoundButton2.cpp b/RoundButton2.cpp new file mode 100644 index 0000000..86653b2 --- /dev/null +++ b/RoundButton2.cpp @@ -0,0 +1,584 @@ +/******************************************************************** + created: 2005/06/03 + created: 3:6:2005 13:22 + filename: x:\Software\Mfc\Source\Controls\Buttons\RoundButton2.cpp + file path: x:\Software\Mfc\Source\Controls\Buttons + file base: RoundButton2 + file ext: cpp + author: Markus Zocholl + + purpose: CRoundButton2 defines a universal Button-Control with the + following features: + + * Shape is a rounded Rectangle + * Button includes Border and Button-Face + * Many parameters to get an individual look + * Functions of Button to be en- or disabled: + - Button (disabled means a static control with userdefined styles) + - Hover +*********************************************************************/ + +#include "StdAfx.h" +#include +#include ".\RoundButton2.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +/************************************************************************/ +/* Construction and Destruction */ +/************************************************************************/ + +//! Construction +CRoundButton2::CRoundButton2(void): + m_bDefaultButton(false) + , m_bIsCheckButton(false) + , m_bIsRadioButton(false) + , m_bIsHotButton(false) + , m_bMouseOnButton(false) + , m_bIsChecked(false) + , m_ptRoundButtonStyle(NULL) + , m_rBtnSize(CRect(0, 0, 0, 0)) + , m_bRedraw(false) + , m_sOldCaption(_T("")) + { + // Set Standards in Font-Style + m_tLogFont.lfHeight = 16; + m_tLogFont.lfWidth = 0; + m_tLogFont.lfEscapement = 0; + m_tLogFont.lfOrientation = 0; + m_tLogFont.lfWeight = FW_BOLD; + m_tLogFont.lfItalic = false; + m_tLogFont.lfUnderline = false; + m_tLogFont.lfStrikeOut = false; + m_tLogFont.lfCharSet = DEFAULT_CHARSET; + m_tLogFont.lfOutPrecision = OUT_DEFAULT_PRECIS; + m_tLogFont.lfClipPrecision = CLIP_DEFAULT_PRECIS; + m_tLogFont.lfQuality = ANTIALIASED_QUALITY; + m_tLogFont.lfPitchAndFamily = DEFAULT_PITCH; + //strcpy(m_tLogFont.lfFaceName, "Tahoma"); + lstrcpy(m_tLogFont.lfFaceName, _T("Tahoma")); + + m_tBtnFont.CreateFontIndirect(&m_tLogFont); + + // Set Standard Font-Color + m_tTextColor.m_tDisabled = RGB(64, 64, 64); + m_tTextColor.m_tEnabled = RGB( 0, 0, 0); + m_tTextColor.m_tClicked = RGB( 0, 0, 0); + m_tTextColor.m_tPressed = RGB( 0, 0, 0); + m_tTextColor.m_tHot = RGB( 0, 0, 0); +} + +//! Destruction +CRoundButton2::~CRoundButton2(void) +{ +} + +/************************************************************************/ +/* public Functions */ +/************************************************************************/ + +// Set Style of Button +bool CRoundButton2::SetRoundButtonStyle(CRoundButtonStyle* _ptRoundButtonStyle) +{ + // Check, if Button-Style is given + if (_ptRoundButtonStyle == NULL) + return false; + + // Set Pointer to ButtonStyle + m_ptRoundButtonStyle = _ptRoundButtonStyle; + + // Redraw Button + m_bRedraw = true; + + // All Done + return false; +} + +bool CRoundButton2::SetFont(CFont* _ptCFont) +{ + if (_ptCFont == NULL) + return false; + + LOGFONT logFont; + _ptCFont->GetLogFont(&logFont); + return SetFont(&logFont); +} + +// Set Font of Button +bool CRoundButton2::SetFont(LOGFONT* _ptLogFont) +{ + if (_ptLogFont == NULL) + return false; + + // Delete Font, if already given + if (m_tBtnFont.m_hObject != NULL) + m_tBtnFont.DeleteObject(); + + // Store Infos local + memcpy(&m_tLogFont, _ptLogFont, sizeof(LOGFONT)); + + // Create new Font + m_tBtnFont.CreateFontIndirect(&m_tLogFont); + + // Button should be redrawn + m_bRedraw = true; + + return true; +} + +// Set Font of Button +bool CRoundButton2::GetFont(LOGFONT* _ptLogFont) +{ + if (_ptLogFont == NULL) + return false; + + // Store Infos local + memcpy(_ptLogFont, &m_tLogFont, sizeof(LOGFONT)); + + return true; +} + +//! Set Color of Caption +bool CRoundButton2::SetTextColor(tColorScheme* _ptTextColor) +{ + if (_ptTextColor == NULL) + return false; + + // Store Infos locally + memcpy(&m_tTextColor, _ptTextColor, sizeof(tColorScheme)); + + // Button should be redrawn + m_bRedraw = true; + + return true; +} + +//! Get Color of Caption +bool CRoundButton2::GetTextColor(tColorScheme* _ptTextColor) +{ + if (_ptTextColor == NULL) + return false; + + // Store Infos locally + memcpy(_ptTextColor, &m_tTextColor, sizeof(tColorScheme)); + + return true; +} + +/************************************************************************/ +/* Own Drawing-Functions */ +/************************************************************************/ + +//! Generate Bitmaps to hold Buttons +void CRoundButton2::GenButtonBMPs(CDC* _pDC, CRect _rRect) +{ + if (m_tBmpBtn.m_hObject != NULL) + m_tBmpBtn.DeleteObject(); + m_tBmpBtn.m_hObject = NULL; + // Generate Bitmap + if (m_tBmpBtn.CreateCompatibleBitmap(_pDC, _rRect.Width(), _rRect.Height() * BS_LAST_STATE) == FALSE) + { + m_rBtnSize = CRect(0, 0, 0, 0); + } + else + { + m_rBtnSize = _rRect; + } +} + +//! Draw Button-Face +void CRoundButton2::DrawButtonFace(CDC* _pDC) +{ + // We need an attached style + if (m_ptRoundButtonStyle == NULL) + return; + + // Get Pointer to Bitmap of Masks + CBitmap* pButtonMasks = m_ptRoundButtonStyle->GetButtonEdge(_pDC); + + // Create Memory-DC + CDC SourceDC; + SourceDC.CreateCompatibleDC(_pDC); + + // Select Working Objects into DCs + HGDIOBJ hOldBmp1 = SourceDC.SelectObject(pButtonMasks); + + int nState; + + CSize tEdgeSize = m_ptRoundButtonStyle->GetEdgeSize(); + CSize tCorrectedEdgeSize; + CSize tMaskSize = m_ptRoundButtonStyle->GetMaskSize(); + + // Correct Edge-Size for smaller Buttons + tCorrectedEdgeSize.cx = __min(tEdgeSize.cx, __min(m_rBtnSize.Width() / 2, m_rBtnSize.Height() / 2)); + tCorrectedEdgeSize.cy = tCorrectedEdgeSize.cx; + + for (nState = 0; nState < BS_LAST_STATE; nState++) + { + /************************************************************************/ + /* Draw Edges */ + /************************************************************************/ + // Left-Top + _pDC->StretchBlt( + 0, + nState * m_rBtnSize.Height(), + tCorrectedEdgeSize.cx, + tCorrectedEdgeSize.cy, + &SourceDC, + 0, + nState * tMaskSize.cy, + tEdgeSize.cx, + tEdgeSize.cy, + SRCCOPY); + // Left-Bottom + _pDC->StretchBlt( + 0, + nState * m_rBtnSize.Height() + m_rBtnSize.Height() - tCorrectedEdgeSize.cy, + tCorrectedEdgeSize.cx, + tCorrectedEdgeSize.cy, + &SourceDC, + 0, + nState * tMaskSize.cy + tMaskSize.cy - tEdgeSize.cy, + tEdgeSize.cx, + tEdgeSize.cy, + SRCCOPY); + // Right-Top + _pDC->StretchBlt( + m_rBtnSize.Width() - tCorrectedEdgeSize.cx, + nState * m_rBtnSize.Height(), + tCorrectedEdgeSize.cx, + tCorrectedEdgeSize.cy, + &SourceDC, + tMaskSize.cx - tEdgeSize.cx, + nState * tMaskSize.cy, + tEdgeSize.cx, + tEdgeSize.cy, + SRCCOPY); + // Right-Bottom + _pDC->StretchBlt( + m_rBtnSize.Width() - tCorrectedEdgeSize.cx, + nState * m_rBtnSize.Height() + m_rBtnSize.Height() - tCorrectedEdgeSize.cy, + tCorrectedEdgeSize.cx, + tCorrectedEdgeSize.cy, + &SourceDC, + tMaskSize.cx - tEdgeSize.cx, + nState * tMaskSize.cy + tMaskSize.cy - tEdgeSize.cy, + tEdgeSize.cx, + tEdgeSize.cy, + SRCCOPY); + /************************************************************************/ + /* Draw Sides */ + /************************************************************************/ + // Top + _pDC->StretchBlt( + tCorrectedEdgeSize.cx, + nState * m_rBtnSize.Height(), + m_rBtnSize.Width() - 2 * tCorrectedEdgeSize.cx, + tCorrectedEdgeSize.cy, + &SourceDC, + tEdgeSize.cx, + nState * tMaskSize.cy, + 1, + tEdgeSize.cy, + SRCCOPY); + // Bottom + _pDC->StretchBlt( + tCorrectedEdgeSize.cx, + nState * m_rBtnSize.Height() + m_rBtnSize.Height() - tCorrectedEdgeSize.cy, + m_rBtnSize.Width() - 2 * tCorrectedEdgeSize.cx, + tCorrectedEdgeSize.cy, + &SourceDC, + tEdgeSize.cx, + nState * tMaskSize.cy + tMaskSize.cy - tEdgeSize.cy, + 1, + tEdgeSize.cy, + SRCCOPY); + // Left + _pDC->StretchBlt( + 0, + nState * m_rBtnSize.Height() + tCorrectedEdgeSize.cy, + tCorrectedEdgeSize.cx, + m_rBtnSize.Height() - 2 * tCorrectedEdgeSize.cy, + &SourceDC, + 0, + nState * tMaskSize.cy + tEdgeSize.cy, + tEdgeSize.cx, + 1, + SRCCOPY); + // Right + _pDC->StretchBlt( + m_rBtnSize.Width() - tCorrectedEdgeSize.cx, + nState * m_rBtnSize.Height() + tCorrectedEdgeSize.cy, + tCorrectedEdgeSize.cx, + m_rBtnSize.Height() - 2 * tCorrectedEdgeSize.cy, + &SourceDC, + tMaskSize.cx - tEdgeSize.cx, + nState * tMaskSize.cy + tEdgeSize.cy, + tEdgeSize.cx, + 1, + SRCCOPY); + /************************************************************************/ + /* Filling */ + /************************************************************************/ + _pDC->StretchBlt( + tCorrectedEdgeSize.cx, + nState * m_rBtnSize.Height() + tCorrectedEdgeSize.cy, + m_rBtnSize.Width() - 2* tCorrectedEdgeSize.cx, + m_rBtnSize.Height() - 2 * tCorrectedEdgeSize.cy, + &SourceDC, + tEdgeSize.cx, + nState * tMaskSize.cy + tEdgeSize.cy, + 1, + 1, + SRCCOPY); + } + + // Select Old Objects into DCs + SourceDC.SelectObject(hOldBmp1); +} + +//! Draw Caption on Button +void CRoundButton2::DrawButtonCaption(CDC *_pDC) +{ + // Select Transparency for Background + int nOldBckMode = _pDC->SetBkMode(TRANSPARENT); + + // Get old Text-Color + COLORREF tOldColor = _pDC->SetTextColor(RGB(0,0,0)); + + // Select Font into DC + HGDIOBJ hOldFont = _pDC->SelectObject(&m_tBtnFont); + + // Get Caption of Button + CString sCaption; + this->GetWindowText(sCaption); + + for (int nState = 0; nState < BS_LAST_STATE; nState++) + { + switch(nState) + { + case BS_ENABLED: + _pDC->SetTextColor(m_tTextColor.m_tEnabled); + break; + case BS_CLICKED: + _pDC->SetTextColor(m_tTextColor.m_tClicked); + break; + case BS_PRESSED: + _pDC->SetTextColor(m_tTextColor.m_tPressed); + break; + case BS_HOT: + _pDC->SetTextColor(m_tTextColor.m_tHot); + break; + case BS_DISABLED: + default: + _pDC->SetTextColor(m_tTextColor.m_tDisabled); + break; + } + + _pDC->DrawText( + sCaption, + CRect( + m_rBtnSize.left, + nState * m_rBtnSize.Height() + m_rBtnSize.top, + m_rBtnSize.right, + nState * m_rBtnSize.Height() + m_rBtnSize.bottom), + DT_CENTER | DT_VCENTER | DT_SINGLELINE); + } + + // Select Old Font back + _pDC->SelectObject(hOldFont); + + // Set old Background-Mode + _pDC->SetBkMode(nOldBckMode); + + // Set old Text-Color + _pDC->SetTextColor(tOldColor); +} + +/************************************************************************/ +/* Overwritten Functions for Init and Draw of Button */ +/************************************************************************/ + +//! Presubclass-Window-Function +void CRoundButton2::PreSubclassWindow() +{ +#ifdef _DEBUG + // We really should be only sub classing a button control + TCHAR buffer[255]; + GetClassName (m_hWnd, buffer, sizeof(buffer) / sizeof(TCHAR)); + ASSERT (CString (buffer) == _T("Button")); +#endif + + // Check if it's a default button + if (GetStyle() & 0x0FL) + m_bDefaultButton = true; + + // Make the button owner-drawn + ModifyStyle (0x0FL, BS_OWNERDRAW | BS_AUTOCHECKBOX, SWP_FRAMECHANGED); + + CButton::PreSubclassWindow(); +} + +//! Draw-Item-Function +/*! This Function is called each time, the Button needs a redraw +*/ +void CRoundButton2::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) +{ + // Get DC of Item + CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC); + ASSERT (pDC != NULL); + + // Should Buttons be generated? + bool bGenerate = !m_rBtnSize.EqualRect(&lpDrawItemStruct->rcItem) || m_bRedraw; + + // If Rectangles of Button are not the same + if (bGenerate) + { + // Generate Bitmap to hold Buttons + GenButtonBMPs(pDC, lpDrawItemStruct->rcItem); + + // Redraw done + m_bRedraw = false; + } + + // Generate DC to draw in Memory + CDC MemDC; + MemDC.CreateCompatibleDC(pDC); + + HGDIOBJ hOldBmp = MemDC.SelectObject(m_tBmpBtn); + + CString sActualCaption; + // Get actual caption + GetWindowText(sActualCaption); + + // Check, if caption has changed + if (sActualCaption != m_sOldCaption) + bGenerate = true; + + // Store old caption + m_sOldCaption = sActualCaption; + + // If Rectangles of Button are not the same + if (bGenerate) + { + // Draw Buttons + DrawButtonFace(&MemDC); + + // Draw Button-Caption + DrawButtonCaption(&MemDC); + } + + int nButtonState; + + nButtonState = BS_ENABLED; + + if (m_bIsHotButton && m_bMouseOnButton) + nButtonState = BS_HOT; + + if ((lpDrawItemStruct->itemState & ODS_DISABLED) == ODS_DISABLED) + nButtonState = BS_DISABLED; + else + { + if ((lpDrawItemStruct->itemState & ODS_SELECTED) == ODS_SELECTED) + nButtonState = BS_PRESSED; + else + { + if (this->m_bIsChecked) + { + nButtonState = BS_CLICKED; + } + } + } + + // Copy correct Bitmap to Screen + pDC->BitBlt( + lpDrawItemStruct->rcItem.left, + lpDrawItemStruct->rcItem.top, + m_rBtnSize.Width(), + m_rBtnSize.Height(), + &MemDC, + 0, + m_rBtnSize.Height() * nButtonState, + SRCCOPY); + + MemDC.SelectObject(hOldBmp); +} + + +BEGIN_MESSAGE_MAP(CRoundButton2, CButton) +ON_WM_LBUTTONUP() +ON_WM_MOUSEMOVE() +ON_WM_CAPTURECHANGED() +END_MESSAGE_MAP() + +void CRoundButton2::OnLButtonUp(UINT nFlags, CPoint point) +{ + if (m_bIsCheckButton) + { + m_bIsChecked = !m_bIsChecked; + } + if (m_bIsRadioButton) + { + m_bIsChecked = true; + } + + CButton::OnLButtonUp(nFlags, point); +} + +void CRoundButton2::OnMouseMove(UINT nFlags, CPoint point) +{ + CRect rcClient; + + // Get Rectangle of Client + GetClientRect(rcClient); + + // Check, if Mouse is on Control + if (rcClient.PtInRect(point)) + { + // We only need to redraw, if the mouse enters + bool bRedrawNeeded = !m_bMouseOnButton; + + // Mouse is on Control + m_bMouseOnButton = true; + + // Set Capture to recognize, when the mouse leaves the control + SetCapture(); + + // Redraw Control, if Button is hot + if (m_bIsHotButton) + Invalidate(); + } + else + { + // We have lost the mouse-capture, so the mouse has left the buttons face + m_bMouseOnButton = false; + + // Mouse has left the button + ReleaseCapture(); + + // Redraw Control, if Button is hot + if (m_bIsHotButton) + Invalidate(); + } + + CButton::OnMouseMove(nFlags, point); +} +void CRoundButton2::OnCaptureChanged(CWnd *pWnd) +{ + // Check, if we lost the mouse-capture + if (GetCapture() != this) + { + // We have lost the mouse-capture, so the mouse has left the buttons face + m_bMouseOnButton = false; + + // Redraw Control, if Button is hot + if (m_bIsHotButton) + Invalidate(); + } + + CButton::OnCaptureChanged(pWnd); +} diff --git a/RoundButton2.h b/RoundButton2.h new file mode 100644 index 0000000..ff967d5 --- /dev/null +++ b/RoundButton2.h @@ -0,0 +1,139 @@ +/******************************************************************** + created: 2005/06/03 + created: 3:6:2005 13:21 + filename: x:\Software\Mfc\Source\Controls\Buttons\RoundButton2.h + file path: x:\Software\Mfc\Source\Controls\Buttons + file base: RoundButton2 + file ext: h + author: Markus Zocholl + + purpose: CRoundButton2 defines a universal Button-Control with the + following features: + + * Shape is a rounded Rectangle + * Button includes Border and Button-Face + * Many parameters to get an individual look + * Functions of Button to be en- or disabled: + - Button (disabled means a static control with userdefined styles) + - Hover +*********************************************************************/ + +#pragma once +#include "afxwin.h" +#include "RoundButtonStyle.h" + +class CRoundButton2 : + public CButton +{ +public: + /************************************************************************/ + /* Con- / Destruction */ + /************************************************************************/ + //! Constructor + CRoundButton2(void); + //! Destructor + ~CRoundButton2(void); + + /************************************************************************/ + /* Functions for Design of Button */ + /************************************************************************/ + //! Set Style of Button + bool SetRoundButtonStyle(CRoundButtonStyle* _ptRoundButtonStyle); + //! Get Font of Button + bool GetFont(LOGFONT* _ptLogFont); + //! Set Font of Button + bool SetFont(CFont* _ptCFont); + bool SetFont(LOGFONT* _ptLogFont); + //! Get Color of Caption + bool GetTextColor(tColorScheme* _ptTextColor); + //! Set Color of Caption + bool SetTextColor(tColorScheme* _ptTextColor); + + /************************************************************************/ + /* Access to Functions of Button */ + /************************************************************************/ + //! Button is Check button + void SetCheckButton(bool _bCheckButton) { m_bIsCheckButton = _bCheckButton; }; + //! Is Button a Check button + bool GetCheckButton() { return m_bIsCheckButton; }; + //! Button is Radio button + void SetRadioButton(bool _bRadioButton) { m_bIsRadioButton = _bRadioButton; }; + //! Is Button a Radio button + bool GetRadioButton() { return m_bIsRadioButton; }; + //! Button is Hot-button + void SetHotButton(bool _bHotButton) { m_bIsHotButton = _bHotButton; }; + //! Is Button a Hot-button + bool GetHotButton() { return m_bIsHotButton; }; + + //! Change Check-Status of Button + void SetCheck(bool _bIsChecked) { m_bIsChecked = _bIsChecked; Invalidate(); }; + //! Get Current Check-Status of Button + bool GetCheck() { return m_bIsChecked; }; + + /************************************************************************/ + /* Message-Map of Control */ + /************************************************************************/ + DECLARE_MESSAGE_MAP() + afx_msg void OnLButtonUp(UINT nFlags, CPoint point); + afx_msg void OnMouseMove(UINT nFlags, CPoint point); + +protected: + + /************************************************************************/ + /* Own Drawing-Functions */ + /************************************************************************/ + + //! Generate Bitmaps to hold Buttons + void GenButtonBMPs(CDC* _pDC, CRect _rRect); + //! Draw Button-Face + void DrawButtonFace(CDC* _pDC); + //! Draw Caption on Button + void DrawButtonCaption(CDC *_pDC); + + /************************************************************************/ + /* Overwritten Functions for Init and Draw of Button */ + /************************************************************************/ + + //! PreSubclass-Function + virtual void PreSubclassWindow(); + //! Draw Item-Function + virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct); + +private: + //! Size of Button-Images + CRect m_rBtnSize; + //! Image of Buttons + CBitmap m_tBmpBtn; + + //! Font for Caption + CFont m_tBtnFont; + //! Data-Block for Font + LOGFONT m_tLogFont; + //! Color Scheme of Caption + tColorScheme m_tTextColor; + + //! Stored Old Caption to recognize the need for a redraw + CString m_sOldCaption; + + //! Is Button Default-Button + bool m_bDefaultButton; + //! Is Check-Button + bool m_bIsCheckButton; + //! Is Radio-Button + bool m_bIsRadioButton; + //! Is Hot-Button + bool m_bIsHotButton; + //! Is Checked + bool m_bIsChecked; + + //! The Mouse is on the Button-Area, needed for Hot-Button + bool m_bMouseOnButton; + + //! Button should be redrawn + bool m_bRedraw; + + //! Structure containing Style of Button + CRoundButtonStyle* m_ptRoundButtonStyle; +public: + afx_msg void OnCaptureChanged(CWnd *pWnd); +}; \ No newline at end of file diff --git a/RoundButtonStyle.cpp b/RoundButtonStyle.cpp new file mode 100644 index 0000000..cd74832 --- /dev/null +++ b/RoundButtonStyle.cpp @@ -0,0 +1,352 @@ +/******************************************************************** + created: 2005/06/03 + created: 03:06:2005 11:27 + filename: x:\Software\Mfc\Source\Controls\Buttons\RoundButtonStyle.cpp + file path: x:\Software\Mfc\Source\Controls\Buttons + file base: RoundButtonStyle + file ext: cpp + author: Markus Zocholl + + purpose: CRoundButtonStyle manages the Style of CRoundButton, a + Button-Control with round Design. + Because the generation of the Button-Images is time consuming + this is only done once in the Style-Class, and all Buttons + associated with this class take the same Images. +*********************************************************************/ + +#include "StdAfx.h" +#include "math.h" +#include ".\roundbuttonstyle.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +/************************************************************************/ +/* Construction / Destruction */ +/************************************************************************/ + +//! Constructor +CRoundButtonStyle::CRoundButtonStyle(void) +: m_bButtonDrawn(false) +{ + // No Image => No Size + m_tBtnSize = CSize(0, 0); + + // Set Standard-AntiAliasing-Zone + m_tButtonStyle.m_dSizeAA = 2.0; + + // Set Standard-Position of HighLight + m_tButtonStyle.m_dHighLightX = 0.0; + m_tButtonStyle.m_dHighLightY = -7.0; + + // Set Radii of Edges + m_tButtonStyle.m_dRadius = 10.0; + m_tButtonStyle.m_dBorderRatio = 0.2; + // Modified by ritoseo + m_tButtonStyle.m_dRadius = 8.0; + m_tButtonStyle.m_dBorderRatio = 0.1; + + // Set Heights of Button + m_tButtonStyle.m_dHeightBorder = 0.5; + m_tButtonStyle.m_dHeightButton = 0.5; + // Modified by ritoseo + m_tButtonStyle.m_dHeightBorder = 0.1; + m_tButtonStyle.m_dHeightButton = 0.1; + + + // Set Data of Highlight + m_tButtonStyle.m_dRadiusHighLight = 7.0; + m_tButtonStyle.m_dPowerHighLight = 0.4; + + // Set Colors for different States + m_tButtonStyle.m_tColorBack.m_tDisabled = GetSysColor(COLOR_3DFACE); + m_tButtonStyle.m_tColorBorder.m_tDisabled = RGB(128, 128, 128); + m_tButtonStyle.m_tColorFace.m_tDisabled = RGB(128, 128, 128); + + m_tButtonStyle.m_tColorBack.m_tEnabled = GetSysColor(COLOR_3DFACE); + m_tButtonStyle.m_tColorBorder.m_tEnabled = RGB(164, 128, 128); + m_tButtonStyle.m_tColorFace.m_tEnabled = RGB(164, 164, 164); + // Modified by ritoseo + m_tButtonStyle.m_tColorBorder.m_tEnabled = RGB(164 + 10, 164 + 10, 164 + 10); + m_tButtonStyle.m_tColorFace.m_tEnabled = RGB(164 + 10, 164 + 10, 164 + 10); + + m_tButtonStyle.m_tColorBack.m_tClicked = GetSysColor(COLOR_3DFACE); + m_tButtonStyle.m_tColorBorder.m_tClicked = RGB(255, 255, 0); + m_tButtonStyle.m_tColorFace.m_tClicked = RGB(164, 164, 164); + + m_tButtonStyle.m_tColorBack.m_tPressed = GetSysColor(COLOR_3DFACE); + m_tButtonStyle.m_tColorBorder.m_tPressed = RGB(164, 128, 128); + m_tButtonStyle.m_tColorFace.m_tPressed = RGB( 64, 64, 64); + + m_tButtonStyle.m_tColorBack.m_tHot = GetSysColor(COLOR_3DFACE); + m_tButtonStyle.m_tColorBorder.m_tHot = RGB(164, 128, 128); + m_tButtonStyle.m_tColorFace.m_tHot = RGB(192, 192, 192); +} + +//! Destructor +CRoundButtonStyle::~CRoundButtonStyle(void) +{ +} + +/************************************************************************/ +/* Access to Button-Style */ +/************************************************************************/ + +// Get current set Button-Style +bool CRoundButtonStyle::GetButtonStyle(tButtonStyle* _ptButtonStyle) +{ + // Check, if Pointer to a Button-Style-Struct is given + if (_ptButtonStyle == NULL) + return false; + + // Copy Style to given Struct + memcpy(_ptButtonStyle, &m_tButtonStyle, sizeof(tButtonStyle)); + + // All done + return true; +} + +// Set Style of Button to new value +bool CRoundButtonStyle::SetButtonStyle(tButtonStyle* _ptButtonStyle) +{ + // Check, if new Button-Style is given + if (_ptButtonStyle == NULL) + return false; + + // Copy new Style to Construct + memcpy(&m_tButtonStyle, _ptButtonStyle, sizeof(tButtonStyle)); + + // Set Flag to redraw Buttons + m_bButtonDrawn = false; + + // All done + return true; +} + +/************************************************************************/ +/* Request for graphical objects */ +/************************************************************************/ + +// Get Pointer to Bitmap containing Edges of Button-Face +CBitmap* CRoundButtonStyle::GetButtonEdge(CDC* _pDC) +{ + // Check, if Button needs to be redrawn + if (!m_bButtonDrawn) + { + // Draw Masks of Button + DrawMasks(_pDC); + + m_bButtonDrawn = true; + } + + // Return Pointer to Bitmap + return &m_tBmpButtonEdge; +} + +/************************************************************************/ +/* Drawing-Routines */ +/************************************************************************/ + +// Draw all Masks of Button +bool CRoundButtonStyle::DrawMasks(CDC* _pDC) +{ + CDC MemDC; + + // Create DC in Memory + if (MemDC.CreateCompatibleDC(_pDC) == FALSE) + return false; + + /************************************************************************/ + /* Generate Variables */ + /************************************************************************/ + + // Distance from Center of Button + double fDistCenter = 0.0; + // Distance from Highlight-Center + double fDistHigh = 0.0; + // X-Position of Highlight + double fXHigh; + // Y-Position of Highlight + double fYHigh; + // Color-Factor of Background-Color + double fFacBack = 0.0; + // Color-Factor of Border-Color + double fFacBorder = 0.0; + // Color-Factor of Button-Face-Color + double fFacFace = 0.0; + // Color-Factor of Highlight-Color + double fFacHigh = 0.0; + // Color-Factor Red + double fFacR; + // Color-Factor Green + double fFacG; + // Color-Factor Blue + double fFacB; + // Color of actual Pixel + COLORREF tColPixel; + // Size of Anti-Aliasing-Region + double fSizeAA; + // Radius of Outer Rim (between Border and Nirvana) + double fRadOuter; + // Radius of Inner Rim (between Button-Face and Border) + double fRadInner; + // Ratio of Border + double fRatioBorder; + // Height of Border + double fHeightBorder; + // Height of Button-Face + double fHeightButton; + // Radius of Highlight + double fRadHigh; + // Power of Highlight + double fPowHigh; + // Size of single Edge + int nSizeEdge = 0; + + /************************************************************************/ + /* Load Infos of Style */ + /************************************************************************/ + + // Load Position of HighLight + fSizeAA = m_tButtonStyle.m_dSizeAA; + + fXHigh = m_tButtonStyle.m_dHighLightX; + fYHigh = m_tButtonStyle.m_dHighLightY; + + fRadOuter = m_tButtonStyle.m_dRadius; + fRatioBorder = m_tButtonStyle.m_dBorderRatio; + + fHeightBorder = m_tButtonStyle.m_dHeightBorder; + fHeightButton = m_tButtonStyle.m_dHeightButton; + + fRadHigh = m_tButtonStyle.m_dRadiusHighLight; + fPowHigh = m_tButtonStyle.m_dPowerHighLight; + + // Calculate Radius of Inner Border + fRadInner = __min(fRadOuter, __max(0.0f, fRadOuter * (1.0f - fRatioBorder))); + + // Calculate Size of an Edge + nSizeEdge = (int)ceil(fRadOuter + fSizeAA / 2.0); + + // Store Size of Mask in global var + m_tBtnSize.SetSize(nSizeEdge, nSizeEdge); + + // Delete old Bitmap, if present + if (m_tBmpButtonEdge.m_hObject != NULL) + m_tBmpButtonEdge.DeleteObject(); + + // Generate new Bitmap + m_tBmpButtonEdge.CreateCompatibleBitmap( + _pDC, + 2 * nSizeEdge + 1, + (2 * nSizeEdge + 1) * BS_LAST_STATE); + + // Select Bitmap of Button-Edge into DC + HGDIOBJ hOldBmp = MemDC.SelectObject(m_tBmpButtonEdge); + + // Draw Button-Edge + int nX; + int nY; + int nState; + + COLORREF tColorBack; + COLORREF tColorBorder; + COLORREF tColorFace; + + for (nX = -nSizeEdge; nX <= nSizeEdge; nX++) + { + for (nY = -nSizeEdge; nY <= nSizeEdge; nY++) + { + // Calculate Distance of Point from Center of Button + fDistCenter = sqrt((double)nX * (double)nX + (double)nY * (double)nY); + + // Calculate factor of Background + fFacBack = __max(0.0, __min(1.0, 0.5 + (fDistCenter - fRadOuter) * 2.0 / fSizeAA)); + + // Calculate Factor for Border + fFacBorder = 1.0 - fHeightBorder * pow((fRadOuter + fRadInner - fDistCenter * 2.0) / (fRadOuter - fRadInner) ,2); + fFacBorder = __max(0.0, __min(1.0, 0.5 - (fDistCenter - fRadOuter) * 2.0 / fSizeAA)) * fFacBorder; + fFacBorder = __max(0.0, __min(1.0, 0.5 + (fDistCenter - fRadInner) * 2.0 / fSizeAA)) * fFacBorder; + + for (nState = 0; nState < BS_LAST_STATE; nState++) + { + // Get Colors of State + switch(nState) + { + case BS_ENABLED: + tColorBack = m_tButtonStyle.m_tColorBack.m_tEnabled; + tColorBorder = m_tButtonStyle.m_tColorBorder.m_tEnabled; + tColorFace = m_tButtonStyle.m_tColorFace.m_tEnabled; + break; + case BS_CLICKED: + tColorBack = m_tButtonStyle.m_tColorBack.m_tClicked; + tColorBorder = m_tButtonStyle.m_tColorBorder.m_tClicked; + tColorFace = m_tButtonStyle.m_tColorFace.m_tClicked; + break; + case BS_PRESSED: + tColorBack = m_tButtonStyle.m_tColorBack.m_tPressed; + tColorBorder = m_tButtonStyle.m_tColorBorder.m_tPressed; + tColorFace = m_tButtonStyle.m_tColorFace.m_tPressed; + break; + case BS_HOT: + tColorBack = m_tButtonStyle.m_tColorBack.m_tHot; + tColorBorder = m_tButtonStyle.m_tColorBorder.m_tHot; + tColorFace = m_tButtonStyle.m_tColorFace.m_tHot; + break; + case BS_DISABLED: + default: + tColorBack = m_tButtonStyle.m_tColorBack.m_tDisabled; + tColorBorder = m_tButtonStyle.m_tColorBorder.m_tDisabled; + tColorFace = m_tButtonStyle.m_tColorFace.m_tDisabled; + break; + } + + // Calculate Distance of Point from Highlight of Button + fDistHigh = sqrt(((double)nX - fXHigh) * ((double)nX - fXHigh) + ((double)nY - fYHigh) * ((double)nY - fYHigh)); + + // Calculate Factor of Inner Surface + if (fHeightButton > 0) + fFacFace = 1.0 - fHeightButton * (fDistCenter / fRadInner) * (fDistCenter / fRadInner); + else + fFacFace = 1.0 + fHeightButton - fHeightButton * (fDistCenter / fRadInner) * (fDistCenter / fRadInner); + fFacFace = __max(0.0, __min(1.0, 0.5 - (fDistCenter - fRadInner) * 2.0 / fSizeAA)) * fFacFace; + + // Calculate Factor of Highlight + fFacHigh = 1.0 + __max(-1.0, __min(1.0, 1.0 - fHeightButton * fDistHigh / fRadHigh)) * fPowHigh; + fFacFace = fFacFace * fFacHigh; + + // Calculate Color-Factors + fFacR = + (float)GetRValue(tColorBack) * fFacBack + + (float)GetRValue(tColorBorder) * fFacBorder + + (float)GetRValue(tColorFace) * fFacFace; + fFacG = + (float)GetGValue(tColorBack) * fFacBack + + (float)GetGValue(tColorBorder) * fFacBorder + + (float)GetGValue(tColorFace) * fFacFace; + fFacB = + (float)GetBValue(tColorBack) * fFacBack + + (float)GetBValue(tColorBorder) * fFacBorder + + (float)GetBValue(tColorFace) * fFacFace; + + // Calculate actual Color of Pixel + tColPixel = RGB( + __max(0, __min(255, (int)fFacR)), + __max(0, __min(255, (int)fFacG)), + __max(0, __min(255, (int)fFacB)) + ); + + // Draw Pixels + MemDC.SetPixel(nSizeEdge + nX, nSizeEdge + nY + (2 * nSizeEdge + 1) * nState, tColPixel); + } + } + } + + // Select Old Bitmap into DC + MemDC.SelectObject(hOldBmp); + + return true; +} diff --git a/RoundButtonStyle.h b/RoundButtonStyle.h new file mode 100644 index 0000000..c23865e --- /dev/null +++ b/RoundButtonStyle.h @@ -0,0 +1,149 @@ +/******************************************************************** + created: 2005/06/03 + created: 03:06:2005 11:23 + filename: x:\Software\Mfc\Source\Controls\Buttons\RoundButtonStyle.h + file path: x:\Software\Mfc\Source\Controls\Buttons + file base: RoundButtonStyle + file ext: h + author: Markus Zocholl + + purpose: CRoundButtonStyle manages the Style of CRoundButton, a + Button-Control with round Design. + Because the generation of the Button-Images is time consuming + this is only done once in the Style-Class, and all Buttons + associated with this class take the same Images. +*********************************************************************/ + +#pragma once +#include "afxwin.h" + +//! State of Button +static enum ButtonState { + BS_DISABLED = 0, // +#include + +void PrintProcessNameAndID(DWORD processID, CString& strPath) +{ + TCHAR szProcessName[MAX_PATH] = TEXT(""); + + // Get a handle to the process. + HANDLE hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | + PROCESS_VM_READ, + FALSE, processID ); + + // Get the process name. + if (NULL != hProcess ) + { + HMODULE hMod; + DWORD cbNeeded; + + if ( EnumProcessModules( hProcess, &hMod, sizeof(hMod), + &cbNeeded) ) + { + GetModuleFileNameEx( hProcess, hMod, szProcessName, sizeof(szProcessName)/sizeof(TCHAR)); + } + } + + // Print the process name and identifier. + strPath = szProcessName; + // Release the handle to the process. + CloseHandle( hProcess ); +} + +BOOL EnumProcessAndFocus(CString processPath) +{ + DWORD aProcesses[1024], cbNeeded, cProcesses; + unsigned int i; + BOOL bFound = false; + + if ( !EnumProcesses( aProcesses, sizeof(aProcesses), &cbNeeded ) ) + { + return false; + } + + // Calculate how many process identifiers were returned. + cProcesses = cbNeeded / sizeof(DWORD); + + // Print the name and process identifier for each process. + for ( i = 0; i < cProcesses; i++ ) + { + if( aProcesses[i] != 0 ) + { + CString strPath; + PrintProcessNameAndID( aProcesses[i], strPath ); + if(strPath.Find(processPath) >= 0) { + HWND hwnd = GetWinHandle(aProcesses[i]); + ::BringWindowToTop(hwnd); + ::SetForegroundWindow(hwnd); + ::ShowWindow(hwnd, SW_SHOWDEFAULT); + bFound = true; + } + } + } + + return bFound; +} + +BOOL CTouchBoardApp::InitInstance() +{ + // α׷ Ŵ佺Ʈ ComCtl32.dll 6 ̻ Ͽ ־ Ÿ + // ϵ ϴ , Windows XP 󿡼 ݵ InitCommonControlsEx() ʿմϴ. + // InitCommonControlsEx() â ϴ. + INITCOMMONCONTROLSEX InitCtrls; + InitCtrls.dwSize = sizeof(InitCtrls); + // α׷ Ʈ Ŭ ϵ + // ׸ Ͻʽÿ. + InitCtrls.dwICC = ICC_WIN95_CLASSES; + InitCommonControlsEx(&InitCtrls); + + CWinApp::InitInstance(); + + if (!AfxSocketInit()) + { + AfxMessageBox(IDP_SOCKETS_INIT_FAILED); + return FALSE; + } + + + /* ߺ - added by ritoseo */ + HANDLE hEvent; + hEvent = CreateEvent(NULL, FALSE, TRUE, AfxGetAppName()); + if ( GetLastError() == ERROR_ALREADY_EXISTS) + { + EnumProcessAndFocus(L"TouchBoard.exe"); + return FALSE; + } + /************************************/ + + AfxEnableControlContainer(); + + // ȭ ڿ Ʈ Ǵ + // Ʈ ԵǾ ִ ڸ ϴ. + CShellManager *pShellManager = new CShellManager; + + // MFC Ʈ ׸ ϱ "Windows " ־ Ȱȭ + CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerWindows)); + + // ǥ ʱȭ + // ̵ ʰ ũ⸦ ̷ + // Ʒ ʿ Ư ʱȭ + // ƾ ؾ մϴ. + // ش Ʈ Ű Ͻʽÿ. + // TODO: ڿ ȸ Ǵ ̸ + // ؾ մϴ. + SetRegistryKey(_T(" α׷ 翡 α׷")); + + CTouchBoardDlg dlg; + m_pMainWnd = &dlg; + INT_PTR nResponse = dlg.DoModal(); + if (nResponse == IDOK) + { + // TODO: ⿡ [Ȯ] ŬϿ ȭ ڰ ó + // ڵ带 ġմϴ. + } + else if (nResponse == IDCANCEL) + { + // TODO: ⿡ [] ŬϿ ȭ ڰ ó + // ڵ带 ġմϴ. + } + else if (nResponse == -1) + { + TRACE(traceAppMsg, 0, ": ȭ ڸ Ƿ α׷ ġ ʰ ˴ϴ.\n"); + TRACE(traceAppMsg, 0, ": ȭ ڿ MFC Ʈ ϴ #define _AFX_NO_MFC_CONTROLS_IN_DIALOGS ϴ.\n"); + } + + // ڸ մϴ. + if (pShellManager != NULL) + { + delete pShellManager; + } + + // ȭ ڰ Ƿ α׷ ޽ ʰ α׷ ֵ FALSE + // ȯմϴ. + return FALSE; +} + diff --git a/TouchBoard.h b/TouchBoard.h new file mode 100644 index 0000000..3eee5ab --- /dev/null +++ b/TouchBoard.h @@ -0,0 +1,32 @@ + +// TouchBoard.h : PROJECT_NAME α׷ Դϴ. +// + +#pragma once + +#ifndef __AFXWIN_H__ + #error "PCH ϱ 'stdafx.h' մϴ." +#endif + +#include "resource.h" // ȣԴϴ. + + +// CTouchBoardApp: +// Ŭ ؼ TouchBoard.cpp Ͻʽÿ. +// + +class CTouchBoardApp : public CWinApp +{ +public: + CTouchBoardApp(); + +// Դϴ. +public: + virtual BOOL InitInstance(); + +// Դϴ. + + DECLARE_MESSAGE_MAP() +}; + +extern CTouchBoardApp theApp; \ No newline at end of file diff --git a/TouchBoard.rc b/TouchBoard.rc new file mode 100644 index 0000000..f23e321 Binary files /dev/null and b/TouchBoard.rc differ diff --git a/TouchBoardDlg.cpp b/TouchBoardDlg.cpp new file mode 100644 index 0000000..1cbd099 --- /dev/null +++ b/TouchBoardDlg.cpp @@ -0,0 +1,3128 @@ + +// TouchBoardDlg.cpp : +// + +#include "stdafx.h" +#include "TouchBoard.h" +#include "TouchBoardDlg.h" +#include "OnCastDlg.h" +#include "afxdialogex.h" +#include "CRoundButton.h" + +#pragma comment(lib,"Ws2_32.lib") +#pragma comment(lib,"Wininet.lib") +#pragma comment(lib,"Iphlpapi.lib") +#ifdef _DEBUG +#pragma comment(lib,"cximage/debug/cximage.lib") +#pragma comment(lib,"cximage/debug/Jpeg.lib") +#pragma comment(lib,"cximage/debug/png.lib") +#pragma comment(lib,"cximage/debug/mng.lib") +#pragma comment(lib,"cximage/debug/jasper.lib") +#pragma comment(lib,"cximage/debug/zlib.lib") +#pragma comment(lib,"cximage/debug/Tiff.lib") +#pragma comment(lib,"cximage/debug/libdcr.lib") +#pragma comment(lib,"cximage/debug/libpsd.lib") +#else +#pragma comment(lib,"cximage/cximage.lib") +#pragma comment(lib,"cximage/Jpeg.lib") +#pragma comment(lib,"cximage/png.lib") +#pragma comment(lib,"cximage/mng.lib") +#pragma comment(lib,"cximage/jasper.lib") +#pragma comment(lib,"cximage/zlib.lib") +#pragma comment(lib,"cximage/Tiff.lib") +#pragma comment(lib,"cximage/libdcr.lib") +#pragma comment(lib,"cximage/libpsd.lib") +#endif + +#include +#include +#include +#include + +#include +#include + +#ifdef _DEBUG +#define new DEBUG_NEW +#endif + +CTouchBoardDlg *g_pMainDlg = NULL; + +// α׷ Ǵ CAboutDlg ȭ Դϴ. + +class CAboutDlg : public CDialogEx +{ +public: + CAboutDlg(); + +// ȭ Դϴ. + enum { IDD = IDD_ABOUTBOX }; + + protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV Դϴ. + +// Դϴ. +protected: + DECLARE_MESSAGE_MAP() +}; + +CAboutDlg::CAboutDlg() : CDialogEx(CAboutDlg::IDD) +{ +} + +void CAboutDlg::DoDataExchange(CDataExchange* pDX) +{ + CDialogEx::DoDataExchange(pDX); +} + +BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx) +END_MESSAGE_MAP() + + +// CTouchBoardDlg ȭ + + + +CTouchBoardDlg::CTouchBoardDlg(CWnd* pParent /*=NULL*/) + : CDialogEx(CTouchBoardDlg::IDD, pParent) +{ + m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); +} + +void CTouchBoardDlg::DoDataExchange(CDataExchange* pDX) +{ + CDialogEx::DoDataExchange(pDX); + DDX_Control(pDX, IDC_EDIT_LOG, m_logEdit); +} + +BEGIN_MESSAGE_MAP(CTouchBoardDlg, CDialogEx) + ON_WM_SYSCOMMAND() + ON_WM_PAINT() + ON_WM_QUERYDRAGICON() + ON_BN_CLICKED(IDC_BUTTON_SETUP, &CTouchBoardDlg::OnBnClickedButtonSetup) + ON_WM_DESTROY() + ON_REGISTERED_MESSAGE(WM_TBD_SETUP_SAVE, &CTouchBoardDlg::OnTbdSetupSave) + ON_REGISTERED_MESSAGE(WM_TBD_GROUP_PUSH, &CTouchBoardDlg::OnTbdLevel2Push) + ON_REGISTERED_MESSAGE(WM_TBD_UPDATE_GROUP, &CTouchBoardDlg::OnTbdUpdateLevel2) + ON_REGISTERED_MESSAGE(WM_TBD_UPDATE_LOG, &CTouchBoardDlg::OnTbdLogUpdate) + ON_REGISTERED_MESSAGE(WM_TBD_SUB_GROUPING, &CTouchBoardDlg::OnTbdSubGrouping) + + ON_WM_ERASEBKGND() + ON_BN_CLICKED(IDC_BUTTON_CAST_ALL, &CTouchBoardDlg::OnBnClickedButtonCastAll) + ON_BN_CLICKED(IDC_BUTTON_CAST_FIRE, &CTouchBoardDlg::OnBnClickedButtonCastFire) + ON_BN_CLICKED(IDC_BUTTON_CAST_RESCUE, &CTouchBoardDlg::OnBnClickedButtonCastRescue) + ON_BN_CLICKED(IDC_BUTTON_CAST_EMERGENCY, &CTouchBoardDlg::OnBnClickedButtonCastEmergency) + ON_BN_CLICKED(IDC_BUTTON_CAST_NORMAL, &CTouchBoardDlg::OnBnClickedButtonCastNormal) + ON_BN_CLICKED(IDC_BUTTON_RESTORE, &CTouchBoardDlg::OnBnClickedButtonRestore) + ON_BN_CLICKED(IDC_BUTTON_WIRELESS, &CTouchBoardDlg::OnBnClickedButtonWireless) + ON_BN_CLICKED(IDC_BUTTON_CALL, &CTouchBoardDlg::OnBnClickedButtonCall) + ON_WM_CLOSE() + ON_BN_CLICKED(IDC_BUTTON_CAST_WHOLE, &CTouchBoardDlg::OnBnClickedButtonCastWhole) + ON_WM_TIMER() + ON_BN_CLICKED(IDC_BUTTON_MICVOL_MINUS, &CTouchBoardDlg::OnBnClickedButtonMicvolMinus) + ON_BN_CLICKED(IDC_BUTTON_MICVOL_PLUS, &CTouchBoardDlg::OnBnClickedButtonMicvolPlus) + ON_BN_CLICKED(IDC_BUTTON_SPKVOL_MINUS, &CTouchBoardDlg::OnBnClickedButtonSpkvolMinus) + ON_BN_CLICKED(IDC_BUTTON_SPKVOL_PLUS, &CTouchBoardDlg::OnBnClickedButtonSpkvolPlus) + ON_WM_CTLCOLOR() +END_MESSAGE_MAP() + + + + +#include +#include +#include +#include +#include + +#pragma comment(lib, "DbgHelp") +#define MAX_BUFF_SIZE 1024 + +using namespace std; +DWORD WINAPI func(); + +BOOL CheckPing(char strAddr[]) +{ + BOOL bChkInternet; + int nMaxTime = 1; + + HRESULT hr; + char *SendData = "Check TCP/IP"; + + LPVOID ReplyBuffer; + INT32 iBufferLen; + DWORD dwRetVal; + HANDLE hlcmpFile; + + char pingAddr[64]; + sprintf(pingAddr, "%s", strAddr); + + hlcmpFile = IcmpCreateFile(); + iBufferLen = sizeof(ICMP_ECHO_REPLY) + strlen(SendData); + ReplyBuffer = (VOID*)malloc(iBufferLen); + while (TRUE) + { + dwRetVal = IcmpSendEcho(hlcmpFile, + inet_addr(pingAddr), //www.00.co.kr + SendData, + strlen(SendData), + NULL, + ReplyBuffer, + iBufferLen, + 1000); + + + if (dwRetVal != 0) { + PICMP_ECHO_REPLY pEchoReply = (PICMP_ECHO_REPLY)ReplyBuffer; + struct in_addr ReplyAddr; + ReplyAddr.S_un.S_addr = pEchoReply->Address; + TRACE("\tSent icmp message to %s\n", pingAddr); + if (dwRetVal > 1) { + TRACE("\tReceived %ld icmp message responses\n", dwRetVal); + TRACE("\tInformation from the first response:\n"); + } + else { + TRACE("\tReceived %ld icmp message response\n", dwRetVal); + TRACE("\tInformation from this response:\n"); + } + TRACE("\t Received from %s\n", inet_ntoa(ReplyAddr)); + TRACE("\t Status = %ld\n", + pEchoReply->Status); + TRACE("\t Roundtrip time = %ld milliseconds\n", + pEchoReply->RoundTripTime); + + if (pEchoReply->Status != 0) + return FALSE; + + break; + } + + Sleep(1000); + nMaxTime--; + + if (0 == nMaxTime) + { + //AfxMessageBox(_T("ͳݿ ȵ"), MB_OK); + //free(ReplyBuffer); + TRACE("PING Failed at %s\n", pingAddr); + return FALSE; + } + } + + if(dwRetVal != 0) + TRACE("PING Okay at %s\n", pingAddr); + //free(ReplyBuffer); + return (dwRetVal != 0); +} + +void make_minidump(EXCEPTION_POINTERS* e) +{ + TCHAR tszFileName[MAX_BUFF_SIZE] = {0}; + TCHAR tszPath[MAX_BUFF_SIZE] = {0}; + SYSTEMTIME stTime = {0}; + GetSystemTime(&stTime); + SHGetSpecialFolderPath(NULL,tszPath, CSIDL_APPDATA, FALSE); + StringCbPrintf(tszFileName, + _countof(tszFileName), + _T("%s\\%s__%4d%02d%02d_%02d%02d%02d.dmp"), + _T("D:\\"), _T("CrashDump"), + stTime.wYear, + stTime.wMonth, + stTime.wDay, + stTime.wHour, + stTime.wMinute, + stTime.wSecond); + + HANDLE hFile = CreateFile(tszFileName, GENERIC_WRITE, FILE_SHARE_READ, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); + if(hFile == INVALID_HANDLE_VALUE) + return; + + MINIDUMP_EXCEPTION_INFORMATION exceptionInfo; + exceptionInfo.ThreadId = GetCurrentThreadId(); + exceptionInfo.ExceptionPointers = e; + exceptionInfo.ClientPointers = FALSE; + + MiniDumpWriteDump( + GetCurrentProcess(), + GetCurrentProcessId(), + hFile, + MINIDUMP_TYPE(MiniDumpWithIndirectlyReferencedMemory | MiniDumpScanMemory | MiniDumpWithFullMemory), + e ? &exceptionInfo : NULL, + NULL, + NULL); + + if(hFile) + { + CloseHandle(hFile); + hFile = NULL; + } + return; +} + +LONG CALLBACK unhandled_handler(EXCEPTION_POINTERS* e) +{ + make_minidump(e); + return EXCEPTION_CONTINUE_SEARCH; +} + + +// CTouchBoardDlg ޽ ó + +BOOL CTouchBoardDlg::OnInitDialog() +{ + CDialogEx::OnInitDialog(); + + SetUnhandledExceptionFilter( unhandled_handler); // added by ritoseo - 2019-09-10 + // ý ޴ "..." ޴ ׸ ߰մϴ. + + // IDM_ABOUTBOX ý ־ մϴ. + ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); + ASSERT(IDM_ABOUTBOX < 0xF000); + + CMenu* pSysMenu = GetSystemMenu(FALSE); + if (pSysMenu != NULL) + { + BOOL bNameValid; + CString strAboutMenu; + bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX); + ASSERT(bNameValid); + if (!strAboutMenu.IsEmpty()) + { + pSysMenu->AppendMenu(MF_SEPARATOR); + pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); + } + } + + // ȭ մϴ. α׷ â ȭ ڰ ƴ 쿡 + // ӿũ ۾ ڵ մϴ. + SetIcon(m_hIcon, TRUE); // ū մϴ. + SetIcon(m_hIcon, FALSE); // մϴ. + + // TODO: ⿡ ߰ ʱȭ ۾ ߰մϴ. + WSADATA wsaData = {0}; + int iResult; + + g_pMainDlg = this; + + m_sock = INVALID_SOCKET; + m_iSelectGroup = -1; + m_sendSize = 0; + m_recvSize = 0; + m_bIsActive = TRUE; + m_stationCount = 0; + m_iGroupBtnCount = 0; + + m_pMemDC = NULL; + m_pDCBitmap = NULL; + m_pDidLinePen = NULL; + + m_recvSize = 0; + + // Initialize Winsock + iResult = WSAStartup(MAKEWORD(2, 2), &wsaData); + if (iResult != 0) { + TRACE(L"WSAStartup failed: %d\n", iResult); + } + + for(int i = 0;i < TBD_MAX_STATION_COUNT;i++) { + m_pStationList[i] = NULL; + } + for(int i = 0;i < TBD_MAX_GROUP_COUNT;i++) { + m_pGroupBtn[i] = NULL; + } + + RGB2RGBQURD(RGB(255, 0, 0), RGB_QUAD_RED); + RGB2RGBQURD(RGB(0, 255, 0), RGB_QUAD_GREEN); + RGB2RGBQURD(RGB(0, 0, 255), RGB_QUAD_BLUE); + +#if USE_ROUND_BUTTON2 + //m_topFont.CreatePointFont(210, L""); + m_topFont.CreateFont(28, 11, 0, 0, 1500, 0, 0, 0, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY, DEFAULT_PITCH, L""); + m_castFont.CreateFont(28, 11, 0, 0, 1500, 0, 0, 0, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY, DEFAULT_PITCH, L""); + m_titleFont.CreateFont(38, 15, 0, 0, 1000, 0, 0, 0, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY, DEFAULT_PITCH, L""); +#else + m_topFont.CreatePointFont(240, L""); + m_castFont.CreatePointFont(180, L""); +#endif + + m_logFont.CreatePointFont(80, L""); + //m_btnFont.CreatePointFont(160, L""); + m_btnFont.CreateFont(20, 7, 0, 0, 1000, 0, 0, 0, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY, DEFAULT_PITCH, L""); + m_btnSmallFont.CreateFont(20, 5, 0, 0, 1000, 0, 0, 0, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY, DEFAULT_PITCH, L""); + m_btnUnderFont.CreateFont(20, 8, 0, 0, 1000, 0, 0, 0, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY, DEFAULT_PITCH, L""); + + + GetMonitorInformation(); + TRACE("Monitor Resolution : %d x %d\n", m_infoMonitor.nWidth, m_infoMonitor.nHeight); + m_bIsFullHD = false; + if (m_infoMonitor.nWidth >= 1920) { + m_iScreenWidth = 1920; + m_iScreenHeight = 1080; + m_bIsFullHD = true; + } else { + m_iScreenWidth = TBD_STANDARD_WIDTH; + m_iScreenHeight = TBD_STANDARD_HEIGHT; + } + +#if 0 + m_bIsFullHD = false; + m_iScreenWidth = TBD_STANDARD_WIDTH; + m_iScreenHeight = TBD_STANDARD_HEIGHT; +#endif + + /* + m_iScreenWidth = m_infoMonitor.nWidth; + m_iScreenHeight = m_infoMonitor.nHeight; + if (m_iScreenWidth > TBD_STANDARD_WIDTH) { + m_iScreenWidth = 1920; + m_iScreenHeight = 1080; + m_bIsFullHD = true; + } + */ + + SetWindowPos(NULL, 0, 0, m_iScreenWidth, m_iScreenHeight, 0); + + +#if TBD_USE_COLOR_BUTTON == 1 + INT32 idx; + INT32 iMoveXGap = 118; + CRect rt; + GetDlgItem(IDC_BUTTON_CAST)->GetClientRect(&rt); + GetDlgItem(IDC_BUTTON_CAST)->ShowWindow(SW_HIDE); + GetDlgItem(IDC_BUTTON_CAST)->SetDlgCtrlID(0); + + if (m_bIsFullHD) { + rt.right += 20; + iMoveXGap += 20; + } + +#if TBD_USE_THREELINE_GROUP == 1 + rt.bottom -= 15; +#endif + + rt.MoveToXY(20, 19); +#if USE_ROUND_BUTTON2 + tButtonStyle style; + m_pTopButton[0] = new CRoundButton2; + m_tTopStyle[0].GetButtonStyle(&style); + //style.m_tColorFace.m_tEnabled = RGB(130, 255, 130); + style.m_tColorFace.m_tEnabled = RGB(57, 119, 206); + m_tTopStyle[0].SetButtonStyle(&style); + m_pTopButton[0]->SetRoundButtonStyle(&m_tTopStyle[0]); +#else + m_pTopButton[0] = new CColorButton(RGB(0,0,0), RGB(130,255,130)); +#endif + m_pTopButton[0]->Create(L"", WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON|BS_OWNERDRAW|BS_MULTILINE,rt,this,IDC_BUTTON_CAST); + m_pTopButton[0]->SetFont(&m_topFont); + m_pTopButton[0]->ShowWindow(SW_HIDE); + + + +#if USE_ROUND_BUTTON2 + rt.MoveToX(20); +#else + rt.MoveToX(20 + 118); +#endif + GetDlgItem(IDC_BUTTON_WIRELESS)->ShowWindow(SW_HIDE); + GetDlgItem(IDC_BUTTON_WIRELESS)->SetDlgCtrlID(0); +#if USE_ROUND_BUTTON2 + m_pTopButton[1] = new CRoundButton2; + m_tTopStyle[1].GetButtonStyle(&style); + style.m_tColorBack.m_tEnabled = TOPBAR_BACK_COLOR; + style.m_tColorBack.m_tPressed = TOPBAR_BACK_COLOR; + m_tTopStyle[1].SetButtonStyle(&style); + m_pTopButton[1]->SetRoundButtonStyle(&m_tTopStyle[1]); +#else + m_pTopButton[1] = new CColorButton(); +#endif + m_pTopButton[1]->Create(L"",WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON|BS_OWNERDRAW|BS_MULTILINE,rt,this,IDC_BUTTON_WIRELESS); + m_pTopButton[1]->SetFont(&m_topFont); + m_pTopButton[1]->ShowWindow(SW_SHOW); + + +#if USE_ROUND_BUTTON2 + rt.MoveToX(20 + iMoveXGap); +#else + rt.MoveToX(20 + 118 * 2); +#endif + GetDlgItem(IDC_BUTTON_CALL)->ShowWindow(SW_HIDE); + GetDlgItem(IDC_BUTTON_CALL)->SetDlgCtrlID(0); +#if USE_ROUND_BUTTON2 + m_pTopButton[2] = new CRoundButton2; + m_tTopStyle[2].GetButtonStyle(&style); + style.m_tColorBack.m_tEnabled = TOPBAR_BACK_COLOR; + style.m_tColorBack.m_tPressed = TOPBAR_BACK_COLOR; + m_tTopStyle[2].SetButtonStyle(&style); + m_pTopButton[2]->SetRoundButtonStyle(&m_tTopStyle[2]); +#else + m_pTopButton[2] = new CColorButton(); +#endif + m_pTopButton[2]->Create(L"ȭ",WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON|BS_OWNERDRAW|BS_MULTILINE,rt,this,IDC_BUTTON_CALL); + m_pTopButton[2]->SetFont(&m_topFont); + m_pTopButton[2]->ShowWindow(SW_SHOW); + + +#if USE_ROUND_BUTTON2 + rt.MoveToX(20 + iMoveXGap * 9 + 30); + if (m_bIsFullHD) { + rt.MoveToX(20 + iMoveXGap * 12 + 70); + } +#else + rt.MoveToX(20 + 118 * 3); +#endif + GetDlgItem(IDOK)->ShowWindow(SW_HIDE); + GetDlgItem(IDOK)->SetDlgCtrlID(0); +#if USE_ROUND_BUTTON2 + m_pTopButton[3] = new CRoundButton2; + m_tTopStyle[3].GetButtonStyle(&style); + style.m_tColorBack.m_tEnabled = TOPBAR_BACK_COLOR; + style.m_tColorBack.m_tPressed = TOPBAR_BACK_COLOR; + m_tTopStyle[3].SetButtonStyle(&style); + m_pTopButton[3]->SetRoundButtonStyle(&m_tTopStyle[3]); +#else + m_pTopButton[3] = new CColorButton(); +#endif + m_pTopButton[3]->Create(L"", + WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON| + BS_OWNERDRAW|BS_MULTILINE, + rt,this,IDOK); + m_pTopButton[3]->SetFont(&m_topFont); + m_pTopButton[3]->ShowWindow(SW_SHOW); + + + INT32 pivot_y = 320; + INT32 btn_gap_y = 82; + + +#if USE_ROUND_BUTTON2 + GetDlgItem(IDC_BUTTON_CAST_ALL)->GetClientRect(&rt); + rt.MoveToXY(17, pivot_y + btn_gap_y * 6); +#else + rt.MoveToX(20 + 118 * 9); + rt.right += 30; +#endif + GetDlgItem(IDC_BUTTON_SETUP)->ShowWindow(SW_HIDE); + GetDlgItem(IDC_BUTTON_SETUP)->SetDlgCtrlID(0); +#if USE_ROUND_BUTTON2 + m_pTopButton[4] = new CRoundButton2; + m_tTopStyle[4].GetButtonStyle(&style); + //style.m_tColorFace.m_tEnabled = RGB(240, 180, 120); + style.m_tColorBack.m_tEnabled = ACT_BTN_REGION_BACK_COLOR; + style.m_tColorBack.m_tPressed = ACT_BTN_REGION_BACK_COLOR; + m_tTopStyle[4].SetButtonStyle(&style); + m_pTopButton[4]->SetRoundButtonStyle(&m_tTopStyle[4]); +#else + m_pTopButton[4] = new CColorButton(); +#endif + m_pTopButton[4]->Create(L"ȯ漳", + WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON| + BS_OWNERDRAW|BS_MULTILINE, + rt,this,IDC_BUTTON_SETUP); + m_pTopButton[4]->SetFont(&m_topFont); + m_pTopButton[4]->ShowWindow(SW_SHOW); + + + idx = 0; + GetDlgItem(IDC_BUTTON_CAST_ALL)->GetClientRect(&rt); + GetDlgItem(IDC_BUTTON_CAST_ALL)->ShowWindow(SW_HIDE); + GetDlgItem(IDC_BUTTON_CAST_ALL)->SetDlgCtrlID(0); + rt.MoveToXY(17, pivot_y); +#if USE_ROUND_BUTTON2 + m_pActButton[idx] = new CRoundButton2; + m_tActStyle[idx].GetButtonStyle(&style); + style.m_tColorFace.m_tEnabled = RGB(240, 180, 120); + style.m_tColorBack.m_tEnabled = ACT_BTN_REGION_BACK_COLOR; + style.m_tColorBack.m_tPressed = ACT_BTN_REGION_BACK_COLOR; + m_tActStyle[idx].SetButtonStyle(&style); + m_pActButton[idx]->SetRoundButtonStyle(&m_tActStyle[idx]); + m_pActButton[idx]->SetFont(&m_castFont); +#else + m_pActButton[idx] = new CColorButton(RGB(0,0,0), RGB(240,180,120)); +#endif + m_pActButton[idx]->Create(L"", WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON|BS_OWNERDRAW|BS_MULTILINE,rt,this,IDC_BUTTON_CAST_ALL); + m_pActButton[idx]->ShowWindow(SW_SHOW); + +#if 0 + m_pActButton[idx]->GetClientRect(rcOK); + + rgnOK.CreateRoundRectRgn(rcOK.left, rcOK.top, + rcOK.right, rcOK.bottom, + 35, 35); + nRet = m_pActButton[idx]->SetWindowRgn(rgnOK, TRUE); +#endif + + idx = 1; + GetDlgItem(IDC_BUTTON_CAST_FIRE)->ShowWindow(SW_HIDE); + GetDlgItem(IDC_BUTTON_CAST_FIRE)->SetDlgCtrlID(0); + rt.MoveToXY(17, pivot_y + btn_gap_y); +#if USE_ROUND_BUTTON2 + m_pActButton[idx] = new CRoundButton2; + m_tActStyle[idx].GetButtonStyle(&style); + style.m_tColorFace.m_tEnabled = RGB(219, 40, 20); + style.m_tColorBack.m_tEnabled = ACT_BTN_REGION_BACK_COLOR; + style.m_tColorBack.m_tPressed = ACT_BTN_REGION_BACK_COLOR; + m_tActStyle[idx].SetButtonStyle(&style); + m_pActButton[idx]->SetRoundButtonStyle(&m_tActStyle[idx]); + m_pActButton[idx]->SetFont(&m_castFont); + +#else + m_pActButton[idx] = new CColorButton(RGB(0,0,0), RGB(255,130,130)); +#endif + m_pActButton[idx]->Create(L"ȭ", WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON|BS_OWNERDRAW|BS_MULTILINE,rt,this,IDC_BUTTON_CAST_FIRE); + m_pActButton[idx]->ShowWindow(SW_SHOW); + + idx = 2; + GetDlgItem(IDC_BUTTON_CAST_RESCUE)->ShowWindow(SW_HIDE); + GetDlgItem(IDC_BUTTON_CAST_RESCUE)->SetDlgCtrlID(0); + rt.MoveToXY(17, pivot_y + btn_gap_y * 2); +#if USE_ROUND_BUTTON2 + m_pActButton[idx] = new CRoundButton2; + m_tActStyle[idx].GetButtonStyle(&style); + style.m_tColorFace.m_tEnabled = RGB(241, 164, 36); + style.m_tColorBack.m_tEnabled = ACT_BTN_REGION_BACK_COLOR; + style.m_tColorBack.m_tPressed = ACT_BTN_REGION_BACK_COLOR; + m_tActStyle[idx].SetButtonStyle(&style); + m_pActButton[idx]->SetRoundButtonStyle(&m_tActStyle[idx]); + m_pActButton[idx]->SetFont(&m_castFont); +#else + m_pActButton[idx] = new CColorButton(RGB(0,0,0), RGB(252,254,209)); +#endif + m_pActButton[idx]->Create(L"", WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON|BS_OWNERDRAW|BS_MULTILINE,rt,this,IDC_BUTTON_CAST_RESCUE); + m_pActButton[idx]->ShowWindow(SW_SHOW); + + idx = 3; + GetDlgItem(IDC_BUTTON_CAST_EMERGENCY)->ShowWindow(SW_HIDE); + GetDlgItem(IDC_BUTTON_CAST_EMERGENCY)->SetDlgCtrlID(0); + rt.MoveToXY(17, pivot_y + btn_gap_y * 3); +#if USE_ROUND_BUTTON2 + m_pActButton[idx] = new CRoundButton2; + m_tActStyle[idx].GetButtonStyle(&style); + style.m_tColorFace.m_tEnabled = RGB(0, 146, 55); + style.m_tColorBack.m_tEnabled = ACT_BTN_REGION_BACK_COLOR; + style.m_tColorBack.m_tPressed = ACT_BTN_REGION_BACK_COLOR; + m_tActStyle[idx].SetButtonStyle(&style); + m_pActButton[idx]->SetRoundButtonStyle(&m_tActStyle[idx]); + m_pActButton[idx]->SetFont(&m_castFont); +#else + m_pActButton[idx] = new CColorButton(RGB(0,0,0), RGB(130,255,130)); +#endif + m_pActButton[idx]->Create(L"޹", WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON|BS_OWNERDRAW|BS_MULTILINE,rt,this,IDC_BUTTON_CAST_EMERGENCY); + m_pActButton[idx]->ShowWindow(SW_SHOW); + + idx = 4; + GetDlgItem(IDC_BUTTON_CAST_NORMAL)->ShowWindow(SW_HIDE); + GetDlgItem(IDC_BUTTON_CAST_NORMAL)->SetDlgCtrlID(0); + rt.MoveToXY(17, pivot_y + btn_gap_y * 4); +#if USE_ROUND_BUTTON2 + m_pActButton[idx] = new CRoundButton2; + m_tActStyle[idx].GetButtonStyle(&style); + style.m_tColorFace.m_tEnabled = RGB(1, 109, 181); + style.m_tColorBack.m_tEnabled = ACT_BTN_REGION_BACK_COLOR; + style.m_tColorBack.m_tPressed = ACT_BTN_REGION_BACK_COLOR; + m_tActStyle[idx].SetButtonStyle(&style); + m_pActButton[idx]->SetRoundButtonStyle(&m_tActStyle[idx]); + m_pActButton[idx]->SetFont(&m_castFont); +#else + m_pActButton[idx] = new CColorButton(RGB(0,0,0), RGB(70,70,200)); +#endif + m_pActButton[idx]->Create(L"Ÿ", WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON|BS_OWNERDRAW|BS_MULTILINE,rt,this,IDC_BUTTON_CAST_NORMAL); + m_pActButton[idx]->ShowWindow(SW_SHOW); + + idx = 5; + GetDlgItem(IDC_BUTTON_RESTORE)->ShowWindow(SW_HIDE); + GetDlgItem(IDC_BUTTON_RESTORE)->SetDlgCtrlID(0); + rt.MoveToXY(17, pivot_y + btn_gap_y * 5); +#if USE_ROUND_BUTTON2 + m_pActButton[idx] = new CRoundButton2; + m_tActStyle[idx].GetButtonStyle(&style); + style.m_tColorBack.m_tEnabled = ACT_BTN_REGION_BACK_COLOR; + style.m_tColorBack.m_tPressed = ACT_BTN_REGION_BACK_COLOR; + m_tActStyle[idx].SetButtonStyle(&style); + m_pActButton[idx]->SetRoundButtonStyle(&m_tActStyle[idx]); + m_pActButton[idx]->SetFont(&m_castFont); +#else + m_pActButton[idx] = new CColorButton; +#endif + m_pActButton[idx]->Create(L"", WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON|BS_OWNERDRAW|BS_MULTILINE,rt,this,IDC_BUTTON_RESTORE); + m_pActButton[idx]->ShowWindow(SW_SHOW); + + idx = 6; + GetDlgItem(IDC_BUTTON_CAST_WHOLE)->ShowWindow(SW_HIDE); + GetDlgItem(IDC_BUTTON_CAST_WHOLE)->SetDlgCtrlID(0); + rt.MoveToXY(17, pivot_y - btn_gap_y); +#if USE_ROUND_BUTTON2 + m_pActButton[idx] = new CRoundButton2; + m_tActStyle[idx].GetButtonStyle(&style); + style.m_tColorBack.m_tEnabled = ACT_BTN_REGION_BACK_COLOR; + style.m_tColorBack.m_tPressed = ACT_BTN_REGION_BACK_COLOR; + m_tActStyle[idx].SetButtonStyle(&style); + m_pActButton[idx]->SetRoundButtonStyle(&m_tActStyle[idx]); + m_pActButton[idx]->SetFont(&m_castFont); +#else + m_pActButton[idx] = new CColorButton; +#endif + m_pActButton[idx]->Create(L"ü", WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON|BS_OWNERDRAW|BS_MULTILINE,rt,this,IDC_BUTTON_CAST_WHOLE); + m_pActButton[idx]->ShowWindow(SW_SHOW); +#endif + + m_setupDlg.Create(IDD_SETUP_DIALOG, this); + m_setupDlg.LoadSettings(); + + +#if TBD_BUTTON_UI_STYLE == 2 + int offset = -10; + MoveWindowDirection(GetDlgItem(IDC_BUTTON_CAST), 0, offset); + MoveWindowDirection(GetDlgItem(IDC_BUTTON_CALL), 0, offset); + MoveWindowDirection(GetDlgItem(IDC_BUTTON_WIRELESS), 0, offset); + MoveWindowDirection(GetDlgItem(IDOK), 0, offset); +#if !USE_ROUND_BUTTON2 + MoveWindowDirection(GetDlgItem(IDC_BUTTON_SETUP), 0, offset); +#endif + MoveWindowDirection(GetDlgItem(IDC_STATIC_TITLE), 0, offset); + #if TBD_USE_THREELINE_GROUP == 1 + MoveWindowDirection(GetDlgItem(IDC_STATIC_TITLE), 0, offset + 3); + #endif + + #if USE_ROUND_BUTTON2 + offset = 65; + if (m_bIsFullHD) { + offset += 10; + } + MoveWindowDirection(GetDlgItem(IDC_BUTTON_SPKVOL_MINUS), 0, offset); + MoveWindowDirection(GetDlgItem(IDC_STATIC_SPKVOL), 0, offset); + MoveWindowDirection(GetDlgItem(IDC_STATIC_SPKVOL_VALUE), 0, offset); + MoveWindowDirection(GetDlgItem(IDC_BUTTON_SPKVOL_PLUS), 0, offset); + #endif +#endif + + if (m_bIsFullHD) { + MoveWindowDirection(GetDlgItem(IDC_STATIC_TITLE), 250, 0); + } + + + GetDlgItem(IDC_BUTTON_CAST_WHOLE)->SetFont(&m_castFont); + GetDlgItem(IDC_BUTTON_CAST_ALL)->SetFont(&m_castFont); + GetDlgItem(IDC_BUTTON_CAST_FIRE)->SetFont(&m_castFont); + GetDlgItem(IDC_BUTTON_CAST_RESCUE)->SetFont(&m_castFont); + GetDlgItem(IDC_BUTTON_CAST_EMERGENCY)->SetFont(&m_castFont); + GetDlgItem(IDC_BUTTON_CAST_NORMAL)->SetFont(&m_castFont); + GetDlgItem(IDC_BUTTON_RESTORE)->SetFont(&m_castFont); + GetDlgItem(IDC_BUTTON_SETUP)->SetFont(&m_castFont); +#if USE_ROUND_BUTTON2 + GetDlgItem(IDC_STATIC_TITLE)->SetFont(&m_titleFont); +#endif + + GetDlgItem(IDC_BUTTON_PS_STATUS)->ShowWindow(SW_HIDE); + GetDlgItem(IDC_BUTTON_ES_STATUS)->ShowWindow(SW_HIDE); + GetDlgItem(IDC_BUTTON_CT_STATUS)->ShowWindow(SW_HIDE); + + GetDlgItem(IDC_BUTTON_PS_STATUS)->GetClientRect(rt); + rt.MoveToXY(17, 70); + + m_pStatusButton[0] = new CColorButton(RGB(0, 0, 0), STATUS_BTN_GOOD_BACK_COLOR); + m_pStatusButton[0]->Create(L"PS", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON | BS_OWNERDRAW | BS_MULTILINE, rt, this, IDC_BUTTON_PS_STATUS); + m_pStatusButton[0]->SetFont(&m_castFont); + m_pStatusButton[0]->ShowWindow(SW_SHOW); + + rt.MoveToXY(17 + rt.Width() + 5, 70); + m_pStatusButton[1] = new CColorButton(RGB(0, 0, 0), STATUS_BTN_GOOD_BACK_COLOR); + m_pStatusButton[1]->Create(L"ES", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON | BS_OWNERDRAW | BS_MULTILINE, rt, this, IDC_BUTTON_ES_STATUS); + m_pStatusButton[1]->SetFont(&m_castFont); + m_pStatusButton[1]->ShowWindow(SW_SHOW); + + rt.MoveToXY(17 + (rt.Width() + 5) * 2, 70); + m_pStatusButton[2] = new CColorButton(RGB(0, 0, 0), RGB(255, 0, 0)); + m_pStatusButton[2]->Create(L"CT", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON | BS_OWNERDRAW | BS_MULTILINE, rt, this, IDC_BUTTON_CT_STATUS); + m_pStatusButton[2]->SetFont(&m_castFont); + m_pStatusButton[2]->ShowWindow(SW_SHOW); + + + GetDlgItem(IDC_BUTTON_NAME)->SetFont(&m_castFont); + m_setupDlg.GetDlgItem(IDC_BUTTON_MICVOL_MINUS)->SetFont(&m_topFont); + m_setupDlg.GetDlgItem(IDC_BUTTON_MICVOL_PLUS)->SetFont(&m_castFont); + m_setupDlg.GetDlgItem(IDC_STATIC_MICVOL)->SetFont(&m_castFont); + m_setupDlg.GetDlgItem(IDC_STATIC_MICVOL_VALUE)->SetFont(&m_castFont); + + m_setupDlg.GetDlgItem(IDC_BUTTON_LINEVOL_MINUS)->SetFont(&m_topFont); + m_setupDlg.GetDlgItem(IDC_BUTTON_LINEVOL_PLUS)->SetFont(&m_castFont); + m_setupDlg.GetDlgItem(IDC_STATIC_LINEVOL)->SetFont(&m_castFont); + m_setupDlg.GetDlgItem(IDC_STATIC_LINEVOL_VALUE)->SetFont(&m_castFont); + + GetDlgItem(IDC_STATIC_SPKVOL)->SetFont(&m_castFont); + GetDlgItem(IDC_STATIC_SPKVOL_VALUE)->SetFont(&m_castFont); + GetDlgItem(IDC_EDIT_LOG)->SetFont(&m_logFont); +#if TBD_BUTTON_UI_STYLE == 2 + GetDlgItem(IDC_EDIT_LOG)->MoveWindow(180, m_iScreenHeight - 110, m_iScreenWidth - 210, 50); +#else + GetDlgItem(IDC_EDIT_LOG)->MoveWindow(180, TBD_STANDARD_HEIGHT - 130, TBD_STANDARD_WIDTH - 210, 70); +#endif + + + UpdateSettingToVariable(); + + m_ciBackground.Create(m_iScreenWidth, m_iScreenHeight, 32); + RGBQUAD rgbquad; + RGB2RGBQURD(RGB(240, 240, 240), rgbquad); +#if USE_ROUND_BUTTON2 + RGB2RGBQURD(GLOBAL_BACK_COLOR, rgbquad); +#endif + m_ciBackground.FloodFill(0, 0, rgbquad); + + + HINSTANCE hInst = AfxGetInstanceHandle(); + HRSRC res = FindResource(hInst, MAKEINTRESOURCE(IDB_PNG_SYMBOL), L"PNG"); + m_ciSymbol.AlphaCreate(); + m_ciSymbol.LoadResource(res, CXIMAGE_FORMAT_PNG, hInst); + m_ciSymbol.Resample(75, 33); + + + +#if TBD_USE_SOCKET_THREAD == 1 + m_pReceiveThread = AfxBeginThread(SocketReceiveThread, this); +#else + m_pReceiveThread = AfxBeginThread(SocketConnectionThread, this); + SetTimer(TBD_TIMER_EVENT_SOCKET, 10, NULL); +#endif + + m_pPingThread = AfxBeginThread(PingCheckThread, this); + + +#if USE_DUMMY_DATA_FOR_UI + { + int station_idx = 0; + m_stationCount = 0; + m_iGroupBtnCount = 0; + + for (station_idx == 0; station_idx < 22; station_idx++) { + if (m_pStationList[station_idx] == NULL) { + m_pStationList[station_idx] = new CStationInfo; + m_pStationList[station_idx]->m_pButton = NULL; + } + m_pStationList[station_idx]->mGroupIdx = station_idx; + m_pStationList[station_idx]->mWardId = station_idx; + m_pStationList[station_idx]->mStationId = station_idx; + m_pStationList[station_idx]->mNickName = L"ҹ溻"; + m_pStationList[station_idx]->mNickIndex = station_idx; + m_pStationList[station_idx]->mLevel = 2; + m_pStationList[station_idx]->mUpWardId = station_idx; + m_pStationList[station_idx]->mSubCount = 10; + m_pStationList[station_idx]->mSubGroupId = station_idx; + m_pStationList[station_idx]->mBtnShiftRow = -1; + if (m_iGroupBtnCount < TBD_MAX_GROUP_COUNT) // added by ritoseo - 2022-01-20 + m_iGroupBtnCount++; + m_stationCount++; + } + + for (station_idx == 22; station_idx < 33; station_idx++) { + if (m_pStationList[station_idx] == NULL) { + m_pStationList[station_idx] = new CStationInfo; + m_pStationList[station_idx]->m_pButton = NULL; + } + m_pStationList[station_idx]->mGroupIdx = 1; + m_pStationList[station_idx]->mWardId = station_idx; + m_pStationList[station_idx]->mStationId = station_idx; + m_pStationList[station_idx]->mNickName = L""; + m_pStationList[station_idx]->mNickIndex = station_idx - 22; + m_pStationList[station_idx]->mLevel = 3; + m_pStationList[station_idx]->mUpWardId = station_idx; + m_pStationList[station_idx]->mSubCount = 1; + m_pStationList[station_idx]->mSubGroupId = station_idx; + m_pStationList[station_idx]->mBtnShiftRow = -1; + m_stationCount++; + } + + CalcButtonPositioning(); + UpdateTouchButtonList(); + } +#endif + + + return TRUE; // Ŀ Ʈѿ TRUE ȯմϴ. +} + +void CTouchBoardDlg::OnSysCommand(UINT nID, LPARAM lParam) +{ + if ((nID & 0xFFF0) == IDM_ABOUTBOX) + { + CAboutDlg dlgAbout; + dlgAbout.DoModal(); + } + else + { + CDialogEx::OnSysCommand(nID, lParam); + } +} + + + +// ȭ ڿ ּȭ ߸ ߰ ׸ +// Ʒ ڵ尡 ʿմϴ. / ϴ MFC α׷ 쿡 +// ӿũ ۾ ڵ մϴ. + +void CTouchBoardDlg::OnPaint() +{ + if (IsIconic()) + { + CPaintDC dc(this); // ׸⸦ ̽ ؽƮԴϴ. + + SendMessage(WM_ICONERASEBKGND, reinterpret_cast(dc.GetSafeHdc()), 0); + + // Ŭ̾Ʈ 簢  ϴ. + int cxIcon = GetSystemMetrics(SM_CXICON); + int cyIcon = GetSystemMetrics(SM_CYICON); + CRect rect; + GetClientRect(&rect); + int x = (rect.Width() - cxIcon + 1) / 2; + int y = (rect.Height() - cyIcon + 1) / 2; + + // ׸ϴ. + dc.DrawIcon(x, y, m_hIcon); + } + else + { + CPaintDC dc(this); + + CBitmap *pOldBitmap; + CPen *pOldPen; + + if(m_pMemDC == NULL) { + m_pMemDC = new CDC(); + m_pMemDC->CreateCompatibleDC(&dc); + } + + if(m_pDCBitmap == NULL) { + m_pDCBitmap = new CBitmap(); + m_pDCBitmap->CreateCompatibleBitmap(&dc, m_iScreenWidth, m_iScreenHeight); + } + + if(m_pDidLinePen == NULL) { + m_pDidLinePen = new CPen(); + m_pDidLinePen->CreatePen(PS_SOLID, 3, TOUCH_BTN_LINE_COLOR); + } + + pOldBitmap = m_pMemDC->SelectObject(m_pDCBitmap); + pOldPen = m_pMemDC->SelectObject(m_pDidLinePen); + + m_pMemDC->SetBkMode( TRANSPARENT ); + m_ciBackground.Draw2(m_pMemDC->GetSafeHdc()); + +#if USE_ROUND_BUTTON2 + m_pMemDC->FillSolidRect(0, 0, m_iScreenWidth, 65, TOPBAR_BACK_COLOR); + m_pMemDC->FillSolidRect(0, 220, 190, 675 /*+ 60 */, ACT_BTN_REGION_BACK_COLOR); + if (m_bIsFullHD) { + m_pMemDC->FillSolidRect(190, 65, m_iScreenWidth - 190 - 40, 150, RGB(155, 155, 155)); + m_pMemDC->FillSolidRect(191, 66, m_iScreenWidth - 190 - 42, 148, RGB(255, 255, 255)); + } else { + m_pMemDC->FillSolidRect(190, 65, 1045, 150, RGB(155, 155, 155)); + m_pMemDC->FillSolidRect(191, 66, 1043, 148, RGB(255, 255, 255)); + } + + //m_pMemDC->FillSolidRect(190, 220, 1045, 750, RGB(155, 155, 155)); + //m_pMemDC->FillSolidRect(191, 221, 1043, 748, RGB(255, 255, 255)); + + +#endif + + for(INT32 i = 0;i < m_stationCount;i++) + { + if(m_pStationList[i] && m_pStationList[i]->mStationId > 0) + { +#if TBD_BUTTON_UI_STYLE == 2 + if(m_pStationList[i]->mGroupIdx == m_iSelectGroup && m_pStationList[i]->mLevel < 4) { + RECT rect = m_pStationList[i]->mGroupBox; + INT32 off_x = m_pStationList[i]->mBtnPosX + TBD_BTN_SUB_START_X; + INT32 off_y = m_pStationList[i]->mBtnPosY + TBD_BTN_SUB_START_Y; + + COLORREF color = TBD_BTN_GROUP_LINE_BASE_COLOR; + if(m_pStationList[i]->m_pButton->m_bChecked) + color = TBD_BTN_GROUP_LINE_CHECK_COLOR; + + m_pMemDC->Draw3dRect(rect.left + off_x, rect.top + off_y, rect.right - rect.left, rect.bottom - rect.top, color, color); + m_pMemDC->Draw3dRect(rect.left + off_x - 1, rect.top + off_y - 1, rect.right - rect.left + 2, rect.bottom - rect.top + 2, color, color); + } +#else + if(m_pStationList[i]->mGroupIdx == m_iSelectGroup && m_pStationList[i]->mSubCount > 0) { + RECT rect = m_pStationList[i]->mGroupBox; + INT32 off_x = m_pStationList[i]->mBtnPosX + TBD_BTN_SUB_START_X; + INT32 off_y = m_pStationList[i]->mBtnPosY + TBD_BTN_SUB_START_Y; + + COLORREF color = TBD_BTN_GROUP_LINE_BASE_COLOR; + if(m_pStationList[i]->m_pButton->m_bChecked) + color = TBD_BTN_GROUP_LINE_CHECK_COLOR; + + m_pMemDC->Draw3dRect(rect.left + off_x, rect.top + off_y, rect.right - rect.left, rect.bottom - rect.top, color, color); + m_pMemDC->Draw3dRect(rect.left + off_x - 1, rect.top + off_y - 1, rect.right - rect.left + 2, rect.bottom - rect.top + 2, color, color); + } +#endif + } + } + + //m_pMemDC->Draw3dRect(100, 100, 700, 600, RGB(255, 0, 0), RGB(255, 0, 0)); + if (m_bIsFullHD) { + m_ciSymbol.Draw(m_pMemDC->GetSafeHdc(), 490 + 250, 18); + } else { + m_ciSymbol.Draw(m_pMemDC->GetSafeHdc(), 490, 18); + } + dc.BitBlt(0, 0, m_iScreenWidth, m_iScreenHeight, m_pMemDC, 0, 0, SRCCOPY); + m_pMemDC->SelectObject(pOldPen); + m_pMemDC->SelectObject(pOldBitmap); + + CDialogEx::OnPaint(); + } +} + +// ڰ ּȭ â ȿ Ŀ ǥõǵ ýۿ +// Լ ȣմϴ. +HCURSOR CTouchBoardDlg::OnQueryDragIcon() +{ + return static_cast(m_hIcon); +} + +in_addr* CTouchBoardDlg::atoaddr(char *address) +{ + struct hostent *host; + static struct in_addr saddr; + + /* First try it as aaa.bbb.ccc.ddd. */ + saddr.s_addr = inet_addr(address); + if (saddr.s_addr != (unsigned long)-1) { + return &saddr; + } + + host = gethostbyname(address); + if (host != NULL) { + return (struct in_addr *) *host->h_addr_list; + } + + return NULL; +} + +SOCKET CTouchBoardDlg::ConnectRequest(char *pAddress, int port) + { + SOCKET sock; + int iResult; + sockaddr_in address; + in_addr *pAddr; + + sock = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED); + pAddr = atoaddr(pAddress); + + memset((char *) &address, 0, sizeof(address)); + address.sin_family = AF_INET; + address.sin_port = htons(m_port); + address.sin_addr.s_addr = pAddr->s_addr; + + char optval = 1; + int ret = setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, &optval, sizeof(int)); + ret = setsockopt(sock, IPPROTO_TCP, SO_KEEPALIVE, &optval, sizeof(int)); + + unsigned long iMode = 1; + iResult = ioctlsocket(sock, FIONBIO, &iMode); // Socket to NON BLOCKING + if (iResult != NO_ERROR) + { + printf("ioctlsocket failed with error: %ld\n", iResult); + } + + iResult = connect(sock, (sockaddr *)&address, sizeof(address)); + if(iResult == SOCKET_ERROR) + { + TIMEVAL Timeout; + Timeout.tv_sec = 0; + Timeout.tv_usec = 100000; + +#if 0 + iMode = 0; + iResult = ioctlsocket(sock, FIONBIO, &iMode); // Socket to BLOCKING + if (iResult != NO_ERROR) + { + printf("ioctlsocket failed with error: %ld\n", iResult); + } +#endif + + fd_set Write, Err; + for(int i = 0;i < 20;i++) { + FD_ZERO(&Write); + FD_ZERO(&Err); + FD_SET(sock, &Write); + FD_SET(sock, &Err); + + // check if the socket is ready + select(0,NULL,&Write,&Err,&Timeout); + if(FD_ISSET(sock, &Write)) + return sock; + if(!m_bIsActive) { + break; + } + } + closesocket(sock); + sock = INVALID_SOCKET; + } + + return sock; + } + +INT32 CTouchBoardDlg::SocketSendExceptionHandle(char *sendData, int datasize) +{ + INT32 ret = 0; + m_sockMutex.Lock(); + if(m_sendSize > 0) { + memcpy(m_sendBuffer + m_sendSize, sendData, datasize); + m_sendSize += datasize; + ret = datasize; + } else { + INT32 size = SocketSend(sendData, datasize); + if((size > 0 && size < datasize) || size == 0) { + memcpy(m_sendBuffer + m_sendSize, sendData + size, datasize - size); + m_sendSize += (datasize - size); + ret = datasize; + } + } + m_sockMutex.Unlock(); + return ret; +} + +INT32 CTouchBoardDlg::SocketSend(char *sendData, int datasize) +{ + fd_set tabSocketToWait; + struct timeval timeout; + int status; + int connect_timeout = 1; + int sock = m_sock; + + FD_ZERO(&tabSocketToWait); + FD_SET(sock,&tabSocketToWait); + timeout.tv_sec = connect_timeout/1000; + timeout.tv_usec = (connect_timeout%1000) * 1000; + + status = select(sock+1, + (fd_set *)0, + &tabSocketToWait, + (fd_set *)0, + &timeout); + + if(status > 0) + { + status = send(sock, sendData, datasize, 0); + if(status < 0) + { + if(errno == EAGAIN || errno == EWOULDBLOCK) + return 0; + else + { + perror("++++++++++++++++++++++++++++ socket Recv"); + return -1; + } + } + + return status; + } + + return 0; +} + + +void CTouchBoardDlg::UpdateSubGroupList() +{ + for(INT32 i = 0;i < m_stationCount;i++) + { + if(m_pStationList[i]->mLevel == 3) + { + for(INT32 j = 0;j < m_stationCount;j++) { + if(m_pStationList[j]->mUpWardId == m_pStationList[i]->mWardId && m_pStationList[j]->mLevel > m_pStationList[i]->mLevel) { + m_pStationList[j]->mSubGroupId = m_pStationList[i]->mWardId; + m_pStationList[i]->mSubCount++; + } + } + } + } + + for(INT32 i = 0;i < m_stationCount;i++) + { + if(m_pStationList[i]->mLevel == 2) + { + for(INT32 j = 0;j < m_stationCount;j++) { + if(m_pStationList[j]->mUpWardId == m_pStationList[i]->mWardId && m_pStationList[j]->mSubCount == 0 && m_pStationList[j]->mLevel > m_pStationList[i]->mLevel) { + m_pStationList[j]->mSubGroupId = m_pStationList[i]->mWardId; + m_pStationList[i]->mSubCount++; + } + } + } + } + + /* + for(INT32 i = 0;i < m_stationCount;i++) + { + if(m_pStationList[i]->mLevel == 1) + { + for(INT32 j = 0;j < m_stationCount;j++) { + if(m_pStationList[j]->mUpWardId == m_pStationList[i]->mWardId && m_pStationList[j]->mSubCount == 0) { + m_pStationList[j]->mSubGroupId = m_pStationList[i]->mWardId; + m_pStationList[i]->mSubCount++; + } + } + } + } + */ +} + +void CTouchBoardDlg::CalcButtonPositioning() +{ + for(INT32 iGrp = 0;iGrp < m_iGroupBtnCount;iGrp++) + { + INT32 iGrpRow = 0; + INT32 iSubGrpIdx = 0; + +#if TBD_BUTTON_UI_STYLE == 1 + for(INT32 i = 0;i < m_stationCount;i++) + { + if(m_pStationList[i]->mGroupIdx == iGrp) + { + if(m_pStationList[i]->mLevel == 2) + { + if(m_pStationList[i]->m_pButton == NULL) { + m_pStationList[i]->m_pButton = new CTouchButton; + m_pStationList[i]->m_pButton->m_bEnabled = TRUE; + } + m_pStationList[i]->m_pButton->m_strName = m_pStationList[i]->mNickName + L"Ȳ"; + m_pStationList[i]->mBtnPosX = 0; + m_pStationList[i]->mBtnPosY = 0; + + if(m_pStationList[i]->mSubCount > 0) + { + INT32 btnIdx = 0; + for(INT32 j = 0;j < m_stationCount;j++) + { + if(m_pStationList[j]->mSubGroupId == m_pStationList[i]->mWardId) { + + INT32 row, column; + row = btnIdx / TBD_BTN_SUB_COLUMN_SIZE; + column = btnIdx % TBD_BTN_SUB_COLUMN_SIZE; + + if(m_pStationList[j]->m_pButton == NULL) { + m_pStationList[j]->m_pButton = new CTouchButton; + m_pStationList[i]->m_pButton->m_bEnabled = TRUE; + } + m_pStationList[j]->m_pButton->m_strName = m_pStationList[j]->mNickName; + m_pStationList[j]->mBtnPosX = TBD_BTN_SUB_START_X + (TBD_BTN_WIDTH + 10) * column; + m_pStationList[j]->mBtnPosY = (TBD_BTN_HEIGHT + 5) * row; + //m_pStationList[j]->m_pButton->m_bVisible = false; + + btnIdx++; + } + } + + m_pStationList[i]->m_pButton->m_iBtnFlag |= TOUCH_BTN_FLAG_CHECKABLE; + m_pStationList[i]->mGroupBox.left = -TBD_BTN_SUB_MARGIN_X; + m_pStationList[i]->mGroupBox.top = -TBD_BTN_SUB_MARGIN_Y; + if(m_pStationList[i]->mSubCount < TBD_BTN_SUB_COLUMN_SIZE) { + m_pStationList[i]->mGroupBox.right = TBD_BTN_SUB_START_X + (TBD_BTN_WIDTH + 10) * (m_pStationList[i]->mSubCount - 1) + TBD_BTN_WIDTH + TBD_BTN_SUB_MARGIN_X; + m_pStationList[i]->mGroupBox.bottom = TBD_BTN_HEIGHT + TBD_BTN_SUB_MARGIN_Y; + } else { + m_pStationList[i]->mGroupBox.right = TBD_BTN_SUB_START_X + (TBD_BTN_WIDTH + 10) * (TBD_BTN_SUB_COLUMN_SIZE - 1) + TBD_BTN_WIDTH + TBD_BTN_SUB_MARGIN_X; + m_pStationList[i]->mGroupBox.bottom = TBD_BTN_HEIGHT + (TBD_BTN_HEIGHT + 5) * ((m_pStationList[i]->mSubCount - 1) / TBD_BTN_SUB_COLUMN_SIZE) + TBD_BTN_SUB_MARGIN_Y; + } + + iGrpRow += ((btnIdx - 1) / TBD_BTN_SUB_COLUMN_SIZE) + 1; + } + + iSubGrpIdx++; + } + + + if(m_pStationList[i]->mLevel == 3 && m_pStationList[i]->mSubCount > 0) + { + if(m_pStationList[i]->m_pButton == NULL) { + m_pStationList[i]->m_pButton = new CTouchButton; + m_pStationList[i]->m_pButton->m_bEnabled = TRUE; + } + m_pStationList[i]->m_pButton->m_strName = m_pStationList[i]->mNickName; + m_pStationList[i]->mBtnPosX = 0; + m_pStationList[i]->mBtnPosY = (TBD_BTN_HEIGHT + 5) * iGrpRow + 20 * iSubGrpIdx; + + if(m_pStationList[i]->mSubCount > 0) + { + INT32 btnIdx = 0; + for(INT32 j = 0;j < m_stationCount;j++) + { + if(m_pStationList[j]->mUpWardId == m_pStationList[i]->mWardId) { + + INT32 row, column; + row = btnIdx / TBD_BTN_SUB_COLUMN_SIZE; + column = btnIdx % TBD_BTN_SUB_COLUMN_SIZE; + + if(m_pStationList[j]->m_pButton == NULL) { + m_pStationList[j]->m_pButton = new CTouchButton; + m_pStationList[i]->m_pButton->m_bEnabled = TRUE; + } + m_pStationList[j]->m_pButton->m_strName = m_pStationList[j]->mNickName; + m_pStationList[j]->mBtnPosX = TBD_BTN_SUB_START_X + (TBD_BTN_WIDTH + 10) * column; + m_pStationList[j]->mBtnPosY = (TBD_BTN_HEIGHT + 5) * (iGrpRow + row) + 20 * iSubGrpIdx; + m_pStationList[j]->m_pButton->m_bVisible = false; + + btnIdx++; + } + } + + m_pStationList[i]->m_pButton->m_iBtnFlag |= TOUCH_BTN_FLAG_CHECKABLE; + m_pStationList[i]->mGroupBox.left = -TBD_BTN_SUB_MARGIN_X; + m_pStationList[i]->mGroupBox.top = -TBD_BTN_SUB_MARGIN_Y; + if(m_pStationList[i]->mSubCount < TBD_BTN_SUB_COLUMN_SIZE) { + m_pStationList[i]->mGroupBox.right = TBD_BTN_SUB_START_X + (TBD_BTN_WIDTH + 10) * (m_pStationList[i]->mSubCount - 1) + TBD_BTN_WIDTH + TBD_BTN_SUB_MARGIN_X; + m_pStationList[i]->mGroupBox.bottom = TBD_BTN_HEIGHT + TBD_BTN_SUB_MARGIN_Y; + } else { + m_pStationList[i]->mGroupBox.right = TBD_BTN_SUB_START_X + (TBD_BTN_WIDTH + 10) * (TBD_BTN_SUB_COLUMN_SIZE - 1) + TBD_BTN_WIDTH + TBD_BTN_SUB_MARGIN_X; + m_pStationList[i]->mGroupBox.bottom = TBD_BTN_HEIGHT + (TBD_BTN_HEIGHT + 5) * ((m_pStationList[i]->mSubCount - 1) / TBD_BTN_SUB_COLUMN_SIZE) + TBD_BTN_SUB_MARGIN_Y; + } + + iGrpRow += ((btnIdx - 1) / 5) + 1; + iSubGrpIdx++; + } + } + } + + //if(m_pStationList[i]->m_pButton) + // m_pStationList[i]->m_pButton->m_bEnabled = TRUE; + } +#else + /* Sorting for NickName Index */ + for(INT32 i = 0;i < m_stationCount;i++) + { + if(m_pStationList[i]->mGroupIdx == iGrp && m_pStationList[i]->mNickIndex >= 0) + { + for(INT32 j = i + 1;j < m_stationCount;j++) { + if(m_pStationList[j]->mGroupIdx == iGrp && m_pStationList[j]->mNickIndex >= 0 && m_pStationList[j]->mNickIndex < m_pStationList[i]->mNickIndex) { + CStationInfo* pTemp = m_pStationList[j]; + m_pStationList[j] = m_pStationList[i]; + m_pStationList[i] = pTemp; + } + } + } + } + + + INT32 iGroupRowCount = 0; + for (INT32 i = 0; i < m_stationCount; i++) + { + if (m_pStationList[i]->mGroupIdx == iGrp) + { +#if TBD_BUTTON_UI_STYLE == 2 + if (m_pStationList[i]->mLevel == 2 && m_pStationList[i]->mStationId > 0) + //if(m_pStationList[i]->mLevel == 2) +#else + if (m_pStationList[i]->mLevel == 2) +#endif + { + iGroupRowCount++; + iSubGrpIdx++; + } + + if (m_pStationList[i]->mLevel == 3) + { + if (m_pStationList[i]->mSubCount > 0) + { + INT32 btnIdx = 0; + for (INT32 j = 0; j < m_stationCount; j++) + { + if (m_pStationList[j]->mUpWardId == m_pStationList[i]->mWardId) { + btnIdx++; + } + } + + iGroupRowCount += ((btnIdx - 1) / 5) + 1; + iSubGrpIdx++; + } + else { + iGroupRowCount++; + iSubGrpIdx++; + } + } + } + } + iSubGrpIdx = 0; + + + INT32 i_sub_column_size = TBD_BTN_SUB_COLUMN_SIZE; + if (m_bIsFullHD) { + i_sub_column_size = 9; + } + + for(INT32 i = 0;i < m_stationCount;i++) + { + if(m_pStationList[i]->mGroupIdx == iGrp) + { + #if TBD_BUTTON_UI_STYLE == 2 + if(m_pStationList[i]->mLevel == 2 && m_pStationList[i]->mStationId > 0) + //if(m_pStationList[i]->mLevel == 2) + #else + if(m_pStationList[i]->mLevel == 2) + #endif + { + if(m_pStationList[i]->m_pButton == NULL) { + m_pStationList[i]->m_pButton = new CTouchButton; + m_pStationList[i]->m_pButton->m_bEnabled = TRUE; + } + m_pStationList[i]->m_pButton->m_strName = m_pStationList[i]->mNickName + L"Ȳ"; + m_pStationList[i]->mBtnPosX = 0; + m_pStationList[i]->mBtnPosY = 0; + m_pStationList[i]->mSubCount = 0; + m_pStationList[i]->mBtnGroupRow = iGrpRow; + + m_pStationList[i]->m_pButton->m_iBtnFlag |= TOUCH_BTN_FLAG_CHECKABLE; + m_pStationList[i]->mGroupBox.left = -TBD_BTN_SUB_MARGIN_X; + m_pStationList[i]->mGroupBox.top = -TBD_BTN_SUB_MARGIN_Y; + //m_pStationList[i]->mGroupBox.right = TBD_BTN_WIDTH + TBD_BTN_SUB_MARGIN_X; + m_pStationList[i]->mGroupBox.right = TBD_BTN_SUB_START_X + (TBD_BTN_WIDTH + 10) * (i_sub_column_size - 1) + TBD_BTN_WIDTH + TBD_BTN_SUB_MARGIN_X; + m_pStationList[i]->mGroupBox.bottom = TBD_BTN_HEIGHT + TBD_BTN_SUB_MARGIN_Y; + + iGrpRow++; + iSubGrpIdx++; + } + + if(m_pStationList[i]->mLevel == 3) + { + if(m_pStationList[i]->m_pButton == NULL) { + m_pStationList[i]->m_pButton = new CTouchButton; + m_pStationList[i]->m_pButton->m_bEnabled = TRUE; + } + m_pStationList[i]->m_pButton->m_strName = m_pStationList[i]->mNickName; + m_pStationList[i]->mBtnPosX = 0; + m_pStationList[i]->mBtnPosY = (TBD_BTN_HEIGHT + 5) * iGrpRow + TBD_BTN_GROUP_MARGIN_Y * iSubGrpIdx; + m_pStationList[i]->mBtnGroupRow = iGrpRow; + + if(m_pStationList[i]->mSubCount > 0) + { + INT32 btnIdx = 0; + for(INT32 j = 0;j < m_stationCount;j++) + { + if(m_pStationList[j]->mUpWardId == m_pStationList[i]->mWardId) { + + INT32 row, column; + row = btnIdx / i_sub_column_size; + column = btnIdx % i_sub_column_size; + + if(m_pStationList[j]->m_pButton == NULL) { + m_pStationList[j]->m_pButton = new CTouchButton; + m_pStationList[i]->m_pButton->m_bEnabled = TRUE; + } + m_pStationList[j]->m_pButton->m_strName = m_pStationList[j]->mNickName; + m_pStationList[j]->mBtnPosX = TBD_BTN_SUB_START_X + (TBD_BTN_WIDTH + 10) * column; + m_pStationList[j]->mBtnPosY = (TBD_BTN_HEIGHT + 5) * (iGrpRow + row) + TBD_BTN_GROUP_MARGIN_Y * iSubGrpIdx; + m_pStationList[j]->mBtnGroupRow = iGrpRow; + m_pStationList[j]->m_pButton->m_bVisible = false; + + btnIdx++; + } + } + + m_pStationList[i]->m_pButton->m_iBtnFlag |= TOUCH_BTN_FLAG_CHECKABLE; + m_pStationList[i]->mGroupBox.left = -TBD_BTN_SUB_MARGIN_X; + m_pStationList[i]->mGroupBox.top = -TBD_BTN_SUB_MARGIN_Y; + if(m_pStationList[i]->mSubCount < i_sub_column_size) { + //m_pStationList[i]->mGroupBox.right = TBD_BTN_SUB_START_X + (TBD_BTN_WIDTH + 10) * (m_pStationList[i]->mSubCount - 1) + TBD_BTN_WIDTH + TBD_BTN_SUB_MARGIN_X; + m_pStationList[i]->mGroupBox.right = TBD_BTN_SUB_START_X + (TBD_BTN_WIDTH + 10) * (i_sub_column_size - 1) + TBD_BTN_WIDTH + TBD_BTN_SUB_MARGIN_X; + m_pStationList[i]->mGroupBox.bottom = TBD_BTN_HEIGHT + TBD_BTN_SUB_MARGIN_Y; + } else { + m_pStationList[i]->mGroupBox.right = TBD_BTN_SUB_START_X + (TBD_BTN_WIDTH + 10) * (i_sub_column_size - 1) + TBD_BTN_WIDTH + TBD_BTN_SUB_MARGIN_X; + m_pStationList[i]->mGroupBox.bottom = TBD_BTN_HEIGHT + (TBD_BTN_HEIGHT + 5) * ((m_pStationList[i]->mSubCount - 1) / i_sub_column_size) + TBD_BTN_SUB_MARGIN_Y; + } + + iGrpRow += ((btnIdx - 1) / i_sub_column_size) + 1; + iSubGrpIdx++; + } else { + m_pStationList[i]->m_pButton->m_iBtnFlag |= TOUCH_BTN_FLAG_CHECKABLE; + m_pStationList[i]->mGroupBox.left = -TBD_BTN_SUB_MARGIN_X; + m_pStationList[i]->mGroupBox.top = -TBD_BTN_SUB_MARGIN_Y; + //m_pStationList[i]->mGroupBox.right = TBD_BTN_WIDTH + TBD_BTN_SUB_MARGIN_X; + m_pStationList[i]->mGroupBox.right = TBD_BTN_SUB_START_X + (TBD_BTN_WIDTH + 10) * (i_sub_column_size - 1) + TBD_BTN_WIDTH + TBD_BTN_SUB_MARGIN_X; + m_pStationList[i]->mGroupBox.bottom = TBD_BTN_HEIGHT + TBD_BTN_SUB_MARGIN_Y; + + iGrpRow++; + iSubGrpIdx++; + } + } + + if (iGroupRowCount > 12) { + if ((m_pStationList[i]->mSubCount < 1 && m_pStationList[i]->mBtnGroupRow == 0) || iGrpRow > 12) { + //m_pStationList[i]->mGroupBox.right = TBD_BTN_SUB_START_X + TBD_BTN_WIDTH + TBD_BTN_SUB_MARGIN_X; + m_pStationList[i]->mGroupBox.right = TBD_BTN_WIDTH + TBD_BTN_SUB_MARGIN_X; + + if (iGrpRow > 12 && m_pStationList[i]->mLevel <= 3) { + INT32 rowIndex = -1; + for (INT32 j = 0; j < m_stationCount; j++) + { + if (m_pStationList[j]->mGroupIdx == iGrp && m_pStationList[j]->mBtnGroupRow < iGrpRow && m_pStationList[j]->mSubCount < 2) { + BOOL exist = false; + for (INT32 k = 0; k < m_stationCount; k++) { + if (m_pStationList[k]->mBtnShiftRow == m_pStationList[j]->mBtnGroupRow) { + exist = true; + break; + } + } + if (!exist) { + rowIndex = m_pStationList[j]->mBtnGroupRow; + break; + } + } + } + + if (rowIndex >= 0) { + m_pStationList[i]->mBtnShiftRow = rowIndex; + //m_pStationList[i]->mBtnPosX += 648; + //m_pStationList[i]->mBtnPosY = (TBD_BTN_HEIGHT + 5) * rowIndex + TBD_BTN_GROUP_MARGIN_Y * rowIndex; + m_pStationList[i]->mBtnPosX += (TBD_BTN_WIDTH + TBD_BTN_SUB_MARGIN_X * 3) * (rowIndex + 1); + m_pStationList[i]->mBtnPosY = 0; + + for (INT32 j = 0; j < m_stationCount; j++) + { + if (m_pStationList[j]->mUpWardId == m_pStationList[i]->mWardId) { + m_pStationList[j]->mBtnPosX += 648; + m_pStationList[j]->mBtnShiftRow = rowIndex; + m_pStationList[j]->mBtnPosY = (TBD_BTN_HEIGHT + 5) * (rowIndex) + TBD_BTN_GROUP_MARGIN_Y * rowIndex; + } + } + } + } + } + } + } + + } + +#endif + } +} + +void CTouchBoardDlg::UpdateTouchButtonList() +{ + int idx = 0; + int row, column; + + int column_cut_base = 9; + int column_count = (m_iGroupBtnCount + 1) / 2; + double btn_width = TBD_BTN_WIDTH; + int grp_btn_height = TBD_BTN_HEIGHT; + int grp_btn_start_y = TBD_BTN_GROUP_START_Y; + int grp_btn_padding = 10; + + if (m_bIsFullHD) { + column_cut_base = 14; + } + +#if TBD_USE_THREELINE_GROUP == 1 +#if USE_ROUND_BUTTON2 + if(column_count <= column_cut_base) { + //btn_width *= ((double)(10.0 - (column_count - 6) * 1.5) / 10.0); + if (m_bIsFullHD) { + //btn_width = (double)1538.0 / (double)column_count; + btn_width = (double)1664.0 / (double)column_count; + grp_btn_height *= 1.1; + grp_btn_start_y *= 0.88; + } else { + //btn_width = 940 / column_count; + btn_width = 1024.0 / column_count; + grp_btn_height *= 1.1; + grp_btn_start_y *= 0.88; + if (btn_width > TBD_BTN_WIDTH) + btn_width = TBD_BTN_WIDTH; + } + + } else if(column_count > column_cut_base) { + column_count = column_cut_base; + //btn_width *= ((double)(10.0 - (column_count - 6) * 1.5) / 10.0); + //btn_width = 940 / column_count; + btn_width = 1024.0 / column_count; + if (btn_width > TBD_BTN_WIDTH) + btn_width = TBD_BTN_WIDTH; + grp_btn_padding = 5; + grp_btn_height *= 0.9; + grp_btn_start_y *= 0.78; + } +#else + if (column_count <= 7) { + //btn_width *= ((double)(10.0 - (column_count - 6) * 1.5) / 10.0); + btn_width = 900 / column_count; + if (btn_width > TBD_BTN_WIDTH) + btn_width = TBD_BTN_WIDTH; + + } + else if (column_count > 7) { + column_count = 7; + //btn_width *= ((double)(10.0 - (column_count - 6) * 1.5) / 10.0); + btn_width = 900 / column_count; + if (btn_width > TBD_BTN_WIDTH) + btn_width = TBD_BTN_WIDTH; + grp_btn_padding = 5; + grp_btn_height *= 0.9; + grp_btn_start_y *= 0.78; + } +#endif + + +#else + if(column_count > 6) { + btn_width *= ((double)(10 - (column_count - 6) * 1.5) / 10.0); + } +#endif + + row = 0; + column = 0; + for(INT32 i = 0;i < m_stationCount;i++) + { + if(m_pStationList[i]->mLevel == 2) + { + row = idx / column_count; + column = idx % column_count; + if(m_pGroupBtn[idx]) { + m_pGroupBtn[idx]->DestroyWindow(); + delete m_pGroupBtn[idx]; + m_pGroupBtn[idx] = NULL; + } + m_pGroupBtn[idx] = new CTouchButton; + m_pGroupBtn[idx]->m_pFont = &m_castFont; + m_pGroupBtn[idx]->m_iBtnType = TOUCH_BTN_TYPE_GROUP; + m_pGroupBtn[idx]->m_uiPressMessage = WM_TBD_GROUP_PUSH; + m_pGroupBtn[idx]->m_strName = m_pStationList[i]->mNickName; + m_pGroupBtn[idx]->initialize((double)TBD_BTN_GROUP_START_X + (btn_width) * (double)column, grp_btn_start_y + (grp_btn_height + grp_btn_padding) * row, btn_width - 10, grp_btn_height, 0, 0, m_pStationList[i]->mWardId, this); + idx++; + } + + if(m_pStationList[i]->m_pButton) + { + if(m_pStationList[i]->mStationId == 0) + m_pStationList[i]->m_pButton->m_bPressable = false; + + if(m_pStationList[i]->mNickName.GetLength() < 10) + m_pStationList[i]->m_pButton->m_pFont = &m_btnFont; + else + m_pStationList[i]->m_pButton->m_pFont = &m_btnSmallFont; + m_pStationList[i]->m_pButton->m_pFontSub = &m_btnUnderFont; + m_pStationList[i]->m_pButton->initialize(TBD_BTN_SUB_START_X + m_pStationList[i]->mBtnPosX, TBD_BTN_SUB_START_Y + m_pStationList[i]->mBtnPosY, TBD_BTN_WIDTH, TBD_BTN_HEIGHT, 0/*TBD_BTN_ICON_WIDTH*/, 0/*TBD_BTN_ICON_HEIGHT*/, m_pStationList[i]->mWardId, this); + m_pStationList[i]->m_pButton->ShowWindow(SW_HIDE); + } + } + + Invalidate(false); +} + +void CTouchBoardDlg::MoveWindowDirection(CWnd *pWnd, INT32 xpos, INT32 ypos) +{ + CRect rt; + + pWnd->GetWindowRect(&rt); + pWnd->GetParent()->ScreenToClient(rt); + + rt.left += xpos; + rt.top += ypos; + rt.right += xpos; + rt.bottom += ypos; + pWnd->MoveWindow(&rt); + pWnd->Invalidate(FALSE); +} + +static int findNumberFromString(char *pString) +{ + int len; + int i; + int value = -1; + if(pString == NULL) + return -1; + + len = strlen(pString); + for(i = 0;i < len;i++) { + if(pString[i] >= '0' && pString[i] <= '9') { + value = atoi(&pString[i]); + break; + } + } + + return value; +} + + +INT32 CTouchBoardDlg::PacketDizest(char *pBuffer) +{ + char *pData; + char *pToken; + char *pTokenSub; + char *pTokenNext; + + INT32 station_idx = -1; + INT32 command = 0; + INT32 subIndex = 0; + INT32 launcherIdx = 0; + +#if USE_DO_PACKET_DUMP + static int packetCount = 0; + char packetFile[128]; + sprintf(packetFile, "packet-%03d.txt", packetCount); + packetCount++; + FILE *fp; + fp = fopen(packetFile, "wt"); + if (fp) { + fwrite(pBuffer, 1, strlen(pBuffer), fp); + fclose(fp); + } +#endif + + pToken = strstr(pBuffer, "\r\n\r\n"); + if(!pToken) + return 0; + INT32 len = ((INT32)(pToken - pBuffer)) + 4; + + pData = new char[len + 1]; + ZeroMemory(pData, len + 1); + memcpy(pData, pBuffer, len); + + pToken = pData; + + m_infoMutex.Lock(); + while((pTokenNext = strstr(pToken, "\r\n"))) + { + *pTokenNext = 0; + + if(!strncmp(pToken, "MESSAGE_TYPE=", strlen("MESSAGE_TYPE="))) + { + pToken += strlen("MESSAGE_TYPE="); + + if(!strcmp(pToken, "INFORM-STATIONS")) { + TRACE("Handle INFORM-STATIONS. %d bytes.\n", len); + command = TBD_SERVER_COMMAND_STATION_INFORM; + station_idx = 0; + m_iGroupBtnCount = 0; + } else if(!strcmp(pToken, "NOTIFY")) { + TRACE("Handle NOTIFICATION. %d bytes.\n", len); + command = TBD_SERVER_COMMAND_STATION_NOTIFY; + m_strWardId = ""; + } else if(!strcmp(pToken, "CAST_STATUS")) { + command = TBD_SERVER_COMMAND_CAST_STATUS; + } else if(!strcmp(pToken, "DEVICE_STATUS")) { + command = TBD_SERVER_COMMAND_DEVICE_STATUS; + } + } + else if(!strncmp(pToken, "POSITION=", strlen("POSITION="))) + { + pToken += strlen("POSITION="); + } + else if(!strncmp(pToken, "MIC_VOLUME=", strlen("MIC_VOLUME="))) + { + pToken += strlen("MIC_VOLUME="); + CString strValue; + strValue = pToken; + m_setupDlg.GetDlgItem(IDC_STATIC_MICVOL_VALUE)->SetWindowTextW(strValue + L"/12"); + } + else if(!strncmp(pToken, "LINEIN_VOLUME=", strlen("LINEIN_VOLUME="))) + { + pToken += strlen("LINEIN_VOLUME="); + CString strValue; + strValue = pToken; + m_setupDlg.GetDlgItem(IDC_STATIC_LINEVOL_VALUE)->SetWindowTextW(strValue + L"/12"); + } + else if(!strncmp(pToken, "SPK_VOLUME=", strlen("SPK_VOLUME="))) + { + pToken += strlen("SPK_VOLUME="); + CString strValue; + INT32 curValue, maxValue, ret; + strValue = pToken; + ret = sscanf(pToken, "%d/%d", &curValue, &maxValue); + if(ret == 1) { + strValue = curValue + L"/15"; + } + GetDlgItem(IDC_STATIC_SPKVOL_VALUE)->SetWindowTextW(strValue); + } + + switch(command) + { + case TBD_SERVER_COMMAND_STATION_INFORM: + if(!strncmp(pToken, "WID_", strlen("WID_"))) { + if(m_pStationList[station_idx] == NULL) { + m_pStationList[station_idx] = new CStationInfo; + m_pStationList[station_idx]->m_pButton = NULL; + } + pTokenSub = strchr(pToken, '='); + m_pStationList[station_idx]->mGroupIdx = atoi(pToken + strlen("WID_")); + m_pStationList[station_idx]->mWardId = atoi(pTokenSub + 1); + m_pStationList[station_idx]->mLevel = 2; + m_pStationList[station_idx]->mUpWardId = 0; + m_pStationList[station_idx]->mSubCount = 0; + m_pStationList[station_idx]->mSubGroupId = 0; + m_pStationList[station_idx]->mBtnShiftRow = -1; + if(m_iGroupBtnCount < TBD_MAX_GROUP_COUNT) // added by ritoseo - 2022-01-20 + m_iGroupBtnCount++; + TRACE(L"WARD ID : %d\n", m_pStationList[station_idx]->mWardId); + } else if(!strncmp(pToken, "NICK_", strlen("NICK_"))) { + int ret, index; + char strDummy[128]; + UTF8_CONVERSION_EX; + pTokenSub = strchr(pToken, '='); + ret = sscanf(pTokenSub + 1, "%d.%s", &index, strDummy); + if(ret == 2) { + m_pStationList[station_idx]->mNickName = UTF82A_EX(strDummy); + m_pStationList[station_idx]->mNickIndex = index; + } else { + m_pStationList[station_idx]->mNickIndex = -1; + m_pStationList[station_idx]->mNickName = UTF82A_EX(pTokenSub + 1); + } + } else if(!strncmp(pToken, "IPADDR_", strlen("IPADDR_"))) { + pTokenSub = strchr(pToken, '='); + m_pStationList[station_idx]->mIpAddr = (pTokenSub + 1); + } else if(!strncmp(pToken, "SID_", strlen("SID_"))) { + pTokenSub = strchr(pToken, '='); + m_pStationList[station_idx]->mStationId = atoi(pTokenSub + 1); + } else if(!strncmp(pToken, "FIN", strlen("FIN"))) { + station_idx++; + } else if(!strncmp(pToken, "START", strlen("START"))) { + } else if(!strncmp(pToken, "END", strlen("END"))) { + m_stationCount = station_idx; + UpdateSubGroupList(); + CalcButtonPositioning(); + AfxGetMainWnd()->PostMessage(WM_TBD_UPDATE_GROUP); + //UpdateTouchButtonList(); + TRACE(L"Total Station Count : %d\n", m_stationCount); + + CString strOrder; + strOrder = "BYPASS\r\n"; + strOrder += "REQUEST=CAST_STATUS\r\n"; + strOrder += "CVI_NO="; + strOrder += m_strCviNo; + strOrder += "\r\n"; + strOrder += "\r\n"; + + char *pSendBuffer; + UTF8_CONVERSION_EX; + pSendBuffer = W2UTF8_EX(strOrder); + SocketSendExceptionHandle(pSendBuffer, strlen(pSendBuffer)); + } else if(!strncmp(pToken, "SUB_", strlen("SUB_"))) { + pTokenSub = strstr(pToken, "::"); + int grpIdx = atoi(pToken + strlen("SUB_")); + + pToken = pTokenSub + 2; + if(!strncmp(pToken, "WID_", strlen("WID_"))) { + if(m_pStationList[station_idx] == NULL) { + m_pStationList[station_idx] = new CStationInfo; + m_pStationList[station_idx]->m_pButton = NULL; + } + pTokenSub = strchr(pToken, '='); + m_pStationList[station_idx]->mGroupIdx = grpIdx; + m_pStationList[station_idx]->mWardId = atoi(pTokenSub + 1); + m_pStationList[station_idx]->mSubCount = 0; + m_pStationList[station_idx]->mBtnShiftRow = -1; + //TRACE(L"SUB WARD ID : %d\n", m_pStationList[station_idx]->mWardId); + } else if(!strncmp(pToken, "NICK_", strlen("NICK_"))) { + int ret, index; + char strDummy[128]; + UTF8_CONVERSION_EX; + pTokenSub = strchr(pToken, '='); + ret = sscanf(pTokenSub + 1, "%d.%s", &index, strDummy); + if(ret == 2) { + m_pStationList[station_idx]->mNickName = UTF82A_EX(strDummy); + m_pStationList[station_idx]->mNickIndex = index; + } else { + m_pStationList[station_idx]->mNickIndex = -1; + m_pStationList[station_idx]->mNickName = UTF82A_EX(pTokenSub + 1); + } + } else if(!strncmp(pToken, "IPADDR_", strlen("IPADDR_"))) { + pTokenSub = strchr(pToken, '='); + m_pStationList[station_idx]->mIpAddr = (pTokenSub + 1); + } else if(!strncmp(pToken, "SID_", strlen("SID_"))) { + pTokenSub = strchr(pToken, '='); + m_pStationList[station_idx]->mStationId = atoi(pTokenSub + 1); + } else if(!strncmp(pToken, "LV_", strlen("LV_"))) { + pTokenSub = strchr(pToken, '='); + m_pStationList[station_idx]->mLevel = atoi(pTokenSub + 1); + if(m_pStationList[station_idx]->mLevel == 2 || m_pStationList[station_idx]->mLevel == 3) + m_pStationList[station_idx]->mSubGroupId = m_pStationList[station_idx]->mWardId; + } else if(!strncmp(pToken, "UWID_", strlen("UWID_"))) { + pTokenSub = strchr(pToken, '='); + m_pStationList[station_idx]->mUpWardId = atoi(pTokenSub + 1); + } else if(!strncmp(pToken, "FIN", strlen("FIN"))) { + station_idx++; + } + } + break; + + case TBD_SERVER_COMMAND_STATION_NOTIFY: + if(!strncmp(pToken, "DEVICE_NAME=", strlen("DEVICE_NAME="))) { + UTF8_CONVERSION_EX; + pToken += strlen("DEVICE_NAME="); + m_strDeviceName = UTF82A_EX(pToken); + TRACE("RECEIVE DEVICE NAME : %s\n", pToken); + + CString strName; + GetDlgItem(IDC_BUTTON_NAME)->GetWindowTextW(strName); + if(strName != m_strDeviceName) { + GetDlgItem(IDC_BUTTON_NAME)->SetWindowTextW(m_strDeviceName); + } + + Invalidate(false); + } else if(!strncmp(pToken, "CVI_NO=", strlen("CVI_NO="))) { + UTF8_CONVERSION_EX; + pToken += strlen("CVI_NO="); + m_strCviNo = UTF82A_EX(pToken); + } else if(!strncmp(pToken, "WARD_ID=", strlen("WARD_ID="))) { + UTF8_CONVERSION_EX; + pToken += strlen("WARD_ID="); + m_strWardId = UTF82A_EX(pToken); + } + break; + + case TBD_SERVER_COMMAND_CAST_STATUS: + if(!strncmp(pToken, "SID_", strlen("SID_"))) { + char *pTokenSub = strchr(pToken, '='); + pToken += strlen("SID_"); + INT32 station_id = atoi(pToken); + INT32 status = atoi(pTokenSub + 1); + INT32 caller_desk_id = -1; + INT32 caller_cvi_no = -1; + INT32 my_desk_id = -1; + INT32 button_pushed = -1; + + if(m_strWardId.GetLength() == 0 && m_strDeviceName.GetLength() > 0) { + UTF8_CONVERSION_EX; + char *strDeviceName; + strDeviceName = W2UTF8_EX(m_strDeviceName); + my_desk_id = findNumberFromString(strDeviceName); + } + + pTokenSub = strchr(pToken, '|'); + if(pTokenSub) { + caller_desk_id = atoi(pTokenSub + 1); + pTokenSub = strchr(pTokenSub, ','); + if(pTokenSub) { + caller_cvi_no = atoi(pTokenSub + 1); + } + + pTokenSub = strchr(pToken, '/'); + if(pTokenSub) { + button_pushed = atoi(pTokenSub + 1); + } + } + + for(INT32 i = 0;i < m_stationCount;i++) + { + if(m_pStationList[i]->mStationId == station_id && station_id > 0) { + if(status > 0) { + for(INT32 j = 0;j < 4;j++) + m_pStationList[i]->m_pButton->m_bStatus[j] = FALSE; + m_pStationList[i]->m_pButton->m_bStatus[status - 1] = TRUE; + if(button_pushed == 1) { + m_pStationList[i]->m_pButton->m_bStatus[4] = TRUE; + } + m_pStationList[i]->mCallerNo = caller_desk_id; + if(m_pStationList[i]->mCallerCviNo == -1 && caller_cvi_no == _ttoi(m_strCviNo) && caller_cvi_no > 0) { // CT ׷ ڵ ü + if(m_iSelectGroup != m_pStationList[i]->mGroupIdx + && m_pStationList[i]->mGroupIdx < TBD_MAX_GROUP_COUNT + && m_pGroupBtn[m_pStationList[i]->mGroupIdx]) { + AfxGetMainWnd()->PostMessage(WM_TBD_GROUP_PUSH, m_pGroupBtn[m_pStationList[i]->mGroupIdx]->m_btnId); + } + } + + m_pStationList[i]->mCallerCviNo = caller_cvi_no; + m_pStationList[i]->m_pButton->m_iUnderNumber = caller_desk_id; // CTδ δ ȣ ǥ + + if(my_desk_id == caller_desk_id) // CT δ̰ ۽ڰ ڽ ϴܹȣ ǥ X(̸Ƽǥ) + m_pStationList[i]->m_pButton->m_iUnderNumber = -1; + + if(my_desk_id > 0 && caller_desk_id == -1 && caller_cvi_no) { // 뿡 ü Ȯ + m_pStationList[i]->m_pButton->m_iUnderNumber = 0; // 0 : "" ǥ + } + + if(my_desk_id == -1 && button_pushed == 1) // CTڽ ҹ漭̰ ⵿ġ ö ġȲ ǥ + m_pStationList[i]->m_pButton->m_iUnderNumber = -1; + + if(m_pStationList[i]->m_pButton->GetSafeHwnd() > 0) + m_pStationList[i]->m_pButton->Invalidate(FALSE); + } else { + for(INT32 j = 0;j < 5;j++) + m_pStationList[i]->m_pButton->m_bStatus[j] = FALSE; + m_pStationList[i]->m_pButton->m_iUnderNumber = -1; + m_pStationList[i]->mCallerNo = -1; + m_pStationList[i]->mCallerCviNo = -1; + if(m_pStationList[i]->m_pButton->GetSafeHwnd() > 0) + m_pStationList[i]->m_pButton->Invalidate(FALSE); + } + } + } + //m_logEdit.Trace(L"STATION %d = %d, deskid : %d, cvino : %d", station_id, status, caller_desk_id, caller_cvi_no); + } + break; + + case TBD_SERVER_COMMAND_DEVICE_STATUS: + if(!strncmp(pToken, "SID_", strlen("SID_"))) { + char *pTokenSub = strchr(pToken, '='); + pToken += strlen("SID_"); + INT32 station_id = atoi(pToken); + INT32 status = atoi(pTokenSub + 1); + + for(INT32 i = 0;i < m_stationCount;i++) + { + if(m_pStationList[i]->mStationId == station_id && station_id > 0) { + if(status > 0) { + m_pStationList[i]->m_pButton->m_bEnabled = TRUE; + } else { + m_pStationList[i]->m_pButton->m_bEnabled = FALSE; + } + + if(m_pStationList[i]->m_pButton->GetSafeHwnd() != 0) + m_pStationList[i]->m_pButton->Invalidate(FALSE); + } + } + //m_logEdit.Trace(L"STATION %d = %d", station_id, status); + } + break; + + default: + break; + } + + pToken = pTokenNext + 2; + } + m_infoMutex.Unlock(); + + switch(command) + { + case TBD_SERVER_COMMAND_CAST_STATUS: + break; + case TBD_SERVER_COMMAND_STATION_NOTIFY: + if(m_strWardId.GetLength() == 0) // . ü ư ߰ + { + INT32 offset = 50; + if(!GetDlgItem(IDC_BUTTON_CAST_WHOLE)->IsWindowVisible()) + { + GetDlgItem(IDC_BUTTON_CAST_WHOLE)->ShowWindow(SW_SHOW); + + MoveWindowDirection(GetDlgItem(IDC_BUTTON_CAST_WHOLE), 0, offset - 15); + MoveWindowDirection(GetDlgItem(IDC_BUTTON_CAST_ALL), 0, offset); + MoveWindowDirection(GetDlgItem(IDC_BUTTON_CAST_FIRE), 0, offset); + MoveWindowDirection(GetDlgItem(IDC_BUTTON_CAST_RESCUE), 0, offset); + MoveWindowDirection(GetDlgItem(IDC_BUTTON_CAST_EMERGENCY), 0, offset); + MoveWindowDirection(GetDlgItem(IDC_BUTTON_CAST_NORMAL), 0, offset); + MoveWindowDirection(GetDlgItem(IDC_BUTTON_RESTORE), 0, offset); + } + } + else // ҹ漭 CT. ü ư + { + INT32 offset = 50; + if(GetDlgItem(IDC_BUTTON_CAST_WHOLE)->IsWindowVisible()) + { + GetDlgItem(IDC_BUTTON_CAST_WHOLE)->ShowWindow(SW_HIDE); + + MoveWindowDirection(GetDlgItem(IDC_BUTTON_CAST_WHOLE), 0, -(offset - 15)); + MoveWindowDirection(GetDlgItem(IDC_BUTTON_CAST_ALL), 0, -offset); + MoveWindowDirection(GetDlgItem(IDC_BUTTON_CAST_FIRE), 0, -offset); + MoveWindowDirection(GetDlgItem(IDC_BUTTON_CAST_RESCUE), 0, -offset); + MoveWindowDirection(GetDlgItem(IDC_BUTTON_CAST_EMERGENCY), 0, -offset); + MoveWindowDirection(GetDlgItem(IDC_BUTTON_CAST_NORMAL), 0, -offset); + MoveWindowDirection(GetDlgItem(IDC_BUTTON_RESTORE), 0, -offset); + } + } + break; + default: + break; + } + + delete pData; + + return len; +} + + +UINT CTouchBoardDlg::PingCheckThread(LPVOID aParam) +{ + CTouchBoardDlg *pThis = (CTouchBoardDlg *)aParam; + ULONGLONG ullTryTime = 0; + ULONGLONG ullCurTime = 0; + + while (pThis->m_bIsActive) + { + ULONGLONG curTickTime = GetTickCount64(); + + ullCurTime = GetTickCount64(); + if (pThis->m_strPSAddr.GetLength() > 0 && ullCurTime - ullTryTime > 1000) + { + char ipAddr[32] = { 0, }; + INT32 port; + SOCKET sock; + pThis->WideToMultiByte(pThis->m_strPSAddr, ipAddr); + BOOL result = CheckPing(ipAddr); + if (!result) { + pThis->m_pStatusButton[0]->SetColor(RGB(0, 0, 0), RGB(255, 0, 0)); + } else { + pThis->m_pStatusButton[0]->SetColor(RGB(0, 0, 0), STATUS_BTN_GOOD_BACK_COLOR); + } + } + + if (pThis->m_strESAddr.GetLength() > 0 && ullCurTime - ullTryTime > 1000) + { + char ipAddr[32] = { 0, }; + INT32 port; + SOCKET sock; + pThis->WideToMultiByte(pThis->m_strESAddr, ipAddr); + BOOL result = CheckPing(ipAddr); + + if (!result) { + pThis->m_pStatusButton[1]->SetColor(RGB(0, 0, 0), RGB(255, 0, 0)); + } + else { + pThis->m_pStatusButton[1]->SetColor(RGB(0, 0, 0), STATUS_BTN_GOOD_BACK_COLOR); + } + } + + if (ullCurTime - ullTryTime > 2000) { + ullTryTime = ullCurTime; + } + + Sleep(10); + } + + return 0; +} + + +UINT CTouchBoardDlg::SocketConnectionThread(LPVOID aParam) +{ + CTouchBoardDlg *pThis = (CTouchBoardDlg *)aParam; + ULONGLONG ullTryTime = 0; + ULONGLONG ullCurTime = 0; + + while(pThis->m_bIsActive) + { + ULONGLONG curTickTime = GetTickCount64(); + + pThis->m_sockMutex.Lock(); + ullCurTime = GetTickCount64(); + if(pThis->m_sock == INVALID_SOCKET && pThis->m_strServerAddr.GetLength() > 0 && ullCurTime - ullTryTime > 2000) + { + char ipAddr[32] = {0, }; + INT32 port; + SOCKET sock; + pThis->WideToMultiByte(pThis->m_strServerAddr, ipAddr); + ullTryTime = ullCurTime; + + ZeroMemory(&pThis->m_recvBuffer, sizeof(pThis->m_recvBuffer)); + pThis->m_recvSize = 0; + pThis->m_sendSize = 0; + port = pThis->m_port; + + pThis->m_sockMutex.Unlock(); + sock = pThis->ConnectRequest(ipAddr, port); + pThis->m_sockMutex.Lock(); + + pThis->m_sock = sock; + if(pThis->m_sock == INVALID_SOCKET) { + pThis->m_logEdit.Trace(L"[%s] CT ", pThis->m_strServerAddr); + pThis->m_pStatusButton[2]->SetColor(RGB(0, 0, 0), RGB(255, 0, 0)); + } else { + pThis->m_logEdit.Trace(L"[%s] CT ", pThis->m_strServerAddr); + pThis->m_pStatusButton[2]->SetColor(RGB(0, 0, 0), STATUS_BTN_GOOD_BACK_COLOR); + } + } + pThis->m_sockMutex.Unlock(); + + Sleep(10); + } + + return 0; +} + +UINT CTouchBoardDlg::SocketReceiveThread(LPVOID aParam) +{ + CTouchBoardDlg *pThis = (CTouchBoardDlg *)aParam; + INT size; + ULONGLONG sendTickTime = 0; + ULONGLONG ullTryTime = 0; + ULONGLONG ullCurTime = 0; + + ZeroMemory(pThis->m_recvBuffer, TBD_RECV_BUFSIZE); + pThis->m_recvSize = 0; + + while(pThis->m_bIsActive) + { + ULONGLONG curTickTime = GetTickCount64(); + + pThis->m_sockMutex.Lock(); + if(pThis->m_sock != INVALID_SOCKET) + { + size = recv(pThis->m_sock, pThis->m_recvBuffer + pThis->m_recvSize, TBD_RECV_BUFSIZE - pThis->m_recvSize, 0); + if(size > 0) + { + TRACE("Bytes received: %d\n", size); + pThis->m_recvSize += size; + } + else if(size == 0) + { + TRACE("Connection Closed!\n"); + shutdown(pThis->m_sock, SD_BOTH); + closesocket(pThis->m_sock); + pThis->m_sock = INVALID_SOCKET; + if(pThis->m_sock == INVALID_SOCKET) { + /* TODO - Handle Exception + */ + pThis->m_logEdit.Trace(L"[%s] CT ϴ. CODE[0]", pThis->m_strServerAddr); + } + } + else + { + int nError = WSAGetLastError(); + + if(nError != WSAEWOULDBLOCK && nError != 0) + { + TRACE("recv failed: %d\n", nError); + shutdown(pThis->m_sock, SD_BOTH); + closesocket(pThis->m_sock); + pThis->m_sock = INVALID_SOCKET; + pThis->m_logEdit.Trace(L"[%s] CT ϴ. CODE[%d]", pThis->m_strServerAddr, nError); + } + } + + if(pThis->m_sendSize > 0) + { + int ret = pThis->SocketSend(pThis->m_sendBuffer, pThis->m_sendSize); + if(ret > 0) + { + if(ret < pThis->m_sendSize) { + memcpy(pThis->m_sendBuffer, pThis->m_sendBuffer + ret, pThis->m_sendSize - ret); + } + pThis->m_sendSize -= ret; + } else if(ret == 0) { + TRACE("Connection Closed!\n"); + shutdown(pThis->m_sock, SD_BOTH); + closesocket(pThis->m_sock); + pThis->m_sock = INVALID_SOCKET; + } else if(ret < 0) { + int nError = WSAGetLastError(); + + if(nError != WSAEWOULDBLOCK && nError != 0) + { + TRACE("recv failed: %d\n", nError); + shutdown(pThis->m_sock, SD_BOTH); + closesocket(pThis->m_sock); + pThis->m_sock = INVALID_SOCKET; + pThis->m_logEdit.Trace(L"[%s] CT ϴ. CODE[%d]", pThis->m_strServerAddr, nError); + } + } + } + } + + if(curTickTime - sendTickTime > 2000) { + char keepAlive[] = "KEEP_ALIVE\r\n\r\n"; + memcpy(pThis->m_sendBuffer + pThis->m_sendSize, keepAlive, strlen(keepAlive)); + pThis->m_sendSize += strlen(keepAlive); + sendTickTime = curTickTime; + } + pThis->m_sockMutex.Unlock(); + + ullCurTime = GetTickCount64(); + if(pThis->m_sock == INVALID_SOCKET && pThis->m_strServerAddr.GetLength() > 0 && ullCurTime - ullTryTime > 2000) + { + char ipAddr[32] = {0, }; + pThis->WideToMultiByte(pThis->m_strServerAddr, ipAddr); + ullTryTime = ullCurTime; + + ZeroMemory(&pThis->m_recvBuffer, sizeof(pThis->m_recvBuffer)); + pThis->m_recvSize = 0; + pThis->m_sendSize = 0; + pThis->m_sock = pThis->ConnectRequest(ipAddr, pThis->m_port); + if(pThis->m_sock == INVALID_SOCKET) { + /* TODO - Handle Exception + */ + pThis->m_logEdit.Trace(L"[%s] CT ", pThis->m_strServerAddr); + } else { + pThis->m_logEdit.Trace(L"[%s] CT ", pThis->m_strServerAddr); + sendTickTime = GetTickCount64(); + } + } + + + + if(pThis->m_recvSize >= 4 && strstr(pThis->m_recvBuffer, "\r\n\r\n")) // Packet is end with CR+LF+CR+LF + { + int ret = pThis->PacketDizest(pThis->m_recvBuffer); + + if(ret > 0 && pThis->m_recvSize > ret) { + memcpy(pThis->m_recvBuffer, pThis->m_recvBuffer + ret, pThis->m_recvSize - ret); + } + if(ret > 0) + pThis->m_recvSize -= ret; + + ZeroMemory(pThis->m_recvBuffer + pThis->m_recvSize, TBD_RECV_BUFSIZE - pThis->m_recvSize); + //TRACE("RecvSize To: %d\n", pThis->m_recvSize); + } + + Sleep(1); + } + + if(pThis->m_sock != INVALID_SOCKET) + { + INT iResult = shutdown(pThis->m_sock, SD_BOTH); + if (iResult == SOCKET_ERROR) { + TRACE("listen socket shutdown failed: %d\n", WSAGetLastError()); + } + } + + return 0; +} + +void CTouchBoardDlg::WideToMultiByte(const wchar_t *src, char* dest) + { + int len = ::WideCharToMultiByte(CP_ACP, 0, src, -1, dest, 0, NULL, NULL); + ::WideCharToMultiByte(CP_ACP, 0, src, -1, dest, len, NULL, NULL); + } + + void CTouchBoardDlg::MultiByteToWide(const char* src, wchar_t *dest, int buffersize) + { + int len = ::MultiByteToWideChar(CP_ACP, 0, src, -1, dest, buffersize); + ::MultiByteToWideChar(CP_ACP, 0, src, -1, dest, buffersize); + } + + + int CTouchBoardDlg::GetMonitorInformation(void) +{ + m_infoMonitor.nMonitor = ::GetSystemMetrics(SM_CMONITORS); + m_infoMonitor.bSameDisplayFormat = ::GetSystemMetrics(SM_SAMEDISPLAYFORMAT); + + m_infoMonitor.rcVirtual.left = ::GetSystemMetrics(SM_XVIRTUALSCREEN); + m_infoMonitor.rcVirtual.top = ::GetSystemMetrics(SM_YVIRTUALSCREEN); + m_infoMonitor.rcVirtual.right = m_infoMonitor.rcVirtual.left + ::GetSystemMetrics(SM_CXVIRTUALSCREEN); + m_infoMonitor.rcVirtual.bottom = m_infoMonitor.rcVirtual.top + ::GetSystemMetrics(SM_CYVIRTUALSCREEN); + + m_infoMonitor.nWidth = ::GetSystemMetrics(SM_CXSCREEN); // ػ x + m_infoMonitor.nHeight = ::GetSystemMetrics(SM_CYSCREEN); // ػ y + m_infoMonitor.nWidthVirtual = ::GetSystemMetrics(SM_CXVIRTUALSCREEN); // ػ x + m_infoMonitor.nHeightVirtual = ::GetSystemMetrics(SM_CYVIRTUALSCREEN); // ػ y + + m_infoMonitor.nMegaPixel = (m_infoMonitor.nWidth * m_infoMonitor.nHeight)/(1000*1000); + m_infoMonitor.nMegaPixel = max(1,m_infoMonitor.nMegaPixel); + + return 0; + } + + void CTouchBoardDlg::OnBnClickedButtonSetup() + { + // TODO: Add your control notification handler code here + INT32 x, y; + RECT pos; + GetWindowRect(&pos); + if (m_bIsFullHD) { + x = pos.left + (1920 - TBD_SETUP_DLG_WIDTH) / 2; + y = pos.top + (1080 - TBD_SETUP_DLG_HEIGHT) / 2; + m_setupDlg.UpdateVariableToCtrl(); + m_setupDlg.SetWindowPos(NULL, x, y, TBD_SETUP_DLG_WIDTH, TBD_SETUP_DLG_HEIGHT, 0); + } + else { + x = pos.left + (TBD_STANDARD_WIDTH - TBD_SETUP_DLG_WIDTH) / 2; + y = pos.top + (TBD_STANDARD_HEIGHT - TBD_SETUP_DLG_HEIGHT) / 2; + m_setupDlg.UpdateVariableToCtrl(); + m_setupDlg.SetWindowPos(NULL, x, y, TBD_SETUP_DLG_WIDTH, TBD_SETUP_DLG_HEIGHT, 0); + } + m_setupDlg.ShowWindow(SW_SHOW); + } + + + void CTouchBoardDlg::OnDestroy() + { + CDialogEx::OnDestroy(); + + // TODO: Add your message handler code here + + if(m_sock != INVALID_SOCKET) + { + shutdown(m_sock, 2); + closesocket(m_sock); + } + + WSACleanup(); + + for(int i = 0;i < m_stationCount;i++) { + delete m_pStationList[i]; + } +} + +void CTouchBoardDlg::UpdateSettingToVariable() +{ + m_sockMutex.Lock(); + m_strServerAddr.Format(L"%d.%d.%d.%d", m_setupDlg.m_ctAddr[0], m_setupDlg.m_ctAddr[1], m_setupDlg.m_ctAddr[2], m_setupDlg.m_ctAddr[3]); + m_strESAddr.Format(L"%d.%d.%d.%d", m_setupDlg.m_esAddr[0], m_setupDlg.m_esAddr[1], m_setupDlg.m_esAddr[2], m_setupDlg.m_esAddr[3]); + m_strPSAddr.Format(L"%d.%d.%d.%d", m_setupDlg.m_psAddr[0], m_setupDlg.m_psAddr[1], m_setupDlg.m_psAddr[2], m_setupDlg.m_psAddr[3]); + m_port = 27879; + m_sockMutex.Unlock(); +} + +afx_msg LRESULT CTouchBoardDlg::OnTbdSetupSave(WPARAM wParam, LPARAM lParam) +{ + if(wParam == 1) { /* Ip address is changed */ + if(m_sock != INVALID_SOCKET) + { + INT iResult = shutdown(m_sock, SD_BOTH); + if (iResult == SOCKET_ERROR) { + TRACE("listen socket shutdown failed: %d\n", WSAGetLastError()); + } + + closesocket(m_sock); + m_sock = INVALID_SOCKET; + } + } + UpdateSettingToVariable(); + return 0; +} + +afx_msg LRESULT CTouchBoardDlg::OnTbdUpdateLevel2(WPARAM wParam, LPARAM lParam) +{ + UpdateTouchButtonList(); + + /* CT WARDID ϴ ϴ ҹ漭 Default ׷ */ + if(m_strWardId.GetLength() > 0) { + INT32 iWardId = _ttoi(m_strWardId); + for(INT32 i = 0;i < m_stationCount;i++) { + if(m_pStationList[i]->mWardId == iWardId) { + m_iSelectGroup = m_pStationList[i]->mGroupIdx; + break; + } + } + } + + if(m_iSelectGroup == -1) { + m_pGroupBtn[0]->PostMessage(WM_LBUTTONDOWN); + } else { + m_pGroupBtn[m_iSelectGroup]->PostMessage(WM_LBUTTONDOWN); + } + return 0; +} + +afx_msg LRESULT CTouchBoardDlg::OnTbdLevel2Push(WPARAM wParam, LPARAM lParam) +{ + TRACE("PUSH : %d\n", wParam); + INT32 grpIdx = -1; + + if(m_strWardId.GetLength() > 0) { + INT32 iWardId = _ttoi(m_strWardId); + INT32 iGroupIdx = -1; + for(INT32 i = 0;i < m_stationCount;i++) { + if(m_pStationList[i]->mWardId == iWardId) { + iGroupIdx = m_pStationList[i]->mGroupIdx; + break; + } + } + + for(INT32 i = 0;i < m_iGroupBtnCount;i++) { + if(m_pGroupBtn[i]->m_btnId == wParam) { + grpIdx = i; + break; + } + } + + if(iGroupIdx != grpIdx) + return 0; + } + + for(INT32 i = 0;i < m_iGroupBtnCount;i++) { + if(m_pGroupBtn[i]->m_btnId != wParam) + m_pGroupBtn[i]->SetPressState(false); + else { + grpIdx = i; + m_pGroupBtn[i]->SetPressState(true); + } + } + + m_iSelectGroup = grpIdx; + //m_logEdit.Trace(L"HOHOHO : %d", m_iSelectGroup); + + for(INT32 i = 0;i < m_stationCount;i++) + { + if(m_pStationList[i]->mGroupIdx == grpIdx) + { + if(m_pStationList[i]->m_pButton) + { + m_pStationList[i]->m_pButton->ShowWindow(SW_SHOW); + } + } + else + { + if(m_pStationList[i]->m_pButton) + { + m_pStationList[i]->m_pButton->ShowWindow(SW_HIDE); + } + } + } + + Invalidate(false); + return 0; +} + +BOOL CTouchBoardDlg::OnEraseBkgnd(CDC* pDC) +{ + // TODO: Add your message handler code here and/or call default + + //return false; + + return CDialogEx::OnEraseBkgnd(pDC); +} + + +void CTouchBoardDlg::OnBnClickedButtonCastAll() +{ + // TODO: Add your control notification handler code here + RequestCastOrder(TBD_REQUEST_CAST_TYPE_ALL); +} + + +void CTouchBoardDlg::OnBnClickedButtonCastFire() +{ + // TODO: Add your control notification handler code here + RequestCastOrder(TBD_REQUEST_CAST_TYPE_FIRE); +} + + +void CTouchBoardDlg::OnBnClickedButtonCastRescue() +{ + // TODO: Add your control notification handler code here + RequestCastOrder(TBD_REQUEST_CAST_TYPE_RESQUE); +} + + +void CTouchBoardDlg::OnBnClickedButtonCastEmergency() +{ + // TODO: Add your control notification handler code here + RequestCastOrder(TBD_REQUEST_CAST_TYPE_EMERGENCY); +} + + +void CTouchBoardDlg::OnBnClickedButtonCastNormal() +{ + // TODO: Add your control notification handler code here + RequestCastOrder(TBD_REQUEST_CAST_TYPE_GENERAL); +} + + +void CTouchBoardDlg::OnBnClickedButtonRestore() +{ + // TODO: Add your control notification handler code here + + // μ + TCHAR form[128]; + CString strOrder; + strOrder = "BYPASS\r\n"; + strOrder += "CAST_ORDER=STOP\r\n"; + strOrder += "CVI_NO="; + strOrder += m_strCviNo; + strOrder += "\r\n"; + strOrder += "\r\n"; + + char *pSendBuffer; + UTF8_CONVERSION_EX; + pSendBuffer = W2UTF8_EX(strOrder); + SocketSendExceptionHandle(pSendBuffer, strlen(pSendBuffer)); + +#if 1 + for(INT32 i = 0;i < m_stationCount;i++) { + if(m_pStationList[i]->m_pButton) { + m_pStationList[i]->m_pButton->m_bChecked = FALSE; + m_pStationList[i]->m_pButton->m_bPressed = FALSE; + m_pStationList[i]->m_pButton->Invalidate(FALSE); + } + } + + Invalidate(FALSE); +#endif + +} + +void CTouchBoardDlg::RequestCastOrder(INT32 iCastType) +{ + CString strOrder; + INT32 iSendCount = 0; + BOOL *pbSelectList; + + pbSelectList = new BOOL[m_stationCount]; + ZeroMemory(pbSelectList, m_stationCount * sizeof(BOOL)); + + if(iCastType == TBD_REQUEST_CAST_TYPE_ALL) // + { + for(INT32 i = 0;i < m_stationCount;i++) + { + if(m_pStationList[i]->m_pButton && m_pStationList[i]->m_pButton->m_bEnabled && m_pStationList[i]->mGroupIdx == m_iSelectGroup) { + pbSelectList[i] = true; + //m_pStationList[i]->m_pButton->SetPressState(true); + } + } + } + else if(iCastType == TBD_REQUEST_CAST_TYPE_WHOLE) // ü + { + for(INT32 i = 0;i < m_stationCount;i++) + { + if(m_pStationList[i]->mStationId > 0 && m_pStationList[i]->m_pButton && m_pStationList[i]->m_pButton->m_bEnabled) { + pbSelectList[i] = true; + //m_pStationList[i]->m_pButton->SetPressState(true); + } + } + } + else + { + for(INT32 i = 0;i < m_stationCount;i++) + { + // ׷ üũ ܸ Ʈ ó + if(m_pStationList[i]->m_pButton && m_pStationList[i]->m_pButton->m_bChecked && m_pStationList[i]->mSubCount > 0) { + pbSelectList[i] = true; + for(INT j = 0;j < m_stationCount;j++) { + if(m_pStationList[j]->mUpWardId == m_pStationList[i]->mWardId) { + pbSelectList[j] = true; + } + } + } + + if(m_pStationList[i]->m_pButton && m_pStationList[i]->m_pButton->m_bPressed) + pbSelectList[i] = true; + } + } + + for(INT32 i = 0;i < m_stationCount;i++) + { + if(pbSelectList[i]) + iSendCount++; + } + + if(iSendCount > 0) + { + CString dlgMessage; + TCHAR form[128]; + strOrder = "BYPASS\r\n"; + + if(iCastType == TBD_REQUEST_CAST_TYPE_FIRE) { + strOrder += "COMMAND=FIRE\r\n"; + dlgMessage = L"ȭԴϴ"; + } else if(iCastType == TBD_REQUEST_CAST_TYPE_EMERGENCY) { + strOrder += "COMMAND=EMERGENCY\r\n"; + dlgMessage = L"޹Դϴ"; + } else if(iCastType == TBD_REQUEST_CAST_TYPE_GENERAL) { + strOrder += "COMMAND=GENERAL\r\n"; + dlgMessage = L"ŸԴϴ"; + } else if(iCastType == TBD_REQUEST_CAST_TYPE_RESQUE) { + strOrder += "COMMAND=RESCUSE\r\n"; + dlgMessage = L"Դϴ"; + } else if(iCastType == TBD_REQUEST_CAST_TYPE_ALL) { + //strOrder += "COMMAND=ALL\r\n"; + strOrder += "COMMAND=GENERAL\r\n"; + dlgMessage = L"Դϴ"; + iCastType = TBD_REQUEST_CAST_TYPE_GENERAL; + } else if(iCastType == TBD_REQUEST_CAST_TYPE_WHOLE) { + strOrder += "COMMAND=GENERAL\r\n"; + dlgMessage = L"üԴϴ"; + iCastType = TBD_REQUEST_CAST_TYPE_GENERAL; + } + + wsprintf(form, L"STATION_COUNT=%d\r\n", iSendCount); + strOrder += form; + wsprintf(form, L"CAST_ORDER=MIC\r\n"); + strOrder += form; + + + if(m_setupDlg.m_bSendTTS) { + if(m_setupDlg.m_strTTSMessage.GetLength() > 0) { + wsprintf(form, L"CAST_SOURCE=TTS\r\n"); + strOrder += form; + } + } + else if(m_setupDlg.m_bSendLineIn) { + wsprintf(form, L"CAST_SOURCE=LINEIN\r\n"); + strOrder += form; + } + + strOrder += "CVI_NO="; + strOrder += m_strCviNo; + strOrder += "\r\n"; + + for(INT32 i = 0;i < m_stationCount;i++) { + if(pbSelectList[i]) { + wsprintf(form, L"STATION_ID=%d\r\n", m_pStationList[i]->mStationId); + strOrder += form; + } + } + strOrder += "\r\n"; + + char *pSendBuffer; + UTF8_CONVERSION_EX; + pSendBuffer = W2UTF8_EX(strOrder); + SocketSendExceptionHandle(pSendBuffer, strlen(pSendBuffer)); + + for(INT32 i = 0;i < m_stationCount;i++) { + if(pbSelectList[i]) { + m_pStationList[i]->m_pButton->m_bChecked = FALSE; + m_pStationList[i]->m_pButton->m_bPressed = FALSE; + m_pStationList[i]->m_pButton->Invalidate(FALSE); + } + } +#if 0 + COnCastDlg dlg; + dlg.m_strMessage = dlgMessage; + dlg.DoModal(); + + // μ + strOrder = "BYPASS\r\n"; + strOrder += "CAST_ORDER=STOP\r\n"; + wsprintf(form, L"STATION_COUNT=%d\r\n", iSendCount); + strOrder += form; + strOrder += "CVI_NO="; + strOrder += m_strCviNo; + strOrder += "\r\n"; + for(INT32 i = 0;i < m_stationCount;i++) { + if(pbSelectList[i]) { + wsprintf(form, L"STATION_ID=%d\r\n", m_pStationList[i]->mStationId); + strOrder += form; + } + } + strOrder += "\r\n"; + pSendBuffer = W2UTF8_EX(strOrder); + SocketSendExceptionHandle(pSendBuffer, strlen(pSendBuffer)); + + for(INT32 i = 0;i < m_stationCount;i++) { + if(pbSelectList[i]) { + m_pStationList[i]->m_pButton->m_bChecked = FALSE; + m_pStationList[i]->m_pButton->m_bPressed = FALSE; + m_pStationList[i]->m_pButton->Invalidate(FALSE); + } + } +#endif + + Invalidate(FALSE); + } + + delete pbSelectList; +} + +ULONG CTouchBoardDlg::ProcIDFromWnd(HWND hwnd) +{ + ULONG idProc; + GetWindowThreadProcessId( hwnd, &idProc ); + return idProc; +} + +HWND CTouchBoardDlg::GetWinHandle(ULONG pid) +{ + HWND tempHwnd = ::FindWindow(NULL,NULL); // ֻ ڵ ã + + while( tempHwnd != NULL ) + { + if( ::GetParent(tempHwnd) == NULL ) + if( pid == ProcIDFromWnd(tempHwnd) ) + return tempHwnd; + + tempHwnd = ::GetWindow(tempHwnd, GW_HWNDNEXT); + } + + return NULL; +} + +BOOL CTouchBoardDlg::EnumProcessAndFocus(CString processPath) +{ + DWORD aProcesses[1024], cbNeeded, cProcesses; + unsigned int i; + BOOL bFound = false; + + if ( !EnumProcesses( aProcesses, sizeof(aProcesses), &cbNeeded ) ) + { + return false; + } + + // Calculate how many process identifiers were returned. + cProcesses = cbNeeded / sizeof(DWORD); + + // Print the name and process identifier for each process. + for ( i = 0; i < cProcesses; i++ ) + { + if( aProcesses[i] != 0 ) + { + CString strPath; + PrintProcessNameAndID( aProcesses[i], strPath ); + if(strPath == processPath) { + HWND hwnd = GetWinHandle(aProcesses[i]); + ::BringWindowToTop(hwnd); + ::SetForegroundWindow(hwnd); +#if USE_ROUND_BUTTON2 +#else + ::ShowWindow(hwnd, SW_SHOWMAXIMIZED); + + HANDLE hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_TERMINATE | + PROCESS_VM_READ, + FALSE, aProcesses[i] ); + + if(TerminateProcess(hProcess, 0)) + { + unsigned long nCode; //μ + GetExitCodeProcess(hProcess, &nCode); + } + CloseHandle( hProcess ); +#endif + bFound = true; + } + } + } + + return bFound; +} + +void CTouchBoardDlg::PrintProcessNameAndID(DWORD processID, CString& strPath) +{ + TCHAR szProcessName[MAX_PATH] = TEXT(""); + + // Get a handle to the process. + HANDLE hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | + PROCESS_QUERY_LIMITED_INFORMATION | + PROCESS_VM_READ, + FALSE, processID ); + + // Get the process name. + if (NULL != hProcess ) + { +#if 0 + HMODULE hMod; + DWORD cbNeeded; + + if ( EnumProcessModules( hProcess, &hMod, sizeof(hMod), + &cbNeeded) ) + { + //GetModuleBaseName( hProcess, hMod, szProcessName, + // sizeof(szProcessName)/sizeof(TCHAR) ); + GetModuleFileNameEx( hProcess, hMod, szProcessName, sizeof(szProcessName)/sizeof(TCHAR)); + //GetProcessImageFileName(hProcess, szProcessName, sizeof(szProcessName) / sizeof(TCHAR)); + } +#else + GetModuleFileNameEx(hProcess, NULL, szProcessName, sizeof(szProcessName) / sizeof(TCHAR)); +#endif + + TRACE(TEXT("%s (PID: %u)\n"), szProcessName, processID); + } + + // Print the process name and identifier. + //TRACE(TEXT("%s (PID: %u)\n"), szProcessName, processID ); + strPath = szProcessName; + // Release the handle to the process. + CloseHandle( hProcess ); +} + +void CTouchBoardDlg::OnBnClickedButtonWireless() +{ + // TODO: Add your control notification handler code here + if(m_setupDlg.m_strWirelessPath.GetLength() == 0) + return; + + BOOL bRet = EnumProcessAndFocus(m_setupDlg.m_strWirelessPath); + if (bRet) + return; + + //if(bRet) + // return; + + TCHAR strPath[512]; + TCHAR strName[512]; + SHELLEXECUTEINFOW sei; + ZeroMemory(&sei, sizeof(SHELLEXECUTEINFOW)); + sei.cbSize = sizeof(SHELLEXECUTEINFOW); + + int pos = m_setupDlg.m_strWirelessPath.ReverseFind('\\'); + if(pos >= 0) { + wsprintf(strPath, L"%s", m_setupDlg.m_strWirelessPath.Left(pos)); + wsprintf(strName, L"%s", m_setupDlg.m_strWirelessPath.Mid(pos + 1)); + sei.lpFile = strName; + sei.lpDirectory = strPath; + sei.nShow = SW_SHOWMAXIMIZED; + sei.fMask = SEE_MASK_NOCLOSEPROCESS; + sei.lpVerb = __T("open"); + BOOL result = ShellExecuteEx(&sei); +#if USE_ROUND_BUTTON2 +#else + if(result) { + AfxPostQuitMessage(0); + } +#endif + } +} + + +void CTouchBoardDlg::OnBnClickedButtonCall() +{ + // TODO: Add your control notification handler code here + if(m_setupDlg.m_strCallPath.GetLength() == 0) + return; + + BOOL bRet = EnumProcessAndFocus(m_setupDlg.m_strCallPath); + if(bRet) + return; + + TCHAR strPath[512]; + TCHAR strName[512]; + SHELLEXECUTEINFOW sei; + ZeroMemory(&sei, sizeof(SHELLEXECUTEINFOW)); + sei.cbSize = sizeof(SHELLEXECUTEINFOW); + + int pos = m_setupDlg.m_strCallPath.ReverseFind('\\'); + if(pos >= 0) { + wsprintf(strPath, L"%s", m_setupDlg.m_strCallPath.Left(pos)); + wsprintf(strName, L"%s", m_setupDlg.m_strCallPath.Mid(pos + 1)); + sei.lpFile = strName; + sei.lpDirectory = strPath; + sei.nShow = SW_SHOWMAXIMIZED; + sei.fMask = SEE_MASK_NOCLOSEPROCESS; + sei.lpVerb = __T("open"); + BOOL result = ShellExecuteEx(&sei); +#if USE_ROUND_BUTTON2 +#else + if(result) { + AfxPostQuitMessage(0); + } +#endif + } +} + + +void CTouchBoardDlg::OnClose() +{ + // TODO: Add your message handler code here and/or call default + m_bIsActive = false; + + KillTimer(TBD_TIMER_EVENT_SOCKET); + + if(m_sock != INVALID_SOCKET) + { + INT iResult = shutdown(m_sock, SD_BOTH); + if (iResult == SOCKET_ERROR) { + TRACE("listen socket shutdown failed: %d\n", WSAGetLastError()); + } + + closesocket(m_sock); + } + + if(m_pReceiveThread) + ::WaitForSingleObject(m_pReceiveThread->m_hThread, INFINITE); + + CDialogEx::OnClose(); +} + + +afx_msg LRESULT CTouchBoardDlg::OnTbdLogUpdate(WPARAM wParam, LPARAM lParam) +{ + m_logEdit.UpdateLogsToEdit(); + return 0; +} + +afx_msg LRESULT CTouchBoardDlg::OnTbdSubGrouping(WPARAM wParam, LPARAM lParam) +{ + DWORD ward_id = wParam; + BOOL bNextState = lParam; + + for(INT32 i = 0;i < m_stationCount;i++) { + if(m_pStationList[i]->mWardId == ward_id || (m_pStationList[i]->mUpWardId == ward_id && m_pStationList[i]->mSubCount == 0)) { + if(m_pStationList[i]->m_pButton->m_bEnabled) + m_pStationList[i]->m_pButton->SetPressState(bNextState); + } + } + + return 0; +} + + +void CTouchBoardDlg::OnBnClickedButtonCastWhole() +{ + // TODO: Add your control notification handler code here + + RequestCastOrder(TBD_REQUEST_CAST_TYPE_WHOLE); +} + + +void CTouchBoardDlg::OnTimer(UINT_PTR nIDEvent) +{ + // TODO: Add your message handler code here and/or call default + + if(nIDEvent == TBD_TIMER_EVENT_SOCKET) + { + INT size; + static ULONGLONG sendTickTime = 0; + static ULONGLONG ullTryTime = 0; + ULONGLONG ullCurTime = 0; + + ULONGLONG curTickTime = GetTickCount64(); + m_sockMutex.Lock(); + if(m_sock != INVALID_SOCKET) + { + size = recv(m_sock, m_recvBuffer + m_recvSize, TBD_RECV_BUFSIZE - m_recvSize, 0); + if(size > 0) + { + TRACE("Bytes received: %d\n", size); + m_recvSize += size; + } + else if(size == 0) + { + TRACE("Connection Closed!\n"); + shutdown(m_sock, SD_BOTH); + closesocket(m_sock); + m_sock = INVALID_SOCKET; + if(m_sock == INVALID_SOCKET) { + /* TODO - Handle Exception + */ + m_logEdit.Trace(L"[%s] CT ϴ. CODE[0]", m_strServerAddr); + } + } + else + { + int nError = WSAGetLastError(); + + if(nError != WSAEWOULDBLOCK && nError != 0) + { + TRACE("recv failed: %d\n", nError); + shutdown(m_sock, SD_BOTH); + closesocket(m_sock); + m_sock = INVALID_SOCKET; + m_logEdit.Trace(L"[%s] CT ϴ. CODE[%d]", m_strServerAddr, nError); + } + } + + if(m_sendSize > 0) + { + int ret = SocketSend(m_sendBuffer, m_sendSize); + if(ret > 0) + { + if(ret < m_sendSize) { + memcpy(m_sendBuffer, m_sendBuffer + ret, m_sendSize - ret); + } + m_sendSize -= ret; + } else if(ret == 0) { + TRACE("Connection Closed!\n"); + shutdown(m_sock, SD_BOTH); + closesocket(m_sock); + m_sock = INVALID_SOCKET; + } else if(ret < 0) { + int nError = WSAGetLastError(); + + if(nError != WSAEWOULDBLOCK && nError != 0) + { + TRACE("recv failed: %d\n", nError); + shutdown(m_sock, SD_BOTH); + closesocket(m_sock); + m_sock = INVALID_SOCKET; + m_logEdit.Trace(L"[%s] CT ϴ. CODE[%d]", m_strServerAddr, nError); + } + } + } + + if(curTickTime - sendTickTime > 2000) { + char keepAlive[] = "KEEP_ALIVE\r\n\r\n"; + memcpy(m_sendBuffer + m_sendSize, keepAlive, strlen(keepAlive)); + m_sendSize += strlen(keepAlive); + sendTickTime = curTickTime; + } + } + m_sockMutex.Unlock(); + + #if 0 + ullCurTime = GetTickCount64(); + if(m_sock == INVALID_SOCKET && m_strServerAddr.GetLength() > 0 && ullCurTime - ullTryTime > 2000) + { + char ipAddr[32] = {0, }; + WideToMultiByte(m_strServerAddr, ipAddr); + ullTryTime = ullCurTime; + + ZeroMemory(m_recvBuffer, sizeof(m_recvBuffer)); + m_recvSize = 0; + m_sendSize = 0; + m_sock = ConnectRequest(ipAddr, m_port); + if(m_sock == INVALID_SOCKET) { + /* TODO - Handle Exception + */ + m_logEdit.Trace(L"[%s] CT ", m_strServerAddr); + } else { + m_logEdit.Trace(L"[%s] CT ", m_strServerAddr); + sendTickTime = GetTickCount64(); + } + } + #endif + +#if USE_PACKET_DUMP_FILE + { + static int packetCount = 0; + char packetFile[128]; + FILE *fp; + sprintf(packetFile, "packet-%03d.txt", packetCount); + packetCount++; + fp = fopen(packetFile, "rt"); + if (fp) { + fread(m_recvBuffer, 1, sizeof(m_recvBuffer), fp); + fclose(fp); + + m_recvSize = strlen(m_recvBuffer); + } + } +#endif + + if(m_recvSize >= 4 && strstr(m_recvBuffer, "\r\n\r\n")) // Packet is end with CR+LF+CR+LF + { + int ret = PacketDizest(m_recvBuffer); + + if(ret > 0 && m_recvSize > ret) { + memcpy(m_recvBuffer, m_recvBuffer + ret, m_recvSize - ret); + } + if(ret > 0) + m_recvSize -= ret; + + ZeroMemory(m_recvBuffer + m_recvSize, TBD_RECV_BUFSIZE - m_recvSize); + //TRACE("RecvSize To: %d\n", pThis->m_recvSize); + } + } + + CDialogEx::OnTimer(nIDEvent); +} + + +void CTouchBoardDlg::OnBnClickedButtonMicvolMinus() +{ + // TODO: Add your control notification handler code here + char strMessage[256]; + sprintf(strMessage, "MIC_VOLUME=MINUS\r\n\r\n"); + SocketSendExceptionHandle(strMessage, strlen(strMessage)); +} + + +void CTouchBoardDlg::OnBnClickedButtonMicvolPlus() +{ + // TODO: Add your control notification handler code here + char strMessage[256]; + sprintf(strMessage, "MIC_VOLUME=PLUS\r\n\r\n"); + SocketSendExceptionHandle(strMessage, strlen(strMessage)); +} + + +void CTouchBoardDlg::OnBnClickedButtonSpkvolMinus() +{ + // TODO: Add your control notification handler code here + char strMessage[256]; + sprintf(strMessage, "SPK_VOLUME=MINUS\r\n\r\n"); + SocketSendExceptionHandle(strMessage, strlen(strMessage)); +} + + +void CTouchBoardDlg::OnBnClickedButtonSpkvolPlus() +{ + // TODO: Add your control notification handler code here + char strMessage[256]; + sprintf(strMessage, "SPK_VOLUME=PLUS\r\n\r\n"); + SocketSendExceptionHandle(strMessage, strlen(strMessage)); +} + + +HBRUSH CTouchBoardDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) +{ + HBRUSH hbr = CDialogEx::OnCtlColor(pDC, pWnd, nCtlColor); + + // TODO: ⼭ DC Ư մϴ. + UINT nID = pWnd->GetDlgCtrlID(); + + switch (nID) + { + case IDC_STATIC_TITLE: + pDC->SetTextColor(RGB(255, 255, 255)); + pDC->SetBkColor(TOPBAR_BACK_COLOR); + hbr = ::CreateSolidBrush(TOPBAR_BACK_COLOR); + break; + } + + + // TODO: ⺻ ٸ 귯ø ȯմϴ. + return hbr; +} diff --git a/TouchBoardDlg.h b/TouchBoardDlg.h new file mode 100644 index 0000000..d14cd8d --- /dev/null +++ b/TouchBoardDlg.h @@ -0,0 +1,303 @@ + +// TouchBoardDlg.h : +// + +#pragma once + +#include "TouchSetupDlg.h" +#include "TouchButton.h" +#include "LogEdit.h" +#include "afxwin.h" +#include "ColorButton.h" +#include "RoundButton2.h" +#include "RoundButtonStyle.h" + +#undef PSAPI_VERSION +#define PSAPI_VERSION 1 + +#include +#pragma comment(lib, "psapi.lib") + +#define USE_ROUND_BUTTON2 1 +//#define USE_DO_PACKET_DUMP 1 +//#define USE_PACKET_DUMP_FILE 1 +//#define USE_DUMMY_DATA_FOR_UI 1 + +#define TBD_SETTING_FILE "tbd.ini" +#define TBD_CLIENT_DEFAULT_PORT 17080 +#define TBD_RECV_BUFSIZE (1024 * 512) +#define TBD_SEND_BUFSIZE (1024 * 512) +#define TBD_STANDARD_WIDTH 1280 +#define TBD_STANDARD_HEIGHT 1024 + +#if TBD_BUTTON_UI_STYLE == 2 +#define TBD_BTN_WIDTH 152 +#define TBD_BTN_HEIGHT 45 +#define TBD_BTN_ICON_WIDTH 30 +#define TBD_BTN_ICON_HEIGHT 45 +#else +#define TBD_BTN_WIDTH 152 +#define TBD_BTN_HEIGHT 45 +#define TBD_BTN_ICON_WIDTH 30 +#define TBD_BTN_ICON_HEIGHT 45 +//#define TBD_BTN_HEIGHT 60 +//#define TBD_BTN_ICON_WIDTH 15 +//#define TBD_BTN_ICON_HEIGHT 15 +#endif + + +#if TBD_BUTTON_UI_STYLE == 2 +#define TBD_BTN_SUB_MARGIN_X 6 +#define TBD_BTN_SUB_MARGIN_Y 6 +#if USE_ROUND_BUTTON2 +#define TBD_BTN_GROUP_START_X 206 +#else +#define TBD_BTN_GROUP_START_X 235 +#endif +#define TBD_BTN_GROUP_START_Y 95 + +#define TBD_BTN_SUB_START_X 210 +#if USE_ROUND_BUTTON2 +#define TBD_BTN_SUB_START_Y 230 +#else +#define TBD_BTN_SUB_START_Y 220 +#endif +#define TBD_BTN_SUB_COLUMN_SIZE 5 +#define TBD_BTN_GROUP_MARGIN_Y 12 +#else +#define TBD_BTN_SUB_MARGIN_X 8 +#define TBD_BTN_SUB_MARGIN_Y 8 +#define TBD_BTN_GROUP_START_X 240 +#define TBD_BTN_GROUP_START_Y 110 +#define TBD_BTN_SUB_START_X 210 +#define TBD_BTN_SUB_START_Y 260 +#define TBD_BTN_SUB_COLUMN_SIZE 5 +#define TBD_BTN_GROUP_MARGIN_Y 20 +#endif + +#define TBD_BTN_GROUP_LINE_BASE_COLOR RGB(150, 150, 150) +#define TBD_BTN_GROUP_LINE_CHECK_COLOR RGB(200, 0, 0) + +//#define ACT_BTN_REGION_BACK_COLOR RGB(0, 50, 150) +//#define ACT_BTN_REGION_BACK_COLOR RGB(20, 40, 65) +#define ACT_BTN_REGION_BACK_COLOR RGB(58, 58, 67) +#define STATUS_BTN_GOOD_BACK_COLOR RGB(57, 119, 206) + +#define TOPBAR_BACK_COLOR RGB(58, 58, 67) +#define GLOBAL_BACK_COLOR RGB(232, 242, 247) + +#define TBD_MAX_STATION_COUNT 1000 +#define TBD_MAX_GROUP_COUNT 30 + +#define TBD_SERVER_COMMAND_STATION_INFORM 10000 +#define TBD_SERVER_COMMAND_STATION_NOTIFY 10001 +#define TBD_SERVER_COMMAND_CAST_STATUS 10002 +#define TBD_SERVER_COMMAND_DEVICE_STATUS 10003 + +#define TBD_REQUEST_CAST_TYPE_ALL 100 +#define TBD_REQUEST_CAST_TYPE_FIRE 101 +#define TBD_REQUEST_CAST_TYPE_RESQUE 102 +#define TBD_REQUEST_CAST_TYPE_EMERGENCY 103 +#define TBD_REQUEST_CAST_TYPE_GENERAL 104 +#define TBD_REQUEST_CAST_TYPE_WHOLE 105 + +#define TBD_TIMER_EVENT_SOCKET 1000 + +typedef struct _tMonitor +{ + int nWidth; // Width + int nHeight; // Height + int nWidthVirtual; // Width Virtual + int nHeightVirtual; // Height Virtual + int nBitPerPixel; // BitPerPixel + int nRefresh; // Refresh + int nMonitor; // Monitors + int nMegaPixel; // MegaPixel + BOOL bSameDisplayFormat; // SameDisplayFormat + RECT rcVirtual; + CArray< MONITORINFOEX, MONITORINFOEX > aryMonitors; +} TMONITOR; + +class CStationInfo +{ +public: + int mGroupIdx; + int mSubGroupId; + int mWardId; // ID + int mUpWardId; // ̼ ID + int mStationId; // ̼ ID + int mLevel; + int mSubCount; // ̼ + + int mCallerNo; // ȣ + int mCallerCviNo; // CT CVI ȣ + + int mNickIndex; // ġ ׷ ε + boolean mIsHeader; + CString mNickName; + CString mIpAddr; + + int mBtnPosX; + int mBtnPosY; + int mBtnGroupRow; // added by ritoseo - 2022-02-03 + int mBtnShiftRow; // added by ritoseo - 2022-02-03 + boolean mGrouping; + RECT mGroupBox; + CTouchButton* m_pButton; +}; + + +// CTouchBoardDlg ȭ +class CTouchBoardDlg : public CDialogEx +{ +// Դϴ. +public: + CTouchBoardDlg(CWnd* pParent = NULL); // ǥ Դϴ. + +// ȭ Դϴ. + enum { IDD = IDD_TOUCHBOARD_DIALOG }; + + protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV Դϴ. + + +// Դϴ. +protected: + HICON m_hIcon; + + CString m_strServerAddr; + CString m_strESAddr; + CString m_strPSAddr; + SOCKET m_sock; + INT32 m_port; + TMONITOR m_infoMonitor; + CString m_strDeviceName; + CString m_strCviNo; + CString m_strWardId; + CMutex m_infoMutex; + + char m_sendBuffer[TBD_SEND_BUFSIZE]; + char m_recvBuffer[TBD_RECV_BUFSIZE]; + INT32 m_sendSize; + INT32 m_recvSize; + INT32 m_iRequestWaitFlag; + BOOL m_bIsActive; + CMutex m_sockMutex; + CWinThread *m_pReceiveThread; + CWinThread *m_pPingThread; + CTouchSetupDlg m_setupDlg; + + CxImage m_ciSymbol; + CxImage m_ciBackground; + CDC* m_pMemDC; + CBitmap* m_pDCBitmap; + CPen* m_pDidLinePen; + + INT32 m_iSelectGroup; + CStationInfo *m_pStationList[TBD_MAX_STATION_COUNT]; + INT32 m_stationCount; + + INT32 m_iGroupBtnCount; + CTouchButton *m_pGroupBtn[TBD_MAX_GROUP_COUNT]; + + INT32 m_iScreenWidth; + INT32 m_iScreenHeight; + BOOL m_bIsFullHD; + + // ޽ Լ + virtual BOOL OnInitDialog(); + afx_msg void OnSysCommand(UINT nID, LPARAM lParam); + afx_msg void OnPaint(); + afx_msg HCURSOR OnQueryDragIcon(); + DECLARE_MESSAGE_MAP() + + void WideToMultiByte(const wchar_t *src, char* dest); + void MultiByteToWide(const char* src, wchar_t *dest, int buffersize); + in_addr* atoaddr(char *address); + SOCKET ConnectRequest(char *pAddress, int port); + INT32 SocketSend(char *sendData, int datasize); + INT32 PacketDizest(char *pBuffer); + int GetMonitorInformation(void); + void UpdateSettingToVariable(); + void UpdateSubGroupList(); + void UpdateTouchButtonList(); + void CalcButtonPositioning(); + void RequestCastOrder(INT32 iCastType); + ULONG ProcIDFromWnd(HWND hwnd); + HWND GetWinHandle(ULONG pid); + void PrintProcessNameAndID(DWORD processID, CString& strPath); + BOOL EnumProcessAndFocus(CString processPath); + void MoveWindowDirection(CWnd *pWnd, INT32 xpos, INT32 ypos); + + static UINT SocketReceiveThread(LPVOID aParam); + static UINT SocketConnectionThread(LPVOID aParam); + static UINT PingCheckThread(LPVOID aParam); +public: + CFont m_titleFont; + CFont m_topFont; + CFont m_castFont; + CFont m_btnFont; + CFont m_btnSmallFont; + CFont m_logFont; + CFont m_btnUnderFont; + CLogEdit m_logEdit; + +#if USE_ROUND_BUTTON2 + CRoundButtonStyle m_tButtonStyle; + CRoundButtonStyle m_tTopStyle[5]; + CRoundButtonStyle m_tActStyle[8]; + CRoundButton2 *m_pTopButton[5]; + CRoundButton2 *m_pActButton[8]; +#else + CColorButton *m_pTopButton[5]; + CColorButton *m_pActButton[8]; +#endif + CColorButton *m_pStatusButton[3]; + + CString getStrWardId() { + CString strResult; + m_infoMutex.Lock(); + strResult = m_strWardId; + m_infoMutex.Unlock(); + + return strResult; + } + + CString getStrDeviceName() { + CString strResult; + m_infoMutex.Lock(); + strResult = m_strDeviceName; + m_infoMutex.Unlock(); + + return strResult; + } + + INT32 SocketSendExceptionHandle(char *sendData, int datasize); + + afx_msg void OnBnClickedButtonSetup(); + afx_msg void OnDestroy(); + afx_msg LRESULT OnTbdSetupSave(WPARAM wParam, LPARAM lParam); + afx_msg LRESULT OnTbdUpdateLevel2(WPARAM wParam, LPARAM lParam); + afx_msg LRESULT OnTbdLevel2Push(WPARAM wParam, LPARAM lParam); + afx_msg LRESULT OnTbdLogUpdate(WPARAM wParam, LPARAM lParam); + afx_msg LRESULT OnTbdSubGrouping(WPARAM wParam, LPARAM lParam); + afx_msg BOOL OnEraseBkgnd(CDC* pDC); + + afx_msg void OnBnClickedButtonCastAll(); + afx_msg void OnBnClickedButtonCastFire(); + afx_msg void OnBnClickedButtonCastRescue(); + afx_msg void OnBnClickedButtonCastEmergency(); + afx_msg void OnBnClickedButtonCastNormal(); + afx_msg void OnBnClickedButtonRestore(); + afx_msg void OnBnClickedButtonWireless(); + afx_msg void OnBnClickedButtonCall(); + afx_msg void OnClose(); + afx_msg void OnBnClickedButtonCastWhole(); + + afx_msg void OnTimer(UINT_PTR nIDEvent); + afx_msg void OnBnClickedButtonMicvolMinus(); + afx_msg void OnBnClickedButtonMicvolPlus(); + afx_msg void OnBnClickedButtonSpkvolMinus(); + afx_msg void OnBnClickedButtonSpkvolPlus(); + afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor); +}; diff --git a/TouchButton.cpp b/TouchButton.cpp new file mode 100644 index 0000000..208a76e --- /dev/null +++ b/TouchButton.cpp @@ -0,0 +1,433 @@ +// TouchButton.cpp : implementation file +// + +#include "stdafx.h" +#include "TouchBoard.h" +#include "TouchBoardDlg.h" +#include "TouchButton.h" + +const static int TBD_BTN_TYPE = 1; + +// CTouchButton +extern CTouchBoardDlg *g_pMainDlg; +CxImage CTouchButton::m_ciStatus[MAX_STATUS_COUNT]; +CxImage CTouchButton::m_ciCheck; +BOOL CTouchButton::m_bGlobalInit = false; +INT32 CTouchButton::m_iLongPressMode = TOUCH_BTN_LONG_PRESS_MODE_PRESSING; + +IMPLEMENT_DYNAMIC(CTouchButton, CWnd) + +CTouchButton::CTouchButton() +{ + m_pMemDC = NULL; + m_pDCBitmap = NULL; + m_pDidLinePen = NULL; + m_pFillBrush = NULL; + m_pFont = NULL; + m_pFontSub = NULL; + + m_buttonUiStyle = 2; // 1 : 4 ǥ Ÿ, 2 : 1 ǥ Ÿ + m_iUnderNumber = -1; + m_bPressable = true; + m_bPressed = false; + m_bChecked = false; + m_bCreated = false; + m_bVisible = true; + m_uiPressMessage = 0; + m_iBtnType = TOUCH_BTN_TYPE_LEVEL4; + m_iBtnFlag = TOUCH_BTN_FLAG_STATE; + + m_strName = L"119"; + + for(int i = 0;i < MAX_STATUS_COUNT;i++) + m_bStatus[i] = false; +} + +CTouchButton::~CTouchButton() +{ +} + + +BEGIN_MESSAGE_MAP(CTouchButton, CWnd) + ON_WM_PAINT() + ON_WM_LBUTTONDOWN() + ON_WM_LBUTTONUP() + ON_WM_TIMER() + ON_WM_ERASEBKGND() + ON_WM_LBUTTONDBLCLK() + ON_WM_RBUTTONDOWN() +END_MESSAGE_MAP() + + + +// CTouchButton message handlers + +void CTouchButton::OnPaint() +{ + CPaintDC dc(this); // device context for painting + // TODO: Add your message handler code here + // Do not call CWnd::OnPaint() for painting messages + CBitmap *pOldBitmap; + CPen *pOldPen; + bool isOnAir = false; + + if(m_pMemDC == NULL) { + m_pMemDC = new CDC(); + m_pMemDC->CreateCompatibleDC(&dc); + } + + if(m_pDCBitmap == NULL) { + m_pDCBitmap = new CBitmap(); + m_pDCBitmap->CreateCompatibleBitmap(&dc, m_width, m_height); + } + + if(m_pDidLinePen == NULL) { + m_pDidLinePen = new CPen(); + m_pDidLinePen->CreatePen(PS_SOLID, 1, TOUCH_BTN_LINE_COLOR); + } + + if(m_pFillBrush == NULL) { + m_pFillBrush = new CBrush(); + m_pFillBrush->CreateSolidBrush(RGB(0, 200, 200)); + } + + pOldBitmap = m_pMemDC->SelectObject(m_pDCBitmap); + pOldPen = m_pMemDC->SelectObject(m_pDidLinePen); + + if(m_iBtnType != TOUCH_BTN_TYPE_GROUP) { + if(m_iUnderNumber >= 0) + isOnAir = true; + for(INT32 i = 0;i < MAX_STATUS_COUNT;i++) { + if(m_bStatus[i]) { + isOnAir = true; + } + } + } + + + if(isEnableButton()) { + if(m_bPressed) { + m_pMemDC->FillSolidRect(0, 0, m_width, m_height, TOUCH_BTN_PRESS_COLOR); + } else if(isOnAir) { + m_pMemDC->FillSolidRect(0, 0, m_width, m_height, TOUCH_BTN_ONAIR_COLOR); + } else { + m_pMemDC->FillSolidRect(0, 0, m_width, m_height / 2, TOUCH_BTN_GENERAL_COLOR_UP); + m_pMemDC->FillSolidRect(0, m_height / 2, m_width, m_height / 2, TOUCH_BTN_GENERAL_COLOR_DOWN); + } + } else { + if(m_iBtnType == TOUCH_BTN_TYPE_GROUP) { + m_pMemDC->FillSolidRect(0, 0, m_width, m_height, TOUCH_BTN_GROUP_COLOR_DISABLE); + } else { + m_pMemDC->FillSolidRect(0, 0, m_width, m_height, TOUCH_BTN_GENERAL_COLOR_DISABLE); + } + } + + m_pMemDC->SetBkMode( TRANSPARENT ); + + if(m_iBtnType == TOUCH_BTN_TYPE_LEVEL2 || m_iBtnType == TOUCH_BTN_TYPE_LEVEL3 || m_iBtnType == TOUCH_BTN_TYPE_LEVEL4) { + if(m_buttonUiStyle == 1) { + m_pMemDC->FillSolidRect(0, 0, m_ciStatus[0].GetWidth() * 2, m_ciStatus[0].GetHeight() * 4, TOUCH_BTN_CHECK_BG_COLOR); + + if(m_bStatus[0]) + m_ciStatus[0].Draw2(m_pMemDC->GetSafeHdc(), 0, 0); + if(m_bStatus[1]) + m_ciStatus[1].Draw2(m_pMemDC->GetSafeHdc(), m_ciStatus[0].GetWidth(), 0); + if(m_bStatus[2]) + m_ciStatus[2].Draw2(m_pMemDC->GetSafeHdc(), 0, m_ciStatus[0].GetHeight()); + if(m_bStatus[3]) + m_ciStatus[3].Draw(m_pMemDC->GetSafeHdc(), m_ciStatus[1].GetWidth(), m_ciStatus[1].GetHeight()); + } else if(m_buttonUiStyle == 2) { + //TRACE("BTN WIDTH : %d, HEIGHT : %d\n", m_ciStatus[0].GetWidth(), m_ciStatus[0].GetHeight()); + m_pMemDC->FillSolidRect(0, 0, m_ciStatus[0].GetWidth(), m_ciStatus[0].GetHeight() * 2, TOUCH_BTN_CHECK_BG_COLOR); + for(INT32 i = 0;i < MAX_STATUS_COUNT;i++) { + if(m_bStatus[i]) { + m_ciStatus[i].Draw2(m_pMemDC->GetSafeHdc(), 0, (m_height - m_ciStatus[0].GetHeight()) / 4); + } + } + } + + + if(m_bChecked) { + //m_pMemDC->FillSolidRect(0 + 4, m_ciStatus[0].GetHeight() * 2 + 4, m_ciStatus[0].GetWidth() * 2 - 8, m_ciStatus[0].GetHeight() * 2 - 8, TOUCH_BTN_PRESS_COLOR); + m_ciCheck.Draw(m_pMemDC->GetSafeHdc(), 3, m_ciStatus[1].GetHeight() * 2 + 3); + } + } + + RECT rt; + COLORREF crOldColor = SetTextColor(m_pMemDC->GetSafeHdc(), RGB(0, 0, 0)); + CFont *pOldFont = m_pMemDC->SelectObject(m_pFont); + GetClientRect(&rt); + + if(isEnableButton()) { + if (m_bPressed) { + SetTextColor(m_pMemDC->GetSafeHdc(), TOUCH_BTN_PRESS_FONT_COLOR); + } else { + SetTextColor(m_pMemDC->GetSafeHdc(), TOUCH_BTN_GENERAL_FONT_COLOR); + } + } else { + if(m_iBtnType == TOUCH_BTN_TYPE_GROUP) { + //SetTextColor(m_pMemDC->GetSafeHdc(), RGB(100, 100, 100)); + SetTextColor(m_pMemDC->GetSafeHdc(), TOUCH_BTN_GENERAL_FONT_COLOR); + } else { + SetTextColor(m_pMemDC->GetSafeHdc(), RGB(220, 220, 220)); + } + } + + if(m_iBtnType == TOUCH_BTN_TYPE_LEVEL2 || m_iBtnType == TOUCH_BTN_TYPE_LEVEL3 || m_iBtnType == TOUCH_BTN_TYPE_LEVEL4) { + rt.left = 30; + } + //rt.top = rt.bottom - 40; + ::DrawText(m_pMemDC->GetSafeHdc(), m_strName, m_strName.GetLength(), &rt, DT_SINGLELINE|DT_CENTER|DT_VCENTER); + ::SetTextColor(m_pMemDC->GetSafeHdc(), crOldColor); + + if(m_iUnderNumber >= 0) { + TCHAR strUnder[64]; + RECT rtFill; + GetClientRect(&rt); + GetClientRect(&rtFill); + if(m_buttonUiStyle == 1) { + rt.top = 30; + rt.right = 30; + rtFill.top = 32; + rtFill.right = 30; + } else if(m_buttonUiStyle == 2) { + rt.right = 30; + rtFill.right = 30; + } + + if(m_iUnderNumber > 0) { + wsprintf(strUnder, L"%d", m_iUnderNumber); + } else { + wsprintf(strUnder, L""); + } + m_pMemDC->SelectObject(m_pFontSub); + m_pMemDC->FillRect(&rtFill, m_pFillBrush); + ::DrawText(m_pMemDC->GetSafeHdc(), strUnder, lstrlen(strUnder), &rt, DT_SINGLELINE|DT_CENTER|DT_VCENTER); + } + + m_pMemDC->SelectObject(pOldPen); + + dc.BitBlt(0, 0, m_width, m_height, m_pMemDC, 0, 0, SRCCOPY); + m_pMemDC->SelectObject(pOldBitmap); + m_pMemDC->SelectObject(pOldFont); +} + +BOOL CTouchButton::isEnableButton() +{ + BOOL bResult = TRUE; + if(m_iBtnType == TOUCH_BTN_TYPE_GROUP) { + if(m_bPressed) { + bResult = TRUE; + } else { + bResult = FALSE; + } + } else { + if(!m_bEnabled) { + bResult = FALSE; + } else { + bResult = TRUE; + } + } + + return bResult; +} + +void CTouchButton::initialize(int x, int y, int total_width, int total_height, int ico_width, int ico_height, int id, CWnd *pParent) +{ + m_btnId = id; + m_width = total_width; + m_height = total_height; + RECT size; + size.left = x; + size.top = y; + size.right = x + m_width; + size.bottom = y + m_height; + //Create(L"TB", L"TB", WS_CHILD, size, pParent, id); + DWORD dwStyle = WS_CHILD | WS_BORDER; + if(m_bVisible) + dwStyle |= WS_VISIBLE; + + if(m_bCreated) { + DestroyWindow(); + } + + BOOL ret = Create(NULL, NULL, dwStyle, size, pParent, m_btnId); + if(ret != TRUE) { + TRACE("FAIL CREATE BUTTON!\n"); + MessageBox(L"ư ߽ϴ", L""); + PostMessage(WM_CLOSE); + } + + m_bCreated = TRUE; + + if(!m_bGlobalInit) + { + for(INT32 i = 0;i < MAX_STATUS_COUNT;i++) { + m_ciStatus[i].Create(TBD_BTN_ICON_WIDTH, TBD_BTN_ICON_HEIGHT, 32); + m_ciStatus[i].Clear(); + } + + RGBQUAD color; + m_ciStatus[0].FloodFill(0, 0, RGB_QUAD_RED); + m_ciStatus[1].FloodFill(0, 0, RGB_QUAD_GREEN); + m_ciStatus[2].FloodFill(0, 0, RGB_QUAD_BLUE); + + RGB2RGBQURD(RGB(0, 255, 255), color); + m_ciStatus[3].FloodFill(0, 0, color); + + RGB2RGBQURD(RGB(10, 10, 255), color); + m_ciStatus[4].FloodFill(0, 0, color); + + HINSTANCE hInst = AfxGetInstanceHandle(); + HRSRC res = FindResource(hInst, MAKEINTRESOURCE(IDB_PNG_CHECK), L"PNG"); + m_ciCheck.LoadResource(res, CXIMAGE_FORMAT_PNG, hInst); + + res = FindResource(hInst, MAKEINTRESOURCE(IDB_PNG_ICON_FIRE), L"PNG"); + m_ciStatus[0].LoadResource(res, CXIMAGE_FORMAT_PNG, hInst); + res = FindResource(hInst, MAKEINTRESOURCE(IDB_PNG_ICON_RESCUE), L"PNG"); + m_ciStatus[1].LoadResource(res, CXIMAGE_FORMAT_PNG, hInst); + res = FindResource(hInst, MAKEINTRESOURCE(IDB_PNG_ICON_EMERGENCY), L"PNG"); + m_ciStatus[2].LoadResource(res, CXIMAGE_FORMAT_PNG, hInst); + res = FindResource(hInst, MAKEINTRESOURCE(IDB_PNG_ICON_MIC), L"PNG"); + m_ciStatus[3].LoadResource(res, CXIMAGE_FORMAT_PNG, hInst); + + for(INT32 i = 0;i < 4;i++) { + BOOL res = m_ciStatus[i].Resample(TBD_BTN_ICON_WIDTH, TBD_BTN_ICON_HEIGHT, 0, 0); + if(!res) { + TRACE("RESIZING FAILED...\n"); + } + } + + m_bGlobalInit = true; + m_iLongPressMode = TOUCH_BTN_LONG_PRESS_MODE_PRESSING; + } + + if(!m_bVisible) + ShowWindow(SW_HIDE); +#if 0 + for(int i = 0;i < MAX_STATUS_COUNT;i++) { + m_ciStatus[i].AlphaCreate(); + m_ciStatus[i].AlphaSet(100); + } +#endif +} + + +void CTouchButton::OnLButtonDown(UINT nFlags, CPoint point) +{ + // TODO: Add your message handler code here and/or call default + if(m_iBtnType == TOUCH_BTN_TYPE_GROUP) { + if(m_uiPressMessage) { + AfxGetMainWnd()->PostMessageW(m_uiPressMessage, m_btnId, 0); + } else { + m_bPressed = true; + Invalidate(false); + } + } else { + if(!m_bEnabled) + return; + + m_pressTime = GetTickCount64(); + if(m_iBtnFlag & TOUCH_BTN_FLAG_CHECKABLE) { + SetTimer(1, 500, NULL); + } + } + + CWnd::OnLButtonDown(nFlags, point); +} + + +void CTouchButton::OnLButtonUp(UINT nFlags, CPoint point) +{ + // TODO: Add your message handler code here and/or call default + UINT64 curTick = GetTickCount64(); + + if(m_iBtnType == TOUCH_BTN_TYPE_GROUP) { + } else { + if(curTick - m_pressTime < 500) { + TRACE("CLICK\n"); + SetPressState(~m_bPressed); + //m_bPressed = ~m_bPressed; + } else { + TRACE("LONG CLICK\n"); + } + + if(m_uiPressMessage) { + AfxGetMainWnd()->PostMessageW(m_uiPressMessage, m_btnId, 0); + } + + KillTimer(1); + m_pressTime = 0; + Invalidate(false); + } + + CWnd::OnLButtonUp(nFlags, point); + +} + + +void CTouchButton::OnTimer(UINT_PTR nIDEvent) +{ + // TODO: Add your message handler code here and/or call default + if(nIDEvent == 1) + { + if(m_pressTime > 0) { + if(m_iLongPressMode == TOUCH_BTN_LONG_PRESS_MODE_GROUPING) + { + m_bChecked = ~m_bChecked; + Invalidate(false); + AfxGetMainWnd()->Invalidate(false); + } else if(m_iLongPressMode == TOUCH_BTN_LONG_PRESS_MODE_PRESSING) { + BOOL bNextPressed = ~m_bPressed; + AfxGetMainWnd()->PostMessageW(WM_TBD_SUB_GROUPING, m_btnId, bNextPressed); + } + } + } + + KillTimer(1); + CWnd::OnTimer(nIDEvent); +} + + +BOOL CTouchButton::OnEraseBkgnd(CDC* pDC) +{ + // TODO: Add your message handler code here and/or call default + //return false; + + return CWnd::OnEraseBkgnd(pDC); +} + + +void CTouchButton::OnLButtonDblClk(UINT nFlags, CPoint point) +{ + // TODO: Add your message handler code here and/or call default + + CWnd::OnLButtonDblClk(nFlags, point); +} + + +void CTouchButton::OnRButtonDown(UINT nFlags, CPoint point) +{ + // TODO: Add your message handler code here and/or call default + if(m_iBtnType == TOUCH_BTN_TYPE_GROUP) { + m_bPressed = true; + if(m_uiPressMessage) { + AfxGetMainWnd()->PostMessageW(m_uiPressMessage, m_btnId, 0); + } + Invalidate(false); + } else { + if(m_iBtnFlag & TOUCH_BTN_FLAG_CHECKABLE) { + if(m_iLongPressMode == TOUCH_BTN_LONG_PRESS_MODE_GROUPING) + { + m_bChecked = ~m_bChecked; + Invalidate(false); + AfxGetMainWnd()->Invalidate(false); + } else if(m_iLongPressMode == TOUCH_BTN_LONG_PRESS_MODE_PRESSING) { + BOOL bNextPressed = ~m_bPressed; + AfxGetMainWnd()->PostMessageW(WM_TBD_SUB_GROUPING, m_btnId, bNextPressed); + } + } + } + + CWnd::OnRButtonDown(nFlags, point); +} diff --git a/TouchButton.h b/TouchButton.h new file mode 100644 index 0000000..d532534 --- /dev/null +++ b/TouchButton.h @@ -0,0 +1,96 @@ +#pragma once + +#define MAX_STATUS_COUNT 5 + +#define TOUCH_BTN_LINE_COLOR RGB(10, 10, 10) +#define TOUCH_BTN_LINE_COLOR_DISABLE RGB(103, 103, 103) +#define TOUCH_BTN_GENERAL_COLOR_UP RGB(233, 233, 233) +#define TOUCH_BTN_GENERAL_COLOR_DOWN RGB(223, 223, 223) +#define TOUCH_BTN_GROUP_COLOR_DISABLE RGB(245, 245, 245) +#define TOUCH_BTN_GENERAL_COLOR_DISABLE RGB(90, 90, 90) + //#define TOUCH_BTN_PRESS_COLOR RGB(130, 255, 130) +#define TOUCH_BTN_PRESS_COLOR RGB(57, 119, 206) +#define TOUCH_BTN_ONAIR_COLOR RGB(200, 200, 0) +#define TOUCH_BTN_CHECK_BG_COLOR RGB(254, 254, 254) + +#define TOUCH_BTN_PRESS_FONT_COLOR RGB(255, 255, 255) +#define TOUCH_BTN_GENERAL_FONT_COLOR RGB(0, 0, 0) + +#define TOUCH_BTN_TYPE_GROUP 1 +#define TOUCH_BTN_TYPE_LEVEL2 2 +#define TOUCH_BTN_TYPE_LEVEL3 3 +#define TOUCH_BTN_TYPE_LEVEL4 4 + +#define TOUCH_BTN_FLAG_STATE 0x0001 +#define TOUCH_BTN_FLAG_CHECKABLE 0x0002 + +#define TOUCH_BTN_LONG_PRESS_MODE_GROUPING 1 +#define TOUCH_BTN_LONG_PRESS_MODE_PRESSING 2 + +// CTouchButton + +class CTouchButton : public CWnd +{ + DECLARE_DYNAMIC(CTouchButton) + +public: + static CxImage m_ciStatus[MAX_STATUS_COUNT]; // 0 : FIRE, 1 : RESQUE, 2 : EMERGENCY, 3 : MIC, 4 : TOUCHED + static CxImage m_ciCheck; + static BOOL m_bGlobalInit; + static INT32 m_iLongPressMode; + INT32 m_width; + INT32 m_height; + INT32 m_buttonUiStyle; + CDC* m_pMemDC; + CBitmap* m_pDCBitmap; + CPen* m_pDidLinePen; + CBrush* m_pFillBrush; + CFont* m_pFont; + CFont* m_pFontSub; + + BOOL m_bCreated; + BOOL m_bVisible; + UINT64 m_pressTime; + BOOL m_bPressed; + BOOL m_bEnabled; + BOOL m_bChecked; + CString m_strName; + INT32 m_btnId; + UINT m_uiPressMessage; + INT32 m_iBtnType; + INT32 m_iBtnFlag; + BOOL m_bPressable; + + INT32 m_iUnderNumber; + + BOOL m_bStatus[MAX_STATUS_COUNT]; + + CTouchButton(); + virtual ~CTouchButton(); + + void initialize(int x, int y, int total_width, int total_height, int ico_width, int ico_height, int id, CWnd *pParent = NULL); + void SetPressState(BOOL bPress) { + BOOL prevState = m_bPressed; + if(!m_bPressable) + return; + + m_bPressed = bPress; + if(m_bPressed != prevState) + Invalidate(false); + } + + BOOL isEnableButton(); + +protected: + DECLARE_MESSAGE_MAP() +public: + afx_msg void OnPaint(); + afx_msg void OnLButtonDown(UINT nFlags, CPoint point); + afx_msg void OnLButtonUp(UINT nFlags, CPoint point); + afx_msg void OnTimer(UINT_PTR nIDEvent); + afx_msg BOOL OnEraseBkgnd(CDC* pDC); + afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point); + afx_msg void OnRButtonDown(UINT nFlags, CPoint point); +}; + + diff --git a/TouchSetupDlg.cpp b/TouchSetupDlg.cpp new file mode 100644 index 0000000..55ae0a1 --- /dev/null +++ b/TouchSetupDlg.cpp @@ -0,0 +1,360 @@ +// TouchSetupDlg.cpp : implementation file +// + +#include "stdafx.h" +#include "TouchBoard.h" +#include "TouchSetupDlg.h" +#include "TouchBoardDlg.h" +#include "afxdialogex.h" + + +// CTouchSetupDlg dialog + +extern CTouchBoardDlg *g_pMainDlg; + +IMPLEMENT_DYNAMIC(CTouchSetupDlg, CDialogEx) + +CTouchSetupDlg::CTouchSetupDlg(CWnd* pParent /*=NULL*/) + : CDialogEx(CTouchSetupDlg::IDD, pParent) +{ + m_bSendLineIn = FALSE; + ZeroMemory(m_ctAddr, sizeof(m_ctAddr)); + ZeroMemory(m_esAddr, sizeof(m_esAddr)); + ZeroMemory(m_psAddr, sizeof(m_psAddr)); +} + +CTouchSetupDlg::~CTouchSetupDlg() +{ +} + +void CTouchSetupDlg::DoDataExchange(CDataExchange* pDX) +{ + CDialogEx::DoDataExchange(pDX); +} + + +BEGIN_MESSAGE_MAP(CTouchSetupDlg, CDialogEx) + ON_BN_CLICKED(IDC_BUTTON_SELECT1, &CTouchSetupDlg::OnBnClickedButtonSelect1) + ON_BN_CLICKED(IDC_BUTTON_SELECT2, &CTouchSetupDlg::OnBnClickedButtonSelect2) + ON_BN_CLICKED(IDC_BUTTON_SAVE, &CTouchSetupDlg::OnBnClickedButtonSave) + ON_BN_CLICKED(IDC_BUTTON_MICVOL_MINUS, &CTouchSetupDlg::OnBnClickedButtonMicvolMinus) + ON_BN_CLICKED(IDC_BUTTON_MICVOL_PLUS, &CTouchSetupDlg::OnBnClickedButtonMicvolPlus) + ON_BN_CLICKED(IDC_BUTTON_LINEVOL_MINUS, &CTouchSetupDlg::OnBnClickedButtonLinevolMinus) + ON_BN_CLICKED(IDC_BUTTON_LINEVOL_PLUS, &CTouchSetupDlg::OnBnClickedButtonLinevolPlus) + ON_BN_CLICKED(IDC_CHECK_LINESEND, &CTouchSetupDlg::OnBnClickedCheckLinesend) + ON_BN_CLICKED(IDCANCEL, &CTouchSetupDlg::OnBnClickedCancel) +END_MESSAGE_MAP() + + +// CTouchSetupDlg message handlers + + +void CTouchSetupDlg::OnBnClickedButtonSelect1() +{ + // TODO: Add your control notification handler code here + TCHAR szFilter[] = L"(*.exe)|*.exe|All Files(*.*)|*.*||"; + CString strPathName; + CFileDialog dlg(TRUE, NULL, NULL, OFN_HIDEREADONLY, szFilter); + + if(IDOK == dlg.DoModal()) { + strPathName = dlg.GetPathName(); + GetDlgItem(IDC_EDIT_WIRELESS_EXEC)->SetWindowTextW(strPathName); + } + TRACE("pszPathname : %S", strPathName); +} + + +void CTouchSetupDlg::OnBnClickedButtonSelect2() +{ + // TODO: Add your control notification handler code here + TCHAR szFilter[] = L"(*.exe)|*.exe|All Files(*.*)|*.*||"; + CString strPathName; + CFileDialog dlg(TRUE, NULL, NULL, OFN_HIDEREADONLY, szFilter); + + if(IDOK == dlg.DoModal()) { + strPathName = dlg.GetPathName(); + GetDlgItem(IDC_EDIT_CALL_EXEC)->SetWindowTextW(strPathName); + } +} + + +void CTouchSetupDlg::LoadSettings() +{ + TCHAR strPath[512] = {0, }; + CString strFilePath; + HRESULT hr = SHGetFolderPath(0, CSIDL_LOCAL_APPDATA, 0, 0, strPath); + FILE *fp = NULL; + + strFilePath = strPath; + strFilePath += L"\\touch_setting.txt"; + m_bSendTTS = FALSE; + + _wfopen_s(&fp, strFilePath, L"rt"); + if(fp) + { + char strLine[128 * 1024]; + char strData[128 * 1024]; + char *pResult; + int isChecked; + + while(!feof(fp)) + { + ZeroMemory(strLine, sizeof(strLine)); + pResult = fgets(strLine, sizeof(strLine), fp); + if(!pResult) + break; + + ZeroMemory(strData, sizeof(strData)); + if (strncmp(strLine, "CT_ADDRESS=", strlen("CT_ADDRESS=")) == 0) { + INT32 value[4]; + sscanf_s(strLine, "CT_ADDRESS=%d.%d.%d.%d", &value[0], &value[1], &value[2], &value[3]); + for (int i = 0; i < 4; i++) + m_ctAddr[i] = value[i]; + //swscanf_s(strLine, L"CT_ADDRESS=%d.%d.%d.%d", &m_ctAddr[0], &m_ctAddr[1], &m_ctAddr[2], &m_ctAddr[3]); + } else if (strncmp(strLine, "ES_ADDRESS=", strlen("ES_ADDRESS=")) == 0) { + INT32 value[4]; + sscanf_s(strLine, "ES_ADDRESS=%d.%d.%d.%d", &value[0], &value[1], &value[2], &value[3]); + for (int i = 0; i < 4; i++) + m_esAddr[i] = value[i]; + } else if (strncmp(strLine, "PS_ADDRESS=", strlen("PS_ADDRESS=")) == 0) { + INT32 value[4]; + sscanf_s(strLine, "PS_ADDRESS=%d.%d.%d.%d", &value[0], &value[1], &value[2], &value[3]); + for (int i = 0; i < 4; i++) + m_psAddr[i] = value[i]; + } else if(strncmp(strLine, "WIRELESS_PATH=", strlen("WIRELESS_PATH=")) == 0) { + sscanf_s(strLine, "WIRELESS_PATH=%[^\r\n]", strData, _countof(strData)); + m_strWirelessPath = strData; + } else if(strncmp(strLine, "CALL_PATH=", strlen("CALL_PATH=")) == 0) { + sscanf_s(strLine, "CALL_PATH=%[^\r\n]", strData, _countof(strData)); + m_strCallPath = strData; + } else if(strncmp(strLine, "SEND_TTS_MSG=", strlen("SEND_TTS_MSG=")) == 0) { + sscanf_s(strLine, "SEND_TTS_MSG=%[^\r\n]", strData, _countof(strData)); + if(atoi(strData) == 1) { + //m_bSendTTS = TRUE; + } + } else if(strncmp(strLine, "TTS_MSG=", strlen("TTS_MSG=")) == 0) { + UTF8_CONVERSION_EX; + sscanf_s(strLine, "TTS_MSG=%[^\r\n]", strData, _countof(strData)); + m_strTTSMessage = UTF82W_EX((char *)strData); + m_strTTSMessage.Replace(L"|", L"\r\n"); + } + } + fclose(fp); + + TRACE(L"LOAD SETTINGS : %s\n", strFilePath); + } + else + { + for(INT32 i = 0;i < 4;i++) + m_ctAddr[i] = 0; + + m_strWirelessPath = ""; + m_strCallPath = ""; + } +} + +void CTouchSetupDlg::SaveSettings() +{ + TCHAR strPath[512] = {0, }; + CString strFilePath; + CString strInfo; + UINT isChecked; + HRESULT hr = SHGetFolderPath(0, CSIDL_LOCAL_APPDATA, 0, 0, strPath); + FILE *fp = NULL; + BYTE addr[4]; + BOOL isIpChanged = false; + + strFilePath = strPath; + strFilePath += L"\\touch_setting.txt"; + + CIPAddressCtrl *pCtrl = (CIPAddressCtrl *)GetDlgItem(IDC_IPADDRESS_CT); + pCtrl->GetAddress(addr[0], addr[1], addr[2], addr[3]); + for(INT32 i = 0;i < 4;i++) { + if(addr[i] != m_ctAddr[i]) + isIpChanged = true; + + m_ctAddr[i] = addr[i]; + } + + pCtrl = (CIPAddressCtrl *)GetDlgItem(IDC_IPADDRESS_ES); + pCtrl->GetAddress(addr[0], addr[1], addr[2], addr[3]); + for (INT32 i = 0; i < 4; i++) { + if (addr[i] != m_esAddr[i]) + isIpChanged = true; + + m_esAddr[i] = addr[i]; + } + + pCtrl = (CIPAddressCtrl *)GetDlgItem(IDC_IPADDRESS_PS); + pCtrl->GetAddress(addr[0], addr[1], addr[2], addr[3]); + for (INT32 i = 0; i < 4; i++) { + if (addr[i] != m_psAddr[i]) + isIpChanged = true; + + m_psAddr[i] = addr[i]; + } + + //pCtrl->GetAddress(m_ctAddr[0], m_ctAddr[1], m_ctAddr[2], m_ctAddr[3]); + CEdit *pEdit = (CEdit *)GetDlgItem(IDC_EDIT_CALL_EXEC); + pEdit->GetWindowTextW(m_strCallPath); + pEdit = (CEdit *)GetDlgItem(IDC_EDIT_WIRELESS_EXEC); + pEdit->GetWindowTextW(m_strWirelessPath); + + pEdit = (CEdit *)GetDlgItem(IDC_EDIT_TTS); + pEdit->GetWindowTextW(m_strTTSMessage); + + CButton *pBox = (CButton *)GetDlgItem(IDC_CHECK_TTS); + if(pBox->GetCheck()) { + m_bSendTTS = TRUE; + } else { + m_bSendTTS = FALSE; + } + + if(m_bSendTTS) { + if(m_strTTSMessage.GetLength() > 0) { + char strTTSMessage[128 * 1024]; + UTF8_CONVERSION_EX; + CString strMsg = m_strTTSMessage; + strMsg.Replace(L"\r\n", L"."); + sprintf(strTTSMessage, "BYPASS\r\nREQUEST_TTS_MESSAGE=0|%s\r\n", W2UTF8_EX(strMsg)); + g_pMainDlg->SocketSendExceptionHandle(strTTSMessage, strlen(strTTSMessage)); + } + } + + _wfopen_s(&fp, strFilePath, L"wt"); + if(fp) + { + fprintf(fp, "CT_ADDRESS=%d.%d.%d.%d\r\n", m_ctAddr[0], m_ctAddr[1], m_ctAddr[2], m_ctAddr[3]); + fprintf(fp, "ES_ADDRESS=%d.%d.%d.%d\r\n", m_esAddr[0], m_esAddr[1], m_esAddr[2], m_esAddr[3]); + fprintf(fp, "PS_ADDRESS=%d.%d.%d.%d\r\n", m_psAddr[0], m_psAddr[1], m_psAddr[2], m_psAddr[3]); + fprintf(fp, "WIRELESS_PATH=%S\r\n", m_strWirelessPath); + fprintf(fp, "CALL_PATH=%S\r\n", m_strCallPath); + + if(m_bSendTTS) + fprintf(fp, "SEND_TTS_MSG=1\r\n"); + if(m_strTTSMessage.GetLength() > 0) { + UTF8_CONVERSION_EX; + CString strMsg = m_strTTSMessage; + strMsg.Replace(L"\r\n", L"|"); + fprintf(fp, "TTS_MSG=%s\r\n", W2UTF8_EX(strMsg)); + } + fclose(fp); + + TRACE(L"SAVE SETTINGS : %s\n", strFilePath); + MessageBox(L" Ǿϴ"); + ShowWindow(SW_HIDE); + } + + AfxGetMainWnd()->PostMessage(WM_TBD_SETUP_SAVE, isIpChanged); +} + + +void CTouchSetupDlg::UpdateVariableToCtrl() +{ + CIPAddressCtrl *pCtrl = (CIPAddressCtrl *)GetDlgItem(IDC_IPADDRESS_CT); + pCtrl->SetAddress(m_ctAddr[0], m_ctAddr[1], m_ctAddr[2], m_ctAddr[3]); + CEdit *pEdit = (CEdit *)GetDlgItem(IDC_EDIT_CALL_EXEC); + pEdit->SetWindowTextW(m_strCallPath); + pEdit = (CEdit *)GetDlgItem(IDC_EDIT_WIRELESS_EXEC); + pEdit->SetWindowTextW(m_strWirelessPath); + pEdit = (CEdit *)GetDlgItem(IDC_EDIT_TTS); + pEdit->SetWindowTextW(m_strTTSMessage); + + pCtrl = (CIPAddressCtrl *)GetDlgItem(IDC_IPADDRESS_ES); + pCtrl->SetAddress(m_esAddr[0], m_esAddr[1], m_esAddr[2], m_esAddr[3]); + pCtrl = (CIPAddressCtrl *)GetDlgItem(IDC_IPADDRESS_PS); + pCtrl->SetAddress(m_psAddr[0], m_psAddr[1], m_psAddr[2], m_psAddr[3]); + + + CButton *pBox = (CButton *)GetDlgItem(IDC_CHECK_TTS); + if(m_bSendTTS) + pBox->SetCheck(TRUE); +} + +void CTouchSetupDlg::OnBnClickedButtonSave() +{ + // TODO: Add your control notification handler code here + + SaveSettings(); +} + + + + +void CTouchSetupDlg::OnBnClickedButtonMicvolMinus() +{ + // TODO: Add your control notification handler code here + char strMessage[256]; + sprintf(strMessage, "MIC_VOLUME=MINUS\r\n\r\n"); + g_pMainDlg->SocketSendExceptionHandle(strMessage, strlen(strMessage)); + +} + + +void CTouchSetupDlg::OnBnClickedButtonMicvolPlus() +{ + // TODO: Add your control notification handler code here + char strMessage[256]; + sprintf(strMessage, "MIC_VOLUME=PLUS\r\n\r\n"); + g_pMainDlg->SocketSendExceptionHandle(strMessage, strlen(strMessage)); +} + + +void CTouchSetupDlg::OnBnClickedButtonLinevolMinus() +{ + // TODO: Add your control notification handler code here + char strMessage[256]; + sprintf(strMessage, "LINEIN_VOLUME=MINUS\r\n\r\n"); + g_pMainDlg->SocketSendExceptionHandle(strMessage, strlen(strMessage)); +} + + +void CTouchSetupDlg::OnBnClickedButtonLinevolPlus() +{ + // TODO: Add your control notification handler code here + char strMessage[256]; + sprintf(strMessage, "LINEIN_VOLUME=PLUS\r\n\r\n"); + g_pMainDlg->SocketSendExceptionHandle(strMessage, strlen(strMessage)); +} + + +BOOL CTouchSetupDlg::PreTranslateMessage(MSG* pMsg) +{ + // TODO: Add your specialized code here and/or call the base class + + if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_RETURN) + { + if (GetDlgItem(IDC_EDIT_TTS) == GetFocus()) + { + CEdit* edit = (CEdit*)GetDlgItem(IDC_EDIT_TTS); + int nLen = edit->GetWindowTextLength(); + edit->SetSel( nLen, nLen ); + edit->ReplaceSel(_T("\r\n")); + } + } + + return CDialogEx::PreTranslateMessage(pMsg); +} + + +void CTouchSetupDlg::OnBnClickedCheckLinesend() +{ + // TODO: Add your control notification handler code here + + CButton *pBox = (CButton *)GetDlgItem(IDC_CHECK_LINESEND); + CWnd *pWnd = (CWnd *)g_pMainDlg->GetDlgItem(IDC_STATIC_LINEIN); + if(pBox->GetCheck()) { + m_bSendLineIn = TRUE; + pWnd->ShowWindow(SW_SHOW); + } else { + m_bSendLineIn = FALSE; + pWnd->ShowWindow(SW_HIDE); + } +} + + +void CTouchSetupDlg::OnBnClickedCancel() +{ + // TODO: ⿡ Ʈ ˸ ó ڵ带 ߰մϴ. + CDialogEx::OnCancel(); +} diff --git a/TouchSetupDlg.h b/TouchSetupDlg.h new file mode 100644 index 0000000..13e01d1 --- /dev/null +++ b/TouchSetupDlg.h @@ -0,0 +1,45 @@ +#pragma once + + +// CTouchSetupDlg dialog + +class CTouchSetupDlg : public CDialogEx +{ + DECLARE_DYNAMIC(CTouchSetupDlg) + +public: + CTouchSetupDlg(CWnd* pParent = NULL); // standard constructor + virtual ~CTouchSetupDlg(); + + void LoadSettings(); + void SaveSettings(); + void UpdateVariableToCtrl(); + + BYTE m_ctAddr[4]; + BYTE m_esAddr[4]; + BYTE m_psAddr[4]; + CString m_strWirelessPath; + CString m_strCallPath; + CString m_strTTSMessage; + BOOL m_bSendTTS; + BOOL m_bSendLineIn; + +// Dialog Data + enum { IDD = IDD_SETUP_DIALOG }; + +protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + + DECLARE_MESSAGE_MAP() +public: + afx_msg void OnBnClickedButtonSelect1(); + afx_msg void OnBnClickedButtonSelect2(); + afx_msg void OnBnClickedButtonSave(); + afx_msg void OnBnClickedButtonMicvolMinus(); + afx_msg void OnBnClickedButtonMicvolPlus(); + afx_msg void OnBnClickedButtonLinevolMinus(); + afx_msg void OnBnClickedButtonLinevolPlus(); + virtual BOOL PreTranslateMessage(MSG* pMsg); + afx_msg void OnBnClickedCheckLinesend(); + afx_msg void OnBnClickedCancel(); +}; diff --git a/UTF8Conv.h b/UTF8Conv.h new file mode 100644 index 0000000..2007f37 --- /dev/null +++ b/UTF8Conv.h @@ -0,0 +1,223 @@ +/** +* Copyright (C) 2008 by Kyung-jin Kim +* e-mail : devmachine@naver.com +* +* +* Description : UTF-8 String Conversion Macros +* Created : Jun-13,2008 +* Version : UTF8Conv V1.1 +*/ + +/** +* The names of the UTF-8 string conversion macros take the form. +* SourceType2DestinationType[EX] ex) W2UTF8, UTF82A_EX +* +* SourceType and DestinationType are described below. +* A (ANSI character string.) +* W (Unicode character string.) +* T (Generic character string.) +* UTF8 (UTF-8 encoded character string.) +* +* When using an UTF-8 conversion macro, specify the UTF8_CONVERSION[EX] macro +* at the beginning of your function in order to avoid compiler errors. +* +* Sample code +* void SampleFunc(LPCTSTR lpsz) +* { +* UTF8_CONVERSION; +* LPSTR utf8 = T2UTF8(lpsz); +* +* // Do something with utf8 +* ... +* } +*/ + +#pragma once +#include +#include + +template +class _SafeAllocator +{ +public: + _SafeAllocator() {} + ~_SafeAllocator() + { + int nCount = static_cast(_parray.size()); + for (int i = 0; i < nCount; ++i) + { + if (_parray[i] != NULL) + delete [] _parray[i]; + } + } + + int Alloc(int nSize) + { + Ty* ptr; + ptr = new Ty[nSize]; + if (!ptr) + return -1; + + _parray.push_back(ptr); + return static_cast(_parray.size() - 1); + } + + void Free(int nIndex) + { + delete _parray[nIndex]; + _parray[nIndex] = NULL; + } + + Ty* GetPtr(int nIndex) const + { + return _parray[nIndex]; + } + +private: + std::vector _parray; +}; + +inline LPSTR WINAPI _W2UTF8Helper(LPSTR lpu, LPCWSTR lpw, int nChars) +{ + ASSERT(lpu != NULL); + ASSERT(lpw != NULL); + if (lpu == NULL || lpw == NULL) + return NULL; + + lpu[0] = '\0'; + int ret = WideCharToMultiByte(CP_UTF8, 0, lpw, -1, lpu, nChars, 0, 0); + if (ret == 0) + { + ASSERT(FALSE); + return NULL; + } + return lpu; +} + +inline LPWSTR WINAPI _UTF82WHelper(LPWSTR lpw, LPCSTR lpu, int nChars) +{ + ASSERT(lpw != NULL); + ASSERT(lpu != NULL); + if (lpw == NULL || lpu == NULL) + return NULL; + + lpw[0] = '\0'; + int ret = MultiByteToWideChar(CP_UTF8, 0, lpu, -1, lpw, nChars); + if (ret == 0) + { + ASSERT(FALSE); + return NULL; + } + return lpw; +} + +inline LPWSTR WINAPI _A2WHelper(LPWSTR lpw, LPCSTR lpa, int nChars) +{ + ASSERT(lpw != NULL); + ASSERT(lpa != NULL); + if (lpw == NULL || lpa == NULL) + return NULL; + + lpw[0] = '\0'; + int ret = MultiByteToWideChar(CP_ACP, 0, lpa, -1, lpw, nChars); + if (ret == 0) + { + ASSERT(FALSE); + return NULL; + } + return lpw; +} + +inline LPSTR WINAPI _W2AHelper(LPSTR lpa, LPCWSTR lpw, int nChars) +{ + ASSERT(lpa != NULL); + ASSERT(lpw != NULL); + if (lpa == NULL || lpw == NULL) + return NULL; + + lpa[0] = '\0'; + int ret = WideCharToMultiByte(CP_ACP, 0, lpw, -1, lpa, nChars, 0, 0); + if (ret == 0) + { + ASSERT(FALSE); + return NULL; + } + return lpa; +} + +#define UTF8_CONVERSION int _conv_uc; (_conv_uc); LPCWSTR _lpw_uc; (_lpw_uc); LPCSTR _lpa_uc; (_lpa_uc); LPCSTR _lpu_uc; (_lpu_uc); + +#define A2UTF8(lpa) (\ + ((_lpa_uc = lpa) == NULL) ? NULL : (\ + _conv_uc = MultiByteToWideChar(CP_ACP, 0, _lpa_uc, -1, NULL, 0) * sizeof(WCHAR),\ + _lpw_uc = _A2WHelper((LPWSTR)_alloca(_conv_uc), _lpa_uc, _conv_uc),\ + _conv_uc = WideCharToMultiByte(CP_UTF8, 0, _lpw_uc, -1, NULL, 0, 0, 0) * sizeof(CHAR),\ + _W2UTF8Helper((LPSTR)_alloca(_conv_uc), _lpw_uc, _conv_uc))) + +#define W2UTF8(lpw) (\ + ((_lpw_uc = lpw) == NULL) ? NULL : (\ + _conv_uc = WideCharToMultiByte(CP_UTF8, 0, _lpw_uc, -1, NULL, 0, 0, 0) * sizeof(CHAR),\ + _W2UTF8Helper((LPSTR)_alloca(_conv_uc), _lpw_uc, _conv_uc))) + +#define UTF82A(lpu) (\ + ((_lpu_uc = lpu) == NULL) ? NULL : (\ + _conv_uc = MultiByteToWideChar(CP_UTF8, 0, _lpu_uc, -1, NULL, 0) * sizeof(WCHAR),\ + _lpw_uc = _UTF82WHelper((LPWSTR)_alloca(_conv_uc), _lpu_uc, _conv_uc),\ + _conv_uc = WideCharToMultiByte(CP_ACP, 0, _lpw_uc, -1, NULL, 0, 0, 0) * sizeof(CHAR),\ + _W2AHelper((LPSTR)_alloca(_conv_uc), _lpw_uc, _conv_uc))) + +#define UTF82W(lpu) (\ + ((_lpu_uc = lpu) == NULL) ? NULL : (\ + _conv_uc = MultiByteToWideChar(CP_UTF8, 0, _lpu_uc, -1, NULL, 0) * sizeof(WCHAR),\ + _UTF82WHelper((LPWSTR)_alloca(_conv_uc), _lpu_uc, _conv_uc))) + +#ifdef _UNICODE + #define T2UTF8 W2UTF8 + #define UTF82T UTF82W +#else + #define T2UTF8 A2UTF8 + #define UTF82T UTF82A +#endif + +#define UTF8_CONVERSION_EX int _conv_uc_ex, _idx1, _idx2; (_conv_uc_ex); (_idx1); (_idx2);\ + _SafeAllocator _saw; _SafeAllocator _saa; _SafeAllocator _sau + +#define A2UTF8_EX(lpa) (\ + ((LPCSTR)lpa == NULL) ? NULL : (\ + _conv_uc_ex = MultiByteToWideChar(CP_ACP, 0, lpa, -1, NULL, 0),\ + ((_idx1 = _saw.Alloc(_conv_uc_ex)) == -1) ? NULL : (\ + _A2WHelper(_saw.GetPtr(_idx1), lpa, _conv_uc_ex),\ + _conv_uc_ex = WideCharToMultiByte(CP_UTF8, 0, _saw.GetPtr(_idx1), -1, NULL, 0, 0, 0),\ + ((_idx2 = _sau.Alloc(_conv_uc_ex)) == -1) ? _saw.Free(_idx1), NULL : (\ + _W2UTF8Helper(_sau.GetPtr(_idx2), _saw.GetPtr(_idx1), _conv_uc_ex),\ + _saw.Free(_idx1), _sau.GetPtr(_idx2))))) + +#define W2UTF8_EX(lpw) (\ + ((LPCWSTR)lpw == NULL) ? NULL : (\ + _conv_uc_ex = WideCharToMultiByte(CP_UTF8, 0, lpw, -1, NULL, 0, 0, 0),\ + ((_idx1 = _sau.Alloc(_conv_uc_ex)) == -1) ? NULL : (\ + _W2UTF8Helper(_sau.GetPtr(_idx1), lpw, _conv_uc_ex)))) + +#define UTF82A_EX(lpu) (\ + ((LPCSTR)lpu == NULL) ? NULL : (\ + _conv_uc_ex = MultiByteToWideChar(CP_UTF8, 0, lpu, -1, NULL, 0),\ + ((_idx1 = _saw.Alloc(_conv_uc_ex)) == -1) ? NULL : (\ + _UTF82WHelper(_saw.GetPtr(_idx1), lpu, _conv_uc_ex),\ + _conv_uc_ex = WideCharToMultiByte(CP_ACP, 0, _saw.GetPtr(_idx1), -1, NULL, 0, 0, 0),\ + ((_idx2 = _saa.Alloc(_conv_uc_ex)) == -1) ? _saw.Free(_idx1), NULL : (\ + _W2AHelper(_saa.GetPtr(_idx2), _saw.GetPtr(_idx1), _conv_uc_ex),\ + _saw.Free(_idx1), _saa.GetPtr(_idx2))))) + +#define UTF82W_EX(lpu) (\ + ((LPCSTR)lpu == NULL) ? NULL : (\ + _conv_uc_ex = MultiByteToWideChar(CP_UTF8, 0, lpu, -1, NULL, 0),\ + ((_idx1 = _saw.Alloc(_conv_uc_ex)) == -1) ? NULL : (\ + _UTF82WHelper(_saw.GetPtr(_idx1), lpu, _conv_uc_ex)))) + +#ifdef _UNICODE + #define T2UTF8_EX W2UTF8_EX + #define UTF82T_EX UTF82W_EX +#else + #define T2UTF8_EX A2UTF8_EX + #define UTF82T_EX UTF82A_EX +#endif \ No newline at end of file diff --git a/cximage/Jpeg.lib b/cximage/Jpeg.lib new file mode 100644 index 0000000..0440753 Binary files /dev/null and b/cximage/Jpeg.lib differ diff --git a/cximage/Tiff.lib b/cximage/Tiff.lib new file mode 100644 index 0000000..812fbd5 Binary files /dev/null and b/cximage/Tiff.lib differ diff --git a/cximage/cximage.lib b/cximage/cximage.lib new file mode 100644 index 0000000..e397e3c Binary files /dev/null and b/cximage/cximage.lib differ diff --git a/cximage/debug/Jpeg.lib b/cximage/debug/Jpeg.lib new file mode 100644 index 0000000..0577411 Binary files /dev/null and b/cximage/debug/Jpeg.lib differ diff --git a/cximage/debug/Tiff.lib b/cximage/debug/Tiff.lib new file mode 100644 index 0000000..cb14e32 Binary files /dev/null and b/cximage/debug/Tiff.lib differ diff --git a/cximage/debug/cximage.lib b/cximage/debug/cximage.lib new file mode 100644 index 0000000..5a51409 Binary files /dev/null and b/cximage/debug/cximage.lib differ diff --git a/cximage/debug/jasper.lib b/cximage/debug/jasper.lib new file mode 100644 index 0000000..12cb1f7 Binary files /dev/null and b/cximage/debug/jasper.lib differ diff --git a/cximage/debug/libdcr.lib b/cximage/debug/libdcr.lib new file mode 100644 index 0000000..e9f5390 Binary files /dev/null and b/cximage/debug/libdcr.lib differ diff --git a/cximage/debug/libpsd.lib b/cximage/debug/libpsd.lib new file mode 100644 index 0000000..53a887c Binary files /dev/null and b/cximage/debug/libpsd.lib differ diff --git a/cximage/debug/mng.lib b/cximage/debug/mng.lib new file mode 100644 index 0000000..0e89574 Binary files /dev/null and b/cximage/debug/mng.lib differ diff --git a/cximage/debug/png.lib b/cximage/debug/png.lib new file mode 100644 index 0000000..b391ec6 Binary files /dev/null and b/cximage/debug/png.lib differ diff --git a/cximage/debug/zlib.lib b/cximage/debug/zlib.lib new file mode 100644 index 0000000..a62f7f1 Binary files /dev/null and b/cximage/debug/zlib.lib differ diff --git a/cximage/jasper.lib b/cximage/jasper.lib new file mode 100644 index 0000000..c50794d Binary files /dev/null and b/cximage/jasper.lib differ diff --git a/cximage/libdcr.lib b/cximage/libdcr.lib new file mode 100644 index 0000000..aff5566 Binary files /dev/null and b/cximage/libdcr.lib differ diff --git a/cximage/libpsd.lib b/cximage/libpsd.lib new file mode 100644 index 0000000..6d35ab9 Binary files /dev/null and b/cximage/libpsd.lib differ diff --git a/cximage/mng.lib b/cximage/mng.lib new file mode 100644 index 0000000..047873e Binary files /dev/null and b/cximage/mng.lib differ diff --git a/cximage/png.lib b/cximage/png.lib new file mode 100644 index 0000000..b9f873d Binary files /dev/null and b/cximage/png.lib differ diff --git a/cximage/xfile.h b/cximage/xfile.h new file mode 100644 index 0000000..75e022e --- /dev/null +++ b/cximage/xfile.h @@ -0,0 +1,79 @@ +/* + * File: xfile.h + * Purpose: General Purpose File Class + */ +/* + -------------------------------------------------------------------------------- + + COPYRIGHT NOTICE, DISCLAIMER, and LICENSE: + + CxFile (c) 11/May/2002 Davide Pizzolato - www.xdp.it + CxFile version 2.00 23/Aug/2002 + CxFile version 2.10 16/Dec/2007 + + Special thanks to Chris Shearer Cooper for new features, enhancements and bugfixes + + Covered code is provided under this license on an "as is" basis, without warranty + of any kind, either expressed or implied, including, without limitation, warranties + that the covered code is free of defects, merchantable, fit for a particular purpose + or non-infringing. The entire risk as to the quality and performance of the covered + code is with you. Should any covered code prove defective in any respect, you (not + the initial developer or any other contributor) assume the cost of any necessary + servicing, repair or correction. This disclaimer of warranty constitutes an essential + part of this license. No use of any covered code is authorized hereunder except under + this disclaimer. + + Permission is hereby granted to use, copy, modify, and distribute this + source code, or portions hereof, for any purpose, including commercial applications, + freely and without fee, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + + 3. This notice may not be removed or altered from any source distribution. + -------------------------------------------------------------------------------- + */ +#if !defined(__xfile_h) +#define __xfile_h + +#if defined (WIN32) || defined (_WIN32_WCE) + #include +#endif + +#include +#include + +#include "ximadef.h" + +class DLL_EXP CxFile +{ +public: + CxFile(void) { }; + virtual ~CxFile() { }; + + virtual bool Close() = 0; + virtual size_t Read(void *buffer, size_t size, size_t count) = 0; + virtual size_t Write(const void *buffer, size_t size, size_t count) = 0; + virtual bool Seek(int32_t offset, int32_t origin) = 0; + virtual int32_t Tell() = 0; + virtual int32_t Size() = 0; + virtual bool Flush() = 0; + virtual bool Eof() = 0; + virtual int32_t Error() = 0; + virtual bool PutC(uint8_t c) + { + // Default implementation + size_t nWrote = Write(&c, 1, 1); + return (bool)(nWrote == 1); + } + virtual int32_t GetC() = 0; + virtual char * GetS(char *string, int32_t n) = 0; + virtual int32_t Scanf(const char *format, void* output) = 0; +}; + +#endif //__xfile_h diff --git a/cximage/ximabmp.h b/cximage/ximabmp.h new file mode 100644 index 0000000..d0f137b --- /dev/null +++ b/cximage/ximabmp.h @@ -0,0 +1,79 @@ +/* + * File: ximabmp.h + * Purpose: BMP Image Class Loader and Writer + */ +/* ========================================================== + * CxImageBMP (c) 07/Aug/2001 Davide Pizzolato - www.xdp.it + * For conditions of distribution and use, see copyright notice in ximage.h + * + * Special thanks to Troels Knakkergaard for new features, enhancements and bugfixes + * + * original CImageBMP and CImageIterator implementation are: + * Copyright: (c) 1995, Alejandro Aguilar Sierra + * + * ========================================================== + */ + +#if !defined(__ximaBMP_h) +#define __ximaBMP_h + +#include "ximage.h" + +const int32_t RLE_COMMAND = 0; +const int32_t RLE_ENDOFLINE = 0; +const int32_t RLE_ENDOFBITMAP = 1; +const int32_t RLE_DELTA = 2; + +#if !defined(BI_RLE8) + #define BI_RLE8 1L +#endif +#if !defined(BI_RLE4) + #define BI_RLE4 2L +#endif + +#if CXIMAGE_SUPPORT_BMP + +class CxImageBMP: public CxImage +{ +public: + CxImageBMP(): CxImage(CXIMAGE_FORMAT_BMP) {}; + + bool Decode(CxFile * hFile); + bool Decode(FILE *hFile) { CxIOFile file(hFile); return Decode(&file); } + +#if CXIMAGE_SUPPORT_ENCODE + bool Encode(CxFile * hFile); + bool Encode(FILE *hFile) { CxIOFile file(hFile); return Encode(&file); } +#endif // CXIMAGE_SUPPORT_ENCODE + +protected: + bool DibReadBitmapInfo(CxFile* fh, BITMAPINFOHEADER *pdib); +}; + +#define BFT_ICON 0x4349 /* 'IC' */ +#define BFT_BITMAP 0x4d42 /* 'BM' */ +#define BFT_CURSOR 0x5450 /* 'PT' */ + +#ifndef WIDTHBYTES +#define WIDTHBYTES(i) ((unsigned)((i+31)&(~31))/8) /* ULONG aligned ! */ +#endif + +#endif + +#define DibWidthBytesN(lpbi, n) (uint32_t)WIDTHBYTES((uint32_t)(lpbi)->biWidth * (uint32_t)(n)) +#define DibWidthBytes(lpbi) DibWidthBytesN(lpbi, (lpbi)->biBitCount) + +#define DibSizeImage(lpbi) ((lpbi)->biSizeImage == 0 \ + ? ((uint32_t)(uint32_t)DibWidthBytes(lpbi) * (uint32_t)(uint32_t)(lpbi)->biHeight) \ + : (lpbi)->biSizeImage) + +#define DibNumColors(lpbi) ((lpbi)->biClrUsed == 0 && (lpbi)->biBitCount <= 8 \ + ? (int32_t)(1 << (int32_t)(lpbi)->biBitCount) \ + : (int32_t)(lpbi)->biClrUsed) + +#define FixBitmapInfo(lpbi) if ((lpbi)->biSizeImage == 0) \ + (lpbi)->biSizeImage = DibSizeImage(lpbi); \ + if ((lpbi)->biClrUsed == 0) \ + (lpbi)->biClrUsed = DibNumColors(lpbi); \ + +#endif diff --git a/cximage/ximacfg.h b/cximage/ximacfg.h new file mode 100644 index 0000000..d48e3d8 --- /dev/null +++ b/cximage/ximacfg.h @@ -0,0 +1,59 @@ +#if !defined(__ximaCFG_h) +#define __ximaCFG_h + +///////////////////////////////////////////////////////////////////////////// +// CxImage supported features +#define CXIMAGE_SUPPORT_ALPHA 1 +#define CXIMAGE_SUPPORT_SELECTION 1 +#define CXIMAGE_SUPPORT_TRANSFORMATION 1 +#define CXIMAGE_SUPPORT_DSP 1 +#define CXIMAGE_SUPPORT_LAYERS 1 +#define CXIMAGE_SUPPORT_INTERPOLATION 1 + +#define CXIMAGE_SUPPORT_DECODE 1 +#define CXIMAGE_SUPPORT_ENCODE 1 // +#define CXIMAGE_SUPPORT_WINDOWS 1 +#define CXIMAGE_SUPPORT_EXIF 1 + +///////////////////////////////////////////////////////////////////////////// +// CxImage supported formats +#define CXIMAGE_SUPPORT_BMP 1 +#define CXIMAGE_SUPPORT_GIF 1 +#define CXIMAGE_SUPPORT_JPG 1 +#define CXIMAGE_SUPPORT_PNG 1 +#define CXIMAGE_SUPPORT_ICO 1 +#define CXIMAGE_SUPPORT_TIF 1 +#define CXIMAGE_SUPPORT_TGA 1 +#define CXIMAGE_SUPPORT_PCX 1 +#define CXIMAGE_SUPPORT_WBMP 1 +#define CXIMAGE_SUPPORT_WMF 1 + +#define CXIMAGE_SUPPORT_JP2 1 +#define CXIMAGE_SUPPORT_JPC 1 +#define CXIMAGE_SUPPORT_PGX 1 +#define CXIMAGE_SUPPORT_PNM 1 +#define CXIMAGE_SUPPORT_RAS 1 + +#define CXIMAGE_SUPPORT_JBG 0 // GPL'd see ../jbig/copying.txt & ../jbig/patents.htm + +#define CXIMAGE_SUPPORT_MNG 1 +#define CXIMAGE_SUPPORT_SKA 1 +#define CXIMAGE_SUPPORT_RAW 1 +#define CXIMAGE_SUPPORT_PSD 1 + +///////////////////////////////////////////////////////////////////////////// +#define CXIMAGE_MAX_MEMORY 268435456 + +#define CXIMAGE_DEFAULT_DPI 96 + +#define CXIMAGE_ERR_NOFILE "null file handler" +#define CXIMAGE_ERR_NOIMAGE "null image!!!" + +#define CXIMAGE_SUPPORT_EXCEPTION_HANDLING 1 + +///////////////////////////////////////////////////////////////////////////// +//color to grey mapping +//#define RGB2GRAY(r,g,b) (((b)*114 + (g)*587 + (r)*299)/1000) +#define RGB2GRAY(r,g,b) (((b)*117 + (g)*601 + (r)*306) >> 10) + +#endif diff --git a/cximage/ximadef.h b/cximage/ximadef.h new file mode 100644 index 0000000..337f6cd --- /dev/null +++ b/cximage/ximadef.h @@ -0,0 +1,210 @@ +#if !defined(__ximadefs_h) +#define __ximadefs_h + +#include "ximacfg.h" + +#if /*defined(_AFXDLL)||*/defined(_USRDLL) + #define DLL_EXP __declspec(dllexport) +#elif defined(_MSC_VER)&&(_MSC_VER<1200) + #define DLL_EXP __declspec(dllimport) +#else + #define DLL_EXP +#endif + + +#if CXIMAGE_SUPPORT_EXCEPTION_HANDLING + #define cx_try try + #define cx_throw(message) throw(message) + #define cx_catch catch (const char *message) +#else + #define cx_try bool cx_error=false; + #define cx_throw(message) {cx_error=true; if(strcmp(message,"")) strncpy(info.szLastError,message,255); goto cx_error_catch;} + #define cx_catch cx_error_catch: char message[]=""; if(cx_error) +#endif + + +#if CXIMAGE_SUPPORT_JP2 || CXIMAGE_SUPPORT_JPC || CXIMAGE_SUPPORT_PGX || CXIMAGE_SUPPORT_PNM || CXIMAGE_SUPPORT_RAS + #define CXIMAGE_SUPPORT_JASPER 1 +#else + #define CXIMAGE_SUPPORT_JASPER 0 +#endif + +#if CXIMAGE_SUPPORT_DSP +#undef CXIMAGE_SUPPORT_TRANSFORMATION + #define CXIMAGE_SUPPORT_TRANSFORMATION 1 +#endif + +#if CXIMAGE_SUPPORT_TRANSFORMATION || CXIMAGE_SUPPORT_TIF || CXIMAGE_SUPPORT_TGA || CXIMAGE_SUPPORT_BMP || CXIMAGE_SUPPORT_WINDOWS + #define CXIMAGE_SUPPORT_BASICTRANSFORMATIONS 1 +#endif + +#if CXIMAGE_SUPPORT_DSP || CXIMAGE_SUPPORT_TRANSFORMATION +#undef CXIMAGE_SUPPORT_INTERPOLATION + #define CXIMAGE_SUPPORT_INTERPOLATION 1 +#endif + +#if (CXIMAGE_SUPPORT_DECODE == 0) +#undef CXIMAGE_SUPPORT_EXIF + #define CXIMAGE_SUPPORT_EXIF 0 +#endif + +#if defined (_WIN32_WCE) + #undef CXIMAGE_SUPPORT_WMF + #define CXIMAGE_SUPPORT_WMF 0 +#endif + +#if !defined(WIN32) && !defined(_WIN32_WCE) + #undef CXIMAGE_SUPPORT_WINDOWS + #define CXIMAGE_SUPPORT_WINDOWS 0 +#endif + +#ifndef min +#define min(a,b) (((a)<(b))?(a):(b)) +#endif +#ifndef max +#define max(a,b) (((a)>(b))?(a):(b)) +#endif + +#ifndef PI + #define PI 3.141592653589793f +#endif + + +#if defined(WIN32) || defined(_WIN32_WCE) +#include +#include +#endif + +#include +#include + +#ifdef __BORLANDC__ + +#ifndef _COMPLEX_DEFINED + +typedef struct tagcomplex { + double x,y; +} _complex; + +#endif + +#define _cabs(c) sqrt(c.x*c.x+c.y*c.y) + +#endif + +#if defined(WIN32) || defined(_WIN32_WCE) + #include "stdint.h" +#endif + +#if !defined(WIN32) && !defined(_WIN32_WCE) + +#include +#include +#include +#include + +typedef uint32_t COLORREF; +typedef void* HANDLE; +typedef void* HRGN; + +#ifndef BOOL +#define BOOL bool +#endif + +#ifndef TRUE +#define TRUE true +#endif + +#ifndef FALSE +#define FALSE false +#endif + +#ifndef TCHAR +#define TCHAR char +#define _T +#endif + +typedef struct tagRECT +{ + int32_t left; + int32_t top; + int32_t right; + int32_t bottom; +} RECT; + +typedef struct tagPOINT +{ + int32_t x; + int32_t y; +} POINT; + +typedef struct tagRGBQUAD { + uint8_t rgbBlue; + uint8_t rgbGreen; + uint8_t rgbRed; + uint8_t rgbReserved; +} RGBQUAD; + +#pragma pack(1) + +typedef struct tagBITMAPINFOHEADER{ + uint32_t biSize; + int32_t biWidth; + int32_t biHeight; + uint16_t biPlanes; + uint16_t biBitCount; + uint32_t biCompression; + uint32_t biSizeImage; + int32_t biXPelsPerMeter; + int32_t biYPelsPerMeter; + uint32_t biClrUsed; + uint32_t biClrImportant; +} BITMAPINFOHEADER; + +typedef struct tagBITMAPFILEHEADER { + uint16_t bfType; + uint32_t bfSize; + uint16_t bfReserved1; + uint16_t bfReserved2; + uint32_t bfOffBits; +} BITMAPFILEHEADER; + +typedef struct tagBITMAPCOREHEADER { + uint32_t bcSize; + uint16_t bcWidth; + uint16_t bcHeight; + uint16_t bcPlanes; + uint16_t bcBitCount; +} BITMAPCOREHEADER; + +typedef struct tagRGBTRIPLE { + uint8_t rgbtBlue; + uint8_t rgbtGreen; + uint8_t rgbtRed; +} RGBTRIPLE; + +#pragma pack() + +#define BI_RGB 0L +#define BI_RLE8 1L +#define BI_RLE4 2L +#define BI_BITFIELDS 3L + +#define GetRValue(rgb) ((uint8_t)(rgb)) +#define GetGValue(rgb) ((uint8_t)(((uint16_t)(rgb)) >> 8)) +#define GetBValue(rgb) ((uint8_t)((rgb)>>16)) +#define RGB(r,g,b) ((COLORREF)(((uint8_t)(r)|((uint16_t)((uint8_t)(g))<<8))|(((uint32_t)(uint8_t)(b))<<16))) + +#ifndef _COMPLEX_DEFINED + +typedef struct tagcomplex { + double x,y; +} _complex; + +#endif + +#define _cabs(c) sqrt(c.x*c.x+c.y*c.y) + +#endif + +#endif //__ximadefs diff --git a/cximage/ximage.h b/cximage/ximage.h new file mode 100644 index 0000000..f54dc9d --- /dev/null +++ b/cximage/ximage.h @@ -0,0 +1,807 @@ +/* + * File: ximage.h + * Purpose: General Purpose Image Class + */ +/* + -------------------------------------------------------------------------------- + + COPYRIGHT NOTICE, DISCLAIMER, and LICENSE: + + CxImage version 7.0.1 07/Jan/2011 + + CxImage : Copyright (C) 2001 - 2010, Davide Pizzolato + + Original CImage and CImageIterator implementation are: + Copyright (C) 1995, Alejandro Aguilar Sierra (asierra(at)servidor(dot)unam(dot)mx) + + Covered code is provided under this license on an "as is" basis, without warranty + of any kind, either expressed or implied, including, without limitation, warranties + that the covered code is free of defects, merchantable, fit for a particular purpose + or non-infringing. The entire risk as to the quality and performance of the covered + code is with you. Should any covered code prove defective in any respect, you (not + the initial developer or any other contributor) assume the cost of any necessary + servicing, repair or correction. This disclaimer of warranty constitutes an essential + part of this license. No use of any covered code is authorized hereunder except under + this disclaimer. + + Permission is hereby granted to use, copy, modify, and distribute this + source code, or portions hereof, for any purpose, including commercial applications, + freely and without fee, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + + 3. This notice may not be removed or altered from any source distribution. + + -------------------------------------------------------------------------------- + + Other information about CxImage, and the latest version, can be found at the + CxImage home page: http://www.xdp.it/cximage/ + + -------------------------------------------------------------------------------- + */ +#if !defined(__CXIMAGE_H) +#define __CXIMAGE_H + +#if _MSC_VER > 1000 +#pragma once +#endif + +#ifdef _LINUX + #define _XOPEN_SOURCE + #include + #include +#endif + +///////////////////////////////////////////////////////////////////////////// +#include "xfile.h" +#include "xiofile.h" +#include "xmemfile.h" +#include "ximadef.h" // adjust some #define + +/* see "ximacfg.h" for CxImage configuration options */ + +///////////////////////////////////////////////////////////////////////////// +// CxImage formats enumerator +enum ENUM_CXIMAGE_FORMATS{ +CXIMAGE_FORMAT_UNKNOWN = 0, +#if CXIMAGE_SUPPORT_BMP +CXIMAGE_FORMAT_BMP = 1, +#endif +#if CXIMAGE_SUPPORT_GIF +CXIMAGE_FORMAT_GIF = 2, +#endif +#if CXIMAGE_SUPPORT_JPG +CXIMAGE_FORMAT_JPG = 3, +#endif +#if CXIMAGE_SUPPORT_PNG +CXIMAGE_FORMAT_PNG = 4, +#endif +#if CXIMAGE_SUPPORT_ICO +CXIMAGE_FORMAT_ICO = 5, +#endif +#if CXIMAGE_SUPPORT_TIF +CXIMAGE_FORMAT_TIF = 6, +#endif +#if CXIMAGE_SUPPORT_TGA +CXIMAGE_FORMAT_TGA = 7, +#endif +#if CXIMAGE_SUPPORT_PCX +CXIMAGE_FORMAT_PCX = 8, +#endif +#if CXIMAGE_SUPPORT_WBMP +CXIMAGE_FORMAT_WBMP = 9, +#endif +#if CXIMAGE_SUPPORT_WMF +CXIMAGE_FORMAT_WMF = 10, +#endif +#if CXIMAGE_SUPPORT_JP2 +CXIMAGE_FORMAT_JP2 = 11, +#endif +#if CXIMAGE_SUPPORT_JPC +CXIMAGE_FORMAT_JPC = 12, +#endif +#if CXIMAGE_SUPPORT_PGX +CXIMAGE_FORMAT_PGX = 13, +#endif +#if CXIMAGE_SUPPORT_PNM +CXIMAGE_FORMAT_PNM = 14, +#endif +#if CXIMAGE_SUPPORT_RAS +CXIMAGE_FORMAT_RAS = 15, +#endif +#if CXIMAGE_SUPPORT_JBG +CXIMAGE_FORMAT_JBG = 16, +#endif +#if CXIMAGE_SUPPORT_MNG +CXIMAGE_FORMAT_MNG = 17, +#endif +#if CXIMAGE_SUPPORT_SKA +CXIMAGE_FORMAT_SKA = 18, +#endif +#if CXIMAGE_SUPPORT_RAW +CXIMAGE_FORMAT_RAW = 19, +#endif +#if CXIMAGE_SUPPORT_PSD +CXIMAGE_FORMAT_PSD = 20, +#endif +CMAX_IMAGE_FORMATS = CXIMAGE_SUPPORT_BMP + CXIMAGE_SUPPORT_GIF + CXIMAGE_SUPPORT_JPG + + CXIMAGE_SUPPORT_PNG + CXIMAGE_SUPPORT_MNG + CXIMAGE_SUPPORT_ICO + + CXIMAGE_SUPPORT_TIF + CXIMAGE_SUPPORT_TGA + CXIMAGE_SUPPORT_PCX + + CXIMAGE_SUPPORT_WBMP+ CXIMAGE_SUPPORT_WMF + + CXIMAGE_SUPPORT_JBG + CXIMAGE_SUPPORT_JP2 + CXIMAGE_SUPPORT_JPC + + CXIMAGE_SUPPORT_PGX + CXIMAGE_SUPPORT_PNM + CXIMAGE_SUPPORT_RAS + + CXIMAGE_SUPPORT_SKA + CXIMAGE_SUPPORT_RAW + CXIMAGE_SUPPORT_PSD + 1 +}; + +#if CXIMAGE_SUPPORT_EXIF + +#define MAX_COMMENT 255 +#define MAX_SECTIONS 20 + +typedef struct tag_ExifInfo { + char Version [5]; + char CameraMake [32]; + char CameraModel [40]; + char DateTime [20]; + int32_t Height, Width; + int32_t Orientation; + int32_t IsColor; + int32_t Process; + int32_t FlashUsed; + float FocalLength; + float ExposureTime; + float ApertureFNumber; + float Distance; + float CCDWidth; + float ExposureBias; + int32_t Whitebalance; + int32_t MeteringMode; + int32_t ExposureProgram; + int32_t ISOequivalent; + int32_t CompressionLevel; + float FocalplaneXRes; + float FocalplaneYRes; + float FocalplaneUnits; + float Xresolution; + float Yresolution; + float ResolutionUnit; + float Brightness; + char Comments[MAX_COMMENT+1]; + + uint8_t * ThumbnailPointer; /* Pointer at the thumbnail */ + unsigned ThumbnailSize; /* Size of thumbnail. */ + + bool IsExif; +} EXIFINFO; + +#endif //CXIMAGE_SUPPORT_EXIF + +///////////////////////////////////////////////////////////////////////////// +// CxImage class +///////////////////////////////////////////////////////////////////////////// +class DLL_EXP CxImage +{ +//extensible information collector +typedef struct tagCxImageInfo { + uint32_t dwEffWidth; ///< uint32_t aligned scan line width + uint8_t* pImage; ///< THE IMAGE BITS + CxImage* pGhost; ///< if this is a ghost, pGhost points to the body + CxImage* pParent; ///< if this is a layer, pParent points to the body + uint32_t dwType; ///< original image format + char szLastError[256]; ///< debugging + int32_t nProgress; ///< monitor + int32_t nEscape; ///< escape + int32_t nBkgndIndex; ///< used for GIF, PNG, MNG + RGBQUAD nBkgndColor; ///< used for RGB transparency + float fQuality; ///< used for JPEG, JPEG2000 (0.0f ... 100.0f) + uint8_t nJpegScale; ///< used for JPEG [ignacio] + int32_t nFrame; ///< used for TIF, GIF, MNG : actual frame + int32_t nNumFrames; ///< used for TIF, GIF, MNG : total number of frames + uint32_t dwFrameDelay; ///< used for GIF, MNG + int32_t xDPI; ///< horizontal resolution + int32_t yDPI; ///< vertical resolution + RECT rSelectionBox; ///< bounding rectangle + uint8_t nAlphaMax; ///< max opacity (fade) + bool bAlphaPaletteEnabled; ///< true if alpha values in the palette are enabled. + bool bEnabled; ///< enables the painting functions + int32_t xOffset; + int32_t yOffset; + uint32_t dwCodecOpt[CMAX_IMAGE_FORMATS]; ///< for GIF, TIF : 0=def.1=unc,2=fax3,3=fax4,4=pack,5=jpg + RGBQUAD last_c; ///< for GetNearestIndex optimization + uint8_t last_c_index; + bool last_c_isvalid; + int32_t nNumLayers; + uint32_t dwFlags; ///< 0x??00000 = reserved, 0x00??0000 = blend mode, 0x0000???? = layer id - user flags + uint8_t dispmeth; + bool bGetAllFrames; + bool bLittleEndianHost; + +#if CXIMAGE_SUPPORT_EXIF + EXIFINFO ExifInfo; +#endif + +} CXIMAGEINFO; + +public: + //public structures +struct rgb_color { uint8_t r,g,b; }; + +#if CXIMAGE_SUPPORT_WINDOWS +// text placement data +// members must be initialized with the InitTextInfo(&this) function. +typedef struct tagCxTextInfo +{ +#if defined (_WIN32_WCE) + TCHAR text[256]; ///< text for windows CE +#else + TCHAR text[4096]; ///< text (char -> TCHAR for UNICODE [Cesar M]) +#endif + LOGFONT lfont; ///< font and codepage data + COLORREF fcolor; ///< foreground color + int32_t align; ///< DT_CENTER, DT_RIGHT, DT_LEFT aligment for multiline text + uint8_t smooth; ///< text smoothing option. Default is false. + uint8_t opaque; ///< text has background or hasn't. Default is true. + ///< data for background (ignored if .opaque==FALSE) + COLORREF bcolor; ///< background color + float b_opacity; ///< opacity value for background between 0.0-1.0 Default is 0. (opaque) + uint8_t b_outline; ///< outline width for background (zero: no outline) + uint8_t b_round; ///< rounding radius for background rectangle. % of the height, between 0-50. Default is 10. + ///< (backgr. always has a frame: width = 3 pixel + 10% of height by default.) +} CXTEXTINFO; +#endif + +public: +/** \addtogroup Constructors */ //@{ + CxImage(uint32_t imagetype = 0); + CxImage(uint32_t dwWidth, uint32_t dwHeight, uint32_t wBpp, uint32_t imagetype = 0); + CxImage(const CxImage &src, bool copypixels = true, bool copyselection = true, bool copyalpha = true); +#if CXIMAGE_SUPPORT_DECODE + CxImage(const TCHAR * filename, uint32_t imagetype); // For UNICODE support: char -> TCHAR + CxImage(FILE * stream, uint32_t imagetype); + CxImage(CxFile * stream, uint32_t imagetype); + CxImage(uint8_t * buffer, uint32_t size, uint32_t imagetype); +#endif + virtual ~CxImage() { DestroyFrames(); Destroy(); }; + CxImage& operator = (const CxImage&); +//@} + +/** \addtogroup Initialization */ //@{ + void* Create(uint32_t dwWidth, uint32_t dwHeight, uint32_t wBpp, uint32_t imagetype = 0); + bool Destroy(); + bool DestroyFrames(); + void Clear(uint8_t bval=0); + void Copy(const CxImage &src, bool copypixels = true, bool copyselection = true, bool copyalpha = true); + bool Transfer(CxImage &from, bool bTransferFrames = true); + bool CreateFromArray(uint8_t* pArray,uint32_t dwWidth,uint32_t dwHeight,uint32_t dwBitsperpixel, uint32_t dwBytesperline, bool bFlipImage); + bool CreateFromMatrix(uint8_t** ppMatrix,uint32_t dwWidth,uint32_t dwHeight,uint32_t dwBitsperpixel, uint32_t dwBytesperline, bool bFlipImage); + void FreeMemory(void* memblock); + + uint32_t Dump(uint8_t * dst); + uint32_t UnDump(const uint8_t * src); + uint32_t DumpSize(); + +//@} + +/** \addtogroup Attributes */ //@{ + int32_t GetSize(); + uint8_t* GetBits(uint32_t row = 0); + uint8_t GetColorType(); + void* GetDIB() const; + uint32_t GetHeight() const; + uint32_t GetWidth() const; + uint32_t GetEffWidth() const; + uint32_t GetNumColors() const; + uint16_t GetBpp() const; + uint32_t GetType() const; + const char* GetLastError(); + static const TCHAR* GetVersion(); + static const float GetVersionNumber(); + + uint32_t GetFrameDelay() const; + void SetFrameDelay(uint32_t d); + + void GetOffset(int32_t *x,int32_t *y); + void SetOffset(int32_t x,int32_t y); + + uint8_t GetJpegQuality() const; + void SetJpegQuality(uint8_t q); + float GetJpegQualityF() const; + void SetJpegQualityF(float q); + + uint8_t GetJpegScale() const; + void SetJpegScale(uint8_t q); + +#if CXIMAGE_SUPPORT_EXIF + EXIFINFO *GetExifInfo() {return &info.ExifInfo;}; + bool GetExifThumbnail(const TCHAR *filename, const TCHAR *outname, int32_t imageType); + #if CXIMAGE_SUPPORT_TRANSFORMATION + bool RotateExif(int32_t orientation = 0); + #endif +#endif + + int32_t GetXDPI() const; + int32_t GetYDPI() const; + void SetXDPI(int32_t dpi); + void SetYDPI(int32_t dpi); + + uint32_t GetClrImportant() const; + void SetClrImportant(uint32_t ncolors = 0); + + int32_t GetProgress() const; + int32_t GetEscape() const; + void SetProgress(int32_t p); + void SetEscape(int32_t i); + + int32_t GetTransIndex() const; + RGBQUAD GetTransColor(); + void SetTransIndex(int32_t idx); + void SetTransColor(RGBQUAD rgb); + bool IsTransparent() const; + + uint32_t GetCodecOption(uint32_t imagetype = 0); + bool SetCodecOption(uint32_t opt, uint32_t imagetype = 0); + + uint32_t GetFlags() const; + void SetFlags(uint32_t flags, bool bLockReservedFlags = true); + + uint8_t GetDisposalMethod() const; + void SetDisposalMethod(uint8_t dm); + + bool SetType(uint32_t type); + + static uint32_t GetNumTypes(); + static uint32_t GetTypeIdFromName(const TCHAR* ext); + static uint32_t GetTypeIdFromIndex(const uint32_t index); + static uint32_t GetTypeIndexFromId(const uint32_t id); + + bool GetRetreiveAllFrames() const; + void SetRetreiveAllFrames(bool flag); + CxImage * GetFrame(int32_t nFrame) const; + + //void* GetUserData() const {return info.pUserData;} + //void SetUserData(void* pUserData) {info.pUserData = pUserData;} +//@} + +/** \addtogroup Palette + * These functions have no effects on RGB images and in this case the returned value is always 0. + * @{ */ + bool IsGrayScale(); + bool IsIndexed() const; + bool IsSamePalette(CxImage &img, bool bCheckAlpha = true); + uint32_t GetPaletteSize(); + RGBQUAD* GetPalette() const; + RGBQUAD GetPaletteColor(uint8_t idx); + bool GetPaletteColor(uint8_t i, uint8_t* r, uint8_t* g, uint8_t* b); + uint8_t GetNearestIndex(RGBQUAD c); + void BlendPalette(COLORREF cr,int32_t perc); + void SetGrayPalette(); + void SetPalette(uint32_t n, uint8_t *r, uint8_t *g, uint8_t *b); + void SetPalette(RGBQUAD* pPal,uint32_t nColors=256); + void SetPalette(rgb_color *rgb,uint32_t nColors=256); + void SetPaletteColor(uint8_t idx, uint8_t r, uint8_t g, uint8_t b, uint8_t alpha=0); + void SetPaletteColor(uint8_t idx, RGBQUAD c); + void SetPaletteColor(uint8_t idx, COLORREF cr); + void SwapIndex(uint8_t idx1, uint8_t idx2); + void SwapRGB2BGR(); + void SetStdPalette(); +//@} + +/** \addtogroup Pixel */ //@{ + bool IsInside(int32_t x, int32_t y); + bool IsTransparent(int32_t x,int32_t y); + bool GetTransparentMask(CxImage* iDst = 0); + RGBQUAD GetPixelColor(int32_t x,int32_t y, bool bGetAlpha = true); + uint8_t GetPixelIndex(int32_t x,int32_t y); + uint8_t GetPixelGray(int32_t x, int32_t y); + void SetPixelColor(int32_t x,int32_t y,RGBQUAD c, bool bSetAlpha = false); + void SetPixelColor(int32_t x,int32_t y,COLORREF cr); + void SetPixelIndex(int32_t x,int32_t y,uint8_t i); + void DrawLine(int32_t StartX, int32_t EndX, int32_t StartY, int32_t EndY, RGBQUAD color, bool bSetAlpha=false); + void DrawLine(int32_t StartX, int32_t EndX, int32_t StartY, int32_t EndY, COLORREF cr); + void BlendPixelColor(int32_t x,int32_t y,RGBQUAD c, float blend, bool bSetAlpha = false); +//@} + +protected: +/** \addtogroup Protected */ //@{ + uint8_t BlindGetPixelIndex(const int32_t x,const int32_t y); + RGBQUAD BlindGetPixelColor(const int32_t x,const int32_t y, bool bGetAlpha = true); + void *BlindGetPixelPointer(const int32_t x,const int32_t y); + void BlindSetPixelColor(int32_t x,int32_t y,RGBQUAD c, bool bSetAlpha = false); + void BlindSetPixelIndex(int32_t x,int32_t y,uint8_t i); +//@} + +public: + +#if CXIMAGE_SUPPORT_INTERPOLATION +/** \addtogroup Interpolation */ //@{ + //overflow methods: + enum OverflowMethod { + OM_COLOR=1, + OM_BACKGROUND=2, + OM_TRANSPARENT=3, + OM_WRAP=4, + OM_REPEAT=5, + OM_MIRROR=6 + }; + void OverflowCoordinates(float &x, float &y, OverflowMethod const ofMethod); + void OverflowCoordinates(int32_t &x, int32_t &y, OverflowMethod const ofMethod); + RGBQUAD GetPixelColorWithOverflow(int32_t x, int32_t y, OverflowMethod const ofMethod=OM_BACKGROUND, RGBQUAD* const rplColor=0); + //interpolation methods: + enum InterpolationMethod { + IM_NEAREST_NEIGHBOUR=1, + IM_BILINEAR =2, + IM_BSPLINE =3, + IM_BICUBIC =4, + IM_BICUBIC2 =5, + IM_LANCZOS =6, + IM_BOX =7, + IM_HERMITE =8, + IM_HAMMING =9, + IM_SINC =10, + IM_BLACKMAN =11, + IM_BESSEL =12, + IM_GAUSSIAN =13, + IM_QUADRATIC =14, + IM_MITCHELL =15, + IM_CATROM =16, + IM_HANNING =17, + IM_POWER =18 + }; + RGBQUAD GetPixelColorInterpolated(float x,float y, InterpolationMethod const inMethod=IM_BILINEAR, OverflowMethod const ofMethod=OM_BACKGROUND, RGBQUAD* const rplColor=0); + RGBQUAD GetAreaColorInterpolated(float const xc, float const yc, float const w, float const h, InterpolationMethod const inMethod, OverflowMethod const ofMethod=OM_BACKGROUND, RGBQUAD* const rplColor=0); +//@} + +protected: +/** \addtogroup Protected */ //@{ + void AddAveragingCont(RGBQUAD const &color, float const surf, float &rr, float &gg, float &bb, float &aa); +//@} + +/** \addtogroup Kernels */ //@{ +public: + static float KernelBSpline(const float x); + static float KernelLinear(const float t); + static float KernelCubic(const float t); + static float KernelGeneralizedCubic(const float t, const float a=-1); + static float KernelLanczosSinc(const float t, const float r = 3); + static float KernelBox(const float x); + static float KernelHermite(const float x); + static float KernelHamming(const float x); + static float KernelSinc(const float x); + static float KernelBlackman(const float x); + static float KernelBessel_J1(const float x); + static float KernelBessel_P1(const float x); + static float KernelBessel_Q1(const float x); + static float KernelBessel_Order1(float x); + static float KernelBessel(const float x); + static float KernelGaussian(const float x); + static float KernelQuadratic(const float x); + static float KernelMitchell(const float x); + static float KernelCatrom(const float x); + static float KernelHanning(const float x); + static float KernelPower(const float x, const float a = 2); +//@} +#endif //CXIMAGE_SUPPORT_INTERPOLATION + +/** \addtogroup Painting */ //@{ +#if CXIMAGE_SUPPORT_WINDOWS + int32_t Blt(HDC pDC, int32_t x=0, int32_t y=0); + HBITMAP Draw2HBITMAP(HDC hdc, int32_t x, int32_t y, int32_t cx, int32_t cy, RECT* pClipRect, bool bSmooth); + HBITMAP MakeBitmap(HDC hdc = NULL, bool bTransparency = false); + HICON MakeIcon(HDC hdc = NULL, bool bTransparency = false); + HANDLE CopyToHandle(); + bool CreateFromHANDLE(HANDLE hMem); //Windows objects (clipboard) + bool CreateFromHBITMAP(HBITMAP hbmp, HPALETTE hpal=0, bool bTransparency = false); //Windows resource + bool CreateFromHICON(HICON hico, bool bTransparency = false); + int32_t Draw(HDC hdc, int32_t x=0, int32_t y=0, int32_t cx = -1, int32_t cy = -1, RECT* pClipRect = 0, bool bSmooth = false, bool bFlipY = false); + int32_t Draw(HDC hdc, const RECT& rect, RECT* pClipRect=NULL, bool bSmooth = false, bool bFlipY = false); + int32_t Stretch(HDC hdc, int32_t xoffset, int32_t yoffset, int32_t xsize, int32_t ysize, uint32_t dwRop = SRCCOPY); + int32_t Stretch(HDC hdc, const RECT& rect, uint32_t dwRop = SRCCOPY); + int32_t Tile(HDC hdc, RECT *rc); + int32_t Draw2(HDC hdc, int32_t x=0, int32_t y=0, int32_t cx = -1, int32_t cy = -1); + int32_t Draw2(HDC hdc, const RECT& rect); + //int32_t DrawString(HDC hdc, int32_t x, int32_t y, const char* text, RGBQUAD color, const char* font, int32_t lSize=0, int32_t lWeight=400, uint8_t bItalic=0, uint8_t bUnderline=0, bool bSetAlpha=false); + int32_t DrawString(HDC hdc, int32_t x, int32_t y, const TCHAR* text, RGBQUAD color, const TCHAR* font, int32_t lSize=0, int32_t lWeight=400, uint8_t bItalic=0, uint8_t bUnderline=0, bool bSetAlpha=false); + // extensions + int32_t DrawStringEx(HDC hdc, int32_t x, int32_t y, CXTEXTINFO *pTextType, bool bSetAlpha=false ); + void InitTextInfo( CXTEXTINFO *txt ); +protected: + bool IsHBITMAPAlphaValid( HBITMAP hbmp ); +public: +#endif //CXIMAGE_SUPPORT_WINDOWS +//@} + + // file operations +#if CXIMAGE_SUPPORT_DECODE +/** \addtogroup Decode */ //@{ +#ifdef WIN32 + //bool Load(LPCWSTR filename, uint32_t imagetype=0); + bool LoadResource(HRSRC hRes, uint32_t imagetype, HMODULE hModule=NULL); +#endif + // For UNICODE support: char -> TCHAR + bool Load(const TCHAR* filename, uint32_t imagetype=0); + //bool Load(const char * filename, uint32_t imagetype=0); + bool Decode(FILE * hFile, uint32_t imagetype); + bool Decode(CxFile * hFile, uint32_t imagetype); + bool Decode(uint8_t * buffer, uint32_t size, uint32_t imagetype); + + bool CheckFormat(CxFile * hFile, uint32_t imagetype = 0); + bool CheckFormat(uint8_t * buffer, uint32_t size, uint32_t imagetype = 0); +//@} +#endif //CXIMAGE_SUPPORT_DECODE + +#if CXIMAGE_SUPPORT_ENCODE +protected: +/** \addtogroup Protected */ //@{ + bool EncodeSafeCheck(CxFile *hFile); +//@} + +public: +/** \addtogroup Encode */ //@{ +#ifdef WIN32 + //bool Save(LPCWSTR filename, uint32_t imagetype=0); +#endif + // For UNICODE support: char -> TCHAR + bool Save(const TCHAR* filename, uint32_t imagetype); + //bool Save(const char * filename, uint32_t imagetype=0); + bool Encode(FILE * hFile, uint32_t imagetype); + bool Encode(CxFile * hFile, uint32_t imagetype); + bool Encode(CxFile * hFile, CxImage ** pImages, int32_t pagecount, uint32_t imagetype); + bool Encode(FILE *hFile, CxImage ** pImages, int32_t pagecount, uint32_t imagetype); + bool Encode(uint8_t * &buffer, int32_t &size, uint32_t imagetype); + + bool Encode2RGBA(CxFile *hFile, bool bFlipY = false); + bool Encode2RGBA(uint8_t * &buffer, int32_t &size, bool bFlipY = false); +//@} +#endif //CXIMAGE_SUPPORT_ENCODE + +/** \addtogroup Attributes */ //@{ + //misc. + bool IsValid() const; + bool IsEnabled() const; + void Enable(bool enable=true); + + // frame operations + int32_t GetNumFrames() const; + int32_t GetFrame() const; + void SetFrame(int32_t nFrame); +//@} + +#if CXIMAGE_SUPPORT_BASICTRANSFORMATIONS +/** \addtogroup BasicTransformations */ //@{ + bool GrayScale(); + bool Flip(bool bFlipSelection = false, bool bFlipAlpha = true); + bool Mirror(bool bMirrorSelection = false, bool bMirrorAlpha = true); + bool Negative(); + bool RotateLeft(CxImage* iDst = NULL); + bool RotateRight(CxImage* iDst = NULL); + bool IncreaseBpp(uint32_t nbit); +//@} +#endif //CXIMAGE_SUPPORT_BASICTRANSFORMATIONS + +#if CXIMAGE_SUPPORT_TRANSFORMATION +/** \addtogroup Transformations */ //@{ + // image operations + bool Rotate(float angle, CxImage* iDst = NULL); + bool Rotate2(float angle, CxImage *iDst = NULL, InterpolationMethod inMethod=IM_BILINEAR, + OverflowMethod ofMethod=OM_BACKGROUND, RGBQUAD *replColor=0, + bool const optimizeRightAngles=true, bool const bKeepOriginalSize=false); + bool Rotate180(CxImage* iDst = NULL); + bool Resample(int32_t newx, int32_t newy, int32_t mode = 1, CxImage* iDst = NULL); + bool Resample2(int32_t newx, int32_t newy, InterpolationMethod const inMethod=IM_BICUBIC2, + OverflowMethod const ofMethod=OM_REPEAT, CxImage* const iDst = NULL, + bool const disableAveraging=false); + bool DecreaseBpp(uint32_t nbit, bool errordiffusion, RGBQUAD* ppal = 0, uint32_t clrimportant = 0); + bool Dither(int32_t method = 0); + bool Crop(int32_t left, int32_t top, int32_t right, int32_t bottom, CxImage* iDst = NULL); + bool Crop(const RECT& rect, CxImage* iDst = NULL); + bool CropRotatedRectangle( int32_t topx, int32_t topy, int32_t width, int32_t height, float angle, CxImage* iDst = NULL); + bool Skew(float xgain, float ygain, int32_t xpivot=0, int32_t ypivot=0, bool bEnableInterpolation = false); + bool Expand(int32_t left, int32_t top, int32_t right, int32_t bottom, RGBQUAD canvascolor, CxImage* iDst = 0); + bool Expand(int32_t newx, int32_t newy, RGBQUAD canvascolor, CxImage* iDst = 0); + bool Thumbnail(int32_t newx, int32_t newy, RGBQUAD canvascolor, CxImage* iDst = 0); + bool CircleTransform(int32_t type,int32_t rmax=0,float Koeff=1.0f); + bool QIShrink(int32_t newx, int32_t newy, CxImage* const iDst = NULL, bool bChangeBpp = false); + +//@} +#endif //CXIMAGE_SUPPORT_TRANSFORMATION + +#if CXIMAGE_SUPPORT_DSP +/** \addtogroup DSP */ //@{ + bool Contour(); + bool HistogramStretch(int32_t method = 0, double threshold = 0); + bool HistogramEqualize(); + bool HistogramNormalize(); + bool HistogramRoot(); + bool HistogramLog(); + int32_t Histogram(int32_t* red, int32_t* green = 0, int32_t* blue = 0, int32_t* gray = 0, int32_t colorspace = 0); + bool Jitter(int32_t radius=2); + bool Repair(float radius = 0.25f, int32_t niterations = 1, int32_t colorspace = 0); + bool Combine(CxImage* r,CxImage* g,CxImage* b,CxImage* a, int32_t colorspace = 0); + bool FFT2(CxImage* srcReal, CxImage* srcImag, CxImage* dstReal, CxImage* dstImag, int32_t direction = 1, bool bForceFFT = true, bool bMagnitude = true); + bool Noise(int32_t level); + bool Median(int32_t Ksize=3); + bool Gamma(float gamma); + bool GammaRGB(float gammaR, float gammaG, float gammaB); + bool ShiftRGB(int32_t r, int32_t g, int32_t b); + bool Threshold(uint8_t level); + bool Threshold(CxImage* pThresholdMask); + bool Threshold2(uint8_t level, bool bDirection, RGBQUAD nBkgndColor, bool bSetAlpha = false); + bool Colorize(uint8_t hue, uint8_t sat, float blend = 1.0f); + bool Light(int32_t brightness, int32_t contrast = 0); + float Mean(); + bool Filter(int32_t* kernel, int32_t Ksize, int32_t Kfactor, int32_t Koffset); + bool Erode(int32_t Ksize=2); + bool Dilate(int32_t Ksize=2); + bool Edge(int32_t Ksize=2); + void HuePalette(float correction=1); + enum ImageOpType { OpAdd, OpAnd, OpXor, OpOr, OpMask, OpSrcCopy, OpDstCopy, OpSub, OpSrcBlend, OpScreen, OpAvg, OpBlendAlpha }; + void Mix(CxImage & imgsrc2, ImageOpType op, int32_t lXOffset = 0, int32_t lYOffset = 0, bool bMixAlpha = false); + void MixFrom(CxImage & imagesrc2, int32_t lXOffset, int32_t lYOffset); + bool UnsharpMask(float radius = 5.0f, float amount = 0.5f, int32_t threshold = 0); + bool Lut(uint8_t* pLut); + bool Lut(uint8_t* pLutR, uint8_t* pLutG, uint8_t* pLutB, uint8_t* pLutA = 0); + bool GaussianBlur(float radius = 1.0f, CxImage* iDst = 0); + bool TextBlur(uint8_t threshold = 100, uint8_t decay = 2, uint8_t max_depth = 5, bool bBlurHorizontal = true, bool bBlurVertical = true, CxImage* iDst = 0); + bool SelectiveBlur(float radius = 1.0f, uint8_t threshold = 25, CxImage* iDst = 0); + bool Solarize(uint8_t level = 128, bool bLinkedChannels = true); + bool FloodFill(const int32_t xStart, const int32_t yStart, const RGBQUAD cFillColor, const uint8_t tolerance = 0, + uint8_t nOpacity = 255, const bool bSelectFilledArea = false, const uint8_t nSelectionLevel = 255); + bool Saturate(const int32_t saturation, const int32_t colorspace = 1); + bool ConvertColorSpace(const int32_t dstColorSpace, const int32_t srcColorSpace); + int32_t OptimalThreshold(int32_t method = 0, RECT * pBox = 0, CxImage* pContrastMask = 0); + bool AdaptiveThreshold(int32_t method = 0, int32_t nBoxSize = 64, CxImage* pContrastMask = 0, int32_t nBias = 0, float fGlobalLocalBalance = 0.5f); + bool RedEyeRemove(float strength = 0.8f); + bool Trace(RGBQUAD color_target, RGBQUAD color_trace); + +//@} + +protected: +/** \addtogroup Protected */ //@{ + bool IsPowerof2(int32_t x); + bool FFT(int32_t dir,int32_t m,double *x,double *y); + bool DFT(int32_t dir,int32_t m,double *x1,double *y1,double *x2,double *y2); + bool RepairChannel(CxImage *ch, float radius); + // + int32_t gen_convolve_matrix (float radius, float **cmatrix_p); + float* gen_lookup_table (float *cmatrix, int32_t cmatrix_length); + void blur_line (float *ctable, float *cmatrix, int32_t cmatrix_length, uint8_t* cur_col, uint8_t* dest_col, int32_t y, int32_t bytes); + void blur_text (uint8_t threshold, uint8_t decay, uint8_t max_depth, CxImage* iSrc, CxImage* iDst, uint8_t bytes); +//@} + +public: +/** \addtogroup ColorSpace */ //@{ + bool SplitRGB(CxImage* r,CxImage* g,CxImage* b); + bool SplitYUV(CxImage* y,CxImage* u,CxImage* v); + bool SplitHSL(CxImage* h,CxImage* s,CxImage* l); + bool SplitYIQ(CxImage* y,CxImage* i,CxImage* q); + bool SplitXYZ(CxImage* x,CxImage* y,CxImage* z); + bool SplitCMYK(CxImage* c,CxImage* m,CxImage* y,CxImage* k); + static RGBQUAD HSLtoRGB(COLORREF cHSLColor); + static RGBQUAD RGBtoHSL(RGBQUAD lRGBColor); + static RGBQUAD HSLtoRGB(RGBQUAD lHSLColor); + static RGBQUAD YUVtoRGB(RGBQUAD lYUVColor); + static RGBQUAD RGBtoYUV(RGBQUAD lRGBColor); + static RGBQUAD YIQtoRGB(RGBQUAD lYIQColor); + static RGBQUAD RGBtoYIQ(RGBQUAD lRGBColor); + static RGBQUAD XYZtoRGB(RGBQUAD lXYZColor); + static RGBQUAD RGBtoXYZ(RGBQUAD lRGBColor); +#endif //CXIMAGE_SUPPORT_DSP + static RGBQUAD RGBtoRGBQUAD(COLORREF cr); + static COLORREF RGBQUADtoRGB (RGBQUAD c); +//@} + +/** \addtogroup Selection */ //@{ + bool SelectionIsValid(); +#if CXIMAGE_SUPPORT_SELECTION + bool SelectionClear(uint8_t level = 0); + bool SelectionCreate(); + bool SelectionDelete(); + bool SelectionInvert(); + bool SelectionMirror(); + bool SelectionFlip(); + bool SelectionAddRect(RECT r, uint8_t level = 255); + bool SelectionAddEllipse(RECT r, uint8_t level = 255); + bool SelectionAddPolygon(POINT *points, int32_t npoints, uint8_t level = 255); + bool SelectionAddColor(RGBQUAD c, uint8_t level = 255); + bool SelectionAddPixel(int32_t x, int32_t y, uint8_t level = 255); + bool SelectionCopy(CxImage &from); + bool SelectionIsInside(int32_t x, int32_t y); + void SelectionGetBox(RECT& r); + bool SelectionToHRGN(HRGN& region); + bool SelectionSplit(CxImage *dest); + uint8_t SelectionGet(const int32_t x,const int32_t y); + bool SelectionSet(CxImage &from); + void SelectionRebuildBox(); + uint8_t* SelectionGetPointer(const int32_t x = 0,const int32_t y = 0); +//@} + +protected: +/** \addtogroup Protected */ //@{ + bool BlindSelectionIsInside(int32_t x, int32_t y); + uint8_t BlindSelectionGet(const int32_t x,const int32_t y); + void SelectionSet(const int32_t x,const int32_t y,const uint8_t level); + +public: + +#endif //CXIMAGE_SUPPORT_SELECTION +//@} + +#if CXIMAGE_SUPPORT_ALPHA +/** \addtogroup Alpha */ //@{ + void AlphaClear(); + bool AlphaCreate(); + void AlphaDelete(); + void AlphaInvert(); + bool AlphaMirror(); + bool AlphaFlip(); + bool AlphaCopy(CxImage &from); + bool AlphaSplit(CxImage *dest); + void AlphaStrip(); + void AlphaSet(uint8_t level); + bool AlphaSet(CxImage &from); + void AlphaSet(const int32_t x,const int32_t y,const uint8_t level); + uint8_t AlphaGet(const int32_t x,const int32_t y); + uint8_t AlphaGetMax() const; + void AlphaSetMax(uint8_t nAlphaMax); + bool AlphaIsValid(); + uint8_t* AlphaGetPointer(const int32_t x = 0,const int32_t y = 0); + bool AlphaFromTransparency(); + + void AlphaPaletteClear(); + void AlphaPaletteEnable(bool enable=true); + bool AlphaPaletteIsEnabled(); + bool AlphaPaletteIsValid(); + bool AlphaPaletteSplit(CxImage *dest); +//@} + +protected: +/** \addtogroup Protected */ //@{ + uint8_t BlindAlphaGet(const int32_t x,const int32_t y); +//@} +#endif //CXIMAGE_SUPPORT_ALPHA + +public: +#if CXIMAGE_SUPPORT_LAYERS +/** \addtogroup Layers */ //@{ + bool LayerCreate(int32_t position = -1); + bool LayerDelete(int32_t position = -1); + void LayerDeleteAll(); + CxImage* GetLayer(int32_t position); + CxImage* GetParent() const; + int32_t GetNumLayers() const; + int32_t LayerDrawAll(HDC hdc, int32_t x=0, int32_t y=0, int32_t cx = -1, int32_t cy = -1, RECT* pClipRect = 0, bool bSmooth = false); + int32_t LayerDrawAll(HDC hdc, const RECT& rect, RECT* pClipRect=NULL, bool bSmooth = false); +//@} +#endif //CXIMAGE_SUPPORT_LAYERS + +protected: +/** \addtogroup Protected */ //@{ + void Startup(uint32_t imagetype = 0); + void CopyInfo(const CxImage &src); + void Ghost(const CxImage *src); + void RGBtoBGR(uint8_t *buffer, int32_t length); + static float HueToRGB(float n1,float n2, float hue); + void Bitfield2RGB(uint8_t *src, uint32_t redmask, uint32_t greenmask, uint32_t bluemask, uint8_t bpp); + static int32_t CompareColors(const void *elem1, const void *elem2); + int16_t m_ntohs(const int16_t word); + int32_t m_ntohl(const int32_t dword); + void bihtoh(BITMAPINFOHEADER* bih); + + void* pDib; //contains the header, the palette, the pixels + BITMAPINFOHEADER head; //standard header + CXIMAGEINFO info; //extended information + uint8_t* pSelection; //selected region + uint8_t* pAlpha; //alpha channel + CxImage** ppLayers; //generic layers + CxImage** ppFrames; +//@} +}; + +//////////////////////////////////////////////////////////////////////////// +#endif // !defined(__CXIMAGE_H) diff --git a/cximage/ximagif.h b/cximage/ximagif.h new file mode 100644 index 0000000..347afff --- /dev/null +++ b/cximage/ximagif.h @@ -0,0 +1,244 @@ +/* + * File: ximagif.h + * Purpose: GIF Image Class Loader and Writer + */ +/* ========================================================== + * CxImageGIF (c) 07/Aug/2001 Davide Pizzolato - www.xdp.it + * For conditions of distribution and use, see copyright notice in ximage.h + * + * Special thanks to Troels Knakkergaard for new features, enhancements and bugfixes + * + * original CImageGIF and CImageIterator implementation are: + * Copyright: (c) 1995, Alejandro Aguilar Sierra + * + * 6/15/97 Randy Spann: Added GIF87a writing support + * R.Spann@ConnRiver.net + * + * DECODE.C - An LZW decoder for GIF + * Copyright (C) 1987, by Steven A. Bennett + * Copyright (C) 1994, C++ version by Alejandro Aguilar Sierra + * + * In accordance with the above, I want to credit Steve Wilhite who wrote + * the code which this is heavily inspired by... + * + * GIF and 'Graphics Interchange Format' are trademarks (tm) of + * Compuserve, Incorporated, an H&R Block Company. + * + * Release Notes: This file contains a decoder routine for GIF images + * which is similar, structurally, to the original routine by Steve Wilhite. + * It is, however, somewhat noticably faster in most cases. + * + * ========================================================== + */ + +#if !defined(__ximaGIF_h) +#define __ximaGIF_h + +#include "ximage.h" + +#if CXIMAGE_SUPPORT_GIF + +typedef int16_t code_int; + +/* Various error codes used by decoder */ +#define OUT_OF_MEMORY -10 +#define BAD_CODE_SIZE -20 +#define READ_ERROR -1 +#define WRITE_ERROR -2 +#define OPEN_ERROR -3 +#define CREATE_ERROR -4 +#define BAD_LINE_WIDTH -5 +#define MAX_CODES 4095 +#define GIFBUFTAM 16383 +#define TRANSPARENCY_CODE 0xF9 + +//LZW GIF Image compression +#define MAXBITSCODES 12 +#define HSIZE 5003 /* 80% occupancy */ +#define MAXCODE(n_bits) (((code_int) 1 << (n_bits)) - 1) +#define HashTabOf(i) htab[i] +#define CodeTabOf(i) codetab[i] + + +class CImageIterator; +class DLL_EXP CxImageGIF: public CxImage +{ +#pragma pack(1) + +typedef struct tag_gifgce{ + uint8_t flags; /*res:3|dispmeth:3|userinputflag:1|transpcolflag:1*/ + uint16_t delaytime; + uint8_t transpcolindex; +} struct_gifgce; + +typedef struct tag_dscgif{ /* Logic Screen Descriptor */ + char header[6]; /* Firma and version */ + uint16_t scrwidth; + uint16_t scrheight; + char pflds; + char bcindx; + char pxasrat; +} struct_dscgif; + +typedef struct tag_image{ /* Image Descriptor */ + uint16_t l; + uint16_t t; + uint16_t w; + uint16_t h; + uint8_t pf; +} struct_image; + +typedef struct tag_TabCol{ /* Tabla de colores */ + int16_t colres; /* color resolution */ + int16_t sogct; /* size of global color table */ + rgb_color paleta[256]; /* paleta */ +} struct_TabCol; + +typedef struct tag_RLE{ + int32_t rl_pixel; + int32_t rl_basecode; + int32_t rl_count; + int32_t rl_table_pixel; + int32_t rl_table_max; + int32_t just_cleared; + int32_t out_bits; + int32_t out_bits_init; + int32_t out_count; + int32_t out_bump; + int32_t out_bump_init; + int32_t out_clear; + int32_t out_clear_init; + int32_t max_ocodes; + int32_t code_clear; + int32_t code_eof; + uint32_t obuf; + int32_t obits; + uint8_t oblock[256]; + int32_t oblen; +} struct_RLE; +#pragma pack() + +public: + CxImageGIF(); + ~CxImageGIF(); + +// bool Load(const TCHAR * imageFileName){ return CxImage::Load(imageFileName,CXIMAGE_FORMAT_GIF);} +// bool Save(const TCHAR * imageFileName){ return CxImage::Save(imageFileName,CXIMAGE_FORMAT_GIF);} + + bool Decode(CxFile * fp); + bool Decode(FILE *fp) { CxIOFile file(fp); return Decode(&file); } + +#if CXIMAGE_SUPPORT_ENCODE + bool Encode(CxFile * fp); + bool Encode(CxFile * fp, CxImage ** pImages, int32_t pagecount, bool bLocalColorMap = false, bool bLocalDispMeth = false); + bool Encode(FILE *fp) { CxIOFile file(fp); return Encode(&file); } + bool Encode(FILE *fp, CxImage ** pImages, int32_t pagecount, bool bLocalColorMap = false) + { CxIOFile file(fp); return Encode(&file, pImages, pagecount, bLocalColorMap); } +#endif // CXIMAGE_SUPPORT_ENCODE + + void SetLoops(int32_t loops); + int32_t GetLoops(); + void SetComment(const char* sz_comment_in); + void GetComment(char* sz_comment_out); + +protected: + bool DecodeExtension(CxFile *fp); + void EncodeHeader(CxFile *fp); + void EncodeLoopExtension(CxFile *fp); + void EncodeExtension(CxFile *fp); + void EncodeBody(CxFile *fp, bool bLocalColorMap = false); + void EncodeComment(CxFile *fp); + bool EncodeRGB(CxFile *fp); + void GifMix(CxImage & imgsrc2, struct_image & imgdesc); + + struct_gifgce gifgce; + + int32_t curx, cury; + int32_t CountDown; + uint32_t cur_accum; + int32_t cur_bits; + int32_t interlaced, iypos, istep, iheight, ipass; + int32_t ibf; + int32_t ibfmax; + uint8_t * buf; +// Implementation + int32_t GifNextPixel (); + void Putword (int32_t w, CxFile* fp ); + void compressNONE (int32_t init_bits, CxFile* outfile); + void compressLZW (int32_t init_bits, CxFile* outfile); + void output (code_int code ); + void cl_hash (int32_t hsize); + void char_out (int32_t c); + void flush_char (); + int16_t init_exp(int16_t size); + int16_t get_next_code(CxFile*); + int16_t decoder(CxFile*, CImageIterator* iter, int16_t linewidth, int32_t &bad_code_count); + int32_t get_byte(CxFile*); + int32_t out_line(CImageIterator* iter, uint8_t *pixels, int32_t linelen); + int32_t get_num_frames(CxFile *f,struct_TabCol* TabColSrc,struct_dscgif* dscgif); + int32_t seek_next_image(CxFile* fp, int32_t position); + + int16_t curr_size; /* The current code size */ + int16_t clear; /* Value for a clear code */ + int16_t ending; /* Value for a ending code */ + int16_t newcodes; /* First available code */ + int16_t top_slot; /* Highest code for current size */ + int16_t slot; /* Last read code */ + + /* The following static variables are used + * for seperating out codes */ + int16_t navail_bytes; /* # bytes left in block */ + int16_t nbits_left; /* # bits left in current uint8_t */ + uint8_t b1; /* Current uint8_t */ + uint8_t * byte_buff; /* Current block */ + uint8_t *pbytes; /* Pointer to next uint8_t in block */ + /* The reason we have these seperated like this instead of using + * a structure like the original Wilhite code did, is because this + * stuff generally produces significantly faster code when compiled... + * This code is full of similar speedups... (For a good book on writing + * C for speed or for space optomisation, see Efficient C by Tom Plum, + * published by Plum-Hall Associates...) + */ + uint8_t * stack; /* Stack for storing pixels */ + uint8_t * suffix; /* Suffix table */ + uint16_t * prefix; /* Prefix linked list */ + +//LZW GIF Image compression routines + int32_t * htab; + uint16_t * codetab; + int32_t n_bits; /* number of bits/code */ + code_int maxcode; /* maximum code, given n_bits */ + code_int free_ent; /* first unused entry */ + int32_t clear_flg; + int32_t g_init_bits; + CxFile* g_outfile; + int32_t ClearCode; + int32_t EOFCode; + + int32_t a_count; + char * accum; + + char * m_comment; + int32_t m_loops; + +//RLE compression routines + void compressRLE( int32_t init_bits, CxFile* outfile); + void rle_clear(struct_RLE* rle); + void rle_flush(struct_RLE* rle); + void rle_flush_withtable(int32_t count, struct_RLE* rle); + void rle_flush_clearorrep(int32_t count, struct_RLE* rle); + void rle_flush_fromclear(int32_t count,struct_RLE* rle); + void rle_output_plain(int32_t c,struct_RLE* rle); + void rle_reset_out_clear(struct_RLE* rle); + uint32_t rle_compute_triangle_count(uint32_t count, uint32_t nrepcodes); + uint32_t rle_isqrt(uint32_t x); + void rle_write_block(struct_RLE* rle); + void rle_block_out(uint8_t c, struct_RLE* rle); + void rle_block_flush(struct_RLE* rle); + void rle_output(int32_t val, struct_RLE* rle); + void rle_output_flush(struct_RLE* rle); +}; + +#endif + +#endif diff --git a/cximage/ximaico.h b/cximage/ximaico.h new file mode 100644 index 0000000..023ce67 --- /dev/null +++ b/cximage/ximaico.h @@ -0,0 +1,58 @@ +/* + * File: ximaico.h + * Purpose: ICON Image Class Loader and Writer + */ +/* ========================================================== + * CxImageICO (c) 07/Aug/2001 Davide Pizzolato - www.xdp.it + * For conditions of distribution and use, see copyright notice in ximage.h + * ========================================================== + */ +#if !defined(__ximaICO_h) +#define __ximaICO_h + +#include "ximage.h" + +#if CXIMAGE_SUPPORT_ICO + +class CxImageICO: public CxImage +{ +typedef struct tagIconDirectoryEntry { + uint8_t bWidth; + uint8_t bHeight; + uint8_t bColorCount; + uint8_t bReserved; + uint16_t wPlanes; + uint16_t wBitCount; + uint32_t dwBytesInRes; + uint32_t dwImageOffset; +} ICONDIRENTRY; + +typedef struct tagIconDir { + uint16_t idReserved; + uint16_t idType; + uint16_t idCount; +} ICONHEADER; + +public: + CxImageICO(): CxImage(CXIMAGE_FORMAT_ICO) {m_dwImageOffset=0;} + +// bool Load(const TCHAR * imageFileName){ return CxImage::Load(imageFileName,CXIMAGE_FORMAT_ICO);} +// bool Save(const TCHAR * imageFileName){ return CxImage::Save(imageFileName,CXIMAGE_FORMAT_ICO);} + bool Decode(CxFile * hFile); + bool Decode(FILE *hFile) { CxIOFile file(hFile); return Decode(&file); } + +#if CXIMAGE_SUPPORT_ENCODE + bool Encode(CxFile * hFile, bool bAppend=false, int32_t nPageCount=0); + bool Encode(CxFile * hFile, CxImage ** pImages, int32_t nPageCount); + bool Encode(FILE *hFile, bool bAppend=false, int32_t nPageCount=0) + { CxIOFile file(hFile); return Encode(&file,bAppend,nPageCount); } + bool Encode(FILE *hFile, CxImage ** pImages, int32_t nPageCount) + { CxIOFile file(hFile); return Encode(&file, pImages, nPageCount); } +#endif // CXIMAGE_SUPPORT_ENCODE +protected: + uint32_t m_dwImageOffset; +}; + +#endif + +#endif diff --git a/cximage/ximaiter.h b/cximage/ximaiter.h new file mode 100644 index 0000000..b160b20 --- /dev/null +++ b/cximage/ximaiter.h @@ -0,0 +1,253 @@ +/* + * File: ImaIter.h + * Purpose: Declaration of the Platform Independent Image Base Class + * Author: Alejandro Aguilar Sierra + * Created: 1995 + * Copyright: (c) 1995, Alejandro Aguilar Sierra + * + * 07/08/2001 Davide Pizzolato - www.xdp.it + * - removed slow loops + * - added safe checks + * + * Permission is given by the author to freely redistribute and include + * this code in any program as int32_t as this credit is given where due. + * + * COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY + * OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES + * THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE + * OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED + * CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT + * THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY + * SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL + * PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER + * THIS DISCLAIMER. + * + * Use at your own risk! + * ========================================================== + */ + +#if !defined(__ImaIter_h) +#define __ImaIter_h + +#include "ximage.h" +#include "ximadef.h" + +class CImageIterator +{ +friend class CxImage; +protected: + int32_t Itx, Ity; // Counters + int32_t Stepx, Stepy; + uint8_t* IterImage; // Image pointer + CxImage *ima; +public: + // Constructors + CImageIterator ( void ); + CImageIterator ( CxImage *image ); + operator CxImage* (); + + // Iterators + BOOL ItOK (); + void Reset (); + void Upset (); + void SetRow(uint8_t *buf, int32_t n); + void GetRow(uint8_t *buf, int32_t n); + uint8_t GetByte( ) { return IterImage[Itx]; } + void SetByte(uint8_t b) { IterImage[Itx] = b; } + uint8_t* GetRow(void); + uint8_t* GetRow(int32_t n); + BOOL NextRow(); + BOOL PrevRow(); + BOOL NextByte(); + BOOL PrevByte(); + + void SetSteps(int32_t x, int32_t y=0) { Stepx = x; Stepy = y; } + void GetSteps(int32_t *x, int32_t *y) { *x = Stepx; *y = Stepy; } + BOOL NextStep(); + BOOL PrevStep(); + + void SetY(int32_t y); /* AD - for interlace */ + int32_t GetY() {return Ity;} + BOOL GetCol(uint8_t* pCol, uint32_t x); + BOOL SetCol(uint8_t* pCol, uint32_t x); +}; + +///////////////////////////////////////////////////////////////////// +inline +CImageIterator::CImageIterator(void) +{ + ima = 0; + IterImage = 0; + Itx = Ity = 0; + Stepx = Stepy = 0; +} +///////////////////////////////////////////////////////////////////// +inline +CImageIterator::CImageIterator(CxImage *imageImpl): ima(imageImpl) +{ + if (ima) IterImage = ima->GetBits(); + Itx = Ity = 0; + Stepx = Stepy = 0; +} +///////////////////////////////////////////////////////////////////// +inline +CImageIterator::operator CxImage* () +{ + return ima; +} +///////////////////////////////////////////////////////////////////// +inline BOOL CImageIterator::ItOK () +{ + if (ima) return ima->IsInside(Itx, Ity); + else return FALSE; +} +///////////////////////////////////////////////////////////////////// +inline void CImageIterator::Reset() +{ + if (ima) IterImage = ima->GetBits(); + else IterImage=0; + Itx = Ity = 0; +} +///////////////////////////////////////////////////////////////////// +inline void CImageIterator::Upset() +{ + Itx = 0; + Ity = ima->GetHeight()-1; + IterImage = ima->GetBits() + ima->GetEffWidth()*(ima->GetHeight()-1); +} +///////////////////////////////////////////////////////////////////// +inline BOOL CImageIterator::NextRow() +{ + if (++Ity >= (int32_t)ima->GetHeight()) return 0; + IterImage += ima->GetEffWidth(); + return 1; +} +///////////////////////////////////////////////////////////////////// +inline BOOL CImageIterator::PrevRow() +{ + if (--Ity < 0) return 0; + IterImage -= ima->GetEffWidth(); + return 1; +} +/* AD - for interlace */ +inline void CImageIterator::SetY(int32_t y) +{ + if ((y < 0) || (y > (int32_t)ima->GetHeight())) return; + Ity = y; + IterImage = ima->GetBits() + ima->GetEffWidth()*y; +} +///////////////////////////////////////////////////////////////////// +inline void CImageIterator::SetRow(uint8_t *buf, int32_t n) +{ + if (n<0) n = (int32_t)ima->GetEffWidth(); + else n = min(n,(int32_t)ima->GetEffWidth()); + + if ((IterImage!=NULL)&&(buf!=NULL)&&(n>0)) memcpy(IterImage,buf,n); +} +///////////////////////////////////////////////////////////////////// +inline void CImageIterator::GetRow(uint8_t *buf, int32_t n) +{ + if ((IterImage!=NULL)&&(buf!=NULL)&&(n>0)) + memcpy(buf,IterImage,min(n,(int32_t)ima->GetEffWidth())); +} +///////////////////////////////////////////////////////////////////// +inline uint8_t* CImageIterator::GetRow() +{ + return IterImage; +} +///////////////////////////////////////////////////////////////////// +inline uint8_t* CImageIterator::GetRow(int32_t n) +{ + SetY(n); + return IterImage; +} +///////////////////////////////////////////////////////////////////// +inline BOOL CImageIterator::NextByte() +{ + if (++Itx < (int32_t)ima->GetEffWidth()) return 1; + else + if (++Ity < (int32_t)ima->GetHeight()){ + IterImage += ima->GetEffWidth(); + Itx = 0; + return 1; + } else + return 0; +} +///////////////////////////////////////////////////////////////////// +inline BOOL CImageIterator::PrevByte() +{ + if (--Itx >= 0) return 1; + else + if (--Ity >= 0){ + IterImage -= ima->GetEffWidth(); + Itx = 0; + return 1; + } else + return 0; +} +///////////////////////////////////////////////////////////////////// +inline BOOL CImageIterator::NextStep() +{ + Itx += Stepx; + if (Itx < (int32_t)ima->GetEffWidth()) return 1; + else { + Ity += Stepy; + if (Ity < (int32_t)ima->GetHeight()){ + IterImage += ima->GetEffWidth(); + Itx = 0; + return 1; + } else + return 0; + } +} +///////////////////////////////////////////////////////////////////// +inline BOOL CImageIterator::PrevStep() +{ + Itx -= Stepx; + if (Itx >= 0) return 1; + else { + Ity -= Stepy; + if (Ity >= 0 && Ity < (int32_t)ima->GetHeight()) { + IterImage -= ima->GetEffWidth(); + Itx = 0; + return 1; + } else + return 0; + } +} +///////////////////////////////////////////////////////////////////// +inline BOOL CImageIterator::GetCol(uint8_t* pCol, uint32_t x) +{ + if ((pCol==0)||(ima->GetBpp()<8)||(x>=ima->GetWidth())) + return 0; + uint32_t h = ima->GetHeight(); + //uint32_t line = ima->GetEffWidth(); + uint8_t bytes = (uint8_t)(ima->GetBpp()>>3); + uint8_t* pSrc; + for (uint32_t y=0;yGetBits(y) + x*bytes; + for (uint8_t w=0;wGetBpp()<8)||(x>=ima->GetWidth())) + return 0; + uint32_t h = ima->GetHeight(); + //uint32_t line = ima->GetEffWidth(); + uint8_t bytes = (uint8_t)(ima->GetBpp()>>3); + uint8_t* pSrc; + for (uint32_t y=0;yGetBits(y) + x*bytes; + for (uint8_t w=0;w +#else + #include "../jasper/include/jasper/jasper.h" +#endif + +class CxImageJAS: public CxImage +{ +public: + CxImageJAS(): CxImage((uint32_t)0) {} // cast to uint32_t + +// bool Load(const TCHAR * imageFileName){ return CxImage::Load(imageFileName,0);} +// bool Save(const TCHAR * imageFileName){ return CxImage::Save(imageFileName,0);} + bool Decode(CxFile * hFile, uint32_t imagetype = 0); + bool Decode(FILE *hFile, uint32_t imagetype = 0) { CxIOFile file(hFile); return Decode(&file,imagetype); } + +#if CXIMAGE_SUPPORT_ENCODE + bool Encode(CxFile * hFile, uint32_t imagetype = 0); + bool Encode(FILE *hFile, uint32_t imagetype = 0) { CxIOFile file(hFile); return Encode(&file,imagetype); } +#endif // CXIMAGE_SUPPORT_ENCODE +protected: + + class CxFileJas + { + public: + CxFileJas(CxFile* pFile,jas_stream_t *stream) + { + if (stream->obj_) jas_free(stream->obj_); + stream->obj_ = pFile; + + // - cannot set the stream->ops_->functions here, + // because this overwrites a static structure in the Jasper library. + // This structure is used by Jasper for internal operations too, e.g. tempfile. + // However the ops_ pointer in the stream can be overwritten. + + //stream->ops_->close_ = JasClose; + //stream->ops_->read_ = JasRead; + //stream->ops_->seek_ = JasSeek; + //stream->ops_->write_ = JasWrite; + + jas_stream_CxFile.close_ = JasClose; + jas_stream_CxFile.read_ = JasRead; + jas_stream_CxFile.seek_ = JasSeek; + jas_stream_CxFile.write_ = JasWrite; + + stream->ops_ = &jas_stream_CxFile; + + // - end + } + static int32_t JasRead(jas_stream_obj_t *obj, char *buf, int32_t cnt) + { return ((CxFile*)obj)->Read(buf,1,cnt); } + static int32_t JasWrite(jas_stream_obj_t *obj, char *buf, int32_t cnt) + { return ((CxFile*)obj)->Write(buf,1,cnt); } + static long JasSeek(jas_stream_obj_t *obj, long offset, int32_t origin) + { return ((CxFile*)obj)->Seek(offset,origin); } + static int32_t JasClose(jas_stream_obj_t * /*obj*/) + { return 1; } + + // +private: + jas_stream_ops_t jas_stream_CxFile; + // - end + + }; + +}; + +#endif + +#endif diff --git a/cximage/ximajbg.h b/cximage/ximajbg.h new file mode 100644 index 0000000..55a6d76 --- /dev/null +++ b/cximage/ximajbg.h @@ -0,0 +1,44 @@ +/* + * File: ximajbg.h + * Purpose: JBG Image Class Loader and Writer + */ +/* ========================================================== + * CxImageJBG (c) 18/Aug/2002 Davide Pizzolato - www.xdp.it + * For conditions of distribution and use, see copyright notice in ximage.h + * + * based on LIBJBG Copyright (c) 2002, Markus Kuhn - All rights reserved. + * ========================================================== + */ +#if !defined(__ximaJBG_h) +#define __ximaJBG_h + +#include "ximage.h" + +#if CXIMAGE_SUPPORT_JBG + +extern "C" { +#include "../jbig/jbig.h" +}; + +class CxImageJBG: public CxImage +{ +public: + CxImageJBG(): CxImage(CXIMAGE_FORMAT_JBG) {} + +// bool Load(const TCHAR * imageFileName){ return CxImage::Load(imageFileName,CXIMAGE_FORMAT_JBG);} +// bool Save(const TCHAR * imageFileName){ return CxImage::Save(imageFileName,CXIMAGE_FORMAT_JBG);} + bool Decode(CxFile * hFile); + bool Decode(FILE *hFile) { CxIOFile file(hFile); return Decode(&file); } + +#if CXIMAGE_SUPPORT_ENCODE + bool Encode(CxFile * hFile); + bool Encode(FILE *hFile) { CxIOFile file(hFile); return Encode(&file); } +#endif // CXIMAGE_SUPPORT_ENCODE +protected: + static void jbig_data_out(uint8_t *buffer, uint32_t len, void *file) + {((CxFile*)file)->Write(buffer,len,1);} +}; + +#endif + +#endif diff --git a/cximage/ximajpg.h b/cximage/ximajpg.h new file mode 100644 index 0000000..4b2fe54 --- /dev/null +++ b/cximage/ximajpg.h @@ -0,0 +1,283 @@ +/* + * File: ximajpg.h + * Purpose: JPG Image Class Loader and Writer + */ +/* ========================================================== + * CxImageJPG (c) 07/Aug/2001 Davide Pizzolato - www.xdp.it + * For conditions of distribution and use, see copyright notice in ximage.h + * + * Special thanks to Troels Knakkergaard for new features, enhancements and bugfixes + * + * Special thanks to Chris Shearer Cooper for CxFileJpg tips & code + * + * EXIF support based on jhead-1.8 by Matthias Wandel + * + * original CImageJPG and CImageIterator implementation are: + * Copyright: (c) 1995, Alejandro Aguilar Sierra + * + * This software is based in part on the work of the Independent JPEG Group. + * Copyright (C) 1991-1998, Thomas G. Lane. + * ========================================================== + */ +#if !defined(__ximaJPEG_h) +#define __ximaJPEG_h + +#include "ximage.h" + +#if CXIMAGE_SUPPORT_JPG + +#define CXIMAGEJPG_SUPPORT_EXIF CXIMAGE_SUPPORT_EXIF + +extern "C" { +#ifdef _LINUX + #include + #include +#else + #include "../jpeg/jpeglib.h" + #include "../jpeg/jerror.h" +#endif +} + +class DLL_EXP CxImageJPG: public CxImage +{ +public: + CxImageJPG(); + ~CxImageJPG(); + +// bool Load(const TCHAR * imageFileName){ return CxImage::Load(imageFileName,CXIMAGE_FORMAT_JPG);} +// bool Save(const TCHAR * imageFileName){ return CxImage::Save(imageFileName,CXIMAGE_FORMAT_JPG);} + bool Decode(CxFile * hFile); + bool Decode(FILE *hFile) { CxIOFile file(hFile); return Decode(&file); } + +#if CXIMAGE_SUPPORT_ENCODE + bool Encode(CxFile * hFile); + bool Encode(FILE *hFile) { CxIOFile file(hFile); return Encode(&file); } +#endif // CXIMAGE_SUPPORT_ENCODE + +/* + * EXIF support based on jhead-1.8 by Matthias Wandel + */ + +#if CXIMAGEJPG_SUPPORT_EXIF + +//-------------------------------------------------------------------------- +// JPEG markers consist of one or more 0xFF bytes, followed by a marker +// code byte (which is not an FF). Here are the marker codes of interest +// in this program. (See jdmarker.c for a more complete list.) +//-------------------------------------------------------------------------- + +#define M_SOF0 0xC0 // Start Of Frame N +#define M_SOF1 0xC1 // N indicates which compression process +#define M_SOF2 0xC2 // Only SOF0-SOF2 are now in common use +#define M_SOF3 0xC3 +#define M_SOF5 0xC5 // NB: codes C4 and CC are NOT SOF markers +#define M_SOF6 0xC6 +#define M_SOF7 0xC7 +#define M_SOF9 0xC9 +#define M_SOF10 0xCA +#define M_SOF11 0xCB +#define M_SOF13 0xCD +#define M_SOF14 0xCE +#define M_SOF15 0xCF +#define M_SOI 0xD8 // Start Of Image (beginning of datastream) +#define M_EOI 0xD9 // End Of Image (end of datastream) +#define M_SOS 0xDA // Start Of Scan (begins compressed data) +#define M_JFIF 0xE0 // Jfif marker +#define M_EXIF 0xE1 // Exif marker +#define M_COM 0xFE // COMment + +#define PSEUDO_IMAGE_MARKER 0x123; // Extra value. + +#define EXIF_READ_EXIF 0x01 +#define EXIF_READ_IMAGE 0x02 +#define EXIF_READ_ALL 0x03 + +class DLL_EXP CxExifInfo +{ + +typedef struct tag_Section_t{ + uint8_t* Data; + int32_t Type; + unsigned Size; +} Section_t; + +public: + EXIFINFO* m_exifinfo; + char m_szLastError[256]; + CxExifInfo(EXIFINFO* info = NULL); + ~CxExifInfo(); + bool DecodeExif(CxFile * hFile, int32_t nReadMode = EXIF_READ_EXIF); + bool EncodeExif(CxFile * hFile); + void DiscardAllButExif(); +protected: + bool process_EXIF(uint8_t * CharBuf, uint32_t length); + void process_COM (const uint8_t * Data, int32_t length); + void process_SOFn (const uint8_t * Data, int32_t marker); + int32_t Get16u(void * Short); + int32_t Get16m(void * Short); + int32_t Get32s(void * Long); + uint32_t Get32u(void * Long); + double ConvertAnyFormat(void * ValuePtr, int32_t Format); + void* FindSection(int32_t SectionType); + bool ProcessExifDir(uint8_t * DirStart, uint8_t * OffsetBase, unsigned ExifLength, + EXIFINFO * const pInfo, uint8_t ** const LastExifRefdP, int32_t NestingLevel=0); + int32_t ExifImageWidth; + int32_t MotorolaOrder; + Section_t Sections[MAX_SECTIONS]; + int32_t SectionsRead; + bool freeinfo; +}; + + CxExifInfo* m_exif; + bool DecodeExif(CxFile * hFile); + bool DecodeExif(FILE * hFile) { CxIOFile file(hFile); return DecodeExif(&file); } + bool GetExifThumbnail(const TCHAR *filename, const TCHAR *outname, int32_t type); + +#endif //CXIMAGEJPG_SUPPORT_EXIF + +//////////////////////////////////////////////////////////////////////////////////////// +////////////////////// C x F i l e J p g //////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////// + +// thanks to Chris Shearer Cooper +class CxFileJpg : public jpeg_destination_mgr, public jpeg_source_mgr + { +public: + enum { eBufSize = 4096 }; + + CxFileJpg(CxFile* pFile) + { + m_pFile = pFile; + + init_destination = InitDestination; + empty_output_buffer = EmptyOutputBuffer; + term_destination = TermDestination; + + init_source = InitSource; + fill_input_buffer = FillInputBuffer; + skip_input_data = SkipInputData; + resync_to_restart = jpeg_resync_to_restart; // use default method + term_source = TermSource; + next_input_byte = NULL; //* => next byte to read from buffer + bytes_in_buffer = 0; //* # of bytes remaining in buffer + + m_pBuffer = new uint8_t[eBufSize]; + } + ~CxFileJpg() + { + delete [] m_pBuffer; + } + + static void InitDestination(j_compress_ptr cinfo) + { + CxFileJpg* pDest = (CxFileJpg*)cinfo->dest; + pDest->next_output_byte = pDest->m_pBuffer; + pDest->free_in_buffer = eBufSize; + } + + static boolean EmptyOutputBuffer(j_compress_ptr cinfo) + { + CxFileJpg* pDest = (CxFileJpg*)cinfo->dest; + if (pDest->m_pFile->Write(pDest->m_pBuffer,1,eBufSize)!=(size_t)eBufSize) + ERREXIT(cinfo, JERR_FILE_WRITE); + pDest->next_output_byte = pDest->m_pBuffer; + pDest->free_in_buffer = eBufSize; + return TRUE; + } + + static void TermDestination(j_compress_ptr cinfo) + { + CxFileJpg* pDest = (CxFileJpg*)cinfo->dest; + size_t datacount = eBufSize - pDest->free_in_buffer; + /* Write any data remaining in the buffer */ + if (datacount > 0) { + if (!pDest->m_pFile->Write(pDest->m_pBuffer,1,datacount)) + ERREXIT(cinfo, JERR_FILE_WRITE); + } + pDest->m_pFile->Flush(); + /* Make sure we wrote the output file OK */ + if (pDest->m_pFile->Error()) ERREXIT(cinfo, JERR_FILE_WRITE); + return; + } + + static void InitSource(j_decompress_ptr cinfo) + { + CxFileJpg* pSource = (CxFileJpg*)cinfo->src; + pSource->m_bStartOfFile = TRUE; + } + + static boolean FillInputBuffer(j_decompress_ptr cinfo) + { + size_t nbytes; + CxFileJpg* pSource = (CxFileJpg*)cinfo->src; + nbytes = pSource->m_pFile->Read(pSource->m_pBuffer,1,eBufSize); + if (nbytes <= 0){ + if (pSource->m_bStartOfFile) //* Treat empty input file as fatal error + ERREXIT(cinfo, JERR_INPUT_EMPTY); + WARNMS(cinfo, JWRN_JPEG_EOF); + // Insert a fake EOI marker + pSource->m_pBuffer[0] = (JOCTET) 0xFF; + pSource->m_pBuffer[1] = (JOCTET) JPEG_EOI; + nbytes = 2; + } + pSource->next_input_byte = pSource->m_pBuffer; + pSource->bytes_in_buffer = nbytes; + pSource->m_bStartOfFile = FALSE; + return TRUE; + } + + static void SkipInputData(j_decompress_ptr cinfo, long num_bytes) + { + CxFileJpg* pSource = (CxFileJpg*)cinfo->src; + if (num_bytes > 0){ + while (num_bytes > (int32_t)pSource->bytes_in_buffer){ + num_bytes -= (int32_t)pSource->bytes_in_buffer; + FillInputBuffer(cinfo); + // note we assume that fill_input_buffer will never return FALSE, + // so suspension need not be handled. + } + pSource->next_input_byte += (size_t) num_bytes; + pSource->bytes_in_buffer -= (size_t) num_bytes; + } + } + + static void TermSource(j_decompress_ptr /*cinfo*/) + { + return; + } +protected: + CxFile *m_pFile; + uint8_t *m_pBuffer; + bool m_bStartOfFile; +}; + +public: + enum CODEC_OPTION + { + ENCODE_BASELINE = 0x1, + ENCODE_ARITHMETIC = 0x2, + ENCODE_GRAYSCALE = 0x4, + ENCODE_OPTIMIZE = 0x8, + ENCODE_PROGRESSIVE = 0x10, + ENCODE_LOSSLESS = 0x20, + ENCODE_SMOOTHING = 0x40, + DECODE_GRAYSCALE = 0x80, + DECODE_QUANTIZE = 0x100, + DECODE_DITHER = 0x200, + DECODE_ONEPASS = 0x400, + DECODE_NOSMOOTH = 0x800, + ENCODE_SUBSAMPLE_422 = 0x1000, + ENCODE_SUBSAMPLE_444 = 0x2000 + }; + + int32_t m_nPredictor; + int32_t m_nPointTransform; + int32_t m_nSmoothing; + int32_t m_nQuantize; + J_DITHER_MODE m_nDither; + +}; + +#endif + +#endif diff --git a/cximage/ximamng.h b/cximage/ximamng.h new file mode 100644 index 0000000..5142194 --- /dev/null +++ b/cximage/ximamng.h @@ -0,0 +1,88 @@ +/* + * File: ximamng.h + * Purpose: Declaration of the MNG Image Class + * Author: Davide Pizzolato - www.xdp.it + * Created: 2001 + */ +/* ========================================================== + * CxImageMNG (c) 07/Aug/2001 Davide Pizzolato - www.xdp.it + * For conditions of distribution and use, see copyright notice in ximage.h + * + * Special thanks to Frank Haug for suggestions and code. + * + * original mng.cpp code created by Nikolaus Brennig, November 14th, 2000. + * + * LIBMNG Copyright (c) 2000,2001 Gerard Juyn (gerard@libmng.com) + * ========================================================== + */ + +#if !defined(__ximaMNG_h) +#define __ximaMNG_h + +#include "ximage.h" + +#if CXIMAGE_SUPPORT_MNG + +//#define MNG_NO_CMS +#define MNG_SUPPORT_DISPLAY +#define MNG_SUPPORT_READ +#define MNG_SUPPORT_WRITE +#define MNG_ACCESS_CHUNKS +#define MNG_STORE_CHUNKS + +extern "C" { +#include "../mng/libmng.h" +#include "../mng/libmng_data.h" +#include "../mng/libmng_error.h" +} + +//uint32_t _stdcall RunMNGThread(void *lpParam); + +typedef struct tagmngstuff +{ + CxFile *file; + uint8_t *image; + uint8_t *alpha; + HANDLE thread; + mng_uint32 delay; + mng_uint32 width; + mng_uint32 height; + mng_uint32 effwdt; + mng_int16 bpp; + mng_bool animation; + mng_bool animation_enabled; + float speed; + int32_t nBkgndIndex; + RGBQUAD nBkgndColor; +} mngstuff; + +class CxImageMNG: public CxImage +{ +public: + CxImageMNG(); + ~CxImageMNG(); + + bool Load(const TCHAR * imageFileName); + + bool Decode(CxFile * hFile); + bool Decode(FILE *hFile) { CxIOFile file(hFile); return Decode(&file); } + +#if CXIMAGE_SUPPORT_ENCODE + bool Encode(CxFile * hFile); + bool Encode(FILE *hFile) { CxIOFile file(hFile); return Encode(&file); } + bool Save(const TCHAR * imageFileName){ return CxImage::Save(imageFileName,CXIMAGE_FORMAT_MNG);} +#endif // CXIMAGE_SUPPORT_ENCODE + + int32_t Resume(); + void SetSpeed(float speed); + + mng_handle hmng; + mngstuff mnginfo; +protected: + void WritePNG(mng_handle hMNG, int32_t Frame, int32_t FrameCount ); + void SetCallbacks(mng_handle mng); +}; + +#endif + +#endif diff --git a/cximage/ximapcx.h b/cximage/ximapcx.h new file mode 100644 index 0000000..0463d2f --- /dev/null +++ b/cximage/ximapcx.h @@ -0,0 +1,64 @@ +/* + * File: ximapcx.h + * Purpose: PCX Image Class Loader and Writer + */ +/* ========================================================== + * CxImagePCX (c) 05/Jan/2002 Davide Pizzolato - www.xdp.it + * For conditions of distribution and use, see copyright notice in ximage.h + * + * Parts of the code come from Paintlib: Copyright (c) 1996-1998 Ulrich von Zadow + * ========================================================== + */ +#if !defined(__ximaPCX_h) +#define __ximaPCX_h + +#include "ximage.h" + +#if CXIMAGE_SUPPORT_PCX + +class CxImagePCX: public CxImage +{ +// PCX Image File +#pragma pack(1) +typedef struct tagPCXHEADER +{ + char Manufacturer; // always 0X0A + char Version; // version number + char Encoding; // always 1 + char BitsPerPixel; // color bits + uint16_t Xmin, Ymin; // image origin + uint16_t Xmax, Ymax; // image dimensions + uint16_t Hres, Vres; // resolution values + uint8_t ColorMap[16][3]; // color palette + char Reserved; + char ColorPlanes; // color planes + uint16_t BytesPerLine; // line buffer size + uint16_t PaletteType; // grey or color palette + char Filter[58]; +} PCXHEADER; +#pragma pack() + +public: + CxImagePCX(): CxImage(CXIMAGE_FORMAT_PCX) {} + +// bool Load(const TCHAR * imageFileName){ return CxImage::Load(imageFileName,CXIMAGE_FORMAT_PCX);} +// bool Save(const TCHAR * imageFileName){ return CxImage::Save(imageFileName,CXIMAGE_FORMAT_PCX);} + bool Decode(CxFile * hFile); + bool Decode(FILE *hFile) { CxIOFile file(hFile); return Decode(&file); } + +#if CXIMAGE_SUPPORT_ENCODE + bool Encode(CxFile * hFile); + bool Encode(FILE *hFile) { CxIOFile file(hFile); return Encode(&file); } +#endif // CXIMAGE_SUPPORT_ENCODE +protected: + bool PCX_PlanesToPixels(uint8_t * pixels, uint8_t * bitplanes, int16_t bytesperline, int16_t planes, int16_t bitsperpixel); + bool PCX_UnpackPixels(uint8_t * pixels, uint8_t * bitplanes, int16_t bytesperline, int16_t planes, int16_t bitsperpixel); + void PCX_PackPixels(const int32_t p,uint8_t &c, uint8_t &n, CxFile &f); + void PCX_PackPlanes(uint8_t* buff, const int32_t size, CxFile &f); + void PCX_PixelsToPlanes(uint8_t* raw, int32_t width, uint8_t* buf, int32_t plane); + void PCX_toh(PCXHEADER* p); +}; + +#endif + +#endif diff --git a/cximage/ximapng.h b/cximage/ximapng.h new file mode 100644 index 0000000..369265a --- /dev/null +++ b/cximage/ximapng.h @@ -0,0 +1,94 @@ +/* + * File: ximapng.h + * Purpose: PNG Image Class Loader and Writer + */ +/* ========================================================== + * CxImagePNG (c) 07/Aug/2001 Davide Pizzolato - www.xdp.it + * For conditions of distribution and use, see copyright notice in ximage.h + * + * Special thanks to Troels Knakkergaard for new features, enhancements and bugfixes + * + * original CImagePNG and CImageIterator implementation are: + * Copyright: (c) 1995, Alejandro Aguilar Sierra + * + * libpng Copyright (c) 1998-2003 Glenn Randers-Pehrson + * ========================================================== + */ +#if !defined(__ximaPNG_h) +#define __ximaPNG_h + +#include "ximage.h" + +#if CXIMAGE_SUPPORT_PNG + +extern "C" { +#ifdef _LINUX + #undef _DLL + #include + #include + #include +#else + #include "../png/png.h" + #include "../png/pngstruct.h" + #include "../png/pnginfo.h" +#endif +} + +class CxImagePNG: public CxImage +{ +public: + CxImagePNG(): CxImage(CXIMAGE_FORMAT_PNG) {} + +// bool Load(const TCHAR * imageFileName){ return CxImage::Load(imageFileName,CXIMAGE_FORMAT_PNG);} +// bool Save(const TCHAR * imageFileName){ return CxImage::Save(imageFileName,CXIMAGE_FORMAT_PNG);} + bool Decode(CxFile * hFile); + bool Decode(FILE *hFile) { CxIOFile file(hFile); return Decode(&file); } + +#if CXIMAGE_SUPPORT_ENCODE + bool Encode(CxFile * hFile); + bool Encode(FILE *hFile) { CxIOFile file(hFile); return Encode(&file); } +#endif // CXIMAGE_SUPPORT_ENCODE + + enum CODEC_OPTION + { + ENCODE_INTERLACE = 0x01, + // Exclusive compression types : 3 bit wide field + ENCODE_COMPRESSION_MASK = 0x0E, + ENCODE_NO_COMPRESSION = 1 << 1, + ENCODE_BEST_SPEED = 2 << 1, + ENCODE_BEST_COMPRESSION = 3 << 1, + ENCODE_DEFAULT_COMPRESSION = 4 << 1 + }; + +protected: + void ima_png_error(png_struct *png_ptr, char *message); + void expand2to4bpp(uint8_t* prow); + + static void PNGAPI user_read_data(png_structp png_ptr, png_bytep data, png_size_t length) + { + CxFile* hFile = (CxFile*)png_get_io_ptr(png_ptr); + if (hFile == NULL || hFile->Read(data,1,length) != length) png_error(png_ptr, "Read Error"); + } + + static void PNGAPI user_write_data(png_structp png_ptr, png_bytep data, png_size_t length) + { + CxFile* hFile = (CxFile*)png_get_io_ptr(png_ptr); + if (hFile == NULL || hFile->Write(data,1,length) != length) png_error(png_ptr, "Write Error"); + } + + static void PNGAPI user_flush_data(png_structp png_ptr) + { + CxFile* hFile = (CxFile*)png_get_io_ptr(png_ptr); + if (hFile == NULL || !hFile->Flush()) png_error(png_ptr, "Flush Error"); + } + + static void PNGAPI user_error_fn(png_structp png_ptr,png_const_charp error_msg) + { + strncpy((char*)png_ptr->error_ptr,error_msg,255); + longjmp(png_ptr->png_jmpbuf, 1); + } +}; + +#endif + +#endif diff --git a/cximage/ximapsd.h b/cximage/ximapsd.h new file mode 100644 index 0000000..7fc88e2 --- /dev/null +++ b/cximage/ximapsd.h @@ -0,0 +1,110 @@ +/* + * File: ximapsd.h + * Purpose: PSD Image Class Loader and Writer + */ +/* ========================================================== + * CxImagePSD (c) Dec/2010 + * For conditions of distribution and use, see copyright notice in ximage.h + * + * libpsd (c) 2004-2007 Graphest Software + * + * ========================================================== + */ +#if !defined(__ximaPSD_h) +#define __ximaPSD_h + +#include "ximage.h" + +#if CXIMAGE_SUPPORT_PSD + +#define CXIMAGE_USE_LIBPSD 1 + +#if CXIMAGE_USE_LIBPSD + extern "C" { + #include "../libpsd/libpsd.h" + } +#endif + +class CxImagePSD: public CxImage +{ + +public: + CxImagePSD(): CxImage(CXIMAGE_FORMAT_PSD) {} + +// bool Load(const char * imageFileName){ return CxImage::Load(imageFileName,CXIMAGE_FORMAT_PSD);} +// bool Save(const char * imageFileName){ return CxImage::Save(imageFileName,CXIMAGE_FORMAT_PSD);} + bool Decode(CxFile * hFile); + bool Decode(FILE *hFile) { CxIOFile file(hFile); return Decode(&file); } + +//#if CXIMAGE_SUPPORT_EXIF +// bool GetExifThumbnail(const TCHAR *filename, const TCHAR *outname, int32_t type); +//#endif //CXIMAGE_SUPPORT_EXIF + +#if CXIMAGE_SUPPORT_ENCODE + bool Encode(CxFile * hFile); + bool Encode(FILE *hFile) { CxIOFile file(hFile); return Encode(&file); } +#endif // CXIMAGE_SUPPORT_ENCODE + +#if CXIMAGE_USE_LIBPSD +protected: + class CxFilePsd + { + public: + CxFilePsd(CxFile* pFile,psd_context *context) + { + context->file = pFile; + + psd_CxFile_ops.size_ = psd_file_size; + psd_CxFile_ops.seek_ = psd_file_seek; + psd_CxFile_ops.read_ = psd_file_read; +// psd_CxFile_ops.write_ = psd_file_write; +// psd_CxFile_ops.close_ = psd_file_close; +// psd_CxFile_ops.gets_ = psd_file_gets; +// psd_CxFile_ops.eof_ = psd_file_eof; +// psd_CxFile_ops.tell_ = psd_file_tell; +// psd_CxFile_ops.getc_ = psd_file_getc; +// psd_CxFile_ops.scanf_ = psd_file_scanf; + + context->ops_ = &psd_CxFile_ops; + + } + + static int32_t psd_file_size(psd_file_obj *obj) + { return ((CxFile*)obj)->Size(); } + + static int32_t psd_file_seek(psd_file_obj *obj, int32_t offset, int32_t origin) + { return ((CxFile*)obj)->Seek(offset,origin); } + + static int32_t psd_file_read(psd_file_obj *obj, void *buf, int32_t size, int32_t cnt) + { return ((CxFile*)obj)->Read(buf,size,cnt); } + +// static int32_t psd_file_write(psd_file_obj *obj, void *buf, int32_t size, int32_t cnt) +// { return ((CxFile*)obj)->Write(buf,size,cnt); } + +// static int32_t psd_file_close(psd_file_obj *obj) +// { return 1; /*((CxFile*)obj)->Close();*/ } + +// static char* psd_file_gets(psd_file_obj *obj, char *string, int32_t n) +// { return ((CxFile*)obj)->GetS(string,n); } + +// static int32_t psd_file_eof(psd_file_obj *obj) +// { return ((CxFile*)obj)->Eof(); } + +// static long psd_file_tell(psd_file_obj *obj) +// { return ((CxFile*)obj)->Tell(); } + +// static int32_t psd_file_getc(psd_file_obj *obj) +// { return ((CxFile*)obj)->GetC(); } + +// static int32_t psd_file_scanf(psd_file_obj *obj,const char *format, void* output) +// { return ((CxFile*)obj)->Scanf(format, output); } + + private: + psd_file_ops psd_CxFile_ops; + }; +#endif //CXIMAGE_USE_LIBPSD +}; + +#endif + +#endif diff --git a/cximage/ximaraw.h b/cximage/ximaraw.h new file mode 100644 index 0000000..465f31d --- /dev/null +++ b/cximage/ximaraw.h @@ -0,0 +1,112 @@ +/* + * File: ximaraw.h + * Purpose: RAW Image Class Loader and Writer + */ +/* ========================================================== + * CxImageRAW (c) May/2006 pdw63 + * For conditions of distribution and use, see copyright notice in ximage.h + * Special thanks to David Coffin for dcraw without which this class would not exist + * + * libdcr (c) Dec/2007 Davide Pizzolato - www.xdp.it + * + * based on dcraw.c -- Dave Coffin's raw photo decoder + * Copyright 1997-2007 by Dave Coffin, dcoffin a cybercom o net + * ========================================================== + */ +#if !defined(__ximaRAW_h) +#define __ximaRAW_h + +#include "ximage.h" + +#if CXIMAGE_SUPPORT_RAW + +extern "C" { + #include "../raw/libdcr.h" +} + +class CxImageRAW: public CxImage +{ + +public: + CxImageRAW(): CxImage(CXIMAGE_FORMAT_RAW) {} + +// bool Load(const char * imageFileName){ return CxImage::Load(imageFileName,CXIMAGE_FORMAT_ICO);} +// bool Save(const char * imageFileName){ return CxImage::Save(imageFileName,CXIMAGE_FORMAT_ICO);} + bool Decode(CxFile * hFile); + bool Decode(FILE *hFile) { CxIOFile file(hFile); return Decode(&file); } + +#if CXIMAGE_SUPPORT_EXIF + bool GetExifThumbnail(const TCHAR *filename, const TCHAR *outname, int32_t type); +#endif //CXIMAGE_SUPPORT_EXIF + +#if CXIMAGE_SUPPORT_ENCODE + bool Encode(CxFile * hFile); + bool Encode(FILE *hFile) { CxIOFile file(hFile); return Encode(&file); } +#endif // CXIMAGE_SUPPORT_ENCODE + + enum CODEC_OPTION + { + DECODE_QUALITY_LIN = 0x00, + DECODE_QUALITY_VNG = 0x01, + DECODE_QUALITY_PPG = 0x02, + DECODE_QUALITY_AHD = 0x03, + }; + +protected: + + class CxFileRaw + { + public: + CxFileRaw(CxFile* pFile,DCRAW *stream) + { + stream->obj_ = pFile; + + ras_stream_CxFile.read_ = raw_sfile_read; + ras_stream_CxFile.write_ = raw_sfile_write; + ras_stream_CxFile.seek_ = raw_sfile_seek; + ras_stream_CxFile.close_ = raw_sfile_close; + ras_stream_CxFile.gets_ = raw_sfile_gets; + ras_stream_CxFile.eof_ = raw_sfile_eof; + ras_stream_CxFile.tell_ = raw_sfile_tell; + ras_stream_CxFile.getc_ = raw_sfile_getc; + ras_stream_CxFile.scanf_ = raw_sfile_scanf; + + stream->ops_ = &ras_stream_CxFile; + + } + + static int32_t raw_sfile_read(dcr_stream_obj *obj, void *buf, int32_t size, int32_t cnt) + { return ((CxFile*)obj)->Read(buf,size,cnt); } + + static int32_t raw_sfile_write(dcr_stream_obj *obj, void *buf, int32_t size, int32_t cnt) + { return ((CxFile*)obj)->Write(buf,size,cnt); } + + static long raw_sfile_seek(dcr_stream_obj *obj, long offset, int32_t origin) + { return ((CxFile*)obj)->Seek(offset,origin); } + + static int32_t raw_sfile_close(dcr_stream_obj *obj) + { return 1; /*((CxFile*)obj)->Close();*/ } + + static char* raw_sfile_gets(dcr_stream_obj *obj, char *string, int32_t n) + { return ((CxFile*)obj)->GetS(string,n); } + + static int32_t raw_sfile_eof(dcr_stream_obj *obj) + { return ((CxFile*)obj)->Eof(); } + + static long raw_sfile_tell(dcr_stream_obj *obj) + { return ((CxFile*)obj)->Tell(); } + + static int32_t raw_sfile_getc(dcr_stream_obj *obj) + { return ((CxFile*)obj)->GetC(); } + + static int32_t raw_sfile_scanf(dcr_stream_obj *obj,const char *format, void* output) + { return ((CxFile*)obj)->Scanf(format, output); } + + private: + dcr_stream_ops ras_stream_CxFile; + }; +}; + +#endif + +#endif diff --git a/cximage/ximaska.h b/cximage/ximaska.h new file mode 100644 index 0000000..c43d0de --- /dev/null +++ b/cximage/ximaska.h @@ -0,0 +1,44 @@ +/* + * File: ximaska.h + * Purpose: SKA Image Class Loader and Writer + */ +/* ========================================================== + * CxImageSKA (c) 25/Sep/2007 Davide Pizzolato - www.xdp.it + * For conditions of distribution and use, see copyright notice in ximage.h + * ========================================================== + */ +#if !defined(__ximaSKA_h) +#define __ximaSKA_h + +#include "ximage.h" + +#if CXIMAGE_SUPPORT_SKA + +class CxImageSKA: public CxImage +{ +#pragma pack(1) + typedef struct tagSkaHeader { + uint16_t Width; + uint16_t Height; + uint8_t BppExp; + uint32_t dwUnknown; +} SKAHEADER; +#pragma pack() + +public: + CxImageSKA(): CxImage(CXIMAGE_FORMAT_SKA) {} + +// bool Load(const char * imageFileName){ return CxImage::Load(imageFileName,CXIMAGE_FORMAT_ICO);} +// bool Save(const char * imageFileName){ return CxImage::Save(imageFileName,CXIMAGE_FORMAT_ICO);} + bool Decode(CxFile * hFile); + bool Decode(FILE *hFile) { CxIOFile file(hFile); return Decode(&file); } + +#if CXIMAGE_SUPPORT_ENCODE + bool Encode(CxFile * hFile); + bool Encode(FILE *hFile) { CxIOFile file(hFile); return Encode(&file); } +#endif // CXIMAGE_SUPPORT_ENCODE +}; + +#endif + +#endif diff --git a/cximage/ximatga.h b/cximage/ximatga.h new file mode 100644 index 0000000..ff9d169 --- /dev/null +++ b/cximage/ximatga.h @@ -0,0 +1,61 @@ +/* + * File: ximatga.h + * Purpose: TARGA Image Class Loader and Writer + */ +/* ========================================================== + * CxImageTGA (c) 05/Jan/2002 Davide Pizzolato - www.xdp.it + * For conditions of distribution and use, see copyright notice in ximage.h + * + * Parts of the code come from Paintlib : Copyright (c) 1996-1998 Ulrich von Zadow + * ========================================================== + */ +#if !defined(__ximaTGA_h) +#define __ximaTGA_h + +#include "ximage.h" + +#if CXIMAGE_SUPPORT_TGA + +class CxImageTGA: public CxImage +{ +#pragma pack(1) +typedef struct tagTgaHeader +{ + uint8_t IdLength; // Image ID Field Length + uint8_t CmapType; // Color Map Type + uint8_t ImageType; // Image Type + + uint16_t CmapIndex; // First Entry Index + uint16_t CmapLength; // Color Map Length + uint8_t CmapEntrySize; // Color Map Entry Size + + uint16_t X_Origin; // X-origin of Image + uint16_t Y_Origin; // Y-origin of Image + uint16_t ImageWidth; // Image Width + uint16_t ImageHeight; // Image Height + uint8_t PixelDepth; // Pixel Depth + uint8_t ImagDesc; // Image Descriptor +} TGAHEADER; +#pragma pack() + +public: + CxImageTGA(): CxImage(CXIMAGE_FORMAT_TGA) {} + +// bool Load(const TCHAR * imageFileName){ return CxImage::Load(imageFileName,CXIMAGE_FORMAT_TGA);} +// bool Save(const TCHAR * imageFileName){ return CxImage::Save(imageFileName,CXIMAGE_FORMAT_TGA);} + bool Decode(CxFile * hFile); + bool Decode(FILE *hFile) { CxIOFile file(hFile); return Decode(&file); } + +#if CXIMAGE_SUPPORT_ENCODE + bool Encode(CxFile * hFile); + bool Encode(FILE *hFile) { CxIOFile file(hFile); return Encode(&file); } +#endif // CXIMAGE_SUPPORT_ENCODE +protected: + uint8_t ExpandCompressedLine(uint8_t* pDest,TGAHEADER* ptgaHead,CxFile *hFile,int32_t width, int32_t y, uint8_t rleLeftover); + void ExpandUncompressedLine(uint8_t* pDest,TGAHEADER* ptgaHead,CxFile *hFile,int32_t width, int32_t y, int32_t xoffset); + void tga_toh(TGAHEADER* p); +}; + +#endif + +#endif diff --git a/cximage/ximath.h b/cximage/ximath.h new file mode 100644 index 0000000..10b9898 --- /dev/null +++ b/cximage/ximath.h @@ -0,0 +1,39 @@ +#if !defined(__ximath_h) +#define __ximath_h + +#include "ximadef.h" + +//***bd*** simple floating point point +class DLL_EXP CxPoint2 +{ +public: + CxPoint2(); + CxPoint2(float const x_, float const y_); + CxPoint2(CxPoint2 const &p); + + float Distance(CxPoint2 const p2); + float Distance(float const x_, float const y_); + + float x,y; +}; + +//and simple rectangle +class DLL_EXP CxRect2 +{ +public: + CxRect2(); + CxRect2(float const x1_, float const y1_, float const x2_, float const y2_); + CxRect2(CxPoint2 const &bl, CxPoint2 const &tr); + CxRect2(CxRect2 const &p); + + float Surface() const; + CxRect2 CrossSection(CxRect2 const &r2) const; + CxPoint2 Center() const; + float Width() const; + float Height() const; + + CxPoint2 botLeft; + CxPoint2 topRight; +}; + +#endif diff --git a/cximage/ximatif.h b/cximage/ximatif.h new file mode 100644 index 0000000..605af09 --- /dev/null +++ b/cximage/ximatif.h @@ -0,0 +1,62 @@ +/* + * File: ximatif.h + * Purpose: TIFF Image Class Loader and Writer + */ +/* ========================================================== + * CxImageTIF (c) 07/Aug/2001 Davide Pizzolato - www.xdp.it + * For conditions of distribution and use, see copyright notice in ximage.h + * + * Special thanks to Troels Knakkergaard for new features, enhancements and bugfixes + * + * Special thanks to Abe for MultiPageTIFF code. + * + * LibTIFF is: + * Copyright (c) 1988-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * ========================================================== + */ + +#if !defined(__ximatif_h) +#define __ximatif_h + +#include "ximage.h" + +#if CXIMAGE_SUPPORT_TIF + +#include "../tiff/tiffio.h" + +class DLL_EXP CxImageTIF: public CxImage +{ +public: + CxImageTIF(): CxImage(CXIMAGE_FORMAT_TIF) {m_tif2=NULL; m_multipage=false; m_pages=0;} + ~CxImageTIF(); + + TIFF* TIFFOpenEx(CxFile * hFile); + void TIFFCloseEx(TIFF* tif); + +// bool Load(const TCHAR * imageFileName){ return CxImage::Load(imageFileName,CXIMAGE_FORMAT_TIF);} +// bool Save(const TCHAR * imageFileName){ return CxImage::Save(imageFileName,CXIMAGE_FORMAT_TIF);} + bool Decode(CxFile * hFile); + bool Decode(FILE *hFile) { CxIOFile file(hFile); return Decode(&file); } + +#if CXIMAGE_SUPPORT_ENCODE + bool Encode(CxFile * hFile, bool bAppend=false); + bool Encode(CxFile * hFile, CxImage ** pImages, int32_t pagecount); + bool Encode(FILE *hFile, bool bAppend=false) { CxIOFile file(hFile); return Encode(&file,bAppend); } + bool Encode(FILE *hFile, CxImage ** pImages, int32_t pagecount) + { CxIOFile file(hFile); return Encode(&file, pImages, pagecount); } +#endif // CXIMAGE_SUPPORT_ENCODE + +protected: + void TileToStrip(uint8* out, uint8* in, uint32 rows, uint32 cols, int32_t outskew, int32_t inskew); + bool EncodeBody(TIFF *m_tif, bool multipage=false, int32_t page=0, int32_t pagecount=0); + TIFF *m_tif2; + bool m_multipage; + int32_t m_pages; + void MoveBits( uint8_t* dest, uint8_t* from, int32_t count, int32_t bpp ); + void MoveBitsPal( uint8_t* dest, uint8_t*from, int32_t count, int32_t bpp, RGBQUAD* pal ); +}; + +#endif + +#endif diff --git a/cximage/ximawbmp.h b/cximage/ximawbmp.h new file mode 100644 index 0000000..1d1e7ed --- /dev/null +++ b/cximage/ximawbmp.h @@ -0,0 +1,49 @@ +/* + * File: ximawbmp.h + * Purpose: WBMP Image Class Loader and Writer + */ +/* ========================================================== + * CxImageWBMP (c) 12/Jul/2002 Davide Pizzolato - www.xdp.it + * For conditions of distribution and use, see copyright notice in ximage.h + * ========================================================== + */ +#if !defined(__ximaWBMP_h) +#define __ximaWBMP_h + +#include "ximage.h" + +#if CXIMAGE_SUPPORT_WBMP + +class CxImageWBMP: public CxImage +{ +#pragma pack(1) +typedef struct tagWbmpHeader +{ + uint32_t Type; // 0 + uint8_t FixHeader; // 0 + uint32_t ImageWidth; // Image Width + uint32_t ImageHeight; // Image Height +} WBMPHEADER; +#pragma pack() +public: + CxImageWBMP(): CxImage(CXIMAGE_FORMAT_WBMP) {} + +// bool Load(const TCHAR * imageFileName){ return CxImage::Load(imageFileName,CXIMAGE_FORMAT_WBMP);} +// bool Save(const TCHAR * imageFileName){ return CxImage::Save(imageFileName,CXIMAGE_FORMAT_WBMP);} + bool Decode(CxFile * hFile); + bool Decode(FILE *hFile) { CxIOFile file(hFile); return Decode(&file); } +protected: + bool ReadOctet(CxFile * hFile, uint32_t *data); + +public: +#if CXIMAGE_SUPPORT_ENCODE + bool Encode(CxFile * hFile); + bool Encode(FILE *hFile) { CxIOFile file(hFile); return Encode(&file); } +protected: + bool WriteOctet(CxFile * hFile, const uint32_t data); +#endif // CXIMAGE_SUPPORT_ENCODE +}; + +#endif + +#endif diff --git a/cximage/ximawmf.h b/cximage/ximawmf.h new file mode 100644 index 0000000..a649a67 --- /dev/null +++ b/cximage/ximawmf.h @@ -0,0 +1,154 @@ +/* +********************************************************************* + * File: ximawmf.h + * Purpose: Windows Metafile Class Loader and Writer + * Author: Volker Horch - vhorch@gmx.de + * created: 13-Jun-2002 +********************************************************************* + */ + +/* +********************************************************************* + Notes by Author: +********************************************************************* + + Limitations: + ============ + + a) Transparency: + + A Metafile is vector graphics, which has transparency by design. + This class always converts into a Bitmap format. Transparency is + supported, but there is no good way to find out, which parts + of the Metafile are transparent. There are two ways how we can + handle this: + + - Clear the Background of the Bitmap with the background color + you like (i have used COLOR_WINDOW) and don't support transparency. + + below #define XMF_SUPPORT_TRANSPARENCY 0 + #define XMF_COLOR_BACK RGB(Background color you like) + + - Clear the Background of the Bitmap with a very unusual color + (which one ?) and use this color as the transparent color + + below #define XMF_SUPPORT_TRANSPARENCY 1 + #define XMF_COLOR_TRANSPARENT_R ... + #define XMF_COLOR_TRANSPARENT_G ... + #define XMF_COLOR_TRANSPARENT_B ... + + b) Resolution + + Once we have converted the Metafile into a Bitmap and we zoom in + or out, the image may not look very good. If we still had the + original Metafile, zooming would produce good results always. + + c) Size + + Although the filesize of a Metafile may be very small, it might + produce a Bitmap with a bombastic size. Assume you have a Metafile + with an image size of 6000*4000, which contains just one Metafile + record ((e.g. a line from (0,0) to (6000, 4000)). The filesize + of this Metafile would be let's say 100kB. If we convert it to + a 6000*4000 Bitmap with 24 Bits/Pixes, the Bitmap would consume + about 68MB of memory. + + I have choosen, to limit the size of the Bitmap to max. + screensize, to avoid memory problems. + + If you want something else, + modify #define XMF_MAXSIZE_CX / XMF_MAXSIZE_CY below + +********************************************************************* +*/ + +#ifndef _XIMAWMF_H +#define _XIMAWMF_H + +#include "ximage.h" + +#if CXIMAGE_SUPPORT_WMF && CXIMAGE_SUPPORT_WINDOWS + +class CxImageWMF: public CxImage +{ + +#pragma pack(1) + +typedef struct tagRECT16 +{ + int16_t left; + int16_t top; + int16_t right; + int16_t bottom; +} RECT16; + +// taken from Windos 3.11 SDK Documentation (Programmer's Reference Volume 4: Resources) +typedef struct tagMETAFILEHEADER +{ + uint32_t key; // always 0x9ac6cdd7 + uint16_t reserved1; // reserved = 0 + RECT16 bbox; // bounding rectangle in metafile units as defined in "inch" + uint16_t inch; // number of metafile units per inch (should be < 1440) + uint32_t reserved2; // reserved = 0 + uint16_t checksum; // sum of the first 10 WORDS (using XOR operator) +} METAFILEHEADER; + +#pragma pack() + +public: + CxImageWMF(): CxImage(CXIMAGE_FORMAT_WMF) { } + + bool Decode(CxFile * hFile, int32_t nForceWidth=0, int32_t nForceHeight=0); + bool Decode(FILE *hFile, int32_t nForceWidth=0, int32_t nForceHeight=0) + { CxIOFile file(hFile); return Decode(&file,nForceWidth,nForceHeight); } + +#if CXIMAGE_SUPPORT_ENCODE + bool Encode(CxFile * hFile); + bool Encode(FILE *hFile) { CxIOFile file(hFile); return Encode(&file); } +#endif // CXIMAGE_SUPPORT_ENCODE + +protected: + void ShrinkMetafile(int32_t &cx, int32_t &cy); + BOOL CheckMetafileHeader(METAFILEHEADER *pmetafileheader); + HENHMETAFILE ConvertWmfFiletoEmf(CxFile *pFile, METAFILEHEADER *pmetafileheader); + HENHMETAFILE ConvertEmfFiletoEmf(CxFile *pFile, ENHMETAHEADER *pemfh); + +}; + +#define METAFILEKEY 0x9ac6cdd7L + +// Background color definition (if no transparency). see Notes above +#define XMF_COLOR_BACK GetSysColor(COLOR_WINDOW) +// alternatives +//#define XMF_COLOR_BACK RGB(192, 192, 192) // lite gray +//#define XMF_COLOR_BACK RGB( 0, 0, 0) // black +//#define XMF_COLOR_BACK RGB(255, 255, 255) // white + + +// transparency support. see Notes above +#define XMF_SUPPORT_TRANSPARENCY 0 +#define XMF_COLOR_TRANSPARENT_R 211 +#define XMF_COLOR_TRANSPARENT_G 121 +#define XMF_COLOR_TRANSPARENT_B 112 +// don't change +#define XMF_COLOR_TRANSPARENT RGB (XMF_COLOR_TRANSPARENT_R, \ + XMF_COLOR_TRANSPARENT_G, \ + XMF_COLOR_TRANSPARENT_B) +// don't change +#define XMF_RGBQUAD_TRANSPARENT XMF_COLOR_TRANSPARENT_B, \ + XMF_COLOR_TRANSPARENT_G, \ + XMF_COLOR_TRANSPARENT_R, \ + 0 +// max. size. see Notes above +// alternatives +//#define XMF_MAXSIZE_CX (GetSystemMetrics(SM_CXSCREEN)-10) +//#define XMF_MAXSIZE_CY (GetSystemMetrics(SM_CYSCREEN)-50) +//#define XMF_MAXSIZE_CX (2*GetSystemMetrics(SM_CXSCREEN)/3) +//#define XMF_MAXSIZE_CY (2*GetSystemMetrics(SM_CYSCREEN)/3) +#define XMF_MAXSIZE_CX 4000 +#define XMF_MAXSIZE_CY 4000 + + +#endif + +#endif diff --git a/cximage/xiofile.h b/cximage/xiofile.h new file mode 100644 index 0000000..faceeb2 --- /dev/null +++ b/cximage/xiofile.h @@ -0,0 +1,125 @@ +#if !defined(__xiofile_h) +#define __xiofile_h + +#include "xfile.h" +//#include + +class DLL_EXP CxIOFile : public CxFile + { +public: + CxIOFile(FILE* fp = NULL) + { + m_fp = fp; + m_bCloseFile = (bool)(fp==0); + } + + ~CxIOFile() + { + Close(); + } +////////////////////////////////////////////////////////// + bool Open(const TCHAR * filename, const TCHAR * mode) + { + if (m_fp) return false; // Can't re-open without closing first + + m_fp = _tfopen(filename, mode); + if (!m_fp) return false; + + m_bCloseFile = true; + + return true; + } +////////////////////////////////////////////////////////// + virtual bool Close() + { + int32_t iErr = 0; + if ( (m_fp) && (m_bCloseFile) ){ + iErr = fclose(m_fp); + m_fp = NULL; + } + return (bool)(iErr==0); + } +////////////////////////////////////////////////////////// + virtual size_t Read(void *buffer, size_t size, size_t count) + { + if (!m_fp) return 0; + return fread(buffer, size, count, m_fp); + } +////////////////////////////////////////////////////////// + virtual size_t Write(const void *buffer, size_t size, size_t count) + { + if (!m_fp) return 0; + return fwrite(buffer, size, count, m_fp); + } +////////////////////////////////////////////////////////// + virtual bool Seek(int32_t offset, int32_t origin) + { + if (!m_fp) return false; + return (bool)(fseek(m_fp, offset, origin) == 0); + } +////////////////////////////////////////////////////////// + virtual int32_t Tell() + { + if (!m_fp) return 0; + return ftell(m_fp); + } +////////////////////////////////////////////////////////// + virtual int32_t Size() + { + if (!m_fp) return -1; + int32_t pos,size; + pos = ftell(m_fp); + fseek(m_fp, 0, SEEK_END); + size = ftell(m_fp); + fseek(m_fp, pos,SEEK_SET); + return size; + } +////////////////////////////////////////////////////////// + virtual bool Flush() + { + if (!m_fp) return false; + return (bool)(fflush(m_fp) == 0); + } +////////////////////////////////////////////////////////// + virtual bool Eof() + { + if (!m_fp) return true; + return (bool)(feof(m_fp) != 0); + } +////////////////////////////////////////////////////////// + virtual int32_t Error() + { + if (!m_fp) return -1; + return ferror(m_fp); + } +////////////////////////////////////////////////////////// + virtual bool PutC(uint8_t c) + { + if (!m_fp) return false; + return (bool)(fputc(c, m_fp) == c); + } +////////////////////////////////////////////////////////// + virtual int32_t GetC() + { + if (!m_fp) return EOF; + return getc(m_fp); + } +////////////////////////////////////////////////////////// + virtual char * GetS(char *string, int32_t n) + { + if (!m_fp) return NULL; + return fgets(string,n,m_fp); + } +////////////////////////////////////////////////////////// + virtual int32_t Scanf(const char *format, void* output) + { + if (!m_fp) return EOF; + return fscanf(m_fp, format, output); + } +////////////////////////////////////////////////////////// +protected: + FILE *m_fp; + bool m_bCloseFile; + }; + +#endif diff --git a/cximage/xmemfile.h b/cximage/xmemfile.h new file mode 100644 index 0000000..4c4e843 --- /dev/null +++ b/cximage/xmemfile.h @@ -0,0 +1,42 @@ +#if !defined(__xmemfile_h) +#define __xmemfile_h + +#include "xfile.h" + +////////////////////////////////////////////////////////// +class DLL_EXP CxMemFile : public CxFile +{ +public: + CxMemFile(uint8_t* pBuffer = NULL, uint32_t size = 0); + ~CxMemFile(); + + bool Open(); + uint8_t* GetBuffer(bool bDetachBuffer = true); + + virtual bool Close(); + virtual size_t Read(void *buffer, size_t size, size_t count); + virtual size_t Write(const void *buffer, size_t size, size_t count); + virtual bool Seek(int32_t offset, int32_t origin); + virtual int32_t Tell(); + virtual int32_t Size(); + virtual bool Flush(); + virtual bool Eof(); + virtual int32_t Error(); + virtual bool PutC(uint8_t c); + virtual int32_t GetC(); + virtual char * GetS(char *string, int32_t n); + virtual int32_t Scanf(const char *format, void* output); + +protected: + bool Alloc(uint32_t nBytes); + void Free(); + + uint8_t* m_pBuffer; + uint32_t m_Size; + bool m_bFreeOnClose; + int32_t m_Position; //current position + int32_t m_Edge; //buffer size + bool m_bEOF; +}; + +#endif diff --git a/cximage/zlib.lib b/cximage/zlib.lib new file mode 100644 index 0000000..8f34b03 Binary files /dev/null and b/cximage/zlib.lib differ diff --git a/res/TouchBoard.ico b/res/TouchBoard.ico new file mode 100644 index 0000000..d56fbcd Binary files /dev/null and b/res/TouchBoard.ico differ diff --git a/res/TouchBoard.rc2 b/res/TouchBoard.rc2 new file mode 100644 index 0000000..835080e Binary files /dev/null and b/res/TouchBoard.rc2 differ diff --git a/res/bitmap1.bmp b/res/bitmap1.bmp new file mode 100644 index 0000000..6e8e840 Binary files /dev/null and b/res/bitmap1.bmp differ diff --git a/res/check.png b/res/check.png new file mode 100644 index 0000000..e77444c Binary files /dev/null and b/res/check.png differ diff --git a/res/emergency.png b/res/emergency.png new file mode 100644 index 0000000..486fb69 Binary files /dev/null and b/res/emergency.png differ diff --git a/res/fire.png b/res/fire.png new file mode 100644 index 0000000..d103045 Binary files /dev/null and b/res/fire.png differ diff --git a/res/icon_emergency.png b/res/icon_emergency.png new file mode 100644 index 0000000..6174d29 Binary files /dev/null and b/res/icon_emergency.png differ diff --git a/res/icon_fire.png b/res/icon_fire.png new file mode 100644 index 0000000..a2a9995 Binary files /dev/null and b/res/icon_fire.png differ diff --git a/res/icon_mic.png b/res/icon_mic.png new file mode 100644 index 0000000..db420e9 Binary files /dev/null and b/res/icon_mic.png differ diff --git a/res/icon_rescue.png b/res/icon_rescue.png new file mode 100644 index 0000000..165f449 Binary files /dev/null and b/res/icon_rescue.png differ diff --git a/res/mic.png b/res/mic.png new file mode 100644 index 0000000..80ea6b9 Binary files /dev/null and b/res/mic.png differ diff --git a/res/rescue.png b/res/rescue.png new file mode 100644 index 0000000..3ffee31 Binary files /dev/null and b/res/rescue.png differ diff --git a/res/symbol.png b/res/symbol.png new file mode 100644 index 0000000..627508d Binary files /dev/null and b/res/symbol.png differ diff --git a/resource.h b/resource.h new file mode 100644 index 0000000..451d5d6 Binary files /dev/null and b/resource.h differ diff --git a/stdafx.cpp b/stdafx.cpp new file mode 100644 index 0000000..83b44e5 --- /dev/null +++ b/stdafx.cpp @@ -0,0 +1,11 @@ + +// stdafx.cpp : ǥ ϸ ִ ҽ Դϴ. +// TouchBoard.pch ̸ ϵ ˴ϴ. +// stdafx.obj ̸ ϵ Ե˴ϴ. + +#include "stdafx.h" + +RGBQUAD RGB_QUAD_RED; +RGBQUAD RGB_QUAD_GREEN; +RGBQUAD RGB_QUAD_BLUE; + diff --git a/stdafx.h b/stdafx.h new file mode 100644 index 0000000..c43046a --- /dev/null +++ b/stdafx.h @@ -0,0 +1,75 @@ + +// stdafx.h : ʴ +// ǥ ý Ʈ +// ִ Դϴ. + +#pragma once + +#ifndef VC_EXTRALEAN +#define VC_EXTRALEAN // ʴ Windows մϴ. +#endif + +#include "targetver.h" + +#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // Ϻ CString ڴ ˴ϴ. + +// MFC κа ޽ ⸦ մϴ. +#define _CRT_SECURE_NO_WARNINGS +#define _AFX_ALL_WARNINGS + +#include // MFC ٽ ǥ Դϴ. +#include // MFC ȮԴϴ. + + +#include // MFC ڵȭ ŬԴϴ. + + + +#ifndef _AFX_NO_OLE_SUPPORT +#include // Internet Explorer 4 Ʈѿ MFC Դϴ. +#endif +#ifndef _AFX_NO_AFXCMN_SUPPORT +#include // Windows Ʈѿ MFC Դϴ. +#endif // _AFX_NO_AFXCMN_SUPPORT + +#include // MFC Ʈ + + +#include // MFC Ȯ + + +#include "cximage/ximage.h" +#include "UTF8Conv.h" + +#define RGB2RGBQURD(rgb, quad) { quad.rgbRed = GetRValue(rgb); quad.rgbBlue = GetBValue(rgb); quad.rgbGreen = GetGValue(rgb); } + +#define TBD_SETUP_DLG_WIDTH 1050 + //#define TBD_SETUP_DLG_HEIGHT 680 +#define TBD_SETUP_DLG_HEIGHT 730 + +#define TBD_BUTTON_UI_STYLE 2 +#define TBD_USE_COLOR_BUTTON 1 +#define TBD_USE_THREELINE_GROUP 1 +#define TBD_USE_SOCKET_THREAD 0 + +extern RGBQUAD RGB_QUAD_RED; +extern RGBQUAD RGB_QUAD_GREEN; +extern RGBQUAD RGB_QUAD_BLUE; + +const UINT WM_TBD_SETUP_SAVE = ::RegisterWindowMessage(L"TBD_SETUP_SAVE"); +const UINT WM_TBD_GROUP_PUSH = ::RegisterWindowMessage(L"TBD_GROUP_PUSH"); +const UINT WM_TBD_UPDATE_GROUP = ::RegisterWindowMessage(L"TBD_UPDATE_GROUP"); +const UINT WM_TBD_UPDATE_LOG = ::RegisterWindowMessage(L"TBD_UPDATE_LOG"); +const UINT WM_TBD_SUB_GROUPING = ::RegisterWindowMessage(L"TBD_SUB_GROUPING"); + +#ifdef _UNICODE +#if defined _M_IX86 +#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"") +#elif defined _M_X64 +#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'\"") +#else +#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"") +#endif +#endif + + diff --git a/targetver.h b/targetver.h new file mode 100644 index 0000000..ad5ca61 --- /dev/null +++ b/targetver.h @@ -0,0 +1,8 @@ +#pragma once + +// SDKDDKVer.h Windows ÷ ÷ մϴ. + +// Windows ÷ α׷ Ϸ 쿡 SDKDDKVer.h ϱ +// WinSDKVer.h ϰ _WIN32_WINNT ũθ Ϸ ÷ Ͻʽÿ. + +#include