├── CommPort.h
├── res
├── head.bmp
├── spm.bmp
├── Port2File.ico
├── Port2File.rc2
└── Port2File.manifest
├── stdafx.cpp
├── Port2File.h
├── consts.h
├── Port2File.sln
├── RedirectPort.h
├── stdafx.h
├── Port2File.cpp
├── README.md
├── resource.h
├── Port2FileDlg.h
├── Port2File.vcxproj.filters
├── Label.h
├── Port2File.vcproj
├── RedirectPort.cpp
├── Port2File.vcxproj
├── Port2File.rc
├── Port2FileDlg.cpp
├── LICENSE
├── CommPort.cpp
└── Label.cpp
/CommPort.h:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eltima-software/RS232-Data-Logger/HEAD/CommPort.h
--------------------------------------------------------------------------------
/res/head.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eltima-software/RS232-Data-Logger/HEAD/res/head.bmp
--------------------------------------------------------------------------------
/res/spm.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eltima-software/RS232-Data-Logger/HEAD/res/spm.bmp
--------------------------------------------------------------------------------
/res/Port2File.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eltima-software/RS232-Data-Logger/HEAD/res/Port2File.ico
--------------------------------------------------------------------------------
/stdafx.cpp:
--------------------------------------------------------------------------------
1 | // stdafx.cpp : source file that includes just the standard includes
2 | // Port2File.pch will be the pre-compiled header
3 | // stdafx.obj will contain the pre-compiled type information
4 |
5 | #include "stdafx.h"
6 |
7 |
8 |
--------------------------------------------------------------------------------
/res/Port2File.rc2:
--------------------------------------------------------------------------------
1 | //
2 | // Port2File.RC2 - resources Microsoft Visual C++ does not edit directly
3 | //
4 |
5 | #ifdef APSTUDIO_INVOKED
6 | #error this file is not editable by Microsoft Visual C++
7 | #endif //APSTUDIO_INVOKED
8 |
9 |
10 | /////////////////////////////////////////////////////////////////////////////
11 | // Add manually edited resources here...
12 |
13 | /////////////////////////////////////////////////////////////////////////////
14 |
--------------------------------------------------------------------------------
/Port2File.h:
--------------------------------------------------------------------------------
1 | // Port2File.h : main header file for the PROJECT_NAME application
2 | //
3 |
4 | #pragma once
5 |
6 | #ifndef __AFXWIN_H__
7 | #error include 'stdafx.h' before including this file for PCH
8 | #endif
9 |
10 | #include "resource.h" // main symbols
11 |
12 |
13 | // CMainApp:
14 | // See Port2File.cpp for the implementation of this class
15 | //
16 |
17 | class CMainApp : public CWinApp
18 | {
19 | public:
20 | CMainApp();
21 |
22 | // Overrides
23 | public:
24 | virtual BOOL InitInstance();
25 |
26 | // Implementation
27 |
28 | DECLARE_MESSAGE_MAP()
29 | };
30 |
31 | extern CMainApp theApp;
--------------------------------------------------------------------------------
/res/Port2File.manifest:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 | Your app description here
10 |
11 |
12 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/consts.h:
--------------------------------------------------------------------------------
1 |
2 | #pragma once
3 |
4 | const TCHAR VAL_BAUDRATE [][7] = {
5 | _T("100"),
6 | _T("300"),
7 | _T("600"),
8 | _T("1200"),
9 | _T("2400"),
10 | _T("4800"),
11 | _T("9600"),
12 | _T("14400"),
13 | _T("19200"),
14 | _T("38400"),
15 | _T("56000"),
16 | _T("57600"),
17 | _T("115200"),
18 | _T("128000"),
19 | _T("256000") };
20 | const int NUM_BAUDRATE = 15;
21 |
22 | const TCHAR VAL_DATABITS [][2] = {
23 | _T("5"),
24 | _T("6"),
25 | _T("7"),
26 | _T("8") };
27 | const int NUM_DATABITS = 4;
28 |
29 | const TCHAR VAL_PARITY [][6] = {
30 | _T("None"),
31 | _T("Odd"),
32 | _T("Even"),
33 | _T("Mark"),
34 | _T("Space") };
35 | const int NUM_PARITY = 5;
36 |
37 | const TCHAR VAL_STOPBIT [3][4] = { _T("1"), _T("1,5"), _T("2") };
38 | const int NUM_STOPBIT = 3;
39 |
40 |
41 | const TCHAR VAL_FC [][10] = { _T("None"), _T("Xon\\Xoff"), _T("Hardware") };
42 | const int NUM_FC = 3;
--------------------------------------------------------------------------------
/Port2File.sln:
--------------------------------------------------------------------------------
1 | Microsoft Visual Studio Solution File, Format Version 11.00
2 | # Visual Studio 2010
3 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Port2File", "Port2File.vcxproj", "{5892FB7D-278E-45FE-A820-B2A323A30711}"
4 | EndProject
5 | Global
6 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
7 | Debug|Win32 = Debug|Win32
8 | Release|Win32 = Release|Win32
9 | Template|Win32 = Template|Win32
10 | EndGlobalSection
11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
12 | {5892FB7D-278E-45FE-A820-B2A323A30711}.Debug|Win32.ActiveCfg = Debug|Win32
13 | {5892FB7D-278E-45FE-A820-B2A323A30711}.Debug|Win32.Build.0 = Debug|Win32
14 | {5892FB7D-278E-45FE-A820-B2A323A30711}.Release|Win32.ActiveCfg = Release|Win32
15 | {5892FB7D-278E-45FE-A820-B2A323A30711}.Release|Win32.Build.0 = Release|Win32
16 | {5892FB7D-278E-45FE-A820-B2A323A30711}.Template|Win32.ActiveCfg = Template|Win32
17 | {5892FB7D-278E-45FE-A820-B2A323A30711}.Template|Win32.Build.0 = Template|Win32
18 | EndGlobalSection
19 | GlobalSection(SolutionProperties) = preSolution
20 | HideSolutionNode = FALSE
21 | EndGlobalSection
22 | EndGlobal
23 |
--------------------------------------------------------------------------------
/RedirectPort.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include "commport.h"
3 |
4 |
5 | #define WM_USER_UPDATE_WND WM_USER + 5587
6 | #define WM_USER_CHANGE_STATUS WM_USER + 5588
7 |
8 | const TCHAR PREFERENCES_KEY[] = _T("Software\\Eltima\\Port2File");
9 | // status codes
10 | enum
11 | {
12 | SC_NO_ERROR = 0,
13 | SC_OPEN_SUCCESS = 1,
14 | SC_OPEN_FILE_ERROR = 2,
15 | SC_OPEN_PORT_ERROR = 3,
16 | SC_FILE_EXCEPTION = 10
17 | };
18 |
19 | class CRedirectPort :
20 | public CCommPort
21 | {
22 | private:
23 | CWnd* m_pParentWnd;
24 | CFile m_File;
25 | void OnRxChar( DWORD dwCount );
26 |
27 | size_t m_stBytesInFile;
28 | size_t m_stBytesWritten;
29 | CString m_sPortName;
30 | int m_nIndex;
31 |
32 | public:
33 | bool m_bIsActive;
34 | BOOL m_bLogStarted;
35 | BOOL m_bAppend;
36 | CString m_sLogFile;
37 | CString m_sStatusMessage;
38 |
39 | DWORD m_dwBaudRate;
40 | int m_iIndexDataBits;
41 | int m_iIndexParity;
42 | int m_iIndexStopBits;
43 | int m_iIndexFlowCtrl;
44 | int m_iStatus;
45 |
46 | public:
47 | BOOL Open();
48 | BOOL Open ( DWORD dwBaudrate, BYTE bDataBits, BYTE bParity, BYTE bStopBits, BYTE bFC );
49 | void Close();
50 |
51 | size_t GetFileTotalBytes() const { return m_stBytesInFile; }
52 | size_t GetFileWrittenBytes() const { return m_stBytesWritten; }
53 |
54 | BOOL SaveSettings ();
55 | BOOL LoadSettings ();
56 |
57 | CRedirectPort(const CString& sPortName, bool IsActive, CWnd* pWnd, int nIndex );
58 | virtual ~CRedirectPort(void);
59 | };
60 |
--------------------------------------------------------------------------------
/stdafx.h:
--------------------------------------------------------------------------------
1 | // stdafx.h : include file for standard system include files,
2 | // or project specific include files that are used frequently,
3 | // but are changed infrequently
4 |
5 | #pragma once
6 |
7 | #ifndef VC_EXTRALEAN
8 | #define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers
9 | #endif
10 |
11 | // Modify the following defines if you have to target a platform prior to the ones specified below.
12 | // Refer to MSDN for the latest info on corresponding values for different platforms.
13 | #ifndef WINVER // Allow use of features specific to Windows 95 and Windows NT 4 or later.
14 | #define WINVER 0x0500 // Change this to the appropriate value to target Windows 98 and Windows 2000 or later.
15 | #endif
16 |
17 | #ifndef _WIN32_WINNT // Allow use of features specific to Windows NT 4 or later.
18 | #define _WIN32_WINNT 0x0500 // Change this to the appropriate value to target Windows 98 and Windows 2000 or later.
19 | #endif
20 |
21 | #ifndef _WIN32_IE // Allow use of features specific to IE 4.0 or later.
22 | #define _WIN32_IE 0x0400 // Change this to the appropriate value to target IE 5.0 or later.
23 | #endif
24 |
25 | #define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // some CString constructors will be explicit
26 |
27 | // turns off MFC's hiding of some common and often safely ignored warning messages
28 | #define _AFX_ALL_WARNINGS
29 |
30 | #include // MFC core and standard components
31 | #include // MFC extensions
32 |
33 | #include // MFC support for Internet Explorer 4 Common Controls
34 | #ifndef _AFX_NO_AFXCMN_SUPPORT
35 | #include // MFC support for Windows Common Controls
36 | #endif // _AFX_NO_AFXCMN_SUPPORT
37 |
38 |
--------------------------------------------------------------------------------
/Port2File.cpp:
--------------------------------------------------------------------------------
1 | // Port2File.cpp : Defines the class behaviors for the application.
2 | //
3 |
4 | #include "stdafx.h"
5 | #include "Port2File.h"
6 | #include "Port2FileDlg.h"
7 |
8 | #ifdef _DEBUG
9 | #define new DEBUG_NEW
10 | #endif
11 |
12 |
13 | // CMainApp
14 |
15 | BEGIN_MESSAGE_MAP(CMainApp, CWinApp)
16 | ON_COMMAND(ID_HELP, CWinApp::OnHelp)
17 | END_MESSAGE_MAP()
18 |
19 |
20 | // CMainApp construction
21 |
22 | CMainApp::CMainApp()
23 | {
24 | // TODO: add construction code here,
25 | // Place all significant initialization in InitInstance
26 | }
27 |
28 |
29 | // The one and only CMainApp object
30 |
31 | CMainApp theApp;
32 |
33 |
34 | // CMainApp initialization
35 |
36 | BOOL CMainApp::InitInstance()
37 | {
38 | // InitCommonControls() is required on Windows XP if an application
39 | // manifest specifies use of ComCtl32.dll version 6 or later to enable
40 | // visual styles. Otherwise, any window creation will fail.
41 | InitCommonControls();
42 |
43 | CWinApp::InitInstance();
44 |
45 | // Standard initialization
46 | // If you are not using these features and wish to reduce the size
47 | // of your final executable, you should remove from the following
48 | // the specific initialization routines you do not need
49 | // Change the registry key under which our settings are stored
50 | // TODO: You should modify this string to be something appropriate
51 | // such as the name of your company or organization
52 | SetRegistryKey(_T("Local AppWizard-Generated Applications"));
53 |
54 | CRedirectDlg dlg;
55 | m_pMainWnd = &dlg;
56 | INT_PTR nResponse = dlg.DoModal();
57 | if (nResponse == IDOK)
58 | {
59 | // TODO: Place code here to handle when the dialog is
60 | // dismissed with OK
61 | }
62 | else if (nResponse == IDCANCEL)
63 | {
64 | // TODO: Place code here to handle when the dialog is
65 | // dismissed with Cancel
66 | }
67 |
68 | // Since the dialog has been closed, return FALSE so that we exit the
69 | // application, rather than start the application's message pump.
70 | return FALSE;
71 | }
72 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # RS232 Data Logger
2 |
3 | ## How Serial Port Logger solves it
4 |
5 | RS232 Data Logger is quite easy to use. It is a one-window application where you can choose the COM ports for monitoring, specify the file to save logged info to, and define serial port settings (baud rate, stop bits, number of bits to transmit, parity checking, and flow control types). All collected data is saved in a text file that you can later read and fully analyze all data you need.
6 |
7 | ## Log serial port communication, view and analyze logged data
8 |
9 | With [free serial port monitor](https://www.com-port-monitoring.com/) you can connect to real or virtual serial port and monitor the transmitted data. Specify the text document to save all intercepted data to for your analysis. RS232 Logger will display how many bytes are stored in the log file and all data logged from the serial port in a comprehensive way.
10 |
11 | ## Test serial communication
12 |
13 | RS232 Data Logger is a handy tool for testing serial port communication. As all data is saved into the log file, it can be analyzed later for any errors in commands or data. RS232 Data Logger can capture data streams of up to 256 COM ports.
14 |
15 | ## Supported operating systems
16 |
17 | * Windows 10 (32-bit and 64-bit)
18 | * Windows server 2012
19 | * Windows 8 (32-bit and 64-bit)
20 | * Windows 7 (32-bit and 64-bit)
21 | * Windows 2008 (32-bit and 64-bit)
22 | * Windows 2003 (32-bit and 64-bit)
23 | * Windows Vista (32-bit and 64-bit)
24 | * Windows XP (32-bit and 64-bit)
25 | * Windows 2000
26 | * Windows NT 4.x
27 | * Windows Me
28 | * Windows 98
29 |
30 | Note, that this is an open source software and you can only use it for non proprietary purposes. If you want to distribute it as a part of your own non-Open Source software product, it's required to obtain appropriate license from Eltima Software (sales@eltima.com)
31 |
32 | If you are looking for more powerful tool, Serial Port Logger is an advanced edition of a free serial port monitor with extra features. https://www.eltima.com/products/rs232-data-logger/
33 |
--------------------------------------------------------------------------------
/resource.h:
--------------------------------------------------------------------------------
1 | //{{NO_DEPENDENCIES}}
2 | // Microsoft Visual C++ generated include file.
3 | // Used by Port2File.rc
4 | //
5 | #define IDM_ABOUTBOX 16
6 | #define IDD_ABOUTBOX 100
7 | #define IDS_ABOUTBOX 101
8 | #define IDD_PORT2FILE_DIALOG 102
9 | #define IDR_MAINFRAME 128
10 | #define IDB_BMP_HEAD 132
11 | #define IDB_SPM 134
12 | #define IDC_CB_BAUDRATE 1005
13 | #define IDC_CB_DATABITS 1006
14 | #define IDC_CB_PARITY 1007
15 | #define IDC_CB_STOPBITS 1008
16 | #define IDC_CB_FC 1009
17 | #define IDC_EDIT2 1010
18 | #define IDC_ED_LOGFILE 1010
19 | #define IDC_BT_VIEW 1011
20 | #define IDC_CHECK_APPEND 1015
21 | #define IDC_LIST_PORTS 1018
22 | #define IDC_BT_STARTLOG 1019
23 | #define IDC_STATIC_2 1025
24 | #define IDC_STATIC_3 1026
25 | #define IDC_STATIC_4 1027
26 | #define IDC_STATIC_5 1028
27 | #define IDC_STATIC_6 1029
28 | #define IDC_STATIC_9 1031
29 | #define IDC_STATIC_A 1032
30 | #define IDC_BT_HELP 1033
31 | #define IDC_STATIC_HOME 1034
32 | #define IDC_STATIC_STATUS 1037
33 | #define IDC_STATIC_RECV 1038
34 | #define IDC_STATIC_TOTAL 1039
35 | #define IDC_BT_HIDE 1040
36 | #define IDC_STATIC_CAPTION 1041
37 | #define IDC_STATIC_TEXT 1042
38 | #define IDC_STATIC_HYPERLINK 1043
39 |
40 | // Next default values for new objects
41 | //
42 | #ifdef APSTUDIO_INVOKED
43 | #ifndef APSTUDIO_READONLY_SYMBOLS
44 | #define _APS_NEXT_RESOURCE_VALUE 135
45 | #define _APS_NEXT_COMMAND_VALUE 32771
46 | #define _APS_NEXT_CONTROL_VALUE 1044
47 | #define _APS_NEXT_SYMED_VALUE 102
48 | #endif
49 | #endif
50 |
--------------------------------------------------------------------------------
/Port2FileDlg.h:
--------------------------------------------------------------------------------
1 | // Port2FileDlg.h : header file
2 | //
3 |
4 | #pragma once
5 | #include "afxcmn.h"
6 | #include "afxwin.h"
7 | #include "RedirectPort.h"
8 | #include
9 | #include "label.h"
10 |
11 | // CRedirectDlg dialog
12 | class CRedirectDlg : public CDialog
13 | {
14 | // Construction
15 | public:
16 | CRedirectDlg(CWnd* pParent = NULL); // standard constructor
17 |
18 | // Dialog Data
19 | enum { IDD = IDD_PORT2FILE_DIALOG };
20 |
21 | protected:
22 | virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
23 |
24 | private:
25 | CListCtrl m_ListPorts;
26 | CImageList m_IconList;
27 | CLabel m_HomeHlink;
28 |
29 | CString m_sErrorStatus;
30 | CString m_sLogFile;
31 | CString m_sRecvBytes;
32 | CString m_sTotalFileSize;
33 |
34 | CComboBox m_cbBaudrate;
35 | CComboBox m_cbDataBits;
36 | CComboBox m_cbParity;
37 | CComboBox m_cbStopBits;
38 | CComboBox m_cbFC;
39 |
40 | BOOL m_bFileAppend;
41 | int m_iCurItemSel;
42 |
43 |
44 | std::vector m_Ports;
45 |
46 | void GetAvailablePorts();
47 | void UpdateSettings ();
48 | //void StartLogging ( int iPort );
49 |
50 | LRESULT OnWriteUpdate ( WPARAM, LPARAM );
51 | LRESULT OnWriteStatus ( WPARAM, LPARAM );
52 |
53 | // Implementation
54 | protected:
55 | HICON m_hIcon;
56 |
57 | // Generated message map functions
58 | virtual BOOL OnInitDialog();
59 | afx_msg void OnPaint();
60 | afx_msg HCURSOR OnQueryDragIcon();
61 | DECLARE_MESSAGE_MAP()
62 | public:
63 |
64 | afx_msg void OnBnClickedBtView();
65 | afx_msg void OnBnClickedBtStartlog();
66 | afx_msg void OnBnClickedCheckLog();
67 | afx_msg void OnBnClickedBtHelp();
68 |
69 | protected:
70 | virtual void OnOK();
71 | virtual void OnCancel();
72 |
73 | protected:
74 | virtual BOOL OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult);
75 | void OnCustomdrawList ( NMHDR* pNMHDR, LRESULT* pResult );
76 | public:
77 | afx_msg void OnHdnGetdispinfoListPorts (NMHDR *pNMHDR, LRESULT *pResult);
78 | afx_msg void OnLvnItemActivateListPorts(NMHDR *pNMHDR, LRESULT *pResult);
79 | afx_msg void OnLvnItemchangedListPorts (NMHDR *pNMHDR, LRESULT *pResult);
80 | afx_msg void OnLvnItemchangingListPorts(NMHDR *pNMHDR, LRESULT *pResult);
81 | afx_msg void OnCbnSelchangeCbBaudrate ();
82 | afx_msg void OnCbnSelchangeCbDatabits ();
83 | afx_msg void OnCbnSelchangeCbParity ();
84 | afx_msg void OnCbnSelchangeCbStopbits ();
85 | afx_msg void OnCbnSelchangeCbFc ();
86 | afx_msg void OnBnClickedCheckAppend ();
87 | afx_msg void OnEnChangeEdLogfile ();
88 | };
89 |
--------------------------------------------------------------------------------
/Port2File.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hpp;hxx;hm;inl;inc;xsd
11 |
12 |
13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx
15 |
16 |
17 |
18 |
19 | Source Files
20 |
21 |
22 | Source Files
23 |
24 |
25 | Source Files
26 |
27 |
28 | Source Files
29 |
30 |
31 | Source Files
32 |
33 |
34 | Source Files
35 |
36 |
37 |
38 |
39 | Header Files
40 |
41 |
42 | Header Files
43 |
44 |
45 | Header Files
46 |
47 |
48 | Header Files
49 |
50 |
51 | Header Files
52 |
53 |
54 | Header Files
55 |
56 |
57 | Header Files
58 |
59 |
60 | Header Files
61 |
62 |
63 |
64 |
65 | Resource Files
66 |
67 |
68 | Resource Files
69 |
70 |
71 | Resource Files
72 |
73 |
74 | Resource Files
75 |
76 |
77 |
78 |
79 |
80 | Resource Files
81 |
82 |
83 |
--------------------------------------------------------------------------------
/Label.h:
--------------------------------------------------------------------------------
1 | #if !defined(AFX_LABEL_H__A4EABEC5_2E8C_11D1_B79F_00805F9ECE10__INCLUDED_)
2 | #define AFX_LABEL_H__A4EABEC5_2E8C_11D1_B79F_00805F9ECE10__INCLUDED_
3 |
4 | #if _MSC_VER >= 1000
5 | #pragma once
6 | #endif // _MSC_VER >= 1000
7 | // Label.h : header file
8 | //
9 |
10 | #define NM_LINKCLICK WM_APP + 0x200
11 |
12 | /////////////////////////////////////////////////////////////////////////////
13 | // CLabel window
14 |
15 | class CLabel : public CStatic
16 | {
17 | // Construction
18 | public:
19 |
20 |
21 | static enum LinkStyle { LinkNone, HyperLink, MailLink };
22 | static enum FlashType {None, Text, Background };
23 | static enum Type3D { Raised, Sunken};
24 | static enum BackFillMode { Normal, Gradient };
25 |
26 | CLabel();
27 | virtual CLabel& SetBkColor(COLORREF crBkgnd, COLORREF crBkgndHigh = 0, BackFillMode mode = Normal);
28 | virtual CLabel& SetTextColor(COLORREF crText);
29 | virtual CLabel& SetText(const CString& strText);
30 | virtual CLabel& SetFontBold(BOOL bBold);
31 | virtual CLabel& SetFontName(const CString& strFont, BYTE byCharSet = ANSI_CHARSET);
32 | virtual CLabel& SetFontUnderline(BOOL bSet);
33 | virtual CLabel& SetFontItalic(BOOL bSet);
34 | virtual CLabel& SetFontSize(int nSize);
35 | virtual CLabel& SetSunken(BOOL bSet);
36 | virtual CLabel& SetBorder(BOOL bSet);
37 | virtual CLabel& SetTransparent(BOOL bSet);
38 | virtual CLabel& FlashText(BOOL bActivate);
39 | virtual CLabel& FlashBackground(BOOL bActivate);
40 | virtual CLabel& SetLink(BOOL bLink,BOOL bNotifyParent);
41 | virtual CLabel& SetLinkCursor(HCURSOR hCursor);
42 | virtual CLabel& SetFont3D(BOOL bSet,Type3D type=Raised);
43 | virtual CLabel& SetRotationAngle(UINT nAngle,BOOL bRotation);
44 | virtual CLabel& SetText3DHiliteColor(COLORREF cr3DHiliteColor);
45 | virtual CLabel& SetFont(LOGFONT lf);
46 | virtual CLabel& SetMailLink(BOOL bEnable, BOOL bNotifyParent);
47 | virtual CLabel& SetHyperLink(const CString& sLink);
48 |
49 | // Attributes
50 | public:
51 | protected:
52 | void UpdateSurface();
53 | void ReconstructFont();
54 | void DrawGradientFill(CDC* pDC, CRect* pRect, COLORREF crStart, COLORREF crEnd, int nSegments);
55 | COLORREF m_crText;
56 | COLORREF m_cr3DHiliteColor;
57 | HBRUSH m_hwndBrush;
58 | HBRUSH m_hBackBrush;
59 | LOGFONT m_lf;
60 | CFont m_font;
61 | BOOL m_bState;
62 | BOOL m_bTimer;
63 | LinkStyle m_Link;
64 | BOOL m_bTransparent;
65 | BOOL m_bFont3d;
66 | BOOL m_bToolTips;
67 | BOOL m_bNotifyParent;
68 | BOOL m_bRotation;
69 | FlashType m_Type;
70 | HCURSOR m_hCursor;
71 | Type3D m_3dType;
72 | BackFillMode m_fillmode;
73 | COLORREF m_crHiColor;
74 | COLORREF m_crLoColor;
75 | CString m_sLink;
76 |
77 | // Operations
78 | public:
79 |
80 | // Overrides
81 | // ClassWizard generated virtual function overrides
82 | //{{AFX_VIRTUAL(CLabel)
83 | protected:
84 | virtual void PreSubclassWindow();
85 | virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
86 | //}}AFX_VIRTUAL
87 |
88 | // Implementation
89 | public:
90 | virtual ~CLabel();
91 |
92 | // Generated message map functions
93 | protected:
94 | //{{AFX_MSG(CLabel)
95 | afx_msg void OnTimer(UINT nIDEvent);
96 | afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
97 | afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message);
98 | afx_msg void OnSysColorChange();
99 | afx_msg void OnPaint();
100 | afx_msg BOOL OnEraseBkgnd(CDC* pDC);
101 | //}}AFX_MSG
102 |
103 | DECLARE_MESSAGE_MAP()
104 | };
105 |
106 | /////////////////////////////////////////////////////////////////////////////
107 |
108 | //{{AFX_INSERT_LOCATION}}
109 | // Microsoft Developer Studio will insert additional declarations immediately before the previous line.
110 |
111 | #endif // !defined(AFX_LABEL_H__A4EABEC5_2E8C_11D1_B79F_00805F9ECE10__INCLUDED_)
112 |
--------------------------------------------------------------------------------
/Port2File.vcproj:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
11 |
12 |
13 |
20 |
32 |
34 |
40 |
44 |
46 |
48 |
50 |
55 |
57 |
59 |
61 |
63 |
65 |
66 |
73 |
83 |
85 |
94 |
98 |
100 |
102 |
104 |
109 |
111 |
113 |
115 |
117 |
119 |
120 |
121 |
122 |
123 |
124 |
128 |
130 |
131 |
133 |
134 |
136 |
137 |
139 |
140 |
142 |
143 |
145 |
147 |
150 |
151 |
153 |
156 |
157 |
158 |
159 |
163 |
165 |
166 |
168 |
169 |
171 |
172 |
174 |
175 |
177 |
178 |
180 |
181 |
183 |
184 |
186 |
187 |
188 |
192 |
194 |
195 |
197 |
198 |
200 |
201 |
203 |
204 |
206 |
207 |
208 |
210 |
211 |
213 |
214 |
215 |
216 |
219 |
220 |
221 |
--------------------------------------------------------------------------------
/RedirectPort.cpp:
--------------------------------------------------------------------------------
1 | #include "StdAfx.h"
2 | #include ".\redirectport.h"
3 |
4 | CRedirectPort::CRedirectPort(const CString& sPortName, bool IsActive, CWnd* pWnd, int nIndex ):
5 | CCommPort()
6 | {
7 | m_bIsActive = IsActive;
8 | m_pParentWnd = pWnd;
9 | ASSERT( m_pParentWnd );
10 |
11 | m_sPortName = sPortName;
12 | m_sLogFile = _T("");
13 | m_sStatusMessage = _T("Ready to start");
14 |
15 | m_bLogStarted = FALSE;
16 | m_bAppend = FALSE;
17 |
18 | m_nIndex = nIndex;
19 | // this is indexes
20 | m_dwBaudRate = 9600;
21 | m_iIndexDataBits = 3;
22 | m_iIndexParity = 0;
23 | m_iIndexStopBits = 0;
24 | m_iIndexFlowCtrl = 2;
25 |
26 | m_stBytesInFile = 0;
27 | m_stBytesWritten = 0;
28 | }
29 |
30 | CRedirectPort::~CRedirectPort(void)
31 | {
32 | if ( IsOpen() )
33 | Close();
34 | }
35 |
36 | void CRedirectPort::OnRxChar( DWORD dwCount )
37 | {
38 | BYTE buffer[4096];
39 | DWORD dwSymbolsRead = Read( (VOID*)buffer, 4096 );
40 |
41 | try
42 | {
43 | m_File.Write( buffer, dwSymbolsRead );
44 |
45 | m_stBytesWritten += dwSymbolsRead;
46 | m_stBytesInFile += dwSymbolsRead;
47 | if ( m_bIsActive )
48 | {
49 | m_pParentWnd ->PostMessage( WM_USER_UPDATE_WND, 0, 0 );
50 | }
51 | }
52 | catch( CFileException *e )
53 | {
54 |
55 |
56 | TCHAR *lpszCause = m_sStatusMessage.GetBufferSetLength( 255 );
57 |
58 | if ( !e ->GetErrorMessage( lpszCause, 255 ) )
59 | m_sStatusMessage = _T("File error");
60 |
61 | m_pParentWnd ->PostMessage( WM_USER_UPDATE_WND, m_nIndex, SC_FILE_EXCEPTION );
62 |
63 | e->Delete();
64 | }
65 | }
66 |
67 | BOOL CRedirectPort::Open()
68 | {
69 | return Open( m_dwBaudRate, m_iIndexDataBits + 5, m_iIndexParity, m_iIndexStopBits, m_iIndexFlowCtrl );
70 | }
71 |
72 | BOOL CRedirectPort::Open( DWORD dwBaudrate, BYTE bDataBits, BYTE bParity, BYTE bStopBits, BYTE bFC )
73 | {
74 | UINT nOpenFlags = CFile::modeWrite | CFile::shareDenyNone | CFile::modeCreate;
75 | if( m_bAppend )
76 | {
77 | nOpenFlags |= CFile::modeNoTruncate;
78 | }
79 |
80 | if ( m_File.Open( m_sLogFile, nOpenFlags ) )
81 | {
82 | if ( m_bAppend )
83 | {
84 | m_File.SeekToEnd();
85 | CFileStatus fsStatus;
86 | m_File.GetStatus( fsStatus );
87 | m_stBytesInFile = (size_t)fsStatus.m_size;
88 | }
89 |
90 | if( CCommPort::Open( m_sPortName, dwBaudrate, bDataBits, bStopBits, bParity, bFC ) )
91 | {
92 | COMMTIMEOUTS Timeouts;
93 | memset( (LPVOID)&Timeouts, 0, sizeof(Timeouts));
94 |
95 | Timeouts.ReadTotalTimeoutConstant = 300;
96 | Timeouts.WriteTotalTimeoutConstant = 300;
97 | SetTimeouts( &Timeouts );
98 | m_pParentWnd ->PostMessage( WM_USER_CHANGE_STATUS, m_nIndex, SC_OPEN_SUCCESS );
99 |
100 | m_sStatusMessage = _T("Logging started");
101 |
102 | return TRUE;
103 | }
104 | else
105 | {
106 | m_iStatus = SC_OPEN_PORT_ERROR;
107 | m_sStatusMessage = _T("Unable open port");
108 | m_pParentWnd ->PostMessage( WM_USER_CHANGE_STATUS, m_nIndex, SC_OPEN_PORT_ERROR );
109 |
110 | m_File.Close();
111 | return FALSE;
112 | }
113 | }
114 | else
115 | {
116 | m_sStatusMessage = _T("Unable open file");
117 | m_pParentWnd ->PostMessage( WM_USER_CHANGE_STATUS, m_nIndex, SC_OPEN_FILE_ERROR );
118 | return FALSE;
119 | }
120 | }
121 |
122 | void CRedirectPort::Close()
123 | {
124 | m_File.Close();
125 | CCommPort::Close();
126 |
127 | m_sStatusMessage = _T("Logging stopped");
128 | }
129 |
130 | BOOL CRedirectPort::SaveSettings()
131 | {
132 | HKEY hKey = NULL;
133 |
134 | CString sPreferenceKey( PREFERENCES_KEY );
135 |
136 | sPreferenceKey += _T("\\");
137 | sPreferenceKey += m_sPortName;
138 |
139 | DWORD dwDisposition;
140 | if ( RegCreateKeyEx( HKEY_CURRENT_USER, sPreferenceKey, 0, 0, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS,
141 | NULL, &hKey, &dwDisposition ) != ERROR_SUCCESS )
142 | {
143 | return FALSE;
144 | }
145 |
146 | // start logging
147 | DWORD dwStarted = (DWORD)m_bLogStarted;
148 | RegSetValueEx( hKey, _T("logging"), 0, REG_DWORD, (BYTE*)&dwStarted, 4 );
149 |
150 | // redirect file
151 | RegSetValueEx( hKey, _T("file"), 0, REG_SZ, (BYTE*)(LPCTSTR)m_sLogFile, m_sLogFile.GetLength() * sizeof (TCHAR) );
152 |
153 |
154 | // check append
155 | RegSetValueEx( hKey, _T("append"), 0, REG_DWORD,(BYTE*)&m_bAppend, 4 );
156 | // port options
157 | RegSetValueEx( hKey, _T("baudrate"), 0, REG_DWORD,(BYTE*)&m_dwBaudRate, 4 );
158 |
159 | RegSetValueEx( hKey, _T("databits"), 0, REG_DWORD,(BYTE*)&m_iIndexDataBits, 4 );
160 |
161 | RegSetValueEx( hKey, _T("parity"), 0, REG_DWORD,(BYTE*)&m_iIndexParity, 4 );
162 |
163 | RegSetValueEx( hKey, _T("stopbits"), 0, REG_DWORD,(BYTE*)&m_iIndexStopBits, 4 );
164 |
165 | RegSetValueEx( hKey, _T("flowctrl"), 0, REG_DWORD,(BYTE*)&m_iIndexFlowCtrl, 4 );
166 |
167 | return TRUE;
168 | }
169 |
170 | BOOL CRedirectPort::LoadSettings ( )
171 | {
172 | HKEY hKey = NULL;
173 |
174 | CString sPreferenceKey( PREFERENCES_KEY );
175 | sPreferenceKey += _T("\\");
176 | sPreferenceKey += m_sPortName;
177 |
178 | if ( RegOpenKeyEx( HKEY_CURRENT_USER, sPreferenceKey, 0, KEY_ALL_ACCESS, &hKey ) != ERROR_SUCCESS )
179 | {
180 | return FALSE;
181 | }
182 |
183 | DWORD cValues; // number of values for key
184 | DWORD cchMaxValue; // longest value name
185 | DWORD cbMaxValueData; // longest value data
186 | BYTE bData [1024];
187 | DWORD dwDataLen = 1024;
188 |
189 | DWORD retCode;
190 | TCHAR achValue[254];
191 | DWORD cchValue = 255; //16383;
192 |
193 | // Get the class name and the value count.
194 | retCode = RegQueryInfoKey( hKey, NULL, NULL, NULL, NULL, NULL, NULL,
195 | &cValues, &cchMaxValue, &cbMaxValueData, NULL, NULL);
196 | // search values of keys
197 | if (cValues)
198 | {
199 | for (DWORD i=0, retCode=ERROR_SUCCESS; i
2 |
3 |
4 |
5 | Debug
6 | Win32
7 |
8 |
9 | Release
10 | Win32
11 |
12 |
13 | Template
14 | Win32
15 |
16 |
17 |
18 | {5892FB7D-278E-45FE-A820-B2A323A30711}
19 | MFCProj
20 |
21 |
22 |
23 | Application
24 | Static
25 | MultiByte
26 |
27 |
28 | Application
29 | Static
30 | Unicode
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 | <_ProjectFileVersion>10.0.40219.1
44 | Debug\
45 | Debug\
46 | true
47 | Release\
48 | Release\
49 | false
50 | AllRules.ruleset
51 |
52 |
53 | AllRules.ruleset
54 |
55 |
56 | AllRules.ruleset
57 |
58 |
59 |
60 |
61 |
62 | Disabled
63 | WIN32;_WINDOWS;_DEBUG;%(PreprocessorDefinitions)
64 | true
65 | EnableFastChecks
66 | MultiThreadedDebug
67 | true
68 | Use
69 | Level3
70 | EditAndContinue
71 |
72 |
73 | true
74 | Windows
75 | MachineX86
76 |
77 |
78 | _DEBUG;%(PreprocessorDefinitions)
79 | false
80 |
81 |
82 | _DEBUG;%(PreprocessorDefinitions)
83 | 0x0409
84 | $(IntDir);%(AdditionalIncludeDirectories)
85 |
86 |
87 |
88 |
89 | WIN32;_WINDOWS;NDEBUG;%(PreprocessorDefinitions)
90 | false
91 | MultiThreaded
92 | true
93 | Use
94 | Level3
95 | ProgramDatabase
96 |
97 |
98 | $(OutDir)DataLogger.exe
99 | true
100 | Windows
101 | true
102 | true
103 | MachineX86
104 |
105 |
106 | NDEBUG;%(PreprocessorDefinitions)
107 | false
108 |
109 |
110 | NDEBUG;%(PreprocessorDefinitions)
111 | 0x0409
112 | $(IntDir);%(AdditionalIncludeDirectories)
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 | Create
123 | Create
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
--------------------------------------------------------------------------------
/Port2File.rc:
--------------------------------------------------------------------------------
1 | // Microsoft Visual C++ generated resource script.
2 | //
3 | #include "resource.h"
4 |
5 | #define APSTUDIO_READONLY_SYMBOLS
6 | /////////////////////////////////////////////////////////////////////////////
7 | //
8 | // Generated from the TEXTINCLUDE 2 resource.
9 | //
10 | #include "afxres.h"
11 |
12 | /////////////////////////////////////////////////////////////////////////////
13 | #undef APSTUDIO_READONLY_SYMBOLS
14 |
15 | /////////////////////////////////////////////////////////////////////////////
16 | // Russian (Russia) resources
17 |
18 | #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS)
19 | LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
20 | #pragma code_page(1251)
21 |
22 | #ifdef APSTUDIO_INVOKED
23 | /////////////////////////////////////////////////////////////////////////////
24 | //
25 | // TEXTINCLUDE
26 | //
27 |
28 | 1 TEXTINCLUDE
29 | BEGIN
30 | "resource.h\0"
31 | END
32 |
33 | 2 TEXTINCLUDE
34 | BEGIN
35 | "#include ""afxres.h""\r\n"
36 | "\0"
37 | END
38 |
39 | 3 TEXTINCLUDE
40 | BEGIN
41 | "#define _AFX_NO_SPLITTER_RESOURCES\r\n"
42 | "#define _AFX_NO_OLE_RESOURCES\r\n"
43 | "#define _AFX_NO_TRACKER_RESOURCES\r\n"
44 | "#define _AFX_NO_PROPERTY_RESOURCES\r\n"
45 | "\r\n"
46 | "#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)\r\n"
47 | "LANGUAGE 9, 1\r\n"
48 | "#pragma code_page(1252)\r\n"
49 | "#include ""res\\Port2File.rc2"" // non-Microsoft Visual C++ edited resources\r\n"
50 | "#include ""afxres.rc"" // Standard components\r\n"
51 | "#endif\r\n"
52 | "\0"
53 | END
54 |
55 | #endif // APSTUDIO_INVOKED
56 |
57 |
58 | /////////////////////////////////////////////////////////////////////////////
59 | //
60 | // Accelerator
61 | //
62 |
63 | IDR_ACCELERATOR1 ACCELERATORS
64 | BEGIN
65 | VK_F1, ID_HELP, VIRTKEY, NOINVERT
66 | END
67 |
68 | #endif // Russian (Russia) resources
69 | /////////////////////////////////////////////////////////////////////////////
70 |
71 |
72 | /////////////////////////////////////////////////////////////////////////////
73 | // English (United States) resources
74 |
75 | #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
76 | LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
77 | #pragma code_page(1252)
78 |
79 | /////////////////////////////////////////////////////////////////////////////
80 | //
81 | // Icon
82 | //
83 |
84 | // Icon with lowest ID value placed first to ensure application icon
85 | // remains consistent on all systems.
86 | IDR_MAINFRAME ICON "res\\Port2File.ico"
87 |
88 | /////////////////////////////////////////////////////////////////////////////
89 | //
90 | // Dialog
91 | //
92 |
93 | IDD_ABOUTBOX DIALOGEX 0, 0, 235, 55
94 | STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
95 | CAPTION "About Port2File"
96 | FONT 8, "MS Shell Dlg", 0, 0, 0x1
97 | BEGIN
98 | ICON IDR_MAINFRAME,IDC_STATIC,11,17,20,20
99 | LTEXT "Port2File Version 1.0",IDC_STATIC,40,10,119,8,SS_NOPREFIX
100 | LTEXT "Copyright (C) 2006",IDC_STATIC,40,25,119,8
101 | DEFPUSHBUTTON "OK",IDOK,178,7,50,16,WS_GROUP
102 | END
103 |
104 | IDD_PORT2FILE_DIALOG DIALOGEX 0, 0, 304, 286
105 | STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
106 | EXSTYLE WS_EX_APPWINDOW
107 | CAPTION "RS232 DataLogger by Eltima Software 2.7 freeware"
108 | FONT 8, "MS Shell Dlg", 0, 0, 0x1
109 | BEGIN
110 | CONTROL "",IDC_LIST_PORTS,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_ALIGNLEFT | LVS_NOCOLUMNHEADER | WS_BORDER | WS_TABSTOP,7,80,115,186
111 | EDITTEXT IDC_ED_LOGFILE,129,80,150,12,ES_AUTOHSCROLL
112 | PUSHBUTTON " ...",IDC_BT_VIEW,281,80,16,12
113 | PUSHBUTTON "Start logging",IDC_BT_STARTLOG,128,252,111,14,WS_DISABLED
114 | COMBOBOX IDC_CB_BAUDRATE,174,121,120,126,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP
115 | COMBOBOX IDC_CB_DATABITS,174,136,120,109,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
116 | COMBOBOX IDC_CB_PARITY,174,151,120,107,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
117 | COMBOBOX IDC_CB_STOPBITS,174,166,120,91,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
118 | COMBOBOX IDC_CB_FC,174,181,120,92,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
119 | LTEXT "Baudrate",IDC_STATIC_2,132,125,30,8
120 | LTEXT "Data bits",IDC_STATIC_3,132,139,30,8
121 | LTEXT "Parity",IDC_STATIC_4,132,154,20,8
122 | LTEXT "Stop bits",IDC_STATIC_5,132,169,29,8
123 | LTEXT "Flow control",IDC_STATIC_6,132,184,40,8
124 | CONTROL "Append to file",IDC_CHECK_APPEND,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,129,96,61,10
125 | LTEXT "Total bytes in file",IDC_STATIC_A,133,224,56,8
126 | LTEXT "Bytes received from port",IDC_STATIC_9,133,212,80,8
127 | CONTROL 132,IDC_STATIC,"Static",SS_BITMAP,0,0,304,62
128 | LTEXT "Available ports",IDC_STATIC,8,67,48,8
129 | PUSHBUTTON "Help",IDC_BT_HELP,242,252,55,14
130 | LTEXT "Eltima Software GmbH - click for other products",IDC_STATIC_HOME,63,271,196,8
131 | LTEXT "Status",IDC_STATIC,134,235,22,8
132 | LTEXT "Static",IDC_STATIC_STATUS,177,235,116,8
133 | LTEXT "Static",IDC_STATIC_RECV,218,212,75,8
134 | LTEXT "Static",IDC_STATIC_TOTAL,218,224,75,8
135 | GROUPBOX "Serial port options",IDC_STATIC,128,110,170,90
136 | GROUPBOX "Statistics",IDC_STATIC,128,201,169,48
137 | END
138 |
139 |
140 | /////////////////////////////////////////////////////////////////////////////
141 | //
142 | // Version
143 | //
144 |
145 | VS_VERSION_INFO VERSIONINFO
146 | FILEVERSION 2,7,0,117
147 | PRODUCTVERSION 2,7,0,117
148 | FILEFLAGSMASK 0x3fL
149 | #ifdef _DEBUG
150 | FILEFLAGS 0x1L
151 | #else
152 | FILEFLAGS 0x0L
153 | #endif
154 | FILEOS 0x4L
155 | FILETYPE 0x1L
156 | FILESUBTYPE 0x0L
157 | BEGIN
158 | BLOCK "StringFileInfo"
159 | BEGIN
160 | BLOCK "040904e4"
161 | BEGIN
162 | VALUE "CompanyName", "Eltima Software"
163 | VALUE "FileDescription", "RS232 Data Logger"
164 | VALUE "FileVersion", "2.7.0.117"
165 | VALUE "InternalName", "DataLogger.exe"
166 | VALUE "LegalCopyright", " (c) Eltima Software. All rights reserved."
167 | VALUE "OriginalFilename", "DataLogger.exe"
168 | VALUE "ProductName", "RS232 Data Logger"
169 | VALUE "ProductVersion", "2.7.0.117"
170 | END
171 | END
172 | BLOCK "VarFileInfo"
173 | BEGIN
174 | VALUE "Translation", 0x409, 1252
175 | END
176 | END
177 |
178 |
179 | /////////////////////////////////////////////////////////////////////////////
180 | //
181 | // DESIGNINFO
182 | //
183 |
184 | #ifdef APSTUDIO_INVOKED
185 | GUIDELINES DESIGNINFO
186 | BEGIN
187 | IDD_ABOUTBOX, DIALOG
188 | BEGIN
189 | LEFTMARGIN, 7
190 | RIGHTMARGIN, 228
191 | TOPMARGIN, 7
192 | BOTTOMMARGIN, 48
193 | END
194 |
195 | IDD_PORT2FILE_DIALOG, DIALOG
196 | BEGIN
197 | VERTGUIDE, 7
198 | VERTGUIDE, 128
199 | VERTGUIDE, 174
200 | VERTGUIDE, 297
201 | BOTTOMMARGIN, 280
202 | HORZGUIDE, 58
203 | HORZGUIDE, 80
204 | HORZGUIDE, 91
205 | HORZGUIDE, 266
206 | END
207 | END
208 | #endif // APSTUDIO_INVOKED
209 |
210 |
211 | /////////////////////////////////////////////////////////////////////////////
212 | //
213 | // Bitmap
214 | //
215 |
216 | IDB_BMP_HEAD BITMAP "res\\head.bmp"
217 | IDB_SPM BITMAP "res\\spm.bmp"
218 |
219 | /////////////////////////////////////////////////////////////////////////////
220 | //
221 | // String Table
222 | //
223 |
224 | STRINGTABLE
225 | BEGIN
226 | IDS_ABOUTBOX "&About Port2File..."
227 | END
228 |
229 | #endif // English (United States) resources
230 | /////////////////////////////////////////////////////////////////////////////
231 |
232 |
233 |
234 | #ifndef APSTUDIO_INVOKED
235 | /////////////////////////////////////////////////////////////////////////////
236 | //
237 | // Generated from the TEXTINCLUDE 3 resource.
238 | //
239 | #define _AFX_NO_SPLITTER_RESOURCES
240 | #define _AFX_NO_OLE_RESOURCES
241 | #define _AFX_NO_TRACKER_RESOURCES
242 | #define _AFX_NO_PROPERTY_RESOURCES
243 |
244 | #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
245 | LANGUAGE 9, 1
246 | #pragma code_page(1252)
247 | #include "res\Port2File.rc2" // non-Microsoft Visual C++ edited resources
248 | #include "afxres.rc" // Standard components
249 | #endif
250 |
251 | /////////////////////////////////////////////////////////////////////////////
252 | #endif // not APSTUDIO_INVOKED
253 |
254 |
--------------------------------------------------------------------------------
/Port2FileDlg.cpp:
--------------------------------------------------------------------------------
1 | // Port2FileDlg.cpp : implementation file
2 | //
3 |
4 | #include "stdafx.h"
5 | #include "Port2File.h"
6 | #include "Port2FileDlg.h"
7 | #include ".\port2filedlg.h"
8 | #include "consts.h"
9 |
10 | #ifdef _DEBUG
11 | #define new DEBUG_NEW
12 | #endif
13 |
14 | const TCHAR STRING_DISABLE [] = _T("[Stopped]");
15 | const TCHAR STRING_ENABLE [] = _T("[Started]");
16 | const TCHAR STRING_ERROR [] = _T("[Error]");
17 |
18 |
19 | /////////////////////////////////////////////////////////////
20 | //
21 | // CRedirectDlg dialog
22 | //
23 | /////////////////////////////////////////////////////////////
24 |
25 | CRedirectDlg::CRedirectDlg(CWnd* pParent /*=NULL*/)
26 | : CDialog(CRedirectDlg::IDD, pParent)
27 | , m_bFileAppend(FALSE)
28 | , m_sLogFile(_T(""))
29 | , m_iCurItemSel(0)
30 | , m_sRecvBytes(_T("0 bytes"))
31 | , m_sTotalFileSize(_T("0 bytes"))
32 | , m_sErrorStatus(_T(""))
33 | {
34 | m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
35 | }
36 |
37 | void CRedirectDlg::DoDataExchange(CDataExchange* pDX)
38 | {
39 | CDialog::DoDataExchange(pDX);
40 | DDX_Control(pDX, IDC_LIST_PORTS, m_ListPorts);
41 | DDX_Check(pDX, IDC_CHECK_APPEND, m_bFileAppend);
42 | DDX_Control(pDX, IDC_CB_BAUDRATE, m_cbBaudrate);
43 | DDX_Control(pDX, IDC_CB_DATABITS, m_cbDataBits);
44 | DDX_Control(pDX, IDC_CB_PARITY, m_cbParity);
45 | DDX_Control(pDX, IDC_CB_STOPBITS, m_cbStopBits);
46 | DDX_Control(pDX, IDC_CB_FC, m_cbFC);
47 | DDX_Text(pDX, IDC_ED_LOGFILE, m_sLogFile);
48 | DDX_Text(pDX, IDC_STATIC_RECV, m_sRecvBytes);
49 | DDX_Text(pDX, IDC_STATIC_TOTAL, m_sTotalFileSize);
50 | DDX_Control(pDX, IDC_STATIC_HOME, m_HomeHlink);
51 | DDX_Text(pDX, IDC_STATIC_STATUS, m_sErrorStatus);
52 | }
53 |
54 | BEGIN_MESSAGE_MAP(CRedirectDlg, CDialog)
55 | ON_WM_PAINT()
56 | ON_WM_QUERYDRAGICON()
57 | //}}AFX_MSG_MAP
58 | ON_BN_CLICKED(IDC_BT_VIEW, OnBnClickedBtView)
59 | ON_BN_CLICKED(IDC_BT_STARTLOG, OnBnClickedBtStartlog)
60 | ON_BN_CLICKED(IDC_BT_HELP, OnBnClickedBtHelp)
61 | ON_BN_CLICKED(IDC_CHECK_APPEND, OnBnClickedCheckAppend)
62 | ON_CBN_SELCHANGE(IDC_CB_BAUDRATE, OnCbnSelchangeCbBaudrate)
63 | ON_CBN_SELCHANGE(IDC_CB_DATABITS, OnCbnSelchangeCbDatabits)
64 | ON_CBN_SELCHANGE(IDC_CB_PARITY, OnCbnSelchangeCbParity)
65 | ON_CBN_SELCHANGE(IDC_CB_STOPBITS, OnCbnSelchangeCbStopbits)
66 | ON_CBN_SELCHANGE(IDC_CB_FC, OnCbnSelchangeCbFc)
67 | ON_EN_CHANGE(IDC_ED_LOGFILE, OnEnChangeEdLogfile)
68 | ON_MESSAGE (WM_USER_UPDATE_WND, OnWriteUpdate )
69 | ON_MESSAGE (WM_USER_CHANGE_STATUS, OnWriteStatus )
70 | ON_NOTIFY (NM_CUSTOMDRAW, IDC_LIST_PORTS, OnCustomdrawList)
71 | ON_COMMAND(ID_HELP, OnBnClickedBtHelp)
72 | END_MESSAGE_MAP()
73 |
74 |
75 | // CRedirectDlg message handlers
76 |
77 | BOOL CRedirectDlg::OnInitDialog()
78 | {
79 | CDialog::OnInitDialog();
80 |
81 | SetIcon(m_hIcon, TRUE); // Set big icon
82 | SetIcon(m_hIcon, FALSE); // Set small icon
83 |
84 | // comm initialization
85 | m_IconList.Create( 16, 16, ILC_MASK | ILC_COLOR24, 1, 1 );
86 | m_IconList.Add( AfxGetApp() ->LoadIcon( MAKEINTRESOURCE( IDR_MAINFRAME ) ) );
87 | m_ListPorts.SetExtendedStyle( LVS_EX_FULLROWSELECT );
88 | m_ListPorts.SetImageList( &m_IconList, LVSIL_SMALL );
89 |
90 | m_HomeHlink.SetLink( true, false );
91 | m_HomeHlink.SetLinkCursor( LoadCursor(NULL, MAKEINTRESOURCE(32649) ) );
92 | m_HomeHlink.SetHyperLink( CString( _T("http:\\\\www.eltima.com\\products") ) );
93 | m_HomeHlink.SetFontBold( true );
94 | m_HomeHlink.SetTextColor( RGB( 0, 0, 255 ) );
95 |
96 |
97 | CWnd* pWnd = (CWnd*)GetDlgItem( IDC_LIST_PORTS );
98 | CRect rect;
99 | pWnd ->GetClientRect( &rect );
100 | m_ListPorts.InsertColumn( 0, _T(""), LVCFMT_LEFT, int(rect.Width() / 2 - 0.05 * rect.Width()) );
101 | m_ListPorts.InsertColumn( 1, _T(""), LVCFMT_LEFT, int(rect.Width() / 2 - 0.05 * rect.Width()) );
102 |
103 | GetAvailablePorts();
104 |
105 | // fill controls
106 | for ( int i=0; i(dc.GetSafeHdc()), 0);
146 |
147 | // Center icon in client rectangle
148 | int cxIcon = GetSystemMetrics(SM_CXICON);
149 | int cyIcon = GetSystemMetrics(SM_CYICON);
150 | CRect rect;
151 | GetClientRect(&rect);
152 | int x = (rect.Width() - cxIcon + 1) / 2;
153 | int y = (rect.Height() - cyIcon + 1) / 2;
154 |
155 | // Draw the icon
156 | dc.DrawIcon(x, y, m_hIcon);
157 | }
158 | else
159 | {
160 | CDialog::OnPaint();
161 | }
162 | }
163 |
164 | HCURSOR CRedirectDlg::OnQueryDragIcon()
165 | {
166 | return static_cast(m_hIcon);
167 | }
168 |
169 |
170 |
171 | ////////////////////////////////////////////////////////////////////////////////////
172 | //
173 | // control handling
174 | //
175 | /////////////////////////////////////////////////////////////////////////////////////
176 | void CRedirectDlg::OnEnChangeEdLogfile()
177 | {
178 | UpdateData();
179 | if ( m_sLogFile.GetLength() )
180 | {
181 | CWnd* pWnd = (CWnd*)GetDlgItem( IDC_BT_STARTLOG );
182 | pWnd ->EnableWindow( TRUE );
183 | }
184 | else
185 | {
186 | CWnd* pWnd = (CWnd*)GetDlgItem( IDC_BT_STARTLOG );
187 | pWnd ->EnableWindow( FALSE );
188 | }
189 |
190 | m_Ports[ m_iCurItemSel ] ->m_sLogFile = m_sLogFile;
191 | }
192 |
193 | void CRedirectDlg::OnBnClickedBtView()
194 | {
195 | static TCHAR BASED_CODE szFilter[] = _T("Text Files (*.txt)|*.txt|All Files (*.*)|*.*||");
196 |
197 | CFileDialog dlg( FALSE, _T("*.txt"), NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, szFilter );
198 | if ( dlg.DoModal() == IDOK )
199 | {
200 | m_sLogFile = dlg.GetPathName();
201 |
202 | if ( m_sLogFile.GetLength() )
203 | {
204 | CWnd* pWnd = (CWnd*)GetDlgItem( IDC_BT_STARTLOG );
205 | pWnd ->EnableWindow( TRUE );
206 | }
207 |
208 | m_Ports[ m_iCurItemSel ] ->m_sLogFile = m_sLogFile;
209 | }
210 |
211 | CEdit* pEdit = (CEdit*)GetDlgItem( IDC_ED_LOGFILE );
212 | pEdit ->SetWindowText( m_sLogFile );
213 | pEdit ->SetSel( m_sLogFile.GetLength(), m_sLogFile.GetLength() );
214 |
215 | UpdateData( FALSE );
216 | }
217 |
218 | void CRedirectDlg::OnBnClickedBtStartlog()
219 | {
220 | if ( m_Ports[ m_iCurItemSel ] ->m_bLogStarted )
221 | {
222 | // stop logging
223 | m_Ports[ m_iCurItemSel ] ->Close();
224 |
225 | CWnd* pWnd = (CWnd*)GetDlgItem( IDC_BT_STARTLOG );
226 | pWnd ->SetWindowText( _T("Start logging") );
227 |
228 | pWnd = (CWnd*)GetDlgItem( IDC_ED_LOGFILE );
229 | pWnd ->EnableWindow( TRUE );
230 |
231 | pWnd = (CWnd*)GetDlgItem( IDC_BT_VIEW );
232 | pWnd ->EnableWindow( TRUE );
233 |
234 | pWnd = (CWnd*)GetDlgItem( IDC_CHECK_APPEND );
235 | pWnd ->EnableWindow( TRUE );
236 |
237 | m_ListPorts.SetItemText( m_iCurItemSel, 1, STRING_DISABLE );
238 |
239 | m_Ports[ m_iCurItemSel ] ->m_bLogStarted = FALSE;
240 |
241 | m_sErrorStatus = m_Ports[m_iCurItemSel] ->m_sStatusMessage;
242 | UpdateData( FALSE );
243 | }
244 | else
245 | {
246 | //////////////////////////////////////////////
247 | CString sBaudrate;
248 | m_cbBaudrate.GetLBText( m_cbBaudrate.GetCurSel(), sBaudrate );
249 | DWORD dwBaudrate = _ttoi( sBaudrate );
250 | int iBits = m_cbDataBits.GetCurSel() + 5;
251 | int iParity = m_cbParity.GetCurSel();
252 | int iStopbits = m_cbStopBits.GetCurSel();
253 | int iFC = m_cbFC.GetCurSel();
254 |
255 | UpdateData();
256 | m_Ports[ m_iCurItemSel ] ->m_sLogFile = m_sLogFile;
257 |
258 | // run logging
259 | if ( (iBits != -1 && iParity != -1 && iStopbits != -1) &&
260 | m_Ports[ m_iCurItemSel ] ->Open( dwBaudrate, iBits, iParity, iStopbits, iFC ) )
261 | {
262 | CWnd* pWnd = (CWnd*)GetDlgItem( IDC_BT_STARTLOG );
263 | pWnd ->SetWindowText( _T("Stop logging") );
264 |
265 | pWnd = (CWnd*)GetDlgItem( IDC_ED_LOGFILE );
266 | pWnd ->EnableWindow( FALSE );
267 |
268 | pWnd = (CWnd*)GetDlgItem( IDC_BT_VIEW );
269 | pWnd ->EnableWindow( FALSE );
270 |
271 | pWnd = (CWnd*)GetDlgItem( IDC_CHECK_APPEND );
272 | pWnd ->EnableWindow( FALSE );
273 |
274 | m_ListPorts.SetItemText( m_iCurItemSel, 1, STRING_ENABLE );
275 |
276 | m_Ports[ m_iCurItemSel ] ->m_bLogStarted = TRUE;
277 | }
278 | else
279 | {
280 | m_ListPorts.SetItemText( m_iCurItemSel, 1, STRING_ERROR );
281 | }
282 | }
283 |
284 | m_ListPorts.RedrawItems( m_iCurItemSel, m_iCurItemSel );
285 | m_ListPorts.Invalidate( TRUE );
286 | m_ListPorts.UpdateWindow();
287 | }
288 |
289 | void CRedirectDlg::OnBnClickedBtHelp()
290 | {
291 | CString str;
292 | TCHAR *Buf = str.GetBufferSetLength (1024);
293 | GetModuleFileName (NULL, Buf, 1024);
294 | *(_tcsrchr (Buf, _T('\\'))) = 0;
295 | str.ReleaseBuffer ();
296 | str += _T("\\");
297 | str += _T("data_logger.chm");
298 | ShellExecute(NULL, _T("open"), str, NULL, NULL, SW_SHOWNORMAL );
299 | }
300 |
301 | // enable logging
302 | void CRedirectDlg::OnCbnSelchangeCbBaudrate()
303 | {
304 | CString sBaudrate;
305 | m_cbBaudrate.GetLBText( m_cbBaudrate.GetCurSel(), sBaudrate );
306 | m_Ports[ m_iCurItemSel ] ->m_dwBaudRate = _ttoi( sBaudrate );
307 |
308 | m_Ports[ m_iCurItemSel ] ->SetBaudrate( m_Ports[ m_iCurItemSel ] ->m_dwBaudRate );
309 | }
310 |
311 | void CRedirectDlg::OnCbnSelchangeCbDatabits()
312 | {
313 | m_Ports[ m_iCurItemSel ] ->m_iIndexDataBits = m_cbDataBits.GetCurSel();
314 | m_Ports[ m_iCurItemSel ] ->SetDataBits( m_cbDataBits.GetCurSel() + 4 );
315 | }
316 |
317 | void CRedirectDlg::OnCbnSelchangeCbParity()
318 | {
319 | m_Ports[ m_iCurItemSel ] ->m_iIndexParity = m_cbParity.GetCurSel();
320 | m_Ports[ m_iCurItemSel ] ->SetParity( m_cbParity.GetCurSel() );
321 | }
322 |
323 | void CRedirectDlg::OnCbnSelchangeCbStopbits()
324 | {
325 | m_Ports[ m_iCurItemSel ] ->m_iIndexStopBits = m_cbStopBits.GetCurSel();
326 | m_Ports[ m_iCurItemSel ] ->SetStopBits( m_cbStopBits.GetCurSel() );
327 | }
328 |
329 | void CRedirectDlg::OnCbnSelchangeCbFc()
330 | {
331 | m_Ports[ m_iCurItemSel ] ->m_iIndexFlowCtrl = m_cbFC.GetCurSel();
332 | m_Ports[ m_iCurItemSel ] ->SetFlowControl( m_cbFC.GetCurSel() );
333 | }
334 |
335 | void CRedirectDlg::OnBnClickedCheckAppend()
336 | {
337 | UpdateData();
338 | m_Ports[m_iCurItemSel] ->m_bAppend = m_bFileAppend;
339 | }
340 |
341 | ////////////////////////////////////////////////////////////////////////////////////
342 | //
343 | // control handling
344 | //
345 | /////////////////////////////////////////////////////////////////////////////////////
346 | void CRedirectDlg::OnOK()
347 | {
348 | OnBnClickedBtStartlog();
349 | }
350 |
351 | void CRedirectDlg::OnCancel()
352 | {
353 | if( MessageBox( _T("Do you really want to quit? All logging tasks will be halted."), _T("Data Logger"),
354 | MB_ICONQUESTION | MB_YESNO ) == IDYES )
355 | {
356 | for ( UINT i=0; iSaveSettings();
360 | delete pPort;
361 | }
362 |
363 | CDialog::OnCancel();
364 | }
365 | }
366 |
367 | BOOL CRedirectDlg::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
368 | {
369 | NMHDR *nmhdr = (NMHDR*)lParam;
370 |
371 | if ( nmhdr ->hwndFrom == m_ListPorts.m_hWnd )
372 | {
373 | if ( nmhdr->code == LVN_ITEMCHANGED )
374 | {
375 |
376 | LPNMLISTVIEW pnmv = (LPNMLISTVIEW) lParam;
377 |
378 | if ( pnmv ->iItem != m_iCurItemSel )
379 | {
380 | m_Ports[m_iCurItemSel] ->m_bIsActive = false;
381 | m_iCurItemSel = pnmv ->iItem;
382 | m_Ports[m_iCurItemSel] ->m_bIsActive = true;
383 | UpdateSettings();
384 | }
385 | }
386 | }
387 |
388 | return CDialog::OnNotify(wParam, lParam, pResult);
389 | }
390 |
391 | LRESULT CRedirectDlg::OnWriteUpdate ( WPARAM, LPARAM )
392 | {
393 | m_sTotalFileSize.Format( _T("%d bytes"), m_Ports[m_iCurItemSel] ->GetFileTotalBytes () );
394 | m_sRecvBytes.Format ( _T("%d bytes"), m_Ports[m_iCurItemSel] ->GetFileWrittenBytes() );
395 |
396 | UpdateData( FALSE );
397 |
398 | return 0;
399 | }
400 |
401 | LRESULT CRedirectDlg::OnWriteStatus ( WPARAM wp, LPARAM lp )
402 | {
403 | // lp - status code
404 | if ( wp == m_iCurItemSel )
405 | {
406 | m_sErrorStatus = m_Ports[m_iCurItemSel] ->m_sStatusMessage;
407 | }
408 |
409 | if ( lp != SC_OPEN_SUCCESS && lp != SC_NO_ERROR )
410 | {
411 | m_ListPorts.SetItemText( (int)wp, 1, STRING_ERROR );
412 | }
413 |
414 | UpdateData( FALSE );
415 | return 0;
416 | }
417 |
418 | ////////////////////////////////////////////////////////////////////////////////
419 | //
420 | // user functions utilites
421 | //
422 | ///////////////////////////////////////////////////////////////////////////////
423 |
424 | void CRedirectDlg::GetAvailablePorts()
425 | {
426 | CStringList portNameList;
427 |
428 | if ( CCommPort::GetAvailablePorts( &portNameList ) )
429 | {
430 | m_Ports.reserve( portNameList.GetCount() );
431 |
432 | CString sDefaultPath;
433 | TCHAR *Buf = sDefaultPath.GetBufferSetLength (1024);
434 | GetModuleFileName (NULL, Buf, 1024);
435 | *(_tcsrchr (Buf, _T('\\'))) = 0;
436 | sDefaultPath.ReleaseBuffer ();
437 | sDefaultPath += _T("\\");
438 | sDefaultPath += _T("Logs");
439 | CreateDirectory( sDefaultPath, NULL );
440 |
441 | POSITION pos = portNameList.GetHeadPosition();
442 | for ( int i=0; i< portNameList.GetCount(); i++ )
443 | {
444 | LV_ITEM item;
445 | item.mask = LVIF_IMAGE | LVIF_TEXT;
446 | item.iItem = m_ListPorts.GetItemCount();
447 |
448 | CString sPortName = portNameList.GetNext( pos );
449 | TCHAR buffer[255];
450 | _tcsncpy( buffer, sPortName, 255 );
451 | item.pszText = buffer;
452 | item.iImage = 0;
453 | item.iSubItem = 0;
454 |
455 | m_Ports.push_back( new CRedirectPort( sPortName, (i==0)?true:false, this, i ) );
456 |
457 | m_Ports[i] ->LoadSettings();
458 |
459 | if ( m_Ports[i] ->m_sLogFile.IsEmpty() )
460 | {
461 | CString sCommDefaultPath = sDefaultPath;
462 | sCommDefaultPath += _T("\\");
463 | sCommDefaultPath += sPortName;
464 | sCommDefaultPath += _T("port");
465 | sCommDefaultPath += _T(".txt");
466 | m_Ports[i] ->m_sLogFile = sCommDefaultPath;
467 | }
468 |
469 | m_ListPorts.InsertItem( &item );
470 |
471 | if ( m_Ports[i] ->m_bLogStarted && m_Ports[ i ] ->Open() )
472 | {
473 | m_ListPorts.SetItemText( item.iItem, 1, STRING_ENABLE );
474 | }
475 | else
476 | {
477 | m_ListPorts.SetItemText( item.iItem, 1, STRING_DISABLE );
478 | }
479 | }
480 |
481 | UpdateSettings();
482 | }
483 | }
484 |
485 | // set active port settings
486 | void CRedirectDlg::UpdateSettings()
487 | {
488 | m_sLogFile = m_Ports[m_iCurItemSel] ->m_sLogFile;
489 |
490 | if ( m_Ports[ m_iCurItemSel ] ->m_bLogStarted )
491 | {
492 | CWnd* pWnd = (CWnd*)GetDlgItem( IDC_BT_STARTLOG );
493 | pWnd ->SetWindowText( _T("Stop logging") );
494 |
495 | pWnd = (CWnd*)GetDlgItem( IDC_ED_LOGFILE );
496 | pWnd ->EnableWindow( FALSE );
497 |
498 | pWnd = (CWnd*)GetDlgItem( IDC_BT_VIEW );
499 | pWnd ->EnableWindow( FALSE );
500 |
501 | pWnd = (CWnd*)GetDlgItem( IDC_CHECK_APPEND );
502 | pWnd ->EnableWindow( FALSE );
503 | }
504 | else
505 | {
506 | CWnd* pWnd = (CWnd*)GetDlgItem( IDC_BT_STARTLOG );
507 | pWnd ->SetWindowText( _T("Start logging") );
508 |
509 | if ( m_sLogFile.GetLength() )
510 | {
511 | pWnd ->EnableWindow( TRUE );
512 | }
513 | else
514 | {
515 | pWnd ->EnableWindow( FALSE );
516 | }
517 |
518 | pWnd = (CWnd*)GetDlgItem( IDC_ED_LOGFILE );
519 | pWnd ->EnableWindow( TRUE );
520 |
521 | pWnd = (CWnd*)GetDlgItem( IDC_BT_VIEW );
522 | pWnd ->EnableWindow( TRUE );
523 |
524 | pWnd = (CWnd*)GetDlgItem( IDC_CHECK_APPEND );
525 | pWnd ->EnableWindow( TRUE );
526 | }
527 |
528 | m_bFileAppend = m_Ports[m_iCurItemSel] ->m_bAppend;
529 |
530 | CString sBaudrate;
531 | sBaudrate.Format( _T("%d"), m_Ports[m_iCurItemSel] ->m_dwBaudRate );
532 | m_cbBaudrate.SetWindowText( sBaudrate );
533 |
534 | m_cbDataBits.SetCurSel( m_Ports[m_iCurItemSel] ->m_iIndexDataBits );
535 | m_cbParity.SetCurSel ( m_Ports[m_iCurItemSel] ->m_iIndexParity );
536 | m_cbStopBits.SetCurSel( m_Ports[m_iCurItemSel] ->m_iIndexStopBits );
537 | m_cbFC.SetCurSel ( m_Ports[m_iCurItemSel] ->m_iIndexFlowCtrl );
538 |
539 | m_sErrorStatus = m_Ports[m_iCurItemSel] ->m_sStatusMessage;
540 |
541 | CString sWrittenBytes, sTotalBytes;
542 | sTotalBytes.Format ( _T("%d bytes"), m_Ports[m_iCurItemSel] ->GetFileTotalBytes() );
543 | sWrittenBytes.Format( _T("%d bytes"), m_Ports[m_iCurItemSel] ->GetFileWrittenBytes() );
544 |
545 | UpdateData( FALSE );
546 |
547 | CEdit* pEdit = (CEdit*)GetDlgItem( IDC_ED_LOGFILE );
548 | pEdit ->SetWindowText( m_sLogFile );
549 | pEdit ->SetSel( m_sLogFile.GetLength() - 1, m_sLogFile.GetLength() );
550 | }
551 |
552 | void CRedirectDlg::OnCustomdrawList ( NMHDR* pNMHDR, LRESULT* pResult )
553 | {
554 | NMLVCUSTOMDRAW* pLVCD = reinterpret_cast( pNMHDR );
555 |
556 | *pResult = 0;
557 |
558 | if ( CDDS_PREPAINT == pLVCD->nmcd.dwDrawStage )
559 | {
560 | *pResult = CDRF_NOTIFYITEMDRAW;
561 | }
562 | else
563 | {
564 | if ( CDDS_ITEM == pLVCD->nmcd.dwDrawStage )
565 | {
566 | TRACE( "dfssdafas" );
567 | }
568 |
569 |
570 | if ( CDDS_ITEMPREPAINT == pLVCD->nmcd.dwDrawStage )
571 | {
572 | if ( !m_Ports[ pLVCD->nmcd.dwItemSpec ] ->m_bLogStarted )
573 | {
574 | pLVCD->clrText = RGB( 128, 128, 128 );
575 | }
576 |
577 | *pResult = CDRF_DODEFAULT;
578 | }
579 | }
580 | }
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | GNU GENERAL PUBLIC LICENSE
2 | Version 2, June 1991
3 |
4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
6 | Everyone is permitted to copy and distribute verbatim copies
7 | of this license document, but changing it is not allowed.
8 |
9 | Preamble
10 |
11 | The licenses for most software are designed to take away your
12 | freedom to share and change it. By contrast, the GNU General Public
13 | License is intended to guarantee your freedom to share and change free
14 | software--to make sure the software is free for all its users. This
15 | General Public License applies to most of the Free Software
16 | Foundation's software and to any other program whose authors commit to
17 | using it. (Some other Free Software Foundation software is covered by
18 | the GNU Lesser General Public License instead.) You can apply it to
19 | your programs, too.
20 |
21 | When we speak of free software, we are referring to freedom, not
22 | price. Our General Public Licenses are designed to make sure that you
23 | have the freedom to distribute copies of free software (and charge for
24 | this service if you wish), that you receive source code or can get it
25 | if you want it, that you can change the software or use pieces of it
26 | in new free programs; and that you know you can do these things.
27 |
28 | To protect your rights, we need to make restrictions that forbid
29 | anyone to deny you these rights or to ask you to surrender the rights.
30 | These restrictions translate to certain responsibilities for you if you
31 | distribute copies of the software, or if you modify it.
32 |
33 | For example, if you distribute copies of such a program, whether
34 | gratis or for a fee, you must give the recipients all the rights that
35 | you have. You must make sure that they, too, receive or can get the
36 | source code. And you must show them these terms so they know their
37 | rights.
38 |
39 | We protect your rights with two steps: (1) copyright the software, and
40 | (2) offer you this license which gives you legal permission to copy,
41 | distribute and/or modify the software.
42 |
43 | Also, for each author's protection and ours, we want to make certain
44 | that everyone understands that there is no warranty for this free
45 | software. If the software is modified by someone else and passed on, we
46 | want its recipients to know that what they have is not the original, so
47 | that any problems introduced by others will not reflect on the original
48 | authors' reputations.
49 |
50 | Finally, any free program is threatened constantly by software
51 | patents. We wish to avoid the danger that redistributors of a free
52 | program will individually obtain patent licenses, in effect making the
53 | program proprietary. To prevent this, we have made it clear that any
54 | patent must be licensed for everyone's free use or not licensed at all.
55 |
56 | The precise terms and conditions for copying, distribution and
57 | modification follow.
58 |
59 | GNU GENERAL PUBLIC LICENSE
60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
61 |
62 | 0. This License applies to any program or other work which contains
63 | a notice placed by the copyright holder saying it may be distributed
64 | under the terms of this General Public License. The "Program", below,
65 | refers to any such program or work, and a "work based on the Program"
66 | means either the Program or any derivative work under copyright law:
67 | that is to say, a work containing the Program or a portion of it,
68 | either verbatim or with modifications and/or translated into another
69 | language. (Hereinafter, translation is included without limitation in
70 | the term "modification".) Each licensee is addressed as "you".
71 |
72 | Activities other than copying, distribution and modification are not
73 | covered by this License; they are outside its scope. The act of
74 | running the Program is not restricted, and the output from the Program
75 | is covered only if its contents constitute a work based on the
76 | Program (independent of having been made by running the Program).
77 | Whether that is true depends on what the Program does.
78 |
79 | 1. You may copy and distribute verbatim copies of the Program's
80 | source code as you receive it, in any medium, provided that you
81 | conspicuously and appropriately publish on each copy an appropriate
82 | copyright notice and disclaimer of warranty; keep intact all the
83 | notices that refer to this License and to the absence of any warranty;
84 | and give any other recipients of the Program a copy of this License
85 | along with the Program.
86 |
87 | 2. You may modify your copy or copies of the Program or any portion
88 | of it, thus forming a work based on the Program, and copy and
89 | distribute such modifications or work under the terms of Section 1
90 | above, provided that you also meet all of these conditions:
91 |
92 | a) You must cause the modified files to carry prominent notices
93 | stating that you changed the files and the date of any change.
94 |
95 | b) You must cause any work that you distribute or publish, that in
96 | whole or in part contains or is derived from the Program or any
97 | part thereof, to be licensed as a whole at no charge to all third
98 | parties under the terms of this License.
99 |
100 | c) If the modified program normally reads commands interactively
101 | when run, you must cause it, when started running for such
102 | interactive use in the most ordinary way, to print or display an
103 | announcement including an appropriate copyright notice and a
104 | notice that there is no warranty (or else, saying that you provide
105 | a warranty) and that users may redistribute the program under
106 | these conditions, and telling the user how to view a copy of this
107 | License. (Exception: if the Program itself is interactive but
108 | does not normally print such an announcement, your work based on
109 | the Program is not required to print an announcement.)
110 |
111 | These requirements apply to the modified work as a whole. If
112 | identifiable sections of that work are not derived from the Program,
113 | and can be reasonably considered independent and separate works in
114 | themselves, then this License, and its terms, do not apply to those
115 | sections when you distribute them as separate works. But when you
116 | distribute the same sections as part of a whole which is a work based
117 | on the Program, the distribution of the whole must be on the terms of
118 | this License, whose permissions for other licensees extend to the
119 | entire whole, and thus to each and every part regardless of who wrote it.
120 |
121 | Thus, it is not the intent of this section to claim rights or contest
122 | your rights to work written entirely by you; rather, the intent is to
123 | exercise the right to control the distribution of derivative or
124 | collective works based on the Program.
125 |
126 | In addition, mere aggregation of another work not based on the Program
127 | with the Program (or with a work based on the Program) on a volume of
128 | a storage or distribution medium does not bring the other work under
129 | the scope of this License.
130 |
131 | 3. You may copy and distribute the Program (or a work based on it,
132 | under Section 2) in object code or executable form under the terms of
133 | Sections 1 and 2 above provided that you also do one of the following:
134 |
135 | a) Accompany it with the complete corresponding machine-readable
136 | source code, which must be distributed under the terms of Sections
137 | 1 and 2 above on a medium customarily used for software interchange; or,
138 |
139 | b) Accompany it with a written offer, valid for at least three
140 | years, to give any third party, for a charge no more than your
141 | cost of physically performing source distribution, a complete
142 | machine-readable copy of the corresponding source code, to be
143 | distributed under the terms of Sections 1 and 2 above on a medium
144 | customarily used for software interchange; or,
145 |
146 | c) Accompany it with the information you received as to the offer
147 | to distribute corresponding source code. (This alternative is
148 | allowed only for noncommercial distribution and only if you
149 | received the program in object code or executable form with such
150 | an offer, in accord with Subsection b above.)
151 |
152 | The source code for a work means the preferred form of the work for
153 | making modifications to it. For an executable work, complete source
154 | code means all the source code for all modules it contains, plus any
155 | associated interface definition files, plus the scripts used to
156 | control compilation and installation of the executable. However, as a
157 | special exception, the source code distributed need not include
158 | anything that is normally distributed (in either source or binary
159 | form) with the major components (compiler, kernel, and so on) of the
160 | operating system on which the executable runs, unless that component
161 | itself accompanies the executable.
162 |
163 | If distribution of executable or object code is made by offering
164 | access to copy from a designated place, then offering equivalent
165 | access to copy the source code from the same place counts as
166 | distribution of the source code, even though third parties are not
167 | compelled to copy the source along with the object code.
168 |
169 | 4. You may not copy, modify, sublicense, or distribute the Program
170 | except as expressly provided under this License. Any attempt
171 | otherwise to copy, modify, sublicense or distribute the Program is
172 | void, and will automatically terminate your rights under this License.
173 | However, parties who have received copies, or rights, from you under
174 | this License will not have their licenses terminated so long as such
175 | parties remain in full compliance.
176 |
177 | 5. You are not required to accept this License, since you have not
178 | signed it. However, nothing else grants you permission to modify or
179 | distribute the Program or its derivative works. These actions are
180 | prohibited by law if you do not accept this License. Therefore, by
181 | modifying or distributing the Program (or any work based on the
182 | Program), you indicate your acceptance of this License to do so, and
183 | all its terms and conditions for copying, distributing or modifying
184 | the Program or works based on it.
185 |
186 | 6. Each time you redistribute the Program (or any work based on the
187 | Program), the recipient automatically receives a license from the
188 | original licensor to copy, distribute or modify the Program subject to
189 | these terms and conditions. You may not impose any further
190 | restrictions on the recipients' exercise of the rights granted herein.
191 | You are not responsible for enforcing compliance by third parties to
192 | this License.
193 |
194 | 7. If, as a consequence of a court judgment or allegation of patent
195 | infringement or for any other reason (not limited to patent issues),
196 | conditions are imposed on you (whether by court order, agreement or
197 | otherwise) that contradict the conditions of this License, they do not
198 | excuse you from the conditions of this License. If you cannot
199 | distribute so as to satisfy simultaneously your obligations under this
200 | License and any other pertinent obligations, then as a consequence you
201 | may not distribute the Program at all. For example, if a patent
202 | license would not permit royalty-free redistribution of the Program by
203 | all those who receive copies directly or indirectly through you, then
204 | the only way you could satisfy both it and this License would be to
205 | refrain entirely from distribution of the Program.
206 |
207 | If any portion of this section is held invalid or unenforceable under
208 | any particular circumstance, the balance of the section is intended to
209 | apply and the section as a whole is intended to apply in other
210 | circumstances.
211 |
212 | It is not the purpose of this section to induce you to infringe any
213 | patents or other property right claims or to contest validity of any
214 | such claims; this section has the sole purpose of protecting the
215 | integrity of the free software distribution system, which is
216 | implemented by public license practices. Many people have made
217 | generous contributions to the wide range of software distributed
218 | through that system in reliance on consistent application of that
219 | system; it is up to the author/donor to decide if he or she is willing
220 | to distribute software through any other system and a licensee cannot
221 | impose that choice.
222 |
223 | This section is intended to make thoroughly clear what is believed to
224 | be a consequence of the rest of this License.
225 |
226 | 8. If the distribution and/or use of the Program is restricted in
227 | certain countries either by patents or by copyrighted interfaces, the
228 | original copyright holder who places the Program under this License
229 | may add an explicit geographical distribution limitation excluding
230 | those countries, so that distribution is permitted only in or among
231 | countries not thus excluded. In such case, this License incorporates
232 | the limitation as if written in the body of this License.
233 |
234 | 9. The Free Software Foundation may publish revised and/or new versions
235 | of the General Public License from time to time. Such new versions will
236 | be similar in spirit to the present version, but may differ in detail to
237 | address new problems or concerns.
238 |
239 | Each version is given a distinguishing version number. If the Program
240 | specifies a version number of this License which applies to it and "any
241 | later version", you have the option of following the terms and conditions
242 | either of that version or of any later version published by the Free
243 | Software Foundation. If the Program does not specify a version number of
244 | this License, you may choose any version ever published by the Free Software
245 | Foundation.
246 |
247 | 10. If you wish to incorporate parts of the Program into other free
248 | programs whose distribution conditions are different, write to the author
249 | to ask for permission. For software which is copyrighted by the Free
250 | Software Foundation, write to the Free Software Foundation; we sometimes
251 | make exceptions for this. Our decision will be guided by the two goals
252 | of preserving the free status of all derivatives of our free software and
253 | of promoting the sharing and reuse of software generally.
254 |
255 | NO WARRANTY
256 |
257 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
258 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
259 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
260 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
261 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
262 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
263 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
264 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
265 | REPAIR OR CORRECTION.
266 |
267 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
268 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
269 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
270 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
271 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
272 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
273 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
274 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
275 | POSSIBILITY OF SUCH DAMAGES.
276 |
277 | END OF TERMS AND CONDITIONS
278 |
279 | How to Apply These Terms to Your New Programs
280 |
281 | If you develop a new program, and you want it to be of the greatest
282 | possible use to the public, the best way to achieve this is to make it
283 | free software which everyone can redistribute and change under these terms.
284 |
285 | To do so, attach the following notices to the program. It is safest
286 | to attach them to the start of each source file to most effectively
287 | convey the exclusion of warranty; and each file should have at least
288 | the "copyright" line and a pointer to where the full notice is found.
289 |
290 |
291 | Copyright (C)
292 |
293 | This program is free software; you can redistribute it and/or modify
294 | it under the terms of the GNU General Public License as published by
295 | the Free Software Foundation; either version 2 of the License, or
296 | (at your option) any later version.
297 |
298 | This program is distributed in the hope that it will be useful,
299 | but WITHOUT ANY WARRANTY; without even the implied warranty of
300 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
301 | GNU General Public License for more details.
302 |
303 | You should have received a copy of the GNU General Public License along
304 | with this program; if not, write to the Free Software Foundation, Inc.,
305 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
306 |
307 | Also add information on how to contact you by electronic and paper mail.
308 |
309 | If the program is interactive, make it output a short notice like this
310 | when it starts in an interactive mode:
311 |
312 | Gnomovision version 69, Copyright (C) year name of author
313 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
314 | This is free software, and you are welcome to redistribute it
315 | under certain conditions; type `show c' for details.
316 |
317 | The hypothetical commands `show w' and `show c' should show the appropriate
318 | parts of the General Public License. Of course, the commands you use may
319 | be called something other than `show w' and `show c'; they could even be
320 | mouse-clicks or menu items--whatever suits your program.
321 |
322 | You should also get your employer (if you work as a programmer) or your
323 | school, if any, to sign a "copyright disclaimer" for the program, if
324 | necessary. Here is a sample; alter the names:
325 |
326 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program
327 | `Gnomovision' (which makes passes at compilers) written by James Hacker.
328 |
329 | , 1 April 1989
330 | Ty Coon, President of Vice
331 |
332 | This General Public License does not permit incorporating your program into
333 | proprietary programs. If your program is a subroutine library, you may
334 | consider it more useful to permit linking proprietary applications with the
335 | library. If this is what you want to do, use the GNU Lesser General
336 | Public License instead of this License.
337 |
--------------------------------------------------------------------------------
/CommPort.cpp:
--------------------------------------------------------------------------------
1 | // CommPort.cpp : implementation file
2 | //
3 |
4 | #include "stdafx.h"
5 | #include "CommPort.h"
6 |
7 |
8 | // CCommPort
9 |
10 | // ===========================================================
11 | // constructor & destructor
12 | // ===========================================================
13 | CCommPort::CCommPort()
14 | {
15 | m_hComm = INVALID_HANDLE_VALUE;
16 | m_hThread = NULL;
17 | lReqTerminate = 0;
18 | }
19 |
20 | CCommPort::~CCommPort()
21 | {
22 | if ( IsOpen() )
23 | Close();
24 | }
25 |
26 | // ===========================================================
27 | // opening and closing ports
28 | // ===========================================================
29 | BOOL CCommPort::Open ( CString sPortName,
30 | DWORD dwBaudRate,
31 | BYTE bDataBits,
32 | BYTE stopbit,
33 | BYTE parity,
34 | BYTE fc )
35 | {
36 | if ( IsOpen() ) return FALSE;
37 |
38 | CString sPort = _T("\\\\.\\");
39 | sPort += sPortName;
40 | m_hComm = CreateFile( sPort,
41 | GENERIC_READ | GENERIC_WRITE,
42 | 0, // must be opened with exclusive-access
43 | NULL, // no security attributes
44 | OPEN_EXISTING, // must use OPEN_EXISTING
45 | FILE_FLAG_OVERLAPPED,
46 | NULL // hTemplate must be NULL for comm devices
47 | );
48 |
49 | TRACE ( _T("Error: %d\n"), GetLastError() );
50 |
51 | if (m_hComm == INVALID_HANDLE_VALUE)
52 | {
53 | TRACE (_T("CreateFile failed with error %d.\n"), GetLastError());
54 |
55 | CloseHandle( m_hComm );
56 | m_hComm = INVALID_HANDLE_VALUE;
57 | return FALSE;
58 | }
59 |
60 | // reconfigure port
61 | DCB dcb;
62 | BOOL fSuccess = GetCommState(m_hComm, &dcb);
63 |
64 | if (!fSuccess)
65 | {
66 | TRACE (_T("GetCommState failed with error %d.\n"), GetLastError());
67 |
68 | CloseHandle( m_hComm );
69 | m_hComm = INVALID_HANDLE_VALUE;
70 | return FALSE;
71 | }
72 |
73 | dcb.BaudRate = dwBaudRate;
74 | dcb.ByteSize = bDataBits;
75 | dcb.Parity = parity;
76 |
77 | switch ( stopbit )
78 | {
79 | case OneStopBit: dcb.StopBits = ONESTOPBIT; break;
80 | case OneFiveStopBits: dcb.StopBits = ONE5STOPBITS; break;
81 | case TwoStopBits: dcb.StopBits = TWOSTOPBITS; break;
82 | }
83 |
84 | switch ( fc )
85 | {
86 | case NoFlowControl:
87 | {
88 | dcb.fInX = FALSE;
89 | dcb.fOutX = FALSE;
90 | dcb.fOutxDsrFlow = FALSE;
91 | dcb.fOutxCtsFlow = FALSE;
92 | dcb.fDtrControl = DTR_CONTROL_ENABLE;
93 | dcb.fRtsControl = RTS_CONTROL_ENABLE;
94 | } break;
95 |
96 | case XonXoffFlowControl:
97 | {
98 | dcb.fInX = TRUE;
99 | dcb.fOutX = TRUE;
100 | dcb.fOutxDsrFlow = FALSE;
101 | dcb.fOutxCtsFlow = FALSE;
102 | dcb.fDtrControl = DTR_CONTROL_ENABLE;
103 | dcb.fRtsControl = RTS_CONTROL_ENABLE;
104 | } break;
105 |
106 | case Hardware:
107 | {
108 | dcb.fInX = FALSE;
109 | dcb.fOutX = FALSE;
110 | dcb.fOutxDsrFlow = TRUE;
111 | dcb.fOutxCtsFlow = TRUE;
112 | dcb.fDtrControl = DTR_CONTROL_HANDSHAKE;
113 | dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;
114 | } break;
115 | }
116 |
117 | // Install new adjustment
118 | fSuccess = SetCommState(m_hComm, &dcb);
119 | if (!fSuccess)
120 | {
121 | TRACE (_T("SetCommState failed with error %d.\n"), GetLastError());
122 |
123 | CloseHandle( m_hComm );
124 | m_hComm = INVALID_HANDLE_VALUE;
125 | return FALSE;
126 | }
127 |
128 | // launch comm event handler
129 | DWORD dwId;
130 | m_hThread = CreateThread( NULL, 0, EventHandler, (LPVOID)this, CREATE_SUSPENDED, &dwId );
131 |
132 | if ( m_hThread != NULL )
133 | {
134 | m_hEventTerminate = CreateEvent( NULL, FALSE, FALSE, _T("OnStopThread") );
135 | lReqTerminate = 1;
136 | ResumeThread( m_hThread );
137 | }
138 | else
139 | {
140 | CloseHandle( m_hComm );
141 | m_hComm = INVALID_HANDLE_VALUE;
142 | return FALSE;
143 | }
144 |
145 | return TRUE;
146 | }
147 |
148 | BOOL CCommPort::Open ( CString sPortName, CString sConfig )
149 | {
150 | if ( IsOpen() ) return FALSE;
151 |
152 | CString sPort = _T("\\\\.\\");
153 | sPort += sPortName;
154 |
155 | m_hComm = CreateFile( sPort,
156 | GENERIC_READ | GENERIC_WRITE,
157 | 0, // must be opened with exclusive-access
158 | NULL, // no security attributes
159 | OPEN_EXISTING, // must use OPEN_EXISTING
160 | FILE_FLAG_OVERLAPPED,
161 | NULL // hTemplate must be NULL for comm devices
162 | );
163 |
164 | if (m_hComm == INVALID_HANDLE_VALUE)
165 | {
166 | TRACE (_T("CreateFile failed with error %d.\n"), GetLastError());
167 |
168 | return FALSE;
169 | }
170 |
171 | // execute rearranging the port
172 | DCB dcb;
173 |
174 | if ( !GetCommState( m_hComm, &dcb) )
175 | {
176 | TRACE ( _T("GetCommState failed with error %d.\n"), GetLastError());
177 |
178 | CloseHandle ( m_hComm );
179 | m_hComm = INVALID_HANDLE_VALUE;
180 | return FALSE;
181 | }
182 |
183 | if ( !BuildCommDCB ( sConfig, &dcb ) )
184 | {
185 | TRACE( _T("BuildCommDCB failed with error %d.\n"), GetLastError());
186 |
187 | CloseHandle ( m_hComm );
188 | m_hComm = INVALID_HANDLE_VALUE;
189 | return FALSE;
190 | }
191 |
192 | // set new settings
193 | if ( !SetCommState(m_hComm, &dcb) )
194 | {
195 | TRACE ( _T("SetCommState failed with error %d.\n"), GetLastError());
196 |
197 | CloseHandle ( m_hComm );
198 | m_hComm = INVALID_HANDLE_VALUE;
199 | return FALSE;
200 | }
201 |
202 | // launch comm event handler
203 | DWORD dwId;
204 | m_hThread = CreateThread( NULL, 0, EventHandler, (LPVOID)this, CREATE_SUSPENDED, &dwId );
205 |
206 | if ( m_hThread != NULL )
207 | {
208 | m_hEventTerminate = CreateEvent( NULL, FALSE, FALSE, _T("OnStopThread") );
209 | lReqTerminate = 1;
210 | ResumeThread( m_hThread );
211 | }
212 | else
213 | {
214 | TRACE( _T( "Thread is fault! Error is %d"), GetLastError() );
215 |
216 | CloseHandle ( m_hComm );
217 | m_hComm = INVALID_HANDLE_VALUE;
218 | return FALSE;
219 | }
220 |
221 | return TRUE;
222 | }
223 |
224 |
225 | // ==============================================================
226 | // can open
227 | // ==============================================================
228 | BOOL CCommPort::TestOpen( CString sTestingPort )
229 | {
230 | CString sPort = _T("\\\\.\\");
231 | sPort += sTestingPort;
232 | HANDLE hComm = CreateFile( sPort, GENERIC_READ | GENERIC_WRITE,
233 | 0, NULL, OPEN_EXISTING, 0, NULL );
234 |
235 | BOOL fResult = FALSE;
236 | if ( hComm != INVALID_HANDLE_VALUE )
237 | {
238 | CloseHandle( hComm );
239 | return TRUE;
240 | }
241 | else
242 | return FALSE;
243 | }
244 |
245 | // ==============================================================
246 | // close port
247 | // ==============================================================
248 | void CCommPort::Close()
249 | {
250 | PurgeComm( m_hComm, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR );
251 | CancelIo( m_hComm );
252 | SetCommMask (m_hComm, 0);
253 |
254 | if ( m_hThread != NULL )
255 | {
256 | InterlockedDecrement( &lReqTerminate );
257 | Sleep( 0 );
258 |
259 | OSVERSIONINFO info;
260 | info.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
261 |
262 | GetVersionEx ( &info );
263 |
264 | if ( info.dwPlatformId == VER_PLATFORM_WIN32_NT )
265 | {
266 | // windows NT family
267 | while( WaitForSingleObject( m_hEventTerminate, 100 ) != WAIT_OBJECT_0 )
268 | {
269 | MSG msg;
270 | GetMessage(&msg, NULL, 0, 0);
271 | if ( !TranslateAccelerator(msg.hwnd, NULL, &msg) )
272 | {
273 | TranslateMessage(&msg);
274 | DispatchMessage(&msg);
275 | }
276 | }
277 | }
278 | else
279 | {
280 | // other windows
281 | TerminateThread( m_hThread, 0 );
282 | }
283 |
284 | CloseHandle( m_hComm );
285 | m_hComm = INVALID_HANDLE_VALUE;
286 |
287 | CloseHandle( m_hThread );
288 | CloseHandle( m_hEventTerminate );
289 |
290 | m_hThread = NULL;
291 | m_hEventTerminate = NULL;
292 | lReqTerminate = 0;
293 | }
294 | }
295 |
296 | // ==============================================================
297 | // enumerate available ports
298 | // ==============================================================
299 | DWORD CCommPort::GetAvailablePorts ( CStringList* portList )
300 | {
301 | //HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\SERIALCOMM
302 | HKEY hKey = NULL;
303 |
304 | if ( RegOpenKey( HKEY_LOCAL_MACHINE, _T("Hardware\\DeviceMap\\SerialComm"), &hKey ) != ERROR_SUCCESS )
305 | {
306 | return 0;
307 | }
308 |
309 | DWORD cValues; // number of values for key
310 | DWORD cchMaxValue; // longest value name
311 | DWORD cbMaxValueData; // longest value data
312 |
313 | BYTE bData [100];
314 | DWORD dwDataLen = 100;
315 |
316 | DWORD i, retCode, iFindedPorts=0;
317 |
318 | TCHAR achValue[255];
319 | DWORD cchValue = 255; //16300; //16383
320 |
321 | // Get the class name and the value count.
322 | retCode = RegQueryInfoKey( hKey, NULL, NULL, NULL, NULL, NULL, NULL,
323 | &cValues, &cchMaxValue, &cbMaxValueData, NULL, NULL);
324 |
325 | // enumerate all keys.
326 | if (cValues)
327 | {
328 | DWORD dwType;
329 | for (i=0, retCode=ERROR_SUCCESS; iAddTail( (LPCTSTR)bData );
340 | iFindedPorts++;
341 | }
342 | }
343 | }
344 |
345 | return iFindedPorts;
346 | }
347 |
348 | // ===========================================================
349 | // read & write
350 | // ===========================================================
351 |
352 | DWORD CCommPort::Read ( LPVOID lpBuf, DWORD dwCount )
353 | {
354 | if ( !IsOpen() ) return 0;
355 |
356 | OVERLAPPED o;
357 | memset ( &o, 0, sizeof (OVERLAPPED) );
358 | o.hEvent = CreateEvent( NULL, FALSE, FALSE, NULL);
359 |
360 | DWORD dwBytesRead=0;
361 |
362 | BOOL bResult = ReadFile(m_hComm, lpBuf, dwCount, &dwBytesRead, &o);
363 | if ( !bResult )
364 | {
365 | if ( GetLastError() == ERROR_IO_PENDING )
366 | {
367 | bResult = GetOverlappedResult( m_hComm, &o, &dwBytesRead, TRUE);
368 | return dwBytesRead;
369 | }
370 | else
371 | return 0;
372 | }
373 |
374 | CloseHandle( o.hEvent );
375 | return dwBytesRead;
376 | }
377 |
378 | DWORD CCommPort::Write( LPCVOID lpBuf, DWORD dwCount )
379 | {
380 | if ( !IsOpen() ) return 0;
381 |
382 | OVERLAPPED o;
383 | memset ( &o, 0, sizeof (OVERLAPPED) );
384 | o.hEvent = CreateEvent( NULL, FALSE, FALSE, NULL);
385 |
386 | DWORD dwBytesWritten = 0;
387 | BOOL bResult = WriteFile(m_hComm, lpBuf, dwCount, &dwBytesWritten, &o ) ;
388 |
389 | if ( !bResult )
390 | {
391 | if ( GetLastError() == ERROR_IO_PENDING )
392 | {
393 | bResult = GetOverlappedResult( m_hComm, &o, &dwBytesWritten, TRUE );
394 | if ( !bResult )
395 | {
396 | //CloseHandle( o.hEvent );
397 | return 0;
398 | }
399 | }
400 | else
401 | {
402 | CloseHandle( o.hEvent );
403 | return 0;
404 | }
405 | }
406 |
407 | CloseHandle( o.hEvent );
408 | return dwBytesWritten;
409 | }
410 |
411 | // ===========================================================
412 | // port configuration
413 | // ===========================================================
414 | BOOL CCommPort::GetConfig(COMMCONFIG& config)
415 | {
416 | ASSERT( IsOpen() );
417 |
418 | DWORD dwSize = sizeof(COMMCONFIG);
419 |
420 | return GetCommConfig( m_hComm, &config, &dwSize );
421 | }
422 |
423 | BOOL CCommPort::SetConfig(COMMCONFIG& config)
424 | {
425 | ASSERT( IsOpen() );
426 |
427 | return SetCommConfig( m_hComm, &config, sizeof(COMMCONFIG));
428 | }
429 |
430 | BOOL CCommPort::GetState(LPDCB dcb)
431 | {
432 | ASSERT ( IsOpen() );
433 |
434 | return GetCommState( m_hComm, dcb );
435 | }
436 |
437 | BOOL CCommPort::SetState(LPDCB dcb)
438 | {
439 | ASSERT( IsOpen() );
440 |
441 | return SetCommState( m_hComm, dcb );
442 | }
443 |
444 | // ===========================================================
445 | // timeouts
446 | // ===========================================================
447 | BOOL CCommPort::SetTimeouts( LPCOMMTIMEOUTS lpCommTimeouts )
448 | {
449 | return SetCommTimeouts( m_hComm, lpCommTimeouts );
450 | }
451 |
452 | BOOL CCommPort::GetTimeouts( LPCOMMTIMEOUTS lpCommTimeouts )
453 | {
454 | return GetCommTimeouts( m_hComm, lpCommTimeouts );
455 | }
456 |
457 | // ===========================================================
458 | // buffer cleaning
459 | // ===========================================================
460 | BOOL CCommPort::Purge ( DWORD dwFlags )
461 | {
462 | ASSERT( IsOpen() );
463 |
464 | return PurgeComm ( m_hComm, dwFlags );
465 | }
466 |
467 | BOOL CCommPort::ClearWriteQueue()
468 | {
469 | return Purge ( PURGE_TXCLEAR );
470 | }
471 |
472 | BOOL CCommPort::ClearReadQueue ()
473 | {
474 | return Purge ( PURGE_RXCLEAR );
475 | }
476 |
477 | BOOL CCommPort::AbortAllRead ()
478 | {
479 | return Purge ( PURGE_RXABORT );
480 | }
481 |
482 | BOOL CCommPort::AbortAllWrite ()
483 | {
484 | return Purge ( PURGE_TXABORT );
485 | }
486 |
487 | BOOL CCommPort::Flush()
488 | {
489 | ASSERT( IsOpen() );
490 |
491 | return ::FlushFileBuffers( m_hComm );
492 | }
493 |
494 | // ===========================================================
495 | // transmition control
496 | // ===========================================================
497 | BOOL CCommPort::TransmitChar( char cChar )
498 | {
499 | ASSERT( IsOpen() );
500 |
501 | return TransmitCommChar( m_hComm, cChar );
502 | }
503 |
504 | BOOL CCommPort::SetBreak()
505 | {
506 | ASSERT( IsOpen() );
507 |
508 | return SetCommBreak( m_hComm );
509 | }
510 |
511 | BOOL CCommPort::ClearBreak()
512 | {
513 | ASSERT( IsOpen() );
514 |
515 | return ClearCommBreak( m_hComm );
516 | }
517 |
518 | BOOL CCommPort::EscapeFunction( DWORD dwFunc )
519 | {
520 | ASSERT( IsOpen() );
521 |
522 | return EscapeCommFunction( m_hComm, dwFunc );
523 | }
524 |
525 | BOOL CCommPort::ClearError( LPDWORD lpErrors, LPCOMSTAT lpStat)
526 | {
527 | return ClearCommError( m_hComm, lpErrors, lpStat);
528 | }
529 |
530 | BOOL CCommPort::GetModemStatus( LPDWORD lpModemStat )
531 | {
532 | return GetCommModemStatus( m_hComm, lpModemStat );
533 | }
534 |
535 | BOOL CCommPort::GetProperties( LPCOMMPROP lpCommProp )
536 | {
537 | return GetCommProperties( m_hComm, lpCommProp );
538 | }
539 |
540 |
541 | // ===========================================================
542 | // events
543 | // ===========================================================
544 | BOOL CCommPort::SetMask ( DWORD dwMask )
545 | {
546 | ASSERT( IsOpen() );
547 |
548 | return SetCommMask( m_hComm, dwMask);
549 | }
550 |
551 | BOOL CCommPort::GetMask ( DWORD& dwMask )
552 | {
553 | ASSERT( IsOpen() );
554 |
555 | return GetCommMask( m_hComm, &dwMask );
556 | }
557 |
558 | DWORD CCommPort::EventHandler ( LPVOID lpParam )
559 | {
560 | CCommPort *pPort = (CCommPort*)lpParam;
561 | DWORD dwMask = EV_BREAK | EV_CTS | EV_DSR | EV_ERR | EV_RING |
562 | EV_RLSD | EV_RXCHAR | EV_RXFLAG | EV_TXEMPTY;
563 |
564 | if ( !pPort->SetMask( dwMask ) )
565 | {
566 | pPort ->OnEventError( COMM_SET_EVNT_MASK_ERROR );
567 | TRACE ( _T("Thread event handling exiting with error Can't set Mask!\r\n") );
568 | return 1;
569 | }
570 |
571 | OVERLAPPED o;
572 | DWORD dwResMask=0;
573 |
574 | o.hEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
575 | o.Internal = 0;
576 | o.InternalHigh = 0;
577 | o.Offset = 0;
578 | o.OffsetHigh = 0;
579 |
580 | while (1)
581 | {
582 | // exit from thread
583 | if ( pPort->lReqTerminate == 0)
584 | {
585 | CloseHandle( o.hEvent );
586 | SetEvent( pPort->m_hEventTerminate );
587 | TRACE ( _T("Thread event handling exiting with 0!\r\n") );
588 | return 0;
589 | }
590 |
591 | // handling comm events
592 | if ( !WaitCommEvent( pPort->m_hComm, &dwResMask, &o ) )
593 | {
594 | DWORD dwError = GetLastError();
595 | if ( dwError != ERROR_IO_PENDING )
596 | {
597 | pPort ->OnEventError( COMM_WAIT_FOR_EVENT_ERROR );
598 | CloseHandle( o.hEvent );
599 | SetEvent( pPort->m_hEventTerminate );
600 | TRACE ( _T("Thread event handling exiting with 1!\r\n") );
601 | return 1;
602 | }
603 | else
604 | {
605 | DWORD dwBytesTransfer;
606 | GetOverlappedResult( pPort->m_hComm, &o, &dwBytesTransfer, TRUE );
607 | }
608 | }
609 |
610 | if ( dwResMask & EV_BREAK )
611 | {
612 | pPort ->OnBreak();
613 | }
614 |
615 | if ( dwResMask & EV_CTS )
616 | {
617 | DWORD dwStatus;
618 | pPort ->GetModemStatus( &dwStatus );
619 | if ( dwStatus & MS_CTS_ON )
620 | pPort ->OnCTS( TRUE );
621 | else
622 | pPort ->OnCTS( FALSE );
623 | }
624 |
625 | if ( dwResMask & EV_DSR )
626 | {
627 | DWORD dwStatus;
628 | pPort ->GetModemStatus( &dwStatus );
629 | if ( dwStatus & MS_DSR_ON )
630 | pPort ->OnDSR( TRUE );
631 | else
632 | pPort ->OnDSR( FALSE );
633 | }
634 |
635 | if ( dwResMask & EV_ERR )
636 | {
637 | DWORD dwError;
638 | COMSTAT comStat;
639 | pPort ->ClearError( &dwError, &comStat );
640 | pPort ->OnERR( dwError );
641 | }
642 |
643 | if ( dwResMask & EV_RING )
644 | {
645 | DWORD dwStatus;
646 | pPort ->GetModemStatus( &dwStatus );
647 | if ( dwStatus & MS_DSR_ON )
648 | pPort ->OnRing( TRUE );
649 | else
650 | pPort ->OnRing( FALSE );
651 | }
652 |
653 | if ( dwResMask & EV_RLSD )
654 | {
655 | DWORD dwStatus;
656 | pPort ->GetModemStatus( &dwStatus );
657 | if ( dwStatus & MS_RLSD_ON )
658 | pPort ->OnRlsd( TRUE );
659 | else
660 | pPort ->OnRlsd( FALSE );
661 | }
662 |
663 | if ( dwResMask & EV_RXCHAR )
664 | {
665 | DWORD dwError;
666 | COMSTAT comStat;
667 | pPort ->ClearError( &dwError, &comStat );
668 | pPort ->OnRxChar( comStat.cbInQue );
669 | }
670 |
671 | if ( dwResMask & EV_RXFLAG )
672 | {
673 | pPort ->OnRxFlag();
674 | }
675 |
676 | if ( dwResMask & EV_TXEMPTY )
677 | {
678 | pPort ->OnTxEmpty();
679 | }
680 | } // while
681 |
682 | CloseHandle( o.hEvent );
683 |
684 | return 0;
685 | }
686 |
687 | void CCommPort::OnBreak() {}
688 | void CCommPort::OnCTS( BOOL fCTS ) {}
689 | void CCommPort::OnDSR( BOOL fDSR ) {}
690 | void CCommPort::OnERR( DWORD dwError ) {}
691 | void CCommPort::OnRing( BOOL fRing ) {}
692 | void CCommPort::OnRlsd( BOOL fLSD ) {}
693 | void CCommPort::OnRxChar( DWORD dwCount ) {}
694 | void CCommPort::OnRxFlag() {}
695 | void CCommPort::OnTxEmpty(){}
696 | void CCommPort::OnEventError ( DWORD dwErrCode ) {}
697 |
698 |
699 | // baudrate manipulation
700 | BOOL CCommPort::SetBaudrate ( DWORD dwBaudRate )
701 | {
702 | if ( !IsOpen() )
703 | {
704 | return FALSE;
705 | }
706 |
707 | DCB dcb;
708 | BOOL result = GetCommState( m_hComm, &dcb );
709 |
710 | if ( result )
711 | {
712 | dcb.BaudRate = dwBaudRate;
713 |
714 | result = SetCommState( m_hComm, &dcb );
715 | }
716 | else
717 | {
718 | return FALSE;
719 | }
720 |
721 | return result;
722 | }
723 |
724 | DWORD CCommPort::GetBaudrate ( )
725 | {
726 | if ( !IsOpen() )
727 | {
728 | return 0;
729 | }
730 |
731 | DCB dcb;
732 | if ( GetCommState( m_hComm, &dcb ) )
733 | return dcb.BaudRate;
734 | else
735 | return 0;
736 | }
737 |
738 | // databits manipulation
739 | BOOL CCommPort::SetDataBits ( BYTE bDataBits )
740 | {
741 | if ( !IsOpen() )
742 | {
743 | return FALSE;
744 | }
745 |
746 | DCB dcb;
747 | BOOL result = GetCommState( m_hComm, &dcb );
748 |
749 | if ( result )
750 | {
751 | dcb.ByteSize = bDataBits;
752 |
753 | result = SetCommState( m_hComm, &dcb );
754 | }
755 | else
756 | {
757 | return FALSE;
758 | }
759 |
760 | return result;
761 | }
762 |
763 | BYTE CCommPort::GetDataBits ( )
764 | {
765 | if ( !IsOpen() )
766 | {
767 | return 0;
768 | }
769 |
770 | DCB dcb;
771 | if( GetCommState( m_hComm, &dcb ) )
772 | {
773 | return dcb.ByteSize;
774 | }
775 | else
776 | {
777 | return 0;
778 | }
779 | }
780 | // parity manipulation
781 | BOOL CCommPort::SetParity ( BYTE bParity )
782 | {
783 | if ( !IsOpen() )
784 | {
785 | return FALSE;
786 | }
787 |
788 | DCB dcb;
789 | BOOL result = GetCommState( m_hComm, &dcb );
790 |
791 | if ( result )
792 | {
793 | dcb.Parity = bParity;
794 |
795 | result = SetCommState( m_hComm, &dcb );
796 | }
797 | else
798 | {
799 | return FALSE;
800 | }
801 |
802 | return result;
803 | }
804 |
805 | BOOL CCommPort::GetParity ( BYTE& Parity )
806 | {
807 | if ( !IsOpen() )
808 | {
809 | return FALSE;
810 | }
811 |
812 | DCB dcb;
813 | if( GetCommState( m_hComm, &dcb ) )
814 | {
815 | Parity = dcb.Parity;
816 | return TRUE;
817 | }
818 | else
819 | {
820 | return TRUE;
821 | }
822 | }
823 |
824 | BOOL CCommPort::SetStopBits ( BYTE bStopBits )
825 | {
826 | if ( !IsOpen() )
827 | {
828 | return FALSE;
829 | }
830 |
831 | DCB dcb;
832 | BOOL result = GetCommState( m_hComm, &dcb );
833 |
834 | if ( result )
835 | {
836 | dcb.StopBits = bStopBits;
837 |
838 | result = SetCommState( m_hComm, &dcb );
839 | }
840 | else
841 | {
842 | return FALSE;
843 | }
844 |
845 | return result;
846 | }
847 |
848 | BOOL CCommPort::GetStopBits ( BYTE &StopBits )
849 | {
850 | if ( !IsOpen() )
851 | {
852 | return FALSE;
853 | }
854 |
855 | DCB dcb;
856 | if( GetCommState( m_hComm, &dcb ) )
857 | {
858 | StopBits = dcb.StopBits;
859 | return TRUE;
860 | }
861 | else
862 | {
863 | return FALSE;
864 | }
865 | }
866 |
867 | BOOL CCommPort::SetFlowControl( BYTE fc )
868 | {
869 | if ( !IsOpen() )
870 | {
871 | return FALSE;
872 | }
873 |
874 | DCB dcb;
875 | if( GetCommState( m_hComm, &dcb ) )
876 | {
877 | switch ( fc )
878 | {
879 | case NoFlowControl:
880 | {
881 | dcb.fInX = FALSE;
882 | dcb.fOutX = FALSE;
883 | dcb.fOutxDsrFlow = FALSE;
884 | dcb.fOutxCtsFlow = FALSE;
885 | dcb.fDtrControl = DTR_CONTROL_ENABLE;
886 | dcb.fRtsControl = RTS_CONTROL_ENABLE;
887 | } break;
888 |
889 | case XonXoffFlowControl:
890 | {
891 | dcb.fInX = TRUE;
892 | dcb.fOutX = TRUE;
893 | dcb.fOutxDsrFlow = FALSE;
894 | dcb.fOutxCtsFlow = FALSE;
895 | dcb.fDtrControl = DTR_CONTROL_ENABLE;
896 | dcb.fRtsControl = RTS_CONTROL_ENABLE;
897 | } break;
898 |
899 | case Hardware:
900 | {
901 | dcb.fInX = FALSE;
902 | dcb.fOutX = FALSE;
903 | dcb.fOutxDsrFlow = TRUE;
904 | dcb.fOutxCtsFlow = TRUE;
905 | dcb.fDtrControl = DTR_CONTROL_HANDSHAKE;
906 | dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;
907 | } break;
908 | }
909 | return SetCommState( m_hComm, &dcb );
910 | }
911 | else
912 | {
913 | return FALSE;
914 | }
915 | }
--------------------------------------------------------------------------------
/Label.cpp:
--------------------------------------------------------------------------------
1 | // Label.cpp : implementation file
2 | //
3 |
4 | #include "stdafx.h"
5 | #include "Label.h"
6 |
7 | #ifdef _DEBUG
8 | #define new DEBUG_NEW
9 | #undef THIS_FILE
10 | static char THIS_FILE[] = __FILE__;
11 | #endif
12 |
13 | BEGIN_MESSAGE_MAP(CLabel, CStatic)
14 | //{{AFX_MSG_MAP(CLabel)
15 | ON_WM_TIMER()
16 | ON_WM_LBUTTONDOWN()
17 | ON_WM_SETCURSOR()
18 | ON_WM_SYSCOLORCHANGE()
19 | ON_WM_PAINT()
20 | ON_WM_ERASEBKGND()
21 | //}}AFX_MSG_MAP
22 | END_MESSAGE_MAP()
23 |
24 | /////////////////////////////////////////////////////////////////////////////
25 | // CLabel Version 1.2
26 | //
27 | // From now on I'll try to keep a log of fixes and enhancements...
28 | //
29 | // The new feature were added due to the response of people.
30 | // All I ask is to all you programmers out there, is if you add, fix or
31 | // enhance this code, sent me a copy and I'll send the copy on to www.codeproject.com
32 | //
33 | // Happy Software Engineer :)
34 | //
35 | // New features include:
36 | //
37 | // A. Support for 3D Fonts
38 | // B. Support for background transparency
39 | // C. More comments provided
40 | // D. If alignment is 'centered' and the window text is seperated by '\r\n'
41 | // the will be centered accordingly - requested by someone @ nasa ;)
42 | // E. Support for font rotation.
43 | // F. Respond to System Color Change
44 | // G. OnPaint improved performance - using Double Buffering Technique
45 | //
46 | // Thanks to:
47 | // Mark McDowell - For suggestion on 'Increasing the flexibility of "hypertext" setting...'
48 | // Erich Ruth - For suggestion on 'Font Rotation'
49 | //
50 |
51 | /////////////////////////////////////////////////////////////////////////////
52 | // CLabel Version 1.3
53 | //
54 | // A. Added SS_LEFTNOWORDWRAP to include wordwrap
55 | // B. Fix repainting problem
56 | // C. Fix SetBkColor
57 | // D. Added SS_CENTER
58 |
59 | // Thanks to:
60 | // Marius - Added styling problem.
61 | // Azing Vondeling & Broker - Spotting painting Problem.
62 | // Mel Stober - Back Color & SS_CENTER
63 | //
64 | /////////////////////////////////////////////////////////////////////////////
65 | // CLabel Version 1.4
66 | //
67 | // A. Fix to transparency mode
68 | // B. Added new SetText3DHiliteColor to change the 3D Font face color - default is white.
69 | //
70 | // Thanks to:
71 | // michael.groeger - Spotting Transparency with other controls bug.
72 | //
73 | //
74 | /////////////////////////////////////////////////////////////////////////////
75 | // CLabel Version 1.5
76 | //
77 | // A. Sanity handle check
78 | // B. Support Interface Charset
79 | // C. Check compilition with _UNICODE
80 | // D. Fix hyperlink feature
81 | // E. Support default Dialog Font
82 | // F. Inclusion of SS_OWNERDRAW via control creation and subclassing
83 | // G. Modification to Text aligmnent code
84 | // H. New background gradient fill function
85 | //
86 | // Thanks to:
87 | // Steve Kowald - Using null handles
88 | // Alan Chan - Supporting International Windows
89 | // Dieter Fauth - Request for default Dialog font
90 | // Herb Illfelder - Text Alignment code
91 | //
92 | /////////////////////////////////////////////////////////////////////////////
93 | // CLabel Version 1.6
94 | // Jeroen Roosendaal - SetFont suggestion
95 | // Laurent - Spotting SelectObject bugs
96 | // Bernie - Fix PreCreateWindow bug
97 | // Jignesh I. Patel - Added expanded tabs feature
98 | // Jim Farmelant - Fix SetText crash
99 |
100 |
101 | //////////////////////////////////////////////////////////////////////////
102 | //
103 | // Function: CLabel::CLabel
104 | //
105 | // Description: Default contructor
106 | //
107 | // INPUTS:
108 | //
109 | // RETURNS:
110 | //
111 | // NOTES:
112 | //
113 | // MODIFICATIONS:
114 | //
115 | // Name Date Version Comments
116 | // NT ALMOND 26/08/98 1.0 Origin
117 | //
118 | //////////////////////////////////////////////////////////////////////////
119 | CLabel::CLabel()
120 | {
121 | m_crText = GetSysColor(COLOR_WINDOWTEXT);
122 |
123 | // 1.1
124 | m_hBackBrush = NULL;
125 |
126 |
127 | m_crHiColor = 0;
128 | m_crLoColor = 0;
129 |
130 | m_bTimer = FALSE;
131 | m_bState = FALSE;
132 | m_bTransparent = FALSE;
133 | m_Link = LinkNone;
134 | m_hCursor = NULL;
135 | m_Type = None;
136 | m_bFont3d = FALSE;
137 | m_bNotifyParent = FALSE;
138 | m_bToolTips = FALSE;
139 | m_bRotation = FALSE;
140 | m_fillmode = Normal;
141 | m_cr3DHiliteColor = RGB(255,255,255);
142 |
143 | m_hwndBrush = ::CreateSolidBrush(GetSysColor(COLOR_3DFACE));
144 | }
145 |
146 | //////////////////////////////////////////////////////////////////////////
147 | //
148 | // Function: CLabel::~CLabel
149 | //
150 | // Description:
151 | //
152 | // INPUTS:
153 | //
154 | // RETURNS:
155 | //
156 | // NOTES:
157 | //
158 | // MODIFICATIONS:
159 | //
160 | // Name Date Version Comments
161 | // NT ALMOND 26/08/98 1.0 Origin
162 | // NT ALMOND 15092000 1.5 Handle Check
163 | //////////////////////////////////////////////////////////////////////////
164 | CLabel::~CLabel()
165 | {
166 | // Clean up
167 | m_font.DeleteObject();
168 | ::DeleteObject(m_hwndBrush);
169 |
170 | // Stop Checking complaining
171 | if (m_hBackBrush)
172 | ::DeleteObject(m_hBackBrush);
173 |
174 | }
175 |
176 | void CLabel::UpdateSurface()
177 | {
178 | CRect (rc);
179 | GetWindowRect(rc);
180 | RedrawWindow();
181 |
182 | GetParent()->ScreenToClient(rc);
183 | GetParent()->InvalidateRect(rc,TRUE);
184 | GetParent()->UpdateWindow();
185 | }
186 |
187 | //////////////////////////////////////////////////////////////////////////
188 | //
189 | // Function: CLabel::ReconstructFont
190 | //
191 | // Description: Helper function to build font after it was changed
192 | //
193 | // INPUTS:
194 | //
195 | // RETURNS:
196 | //
197 | // NOTES: PROTECTED
198 | //
199 | // MODIFICATIONS:
200 | //
201 | // Name Date Version Comments
202 | // NT ALMOND 26/08/98 1.0 Origin
203 | //
204 | //////////////////////////////////////////////////////////////////////////
205 | void CLabel::ReconstructFont()
206 | {
207 | m_font.DeleteObject();
208 | BOOL bCreated = m_font.CreateFontIndirect(&m_lf);
209 |
210 | ASSERT(bCreated);
211 | }
212 |
213 | //////////////////////////////////////////////////////////////////////////
214 | //
215 | // Function: CLabel::OnPaint
216 | //
217 | // Description: Handles all the drawing code for the label
218 | //
219 | // INPUTS:
220 | //
221 | // RETURNS:
222 | //
223 | // NOTES: Called by Windows... not by USER
224 | // Probably needs tiding up a some point.
225 | // Different states will require this code to be reworked.
226 | //
227 | //
228 | // MODIFICATIONS:
229 | //
230 | // Name Date Version Comments
231 | // NT ALMOND 22/10/98 1.0 Origin
232 | // NT ALMOND 15092000 1.5 Handle Check
233 | // NT ALMOND 15092000 1.5 Alignment mods
234 | // NT ALMOND 15092000 1.5 Gradient Fill Mode
235 | // NT ALMOND 02072002 1.6 Fill SelectObject bugs
236 | // NT ALMOND 02072002 1.6 Added to expand tabs
237 | //////////////////////////////////////////////////////////////////////////
238 |
239 | void CLabel::OnPaint()
240 | {
241 | CPaintDC dc(this); // device context for painting
242 |
243 | DWORD dwFlags = 0;
244 |
245 | CRect rc;
246 | GetClientRect(rc);
247 | CString strText;
248 | GetWindowText(strText);
249 | CBitmap bmp;
250 |
251 |
252 | ///////////////////////////////////////////////////////
253 | //
254 | // Set up for double buffering...
255 | //
256 | CDC* pDCMem;
257 | CBitmap* pOldBitmap = NULL;
258 |
259 | if (!m_bTransparent)
260 | {
261 | pDCMem = new CDC;
262 | pDCMem->CreateCompatibleDC(&dc);
263 | bmp.CreateCompatibleBitmap(&dc,rc.Width(),rc.Height());
264 | pOldBitmap = pDCMem->SelectObject(&bmp);
265 | }
266 | else
267 | {
268 | pDCMem = &dc;
269 | }
270 |
271 | UINT nMode = pDCMem->SetBkMode(TRANSPARENT);
272 |
273 |
274 | COLORREF crText = pDCMem->SetTextColor(m_crText);
275 | CFont *pOldFont = pDCMem->SelectObject(&m_font);
276 |
277 |
278 | // Fill in backgound if not transparent
279 | if (!m_bTransparent)
280 | {
281 | if (m_fillmode == Normal)
282 | {
283 | CBrush br;
284 |
285 | if (m_hBackBrush != NULL)
286 | br.Attach(m_hBackBrush);
287 | else
288 | br.Attach(m_hwndBrush);
289 |
290 | pDCMem->FillRect(rc,&br);
291 |
292 | br.Detach();
293 | }
294 | else // Gradient Fill
295 | {
296 | DrawGradientFill(pDCMem, &rc, m_crLoColor, m_crHiColor, 100);
297 | }
298 |
299 | }
300 |
301 |
302 | // If the text is flashing turn the text color on
303 | // then to the color of the window background.
304 |
305 | LOGBRUSH lb;
306 | ZeroMemory(&lb,sizeof(lb));
307 |
308 | // Stop Checking complaining
309 | if (m_hBackBrush)
310 | ::GetObject(m_hBackBrush,sizeof(lb),&lb);
311 |
312 |
313 | // Something to do with flashing
314 | if (!m_bState && m_Type == Text)
315 | pDCMem->SetTextColor(lb.lbColor);
316 |
317 | DWORD style = GetStyle();
318 |
319 | switch (style & SS_TYPEMASK)
320 | {
321 | case SS_RIGHT:
322 | dwFlags = DT_RIGHT | DT_WORDBREAK;
323 | break;
324 |
325 | case SS_CENTER:
326 | dwFlags = SS_CENTER | DT_WORDBREAK;
327 | break;
328 |
329 | case SS_LEFTNOWORDWRAP:
330 | dwFlags = DT_LEFT;
331 | break;
332 |
333 | default: // treat other types as left
334 | case SS_LEFT:
335 | dwFlags = DT_LEFT | DT_WORDBREAK;
336 | break;
337 | }
338 |
339 |
340 | // Added to expand tabs...
341 | if(strText.Find(_T('\t')) != -1)
342 | dwFlags |= DT_EXPANDTABS;
343 |
344 | // If the text centered make an assumtion that
345 | // the will want to center verticly as well
346 | if (style & SS_CENTERIMAGE)
347 | {
348 | dwFlags = DT_CENTER;
349 |
350 | // Apply
351 | if (strText.Find(_T("\r\n")) == -1)
352 | {
353 | dwFlags |= DT_VCENTER;
354 |
355 | // And because DT_VCENTER only works with single lines
356 | dwFlags |= DT_SINGLELINE;
357 | }
358 |
359 | }
360 |
361 | //
362 | // 3333 DDDDD
363 | // 3 D D
364 | // 33 D D E F X
365 | // 3 D D
366 | // 3333 DDDDD
367 | //
368 | //
369 | if (m_bRotation)
370 | {
371 | int nAlign = pDCMem->SetTextAlign (TA_BASELINE);
372 |
373 | CPoint pt;
374 | GetViewportOrgEx (pDCMem->m_hDC,&pt) ;
375 | SetViewportOrgEx (pDCMem->m_hDC,rc.Width() / 2, rc.Height() / 2, NULL) ;
376 | pDCMem->TextOut (0, 0, strText) ;
377 | SetViewportOrgEx (pDCMem->m_hDC,pt.x / 2, pt.y / 2, NULL) ;
378 | pDCMem->SetTextAlign (nAlign);
379 | }
380 | else
381 | {
382 | pDCMem->DrawText(strText,rc,dwFlags);
383 | if (m_bFont3d)
384 | {
385 | pDCMem->SetTextColor(m_cr3DHiliteColor);
386 |
387 | if (m_3dType == Raised)
388 | rc.OffsetRect(-1,-1);
389 | else
390 | rc.OffsetRect(1,1);
391 |
392 | pDCMem->DrawText(strText,rc,dwFlags);
393 | m_3dType;
394 |
395 | }
396 | }
397 |
398 | // Restore DC's State
399 | pDCMem->SetBkMode(nMode);
400 | pDCMem->SelectObject(pOldFont);
401 | pDCMem->SetTextColor(crText);
402 |
403 | if (!m_bTransparent)
404 | {
405 | dc.BitBlt(0,0,rc.Width(),rc.Height(),pDCMem,0,0,SRCCOPY);
406 | // continue DC restore
407 | pDCMem->SelectObject ( pOldBitmap ) ;
408 | delete pDCMem;
409 | }
410 | }
411 |
412 |
413 | //////////////////////////////////////////////////////////////////////////
414 | //
415 | // Function: CLabel::OnTimer
416 | //
417 | // Description: Used in conjunction with 'FLASH' functions
418 | //
419 | // INPUTS: Windows API
420 | //
421 | // RETURNS: Windows API
422 | //
423 | // NOTES:
424 | //
425 | // MODIFICATIONS:
426 | //
427 | // Name Date Version Comments
428 | // NT ALMOND 26/08/98 1.0 Origin
429 | //
430 | //////////////////////////////////////////////////////////////////////////
431 | void CLabel::OnTimer(UINT nIDEvent)
432 | {
433 |
434 | m_bState = !m_bState;
435 |
436 | UpdateSurface();
437 |
438 | CStatic::OnTimer(nIDEvent);
439 | }
440 |
441 | //////////////////////////////////////////////////////////////////////////
442 | //
443 | // Function: CLabel::OnSetCursor
444 | //
445 | // Description: Used in conjunction with 'LINK' function
446 | //
447 | // INPUTS: Windows API
448 | //
449 | // RETURNS: Windows API
450 | //
451 | // NOTES:
452 | //
453 | // MODIFICATIONS:
454 | //
455 | // Name Date Version Comments
456 | // NT ALMOND 26/08/98 1.0 Origin
457 | //
458 | //////////////////////////////////////////////////////////////////////////
459 | BOOL CLabel::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
460 | {
461 |
462 | if (m_hCursor)
463 | {
464 | ::SetCursor(m_hCursor);
465 | return TRUE;
466 | }
467 |
468 | return CStatic::OnSetCursor(pWnd, nHitTest, message);
469 | }
470 |
471 | //////////////////////////////////////////////////////////////////////////
472 | //
473 | // Function: CLabel::OnLButtonDown
474 | //
475 | // Description: Called when a link is click on
476 | //
477 | // INPUTS: Windows API
478 | //
479 | // RETURNS: Windows API
480 | //
481 | // NOTES:
482 | //
483 | // MODIFICATIONS:
484 | //
485 | // Name Date Version Comments
486 | // NT ALMOND 26/08/98 1.0 Origin
487 | // NT ALMOND 02072002 1.6 Added Mail support
488 | //////////////////////////////////////////////////////////////////////////
489 | void CLabel::OnLButtonDown(UINT nFlags, CPoint point)
490 | {
491 |
492 | if (!m_bNotifyParent) // Fix
493 | {
494 | CString strLink;
495 |
496 | GetWindowText(strLink);
497 | if (m_Link == HyperLink)
498 | {
499 | ShellExecute(NULL,_T("open"),m_sLink.IsEmpty() ? strLink : m_sLink,NULL,NULL,SW_SHOWNORMAL);
500 | }
501 | if (m_Link == MailLink)
502 | {
503 | strLink = _T("mailto:") + strLink;
504 | ShellExecute( NULL, NULL, strLink, NULL, NULL, SW_SHOWNORMAL );
505 | }
506 | }
507 | else
508 | {
509 | // To use notification in parent window
510 | // Respond to a OnNotify in parent and disassemble the message
511 | //
512 | NMHDR nm;
513 |
514 | nm.hwndFrom = GetSafeHwnd();
515 | nm.idFrom = GetDlgCtrlID();
516 | nm.code = NM_LINKCLICK;
517 | GetParent()->SendMessage(WM_NOTIFY,nm.idFrom,(LPARAM) &nm);
518 | }
519 |
520 | CStatic::OnLButtonDown(nFlags, point);
521 | }
522 |
523 | //////////////////////////////////////////////////////////////////////////
524 | //////////////////////////////////////////////////////////////////////////
525 | // THE FUNCTIONS START HERE :----
526 | //////////////////////////////////////////////////////////////////////////
527 | //////////////////////////////////////////////////////////////////////////
528 |
529 | //////////////////////////////////////////////////////////////////////////
530 | //
531 | // Function: CLabel::SetText
532 | //
533 | // Description: Short cut to set window text - caption - label
534 | //
535 | // INPUTS: Text to use
536 | //
537 | // RETURNS: Reference to this
538 | //
539 | // NOTES:
540 | //
541 | // MODIFICATIONS:
542 | //
543 | // Name Date Version Comments
544 | // NT ALMOND 26081998 1.0 Origin
545 | // NT ALMOND 02072002 1.6 Crash Fix
546 | //////////////////////////////////////////////////////////////////////////
547 | CLabel& CLabel::SetText(const CString& strText)
548 | {
549 | if(IsWindow(this->GetSafeHwnd()))
550 | {
551 | SetWindowText(strText);
552 | UpdateSurface();
553 | }
554 |
555 | return *this;
556 | }
557 |
558 | //////////////////////////////////////////////////////////////////////////
559 | //
560 | // Function: CLabel::SetTextColor
561 | //
562 | // Description: Sets the text color
563 | //
564 | // INPUTS: True or false
565 | //
566 | // RETURNS: Reference to 'this' object
567 | //
568 | // NOTES:
569 | //
570 | // MODIFICATIONS:
571 | //
572 | // Name Date Version Comments
573 | // NT ALMOND 22/10/98 1.0 Origin
574 | //
575 | //////////////////////////////////////////////////////////////////////////
576 | CLabel& CLabel::SetTextColor(COLORREF crText)
577 | {
578 |
579 | m_crText = crText;
580 |
581 | UpdateSurface();
582 | return *this;
583 | }
584 |
585 | //////////////////////////////////////////////////////////////////////////
586 | //
587 | // Function: CLabel::SetFontBold
588 | //
589 | // Description: Sets the font ot bold
590 | //
591 | // INPUTS: True or false
592 | //
593 | // RETURNS: Reference to 'this' object
594 | //
595 | // NOTES:
596 | //
597 | // MODIFICATIONS:
598 | //
599 | // Name Date Version Comments
600 | // NT ALMOND 22/10/98 1.0 Origin
601 | //
602 | //////////////////////////////////////////////////////////////////////////
603 | CLabel& CLabel::SetFontBold(BOOL bBold)
604 | {
605 |
606 | m_lf.lfWeight = bBold ? FW_BOLD : FW_NORMAL;
607 | ReconstructFont();
608 | UpdateSurface();
609 | return *this;
610 | }
611 |
612 |
613 |
614 | //////////////////////////////////////////////////////////////////////////
615 | //
616 | // Function: CLabel::SetFontUnderline
617 | //
618 | // Description: Sets font underline attribue
619 | //
620 | // INPUTS: True of false
621 | //
622 | // RETURNS: Reference to 'this' object
623 | //
624 | // NOTES:
625 | //
626 | // MODIFICATIONS:
627 | //
628 | // Name Date Version Comments
629 | // NT ALMOND 26/08/98 1.0 Origin
630 | //
631 | //////////////////////////////////////////////////////////////////////////
632 | CLabel& CLabel::SetFontUnderline(BOOL bSet)
633 | {
634 | m_lf.lfUnderline = bSet;
635 | ReconstructFont();
636 | UpdateSurface();
637 |
638 | return *this;
639 | }
640 |
641 | //////////////////////////////////////////////////////////////////////////
642 | //
643 | // Function: CLabel::SetFontItalic
644 | //
645 | // Description: Sets font italic attribute
646 | //
647 | // INPUTS: True of false
648 | //
649 | // RETURNS: Reference to 'this' object
650 | //
651 | // NOTES:
652 | //
653 | // MODIFICATIONS:
654 | //
655 | // Name Date Version Comments
656 | // NT ALMOND 26/08/98 1.0 Origin
657 | //
658 | //////////////////////////////////////////////////////////////////////////
659 | CLabel& CLabel::SetFontItalic(BOOL bSet)
660 | {
661 |
662 | m_lf.lfItalic = bSet;
663 | ReconstructFont();
664 | UpdateSurface();
665 |
666 | return *this;
667 | }
668 |
669 | //////////////////////////////////////////////////////////////////////////
670 | //
671 | // Function: CLabel::SetSunken
672 | //
673 | // Description: Sets sunken effect on border
674 | //
675 | // INPUTS: True of false
676 | //
677 | // RETURNS: Reference to 'this' object
678 | //
679 | // NOTES:
680 | //
681 | // MODIFICATIONS:
682 | //
683 | // Name Date Version Comments
684 | // NT ALMOND 26/08/98 1.0 Origin
685 | //
686 | //////////////////////////////////////////////////////////////////////////
687 | CLabel& CLabel::SetSunken(BOOL bSet)
688 | {
689 |
690 | if (!bSet)
691 | ModifyStyleEx(WS_EX_STATICEDGE,0,SWP_DRAWFRAME);
692 | else
693 | ModifyStyleEx(0,WS_EX_STATICEDGE,SWP_DRAWFRAME);
694 |
695 | return *this;
696 | }
697 |
698 | //////////////////////////////////////////////////////////////////////////
699 | //
700 | // Function: CLabel::SetBorder
701 | //
702 | // Description: Toggles the border on/off
703 | //
704 | // INPUTS: True of false
705 | //
706 | // RETURNS: Reference to 'this' object
707 | //
708 | // NOTES:
709 | //
710 | // MODIFICATIONS:
711 | //
712 | // Name Date Version Comments
713 | // NT ALMOND 26/08/98 1.0 Origin
714 | //
715 | //////////////////////////////////////////////////////////////////////////
716 | CLabel& CLabel::SetBorder(BOOL bSet)
717 | {
718 |
719 | if (!bSet)
720 | ModifyStyle(WS_BORDER,0,SWP_DRAWFRAME);
721 | else
722 | ModifyStyle(0,WS_BORDER,SWP_DRAWFRAME);
723 |
724 | return *this;
725 | }
726 |
727 | //////////////////////////////////////////////////////////////////////////
728 | //
729 | // Function: CLabel::SetFontSize
730 | //
731 | // Description: Sets the font size
732 | //
733 | // INPUTS: True of false
734 | //
735 | // RETURNS: Reference to 'this' object
736 | //
737 | // NOTES:
738 | //
739 | // MODIFICATIONS:
740 | //
741 | // Name Date Version Comments
742 | // NT ALMOND 26/08/98 1.0 Origin
743 | //
744 | //////////////////////////////////////////////////////////////////////////
745 | CLabel& CLabel::SetFontSize(int nSize)
746 | {
747 |
748 | CFont cf;
749 | LOGFONT lf;
750 |
751 | cf.CreatePointFont(nSize * 10, m_lf.lfFaceName);
752 | cf.GetLogFont(&lf);
753 |
754 | m_lf.lfHeight = lf.lfHeight;
755 | m_lf.lfWidth = lf.lfWidth;
756 |
757 | // nSize*=-1;
758 | // m_lf.lfHeight = nSize;
759 | ReconstructFont();
760 | UpdateSurface();
761 |
762 | return *this;
763 | }
764 |
765 |
766 | //////////////////////////////////////////////////////////////////////////
767 | //
768 | // Function: CLabel::SetBkColor
769 | //
770 | // Description: Sets background color
771 | //
772 | // INPUTS: Colorref of background color
773 | //
774 | // RETURNS: Reference to 'this' object
775 | //
776 | // NOTES:
777 | //
778 | // MODIFICATIONS:
779 | //
780 | // Name Date Version Comments
781 | // NT ALMOND 26/08/98 1.0 Origin
782 | //
783 | //////////////////////////////////////////////////////////////////////////
784 | CLabel& CLabel::SetBkColor(COLORREF crBkgnd, COLORREF crBkgndHigh , BackFillMode mode)
785 | {
786 |
787 | m_crLoColor = crBkgnd;
788 | m_crHiColor = crBkgndHigh;
789 |
790 | m_fillmode = mode;
791 |
792 | if (m_hBackBrush)
793 | ::DeleteObject(m_hBackBrush);
794 |
795 |
796 | if (m_fillmode == Normal)
797 | m_hBackBrush = ::CreateSolidBrush(crBkgnd);
798 |
799 | UpdateSurface();
800 |
801 | return *this;
802 | }
803 |
804 | //////////////////////////////////////////////////////////////////////////
805 | //
806 | // Function: CLabel::SetFontName
807 | //
808 | // Description: Sets the fonts face name
809 | //
810 | // INPUTS: String containing font name
811 | //
812 | // RETURNS: Reference to 'this' object
813 | //
814 | // NOTES:
815 | //
816 | // MODIFICATIONS:
817 | //
818 | // Name Date Version Comments
819 | // NT ALMOND 26/08/98 1.0 Origin
820 | // NT ALMOND 15092000 1.5 Support internation windows
821 | //////////////////////////////////////////////////////////////////////////
822 | CLabel& CLabel::SetFontName(const CString& strFont, BYTE byCharSet /* Default = ANSI_CHARSET */)
823 | {
824 |
825 | m_lf.lfCharSet = byCharSet;
826 |
827 | _tcscpy(m_lf.lfFaceName,strFont);
828 | ReconstructFont();
829 | UpdateSurface();
830 |
831 | return *this;
832 | }
833 |
834 | //////////////////////////////////////////////////////////////////////////
835 | //
836 | // Function: CLabel::FlashText
837 | //
838 | // Description: As the function states
839 | //
840 | // INPUTS: True or false
841 | //
842 | // RETURNS: Reference to 'this' object
843 | //
844 | // NOTES:
845 | //
846 | // MODIFICATIONS:
847 | //
848 | // Name Date Version Comments
849 | // NT ALMOND 26/08/98 1.0 Origin
850 | //
851 | //////////////////////////////////////////////////////////////////////////
852 | CLabel& CLabel::FlashText(BOOL bActivate)
853 | {
854 |
855 | if (m_bTimer)
856 | KillTimer(1);
857 |
858 | if (bActivate)
859 | {
860 | m_bState = FALSE;
861 |
862 | m_bTimer = TRUE;
863 |
864 | SetTimer(1,500,NULL);
865 |
866 | m_Type = Text;
867 | }
868 | else
869 | m_Type = None; // Fix
870 |
871 | return *this;
872 | }
873 |
874 | //////////////////////////////////////////////////////////////////////////
875 | //
876 | // Function: CLabel::FlashBackground
877 | //
878 | // Description: As the function states
879 | //
880 | // INPUTS: True or false
881 | //
882 | // RETURNS: Reference to 'this' object
883 | //
884 | // NOTES:
885 | //
886 | // MODIFICATIONS:
887 | //
888 | // Name Date Version Comments
889 | // NT ALMOND 26/08/98 1.0 Origin
890 | //
891 | //////////////////////////////////////////////////////////////////////////
892 | CLabel& CLabel::FlashBackground(BOOL bActivate)
893 | {
894 |
895 | if (m_bTimer)
896 | KillTimer(1);
897 |
898 | if (bActivate)
899 | {
900 | m_bState = FALSE;
901 |
902 | m_bTimer = TRUE;
903 | SetTimer(1,500,NULL);
904 |
905 | m_Type = Background;
906 | }
907 |
908 | return *this;
909 | }
910 |
911 |
912 | //////////////////////////////////////////////////////////////////////////
913 | //
914 | // Function: CLabel::SetLink
915 | //
916 | // Description: Indicates the string is a link
917 | //
918 | // INPUTS: True or false
919 | //
920 | // RETURNS: Reference to 'this' object
921 | //
922 | // NOTES:
923 | //
924 | // MODIFICATIONS:
925 | //
926 | // Name Date Version Comments
927 | // NT ALMOND 26/08/98 1.0 Origin
928 | // NT ALMOND 26/08/99 1.2 Added flexbility of
929 | // Sending Click meessage to parent
930 | //
931 | //////////////////////////////////////////////////////////////////////////
932 | CLabel& CLabel::SetLink(BOOL bLink,BOOL bNotifyParent)
933 | {
934 |
935 | if (bLink)
936 | m_Link = HyperLink;
937 | else
938 | m_Link = LinkNone;
939 |
940 | m_bNotifyParent = bNotifyParent;
941 |
942 | if (m_Link != LinkNone)
943 | ModifyStyle(0,SS_NOTIFY);
944 | else
945 | ModifyStyle(SS_NOTIFY,0);
946 |
947 |
948 |
949 | return *this;
950 | }
951 |
952 | //////////////////////////////////////////////////////////////////////////
953 | //
954 | // Function: CLabel::SetLinkCursor
955 | //
956 | // Description: Sets the internet browers link
957 | //
958 | // INPUTS: Handle of cursor
959 | //
960 | // RETURNS: Reference to 'this' object
961 | //
962 | // NOTES:
963 | //
964 | // MODIFICATIONS:
965 | //
966 | // Name Date Version Comments
967 | // NT ALMOND 26/08/98 1.0 Origin
968 | //
969 | //////////////////////////////////////////////////////////////////////////
970 | CLabel& CLabel::SetLinkCursor(HCURSOR hCursor)
971 | {
972 |
973 | m_hCursor = hCursor;
974 | return *this;
975 | }
976 |
977 | //////////////////////////////////////////////////////////////////////////
978 | //
979 | // Function: CLabel::SetTransparent
980 | //
981 | // Description: Sets the Label window to be transpaent
982 | //
983 | // INPUTS: True or false
984 | //
985 | // RETURNS: Reference to 'this' object
986 | //
987 | // NOTES:
988 | //
989 | // MODIFICATIONS:
990 | //
991 | // Name Date Version Comments
992 | // NT ALMOND 22/10/98 1.0 Origin
993 | //
994 | //////////////////////////////////////////////////////////////////////////
995 | CLabel& CLabel::SetTransparent(BOOL bSet)
996 | {
997 |
998 | m_bTransparent = bSet;
999 | ModifyStyleEx(0,WS_EX_TRANSPARENT); // Fix for transparency
1000 | UpdateSurface();
1001 |
1002 | return *this;
1003 | }
1004 |
1005 | //////////////////////////////////////////////////////////////////////////
1006 | //
1007 | // Function: CLabel::SetFont3D
1008 | //
1009 | // Description: Sets the 3D attribute of the font.
1010 | //
1011 | // INPUTS: True or false, Raised or Sunken
1012 | //
1013 | // RETURNS: Reference to 'this' object
1014 | //
1015 | // NOTES:
1016 | //
1017 | // MODIFICATIONS:
1018 | //
1019 | // Name Date Version Comments
1020 | // NT ALMOND 22/10/98 1.0 Origin
1021 | //
1022 | //////////////////////////////////////////////////////////////////////////
1023 | CLabel& CLabel::SetFont3D(BOOL bSet,Type3D type)
1024 | {
1025 |
1026 | m_bFont3d = bSet;
1027 | m_3dType = type;
1028 | UpdateSurface();
1029 |
1030 |
1031 | return *this;
1032 | }
1033 |
1034 | void CLabel::OnSysColorChange()
1035 | {
1036 |
1037 | if (m_hwndBrush)
1038 | ::DeleteObject(m_hwndBrush);
1039 |
1040 | m_hwndBrush = ::CreateSolidBrush(GetSysColor(COLOR_3DFACE));
1041 |
1042 | UpdateSurface();
1043 |
1044 |
1045 | }
1046 |
1047 |
1048 |
1049 | //////////////////////////////////////////////////////////////////////////
1050 | //
1051 | // Function: CLabel::SetRotationAngle
1052 | //
1053 | // Description: Sets the rotation angle for the current font.
1054 | //
1055 | // INPUTS: Angle in Degress
1056 | //
1057 | // RETURNS: Reference to 'this' object
1058 | //
1059 | // NOTES:
1060 | //
1061 | // MODIFICATIONS:
1062 | //
1063 | // Name Date Version Comments
1064 | // NT ALMOND 22/10/98 1.0 Origin
1065 | //
1066 | //////////////////////////////////////////////////////////////////////////
1067 | CLabel& CLabel::SetRotationAngle(UINT nAngle,BOOL bRotation)
1068 | {
1069 | // Arrrrh...
1070 | // Your looking in here why the font is rotating, aren't you?
1071 | // Well try setting the font name to 'Arial' or 'Times New Roman'
1072 | // Make the Angle 180 and set bRotation to true.
1073 | //
1074 | // Font rotation _ONLY_ works with TrueType fonts...
1075 | //
1076 | //
1077 | m_lf.lfEscapement = m_lf.lfOrientation = (nAngle * 10);
1078 | m_bRotation = bRotation;
1079 |
1080 | ReconstructFont();
1081 |
1082 | UpdateSurface();
1083 |
1084 |
1085 | return *this;
1086 | }
1087 |
1088 | //////////////////////////////////////////////////////////////////////////
1089 | //
1090 | // Function: CLabel::SetText3DHiliteColor
1091 | //
1092 | // Description: Sets the 3D font hilite color
1093 | //
1094 | // INPUTS: Color
1095 | //
1096 | // RETURNS: Reference to 'this' object
1097 | //
1098 | // NOTES:
1099 | //
1100 | // MODIFICATIONS:
1101 | //
1102 | // Name Date Version Comments
1103 | // NT ALMOND 17/07/00 1.0 Origin
1104 | //
1105 | //////////////////////////////////////////////////////////////////////////
1106 | CLabel& CLabel::SetText3DHiliteColor(COLORREF cr3DHiliteColor)
1107 | {
1108 | m_cr3DHiliteColor = cr3DHiliteColor;
1109 | UpdateSurface();
1110 |
1111 |
1112 | return *this;
1113 | }
1114 |
1115 |
1116 | //////////////////////////////////////////////////////////////////////////
1117 | //
1118 | // Function: CLabel::PreSubclassWindow
1119 | //
1120 | // Description: Assigns default dialog font
1121 | //
1122 | // INPUTS:
1123 | //
1124 | // RETURNS:
1125 | //
1126 | // NOTES:
1127 | //
1128 | // MODIFICATIONS:
1129 | //
1130 | // Name Date Version Comments
1131 | // NT ALMOND 15092000 1.5 Origin
1132 | // NT ALMOND 02072002 1.6 Fix crash when GetFont returns NULL
1133 | //////////////////////////////////////////////////////////////////////////
1134 | void CLabel::PreSubclassWindow()
1135 | {
1136 |
1137 | CStatic::PreSubclassWindow();
1138 |
1139 | CFont* cf = GetFont();
1140 | if(cf !=NULL)
1141 | {
1142 | cf->GetObject(sizeof(m_lf),&m_lf);
1143 | }
1144 | else
1145 | {
1146 | GetObject(GetStockObject(SYSTEM_FONT),sizeof(m_lf),&m_lf);
1147 | }
1148 |
1149 | ReconstructFont();
1150 |
1151 | }
1152 |
1153 | //////////////////////////////////////////////////////////////////////////
1154 | //
1155 | // Function: CLabel::PreCreateWindow
1156 | //
1157 | // Description:
1158 | //
1159 | // INPUTS:
1160 | //
1161 | // RETURNS:
1162 | //
1163 | // NOTES:
1164 | //
1165 | // MODIFICATIONS:
1166 | //
1167 | // Name Date Version Comments
1168 | // NT ALMOND 15092000 1.5 Origin
1169 | //////////////////////////////////////////////////////////////////////////
1170 | BOOL CLabel::PreCreateWindow(CREATESTRUCT& cs)
1171 | {
1172 | return CStatic::PreCreateWindow(cs);
1173 | }
1174 |
1175 | //////////////////////////////////////////////////////////////////////////
1176 | //
1177 | // Function: CLabel::DrawGradientFill
1178 | //
1179 | // Description: Internal help function to gradient fill background
1180 | //
1181 | // INPUTS:
1182 | //
1183 | // RETURNS:
1184 | //
1185 | // NOTES:
1186 | //
1187 | // MODIFICATIONS:
1188 | //
1189 | // Name Date Version Comments
1190 | // NT ALMOND 15092000 1.5 Origin
1191 | //////////////////////////////////////////////////////////////////////////
1192 | void CLabel::DrawGradientFill(CDC* pDC, CRect* pRect, COLORREF crStart, COLORREF crEnd, int nSegments)
1193 | {
1194 | // Get the starting RGB values and calculate the incremental
1195 | // changes to be applied.
1196 |
1197 | COLORREF cr;
1198 | int nR = GetRValue(crStart);
1199 | int nG = GetGValue(crStart);
1200 | int nB = GetBValue(crStart);
1201 |
1202 | int neB = GetBValue(crEnd);
1203 | int neG = GetGValue(crEnd);
1204 | int neR = GetRValue(crEnd);
1205 |
1206 | if(nSegments > pRect->Width())
1207 | nSegments = pRect->Width();
1208 |
1209 | int nDiffR = (neR - nR);
1210 | int nDiffG = (neG - nG);
1211 | int nDiffB = (neB - nB);
1212 |
1213 | int ndR = 256 * (nDiffR) / (max(nSegments,1));
1214 | int ndG = 256 * (nDiffG) / (max(nSegments,1));
1215 | int ndB = 256 * (nDiffB) / (max(nSegments,1));
1216 |
1217 | nR *= 256;
1218 | nG *= 256;
1219 | nB *= 256;
1220 |
1221 | neR *= 256;
1222 | neG *= 256;
1223 | neB *= 256;
1224 |
1225 | int nCX = pRect->Width() / max(nSegments,1), nLeft = pRect->left, nRight;
1226 | pDC->SelectStockObject(NULL_PEN);
1227 |
1228 | for (int i = 0; i < nSegments; i++, nR += ndR, nG += ndG, nB += ndB)
1229 | {
1230 | // Use special code for the last segment to avoid any problems
1231 | // with integer division.
1232 |
1233 | if (i == (nSegments - 1))
1234 | nRight = pRect->right;
1235 | else
1236 | nRight = nLeft + nCX;
1237 |
1238 | cr = RGB(nR / 256, nG / 256, nB / 256);
1239 |
1240 | {
1241 | CBrush br(cr);
1242 | CBrush* pbrOld = pDC->SelectObject(&br);
1243 | pDC->Rectangle(nLeft, pRect->top, nRight + 1, pRect->bottom);
1244 | pDC->SelectObject(pbrOld);
1245 | }
1246 |
1247 | // Reset the left side of the drawing rectangle.
1248 |
1249 | nLeft = nRight;
1250 | }
1251 | }
1252 |
1253 |
1254 | //////////////////////////////////////////////////////////////////////////
1255 | //
1256 | // Function: CLabel::SetFont
1257 | //
1258 | // Description: Sets font with LOGFONT structure
1259 | //
1260 | // INPUTS:
1261 | //
1262 | // RETURNS:
1263 | //
1264 | // NOTES:
1265 | //
1266 | // MODIFICATIONS:
1267 | //
1268 | // Name Date Version Comments
1269 | // NT ALMOND 02072002 1.6 Origin
1270 | //////////////////////////////////////////////////////////////////////////
1271 | CLabel& CLabel::SetFont(LOGFONT lf)
1272 | {
1273 | CopyMemory(&m_lf, &lf, sizeof(m_lf));
1274 | ReconstructFont();
1275 | UpdateSurface();
1276 | return *this;
1277 |
1278 | }
1279 |
1280 | BOOL CLabel::OnEraseBkgnd(CDC* pDC)
1281 | {
1282 | // TODO: Add your message handler code here and/or call default
1283 |
1284 | return TRUE;
1285 | }
1286 |
1287 | //////////////////////////////////////////////////////////////////////////
1288 | //
1289 | // Function: CLabel::SetMailLink
1290 | //
1291 | // Description: Sets the label so it becomes Mail enabled
1292 | //
1293 | // INPUTS:
1294 | //
1295 | // RETURNS:
1296 | //
1297 | // NOTES:
1298 | //
1299 | // MODIFICATIONS:
1300 | //
1301 | // Name Date Version Comments
1302 | // NT ALMOND 02072002 1.6 Origin
1303 | //////////////////////////////////////////////////////////////////////////
1304 | CLabel& CLabel::SetMailLink(BOOL bEnable, BOOL bNotifyParent)
1305 | {
1306 | if (bEnable)
1307 | m_Link = MailLink;
1308 | else
1309 | m_Link = LinkNone;
1310 |
1311 |
1312 | m_bNotifyParent = bNotifyParent;
1313 |
1314 | if (m_Link != LinkNone)
1315 | ModifyStyle(0,SS_NOTIFY);
1316 | else
1317 | ModifyStyle(SS_NOTIFY,0);
1318 |
1319 | return *this;
1320 | }
1321 |
1322 | //////////////////////////////////////////////////////////////////////////
1323 | //
1324 | // Function: CLabel::SetHyperLink
1325 | //
1326 | // Description: Sets the label so it becomes hyperlink enabled
1327 | //
1328 | // INPUTS:
1329 | //
1330 | // RETURNS:
1331 | //
1332 | // NOTES:
1333 | //
1334 | // MODIFICATIONS:
1335 | //
1336 | // Name Date Version Comments
1337 | // NT ALMOND 02072002 1.6 Origin
1338 | //////////////////////////////////////////////////////////////////////////
1339 | CLabel& CLabel::SetHyperLink(const CString& sLink)
1340 | {
1341 | m_sLink = sLink;
1342 |
1343 | return *this;
1344 | }
1345 |
--------------------------------------------------------------------------------