摘要:MFC中 创建基于CFormView的文档视图程序
step 1.首先需定义一个视图资源ID,里面设置各种按钮等控件的位置,提示信息等。
step 2.然后写一个视图类,用enum { IDD = IDD_SELECTOR_FORM }将此类和对视图资源ID联系起来。对资源里的各种控件设置对应的变量,然后用此类对变量进行操作。
html5标签
标题标签
章节标签
html4标签
第一部分 创建CForm资源
step 1:添加IDD_CUSTOMSELECTOR_FORM
G:\stock\TskingVS2019\src\Client\StkUI\resource.h
/*************custom extend 工具条 by freema*******/
#define IDD_SETSYSTEMSET1 300
#define IDR_REPLAY 301
#define IDD_CUSTOMSELECTOR_FORM 302 //自定义智能选股
/*****************************************/
step 2:设计资源视图
G:\stock\TskingVS2019\src\Client\StkUI\StkUI.rc
/***********extend by freeman******************************/
IDD_CUSTOMSELECTOR_FORM DIALOGEX 0, 0, 476, 244
STYLE DS_SETFONT | WS_CHILD | WS_BORDER
FONT 9, "宋体", 0, 0, 0x1
BEGIN
COMBOBOX IDC_STOCKGROUP, 75, 15, 80, 102, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
COMBOBOX IDC_KTYPE, 204, 15, 69, 96, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
COMBOBOX IDC_TECH, 326, 15, 112, 96, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
PUSHBUTTON "智能选股...", IDC_RUNSELECTOR, 335, 32, 90, 16, BS_FLAT
CONTROL "Custom1", IDC_GRID, "MFCGridCtrl", WS_BORDER | WS_TABSTOP, 37, 50, 400, 187
LTEXT "股票范围", IDC_STATIC, 39, 17, 33, 8
LTEXT "K线类型", IDC_STATIC, 169, 18, 31, 8
LTEXT "技术指标", IDC_STATIC, 289, 19, 34, 8
CONTROL "Progress1", IDC_PROGRESS, "msctls_progress32", PBS_SMOOTH, 37, 34, 214, 10, WS_EX_STATICEDGE
LTEXT "无选中股票。", IDC_STATIC_INFO, 261, 35, 68, 8
END
/******************************************/
/******custom extend by freman***********/
IDD_CUSTOMSELECTOR_FORM, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 469
TOPMARGIN, 7
BOTTOMMARGIN, 237
END
/********************/
然后,可以看见资源视图
第二部分 创建了一个派生自CFormView的视图类来管理IDD_SELECTOR_FORM资源
G:\stock\TskingVS2019\src\Client\StkUI\View\CustomSelectorView.h
// SelectorView.h : interface of the CCustomSelectorView class
//
/////////////////////////////////////////////////////////////////////////////
#if !defined(AFX_CUSTOMSELECTORVIEW_H__INCLUDED_)
#define AFX_CUSTOMSELECTORVIEW_H__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
class CStaticDoc;
#include "../Dialog/SetGroupDlg.h"
/***
股票列表视图
*/
class CCustomSelectorView : public CFormView
{
DECLARE_DYNCREATE(CCustomSelectorView)
protected: // create from serialization only
CCustomSelectorView();
public:
//{{AFX_DATA(CCustomSelectorView)
enum { IDD = IDD_CUSTOMSELECTOR_FORM };
CStatic m_staticInfo;
CProgressCtrl m_progress;
CButton m_btnRunSelector;
//}}AFX_DATA
protected:
BOOL m_bShouldUpdate;
BOOL m_bRunning;
CStockContainer m_container;
CUIntArray m_signals;
CUIntArray m_reasons;
// Attributes
public:
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CCustomSelectorView)
public:
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~CCustomSelectorView();
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif
public:
virtual void DoDataExchange(CDataExchange* pDX);
virtual void OnInitialUpdate();
virtual void OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint);
protected:
//{{AFX_MSG(CCustomSelectorView)
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnDestroy();
afx_msg void OnRunselector();
//}}AFX_MSG
afx_msg LRESULT OnGetViewTitle(WPARAM wParam, LPARAM lParam);
DECLARE_MESSAGE_MAP()
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_CUSTOMSELECTORVIEW_H__INCLUDED_)
G:\stock\TskingVS2019\src\Client\StkUI\View\CustomSelectorView.cpp
// SelectorView.cpp : implementation of the CCustomSelectorView class
//
//智能选股id被点击后切换到视图\StkUI\View\SelectorView.h by freeman 2019/06/08
//
#include "stdafx.h"
#include "../StaticDoc.h"
#include "CustomSelectorView.h"
#include "../Dialog/ListExportDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CCustomSelectorView
IMPLEMENT_DYNCREATE(CCustomSelectorView, CFormView)
BEGIN_MESSAGE_MAP(CCustomSelectorView, CFormView)
//{{AFX_MSG_MAP(CCustomSelectorView)
ON_WM_CREATE()
ON_WM_DESTROY()
ON_BN_CLICKED(IDC_RUNSELECTOR, OnRunselector)
//}}AFX_MSG_MAP
ON_MESSAGE(WM_USER_GETVIEWTITLE, OnGetViewTitle)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CCustomSelectorView construction/destruction
CCustomSelectorView::CCustomSelectorView()
: CFormView(CCustomSelectorView::IDD)
{
//m_progressTip.SetWindowTextA(_T("正在等待执行..."));
}
CCustomSelectorView::~CCustomSelectorView()
{
}
void CCustomSelectorView::DoDataExchange(CDataExchange* pDX)
{
CFormView::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CCustomSelectorView)
DDX_Control(pDX, IDC_STATIC_INFO, m_staticInfo);
DDX_Control(pDX, IDC_PROGRESS, m_progress);
//DDX_Text(pDX, IDC_MESSAGE, m_progressTip);
DDX_Control(pDX, IDC_RUNSELECTOR, m_btnRunSelector);
//}}AFX_DATA_MAP
}
void CCustomSelectorView::OnInitialUpdate()
{
CFormView::OnInitialUpdate();
}
void CCustomSelectorView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint)
{
if (IsWindowVisible())
SetFocus();
}
#ifdef _DEBUG
void CCustomSelectorView::AssertValid() const
{
CFormView::AssertValid();
}
void CCustomSelectorView::Dump(CDumpContext& dc) const
{
CFormView::Dump(dc);
}
#endif //_DEBUG
int CCustomSelectorView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CFormView::OnCreate(lpCreateStruct) == -1)
return -1;
return 0;
}
void CCustomSelectorView::OnDestroy()
{
CFormView::OnDestroy();
}
//智能选股按钮
void CCustomSelectorView::OnRunselector()
{
// clear
m_btnRunSelector.EnableWindow(FALSE);
m_staticInfo.SetWindowPos(NULL, 0, 0, 0, 0, SWP_HIDEWINDOW | SWP_NOMOVE | SWP_NOSIZE);
CStockContainer cntn;
cntn.RetrieveFromStatic(CStockContainer::typeA, NULL, AfxGetActiveStrategy(), -1);
// progress
m_progress.SetWindowPos(NULL, 0, 0, 0, 0, SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE);
m_progress.SetRange(0, cntn.GetSize());
m_progress.SetPos(0);
// run selector
for (int i = 0; i < cntn.GetSize(); i++)
{
m_progress.SetPos(i + 1);
CString sTip;
sTip.Format("%d/%d", i+1, cntn.GetSize());
m_staticInfo.SetWindowText(sTip);
m_staticInfo.SetRedraw(TRUE);
/* MSG msg;
while (::PeekMessage(&msg, NULL, NULL, NULL, PM_NOREMOVE))
AfxGetApp()->PumpMessage();*/
}
// display result
//OnUpdate(NULL, UPDATE_HINT_SELECTORVIEW, NULL);
m_btnRunSelector.EnableWindow(TRUE);
}
LRESULT CCustomSelectorView::OnGetViewTitle(WPARAM wParam, LPARAM lParam)
{
CString strTitle;
strTitle = _T("自定义智能选股");
lstrcpyn((LPTSTR)lParam, (LPCTSTR)strTitle, wParam);
if ((int)wParam > strTitle.GetLength())
wParam = strTitle.GetLength();
return wParam;
}
第三部分 菜单项
3.1 在主菜单中添加菜单项
G:\stock\TskingVS2019\src\Client\StkUI\resource.h
step 1:添加ID_VIEW_CUSTOMSELECTOR
step 2:在工具栏里添加“综合选股器”
G:\stock\TskingVS2019\src\Client\StkUI\StkUI.rc
POPUP "工具(T)"
BEGIN
MENUITEM "交易(&T)...\tF12", ID_TOOL_TRADER
MENUITEM SEPARATOR
MENUITEM "计算器(&C)...", ID_TOOL_CALCULATOR
MENUITEM "记事本(&N)...", ID_TOOL_NOTE
MENUITEM SEPARATOR
MENUITEM "基本资料和行情选股(&F)...", ID_TOOL_FILTERINFO
MENUITEM "综合选股器", ID_VIEW_CUSTOMSELECTOR
MENUITEM "预警系统(&A)...", ID_TOOL_ALARM
MENUITEM SEPARATOR
MENUITEM "历史行情", ID_VIEW_HISTORYREALTIME
MENUITEM "行情回放", ID_VIEW_REPLAYREALTIME
MENUITEM "系统设置", ID_OPTION_SETSYSTEM
END
3.2 启用点击主菜单项
step 1:在MainFrm.cpp中添加对HistoryRealtimeView.h类的引用
/**** extend 系统设置、行情回放菜单项 by freeman ****/
#include "Dialog/SetSystemSet1.h"
#include "View/PlayBackView.h"
#include "View/HistoryRealtimeView.h"
/**************************************/
step 2:在MainFrm.h中定义消息映射关系
G:\stock\TskingVS2019\src\Client\StkUI\MainFrm.h
/**** extend 系统设置、行情回放、历史行情菜单项 by freeman ****/
afx_msg void OnViewRePlayRealtime();
afx_msg void OnUpdateViewRePlayRealtime(CCmdUI* pCmdUI);
afx_msg void OnOptionSystemset();
afx_msg void OnViewHistoryRealtime();
afx_msg void OnUpdateViewHistoryRealtime(CCmdUI* pCmdUI);
afx_msg void OnViewCustomSelector();
afx_msg void OnUpdateViewCustomSelector(CCmdUI* pCmdUI);
/**************************************/
在主程序中添加点击菜单后生成的消息和对应的消息处理函数
/**** extend 系统设置、行情回放、历史行情菜单项 by freeman ****/
ON_COMMAND(ID_VIEW_REPLAYREALTIME, OnViewRePlayRealtime)
ON_UPDATE_COMMAND_UI(ID_VIEW_REPLAYREALTIME, OnUpdateViewRePlayRealtime)
ON_COMMAND(ID_VIEW_HISTORYREALTIME, OnViewHistoryRealtime)
ON_UPDATE_COMMAND_UI(ID_VIEW_HISTORYREALTIME, OnUpdateViewHistoryRealtime)
ON_COMMAND(ID_VIEW_CUSTOMSELECTOR, OnViewCustomSelector)
ON_UPDATE_COMMAND_UI(ID_VIEW_CUSTOMSELECTOR, OnUpdateViewCustomSelector)
/**************************************/
实现函数
G:\stock\TskingVS2019\src\Client\StkUI\MainFrm.cpp
void CMainFrame::OnViewCustomSelector()
{
AfxSwitchToStaticView(RUNTIME_CLASS(CCustomSelectorView));
}
void CMainFrame::OnUpdateViewCustomSelector(CCmdUI* pCmdUI)
{
CView* pView = AfxGetStaticDoc()->GetActiveView();
pCmdUI->SetCheck(pView && pView->IsKindOf(RUNTIME_CLASS(CCustomSelectorView)));
}
D:\temp\stock\k-line-print-master\client\cnmarket\StkUI\AfxCore.inl
_AFXCORE_INLINE CRealTimeView * AfxGetRealTimeView( )
{
CStaticDoc * pStaticDoc = AfxGetStaticDoc();
return (CRealTimeView *)( pStaticDoc->GetViewIfExist(RUNTIME_CLASS(CRealTimeView)) );
}
第四部分 为视图逐步添加功能
4.1 进度条显示
在for循环中加上下面的语句,进度条才不会停止响应。
for (int i = 0; i < cntn.GetSize(); i++)
{
m_progress.SetPos(i + 1);
MSG msg;
while (::PeekMessage(&msg, NULL, NULL, NULL, PM_NOREMOVE))
AfxGetApp()->PumpMessage();
4.2 结果显示列表框
4.2.1 初始化变量m_Grid
src/Client/StkUI/View/CustomSelectorView.h
CGridCtrl m_Grid;
src/Client/StkUI/View/CustomSelectorView.cpp
DDX_GridControl(pDX, IDC_GRID, m_Grid);
4.3 选中的股票按回车键和鼠标双击
这个由PreTranslateMessage(MSG* pMsg)函数判断按键并进行处理。
BOOL CCustomSelectorView::PreTranslateMessage(MSG* pMsg)
{
// TODO: Add your specialized code here and/or call the base class
if (m_Grid.GetSafeHwnd() == pMsg->hwnd)
{
if (WM_LBUTTONDBLCLK == pMsg->message
|| (WM_KEYDOWN == pMsg->message && VK_RETURN == pMsg->wParam))
{
int nColumnCount = m_Grid.GetColumnCount();
int nRowCount = m_Grid.GetRowCount();
if (nColumnCount <= 0 || nRowCount <= 0)
return CFormView::PreTranslateMessage(pMsg);
CRect rectCell;
m_Grid.GetCellRect(0, 0, &rectCell);
CPoint pt = pMsg->pt;
::ScreenToClient(m_Grid.GetSafeHwnd(), &pt);
if (pt.y >= rectCell.top && pt.y < rectCell.bottom)
return CFormView::PreTranslateMessage(pMsg);
int nSelRow = m_Grid.GetFocusCell().row;
if (nSelRow >= 1 && nSelRow < m_Grid.GetRowCount())
{
int id = m_Grid.GetItemData(nSelRow, 0);
OnDblclkItem(id);
}
}
}
return CFormView::PreTranslateMessage(pMsg);
}
4.4 增加K线类型选择框
UpdateData(TRUE);不能少,表示把天数的修改值更新到变量。
OnUpdate(NULL, UPDATE_HINT_SELECTORVIEW, NULL);不能少,即时更新控件内容。
/智能选股按钮
void CCustomSelectorView::OnRunselector()
{
。。。。
//更新对话框的值到变量,主要是计算天数。
UpdateData(TRUE);
// run selector
for (int i = 0; i < cntn.GetSize(); i++)
{
m_progress.SetPos(i + 1);
第五部分 添加一个下拉框选股菜单列表控件过程记录
step 1:添加控件的资源ID
G:\stock\TskingVS2019\src\Client\StkUI\resource.h
/******************custom extend 对话框 by freeman******************************/
#define IDC_COMBO_SELECTSTOCK_MENU 1350
/************************************************/
step 2:在对话框中定义控件的类型、位置
G:\stock\TskingVS2019\src\Client\StkUI\StkUI.rc
IDD_CUSTOMSELECTOR_FORM DIALOGEX 0, 0, 562, 346
STYLE DS_SETFONT | WS_CHILD | WS_BORDER
FONT 9, "宋体", 0, 0, 0x1
BEGIN
LTEXT "选择菜单种类", IDC_STATIC, 30, 167, 49, 8
COMBOBOX IDC_COMBO_SELECTSTOCK_MENU, 82, 165, 462, 102, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
PUSHBUTTON "智能选股...",IDC_RUNSELECTOR,335,32,90,16,BS_FLAT
END
step 3:定义一个变量
G:\stock\TskingVS2019\src\Client\StkUI\View\CustomSelectorView.h
*/
class CCustomSelectorView : public CFormView
{
DECLARE_DYNCREATE(CCustomSelectorView)
protected: // create from serialization only
CCustomSelectorView();
public:
//{{AFX_DATA(CCustomSelectorView)
enum { IDD = IDD_CUSTOMSELECTOR_FORM };
CStatic m_staticInfo;
CProgressCtrl m_progress;
CButton m_btnRunSelector;
CKTypeComboBox m_cmbKType;
CComboBox m_listMenu;
step 4:将ID和变量关联起来
G:\stock\TskingVS2019\src\Client\StkUI\View\CustomSelectorView.cpp
void CCustomSelectorView::DoDataExchange(CDataExchange* pDX)
{
CFormView::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CCustomSelectorView)
DDX_Control(pDX, IDC_STATIC_INFO, m_staticInfo);
DDX_Control(pDX, IDC_PROGRESS, m_progress);
DDX_Text(pDX, IDC_DAYS, m_nDays);
DDX_Control(pDX, IDC_COMBO_SELECTSTOCK_MENU, m_listMenu);
DDX_Control(pDX, IDC_RUNSELECTOR, m_btnRunSelector);
DDX_Control(pDX, IDC_KTYPE, m_cmbKType);
//}}AFX_DATA_MAP
DDX_GridControl(pDX, IDC_GRID, m_Grid);
}
step 5:对菜单进行初始化
G:\stock\TskingVS2019\src\Client\StkUI\View\CustomSelectorView.cpp
void CCustomSelectorView::OnInitialUpdate()
{
CFormView::OnInitialUpdate();
//初始化菜单项目
m_listMenu.ResetContent();
// Init Storage
m_listMenu.InitStorage(1, 32);
int nItem = m_listMenu.AddString(_T("请选择菜单)"));
m_listMenu.SetItemData(nItem, 0);
nItem = m_listMenu.AddString(_T("26.日K线1涨停后高开阴线(长时间调整后到阳线以下地步区域后启动)"));
m_listMenu.SetItemData(nItem, 1);
nItem = m_listMenu.AddString(_T("26.2日K线1涨停后高开阴线(长时间调整后到阳线以下地步区域后启动)"));
m_listMenu.SetItemData(nItem, 2);
// 默认选择第一项
m_listMenu.SetCurSel(0);
}
step 6:获取选择值
G:\stock\TskingVS2019\src\Client\StkUI\View\CustomSelectorView.cpp
//自定义智能选股按钮
void CCustomSelectorView::OnRunselector()
{
//更新对话框的值到变量,主要是计算天数。
UpdateData(TRUE);
//获取控件对应的变量值
int nKType = m_cmbKType.GetSelect();
int nSel;
// 获取菜单组合框控件的列表框中选中项的索引
nSel = m_listMenu.GetCurSel();
if (CB_ERR == nSel)
return;
分析框架代码
//读取股票K线数据,根据天数选择时间范围
CKData& kdata = m_CurStock.GetKData(CKData::ktypeMin30);
int nStart, nEnd;
nStart = 0, nEnd = 0;
nStart = kdata.GetSize() - m_nDays > 0 ? kdata.GetSize() - m_nDays - 1 : 0;
nEnd = kdata.GetSize() - 1;
int nSel = 1;
nSel = m_listPankouMenu.GetCurSel();
//按日K线循环
for (int k = nStart + 1; k <= nEnd; k++)
{
switch (nSel)
{
case 0: //尾盘急拉
break;
case 1://
break;
}
}
添加股票范围选择框步骤: m_cmbStockGroup
step 1. 添加变量:m_cmbStockGroup
src/Client/StkUI/View/CustomSelectorView.h
class CCustomSelectorView : public CFormView
CButton m_btnRunSelector;
CButton m_btnAddToGroup;
+ CDomainComboBox m_cmbStockGroup;//股票范围,由StkUI\Dialog\SetGroupDlg.h
CKTypeComboBox m_cmbKType;
CComboBox m_listMenu;//K线分析菜单变量
CComboBox m_listPankouMenu;//盘口分析菜单变量
step 2:初始化变量m_cmbStockGroup
src/Client/StkUI/View/CustomSelectorView.cpp
void CCustomSelectorView::OnInitialUpdate()
InitializeGrid();
//初始化股票选择范围。如智能选股
+m_cmbStockGroup.InitStrings(TRUE, TRUE, AfxGetGroupContainer());
+m_cmbStockGroup.SetCurSel(0);
+m_cmbStockGroup.SelectGroupAll();
//初始化K线类型选择框
m_cmbKType.Initialize();
step 3:将变量m_cmbStockGroup和控件IDC_STOCKGROUP关联起来
src/Client/StkUI/View/CustomSelectorView.cpp
void CCustomSelectorView::DoDataExchange(CDataExchange* pDX)
DDX_Control(pDX, IDC_QLTEST, m_btnRunSelectorPankou);
DDX_Control(pDX, IDC_ADDTOGROUP, m_btnAddToGroup);
+DDX_Control(pDX, IDC_STOCKGROUP, m_cmbStockGroup);
DDX_Control(pDX, IDC_KTYPE, m_cmbKType);
//}}AFX_DATA_MAP
CForm充满整个屏幕
添加OnSize()
直接对grid控件进行放大处理
第六部分 添加一个日期范围和时间范围选择框控件过程记录
CustomSelectorView: 增加股票 日期范围选择框
step 1.设计视图
G:\stock\TskingVS2019\src\Client\StkUI\StkUI.rc
找到IDD_CUSTOMSELECTOR_FORM DIALOGEX 0, 0, 954, 547
添加日期控件
GROUPBOX "选择日期范围", IDC_STATIC, 22, 84, 293, 117
CONTROL "日线数据 开始日期", IDC_CHECK_DAY, "Button", BS_AUTOCHECKBOX | BS_FLAT | WS_TABSTOP, 33, 114, 88, 10
CONTROL "DateTimePicker1", IDC_TIME_DAYFROM, "SysDateTimePick32", DTS_RIGHTALIGN | WS_TABSTOP, 122, 112, 63, 15
CONTROL "DateTimePicker1", IDC_TIME_DAYTO, "SysDateTimePick32", DTS_RIGHTALIGN | WS_TABSTOP, 235, 112, 63, 15
LTEXT "结束日期", IDC_STATIC, 197, 114, 33, 8