1001 lines
26 KiB
C++
1001 lines
26 KiB
C++
// FutureCheckerDlg.cpp : implementation file
|
|
//
|
|
|
|
#include "stdafx.h"
|
|
#include "FutureChecker.h"
|
|
#include "FutureCheckerDlg.h"
|
|
|
|
#include "ConfigDlg.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()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CFutureCheckerDlg dialog
|
|
|
|
CFutureCheckerDlg::CFutureCheckerDlg(CWnd* pParent /*=NULL*/)
|
|
: CDialog(CFutureCheckerDlg::IDD, pParent)
|
|
{
|
|
//{{AFX_DATA_INIT(CFutureCheckerDlg)
|
|
// NOTE: the ClassWizard will add member initialization here
|
|
//}}AFX_DATA_INIT
|
|
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
|
|
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
|
|
|
|
m_bMonitorStatus = FALSE;
|
|
|
|
m_pObjFutureCurOnly = NULL; // <= 추가한 것임
|
|
m_pEventFutureCurOnly = NULL; // <= 추가한 것임
|
|
|
|
ClearCheckValue();
|
|
}
|
|
|
|
CFutureCheckerDlg::~CFutureCheckerDlg()
|
|
{
|
|
try
|
|
{
|
|
CString strKey;
|
|
CString* pStrBuf = NULL;
|
|
|
|
if(NULL != m_pEventFutureCurOnly)
|
|
{
|
|
IConnectionPointContainerPtr pCPC;
|
|
IConnectionPointPtr pCP;
|
|
pCPC = m_pObjFutureCurOnly;
|
|
pCPC->FindConnectionPoint(__uuidof(_IDibEvents), &pCP);
|
|
pCP->Unadvise(m_pEventFutureCurOnly->GetCookie());
|
|
m_pEventFutureCurOnly->Destroy();
|
|
}
|
|
}
|
|
catch (_com_error e)
|
|
{
|
|
MessageBox(e.ErrorMessage(), "객체 삭제실패", MB_OK|MB_ICONSTOP);
|
|
}
|
|
}
|
|
|
|
void CFutureCheckerDlg::ClearCheckValue()
|
|
{
|
|
memset( &m_FCURR, NULL, sizeof(FCURR) );
|
|
memset( &m_FAMOUNT, NULL, sizeof(FAMOUNT) );
|
|
memset( &m_APPLYRULEJOIN, NULL, sizeof(APPLYRULEJOIN) );
|
|
memset( &m_CHECKAMOUNT, NULL, sizeof(CHECKAMOUNT) );
|
|
}
|
|
|
|
void CFutureCheckerDlg::DoDataExchange(CDataExchange* pDX)
|
|
{
|
|
CDialog::DoDataExchange(pDX);
|
|
//{{AFX_DATA_MAP(CFutureCheckerDlg)
|
|
DDX_Control(pDX, IDC_TRACE_LIST, m_hTraceListBox);
|
|
//}}AFX_DATA_MAP
|
|
}
|
|
|
|
BEGIN_MESSAGE_MAP(CFutureCheckerDlg, CDialog)
|
|
//{{AFX_MSG_MAP(CFutureCheckerDlg)
|
|
ON_WM_SYSCOMMAND()
|
|
ON_WM_PAINT()
|
|
ON_WM_QUERYDRAGICON()
|
|
ON_BN_CLICKED(IDC_CONFIG_BTN, OnConfigBtn)
|
|
ON_WM_CLOSE()
|
|
ON_BN_CLICKED(IDC_RUN_CHECK, OnRunCheck)
|
|
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_WM_SIZE()
|
|
ON_WM_GETMINMAXINFO()
|
|
ON_WM_COPYDATA()
|
|
//}}AFX_MSG_MAP
|
|
|
|
ON_MESSAGE(WM_CPDIB_RECEIVED, OnReceived) // 추가한 것임
|
|
ON_MESSAGE(WM_HOTKEY, OnHotKey)
|
|
// ON_MESSAGE(WM_HOOKMSG_TARGETAPP_DESTORYED, OnTargetAppDestoryed)
|
|
|
|
END_MESSAGE_MAP()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CFutureCheckerDlg message handlers
|
|
|
|
BOOL CFutureCheckerDlg::OnInitDialog()
|
|
{
|
|
CDialog::OnInitDialog();
|
|
TraceMsg( "Initialize..." );
|
|
|
|
// 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);
|
|
}
|
|
}
|
|
|
|
// 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
|
|
|
|
// TODO: Add extra initialization here
|
|
// Make the total in a larger font
|
|
{
|
|
VERIFY(m_LockUnlockBtnFont.CreateFont(
|
|
15, // 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_RUN_CHECK);
|
|
pButton->SetFont(&m_LockUnlockBtnFont);
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
ReadRegistry();
|
|
// g_Condition.Initialize();
|
|
InstallHotKey( TRUE );
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
STARTUPINFO StartupInfo;
|
|
::GetStartupInfo( &StartupInfo );
|
|
if (StartupInfo.wShowWindow != SW_SHOWNORMAL)
|
|
gwndpl.showCmd = StartupInfo.wShowWindow;
|
|
|
|
::SetWindowPlacement( m_hWnd, &gwndpl);
|
|
|
|
SetWindowPos(&wndTopMost, 0,0,0,0,SWP_NOSIZE|SWP_NOMOVE);
|
|
|
|
m_hTraceListBox.SetContextMenuId(IDR_XLISTBOX);
|
|
UpdateData(FALSE);
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
((CButton*)GetDlgItem( IDC_RUN_CHECK ))->SetWindowText( "잠김" );
|
|
((CButton*)GetDlgItem( IDC_RUN_CHECK ))->SetCheck( FALSE );
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// <= 추가한 것임
|
|
DWORD dwCookie;
|
|
CRuntimeClass* prcCpDibEvent = NULL;
|
|
|
|
try
|
|
{
|
|
HRESULT hr = m_pObjFutureCurOnly.CreateInstance(__uuidof(FutureCurOnly));
|
|
if( SUCCEEDED(hr) )
|
|
{
|
|
prcCpDibEvent = RUNTIME_CLASS(CCpDibEvent);
|
|
m_pEventFutureCurOnly = (CCpDibEvent *)prcCpDibEvent->CreateObject();
|
|
m_pEventFutureCurOnly->SetOwner(GetSafeHwnd());
|
|
IConnectionPointContainerPtr pCPC;
|
|
IConnectionPointPtr pCP;
|
|
|
|
pCPC = m_pObjFutureCurOnly;
|
|
pCPC->FindConnectionPoint(__uuidof(_IDibEvents), &pCP);
|
|
IUnknownPtr pUnk = m_pEventFutureCurOnly->GetIDispatch(TRUE);
|
|
pCP->Advise(pUnk, &dwCookie);
|
|
m_pEventFutureCurOnly->SetCookie(dwCookie);
|
|
}
|
|
}
|
|
catch (_com_error e)
|
|
{
|
|
MessageBox(e.ErrorMessage(), "FutureCurOnly 초기화 실패", MB_OK|MB_ICONSTOP);
|
|
}
|
|
|
|
// CThinThread::CreateThread( 0, 0, NULL, INFINITE );
|
|
|
|
TraceMsg( "Initial Complete!" );
|
|
return TRUE; // return TRUE unless you set the focus to a control
|
|
}
|
|
|
|
BOOL CFutureCheckerDlg::DestroyWindow()
|
|
{
|
|
WriteRegistry();
|
|
|
|
TraceMsg( "<<< 프로그램을 종료합니다 >>>" );
|
|
|
|
////////////////////////////////////
|
|
// Close window smoothly...
|
|
// if( GetOsVersion() == VER_PLATFORM_WIN32_NT )
|
|
// CloseSmoothly( m_hWnd );
|
|
// Free user library...
|
|
if ( g_hUserDll )
|
|
::FreeLibrary( g_hUserDll );
|
|
////////////////////////////////////
|
|
|
|
return CDialog::DestroyWindow();
|
|
}
|
|
|
|
void CFutureCheckerDlg::OnClose()
|
|
{
|
|
int nID = MessageBox( "FutureChecker 프로그램을 종료하시겠습니까?",
|
|
"프로그램 종료", MB_YESNO|MB_ICONQUESTION );
|
|
if( nID == IDYES )
|
|
{
|
|
CDialog::OnOK();
|
|
CDialog::OnClose();
|
|
}
|
|
}
|
|
|
|
void CFutureCheckerDlg::OnSize(UINT nType, int cx, int cy)
|
|
{
|
|
CDialog::OnSize(nType, cx, cy);
|
|
|
|
int nHeightCaption = ::GetSystemMetrics( SM_CYCAPTION );
|
|
nHeightCaption += (::GetSystemMetrics( SM_CYBORDER )*2);
|
|
|
|
CWnd *pWnd=NULL;
|
|
pWnd = (CWnd*)GetDlgItem(IDC_TRACE_LIST);
|
|
if( pWnd )
|
|
pWnd->MoveWindow( 1, 35, cx-2, cy-36, FALSE );
|
|
|
|
RedrawWindow();
|
|
}
|
|
|
|
void CFutureCheckerDlg::OnGetMinMaxInfo(MINMAXINFO FAR* lpMMI)
|
|
{
|
|
CDialog::OnGetMinMaxInfo(lpMMI);
|
|
|
|
lpMMI->ptMinTrackSize.x = 200;
|
|
lpMMI->ptMinTrackSize.y = 60;
|
|
lpMMI->ptMaxTrackSize.x= ::GetSystemMetrics(SM_CXSCREEN);
|
|
lpMMI->ptMaxTrackSize.y= ::GetSystemMetrics(SM_CYSCREEN);
|
|
}
|
|
|
|
void CFutureCheckerDlg::OnSysCommand(UINT nID, LPARAM lParam)
|
|
{
|
|
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
|
|
{
|
|
CAboutDlg dlgAbout;
|
|
dlgAbout.DoModal();
|
|
}
|
|
else
|
|
{
|
|
CDialog::OnSysCommand(nID, 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 CFutureCheckerDlg::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
|
|
{
|
|
CDialog::OnPaint();
|
|
}
|
|
}
|
|
|
|
// The system calls this to obtain the cursor to display while the user drags
|
|
// the minimized window.
|
|
HCURSOR CFutureCheckerDlg::OnQueryDragIcon()
|
|
{
|
|
return (HCURSOR) m_hIcon;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
// override to do startup
|
|
void CFutureCheckerDlg::StartWork()
|
|
{
|
|
CoInitialize(NULL);
|
|
|
|
::SetThreadPriority( GetHandle(), THREAD_PRIORITY_TIME_CRITICAL );
|
|
|
|
try
|
|
{
|
|
}
|
|
catch( _com_error e )
|
|
{
|
|
}
|
|
}
|
|
/////////////////////////////////////////////////////////////////////////
|
|
// override to do work
|
|
void CFutureCheckerDlg::DoWork()
|
|
{
|
|
try
|
|
{
|
|
_WorkThreadProc();
|
|
}
|
|
catch( _com_error e )
|
|
{
|
|
MessageBox(e.ErrorMessage(), "거래량검사 쓰레드 실행오류", MB_OK|MB_ICONSTOP);
|
|
}
|
|
catch(...)
|
|
{
|
|
MessageBox("일반 오류발생.", "거래량검사 쓰레드 실행오류", MB_OK|MB_ICONSTOP);
|
|
}
|
|
}
|
|
/////////////////////////////////////////////////////////////////////////
|
|
// override to do shutdown
|
|
void CFutureCheckerDlg::EndWork()
|
|
{
|
|
CoUninitialize();
|
|
}
|
|
|
|
void CFutureCheckerDlg::OnConfigBtn()
|
|
{
|
|
CConfigDlg dlg;
|
|
|
|
InstallHotKey( FALSE ); // 핫키설정을 해제한다.
|
|
|
|
dlg.DoModal();
|
|
|
|
InstallHotKey( TRUE ); // 핫키설정을 다시한다.
|
|
}
|
|
|
|
void CFutureCheckerDlg::OnRunCheck()
|
|
{
|
|
if( m_bMonitorStatus )
|
|
{
|
|
OnMonitorPause();
|
|
}
|
|
else
|
|
{
|
|
OnMonitorStart();
|
|
}
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// Helper function.
|
|
//
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
void CFutureCheckerDlg::InstallHotKey(BOOL bInstall)
|
|
{
|
|
if(bInstall)
|
|
{
|
|
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() );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
UnregisterHotKey( m_hWnd, REGISTERHOTKEY_ID_LOCK );
|
|
}
|
|
}
|
|
|
|
LRESULT CFutureCheckerDlg::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:
|
|
OnRunCheck();
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void CFutureCheckerDlg::TraceMsg( CString strMsg, CXListBox::Color tc, CXListBox::Color bc )
|
|
{
|
|
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 );
|
|
|
|
// write string, without null-terminator
|
|
// strTrace.Replace( "\r\n", " " );
|
|
// strTrace += "\r\n";
|
|
// g_pLogFile->Write(strTrace, strTrace.GetLength());
|
|
|
|
// LogTrace(strTrace);
|
|
}
|
|
|
|
BOOL CFutureCheckerDlg::EmulateHotKey( EMULATEHOTKEY_SRC srcType, int nIndex, BOOL bSound )
|
|
{
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
// 합집합/교집합 조건처리 진행...
|
|
DWORD dwCurrentTick = ::GetTickCount();
|
|
|
|
if( srcType == SRC_FAMOUNT )
|
|
{
|
|
m_APPLYRULEJOIN.dwTimeFAMOUNT = dwCurrentTick;
|
|
m_APPLYRULEJOIN.nStateFAMOUNT = nIndex+1; // 초기값이 0이라서 Index처리를 1증가해서 처리했음. // Normal(0), 상승(1), 하락(2)
|
|
}
|
|
else if( srcType == SRC_FCURR )
|
|
{
|
|
m_APPLYRULEJOIN.dwTimeFCURR = dwCurrentTick;
|
|
m_APPLYRULEJOIN.nStateFCURR = nIndex+1; // 초기값이 0이라서 Index처리를 1증가해서 처리했음. // Normal(0), 상승(1), 하락(2)
|
|
}
|
|
|
|
CString strMsg="";
|
|
if( g_AppEnv.bFApplyRuleRadio == 1 ) // 합집합(1)
|
|
{
|
|
// 합집합 조건은 거래량과 호가가 시간내에 발생해야 처리함.
|
|
if( (dwCurrentTick-m_APPLYRULEJOIN.dwTimeFAMOUNT <= (DWORD)g_AppEnv.nFApplyRuleRadioLimitTime) &&
|
|
(dwCurrentTick-m_APPLYRULEJOIN.dwTimeFCURR <= (DWORD)g_AppEnv.nFApplyRuleRadioLimitTime) )
|
|
{
|
|
// 합집합 조건은 거래량과 호가변동방향이 동일해야함.
|
|
if( m_APPLYRULEJOIN.nStateFAMOUNT == m_APPLYRULEJOIN.nStateFCURR )
|
|
{
|
|
strMsg += "[합집합] 호가+거래량 ";
|
|
|
|
if( nIndex == 0 )
|
|
strMsg += "상승 : EmulateHotKey 동작.";
|
|
else if( nIndex == 1 )
|
|
strMsg += "하락 : EmulateHotKey 동작.";
|
|
}
|
|
else
|
|
{
|
|
// TraceMsg("합집합 조건 예외상황발생! 호가와 거래량이 반대로 움직였습니다.");
|
|
return FALSE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return FALSE;
|
|
}
|
|
}
|
|
else // 교집합.
|
|
{
|
|
if( srcType == SRC_FAMOUNT )
|
|
strMsg += "[거래량 ";
|
|
else if( srcType == SRC_FCURR )
|
|
strMsg += "[호가 ";
|
|
|
|
if( nIndex == 0 )
|
|
strMsg += "상승] : EmulateHotKey 동작.";
|
|
else if( nIndex == 1 )
|
|
strMsg += "하락] : EmulateHotKey 동작.";
|
|
}
|
|
|
|
TraceMsg( strMsg );
|
|
|
|
WORD wVk;
|
|
WORD wModifier;
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
// 키보드 에뮬레이터 실행.
|
|
if( nIndex == 0 )
|
|
{
|
|
wVk = g_AppEnv.UpConditionHotKey.wVk;
|
|
wModifier = g_AppEnv.UpConditionHotKey.wModifier;
|
|
}
|
|
else if( nIndex == 1 )
|
|
{
|
|
wVk = g_AppEnv.DownConditionHotKey.wVk;
|
|
wModifier = g_AppEnv.DownConditionHotKey.wModifier;
|
|
}
|
|
else
|
|
{
|
|
AfxMessageBox("핫키실행 : EmulateHotKey 인덱스가 잘못되었습니다.");
|
|
return FALSE;
|
|
}
|
|
|
|
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 );
|
|
|
|
keybd_event( (BYTE)wVk, 0,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 );
|
|
|
|
keybd_event( (BYTE)wVk, 0,KEYEVENTF_KEYUP,0 );
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
// 사운드 효과 실행.
|
|
if( bSound )
|
|
PlayResource(IDR_MSGTYPE_WAVE);
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
// 마무리작업.
|
|
if( g_AppEnv.bRunStatCheck != 1 )
|
|
{
|
|
OnMonitorPause(); // 핫키 실행후 풀림상태 계속유지 여부 : 자동잠금 실행.
|
|
}
|
|
else
|
|
{
|
|
// 체크변수를 초기화하고 계속 풀림상태로 진행함.
|
|
ClearCheckValue();
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void CFutureCheckerDlg::OnMonitorStart()
|
|
{
|
|
if( m_bMonitorStatus == TRUE )
|
|
return;
|
|
|
|
if( g_AppEnv.bFApplyRuleRadio == 0 )
|
|
{
|
|
if( !g_AppEnv.bFAmountApplyCheck && !g_AppEnv.bFcurApplyCheck )
|
|
{
|
|
int nID = MessageBox( "거래량+호가 모두 꺼져있습니다.",
|
|
"검사조건 확인", MB_OK|MB_ICONINFORMATION );
|
|
((CButton*)GetDlgItem( IDC_RUN_CHECK ))->SetCheck( FALSE );
|
|
return;
|
|
}
|
|
}
|
|
else if( g_AppEnv.bFApplyRuleRadio == 1 )
|
|
{
|
|
if( !g_AppEnv.bFAmountApplyCheck || !g_AppEnv.bFcurApplyCheck )
|
|
{
|
|
int nID = MessageBox( "[합집합]조건은 거래량+호가 모두 켜져있어야합니다.",
|
|
"검사조건 확인", MB_OK|MB_ICONINFORMATION );
|
|
((CButton*)GetDlgItem( IDC_RUN_CHECK ))->SetCheck( FALSE );
|
|
return;
|
|
}
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// 선물 데이터수신 요청.
|
|
CWaitCursor _waitcursor;
|
|
try
|
|
{
|
|
m_pObjFutureCurOnly->SetInputValue(0, g_AppEnv.szFutureCode);
|
|
m_pObjFutureCurOnly->Subscribe();
|
|
|
|
ClearCheckValue();
|
|
}
|
|
catch( _com_error e )
|
|
{
|
|
MessageBox(e.ErrorMessage(), "CybosPlus Error[Subscribe]", MB_OK|MB_ICONSTOP);
|
|
}
|
|
_waitcursor.Restore();
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
TraceMsg( "풀림..." );
|
|
|
|
CString strTitle;
|
|
strTitle.Format("풀림 - [%s]", g_AppEnv.szFutureCode);
|
|
SetWindowText( strTitle );
|
|
((CButton*)GetDlgItem( IDC_RUN_CHECK ))->SetWindowText( "풀림" );
|
|
((CButton*)GetDlgItem( IDC_RUN_CHECK ))->SetCheck( TRUE );
|
|
m_bMonitorStatus = TRUE;
|
|
}
|
|
void CFutureCheckerDlg::OnUpdateMonitorStart(CCmdUI* pCmdUI)
|
|
{
|
|
if(m_bMonitorStatus)
|
|
pCmdUI->Enable(FALSE);
|
|
else
|
|
{
|
|
pCmdUI->Enable(TRUE);
|
|
}
|
|
}
|
|
|
|
void CFutureCheckerDlg::OnMonitorPause()
|
|
{
|
|
if( m_bMonitorStatus == FALSE )
|
|
return;
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// 선물 데이터수신 요청.
|
|
CWaitCursor _waitcursor;
|
|
try
|
|
{
|
|
m_pObjFutureCurOnly->Unsubscribe();
|
|
|
|
ClearCheckValue();
|
|
}
|
|
catch( _com_error e )
|
|
{
|
|
MessageBox(e.ErrorMessage(), "CybosPlus Error[Unsubscribe]", MB_OK|MB_ICONSTOP);
|
|
}
|
|
_waitcursor.Restore();
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
TraceMsg( "잠김..." );
|
|
|
|
CString strTitle;
|
|
strTitle.Format("잠김 - [%s]", g_AppEnv.szFutureCode);
|
|
SetWindowText( strTitle );
|
|
((CButton*)GetDlgItem( IDC_RUN_CHECK ))->SetWindowText( "잠김" );
|
|
((CButton*)GetDlgItem( IDC_RUN_CHECK ))->SetCheck( FALSE );
|
|
m_bMonitorStatus = FALSE;
|
|
}
|
|
void CFutureCheckerDlg::OnUpdateMonitorPause(CCmdUI* pCmdUI)
|
|
{
|
|
if(!m_bMonitorStatus)
|
|
pCmdUI->Enable(FALSE);
|
|
else
|
|
pCmdUI->Enable(TRUE);
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// AMOUNT 선물 거래량 수신.
|
|
// Using : FutureHook Libary.
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
/*
|
|
LRESULT CFutureCheckerDlg::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 );
|
|
|
|
// strcpy( m_szSourceFrom, "" );
|
|
switch( nWindow )
|
|
{
|
|
case UM_HOOKOK_WND1 :
|
|
// pHookStatWnd1->SetCheck(FALSE);
|
|
// pHookStatWnd1->EnableWindow(FALSE);
|
|
// m_bInputCode1 = FALSE;
|
|
TraceMsg( "[AMOUNT] 윈도우가 닫혔습니다.", 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;
|
|
}
|
|
*/
|
|
BOOL CFutureCheckerDlg::OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct)
|
|
{
|
|
// if( pCopyDataStruct->dwData == UM_HOOKOK_WND1 ) // AMOUNT
|
|
// {
|
|
// SPYMSGDATA cpData;
|
|
// memcpy(&cpData, (SPYMSGDATA*)pCopyDataStruct->lpData, sizeof(SPYMSGDATA)); // transfer data to internal variable
|
|
//
|
|
// m_strTitle = cpData.ExtraData;
|
|
//
|
|
// if( !m_bMonitorStatus )
|
|
// {
|
|
// return CDialog::OnCopyData(pWnd, pCopyDataStruct);
|
|
// }
|
|
// else
|
|
// {
|
|
// m_pWorkEvent->SetEvent();
|
|
// }
|
|
//
|
|
// return TRUE;
|
|
// }
|
|
|
|
return CDialog::OnCopyData(pWnd, pCopyDataStruct);
|
|
}
|
|
BOOL CFutureCheckerDlg::_MessageParse( CString & strMessage, int &nCount )
|
|
{
|
|
/*****************************************************************
|
|
[상승 : 1]
|
|
150451@-75@11125@174135@&10&021@
|
|
^ ^ ^ ^ ^
|
|
[하락 : 10]
|
|
150451@-80@11120@174145@&10&0410@
|
|
^ ^ ^ ^ ^
|
|
*****************************************************************/
|
|
|
|
CString strData="";
|
|
char seps[] = "@";
|
|
char *token;
|
|
|
|
int i=0;
|
|
token = strtok( (LPSTR)(LPCTSTR)strMessage, seps );
|
|
while( token != NULL )
|
|
{
|
|
i++;
|
|
if( i==5 )
|
|
{
|
|
strData.Format( "%s", token );
|
|
|
|
// Ex) &10&0410
|
|
int n1, n2, n3=0;
|
|
int n = sscanf( strData, "&%02d&%02d%d", &n1, &n2, &n3 );
|
|
if( n != 3 )
|
|
return FALSE;
|
|
if( n2 == 2 )
|
|
nCount = n3;
|
|
else if( n2 == 4 )
|
|
nCount = -n3;
|
|
else
|
|
return FALSE;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
token = strtok( NULL, seps );
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
void CFutureCheckerDlg::_WorkThreadProc()
|
|
{
|
|
/* try
|
|
{
|
|
DWORD dwCurTime = GetTickCount();
|
|
|
|
int nCount=0;
|
|
if( ! _MessageParse( m_strTitle, nCount ) )
|
|
{
|
|
TraceMsg("[AMOUNT] 거래량 데이터 분석이 안됩니다.", CXListBox::White, CXListBox::Red);
|
|
return;
|
|
}
|
|
|
|
CheckAmount( dwCurTime, nCount );
|
|
}
|
|
catch(...)
|
|
{
|
|
AfxMessageBox("AMOUNT거래량수신중 : 프로그램 오류가 발생하였습니다.");
|
|
}
|
|
*/
|
|
return;
|
|
}
|
|
|
|
void CFutureCheckerDlg::CheckAmount( DWORD dwCurTime, int nCount )
|
|
{
|
|
m_FAMOUNT.FAMOUNT[m_FAMOUNT.nIndexFAMOUNT].dwTime = dwCurTime;
|
|
m_FAMOUNT.FAMOUNT[m_FAMOUNT.nIndexFAMOUNT].nCount = nCount;
|
|
m_FAMOUNT.nIndexFAMOUNT++;
|
|
if( m_FAMOUNT.nIndexFAMOUNT >= g_AppEnv.nFAmountLimitLine )
|
|
m_FAMOUNT.nIndexFAMOUNT = 0;
|
|
|
|
int nTotalCount=0;
|
|
int nMesu(0), nMedo(0);
|
|
for( int i=0; i<g_AppEnv.nFAmountLimitLine; i++ )
|
|
{
|
|
if( dwCurTime - m_FAMOUNT.FAMOUNT[i].dwTime <= (DWORD)g_AppEnv.nFAamountLimitTime )
|
|
{
|
|
nTotalCount += m_FAMOUNT.FAMOUNT[i].nCount;
|
|
|
|
if( m_FAMOUNT.FAMOUNT[i].nCount > 0 ) // 매수.
|
|
nMesu += m_FAMOUNT.FAMOUNT[i].nCount;
|
|
else // 매도.
|
|
nMedo += -m_FAMOUNT.FAMOUNT[i].nCount;
|
|
}
|
|
}
|
|
|
|
if(g_AppEnv.nFAmountRuleRadio == 0) // 차이계산. //
|
|
{
|
|
if( nTotalCount >= g_AppEnv.nFAmountUpCondition )
|
|
{
|
|
EmulateHotKey( SRC_FAMOUNT, 0, TRUE );
|
|
}
|
|
else if( nTotalCount <= -g_AppEnv.nFAmountDownCondition )
|
|
{
|
|
EmulateHotKey( SRC_FAMOUNT, 1, TRUE );
|
|
}
|
|
}
|
|
else if(g_AppEnv.nFAmountRuleRadio == 1) // 단독합산. //
|
|
{
|
|
if( nMesu >= g_AppEnv.nFAmountUpCondition )
|
|
{
|
|
EmulateHotKey( SRC_FAMOUNT, 0, TRUE );
|
|
}
|
|
else if( nMedo >= g_AppEnv.nFAmountDownCondition )
|
|
{
|
|
EmulateHotKey( SRC_FAMOUNT, 1, TRUE );
|
|
}
|
|
}
|
|
else if(g_AppEnv.nFAmountRuleRadio == 2) // 차이+합산 OR조건. //
|
|
{
|
|
if( nTotalCount >= g_AppEnv.nFAmountUpCondition ||
|
|
nMesu >= g_AppEnv.nFAmountUpCondition )
|
|
{
|
|
EmulateHotKey( SRC_FAMOUNT, 0, TRUE );
|
|
}
|
|
else if( nTotalCount <= -g_AppEnv.nFAmountDownCondition ||
|
|
nMedo >= g_AppEnv.nFAmountDownCondition )
|
|
{
|
|
EmulateHotKey( SRC_FAMOUNT, 1, TRUE );
|
|
}
|
|
}
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// 선물 현재가 수신.
|
|
// Using : FutureCurOnly Object.
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
LONG CFutureCheckerDlg::OnReceived(WPARAM wParam, LPARAM lParam)
|
|
{
|
|
try
|
|
{
|
|
const DWORD dwCurTime = GetTickCount();
|
|
|
|
const float fCurrMoney = (float)m_pObjFutureCurOnly->GetHeaderValue(1); // 1-(float) 현재가.
|
|
const float fMedoMoney = (float)m_pObjFutureCurOnly->GetHeaderValue(18); // 16-(float) 매도 1 우선호가.
|
|
const float fMesuMoney = (float)m_pObjFutureCurOnly->GetHeaderValue(19); // 33-(float) 매수 1 우선호가.
|
|
const long lTotalAmount = (long)m_pObjFutureCurOnly->GetHeaderValue(13); // 13-(long) 누적거래량.
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
// 호가변화 검사.
|
|
////////////////////////////////////////////////////////////////
|
|
if( g_AppEnv.bFcurApplyCheck )
|
|
{
|
|
if( m_FCURR.fPrevCheckMoney > fMedoMoney )
|
|
m_FCURR.nDiffLevel--; // 호가 하락.
|
|
else if( m_FCURR.fPrevCheckMoney < fMedoMoney )
|
|
m_FCURR.nDiffLevel++; // 호가 상승.
|
|
|
|
if( (dwCurTime-m_FCURR.dwStartTime) <= (DWORD)g_AppEnv.nFcurLimitTime )
|
|
{
|
|
if( abs(m_FCURR.nDiffLevel) >= g_AppEnv.nFcurLevelCheck )
|
|
{
|
|
int nIndex=0;
|
|
if( m_FCURR.nDiffLevel >= 0 )
|
|
nIndex = 0; // 상승적용키 동작.
|
|
else
|
|
nIndex = 1; // 하락적용키 동작.
|
|
|
|
EmulateHotKey( SRC_FCURR, nIndex, TRUE );
|
|
}
|
|
else
|
|
{
|
|
m_FCURR.fPrevCheckMoney = fMedoMoney;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
m_FCURR.dwStartTime = dwCurTime;
|
|
m_FCURR.fPrevCheckMoney = fMedoMoney;
|
|
m_FCURR.nDiffLevel = 0;
|
|
}
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
// 거래량변화 검사.
|
|
////////////////////////////////////////////////////////////////
|
|
int nCount = lTotalAmount - m_CHECKAMOUNT.lTotalAmount;
|
|
if( nCount > 0 && m_CHECKAMOUNT.lTotalAmount > 0 )
|
|
{
|
|
CString strMsg="";
|
|
strMsg.Format("매도:%.2f, 매수:%.2f, 거래량:%d", fMedoMoney, fMesuMoney, nCount );
|
|
BOOL bLog = ((CButton*)GetDlgItem( IDC_LOG_CHECK ))->GetCheck();
|
|
|
|
// 새로 들어온 현재가 <= 직전 매수호가 : 체결매도에 표시
|
|
// 새로 들어온 현재가 >= 직전 매도호가 : 체결매수에 표시
|
|
if( fCurrMoney <= m_CHECKAMOUNT.fPrevMesu )
|
|
{
|
|
if( bLog )
|
|
TraceMsg( strMsg, CXListBox::Blue, CXListBox::White );
|
|
nCount = -nCount;
|
|
}
|
|
else
|
|
{
|
|
if( bLog )
|
|
TraceMsg( strMsg, CXListBox::Red, CXListBox::White );
|
|
}
|
|
|
|
if( g_AppEnv.bFAmountApplyCheck )
|
|
CheckAmount( dwCurTime, nCount );
|
|
}
|
|
|
|
m_CHECKAMOUNT.fPrevCMoney = fCurrMoney;
|
|
m_CHECKAMOUNT.fPrevMedo = fMedoMoney;
|
|
m_CHECKAMOUNT.fPrevMesu = fMesuMoney;
|
|
m_CHECKAMOUNT.lTotalAmount = lTotalAmount;
|
|
}
|
|
catch( _com_error e )
|
|
{
|
|
MessageBox(e.ErrorMessage(), "CybosPlus Error[호가수신중]", MB_OK|MB_ICONSTOP);
|
|
}
|
|
catch(...)
|
|
{
|
|
AfxMessageBox("호가수신중 : 프로그램 오류가 발생하였습니다.");
|
|
}
|
|
|
|
return 0;
|
|
}
|