2869 lines
84 KiB
C++
2869 lines
84 KiB
C++
// HookMsgDlg.cpp : implementation file
|
|
//
|
|
|
|
#include "stdafx.h"
|
|
#include "HookMsg.h"
|
|
#include "HookMsgDlg.h"
|
|
#include "FindTargetWndDlg.h"
|
|
#include "ConfigEnvDlg.h"
|
|
|
|
#include "DlgEditTool.h"
|
|
|
|
#include "SrvConnectDlg.h"
|
|
#include "ClientSocket.h"
|
|
|
|
#include "WaitDlg.h"
|
|
|
|
#ifdef _DEBUG
|
|
#define new DEBUG_NEW
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CAboutDlg dialog used for App About
|
|
|
|
class CAboutDlg : public CDialog
|
|
{
|
|
public:
|
|
CAboutDlg();
|
|
|
|
// Dialog Data
|
|
//{{AFX_DATA(CAboutDlg)
|
|
enum { IDD = IDD_ABOUTBOX };
|
|
//}}AFX_DATA
|
|
|
|
// ClassWizard generated virtual function overrides
|
|
//{{AFX_VIRTUAL(CAboutDlg)
|
|
protected:
|
|
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
|
|
//}}AFX_VIRTUAL
|
|
|
|
// Implementation
|
|
protected:
|
|
//{{AFX_MSG(CAboutDlg)
|
|
//}}AFX_MSG
|
|
DECLARE_MESSAGE_MAP()
|
|
};
|
|
|
|
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
|
|
{
|
|
//{{AFX_DATA_INIT(CAboutDlg)
|
|
//}}AFX_DATA_INIT
|
|
}
|
|
|
|
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
|
|
{
|
|
CDialog::DoDataExchange(pDX);
|
|
//{{AFX_DATA_MAP(CAboutDlg)
|
|
//}}AFX_DATA_MAP
|
|
}
|
|
|
|
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
|
|
//{{AFX_MSG_MAP(CAboutDlg)
|
|
// No message handlers
|
|
//}}AFX_MSG_MAP
|
|
END_MESSAGE_MAP()
|
|
|
|
void CHookMsgApp::OnAppAbout()
|
|
{
|
|
CAboutDlg aboutDlg;
|
|
aboutDlg.DoModal();
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CHookMsgDlg dialog
|
|
//
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
CHookMsgDlg::CHookMsgDlg(CWnd* pParent /*=NULL*/)
|
|
: CDialog(CHookMsgDlg::IDD, pParent)
|
|
{
|
|
m_bInitSuccess = FALSE;
|
|
|
|
//{{AFX_DATA_INIT(CHookMsgDlg)
|
|
m_bInputCode1 = FALSE;
|
|
m_bInputCode2 = FALSE;
|
|
m_bInputCode3 = FALSE;
|
|
m_bInfoTickerConnect = FALSE;
|
|
//}}AFX_DATA_INIT
|
|
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
|
|
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
|
|
|
|
m_bMonitorStatus = FALSE;
|
|
m_nTrayIconTimer = 0;
|
|
|
|
m_pLCDlg = NULL;
|
|
|
|
m_nSourceFrom = -1;
|
|
|
|
g_pStockData = NULL;
|
|
|
|
m_pCpCybos = NULL;
|
|
|
|
memset( m_szHotKey_JCode, NULL, sizeof(m_szHotKey_JCode) );
|
|
|
|
// m_pCpConclusion = NULL;
|
|
// m_pCpConclusionEvent = NULL; // <= 추가한 것임
|
|
|
|
m_nSrcJumoon_Number = 0; // 원주문번호 초기화.
|
|
m_nAutoMedoMoney = 0; // 자동매도시 주문금액 초기화.
|
|
|
|
m_bUsingStockCheckThread = FALSE;
|
|
|
|
m_dwCallTimeLast = 0;
|
|
m_dwMonitorPauseTime = 0;
|
|
|
|
m_pClientSocket = NULL;
|
|
m_bSvrConnect = FALSE;
|
|
m_strName = "UserID";
|
|
m_strSvrIP = "192.168.0.1";
|
|
m_nSvrPort = 1500;
|
|
m_strSendCommand = "";
|
|
|
|
m_pTickerSocket = NULL;
|
|
|
|
DeleteFile("NewsLog.txt");
|
|
hFile = CreateFile("NewsLog.txt",
|
|
GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
|
|
ASSERT(hFile != INVALID_HANDLE_VALUE);
|
|
}
|
|
|
|
CHookMsgDlg::~CHookMsgDlg()
|
|
{
|
|
TRACE("~CHookMsgDlg() : Step 1\n");
|
|
SAFE_DELETE( g_pStockData );
|
|
|
|
DWORD dwWritten;
|
|
WriteFile(hFile,"[THEEND]\n",9,&dwWritten,NULL);
|
|
CloseHandle(hFile);
|
|
|
|
/*
|
|
try
|
|
{
|
|
if (NULL != m_pCpConclusionEvent)
|
|
{
|
|
IConnectionPointContainerPtr pCPC;
|
|
IConnectionPointPtr pCP;
|
|
pCPC = m_pCpConclusion;
|
|
pCPC->FindConnectionPoint(__uuidof(_IDibEvents), &pCP);
|
|
pCP->Unadvise(m_pCpConclusionEvent->GetCookie());
|
|
m_pCpConclusionEvent->Destroy();
|
|
m_pCpConclusion = 0;
|
|
}
|
|
}
|
|
catch (_com_error e)
|
|
{
|
|
MessageBox(e.ErrorMessage(), "객체 삭제실패", MB_OK|MB_ICONSTOP);
|
|
}
|
|
*/
|
|
TRACE("~CHookMsgDlg() : return.\n");
|
|
}
|
|
|
|
void CHookMsgDlg::DoDataExchange(CDataExchange* pDX)
|
|
{
|
|
CDialog::DoDataExchange(pDX);
|
|
//{{AFX_DATA_MAP(CHookMsgDlg)
|
|
DDX_Control(pDX, IDC_HOOKMSGDLG_CP_VALUE_STATIC, m_hCPValue);
|
|
DDX_Control(pDX, IDC_TRACE_LIST, m_hTraceListBox);
|
|
DDX_Check(pDX, IDC_HOOKMSG_HOOKSTATE_CHECK1, m_bInputCode1);
|
|
DDX_Check(pDX, IDC_HOOKMSG_HOOKSTATE_CHECK2, m_bInputCode2);
|
|
DDX_Check(pDX, IDC_HOOKMSG_HOOKSTATE_CHECK3, m_bInputCode3);
|
|
DDX_Check(pDX, IDC_SVRCONNECT_CHECK, m_bSvrConnect);
|
|
DDX_Check(pDX, IDC_INFOTICKER_CHECK, m_bInfoTickerConnect);
|
|
//}}AFX_DATA_MAP
|
|
}
|
|
|
|
BEGIN_MESSAGE_MAP(CHookMsgDlg, CDialog)
|
|
//{{AFX_MSG_MAP(CHookMsgDlg)
|
|
ON_WM_INITMENUPOPUP()
|
|
ON_WM_CLOSE()
|
|
ON_WM_SYSCOMMAND()
|
|
ON_WM_PAINT()
|
|
ON_WM_QUERYDRAGICON()
|
|
ON_WM_TIMER()
|
|
ON_WM_COPYDATA()
|
|
ON_WM_NCHITTEST()
|
|
ON_BN_CLICKED(IDM_MONITOR_START, OnMonitorStart)
|
|
ON_UPDATE_COMMAND_UI(IDM_MONITOR_START, OnUpdateMonitorStart)
|
|
ON_BN_CLICKED(IDM_MONITOR_PAUSE, OnMonitorPause)
|
|
ON_UPDATE_COMMAND_UI(IDM_MONITOR_PAUSE, OnUpdateMonitorPause)
|
|
ON_BN_CLICKED(IDC_TARGETWND_BTN, OnTargetWndBtn)
|
|
ON_UPDATE_COMMAND_UI(IDC_TARGETWND_BTN, OnUpdateTargetWndBtn)
|
|
ON_BN_CLICKED(IDC_HOOKONOFF_CHECK, OnHookOnOffCheck)
|
|
ON_BN_CLICKED(IDC_CONFIG_ENV_BTN, OnConfigEnvBtn)
|
|
ON_BN_CLICKED(IDC_CONFIG_REJECTLIST_BTN, OnConfigRejectlistBtn)
|
|
ON_BN_CLICKED(IDC_CONFIG_PASS_LIST, OnConfigPassListBtn)
|
|
ON_WM_SIZE()
|
|
ON_WM_GETMINMAXINFO()
|
|
ON_BN_CLICKED(IDC_HOOKMSG_MEDO_BTN, OnHookmsgMedoBtn)
|
|
ON_BN_CLICKED(IDC_HOOKMSG_STOCKPRICECHECK_CHK, OnHookmsgStockpriceCheck)
|
|
ON_BN_CLICKED(IDC_CONFIG_REJECTLIST_BTN2, OnConfigRejectlistBtn2)
|
|
ON_BN_CLICKED(IDC_HOOKMSG_HOOKSTATE_CHECK1, OnHookmsgHookstateCheck1)
|
|
ON_BN_CLICKED(IDC_HOOKMSG_HOOKSTATE_CHECK2, OnHookmsgHookstateCheck2)
|
|
ON_BN_CLICKED(IDC_HOOKMSG_HOOKSTATE_CHECK3, OnHookmsgHookstateCheck3)
|
|
ON_BN_CLICKED(IDC_CONFIG_SPECIAL_LIST, OnConfigSpecialList)
|
|
ON_BN_CLICKED(IDC_CONFIG_MANUAL_LIST, OnConfigManualList)
|
|
ON_BN_CLICKED(IDC_SVRCONNECT_CHECK, OnSvrconnectCheck)
|
|
ON_BN_CLICKED(IDC_INFOTICKER_CHECK, OnInfotickerCheck)
|
|
//}}AFX_MSG_MAP
|
|
|
|
ON_MESSAGE(WM_CPDIB_RECEIVED, OnReceived) // 추가한 것임
|
|
|
|
ON_MESSAGE(WM_HOTKEY, OnHotKey)
|
|
ON_MESSAGE(WM_ICON_NOTIFY, OnTrayNotification)
|
|
ON_MESSAGE(WM_HOOKMSG_TARGETAPP_DESTORYED, OnTargetAppDestoryed)
|
|
ON_MESSAGE(WM_START_COMMAND, OnStartCommand)
|
|
ON_MESSAGE(WM_STOP_COMMAND, OnStopCommand)
|
|
ON_MESSAGE(WM_REJECTLISTUPDATE_COMMAND, OnUpdateRejectListCommand)
|
|
|
|
ON_MESSAGE(WM_SVRSEND_COMMAND, OnSvrSendCommand)
|
|
|
|
ON_MESSAGE(SCM_CLOSE, OnTickerSocketClose) // Client 소켓 해제
|
|
ON_MESSAGE(SCM_RECEIVE, OnTickerSocketReceive) // Client 소켓으로 부터 수신되는 데이터
|
|
|
|
END_MESSAGE_MAP()
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CHookMsgDlg message handlers
|
|
void CHookMsgDlg::OnInitMenuPopup(CMenu *pPopupMenu, UINT nIndex,BOOL bSysMenu)
|
|
{
|
|
ASSERT(pPopupMenu != NULL);
|
|
// Check the enabled state of various menu items.
|
|
|
|
CCmdUI state;
|
|
state.m_pMenu = pPopupMenu;
|
|
ASSERT(state.m_pOther == NULL);
|
|
ASSERT(state.m_pParentMenu == NULL);
|
|
|
|
// Determine if menu is popup in top-level menu and set m_pOther to
|
|
// it if so (m_pParentMenu == NULL indicates that it is secondary popup).
|
|
HMENU hParentMenu;
|
|
if (AfxGetThreadState()->m_hTrackingMenu == pPopupMenu->m_hMenu)
|
|
state.m_pParentMenu = pPopupMenu; // Parent == child for tracking popup.
|
|
else if ((hParentMenu = ::GetMenu(m_hWnd)) != NULL)
|
|
{
|
|
CWnd* pParent = this;
|
|
// Child windows don't have menus--need to go to the top!
|
|
if (pParent != NULL &&
|
|
(hParentMenu = ::GetMenu(pParent->m_hWnd)) != NULL)
|
|
{
|
|
int nIndexMax = ::GetMenuItemCount(hParentMenu);
|
|
for (int nIndex = 0; nIndex < nIndexMax; nIndex++)
|
|
{
|
|
if (::GetSubMenu(hParentMenu, nIndex) == pPopupMenu->m_hMenu)
|
|
{
|
|
// When popup is found, m_pParentMenu is containing menu.
|
|
state.m_pParentMenu = CMenu::FromHandle(hParentMenu);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
state.m_nIndexMax = pPopupMenu->GetMenuItemCount();
|
|
for (state.m_nIndex = 0; state.m_nIndex < state.m_nIndexMax;
|
|
state.m_nIndex++)
|
|
{
|
|
state.m_nID = pPopupMenu->GetMenuItemID(state.m_nIndex);
|
|
if (state.m_nID == 0)
|
|
continue; // Menu separator or invalid cmd - ignore it.
|
|
|
|
ASSERT(state.m_pOther == NULL);
|
|
ASSERT(state.m_pMenu != NULL);
|
|
if (state.m_nID == (UINT)-1)
|
|
{
|
|
// Possibly a popup menu, route to first item of that popup.
|
|
state.m_pSubMenu = pPopupMenu->GetSubMenu(state.m_nIndex);
|
|
if (state.m_pSubMenu == NULL ||
|
|
(state.m_nID = state.m_pSubMenu->GetMenuItemID(0)) == 0 ||
|
|
state.m_nID == (UINT)-1)
|
|
{
|
|
continue; // First item of popup can't be routed to.
|
|
}
|
|
state.DoUpdate(this, TRUE); // Popups are never auto disabled.
|
|
}
|
|
else
|
|
{
|
|
// Normal menu item.
|
|
// Auto enable/disable if frame window has m_bAutoMenuEnable
|
|
// set and command is _not_ a system command.
|
|
state.m_pSubMenu = NULL;
|
|
state.DoUpdate(this, FALSE);
|
|
}
|
|
|
|
// Adjust for menu deletions and additions.
|
|
UINT nCount = pPopupMenu->GetMenuItemCount();
|
|
if (nCount < state.m_nIndexMax)
|
|
{
|
|
state.m_nIndex -= (state.m_nIndexMax - nCount);
|
|
while (state.m_nIndex < nCount &&
|
|
pPopupMenu->GetMenuItemID(state.m_nIndex) == state.m_nID)
|
|
{
|
|
state.m_nIndex++;
|
|
}
|
|
}
|
|
state.m_nIndexMax = nCount;
|
|
}
|
|
}
|
|
|
|
LRESULT CHookMsgDlg::OnNcHitTest(CPoint point)
|
|
{
|
|
UINT nHitTest = CWnd::OnNcHitTest(point);
|
|
|
|
if( nHitTest == HTCLIENT)
|
|
nHitTest = HTCAPTION;
|
|
|
|
return nHitTest;
|
|
}
|
|
|
|
BOOL CHookMsgDlg::OnInitDialog()
|
|
{
|
|
TRACE("CHookMsgDlg::OnInitDialog()\n");
|
|
CDialog::OnInitDialog();
|
|
m_bInitSuccess = TRUE;
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////
|
|
TraceMsg( "[초기화] 환경파일 검사중..." );
|
|
CFileFind _file;
|
|
CString _strFile;
|
|
TCHAR szFilePath[_MAX_PATH]={0,};
|
|
::GetModuleFileName(NULL, szFilePath, _MAX_PATH);
|
|
*(strrchr( szFilePath, '\\' ) + 1) = 0;
|
|
|
|
_strFile.Format( "%s\\Config.ini", szFilePath );
|
|
if( !_file.FindFile( _strFile ) )
|
|
TraceMsg( "[Config.ini] 파일이 없습니다!" );
|
|
|
|
_strFile.Format( "%s\\거부리스트알림.wav", szFilePath );
|
|
if( !_file.FindFile( _strFile ) )
|
|
TraceMsg( "[거부리스트알림.wav] 파일이 없습니다!" , CXListBox::Red, CXListBox::Yellow );
|
|
|
|
_strFile.Format( "%s\\중복종목알림.wav", szFilePath );
|
|
if( !_file.FindFile( _strFile ) )
|
|
TraceMsg( "[중복종목알림.wav] 파일이 없습니다!", CXListBox::Red, CXListBox::Yellow );
|
|
|
|
_strFile.Format( "%s\\자동매수알림.wav", szFilePath );
|
|
if( !_file.FindFile( _strFile ) )
|
|
TraceMsg( "[자동매수알림.wav] 파일이 없습니다!", CXListBox::Red, CXListBox::Yellow );
|
|
|
|
_strFile.Format( "%s\\공시_부정문구.txt", szFilePath );
|
|
if( !_file.FindFile( _strFile ) )
|
|
TraceMsg( "[공시_부정문구.txt] 파일이 없습니다!", CXListBox::Red, CXListBox::Yellow );
|
|
|
|
_strFile.Format( "%s\\공시_긍정문구.txt", szFilePath );
|
|
if( !_file.FindFile( _strFile ) )
|
|
TraceMsg( "[공시_긍정문구.txt] 파일이 없습니다!", CXListBox::Red, CXListBox::Yellow );
|
|
|
|
_strFile.Format( "%s\\공시_특별종목코드.txt", szFilePath );
|
|
if( !_file.FindFile( _strFile ) )
|
|
TraceMsg( "[공시_특별종목코드.txt] 파일이 없습니다!", CXListBox::Red, CXListBox::Yellow );
|
|
|
|
_strFile.Format( "%s\\거부_전장거래부진종목코드.txt", szFilePath );
|
|
if( !_file.FindFile( _strFile ) )
|
|
TraceMsg( "[거부_전장거래부진종목코드.txt] 파일이 없습니다!", CXListBox::Red, CXListBox::Yellow );
|
|
|
|
_strFile.Format( "%s\\뉴스플러스_특별용_긍정문구.txt", szFilePath );
|
|
if( !_file.FindFile( _strFile ) )
|
|
TraceMsg( "[뉴스플러스_특별용_긍정문구.txt] 파일이 없습니다!", CXListBox::Red, CXListBox::Yellow );
|
|
|
|
_strFile.Format( "%s\\뉴스플러스_일반용_긍정문구.txt", szFilePath );
|
|
if( !_file.FindFile( _strFile ) )
|
|
TraceMsg( "[뉴스플러스_일반용_긍정문구.txt] 파일이 없습니다!", CXListBox::Red, CXListBox::Yellow );
|
|
|
|
_strFile.Format( "%s\\뉴스플러스_수동문구.txt", szFilePath );
|
|
if( !_file.FindFile( _strFile ) )
|
|
TraceMsg( "[뉴스플러스_수동문구.txt] 파일이 없습니다!", CXListBox::Red, CXListBox::Yellow );
|
|
|
|
_strFile.Format( "%s\\뉴스플러스_부정문구.txt", szFilePath );
|
|
if( !_file.FindFile( _strFile ) )
|
|
TraceMsg( "[뉴스플러스_부정문구.txt] 파일이 없습니다!", CXListBox::Red, CXListBox::Yellow );
|
|
///////////////////////////////////////////////////////////////////
|
|
|
|
g_theApp.m_strBankAccount = _T("");
|
|
|
|
TraceMsg( "[초기화] 업무키등록..." );
|
|
|
|
ICpTdUtilPtr _objTdUtil;
|
|
try
|
|
{
|
|
_objTdUtil.CreateInstance(CLSID_CpTdUtil);
|
|
short rv = _objTdUtil->TradeInit(0);
|
|
if( -1 == rv )
|
|
AfxMessageBox( "업무키등록 : Error" );
|
|
else if( 1 == rv )
|
|
AfxMessageBox( "업무키등록 : 업무키가 잘못되었습니다." );
|
|
else if( 2 == rv )
|
|
AfxMessageBox( "업무키등록 : 계좌 비밀번호가 잘못되었습니다." );
|
|
|
|
_variant_t vtStrAccount = _objTdUtil->GetAccountNumber();
|
|
|
|
if( vtStrAccount.vt == (VT_BSTR | VT_ARRAY) && rv == 0 )
|
|
{
|
|
SAFEARRAY *psa = vtStrAccount.parray;
|
|
BSTR* bstrArray;
|
|
SafeArrayAccessData( psa, (void**)&bstrArray );
|
|
g_theApp.m_strBankAccount = *bstrArray;
|
|
SafeArrayUnaccessData( psa );
|
|
}
|
|
else
|
|
{
|
|
_objTdUtil.Release();
|
|
PostQuitMessage(0);
|
|
return TRUE;
|
|
}
|
|
|
|
_objTdUtil.Release();
|
|
}
|
|
catch( _com_error e )
|
|
{
|
|
_objTdUtil.Release();
|
|
AfxMessageBox("Cybos가 실행중이 아니거나 초기화에 문제가 발생하였습니다." );
|
|
|
|
PostQuitMessage(0);
|
|
return TRUE;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// 하한가 매매방지창 실행...
|
|
if( g_AppEnv.bLowmoneyInfoDlg )
|
|
{
|
|
::GetModuleFileName(NULL, szFilePath, _MAX_PATH);
|
|
*(strrchr( szFilePath, '\\' ) + 1) = 0;
|
|
strcat( szFilePath, "\\HLStockWindow.exe" );
|
|
SHELLEXECUTEINFO ShExecInfo;
|
|
ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
|
|
ShExecInfo.fMask = NULL;
|
|
ShExecInfo.hwnd = NULL;
|
|
ShExecInfo.lpVerb = NULL;
|
|
ShExecInfo.lpFile = szFilePath;
|
|
ShExecInfo.lpParameters = "-hide";
|
|
ShExecInfo.lpDirectory = NULL;
|
|
ShExecInfo.nShow = SW_NORMAL;
|
|
ShExecInfo.hInstApp = NULL;
|
|
BOOL bSuccess = ShellExecuteEx(&ShExecInfo);
|
|
if( bSuccess )
|
|
TraceMsg( "[초기화] 하한가창 프로그램이 실행되었습니다.", CXListBox::Blue, CXListBox::White );
|
|
else
|
|
TraceMsg( "[초기화] 하한가창 프로그램(HLStockWindow.exe)을 찾을 수 없습니다.", CXListBox::Red, CXListBox::Yellow );
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
CThinThread::CreateThread( 0, 0, NULL, INFINITE ,WORD_THREAD_WITH_HOGA);
|
|
CThinThread::CreateThread( 0, 0, NULL, INFINITE ,WORD_THREAD_WITHOUT_HOGA);
|
|
|
|
g_pStockData = new CStockData( this );
|
|
g_pStockData->Initialize();
|
|
g_pStockData->Open();
|
|
|
|
// ////////////////////////////////////////////////////////////////////////////
|
|
// if( GetOsVersion() != VER_PLATFORM_WIN32_NT )
|
|
// { // win98, win95 계열은 반투명윈도우 API를 지원하지 않습니다.
|
|
// GetDlgItem(IDC_TRANSPARENT_PERCENT_EDIT)->ShowWindow( SW_HIDE );
|
|
// GetDlgItem(IDC_MAKETRANSPARENTWINDOW_BTN)->ShowWindow( SW_HIDE );
|
|
// GetDlgItem(IDC_MAKETRANSPARENT_STATIC)->ShowWindow( SW_HIDE );
|
|
// }
|
|
// ////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Add "About..." menu item to system menu.
|
|
|
|
// IDM_ABOUTBOX must be in the system command range.
|
|
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
|
|
ASSERT(IDM_ABOUTBOX < 0xF000);
|
|
|
|
CMenu* pSysMenu = GetSystemMenu(FALSE);
|
|
if (pSysMenu != NULL)
|
|
{
|
|
CString strAboutMenu;
|
|
strAboutMenu.LoadString(IDS_ABOUTBOX);
|
|
if (!strAboutMenu.IsEmpty())
|
|
{
|
|
pSysMenu->AppendMenu(MF_SEPARATOR);
|
|
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
|
|
pSysMenu->AppendMenu(MF_SEPARATOR);
|
|
pSysMenu->AppendMenu(MF_STRING, IDM_CONFIG_ENV_MENU, "프로그램 환경설정 ");
|
|
pSysMenu->AppendMenu(MF_STRING, IDC_TARGETWND_BTN, "윈도우 지정");
|
|
pSysMenu->AppendMenu(MF_STRING, IDM_CONFIG_REJECTLIST_MENU, "거부종목 설정1");
|
|
pSysMenu->AppendMenu(MF_STRING, IDM_CONFIG_REJECTLIST_MENU2, "거부종목 설정2");
|
|
pSysMenu->AppendMenu(MF_SEPARATOR);
|
|
pSysMenu->AppendMenu(MF_STRING, IDM_MAINWINDOW_SHOW, "메인윈도우 보이기");
|
|
pSysMenu->AppendMenu(MF_STRING, IDM_TOOLWINDOW_SHOW, "상태제어창 보이기");
|
|
pSysMenu->AppendMenu(MF_SEPARATOR);
|
|
pSysMenu->AppendMenu(MF_STRING, IDM_MONITOR_START, "모니터 시작");
|
|
pSysMenu->AppendMenu(MF_STRING, IDM_MONITOR_PAUSE, "모니터 중단");
|
|
pSysMenu->AppendMenu(MF_SEPARATOR);
|
|
pSysMenu->AppendMenu(MF_STRING, ID_APP_EXIT, "프로그램 종료");
|
|
}
|
|
}
|
|
|
|
// Set the icon for this dialog. The framework does this automatically
|
|
// when the application's main window is not a dialog
|
|
SetIcon(m_hIcon, TRUE); // Set big icon
|
|
SetIcon(m_hIcon, FALSE); // Set small icon
|
|
|
|
// Make the total in a larger font
|
|
{
|
|
VERIFY(m_LockUnlockBtnFont.CreateFont(
|
|
18, // nHeight
|
|
0, // nWidth
|
|
0, // nEscapement
|
|
0, // nOrientation
|
|
FW_BOLD, // nWeight
|
|
FALSE, // bItalic
|
|
FALSE, // bUnderline
|
|
0, // cStrikeOut
|
|
ANSI_CHARSET, // nCharSet
|
|
OUT_DEFAULT_PRECIS, // nOutPrecision
|
|
CLIP_DEFAULT_PRECIS, // nClipPrecision
|
|
DEFAULT_QUALITY, // nQuality
|
|
DEFAULT_PITCH | FF_SWISS, // nPitchAndFamily
|
|
"굴림체")); // lpszFacename
|
|
|
|
CButton *pButton = (CButton*)GetDlgItem(IDC_HOOKONOFF_CHECK);
|
|
pButton->SetFont(&m_LockUnlockBtnFont);
|
|
}
|
|
|
|
TraceMsg( "[초기화] 환경설정 진행중..." );
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
CHookMsgApp * pApp = (CHookMsgApp*)AfxGetApp();
|
|
m_strSvrIP = pApp->GetProfileString("Settings", "SrvIP", "192.168.0.1");
|
|
m_nSvrPort = pApp->GetProfileInt("Settings", "SrvPort", 1500 );
|
|
m_strName = pApp->GetProfileString("Settings", "UserName", "홍길동");
|
|
|
|
ReadRegistry();
|
|
g_Condition.Initialize();
|
|
InstallHotKey();
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// 트레이 아이콘 등록
|
|
if (!m_TrayIcon.Create(this, WM_ICON_NOTIFY, _T("Cybos 모니터링"), NULL, IDR_MAINFRAME))
|
|
return FALSE;
|
|
// 아이콘 설정
|
|
m_TrayIcon.SetIcon(IDR_MAINFRAME);
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
STARTUPINFO StartupInfo;
|
|
::GetStartupInfo( &StartupInfo );
|
|
if (StartupInfo.wShowWindow != SW_SHOWNORMAL)
|
|
gwndpl.showCmd = StartupInfo.wShowWindow;
|
|
::SetWindowPlacement( m_hWnd, &gwndpl);
|
|
if( g_theApp.m_bTopmostWnd )
|
|
SetWindowPos(&wndTopMost, 0,0,0,0,SWP_NOSIZE|SWP_NOMOVE);
|
|
else
|
|
SetWindowPos(&wndNoTopMost, 0,0,0,0,SWP_NOSIZE|SWP_NOMOVE);
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
if( g_theApp.m_bInfoTickerConnect )
|
|
{
|
|
m_bInfoTickerConnect = g_theApp.m_bInfoTickerConnect;
|
|
UpdateData(FALSE);
|
|
|
|
OnInfotickerCheck();
|
|
}
|
|
|
|
UpdateData(FALSE);
|
|
|
|
ShowHideLockControlDlg( g_theApp.m_bShowLockContorlDlg );
|
|
|
|
m_hTraceListBox.SetContextMenuId(IDR_XLISTBOX);
|
|
|
|
#ifndef _DEBUG
|
|
GetDlgItem(IDC_HOOKMSG_MEDO_BTN)->ShowWindow( FALSE );
|
|
#endif
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// 체결매수 상황을 수신합.
|
|
/* DWORD dwCookie;
|
|
CRuntimeClass* prcCpDibEvent = NULL;
|
|
try
|
|
{
|
|
m_pCpConclusion.CreateInstance(__uuidof(CpConclusion));
|
|
|
|
prcCpDibEvent = RUNTIME_CLASS(CCpDibEvent);
|
|
m_pCpConclusionEvent = (CCpDibEvent *)prcCpDibEvent->CreateObject();
|
|
m_pCpConclusionEvent->SetOwner(GetSafeHwnd());
|
|
IConnectionPointContainerPtr pCPC;
|
|
IConnectionPointPtr pCP;
|
|
pCPC = m_pCpConclusion;
|
|
pCPC->FindConnectionPoint(__uuidof(_IDibEvents), &pCP);
|
|
IUnknownPtr pUnk = m_pCpConclusionEvent->GetIDispatch(TRUE);
|
|
pCP->Advise(pUnk, &dwCookie);
|
|
m_pCpConclusionEvent->SetCookie(dwCookie);
|
|
|
|
m_pCpConclusion->Subscribe();
|
|
}
|
|
catch (_com_error e)
|
|
{
|
|
MessageBox(e.ErrorMessage(), "CHookMsgDlg::OnInitDialog CpConclusion 초기화 실패", MB_OK|MB_ICONSTOP);
|
|
}
|
|
*/
|
|
|
|
m_pCpCybos.CreateInstance(CLSID_CpCybos);
|
|
|
|
HookInstallTargetWnd();
|
|
|
|
TraceMsg( "[초기화] 완료 !!", CXListBox::Black, CXListBox::White, TRUE );
|
|
return TRUE; // return TRUE unless you set the focus to a control
|
|
}
|
|
|
|
void CHookMsgDlg::OnSysCommand(UINT nID, LPARAM lParam)
|
|
{
|
|
if( nID == SC_CLOSE )
|
|
{
|
|
ShowWindow( SW_HIDE );
|
|
return;
|
|
}
|
|
|
|
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
|
|
{
|
|
CAboutDlg dlgAbout;
|
|
dlgAbout.DoModal();
|
|
|
|
#ifdef _DEBUG
|
|
if( m_pClientSocket )
|
|
{
|
|
m_strSendCommand = "테스트 메시지입니다.";
|
|
PostMessage(WM_SVRSEND_COMMAND);
|
|
}
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
switch( nID )
|
|
{
|
|
case IDM_CONFIG_ENV_MENU :
|
|
OnConfigEnvBtn();
|
|
break;
|
|
case IDM_CONFIG_REJECTLIST_MENU :
|
|
OnConfigRejectlistBtn();
|
|
break;
|
|
case IDM_CONFIG_REJECTLIST_MENU2 :
|
|
OnConfigRejectlistBtn2();
|
|
break;
|
|
|
|
case IDM_MAINWINDOW_SHOW :
|
|
ShowWindow( SW_SHOWNORMAL );
|
|
break;
|
|
case IDM_TOOLWINDOW_SHOW :
|
|
{
|
|
if( m_pLCDlg ) {
|
|
if( ::IsWindow( m_pLCDlg->m_hWnd ) )
|
|
ShowHideLockControlDlg( FALSE );
|
|
else
|
|
ShowHideLockControlDlg( TRUE );
|
|
} else {
|
|
ShowHideLockControlDlg( TRUE );
|
|
}
|
|
}
|
|
break;
|
|
case IDC_TARGETWND_BTN :
|
|
OnTargetWndBtn();
|
|
break;
|
|
|
|
case IDM_MONITOR_START:
|
|
OnMonitorStart();
|
|
break;
|
|
|
|
case IDM_MONITOR_PAUSE:
|
|
OnMonitorPause();
|
|
break;
|
|
|
|
case ID_APP_EXIT:
|
|
PostMessage(WM_CLOSE);
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
CDialog::OnSysCommand(nID, lParam);
|
|
}
|
|
}
|
|
|
|
BOOL CHookMsgDlg::OnCommand(WPARAM wParam, LPARAM lParam)
|
|
{
|
|
switch( (UINT)wParam )
|
|
{
|
|
case IDM_CONFIG_ENV_MENU :
|
|
OnConfigEnvBtn();
|
|
break;
|
|
case IDM_CONFIG_REJECTLIST_MENU :
|
|
OnConfigRejectlistBtn();
|
|
break;
|
|
case IDM_CONFIG_REJECTLIST_MENU2 :
|
|
OnConfigRejectlistBtn2();
|
|
break;
|
|
|
|
case IDM_MAINWINDOW_SHOW :
|
|
ShowWindow( SW_SHOWNORMAL );
|
|
break;
|
|
case IDM_TOOLWINDOW_SHOW :
|
|
{
|
|
if( m_pLCDlg ) {
|
|
if( ::IsWindow( m_pLCDlg->m_hWnd ) )
|
|
ShowHideLockControlDlg( FALSE );
|
|
else
|
|
ShowHideLockControlDlg( TRUE );
|
|
} else {
|
|
ShowHideLockControlDlg( TRUE );
|
|
}
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return CDialog::OnCommand(wParam, lParam);
|
|
}
|
|
|
|
// If you add a minimize button to your dialog, you will need the code below
|
|
// to draw the icon. For MFC applications using the document/view model,
|
|
// this is automatically done for you by the framework.
|
|
|
|
void CHookMsgDlg::OnPaint()
|
|
{
|
|
if (IsIconic())
|
|
{
|
|
CPaintDC dc(this); // device context for painting
|
|
|
|
SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
|
|
|
|
// Center icon in client rectangle
|
|
int cxIcon = GetSystemMetrics(SM_CXICON);
|
|
int cyIcon = GetSystemMetrics(SM_CYICON);
|
|
CRect rect;
|
|
GetClientRect(&rect);
|
|
int x = (rect.Width() - cxIcon + 1) / 2;
|
|
int y = (rect.Height() - cyIcon + 1) / 2;
|
|
|
|
// Draw the icon
|
|
dc.DrawIcon(x, y, m_hIcon);
|
|
}
|
|
else
|
|
{
|
|
CPaintDC dc(this); // device context for painting
|
|
CRect rc;
|
|
GetClientRect(&rc);
|
|
|
|
rc.left = rc.right - ::GetSystemMetrics(SM_CXHSCROLL);
|
|
rc.top = rc.bottom - ::GetSystemMetrics(SM_CYVSCROLL);
|
|
dc.DrawFrameControl( rc, DFC_SCROLL, DFCS_SCROLLSIZEGRIP );
|
|
|
|
CDialog::OnPaint();
|
|
}
|
|
}
|
|
|
|
BOOL CHookMsgDlg::DestroyWindow()
|
|
{
|
|
TRACE("DestroyWindow : Step 1\n");
|
|
|
|
m_pCpCybos.Release();
|
|
|
|
CHookMsgApp * pApp = (CHookMsgApp*)AfxGetApp();
|
|
pApp->WriteProfileInt("Settings", "SrvPort", (int)(m_nSvrPort) );
|
|
pApp->WriteProfileString("Settings", "SrvIP", (LPSTR)(LPCTSTR)m_strSvrIP);
|
|
pApp->WriteProfileString("Settings", "UserName", (LPSTR)(LPCTSTR)m_strName);
|
|
|
|
TRACE("DestroyWindow : Step 2\n");
|
|
WriteRegistry();
|
|
|
|
TRACE("DestroyWindow : Step 3\n");
|
|
HAPI_UninstallHook();
|
|
|
|
////////////////////////////////////
|
|
// Close window smoothly...
|
|
// if( GetOsVersion() == VER_PLATFORM_WIN32_NT )
|
|
// CloseSmoothly( m_hWnd );
|
|
// Free user library...
|
|
if ( g_hUserDll )
|
|
::FreeLibrary( g_hUserDll );
|
|
////////////////////////////////////
|
|
|
|
TRACE("DestroyWindow : return CDialog::DestroyWindow();\n");
|
|
return CDialog::DestroyWindow();
|
|
}
|
|
|
|
void CHookMsgDlg::OnClose()
|
|
{
|
|
OnCancel();
|
|
}
|
|
|
|
void CHookMsgDlg::OnCancel()
|
|
{
|
|
UpdateData();
|
|
|
|
int nID = MessageBox( "HookMsg 프로그램을 종료하시겠습니까?",
|
|
"프로그램 종료", MB_YESNO|MB_ICONQUESTION );
|
|
if( nID == IDYES )
|
|
{
|
|
try
|
|
{
|
|
TraceMsg( "<<< 프로그램을 종료합니다 >>>", CXListBox::Black, CXListBox::White );
|
|
|
|
g_theApp.m_bInfoTickerConnect = m_bInfoTickerConnect;
|
|
|
|
if( m_nTrayIconTimer )
|
|
KillTimer(m_nTrayIconTimer);
|
|
|
|
TRACE("OnCancel : Step 1\n");
|
|
if( m_pLCDlg )
|
|
{
|
|
m_pLCDlg->SaveWindowPlacement();
|
|
m_pLCDlg->SendMessage(WM_CLOSE);
|
|
}
|
|
|
|
TRACE("OnCancel : Step 2\n");
|
|
// Connection close...
|
|
if (m_pClientSocket)
|
|
{
|
|
TraceMsg( "Logout...", CXListBox::Black, CXListBox::White );
|
|
m_pClientSocket->ClientSignOut();
|
|
ClientClosed();
|
|
}
|
|
|
|
// 거래소 InfoTicker connection close...
|
|
if (m_pTickerSocket)
|
|
{
|
|
TraceMsg( "InfoTicker connection close...", CXListBox::Black, CXListBox::White );
|
|
SAFE_DELETE(m_pTickerSocket);
|
|
}
|
|
|
|
TRACE("OnCancel : Step 3\n");
|
|
if( g_pStockData )
|
|
{
|
|
BOOL bUsingWaitDlg = TRUE;
|
|
if( bUsingWaitDlg )
|
|
{
|
|
CWaitDlg dlg;
|
|
dlg.m_hWaitEvent = g_pStockData->Close(false);
|
|
dlg.DoModal();
|
|
}
|
|
else
|
|
g_pStockData->Close(true);
|
|
}
|
|
|
|
TRACE("OnCancel : Step 4\n");
|
|
CThinThread::Finalize();
|
|
|
|
TRACE("OnCancel : Step 5\n");
|
|
HWND hTagretWnd = ::FindWindow( "HLStockWindow_Dialog", NULL );
|
|
if( ::IsWindow( hTagretWnd ) )
|
|
::SendMessage(hTagretWnd, WM_CLOSE, 0, 0);
|
|
}
|
|
catch(...)
|
|
{
|
|
|
|
}
|
|
|
|
CDialog::OnCancel();
|
|
TRACE("OnCancel : return. \n");
|
|
}
|
|
}
|
|
|
|
// The system calls this to obtain the cursor to display while the user drags
|
|
// the minimized window.
|
|
HCURSOR CHookMsgDlg::OnQueryDragIcon()
|
|
{
|
|
return (HCURSOR) m_hIcon;
|
|
}
|
|
|
|
void CHookMsgDlg::OnTimer(UINT nIDEvent)
|
|
{
|
|
if( nIDEvent == TIMEID_TRAYICON )
|
|
{
|
|
static int nRotate = 0;
|
|
|
|
m_TrayIcon.SetIcon( IDI_ICON1+nRotate );
|
|
if( ++nRotate == 4 )
|
|
nRotate = 0;
|
|
}
|
|
else if( nIDEvent == TIMEID_7121DBCLICK )
|
|
{
|
|
if( ::IsWindow( g_theApp.m_hFindWindow[2] ) )
|
|
{
|
|
::PostMessage( g_theApp.m_hFindWindow[2], LB_SETCURSEL, 0, NULL );
|
|
|
|
::PostMessage( g_theApp.m_hFindWindow[2], WM_LBUTTONDOWN, 0, MAKELONG(30,5) );
|
|
::PostMessage( g_theApp.m_hFindWindow[2], WM_LBUTTONUP, 0, MAKELONG(30,5) );
|
|
|
|
if( g_AppEnv.b7121DbClickStop ) // 2003.10.30 추가.
|
|
{
|
|
OnMonitorPause();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
TraceMsg( "7121 Click Err: 후킹윈도우지정안됨", CXListBox::Black, CXListBox::Red );
|
|
}
|
|
|
|
KillTimer( nIDEvent );
|
|
}
|
|
|
|
if(m_pCpCybos->GetIsConnect() == 0)
|
|
MessageBox("연결이 종료되었습니다. 다시 접속해주시기 바랍니다.");
|
|
|
|
CDialog::OnTimer(nIDEvent);
|
|
}
|
|
|
|
LRESULT CHookMsgDlg::OnHotKey(WPARAM wParam, LPARAM lParam)
|
|
{
|
|
int idHotKey = (int) wParam; // identifier of hot key
|
|
UINT fuModifiers = (UINT) LOWORD(lParam); // key-modifier flags
|
|
UINT uVirtKey = (UINT) HIWORD(lParam); // virtual-key code
|
|
|
|
int nProg = -1;
|
|
switch (idHotKey)
|
|
{
|
|
case REGISTERHOTKEY_ID_LOCK:
|
|
OnHookOnOffCheck();
|
|
break;
|
|
case REGISTERHOTKEY_ID_NPINPUT:
|
|
{
|
|
long nCodeIndex = atol( m_szHotKey_JCode );
|
|
STOCKDATA * pCodeData = g_pStockData->GetStockData( nCodeIndex );
|
|
if( pCodeData == NULL )
|
|
{
|
|
if( m_bMonitorStatus == FALSE ) // 잠김일때...
|
|
{
|
|
if( g_theApp.m_bHotkeyCodeInputRule1 ) // 잠겼을때 중복/수동종목코드 입력않함
|
|
{
|
|
if( pCodeData->bManualInputCode || pCodeData->bRepeated ) // 중복종목, 수종종목은 입력안되게함.
|
|
{
|
|
CString strMsg;
|
|
strMsg.Format("NP종목코드: %s *잠겼을때 중복/수동종목코드 입력않함.", m_szHotKey_JCode );
|
|
TraceMsg( strMsg );
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
AutoInputJongmokCode(-1, m_szHotKey_JCode );
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
LRESULT CHookMsgDlg::OnTrayNotification(UINT wParam, LONG lParam)
|
|
{
|
|
CMenu menu, *pSubMenu;
|
|
// 오른쪽 마우스 버튼이 눌렸을 경우: 컨텍스트 메뉴 출력
|
|
if (LOWORD(lParam) == WM_RBUTTONUP)
|
|
{
|
|
if (!menu.LoadMenu(IDR_TRAYPOPUP_MENU)) return 0;
|
|
if (!(pSubMenu = menu.GetSubMenu(0))) return 0;
|
|
|
|
// SetMenuDefaultItem( menu.m_hMenu, 0, TRUE );
|
|
|
|
CPoint pos;
|
|
GetCursorPos(&pos);
|
|
SetForegroundWindow();
|
|
// 컨텍스트 메뉴 출력
|
|
pSubMenu->SetDefaultItem(IDM_MAINWINDOW_SHOW);
|
|
|
|
BOOL bCheck = FALSE;
|
|
if( m_pLCDlg ) { bCheck = ::IsWindow( m_pLCDlg->m_hWnd ); }
|
|
pSubMenu->CheckMenuItem(IDM_TOOLWINDOW_SHOW, MF_BYCOMMAND | (bCheck?MF_CHECKED:MF_UNCHECKED) );
|
|
|
|
pSubMenu->TrackPopupMenu(TPM_RIGHTALIGN, pos.x, pos.y, this);
|
|
menu.DestroyMenu();
|
|
}
|
|
|
|
// 왼쪽 마우스 버튼이 더블 클릭되었을 경우
|
|
else if (LOWORD(lParam) == WM_LBUTTONDBLCLK)
|
|
{
|
|
ShowWindow( SW_SHOW );
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
void CHookMsgDlg::HookInstallTargetWnd()
|
|
{
|
|
CButton * pHookStatWnd1 = (CButton*)GetDlgItem( IDC_HOOKMSG_HOOKSTATE_CHECK1 );
|
|
CButton * pHookStatWnd2 = (CButton*)GetDlgItem( IDC_HOOKMSG_HOOKSTATE_CHECK2 );
|
|
CButton * pHookStatWnd3 = (CButton*)GetDlgItem( IDC_HOOKMSG_HOOKSTATE_CHECK3 );
|
|
pHookStatWnd1->SetCheck(FALSE);
|
|
pHookStatWnd2->SetCheck(FALSE);
|
|
pHookStatWnd3->SetCheck(FALSE);
|
|
pHookStatWnd1->EnableWindow(FALSE);
|
|
pHookStatWnd2->EnableWindow(FALSE);
|
|
pHookStatWnd3->EnableWindow(FALSE);
|
|
m_bInputCode1 = FALSE;
|
|
m_bInputCode2 = FALSE;
|
|
m_bInputCode3 = FALSE;
|
|
|
|
HAPI_UninstallHook();
|
|
BOOL bHook = HAPI_InstallHook( m_hWnd,
|
|
g_theApp.m_hFindWindow[0], // TK
|
|
g_theApp.m_hFindWindow[1], // NP
|
|
g_theApp.m_hFindWindow[2] ); // 7121
|
|
if( bHook )
|
|
{
|
|
m_bMonitorStatus = FALSE;
|
|
|
|
if( ::IsWindow(g_theApp.m_hFindWindow[0]) )
|
|
{
|
|
pHookStatWnd1->EnableWindow(TRUE);
|
|
pHookStatWnd1->SetCheck(TRUE);
|
|
m_bInputCode1 = TRUE;
|
|
TraceMsg( "[TK] 후킹, 종목코드 자동입력 설정됨.", CXListBox::Blue, CXListBox::White );
|
|
}
|
|
if( ::IsWindow(g_theApp.m_hFindWindow[1]) )
|
|
{
|
|
pHookStatWnd2->EnableWindow(TRUE);
|
|
pHookStatWnd2->SetCheck(TRUE);
|
|
m_bInputCode2 = TRUE;
|
|
TraceMsg( "[NP] 후킹, 종목코드 자동입력 설정됨.", CXListBox::Blue, CXListBox::White );
|
|
}
|
|
if( ::IsWindow(g_theApp.m_hFindWindow[2]) )
|
|
{
|
|
pHookStatWnd3->EnableWindow(TRUE);
|
|
pHookStatWnd3->SetCheck(TRUE);
|
|
m_bInputCode3 = TRUE;
|
|
TraceMsg( "[7121] 후킹, 종목코드 자동입력 설정됨.", CXListBox::Blue, CXListBox::White );
|
|
}
|
|
}
|
|
}
|
|
|
|
void CHookMsgDlg::OnTargetWndBtn()
|
|
{
|
|
ShowWindow( SW_HIDE );
|
|
|
|
CFindTargetWndDlg dlg;
|
|
|
|
for( int i=0; i<MAX_FIND; i++ )
|
|
{
|
|
dlg.m_hFindWindow[i] = g_theApp.m_hFindWindow[i];
|
|
}
|
|
|
|
if( IDOK == dlg.DoModal() )
|
|
{
|
|
for( int i=0; i<MAX_FIND; i++ )
|
|
{
|
|
g_theApp.m_hFindWindow[i] = dlg.m_hFindWindow[i];
|
|
}
|
|
|
|
HookInstallTargetWnd();
|
|
}
|
|
|
|
ShowWindow( SW_SHOW );
|
|
}
|
|
void CHookMsgDlg::OnUpdateTargetWndBtn(CCmdUI* pCmdUI)
|
|
{
|
|
if(m_bMonitorStatus)
|
|
pCmdUI->Enable(FALSE);
|
|
else
|
|
pCmdUI->Enable(TRUE);
|
|
}
|
|
|
|
void CHookMsgDlg::OnHookOnOffCheck()
|
|
{
|
|
if( !m_bMonitorStatus )
|
|
{
|
|
OnMonitorStart();
|
|
}
|
|
else
|
|
{
|
|
OnMonitorPause();
|
|
}
|
|
}
|
|
|
|
void CHookMsgDlg::OnHookmsgStockpriceCheck()
|
|
{
|
|
BOOL bEnable = ((CButton*)GetDlgItem( IDC_HOOKMSG_STOCKPRICECHECK_CHK ))->GetCheck();
|
|
|
|
CWaitCursor wait;
|
|
|
|
if( bEnable )
|
|
{
|
|
g_pStockData->Start();
|
|
m_bUsingStockCheckThread = TRUE;
|
|
|
|
TraceMsg("코스닥 현재가체크기능 : Start");
|
|
}
|
|
else
|
|
{
|
|
g_pStockData->Stop();
|
|
m_bUsingStockCheckThread = FALSE;
|
|
|
|
TraceMsg("코스닥 현재가체크기능 : Stop");
|
|
}
|
|
|
|
wait.Restore();
|
|
}
|
|
|
|
void CHookMsgDlg::OnMonitorStart()
|
|
{
|
|
m_dwCallTimeLast = 0;
|
|
|
|
if( m_bMonitorStatus == TRUE )
|
|
return;
|
|
|
|
if( !::IsWindow(g_theApp.m_hFindWindow[0]) &&
|
|
!::IsWindow(g_theApp.m_hFindWindow[1]) &&
|
|
!::IsWindow(g_theApp.m_hFindWindow[2]) &&
|
|
!m_bInfoTickerConnect )
|
|
{
|
|
AfxMessageBox( "[윈도우지정 or InfoTicker접속]을 먼저하세요." );
|
|
((CButton*)GetDlgItem( IDC_HOOKONOFF_CHECK ))->SetCheck( FALSE );
|
|
return;
|
|
}
|
|
|
|
int nBankAccount = g_theApp.m_strBankAccountPermitted.Find(g_theApp.m_strBankAccount);
|
|
if( nBankAccount == -1 )
|
|
{
|
|
nBankAccount = g_theApp.m_strBankAccountPermitted.Find("Root");
|
|
if( nBankAccount == -1 )
|
|
{
|
|
TraceMsg( "프로그램 사용인증된 계좌번호가 아닙니다.", CXListBox::White, CXListBox::Red, TRUE );
|
|
return;
|
|
}
|
|
}
|
|
|
|
SetWindowText( "풀림" );
|
|
m_bMonitorStatus = TRUE;
|
|
|
|
((CButton*)GetDlgItem( IDC_HOOKONOFF_CHECK ))->SetWindowText( "풀림" );
|
|
((CButton*)GetDlgItem( IDC_HOOKONOFF_CHECK ))->SetCheck( TRUE );
|
|
|
|
m_TrayIcon.SetTooltipText( "풀림 상태입니다." );
|
|
m_nTrayIconTimer = SetTimer( TIMEID_TRAYICON, 500, 0);
|
|
|
|
TraceMsg( "풀림...", CXListBox::Blue, CXListBox::White );
|
|
|
|
((CButton*)GetDlgItem( IDC_TARGETWND_BTN ))->EnableWindow( FALSE );
|
|
|
|
if( m_pLCDlg )
|
|
m_pLCDlg->SetHookMsgState( TRUE );
|
|
|
|
}
|
|
void CHookMsgDlg::OnUpdateMonitorStart(CCmdUI* pCmdUI)
|
|
{
|
|
if(m_bMonitorStatus)
|
|
pCmdUI->Enable(FALSE);
|
|
else
|
|
pCmdUI->Enable(TRUE);
|
|
}
|
|
|
|
void CHookMsgDlg::OnMonitorPause()
|
|
{
|
|
//~!
|
|
if( g_AppEnv.bSuccessiveBuy || m_bMonitorStatus == FALSE )
|
|
return;
|
|
|
|
m_dwMonitorPauseTime = ::GetTickCount();
|
|
|
|
SetWindowText( "잠김" );
|
|
m_bMonitorStatus = FALSE;
|
|
|
|
((CButton*)GetDlgItem( IDC_HOOKONOFF_CHECK ))->SetWindowText( "잠김" );
|
|
((CButton*)GetDlgItem( IDC_HOOKONOFF_CHECK ))->SetCheck( FALSE );
|
|
|
|
m_TrayIcon.SetIcon( IDI_SPYSTATE1_ICON );
|
|
m_TrayIcon.SetTooltipText( "잠김 상태입니다." );
|
|
|
|
if( m_nTrayIconTimer )
|
|
KillTimer(m_nTrayIconTimer);
|
|
m_nTrayIconTimer = 0;
|
|
|
|
TraceMsg( "잠김...", CXListBox::Red, CXListBox::White );
|
|
|
|
((CButton*)GetDlgItem( IDC_TARGETWND_BTN ))->EnableWindow( TRUE );
|
|
|
|
if( m_pLCDlg )
|
|
m_pLCDlg->SetHookMsgState( FALSE );
|
|
|
|
}
|
|
void CHookMsgDlg::OnUpdateMonitorPause(CCmdUI* pCmdUI)
|
|
{
|
|
if(!m_bMonitorStatus)
|
|
pCmdUI->Enable(FALSE);
|
|
else
|
|
pCmdUI->Enable(TRUE);
|
|
}
|
|
|
|
void CHookMsgDlg::OnHookmsgHookstateCheck1()
|
|
{
|
|
m_bInputCode1 = ((CButton*)GetDlgItem( IDC_HOOKMSG_HOOKSTATE_CHECK1 ))->GetCheck();
|
|
|
|
if( m_bInputCode1 )
|
|
TraceMsg( "[TK] 종목코드 자동입력 설정됨.", CXListBox::Blue, CXListBox::White );
|
|
else
|
|
TraceMsg( "[TK] 종목코드 자동입력 해제됨.", CXListBox::Red, CXListBox::White );
|
|
}
|
|
|
|
void CHookMsgDlg::OnHookmsgHookstateCheck2()
|
|
{
|
|
m_bInputCode2 = ((CButton*)GetDlgItem( IDC_HOOKMSG_HOOKSTATE_CHECK2 ))->GetCheck();
|
|
|
|
if( m_bInputCode2 )
|
|
TraceMsg( "[NP] 종목코드 자동입력 설정됨.", CXListBox::Blue, CXListBox::White );
|
|
else
|
|
TraceMsg( "[NP] 종목코드 자동입력 해제됨.", CXListBox::Red, CXListBox::White );
|
|
}
|
|
|
|
void CHookMsgDlg::OnHookmsgHookstateCheck3()
|
|
{
|
|
m_bInputCode3 = ((CButton*)GetDlgItem( IDC_HOOKMSG_HOOKSTATE_CHECK3 ))->GetCheck();
|
|
|
|
if( m_bInputCode3 )
|
|
TraceMsg( "[7121] 종목코드 자동입력 설정됨.", CXListBox::Blue, CXListBox::White );
|
|
else
|
|
TraceMsg( "[7121] 종목코드 자동입력 해제됨.", CXListBox::Red, CXListBox::White );
|
|
}
|
|
|
|
void CHookMsgDlg::OnConfigRejectlistBtn()
|
|
{
|
|
CDlgEditTool dlg;
|
|
dlg.SetData( "거부리스트1" );
|
|
if( IDOK == dlg.DoModal() )
|
|
{
|
|
HWND hHookMsgApp = ::FindWindow( "TkrRdr_MainWnd", NULL );
|
|
if( ::IsWindow( hHookMsgApp ) )
|
|
::PostMessage( hHookMsgApp, WM_REJECTLISTUPDATE_COMMAND, NULL, NULL );
|
|
}
|
|
|
|
g_pStockData->InitExclusionCodeFromRegistery();
|
|
}
|
|
|
|
void CHookMsgDlg::OnConfigRejectlistBtn2()
|
|
{
|
|
CDlgEditTool dlg;
|
|
dlg.SetData( "거부리스트2" );
|
|
if( IDOK == dlg.DoModal() )
|
|
{
|
|
|
|
}
|
|
}
|
|
|
|
void CHookMsgDlg::OnConfigPassListBtn()
|
|
{
|
|
CDlgEditTool dlg(this);
|
|
dlg.SetData( "중복리스트" );
|
|
if( IDOK == dlg.DoModal() )
|
|
{
|
|
|
|
}
|
|
}
|
|
|
|
void CHookMsgDlg::OnConfigSpecialList()
|
|
{
|
|
CDlgEditTool dlg(this);
|
|
dlg.SetData( "특별종목리스트" );
|
|
if( IDOK == dlg.DoModal() )
|
|
{
|
|
|
|
}
|
|
}
|
|
|
|
void CHookMsgDlg::OnConfigManualList()
|
|
{
|
|
CDlgEditTool dlg(this);
|
|
dlg.SetData( "수동종목리스트" );
|
|
if( IDOK == dlg.DoModal() )
|
|
{
|
|
|
|
}
|
|
}
|
|
|
|
void CHookMsgDlg::OnConfigEnvBtn()
|
|
{
|
|
CConfigEnvDlg dlg;
|
|
|
|
UnregisterHotKey( m_hWnd, REGISTERHOTKEY_ID_LOCK );
|
|
UnregisterHotKey( m_hWnd, REGISTERHOTKEY_ID_NPINPUT );
|
|
|
|
dlg.DoModal();
|
|
|
|
InstallHotKey();
|
|
|
|
if( g_theApp.m_bTopmostWnd )
|
|
SetWindowPos(&wndTopMost, 0,0,0,0,SWP_NOSIZE|SWP_NOMOVE);
|
|
else
|
|
SetWindowPos(&wndNoTopMost, 0,0,0,0,SWP_NOSIZE|SWP_NOMOVE);
|
|
}
|
|
|
|
//void CHookMsgDlg::OnTopMostCheckbox()
|
|
//{
|
|
// if( g_bTopmostWnd )
|
|
// SetWindowPos(&wndNoTopMost, 0,0,0,0,SWP_NOSIZE|SWP_NOMOVE);
|
|
// else
|
|
// SetWindowPos(&wndTopMost, 0,0,0,0,SWP_NOSIZE|SWP_NOMOVE);
|
|
//
|
|
// g_bTopmostWnd = !g_bTopmostWnd;
|
|
//}
|
|
//void CHookMsgDlg::OnMakeTransparentWindowBtn()
|
|
//{
|
|
// UpdateData();
|
|
// if( m_nTransparentPercent == 100 )
|
|
// {
|
|
// ::SetWindowLong(m_hWnd, GWL_EXSTYLE, ::GetWindowLong(m_hWnd, GWL_EXSTYLE) & ~WS_EX_LAYERED );
|
|
// return;
|
|
// }
|
|
//
|
|
// if( 10 <= m_nTransparentPercent && m_nTransparentPercent < 100 )
|
|
// {
|
|
// if( g_hUserDll == NULL )
|
|
// g_hUserDll = ::LoadLibrary(_T("USER32.dll"));
|
|
//
|
|
// //Change style to layered window style...
|
|
// ::SetWindowLong(m_hWnd, GWL_EXSTYLE, ::GetWindowLong(m_hWnd, GWL_EXSTYLE) | WS_EX_LAYERED );
|
|
//
|
|
// SetTransparent(m_hWnd, 0, 255 * m_nTransparentPercent/100 , LWA_ALPHA );
|
|
// }
|
|
//}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// WM_USER + @ Message Handler function.
|
|
//
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
// 외부에서 모니터링 시작명령을 받을시...
|
|
LRESULT CHookMsgDlg::OnStartCommand(WPARAM wParam, LPARAM lParam)
|
|
{
|
|
OnMonitorStart();
|
|
return 0;
|
|
}
|
|
|
|
// 외부에서 모니터링 중단명령을 받을시...
|
|
LRESULT CHookMsgDlg::OnStopCommand(WPARAM wParam, LPARAM lParam)
|
|
{
|
|
// if( 1 == wParam )
|
|
|
|
OnMonitorPause();
|
|
return 0;
|
|
}
|
|
|
|
// 외부에서 거부리스트 갱신됨을 받을시...
|
|
LRESULT CHookMsgDlg::OnUpdateRejectListCommand(WPARAM wParam, LPARAM lParam)
|
|
{
|
|
g_pStockData->InitExclusionCodeFromRegistery();
|
|
return 0;
|
|
}
|
|
|
|
LRESULT CHookMsgDlg::OnTargetAppDestoryed( WPARAM wParam, LPARAM lParam )
|
|
{
|
|
int nWindow = (int)wParam;
|
|
|
|
CButton * pHookStatWnd1 = (CButton*)GetDlgItem( IDC_HOOKMSG_HOOKSTATE_CHECK1 );
|
|
CButton * pHookStatWnd2 = (CButton*)GetDlgItem( IDC_HOOKMSG_HOOKSTATE_CHECK2 );
|
|
CButton * pHookStatWnd3 = (CButton*)GetDlgItem( IDC_HOOKMSG_HOOKSTATE_CHECK3 );
|
|
|
|
switch( nWindow )
|
|
{
|
|
case UM_HOOKOK_WND1 :
|
|
pHookStatWnd1->SetCheck(FALSE);
|
|
pHookStatWnd1->EnableWindow(FALSE);
|
|
m_bInputCode1 = FALSE;
|
|
TraceMsg( "[TK] 윈도우가 닫혔습니다.", CXListBox::White, CXListBox::Red );
|
|
break;
|
|
case UM_HOOKOK_WND2 :
|
|
pHookStatWnd2->SetCheck(FALSE);
|
|
pHookStatWnd2->EnableWindow(FALSE);
|
|
m_bInputCode2 = FALSE;
|
|
TraceMsg( "[NP] 윈도우가 닫혔습니다.", CXListBox::White, CXListBox::Red );
|
|
break;
|
|
case UM_HOOKOK_WND3 :
|
|
pHookStatWnd3->SetCheck(FALSE);
|
|
pHookStatWnd3->EnableWindow(FALSE);
|
|
m_bInputCode3 = FALSE;
|
|
TraceMsg( "[7121] 윈도우가 닫혔습니다.", CXListBox::White, CXListBox::Red );
|
|
break;
|
|
default:
|
|
AfxMessageBox( "개발자에게 연락바랍니다.\r\nUndefined message recved !!" );
|
|
break;
|
|
}
|
|
|
|
OnMonitorPause();
|
|
return 0;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////
|
|
// < Cybos 2002 : ListBox Data Format >
|
|
//--------------------------------------------------------------------------------
|
|
// 8092 -> 1942@A45240@뉴씨앤씨 @7121@&-1&01(주)뉴씨앤씨 공정공시
|
|
// 1 |<->|2 3|<>|4
|
|
//--------------------------------------------------------------------------------
|
|
// 7121 -> 1239725@7121@0@2@ @1@20021204@1943@(주)뉴씨앤씨 공정공시 @공시사항@
|
|
// 1 2 3 4 5 6 7 8
|
|
//--------------------------------------------------------------------------------
|
|
//////////////////////////////////////////////////////////////////////////////////
|
|
BOOL CHookMsgDlg::OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct)
|
|
{
|
|
if( pCopyDataStruct->dwData == UM_HOOKOK_WND1 || // TK
|
|
pCopyDataStruct->dwData == UM_HOOKOK_WND2 || // NP
|
|
pCopyDataStruct->dwData == UM_HOOKOK_WND3 // 7001
|
|
)
|
|
{
|
|
SPYMSGDATA cpData;
|
|
memcpy(&cpData, (SPYMSGDATA*)pCopyDataStruct->lpData, sizeof(SPYMSGDATA)); // transfer data to internal variable
|
|
m_nSourceFrom = pCopyDataStruct->dwData;
|
|
|
|
if( pCopyDataStruct->dwData == UM_HOOKOK_WND1 || // TK
|
|
pCopyDataStruct->dwData == UM_HOOKOK_WND2 ) // NP
|
|
{
|
|
memset(m_szTitle, NULL, MAX_RECEIVE_LEN);
|
|
memcpy(m_szTitle, cpData.ExtraData, strlen((char*)cpData.ExtraData) );
|
|
}
|
|
else
|
|
{
|
|
DWORD dwWritten;
|
|
|
|
switch(cpData.lParam)
|
|
{
|
|
// 시간
|
|
case 1:
|
|
memcpy(m_szWnd3_Time, cpData.ExtraData, strlen((char*)cpData.ExtraData)+1);
|
|
m_szWnd3_Title[0] = NULL;
|
|
m_szWnd3_Name[0] = NULL;
|
|
break;
|
|
// 타이틀
|
|
case 2:
|
|
memcpy(m_szWnd3_Title, cpData.ExtraData, strlen((char*)cpData.ExtraData)+1);
|
|
TRACE("[2]%s(%s)\n", m_szWnd3_Title, m_szWnd3_Name);
|
|
break;
|
|
// 종목명
|
|
case 3:
|
|
memcpy(m_szWnd3_Name, cpData.ExtraData, strlen((char*)cpData.ExtraData)+1);
|
|
TRACE("[3]%s(%s)\n", m_szWnd3_Title, m_szWnd3_Name);
|
|
|
|
if(m_szWnd3_Name[0] != 0)
|
|
{
|
|
WriteFile(hFile,m_szWnd3_Time,strlen(m_szWnd3_Time),&dwWritten,NULL);
|
|
WriteFile(hFile,"\n",1,&dwWritten,NULL);
|
|
WriteFile(hFile,m_szWnd3_Title,strlen(m_szWnd3_Title),&dwWritten,NULL);
|
|
WriteFile(hFile,"\n",1,&dwWritten,NULL);
|
|
WriteFile(hFile,m_szWnd3_Name,strlen(m_szWnd3_Name),&dwWritten,NULL);
|
|
WriteFile(hFile,"\n\n",2,&dwWritten,NULL);
|
|
}
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
if( !m_bMonitorStatus )
|
|
{
|
|
//////////////////////////////////////////////////////////////////////
|
|
// 제목에서 종목코드찾기.
|
|
CString strJCode="";
|
|
CString strJName="";
|
|
CString strTitle = m_szTitle;
|
|
if( _ExtractJCode( m_nSourceFrom, strTitle, strJCode, strJName ) )
|
|
{
|
|
//////////////////////////////////////////////////////
|
|
// 잠김 상태에서도 한번 나온 종목은 무조건 [중복종목]에 등록함!
|
|
g_pStockData->AddRepeatedCode( strJCode );
|
|
}
|
|
|
|
if( m_nSourceFrom == UM_HOOKOK_WND2 )
|
|
{ // 핫키 입력시 종목코드 입력을 위해...
|
|
strncpy( m_szHotKey_JCode, (LPSTR)(LPCTSTR)strJCode.Right(6), 6 );
|
|
GetDlgItem(IDC_HOTKEYCODE_EDIT)->SetWindowText(m_szHotKey_JCode);
|
|
}
|
|
|
|
//////////////////////////////////////////////////////
|
|
// 7121 자동 클릭기능.
|
|
long dwDiffTime = ::GetTickCount() - m_dwMonitorPauseTime;
|
|
if( dwDiffTime <= g_AppEnv.n7121DbClickContinuePauseTime )
|
|
{
|
|
if( m_nSourceFrom == UM_HOOKOK_WND3 && g_AppEnv.b7121DbClick )
|
|
::SetTimer( m_hWnd, TIMEID_7121DBCLICK, g_AppEnv.n7121Delay, NULL );
|
|
}
|
|
|
|
// UM_HOOKOK_WND3 버퍼 초기화
|
|
// m_szWnd3_Title[0] = 0;
|
|
// m_szWnd3_Name[0] = 0;
|
|
|
|
return CDialog::OnCopyData(pWnd, pCopyDataStruct);
|
|
}
|
|
else
|
|
{
|
|
if(RetrieveNewsData())
|
|
{
|
|
m_pWorkEvent2->SetEvent();
|
|
m_pWorkEvent->SetEvent();
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
return CDialog::OnCopyData(pWnd, pCopyDataStruct);
|
|
}
|
|
|
|
BOOL CHookMsgDlg::_ExtractJCode( int nSrcType, CString & _strTitle, CString & strJCode, CString & strJName )
|
|
{
|
|
BOOL bRet = FALSE;
|
|
HRESULT hr;
|
|
ICpStockCodePtr objStockCode;
|
|
|
|
try
|
|
{
|
|
hr = objStockCode.CreateInstance( CLSID_CpStockCode ); // 종목코드변환.
|
|
|
|
CString strExt = "";
|
|
int nStep = 0;
|
|
|
|
if( nSrcType == UM_HOOKOK_WND1 ) // KOSDAQ 티커.
|
|
{
|
|
_strTitle.Replace( " ", " " );
|
|
if( _strTitle.Left(6) == "[공시]" )
|
|
{
|
|
while(AfxExtractSubString(strExt, _strTitle, nStep++, ' '))
|
|
{
|
|
if(nStep == 2)
|
|
{
|
|
strExt.Replace( "(주)", "" );
|
|
strExt.Replace( " ", "" );
|
|
|
|
strJCode = (LPCSTR)objStockCode->NameToCode( (LPCSTR)strExt ); // 예) "하이닉스" -> "A00660"
|
|
strJName = strExt;
|
|
bRet = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else if( nSrcType == UM_HOOKOK_WND2 ) // NewsPlus.
|
|
{
|
|
long _nCode;
|
|
int n = sscanf( _strTitle, "%06d", &_nCode );
|
|
if( n == 1 )
|
|
{
|
|
strJCode.Format( "A%06d", _nCode );
|
|
strJName = (LPCSTR)objStockCode->CodeToName( (LPCSTR)strJCode );
|
|
bRet = TRUE;
|
|
}
|
|
}
|
|
else if( nSrcType == UM_HOOKOK_WND3 ) // 7121 리스트.
|
|
{
|
|
/*
|
|
// "773033@7121@0032@2@0@53250@20031001@1536@(주)엔에스아이 명의개서정지등안내@코스닥@";
|
|
// ^ ^ ^ ^ ^ ^ ^ ^ ^ ^
|
|
while(AfxExtractSubString(strExt, _strTitle, nStep++, '@'))
|
|
{
|
|
if(nStep == 6)
|
|
{
|
|
strJCode = strExt;
|
|
strJName = (LPCSTR)objStockCode->CodeToName( (LPCSTR)strJCode );
|
|
}
|
|
else if( nStep == 9 )
|
|
{
|
|
_strTitle = strExt;
|
|
bRet = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
*/
|
|
//~!
|
|
|
|
strJCode = (LPCSTR)objStockCode->NameToCode( m_szWnd3_Name );
|
|
|
|
|
|
|
|
// 제목에서 코드 찾기
|
|
{
|
|
CString Name = "";
|
|
CString Code = "";
|
|
CString strTitleTmp = m_szWnd3_Title;
|
|
|
|
int iCommaPos = strTitleTmp.Find(",");
|
|
if(iCommaPos >= 0)
|
|
{
|
|
Name = GetLastWord(strTitleTmp.Left(iCommaPos));
|
|
}
|
|
else
|
|
{
|
|
int iSpacePos = strTitleTmp.Find(" ");
|
|
Name = strTitleTmp.Left(iSpacePos);
|
|
}
|
|
|
|
ICpStockCodePtr objStockCode;
|
|
objStockCode.CreateInstance( CLSID_CpStockCode );
|
|
Code = (LPCSTR)objStockCode->NameToCode((bstr_t)(LPCSTR)Name);
|
|
|
|
if(Code[0] != NULL)
|
|
{
|
|
strJCode = Code;
|
|
strJName = Name;
|
|
}
|
|
else if(g_Condition.m_SynonymList[Name.GetString()] != "")
|
|
{
|
|
Name = g_Condition.m_SynonymList[Name.GetString()].data();
|
|
Code = (LPCSTR)objStockCode->NameToCode((bstr_t)Name.GetString());
|
|
if(Code[0] != NULL)
|
|
{
|
|
strJCode = Code;
|
|
strJName = Name;
|
|
}
|
|
}
|
|
|
|
objStockCode.Release();
|
|
}
|
|
|
|
bRet = TRUE;
|
|
}
|
|
else if( nSrcType == UM_SRC_INFOTICKER )
|
|
{
|
|
//------------------------------------------------------------------------------------------------------
|
|
// 09030,20040908,131127,1102004090800005620040908000080,003160,[(주)디아이] ...... (k)타법인출자(주식및)
|
|
//------------------------------------------------------------------------------------------------------
|
|
while(AfxExtractSubString(strExt, _strTitle, nStep++, ','))
|
|
{
|
|
if(nStep == 1)
|
|
{
|
|
if( strExt != "09030" )
|
|
break;
|
|
}
|
|
else if( nStep == 4 )
|
|
{
|
|
if( strncmp((LPCSTR)strExt,"110", 3) != 0 )
|
|
break;
|
|
}
|
|
else if(nStep == 5)
|
|
{
|
|
strJCode.Format( "A%s", strExt ); // <-- 종목코드 구하기.
|
|
strJName = (LPCSTR)objStockCode->CodeToName( (LPCSTR)strJCode );
|
|
}
|
|
else if( nStep == 6 )
|
|
{
|
|
char szName[100]={0,};
|
|
char szData[100]={0,};
|
|
int n = sscanf( (LPCTSTR)strExt, "%s%s", szName, szData );
|
|
if( n == 2 )
|
|
{
|
|
_strTitle.Format( "%s %s", szName, szData ); // <-- 거래소 공시 타이틀 구하기.
|
|
bRet = TRUE;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
throw "데이터 소스를 알 수 없습니다.";
|
|
}
|
|
|
|
objStockCode.Release();
|
|
|
|
strJName.Replace( " ", "" );
|
|
strJCode.Replace( " ", "" );
|
|
|
|
if( strJCode.GetLength() != 7 )
|
|
bRet = FALSE;
|
|
}
|
|
catch( _com_error e ) {
|
|
objStockCode.Release();
|
|
}
|
|
catch( ... ) {
|
|
objStockCode.Release();
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
void CHookMsgDlg::_WorkThreadProc(UINT ThreadType)
|
|
{
|
|
//////////////////////////////////////////////////////////////////////
|
|
// Thread local 변수로 최대한 빨리 복사후 분석을 진행한다. 락킹이 필요하지만 속도를 고려해서 무시한다. 2004/5/6
|
|
|
|
int _nSourceFrom = m_nSourceFrom;
|
|
|
|
///////////////////////////////////////////////////////////////////////
|
|
// 시작시간을 기록함.
|
|
m_dwTickStart = ::GetTickCount();
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// 쓰레드 타입
|
|
CString strSrc="";
|
|
CXListBox::Color TxtColor, BgColor;
|
|
|
|
if(WORD_THREAD_WITHOUT_HOGA == ThreadType) {
|
|
if(m_bUsingStockCheckThread != TRUE)
|
|
return;
|
|
BgColor = CXListBox::BrightGray;
|
|
strSrc = "자동호가 ";
|
|
} else if(WORD_THREAD_WITH_HOGA == ThreadType) {
|
|
BgColor = CXListBox::White;
|
|
strSrc = "수동호가 ";
|
|
} else {
|
|
BgColor = CXListBox::Red;
|
|
strSrc = "쓰레드에러 ";
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// 뉴스 출처
|
|
if( _nSourceFrom == UM_HOOKOK_WND1 ) // KOSDAQ 티커.
|
|
{
|
|
TxtColor = CXListBox::Black;
|
|
strSrc += "[TK] ";
|
|
}
|
|
else if( _nSourceFrom == UM_HOOKOK_WND2 ) // NewsPlus.
|
|
{
|
|
if( m_pClientSocket )
|
|
{
|
|
m_strSendCommand = "[NP] " + g_strTitle;
|
|
PostMessage(WM_SVRSEND_COMMAND);
|
|
}
|
|
|
|
TxtColor = CXListBox::Olive;
|
|
strSrc += "[NP] ";
|
|
|
|
// 핫키 입력시 종목코드 입력을 위해...
|
|
strncpy( m_szHotKey_JCode, (LPSTR)(LPCTSTR)g_strJCode.Right(6), 6 );
|
|
GetDlgItem(IDC_HOTKEYCODE_EDIT)->SetWindowText(m_szHotKey_JCode);
|
|
}
|
|
else if( _nSourceFrom == UM_HOOKOK_WND3 ) // 7121.
|
|
{
|
|
TxtColor = CXListBox::Blue;
|
|
strSrc += "[7121] ";
|
|
}
|
|
else if( _nSourceFrom == UM_SRC_INFOTICKER ) // 거래소 InfoTicker
|
|
{
|
|
TxtColor = CXListBox::Blue;
|
|
strSrc += "[InfoTicker] ";
|
|
}
|
|
|
|
//
|
|
if(g_AppEnv_Debug.bTraceOnly)
|
|
return;
|
|
|
|
//////////////////////////////////////////////////////
|
|
// 종목코드의 상태를 얻어옴.
|
|
long nCodeIndex = atol( (LPSTR)(LPCTSTR)g_strJCode.Right(6) );
|
|
STOCKDATA * pCodeData = g_pStockData->GetStockData( nCodeIndex );
|
|
if( pCodeData == NULL )
|
|
{
|
|
TraceMsg( strSrc + "[ " + g_strJCode + " ] 인식이 않되는 종목코드입니다.", CXListBox::White, CXListBox::Red, TRUE );
|
|
return ;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////
|
|
// 거부리스트 검사.
|
|
if( pCodeData->bRejectedFromRegistery == true || // 거부종목 1.
|
|
pCodeData->bRejectedFromFile == true ) // 거부종목 2.
|
|
{
|
|
BOOL bContinueTrade = FALSE;
|
|
|
|
if( pCodeData->bRejectedFromFile == true )
|
|
{
|
|
if( g_AppEnv.bTradeCountCheck )
|
|
{
|
|
if( pCodeData->lTradeCount >= g_AppEnv.lTradeCount )
|
|
{
|
|
bContinueTrade = TRUE;
|
|
}
|
|
}
|
|
|
|
if( g_AppEnv.bTradeMoneyCheck )
|
|
{
|
|
if( pCodeData->lTradeMoney >= g_AppEnv.lTradeMoney )
|
|
{
|
|
bContinueTrade = TRUE;
|
|
}
|
|
}
|
|
}
|
|
|
|
if( bContinueTrade == FALSE )
|
|
{
|
|
PlaySound( "./거부리스트알림.wav" );
|
|
|
|
if( pCodeData->bRejectedFromFile == true )
|
|
TraceMsg( strSrc + "[거부종목2 알림] : " + g_strJCode +", " + g_strJName, TxtColor, BgColor, TRUE );
|
|
else
|
|
TraceMsg( strSrc + "[거부종목1 알림] : " + g_strJCode +", " + g_strJName, TxtColor, BgColor, TRUE );
|
|
|
|
HLStockWindowShow( g_strJCode, "거부리스트" );
|
|
return ;
|
|
}
|
|
|
|
PlaySound( "./거부리스트매매알림.wav" );
|
|
}
|
|
|
|
//////////////////////////////////////////////////////
|
|
// 수동_종목코드 검사.
|
|
if( pCodeData->bManualInputCode == true )
|
|
{
|
|
if( WORD_THREAD_WITH_HOGA == ThreadType && InputCodeTypeStatus(_nSourceFrom) )
|
|
{
|
|
TraceMsg( strSrc + "[수동종목 자동입력] : " + g_strJCode + ", " + g_strJName, TxtColor, BgColor, TRUE );
|
|
AutoInputJongmokCode(_nSourceFrom, g_strJCode.Right(6) );
|
|
if( g_AppEnv.bJInputAndStop1 )
|
|
{
|
|
OnMonitorPause();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
TraceMsg( strSrc + "[수동종목 알림] : " + g_strJCode +", " + g_strJName, TxtColor, BgColor, TRUE );
|
|
}
|
|
|
|
PlaySound( "./수동종목알림.wav" );
|
|
HLStockWindowShow( g_strJCode, "수동종목" );
|
|
return ;
|
|
}
|
|
//////////////////////////////////////////////////////
|
|
// 중복종목 검사.
|
|
if( pCodeData->bRepeated == true )
|
|
{
|
|
if( WORD_THREAD_WITH_HOGA == ThreadType && InputCodeTypeStatus(_nSourceFrom) )
|
|
{
|
|
TraceMsg( strSrc + "[중복종목 자동입력] : " + g_strJCode + ", " + g_strJName, TxtColor, BgColor, TRUE );
|
|
AutoInputJongmokCode(_nSourceFrom, g_strJCode.Right(6) );
|
|
if( g_AppEnv.bJInputAndStop1 )
|
|
{
|
|
OnMonitorPause();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
TraceMsg( strSrc + "[중복종목 알림] : " + g_strJCode +", " + g_strJName, TxtColor, BgColor, TRUE );
|
|
}
|
|
|
|
PlaySound( "./중복종목알림.wav" );
|
|
HLStockWindowShow( g_strJCode, "중복종목" );
|
|
return ;
|
|
}
|
|
|
|
HRESULT hr;
|
|
IDibPtr objStockJpbid2;
|
|
ICpTdDibPtr objCpTd03115;
|
|
ICpTdDibPtr objCpTd03147;
|
|
|
|
BOOL bBkColorStat = FALSE; // 상/하한가 안내창의 배경색지정.(상한 or 하한)
|
|
BOOL bSuccess = FALSE;
|
|
CString strSuccess = "";
|
|
CString strErrorMsg = "";
|
|
//~!
|
|
CString strTime = "";
|
|
TCHAR strMsg[256] = {0,};
|
|
DWORD dwTimeTotal;
|
|
|
|
BYTE cbStockType; // 종목구분.
|
|
long lStockPrice=0; // 투자금액.
|
|
long Cur_lStockPrice=0; // 현재가.
|
|
long nOrder=10; // 주문수량.
|
|
long nCallLevel=0; // 호가 레벨.
|
|
long nTotalBattingMoney = 0; // 설정한 배팅금액.
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// 제목만으로 조건검색을 진행함!
|
|
HM_CONDITION_TYPE ConditionType = g_Condition.DetectConditionTitle( g_strTitle, _nSourceFrom );
|
|
|
|
//////////////////////////////////////////////////////
|
|
// 종목코드 자동입력.
|
|
if( WORD_THREAD_WITH_HOGA == ThreadType && (bSuccess || InputCodeTypeStatus(_nSourceFrom)) )
|
|
{
|
|
TraceMsg( strSrc + "[종목코드 자동입력] : " + g_strJCode + ", " + g_strJName, TxtColor, BgColor, TRUE );
|
|
AutoInputJongmokCode(_nSourceFrom, g_strJCode.Right(6) );
|
|
|
|
if( g_AppEnv.bJInputAndStop2 ) // 2003-11-15 코드삭제. 2004.4.28 추가변경.
|
|
{
|
|
OnMonitorPause();
|
|
}
|
|
}
|
|
|
|
|
|
if( ConditionType != HM_CONDITION_TYPE_FALSE )
|
|
{
|
|
try
|
|
{
|
|
if( ConditionType == HM_CONDITION_TYPE_TRUE )
|
|
{
|
|
if( pCodeData->bSpecialCodeByPublish == true )
|
|
{
|
|
nTotalBattingMoney = g_AppEnv.Money2; // 공시 거래금액(특별).
|
|
nCallLevel = g_AppEnv.Level2-1; // 공시 매수레벨(특별).
|
|
|
|
if(g_AppEnv.bMesuUsingMacro2)
|
|
{
|
|
EmulateHotkey(g_AppEnv.MesuHotKey2.wVk, g_AppEnv.MesuHotKey2.wModifier);
|
|
TraceMsg("공시(특별) 주문 매크로가 실행되었습니다.");
|
|
goto _LAST_JOB_;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
nTotalBattingMoney = g_AppEnv.Money1; // 공시 거래금액(일반).
|
|
nCallLevel = g_AppEnv.Level1-1; // 공시 매수레벨(일반).
|
|
|
|
if(g_AppEnv.bMesuUsingMacro1)
|
|
{
|
|
EmulateHotkey(g_AppEnv.MesuHotKey1.wVk, g_AppEnv.MesuHotKey1.wModifier);
|
|
TraceMsg("공시(일반) 주문 매크로가 실행되었습니다.");
|
|
goto _LAST_JOB_;
|
|
}
|
|
}
|
|
}
|
|
else if( ConditionType == HM_CONDITION_TYPE_SPECIAL )
|
|
{
|
|
nTotalBattingMoney = g_AppEnv.Money4; // 뉴스플러스 거래금액(특별).
|
|
nCallLevel = g_AppEnv.Level4-1; // 뉴스플러스 매수레벨(특별).
|
|
|
|
if(g_AppEnv.bMesuUsingMacro4)
|
|
{
|
|
EmulateHotkey(g_AppEnv.MesuHotKey4.wVk, g_AppEnv.MesuHotKey4.wModifier);
|
|
TraceMsg("NP(특별) 주문 매크로가 실행되었습니다.");
|
|
goto _LAST_JOB_;
|
|
}
|
|
}
|
|
else if( ConditionType == HM_CONDITION_TYPE_NORMAL )
|
|
{
|
|
nTotalBattingMoney = g_AppEnv.Money3; // 뉴스플러스 거래금액(일반).
|
|
nCallLevel = g_AppEnv.Level3-1; // 뉴스플러스 매수레벨(일반).
|
|
|
|
if(g_AppEnv.bMesuUsingMacro3)
|
|
{
|
|
EmulateHotkey(g_AppEnv.MesuHotKey3.wVk, g_AppEnv.MesuHotKey3.wModifier);
|
|
TraceMsg("NP(일반) 주문 매크로가 실행되었습니다.");
|
|
goto _LAST_JOB_;
|
|
}
|
|
}
|
|
else if( ConditionType == HM_CONDITION_TYPE_MANUAL )
|
|
{
|
|
nTotalBattingMoney = g_AppEnv.Money3; // 뉴스플러스 거래금액(일반).
|
|
nCallLevel = g_AppEnv.Level3-1; // 뉴스플러스 매수레벨(일반).
|
|
|
|
// ***
|
|
SetForegroundWindow();
|
|
CString Message;
|
|
Message.Format("%s(%s)\n\n수동 종목입니다. 매수 진행하시겠습니까?", (LPCSTR)g_strJName, (LPCSTR)g_strJCode);
|
|
if(MessageBox(Message, "수동 종목", MB_YESNO) != IDYES)
|
|
goto _LAST_JOB_;
|
|
|
|
// 팝업을 기다리는 동안의 시간을 취소 대기 시간에서 제외
|
|
m_dwTickStart = ::GetTickCount();
|
|
|
|
if(g_AppEnv.bMesuUsingMacro3)
|
|
{
|
|
EmulateHotkey(g_AppEnv.MesuHotKey3.wVk, g_AppEnv.MesuHotKey3.wModifier);
|
|
TraceMsg("NP(일반) 주문 매크로가 실행되었습니다.");
|
|
goto _LAST_JOB_;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
TraceMsg( strSrc + "잘못된 리턴값입니다. 개발자에게 연략바랍니다.", CXListBox::White, CXListBox::Red, TRUE );
|
|
goto _LAST_JOB_;
|
|
}
|
|
|
|
BOOL bCheckState = g_pStockData->StockVerify( nCodeIndex, Cur_lStockPrice, cbStockType );
|
|
if( m_bUsingStockCheckThread == TRUE && WORD_THREAD_WITHOUT_HOGA == ThreadType)
|
|
{
|
|
if( bCheckState == TRUE )
|
|
lStockPrice = g_pStockData->ReCalcPrice( Cur_lStockPrice, nCallLevel ); // 호가 재계산...
|
|
else
|
|
bCheckState = FALSE;
|
|
}
|
|
else
|
|
{
|
|
bCheckState = FALSE;
|
|
}
|
|
|
|
strErrorMsg += "종목코드: " + g_strJCode + "\r\n";
|
|
if( bCheckState == FALSE )
|
|
{
|
|
hr = objStockJpbid2.CreateInstance( CLSID_StockJpbid2 ); // 호가정보처리.
|
|
|
|
objStockJpbid2->SetInputValue( 0, (LPCSTR)g_strJCode );
|
|
|
|
DWORD dwLimitCallStart = ::GetTickCount();
|
|
objStockJpbid2->BlockRequest();
|
|
DWORD dwLimitCallEnd = ::GetTickCount();
|
|
|
|
strTime.Format("(%d ms)",dwLimitCallEnd-dwLimitCallStart);
|
|
|
|
if( (long)(dwLimitCallEnd-dwLimitCallStart) >= g_AppEnv.LimitCall ) // 2003.10.30 추가.
|
|
{
|
|
TraceMsg( strSrc + "호가요청 응답이 제한시간을 초과하였습니다."+strTime, CXListBox::White, CXListBox::Red, TRUE );
|
|
PlayResource(IDR_MSGTYPE_WAVE);
|
|
|
|
objStockJpbid2.Release();
|
|
goto _LAST_JOB_;
|
|
}
|
|
|
|
TraceMsg( strSrc + "[호가요청 Ok]" + g_strJName+strTime, TxtColor, BgColor, TRUE );
|
|
|
|
lStockPrice = objStockJpbid2->GetDataValue(0, nCallLevel); // n차 매도호가.
|
|
Cur_lStockPrice = objStockJpbid2->GetDataValue(0, (long)0); // (1차매도호가)현재가.
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
|
// 상한가 / 하한가 체크. (편법) 거래소:15%, 코스닥:12% 검증방식이 아닌 10차 호가만으로 검사함.
|
|
long _lLowCheck = objStockJpbid2->GetDataValue(1, (long)1); // 2차 매수호가.(하한가 체크).
|
|
objStockJpbid2.Release();
|
|
|
|
if( _lLowCheck==0 || lStockPrice==0 )
|
|
{
|
|
HLStockWindowShow( g_strJCode, "호가요청후" );
|
|
|
|
CString strErr;
|
|
strErr.Format( "\r\n2차매수 호가: %d \r\n%d차매도 호가: %d", _lLowCheck, nCallLevel+1, lStockPrice );
|
|
strErrorMsg += strErr;
|
|
|
|
TraceMsg( strSrc + strErrorMsg, TxtColor, BgColor, TRUE );
|
|
PlayResource(IDR_MSGTYPE_WAVE);
|
|
goto _LAST_JOB_;
|
|
}
|
|
|
|
if( g_theApp.m_bHogaLevelCalc ) // 현재가미적용시 매매단계 호가자동계산 적용.
|
|
{
|
|
// 호가 재계산...
|
|
lStockPrice = g_pStockData->ReCalcPrice( Cur_lStockPrice, nCallLevel );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if( pCodeData->bLowest == true || pCodeData->bHeigest == true )
|
|
{
|
|
strErrorMsg += "*현재가 적용중*";
|
|
|
|
HLStockWindowShow( g_strJCode, strErrorMsg );
|
|
|
|
TraceMsg( strSrc + strErrorMsg, TxtColor, BgColor, TRUE );
|
|
PlayResource(IDR_MSGTYPE_WAVE);
|
|
goto _LAST_JOB_;
|
|
}
|
|
}
|
|
|
|
nOrder = nTotalBattingMoney / lStockPrice;
|
|
nOrder = nOrder - (nOrder%10);
|
|
|
|
if( cbStockType == 0 || cbStockType == 1 || cbStockType == 5 ) // 거래소 or 코스닥. -> StockMstm에 구분 사라짐 ***
|
|
{
|
|
objCpTd03115.CreateInstance( CLSID_CpTd0311 ); // 거래소 매매처리.
|
|
}
|
|
else
|
|
{
|
|
TraceMsg( strSrc + "거래소/코스닥 종목이 아닙니다." );
|
|
goto _LAST_JOB_;
|
|
}
|
|
|
|
DWORD dwCallTime = ::GetTickCount();
|
|
if( !g_AppEnv.bSuccessiveBuy && (dwCallTime-m_dwCallTimeLast) <= 30000 )
|
|
{
|
|
m_dwCallTimeLast = dwCallTime;
|
|
|
|
TraceMsg( strSrc + "마지막 매수주문이 30초를 지나지 않았습니다.", CXListBox::White, CXListBox::Red, TRUE );
|
|
goto _LAST_JOB_;
|
|
}
|
|
|
|
m_dwCallTimeLast = dwCallTime;
|
|
|
|
objCpTd03115->SetInputValue( 0, (LPCSTR)"2" ); // 주문구분.
|
|
objCpTd03115->SetInputValue( 1, (LPCSTR)g_theApp.m_strBankAccount ); // 계좌번호.
|
|
objCpTd03115->SetInputValue( 2, (LPCSTR)"10" ); // 계좌구분. ***상품관리구분코드
|
|
objCpTd03115->SetInputValue( 3, (LPCSTR)g_strJCode ); // 종목코드.
|
|
objCpTd03115->SetInputValue( 4, (long)nOrder ); // 주문수량.
|
|
objCpTd03115->SetInputValue( 5, (long)lStockPrice ); // 주문단가.
|
|
//objCpTd03115->SetInputValue( 6, (LPCSTR)"00" ); // 매매구분, 00:보통(삭제예정)
|
|
objCpTd03115->SetInputValue( 8, (LPCSTR)"01" ); // 주문호가구분코드, 01:보통
|
|
|
|
short nRet = objCpTd03115->BlockRequest();
|
|
TraceMsg( strSrc + "[매수주문 Ok]", TxtColor, BgColor, TRUE );
|
|
if( nRet != 0 )
|
|
{
|
|
strErrorMsg = "[통신에러] :";
|
|
if (0 != objCpTd03115->GetDibStatus()) {
|
|
strErrorMsg += (LPSTR)objCpTd03115->GetDibMsg1();
|
|
strErrorMsg += (LPSTR)objCpTd03115->GetDibMsg2();
|
|
strErrorMsg.TrimRight();
|
|
AfxMessageBox(strErrorMsg);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
strSuccess += "[매수주문] : ";
|
|
strSuccess += (LPSTR)objCpTd03115->GetDibMsg1();
|
|
if( objCpTd03115->GetDibStatus() == 0 )
|
|
bSuccess = TRUE;
|
|
}
|
|
|
|
// long nMedoLevel = nCallLevel + g_AppEnv.LevelMedo;
|
|
// if( nMedoLevel > 9 ) nMedoLevel = 9;
|
|
// m_nAutoMedoMoney = objStockJpbid2->GetDataValue(0, nMedoLevel ); // n차 매도호가.
|
|
|
|
m_nSrcJumoon_Number = objCpTd03115->GetHeaderValue(8); // 자동매수 (원 주문번호) 알아내기.
|
|
objCpTd03115.Release();
|
|
}
|
|
catch( _com_error e )
|
|
{
|
|
_bstr_t bstrSource(e.Source());
|
|
_bstr_t bstrDescription(e.Description());
|
|
|
|
strErrorMsg.Format(
|
|
"[매수주문 실행중 문제가 발생하였습니다.]\n"
|
|
"Code = = %08lx\n"
|
|
"Code meaning = %s\n"
|
|
"Source = %s\n"
|
|
"Description = %s", e.Error(), e.ErrorMessage(), (LPCTSTR) bstrSource, (LPCTSTR) bstrDescription );
|
|
|
|
MessageBox( strErrorMsg, "매매실패!", MB_OK|MB_ICONSTOP );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
HLStockWindowShow( g_strJCode, "조건 불일치" );
|
|
}
|
|
|
|
dwTimeTotal = ::GetTickCount() - m_dwTickStart;
|
|
|
|
if( bSuccess )
|
|
{
|
|
strSuccess.Replace( " ", "" );
|
|
TraceMsg( strSrc + strSuccess, TxtColor, BgColor );
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
// 미체결 잔량 '전량 취소’
|
|
if( g_AppEnv.bNotContractedCancel )
|
|
{
|
|
try
|
|
{
|
|
if( cbStockType == 0 || cbStockType == 1 || cbStockType == 5 ) // 거래소 or KOSDAQ -> StockMstm에 구분 사라짐 ***
|
|
{
|
|
hr = objCpTd03147.CreateInstance( CLSID_CpTd0314 ); // 거래소 취소주문객체. or KOSDAQ 취소주문객체
|
|
}
|
|
else
|
|
{
|
|
TraceMsg( strSrc + "거래소/코스닥 종목이 아닙니다." );
|
|
goto _LAST_JOB_;
|
|
}
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
//objCpTd03147->SetInputValue( 0, (LPCSTR)"2" ); // 잔량 취소 (사용하지 않음)
|
|
objCpTd03147->SetInputValue( 1, (long)m_nSrcJumoon_Number); // 주문 번호
|
|
objCpTd03147->SetInputValue( 2, (LPCSTR)g_theApp.m_strBankAccount ); // 계좌번호.
|
|
objCpTd03147->SetInputValue( 3, (LPCSTR)"10" ); // 계좌구분 -> 상품관리구분코드
|
|
objCpTd03147->SetInputValue( 4, (LPCSTR)g_strJCode ); // 종목코드.
|
|
objCpTd03147->SetInputValue( 5, (long)0 ); // 취소수량.
|
|
|
|
short nRet = objCpTd03147->BlockRequest();
|
|
TraceMsg(strSrc + "[취소주문 Ok]", TxtColor, BgColor, TRUE);
|
|
|
|
CString strMessageCancel = "";
|
|
if( nRet != 0 )
|
|
{
|
|
strMessageCancel += "[잔량취소 통신에러] :";
|
|
if( objCpTd03147->GetDibStatus() != 0 )
|
|
{
|
|
strMessageCancel += (LPSTR)objCpTd03147->GetDibMsg1();
|
|
strMessageCancel += (LPSTR)objCpTd03147->GetDibMsg2();
|
|
strMessageCancel.TrimRight();
|
|
AfxMessageBox(strMessageCancel);
|
|
}
|
|
|
|
TraceMsg( strSrc + strMessageCancel, CXListBox::White, CXListBox::Red );
|
|
}
|
|
else
|
|
{
|
|
strMessageCancel += (LPSTR)objCpTd03147->GetDibMsg1();
|
|
strMessageCancel += (LPSTR)objCpTd03147->GetDibMsg2();
|
|
|
|
if( objCpTd03147->GetDibStatus() != 0 )
|
|
TraceMsg( strSrc + "잔량취소 실패: " + strMessageCancel, CXListBox::White, CXListBox::Red );
|
|
else
|
|
TraceMsg( strSrc + "[취소주문] : " + strMessageCancel, TxtColor, BgColor );
|
|
}
|
|
}
|
|
|
|
objCpTd03147.Release();
|
|
}
|
|
catch( _com_error e )
|
|
{
|
|
TraceMsg( strSrc + "미체결 '잔량처리'중에 문제가 발생하였습니다.(연락바람니다.)", CXListBox::White, CXListBox::Red );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
TraceMsg( strSrc + "미결제 잔량취소기능이 Off상태입니다.", CXListBox::White, CXListBox::Red );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if( strSuccess != "" )
|
|
{
|
|
strSuccess.Replace( " ", "" );
|
|
TraceMsg( strSrc + strSuccess, TxtColor, BgColor );
|
|
|
|
wsprintf( strMsg, "[매수실패] 소요시간:%dms 수량:%d, 단가:%d, 레벨:%d, 현재가:%d.",
|
|
dwTimeTotal, nOrder, lStockPrice, nCallLevel, Cur_lStockPrice );
|
|
TraceMsg( strSrc + strMsg, TxtColor, BgColor, TRUE );
|
|
}
|
|
else
|
|
{
|
|
TraceMsg( strSrc + "[매수조건에 일치하지 않습니다.]", TxtColor, BgColor, TRUE );
|
|
}
|
|
|
|
PlayResource(IDR_MSGTYPE_WAVE);
|
|
}
|
|
|
|
if( bSuccess )
|
|
{
|
|
// 로그분석시에 사용하는 문장이므로 수정불가 -> "[매수성공] %s ..."
|
|
wsprintf( strMsg, "[매수성공] %s 소요시간:%dms 수량:%d, 단가:%d, 레벨:%d, 현재가:%d.",
|
|
(LPSTR)(LPCTSTR)g_strJCode, dwTimeTotal, nOrder, lStockPrice, nCallLevel, Cur_lStockPrice );
|
|
|
|
TraceMsg( strSrc + strMsg, TxtColor, BgColor, TRUE );
|
|
PlaySound( "./자동매수알림.wav" );
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
// 성림씨 프로그램의 동작을 멈추게함!
|
|
HWND hTkrRdrApp = ::FindWindow( "TkrRdr_MainWnd", NULL );
|
|
if( ::IsWindow( hTkrRdrApp ) )
|
|
::PostMessage( hTkrRdrApp, WM_STOP_COMMAND, NULL, NULL );
|
|
|
|
//////////////////////////////////////////////////////
|
|
// 매수성공->자동취소성공시 화면전환기능 수행!
|
|
AutoScreenSwitch();
|
|
}
|
|
|
|
_LAST_JOB_:
|
|
|
|
//////////////////////////////////////////////////////
|
|
// 무조건 한번 나온 종목은 [중복종목]에 등록함!
|
|
g_pStockData->AddRepeatedCode( g_strJCode );
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
// override to do startup
|
|
void CHookMsgDlg::StartWork()
|
|
{
|
|
CoInitialize(NULL);
|
|
}
|
|
/////////////////////////////////////////////////////////////////////////
|
|
// override to do work
|
|
void CHookMsgDlg::DoWork(UINT ThreadType)
|
|
{
|
|
try
|
|
{
|
|
HANDLE hThread = GetHandle();
|
|
int nPrevThreadPriority = ::GetThreadPriority( hThread );
|
|
|
|
::SetThreadPriority(hThread, THREAD_PRIORITY_TIME_CRITICAL);
|
|
|
|
g_pStockData->m_bRunningSkip = TRUE;
|
|
_WorkThreadProc(ThreadType);
|
|
g_pStockData->m_bRunningSkip = FALSE;
|
|
|
|
::SetThreadPriority(hThread, nPrevThreadPriority);
|
|
}
|
|
catch( _com_error e )
|
|
{
|
|
::MessageBox( NULL, "뉴스매매 프로그램 오류가 발생하였습니다. 에러코드:001", "뉴스매매 Main Thread", MB_ICONERROR|MB_TOPMOST );
|
|
}
|
|
catch(...)
|
|
{
|
|
::MessageBox( NULL, "뉴스매매 프로그램 오류가 발생하였습니다. 에러코드:002", "뉴스매매 Main Thread", MB_ICONERROR|MB_TOPMOST );
|
|
}
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
// override to do shutdown
|
|
void CHookMsgDlg::EndWork()
|
|
{
|
|
CoUninitialize();
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// Helper function.
|
|
//
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
void CHookMsgDlg::InstallHotKey()
|
|
{
|
|
UINT fsModifier = 0;
|
|
if (HOTKEYF_ALT & g_AppEnv.LockUnlockHotKey.wModifier)
|
|
fsModifier |= MOD_ALT;
|
|
if (HOTKEYF_CONTROL & g_AppEnv.LockUnlockHotKey.wModifier)
|
|
fsModifier |= MOD_CONTROL;
|
|
if (HOTKEYF_SHIFT & g_AppEnv.LockUnlockHotKey.wModifier)
|
|
fsModifier |= MOD_SHIFT;
|
|
if (!RegisterHotKey(m_hWnd, REGISTERHOTKEY_ID_LOCK,
|
|
fsModifier, g_AppEnv.LockUnlockHotKey.wVk))
|
|
{
|
|
Message_Box( " 핫키등록 실패 - [잠김/풀림]", ::GetLastError() );
|
|
TraceMsg( "HotKey 등록 : [잠김/풀림] 등록실패!", CXListBox::Red, CXListBox::Yellow );
|
|
}
|
|
|
|
fsModifier = 0;
|
|
if (HOTKEYF_ALT & g_AppEnv.NP_InputCodeHotKey.wModifier)
|
|
fsModifier |= MOD_ALT;
|
|
if (HOTKEYF_CONTROL & g_AppEnv.NP_InputCodeHotKey.wModifier)
|
|
fsModifier |= MOD_CONTROL;
|
|
if (HOTKEYF_SHIFT & g_AppEnv.NP_InputCodeHotKey.wModifier)
|
|
fsModifier |= MOD_SHIFT;
|
|
if (!RegisterHotKey(m_hWnd, REGISTERHOTKEY_ID_NPINPUT,
|
|
fsModifier, g_AppEnv.NP_InputCodeHotKey.wVk))
|
|
{
|
|
// Message_Box( " 핫키등록 실패 - [잠김때 NewsPlus 수동 종목코드입력]", ::GetLastError() );
|
|
TraceMsg( "HotKey 등록 : [잠김때 NewsPlus 수동 종목코드입력] 등록실패!", CXListBox::Red, CXListBox::Yellow );
|
|
}
|
|
}
|
|
|
|
void CHookMsgDlg::EmulateHotkey( WORD wVk, WORD wModifier )
|
|
{
|
|
//-----------------------------------------------------
|
|
// 매크로 프로그램에서 이미 등록된 HotKey는 재등록이 않되므로
|
|
// 내 프로그램에서는 Alt키를 함께 조합해서 등록하고
|
|
// 매크로 프로그램에서는 Alt키를 조합시키지않고 나머지는 동일하게 등록해야함.
|
|
//-----------------------------------------------------
|
|
// if (HOTKEYF_ALT & wModifier)
|
|
// keybd_event(VK_MENU, 0, 0, 0);
|
|
if (HOTKEYF_CONTROL & wModifier)
|
|
keybd_event(VK_CONTROL, 0, 0, 0);
|
|
if (HOTKEYF_SHIFT & wModifier)
|
|
keybd_event(VK_SHIFT, 0, 0, 0);
|
|
|
|
// SHORT byMbyVK = VkKeyScan(ch);
|
|
// BYTE byM = HIBYTE(byMbyVK);
|
|
// BYTE byVK = LOBYTE(byMbyVK);
|
|
// if (-1 == byM || -1 == byVK) // match not found
|
|
// return;
|
|
BYTE byScan = MapVirtualKey(wVk, 0);
|
|
keybd_event( LOBYTE(wVk), byScan, 0, 0);
|
|
|
|
//-----------------------------------------------------
|
|
// if (HOTKEYF_ALT & wModifier)
|
|
// keybd_event(VK_MENU, 0, KEYEVENTF_KEYUP, 0);
|
|
if (HOTKEYF_CONTROL & wModifier)
|
|
keybd_event(VK_CONTROL, 0, KEYEVENTF_KEYUP, 0);
|
|
if (HOTKEYF_SHIFT & wModifier)
|
|
keybd_event(VK_SHIFT, 0, KEYEVENTF_KEYUP, 0);
|
|
}
|
|
|
|
void CHookMsgDlg::TraceMsg( CString strMsg, CXListBox::Color tc, CXListBox::Color bc, BOOL bWriteFile )
|
|
{
|
|
static char szTime[20];
|
|
static SYSTEMTIME time;
|
|
GetLocalTime(&time);
|
|
|
|
wsprintf(szTime, "[%02u:%02u:%02u:%03u] ", time.wHour, time.wMinute, time.wSecond, time.wMilliseconds);
|
|
|
|
CString strTrace = "";
|
|
strTrace = szTime;
|
|
strTrace += strMsg;
|
|
|
|
m_hTraceListBox.InsertString( 0, strTrace, tc, bc );
|
|
|
|
if( bWriteFile )
|
|
{
|
|
// write string, without null-terminator
|
|
strTrace.Replace( "\r\n", " " );
|
|
strTrace += "\r\n";
|
|
g_pLogFile->Write(strTrace, strTrace.GetLength());
|
|
|
|
// LogTrace(strTrace);
|
|
}
|
|
}
|
|
|
|
void CHookMsgDlg::PlaySound( CString strWaveFile )
|
|
{
|
|
if( g_AppEnv.bUseSoundEffect )
|
|
{
|
|
::PlaySound( strWaveFile, NULL, SND_ASYNC );
|
|
}
|
|
}
|
|
|
|
void CHookMsgDlg::AutoInputJongmokCode(int nSrcFrom, CString strCode )
|
|
{
|
|
// 03XX 윈도우에 종목코드를 입력하는 샘플코드.
|
|
LPARAM lParam = (LPARAM)(LPCTSTR)strCode;
|
|
if( ::IsWindow( g_theApp.m_hFindWindow[3] ) )
|
|
{
|
|
::SendMessage( g_theApp.m_hFindWindow[3], WM_SETTEXT, NULL, (LPARAM)lParam); // 종목코드를 자동입력함 (First).
|
|
::SendMessage( g_theApp.m_hFindWindow[3], WM_SETFOCUS, NULL, 0 );
|
|
::SendMessage( g_theApp.m_hFindWindow[3], WM_CHAR, 0, 0 );
|
|
}
|
|
if( ::IsWindow( g_theApp.m_hFindWindow[4] ) )
|
|
{
|
|
::SendMessage( g_theApp.m_hFindWindow[4], WM_SETTEXT, NULL, (LPARAM)lParam); // 종목코드를 자동입력함(Second).
|
|
::SendMessage( g_theApp.m_hFindWindow[4], WM_SETFOCUS, NULL, 0 );
|
|
::SendMessage( g_theApp.m_hFindWindow[4], WM_CHAR, 0, 0 );
|
|
}
|
|
|
|
//////////////////////////////////////////////////////
|
|
// 7121 자동 클릭기능.
|
|
if( nSrcFrom == UM_HOOKOK_WND3 && g_AppEnv.b7121DbClick )
|
|
::SetTimer( m_hWnd, TIMEID_7121DBCLICK, g_AppEnv.n7121Delay, NULL );
|
|
}
|
|
|
|
void CHookMsgDlg::AutoScreenSwitch()
|
|
{
|
|
// 화면번호를 입력하는 샘플코드.
|
|
if( ::IsWindow( g_theApp.m_hFindWindow[5] ) )
|
|
{
|
|
::SendMessage( g_theApp.m_hFindWindow[5], WM_SETTEXT, NULL, (LPARAM)"" ); // 매도(0311)화면으로 자동전환시킴.
|
|
::SendMessage( g_theApp.m_hFindWindow[5], WM_SETFOCUS, NULL, 0 );
|
|
::SendMessage( g_theApp.m_hFindWindow[5], WM_CHAR, g_AppEnv.strScreenNumber[0], 0L );
|
|
::SendMessage( g_theApp.m_hFindWindow[5], WM_CHAR, g_AppEnv.strScreenNumber[1], 0L );
|
|
::SendMessage( g_theApp.m_hFindWindow[5], WM_CHAR, g_AppEnv.strScreenNumber[2], 0L );
|
|
::SendMessage( g_theApp.m_hFindWindow[5], WM_CHAR, g_AppEnv.strScreenNumber[3], 0L );
|
|
}
|
|
}
|
|
|
|
void CHookMsgDlg::OnGetMinMaxInfo(MINMAXINFO FAR* lpMMI)
|
|
{
|
|
CDialog::OnGetMinMaxInfo(lpMMI);
|
|
|
|
lpMMI->ptMinTrackSize.x = 100;
|
|
lpMMI->ptMinTrackSize.y = 70;
|
|
lpMMI->ptMaxTrackSize.x= ::GetSystemMetrics(SM_CXSCREEN);
|
|
lpMMI->ptMaxTrackSize.y= ::GetSystemMetrics(SM_CYSCREEN);
|
|
}
|
|
|
|
void CHookMsgDlg::OnSize(UINT nType, int cx, int cy)
|
|
{
|
|
CDialog::OnSize(nType, cx, cy);
|
|
|
|
if( m_bInitSuccess )
|
|
{
|
|
SetDlgCtrlPosition( cx, cy );
|
|
RedrawWindow();
|
|
}
|
|
}
|
|
|
|
void CHookMsgDlg::SetDlgCtrlPosition(int cx, int cy)
|
|
{
|
|
int _nHeightCaption = ::GetSystemMetrics( SM_CYCAPTION );
|
|
_nHeightCaption += (::GetSystemMetrics( SM_CYBORDER )*2);
|
|
|
|
GetDlgItem(IDC_TRACE_LIST )->MoveWindow( 1, 75, cx-2, cy- _nHeightCaption -73, FALSE );
|
|
|
|
GetDlgItem(IDC_HOOKMSG_STOCKPRICECHECK_CHK)->MoveWindow( 5, 75+(cy- _nHeightCaption -71), 85, 18, FALSE );
|
|
GetDlgItem(IDC_HOOKMSGDLG_CP_VALUE_STATIC )->MoveWindow( 100, 75+(cy- _nHeightCaption -70), 90, 16, FALSE );
|
|
|
|
GetDlgItem(IDC_HOTKEYCODE_STATIC )->MoveWindow( 200, 75+(cy- _nHeightCaption -70), 70, 16, FALSE );
|
|
GetDlgItem(IDC_HOTKEYCODE_EDIT )->MoveWindow( 275, 75+(cy- _nHeightCaption -70), 45, 16, FALSE );
|
|
}
|
|
|
|
void CHookMsgDlg::OnHookmsgMedoBtn()
|
|
{
|
|
#ifdef _DEBUG
|
|
///////////////////////////////////////////////////////////////////////////
|
|
// 자동매도 프로그램에게 매도메시지 보냄.
|
|
HWND hStockAutoSaleApp = ::FindWindow( "StockAutoSale_MainWnd", NULL );
|
|
if( ::IsWindow( hStockAutoSaleApp ) )
|
|
{
|
|
memset( &g_AutomedoData, NULL, sizeof(AUTOMEDO_MSGDATA) );
|
|
|
|
strncpy( (char*)g_AutomedoData.szJCode, "A000250", 6 );
|
|
g_AutomedoData.nMesuDanga = 2384;
|
|
g_AutomedoData.nMesuSu = 410;
|
|
|
|
g_AutoMedoCopyDataStructure.dwData = UM_AUTOMEDO;
|
|
::SendMessage(hStockAutoSaleApp, WM_COPYDATA, (WPARAM)m_hWnd, (LPARAM)&g_AutoMedoCopyDataStructure);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
LONG CHookMsgDlg::OnReceived(WPARAM wParam, LPARAM lParam)
|
|
{
|
|
/*
|
|
CString strMsg="";
|
|
|
|
try
|
|
{
|
|
if (0 != m_pCpConclusion->GetDibStatus()) {
|
|
strMsg += m_pCpConclusion->GetDibMsg1();
|
|
strMsg += m_pCpConclusion->GetDibMsg2();
|
|
strMsg.TrimRight();
|
|
MessageBox(strMsg, "MesuChkCpConclusion : 매수결과 수신실패 #1", MB_OK|MB_ICONSTOP);
|
|
return 0;
|
|
}
|
|
#ifdef _DEBUG
|
|
CString strData[9]; long lData[4];
|
|
strData[0] = (LPCTSTR)(_bstr_t)m_pCpConclusion->GetHeaderValue( 0 ); // 0-(string)주문구분
|
|
strData[1] = (LPCTSTR)(_bstr_t)m_pCpConclusion->GetHeaderValue( 1 ); // 1-(string)계좌명
|
|
strData[2] = (LPCTSTR)(_bstr_t)m_pCpConclusion->GetHeaderValue( 2 ); // 2-(string)종목명
|
|
lData[0] = m_pCpConclusion->GetHeaderValue( 3 ); // 3-(long)체결수량
|
|
lData[1] = m_pCpConclusion->GetHeaderValue( 4 ); // 4-(long)체결가격
|
|
lData[2] = m_pCpConclusion->GetHeaderValue( 5 ); // 5-(long)주문번호
|
|
lData[3] = m_pCpConclusion->GetHeaderValue( 6 ); // 6-(long원주문번호
|
|
strData[3] = (LPCTSTR)(_bstr_t)m_pCpConclusion->GetHeaderValue( 7 ); // 7-(string)종합계좌번호
|
|
strData[4] = (LPCTSTR)(_bstr_t)m_pCpConclusion->GetHeaderValue( 8 ); // 8-(string)계좌구분
|
|
strData[5] = (LPCTSTR)(_bstr_t)m_pCpConclusion->GetHeaderValue( 9 ); // 9-(string)종목코드
|
|
strData[6] = (LPCTSTR)(_bstr_t)m_pCpConclusion->GetHeaderValue( 10); // 10-(string)체결구분(1:체결, 2:확인, 3:거부)
|
|
strData[7] = (LPCTSTR)(_bstr_t)m_pCpConclusion->GetHeaderValue( 11); // 11-(string)신용구분
|
|
strData[8] = (LPCTSTR)(_bstr_t)m_pCpConclusion->GetHeaderValue( 12); // 12-(string)매매구분( 체결 구분에서 1:체결일 때만 1:매도, 2:매수)
|
|
|
|
strMsg.Format( "%d : %s,%s,%s, [%d,%d] [%d, %d] %s,%s,%s [%s,%s,%s]",
|
|
m_nSrcJumoon_Number,
|
|
(LPSTR)(LPCTSTR)strData[0], (LPSTR)(LPCTSTR)strData[1], (LPSTR)(LPCTSTR)strData[2],
|
|
lData[0], lData[1], lData[2], lData[3],
|
|
(LPSTR)(LPCTSTR)strData[3], (LPSTR)(LPCTSTR)strData[4], (LPSTR)(LPCTSTR)strData[5], (LPSTR)(LPCTSTR)strData[6], (LPSTR)(LPCTSTR)strData[7], (LPSTR)(LPCTSTR)strData[8] );
|
|
TraceMsg( strMsg, CXListBox::White, CXListBox::Blue );
|
|
return 0;
|
|
#endif
|
|
|
|
CString strConclusion, strGubun;
|
|
long nNumber = (long)m_pCpConclusion->GetHeaderValue( 5 ); // 5-(long)주문번호
|
|
|
|
if( m_nSrcJumoon_Number == nNumber ) // 매수(매도)주문낸 주문번호와 같을때만 처리함.
|
|
{
|
|
strConclusion = (LPCTSTR)(_bstr_t)m_pCpConclusion->GetHeaderValue( 10 ); // 10-(string)체결구분(1:체결, 2:확인, 3:거부)
|
|
if( strConclusion == "1" ) // 1:체결.
|
|
{
|
|
CString strJCode;
|
|
long nCount, nPrice = 0;
|
|
|
|
strJCode = (LPCTSTR)(_bstr_t)m_pCpConclusion->GetHeaderValue( 9 ); // 9-(string)종목코드
|
|
nCount = (long)m_pCpConclusion->GetHeaderValue( 3 ); // 3-(long)체결수량
|
|
nPrice = (long)m_pCpConclusion->GetHeaderValue( 4 ); // 4-(long)체결가격
|
|
|
|
strGubun = (LPCTSTR)(_bstr_t)m_pCpConclusion->GetHeaderValue( 12 ); // 12-(string)매매구분( 체결 구분에서 1:체결일 때만 1:매도, 2:매수)
|
|
if( strGubun == "2" ) // 체결매수.
|
|
{
|
|
if( g_AppEnv.LevelMedo < 9 ) // 자동매도기능 사용여부 검사.
|
|
{
|
|
CString strJCode;
|
|
strJCode = (LPCTSTR)(_bstr_t)m_pCpConclusion->GetHeaderValue( 9 ); // 9-(string)종목코드
|
|
|
|
ICpTdDibPtr _CpTd;
|
|
|
|
long _DummyPrice;
|
|
BYTE _cbStockType;
|
|
g_pStockData->StockVerify( strJCode.Right(5), _DummyPrice, _cbStockType );
|
|
|
|
if( _cbStockType == 1 ) // 거래소.
|
|
{
|
|
_CpTd.CreateInstance( CLSID_CpTd0311 ); // 거래소 매매처리.
|
|
}
|
|
else if( _cbStockType == 5 ) // 코스닥.
|
|
{
|
|
_CpTd.CreateInstance( CLSID_CpTd0315 ); // KOSDAQ 매매처리.
|
|
}
|
|
|
|
_CpTd->SetInputValue( 0, (LPCSTR)"1" ); // 주문구분. 1:현금매도, 2:현금매수
|
|
_CpTd->SetInputValue( 1, (LPCSTR)g_theApp.m_strBankAccount ); // 계좌번호.
|
|
_CpTd->SetInputValue( 2, (LPCSTR)"10" ); // 계좌구분(10:위탁자,
|
|
_CpTd->SetInputValue( 3, (LPCSTR)strJCode ); // 종목코드.
|
|
_CpTd->SetInputValue( 4, (long)nCount ); // 주문수량.
|
|
_CpTd->SetInputValue( 5, (long)m_nAutoMedoMoney ); // 주문단가.
|
|
_CpTd->SetInputValue( 6, (LPCSTR)"00" ); // 매매구분(00:보통가,03:시장가)
|
|
|
|
strMsg.Format( "★매수체결:[%s, %7d, 단가:%7d]->★자동매도:[단가:%d]", strJCode, nCount, nPrice, m_nAutoMedoMoney );
|
|
TraceMsg( strMsg, CXListBox::White, CXListBox::Blue );
|
|
short nRet = _CpTd->BlockRequest(); // 매수->취소->매도!
|
|
if( nRet != 0 )
|
|
{
|
|
if (0 != _CpTd->GetDibStatus())
|
|
AfxMessageBox("매도실패 : \r\n" + strMsg);
|
|
}
|
|
|
|
// _CpTd->GetHeaderValue(8); // 지동매도 (원 주문번호) 알아내기.
|
|
_CpTd.Release();
|
|
}
|
|
}
|
|
else if( strGubun == "1" ) // 체결매도.
|
|
{
|
|
}
|
|
}
|
|
else if( strConclusion == "2" ) // 2:확인
|
|
{
|
|
// TraceMsg( "<매매 확인>", CXListBox::White, CXListBox::Red );
|
|
}
|
|
else if( strConclusion == "3" ) // 3:거부
|
|
{
|
|
// TraceMsg( "<매매 거부>", CXListBox::White, CXListBox::Red );
|
|
}
|
|
}
|
|
}
|
|
catch (_com_error e)
|
|
{
|
|
MessageBox(e.ErrorMessage(), "MesuChkCpConclusion : 매수결과 수신에러 #2", MB_OK|MB_ICONSTOP);
|
|
}
|
|
*/
|
|
return 0;
|
|
}
|
|
|
|
void CHookMsgDlg::OnSvrconnectCheck()
|
|
{
|
|
UpdateData();
|
|
|
|
if( m_bSvrConnect )
|
|
{
|
|
CSrvConnectDlg dlg;
|
|
dlg.m_strIP = m_strSvrIP;
|
|
dlg.m_strName = m_strName;
|
|
dlg.m_nPort = m_nSvrPort;
|
|
|
|
if(IDOK == dlg.DoModal())
|
|
{
|
|
m_strSvrIP = dlg.m_strIP;
|
|
m_strName = dlg.m_strName;
|
|
m_nSvrPort = dlg.m_nPort;
|
|
|
|
// 서버 접속시도.
|
|
TraceMsg( m_strName + " >> 서버연결 시도합니다.." );
|
|
m_pClientSocket = new CClientSocket(this, m_strName);
|
|
|
|
while(!m_pClientSocket->Connect(m_strSvrIP, m_nSvrPort))
|
|
{
|
|
int nRet = AfxMessageBox("서버에 접속 할수 없습니다.\n서버가 실행중인지 확인하십시오.");// , MB_ICONQUESTION|MB_YESNO);
|
|
TraceMsg( m_strName + " >> 서버 연결실패." );
|
|
ClientClosed();
|
|
return;
|
|
}
|
|
|
|
m_bSvrConnect = TRUE; // 재확인 코드. (UpatateData에서 이미 TRUE임.)
|
|
}
|
|
else
|
|
{
|
|
ClientClosed();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Connection close...
|
|
if (m_pClientSocket)
|
|
{
|
|
m_pClientSocket->ClientSignOut();
|
|
TraceMsg( m_strName + " >> 서버접속을 종료합니다." );
|
|
}
|
|
|
|
ClientClosed();
|
|
}
|
|
}
|
|
void CHookMsgDlg::ClientClosed()
|
|
{
|
|
if (m_pClientSocket)
|
|
{
|
|
delete m_pClientSocket;
|
|
m_pClientSocket = NULL;
|
|
}
|
|
|
|
m_bSvrConnect = FALSE;
|
|
UpdateData(FALSE);
|
|
}
|
|
|
|
void CHookMsgDlg::AddClientsCom(CString strFrom, CString strMessage)
|
|
{
|
|
TraceMsg( strFrom + " >> " + strMessage );
|
|
}
|
|
|
|
LRESULT CHookMsgDlg::OnSvrSendCommand(WPARAM wParam, LPARAM lParam)
|
|
{
|
|
if( m_pClientSocket )
|
|
m_pClientSocket->SendClientMessage(m_strSendCommand);
|
|
return 0;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// 거래소 InfoTicker 서버에 접속...
|
|
void CHookMsgDlg::OnInfotickerCheck()
|
|
{
|
|
UpdateData();
|
|
|
|
if( m_bInfoTickerConnect )
|
|
{
|
|
// 서버 접속시도.
|
|
m_pTickerSocket = new CTickerSocket;
|
|
if (!m_pTickerSocket->Create("203.235.1.1", 9902, this))
|
|
{
|
|
SAFE_DELETE( m_pTickerSocket );
|
|
|
|
m_bInfoTickerConnect = FALSE;
|
|
UpdateData( FALSE );
|
|
|
|
MessageBox("[거래소 InfoTicker] 연결에 실패했습니다.");
|
|
return;
|
|
}
|
|
|
|
TraceMsg( "[거래소 InfoTicker] 서버와 연결합니다." );
|
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
|
// InfoTicker 접속 ID: innovision PW: 1234
|
|
char szSend[1024] = "09010,0214,D8AE614FB43478E837D546DAB14089B6,6048B89AA390511B,0,0,0\n";
|
|
m_pTickerSocket->Send(szSend, strlen(szSend));
|
|
|
|
m_bInfoTickerConnect = TRUE; // 재확인 코드. (UpatateData에서 이미 TRUE임.)
|
|
}
|
|
else
|
|
{
|
|
// Connection close...
|
|
TraceMsg( "[거래소 InfoTicker] 접속을 종료합니다." );
|
|
|
|
SAFE_DELETE( m_pTickerSocket );
|
|
}
|
|
|
|
}
|
|
// TickerSocket 소켓 해제
|
|
LRESULT CHookMsgDlg::OnTickerSocketClose(WPARAM wParam, LPARAM lClient)
|
|
{
|
|
SAFE_DELETE( m_pTickerSocket );
|
|
|
|
m_bInfoTickerConnect = FALSE;
|
|
UpdateData( FALSE );
|
|
|
|
MessageBox("[거래소 InfoTicker Server]에서 접속을 해제 시켰습니다.");
|
|
return 0;
|
|
}
|
|
// TickerSocket 소켓으로 부터 수신되는 데이터
|
|
LRESULT CHookMsgDlg::OnTickerSocketReceive(WPARAM wParam, LPARAM lClient)
|
|
{
|
|
memset(m_szTitle, NULL, MAX_RECEIVE_LEN);
|
|
memcpy( m_szTitle, m_pTickerSocket->m_byteReceive, m_pTickerSocket->m_nReceiveLen );
|
|
m_nSourceFrom = UM_SRC_INFOTICKER;
|
|
|
|
TRACE1("OnTickerSocketReceive : recvlen(%d) \n", m_pTickerSocket->m_nReceiveLen);
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// 제목에서 종목코드찾기.
|
|
CString strJCode="";
|
|
CString strJName="";
|
|
CString strTitle = m_szTitle;
|
|
BOOL bSuccess = _ExtractJCode( m_nSourceFrom, strTitle, strJCode, strJName );
|
|
|
|
if( bSuccess )
|
|
{
|
|
if( !m_bMonitorStatus )
|
|
{
|
|
//////////////////////////////////////////////////////
|
|
// 잠김 상태에서도 한번 나온 종목은 무조건 [중복종목]에 등록함!
|
|
g_pStockData->AddRepeatedCode( strJCode );
|
|
TRACE1("OnTickerSocketReceive : [중복종목]등록 : %s \n", strJCode );
|
|
}
|
|
else
|
|
{
|
|
TRACE2("OnTickerSocketReceive : 검사시작 종목코드(%s), 내용(%s) \n", strJCode, strTitle );
|
|
if(RetrieveNewsData()) {
|
|
m_pWorkEvent2->SetEvent();
|
|
m_pWorkEvent->SetEvent();
|
|
}
|
|
}
|
|
}
|
|
else
|
|
TRACE("OnTickerSocketReceive : 거래소공시 분석안됨.\n");
|
|
|
|
return 0;
|
|
}
|
|
|
|
CString CHookMsgDlg::GetLastWord(const CString& strSource) const
|
|
{
|
|
CString strTmp = strSource;
|
|
int iPos = 0;
|
|
|
|
CString strRes1 = "";
|
|
CString strRes2 = "";
|
|
CString szToken = "\"\')]\t ";
|
|
|
|
strRes2 = strTmp.Tokenize(szToken, iPos);
|
|
while (strRes2 != "")
|
|
{
|
|
strRes1 = strRes2;
|
|
strRes2 = strTmp.Tokenize(szToken, iPos);
|
|
}
|
|
|
|
return strRes1;
|
|
}
|
|
|
|
bool CHookMsgDlg::RetrieveNewsData()
|
|
{
|
|
|
|
DWORD dwRetStart = ::GetTickCount();
|
|
DWORD dwRetEnd;
|
|
CString n_strTitle,n_strJName,n_strJCode;
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// 타이틀 정보 저장
|
|
|
|
if(m_nSourceFrom == UM_HOOKOK_WND1 || m_nSourceFrom == UM_HOOKOK_WND2)
|
|
{
|
|
n_strTitle = m_szTitle;
|
|
}
|
|
else if(m_nSourceFrom == UM_HOOKOK_WND3)
|
|
{
|
|
//// 종목명이 없는 정보는 무시한다.
|
|
//if(m_szWnd3_Name[0] == 0)
|
|
//{
|
|
// CString Name;
|
|
// CString strTitleTmp = m_szWnd3_Title;
|
|
//
|
|
// int iCommaPos = strTitleTmp.Find(",");
|
|
// if(iCommaPos >= 0)
|
|
// {
|
|
// Name = GetLastWord(strTitleTmp.Left(iCommaPos));
|
|
// }
|
|
// else
|
|
// {
|
|
// int iSpacePos = strTitleTmp.Find(" ");
|
|
// Name = strTitleTmp.Left(iSpacePos);
|
|
// }
|
|
|
|
// ICpStockCodePtr objStockCode;
|
|
// objStockCode.CreateInstance( CLSID_CpStockCode );
|
|
// CString Code = (LPCSTR)objStockCode->NameToCode((bstr_t)(LPCSTR)Name);
|
|
// objStockCode.Release();
|
|
|
|
// if(Code[0] == NULL)
|
|
// return false;
|
|
|
|
// strcpy(m_szWnd3_Name, Name.GetString());
|
|
// n_strJCode = Code;
|
|
//}
|
|
//n_strTitle = m_szWnd3_Title;
|
|
//n_strJName = m_szWnd3_Name;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// 동일 뉴스 스킵
|
|
|
|
// NewsPlus -> 7001
|
|
if(m_nSourceFrom == UM_HOOKOK_WND3 &&
|
|
g_nSourceFrom == UM_HOOKOK_WND2 &&
|
|
!n_strTitle.Compare(g_strTitle.Right(g_strTitle.GetLength()-6)))
|
|
{
|
|
TraceMsg(n_strTitle+"[NewsPLus->7001,동일뉴스 스킵]", CXListBox::Red, CXListBox::Yellow, TRUE );
|
|
return false;
|
|
// 7001 -> NewsPlus
|
|
}
|
|
else if(m_nSourceFrom == UM_HOOKOK_WND2 &&
|
|
g_nSourceFrom == UM_HOOKOK_WND3 &&
|
|
!g_strTitle.Compare(n_strTitle.Right(n_strTitle.GetLength()-6)))
|
|
{
|
|
TraceMsg(n_strTitle+"[7001->NewsPLus,동일뉴스 스킵]", CXListBox::Red, CXListBox::Yellow, TRUE );
|
|
return false;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// 제목에서 종목코드찾기
|
|
if( FALSE == _ExtractJCode( m_nSourceFrom, n_strTitle, n_strJCode, n_strJName ) )
|
|
{
|
|
// TraceMsg( "[종목코드없음] : " + g_strTitle, CXListBox::White, CXListBox::Red );
|
|
return false;
|
|
}
|
|
|
|
if(n_strJCode[0] == NULL)
|
|
return false;
|
|
|
|
|
|
|
|
dwRetEnd = ::GetTickCount();
|
|
CString strTime;
|
|
strTime.Format("(%d ms)",dwRetEnd - dwRetStart);
|
|
|
|
TraceMsg(n_strTitle+strTime, CXListBox::Red, CXListBox::Yellow, TRUE );
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// 정보 저장
|
|
g_strTitle = n_strTitle;
|
|
g_strJCode = n_strJCode;
|
|
g_strJName = n_strJName;
|
|
g_nSourceFrom = m_nSourceFrom;
|
|
|
|
return true;
|
|
}
|