// MFCLogerDlg.cpp: 实现文件
//
#include "pch.h"
#include "framework.h"
#include "MFCLoger.h"
#include "MFCLogerDlg.h"
#include "afxdialogex.h"
#include <fstream>
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
static UINT BASED_CODE indicators[] = { ID_INDICSTOR_LINE,ID_INDICSTOR_NOTCONNECT };
CMFCLogerDlg::CMFCLogerDlg(CWnd* pParent /*=nullptr*/)
: CDialogEx(IDD_MFCLOGER_DIALOG, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
mIsLogerStop = false;
mhasConnect = false;
}
CMFCLogerDlg::~CMFCLogerDlg()
{
mIsLogerStop = true;
mhasConnect = false;
if (mhFileConfig)
{
CloseHandle(mhFileConfig);
mhFileConfig = NULL;
}
if (mhLogerReadEvent)
{
CloseHandle(mhLogerReadEvent);
mhLogerReadEvent = NULL;
}
if (mhLogerActiveEvent)
{
CloseHandle(mhLogerActiveEvent);
mhLogerActiveEvent = NULL;
}
if (g_hLogerReadThread)
{
CloseHandle(g_hLogerReadThread);
g_hLogerReadThread = NULL;
}
if (g_hLogerActiveThread)
{
CloseHandle(g_hLogerActiveThread);
g_hLogerActiveThread = NULL;
}
if (mhMemShareMutex)
{
CloseHandle(mhMemShareMutex);
mhMemShareMutex = NULL;
}
if (mhLogerMemShareMap)
{
LPVOID pDataView = MapViewOfFile(mhLogerMemShareMap, SECTION_MAP_WRITE, 0, 0, MAP_LOGER_DATA_SIZE);
if (pDataView)
{ //清空共享内存,保证所有共享内存的其他进程能安全退出
ZeroMemory(pDataView, MAP_LOGER_DATA_SIZE);
::UnmapViewOfFile(pDataView);
}
CloseHandle(mhLogerMemShareMap);
mhLogerMemShareMap = NULL;
}
}
void CMFCLogerDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Control(pDX, IDC_EDIT_SERVERLOGER, mServerLogEdit);
}
BEGIN_MESSAGE_MAP(CMFCLogerDlg, CDialogEx)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_BUTTON_CLEAR, &CMFCLogerDlg::OnBnClickedButtonClear)
ON_BN_CLICKED(IDC_BTN_SAVELOG, &CMFCLogerDlg::OnBnClickedBtnSavelog)
ON_EN_CHANGE(IDC_EDIT_SERVERLOGER, &CMFCLogerDlg::OnEnChangeEditServerloger)
END_MESSAGE_MAP()
DWORD CMFCLogerDlg::ListenLogerReadThreadProc(LPVOID lpParameter)
{
CMFCLogerDlg* dlg = (CMFCLogerDlg*)lpParameter;
char buffer[MAP_LOGER_DATA_SIZE] = { 0 };
CString logtext = TEXT("");
CString alltext = TEXT("");
while (!dlg->mIsLogerStop)
{
DWORD dwResult = WaitForSingleObject(dlg->mhLogerReadEvent, INFINITE);
if (dwResult != WAIT_OBJECT_0)break;
DoEnterCriticalSection(dlg->mhMemShareMutex);
LPVOID pDataView = MapViewOfFile(dlg->mhLogerMemShareMap, FILE_MAP_READ | SECTION_MAP_WRITE, 0, 0, MAP_LOGER_DATA_SIZE);
bool hasEvent = false;
if (pDataView)
{
hasEvent = true;
memset(buffer, 0, MAP_LOGER_DATA_SIZE);
memmove(buffer, (char*)pDataView, MAP_LOGER_DATA_SIZE);
ZeroMemory(pDataView, MAP_LOGER_DATA_SIZE);
::UnmapViewOfFile(pDataView);
}
ReleaseMutex(dlg->mhMemShareMutex);
if (hasEvent)
{
logtext = CString(buffer);
dlg->mServerLogEdit.GetWindowTextW(alltext);
if (alltext.GetLength() > 20000)//到达2万字符,则清空文本框
{
dlg->mServerLogEdit.SetWindowTextW(TEXT(""));
dlg->mServerLogEdit.Clear();
alltext.Empty();
}
alltext += logtext + TEXT("\r\n");
dlg->mServerLogEdit.SetWindowTextW(alltext);
dlg->mServerLogEdit.LineScroll(dlg->mServerLogEdit.GetLineCount(), 0);
}
}
return 0;
}
DWORD CMFCLogerDlg::ListenLogerActiveThreadProc(LPVOID lpParameter)
{
CMFCLogerDlg* dlg = (CMFCLogerDlg*)lpParameter;
while (!dlg->mIsLogerStop && dlg->mhLogerActiveEvent)
{
DWORD dwResult = WaitForSingleObject(dlg->mhLogerActiveEvent,500);//超时500毫秒
switch (dwResult)
{
case WAIT_OBJECT_0:
if (!dlg->mhasConnect)
{
dlg->mhasConnect = true;
::SendMessage(dlg->m_LogStatusBar.m_hWnd,SB_SETTEXT,1,(LPARAM)TEXT("有连接"));
::SendMessage(dlg->m_LogStatusBar.m_hWnd, SB_SETICON, TRUE, (LPARAM)
LoadIcon((HINSTANCE)GetWindowLongPtr(dlg->m_hWnd, GWLP_HINSTANCE),
MAKEINTRESOURCE(IDB_BITMAP1)));
CString conStr;
conStr.Format(TEXT("%s-有连接"), dlg->mMainTitle.GetBuffer());
dlg->SetWindowTextW(conStr);
}break;
case WAIT_TIMEOUT:
if (dlg->mhasConnect)
{
dlg->mhasConnect = false;
::SendMessage(dlg->m_LogStatusBar.m_hWnd, SB_SETTEXT, 1, (LPARAM)TEXT("没有连接"));
CString conStr;
conStr.Format(TEXT("%s - 没有连接"), dlg->mMainTitle);
dlg->SetWindowTextW(conStr);
}
break;
default:
break;
}
}
return 0;
}
bool CMFCLogerDlg::InitData()
{
wchar_t curDir[MAX_PATH] = { 0 };
GetCurrentDirectory(MAX_PATH, curDir);
wchar_t filename[MAX_PATH];
wsprintf(filename, TEXT("%s\\my.cfg"), curDir);
LoadConfig();
mhLogerMemShareMap = OpenFileMapping(FILE_MAP_READ | FILE_MAP_WRITE, 0, MAP_MEMSHARE_NAME);
if (!mhLogerMemShareMap)
{
mhLogerMemShareMap = ::CreateFileMapping(INVALID_HANDLE_VALUE,
NULL,
PAGE_READWRITE,
0,
MAP_LOGER_DATA_SIZE,
MAP_MEMSHARE_NAME);
if (!mhLogerMemShareMap)
{
return false;
}
LPVOID pDataView = MapViewOfFile(mhLogerMemShareMap, FILE_MAP_READ | SECTION_MAP_WRITE, 0, 0, MAP_LOGER_DATA_SIZE);
if (pDataView)
{//数据初始化时不用加锁
ZeroMemory(pDataView, MAP_LOGER_DATA_SIZE);
::UnmapViewOfFile(pDataView);
}
}
mhLogerReadEvent = OpenEvent(EVENT_MODIFY_STATE, FALSE, LOGER_EVENT_READ_NAME);
if (!mhLogerReadEvent)
{
mhLogerReadEvent = CreateEvent(NULL, FALSE, FALSE, LOGER_EVENT_READ_NAME);
if (!mhLogerReadEvent)
return FALSE;
}
mhLogerActiveEvent = OpenEvent(EVENT_MODIFY_STATE, FALSE, LOGER_EVENT_ACTIVE_NAME);
if (!mhLogerActiveEvent)
{
mhLogerActiveEvent = CreateEvent(NULL, FALSE, FALSE, LOGER_EVENT_ACTIVE_NAME);
if (!mhLogerActiveEvent)
return FALSE;
}
DWORD threadId;
g_hLogerReadThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ListenLogerReadThreadProc, this, 0, &threadId);
if (!g_hLogerReadThread) {
return FALSE;
}
threadId;
g_hLogerActiveThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ListenLogerActiveThreadProc, this, 0, &threadId);
if (!g_hLogerActiveThread) {
return FALSE;
}
return true;
}
void CMFCLogerDlg::LoadConfig()
{
}
void CMFCLogerDlg::SavaConfig()
{
}
// CMFCLogerDlg 消息处理程序
BOOL CMFCLogerDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != nullptr)
{
BOOL bNameValid;
CString strAboutMenu;
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
}
}
// 设置此对话框的图标。 当应用程序主窗口不是对话框时,框架将自动
// 执行此操作
SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, FALSE); // 设置小图标
mServerLogEdit.ShowScrollBar(SB_VERT, TRUE);
mServerLogEdit.ShowScrollBar(SB_HORZ, TRUE);
mMainTitle.LoadStringW(IDS_MAINTITLE);
m_LogStatusBar.Create(this);
m_LogStatusBar.SetIndicators(indicators, sizeof(indicators) / sizeof(UINT));
CRect rect,stateRect;
GetClientRect(&rect);
m_LogStatusBar.GetClientRect(stateRect);
m_LogStatusBar.MoveWindow(0,rect.bottom- stateRect.Height(),rect.right, stateRect.Height());
m_LogStatusBar.SetPaneInfo(0, ID_INDICSTOR_LINE, SBPS_NORMAL, rect.Width() - 100);
m_LogStatusBar.SetPaneInfo(1, ID_INDICSTOR_NOTCONNECT, SBPS_STRETCH, 100);
/*::SendMessage(m_LogStatusBar.m_hWnd, SB_SETICON, TRUE, (LPARAM)
LoadIcon((HINSTANCE)GetWindowLongPtr(m_hWnd, GWLP_HINSTANCE),
MAKEINTRESOURCE(IDI_NO_CONNECT)));*/
//m_LogStatusBar.SetIcon(0, AfxGetApp()->LoadIcon(IDI_GREEN));
RepositionBars(AFX_IDW_CONTROLBAR_FIRST, AFX_IDW_CONTROLBAR_LAST, ID_INDICSTOR_NOTCONNECT);
//一台主机只能运行一个日志分析器实例,确保共享内存的Mutex是唯一的
mhMemShareMutex = OpenMutex(MUTEX_ALL_ACCESS, FALSE, LOGER_DATA_MUTEX);
if (mhMemShareMutex)
{
::Messa