Why won't this local enum class / lambda function combination work correctly? - visual-c++

This is a boilerplate OnInitDialog handler for CDialog project. I added a enum class and lambda to it:
BOOL CMFCApplication8Dlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
// 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 != nullptr)
{
BOOL bNameValid;
CString strAboutMenu;
bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
ASSERT(bNameValid);
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
enum class EnumStudentItemType
{
BibleReading,
InitialCall,
ReturnVisit,
BibleStudy,
Talk,
Other
};
auto GetStudentItemType = &[](CString strType) -> EnumStudentItemType
{
if (strType == L"Bible Reading")
{
return EnumStudentItemType::BibleReading;
}
if (strType == L"Initial Call")
{
return EnumStudentItemType::InitialCall;
}
if (strType == L"Return Visit")
{
return EnumStudentItemType::ReturnVisit;
}
if (strType == L"Bible Study")
{
return EnumStudentItemType::BibleStudy;
}
if (strType == L"Talk")
{
return EnumStudentItemType::Talk;
}
return EnumStudentItemType::Other;
};
auto eType = GetStudentItemType(L"Bible Reading");
return TRUE; // return TRUE unless you set the focus to a control
}
It does not like this line:
auto eType = GetStudentItemType(L"Bible Reading");
If I move the enum class into the header, and turn the GetStudentItemType method into a function defined in the header, then that line of code which attempts to get the type does not display errors in the IDE.
So:
How do we define a enum class inside a function (not needed anywhere else)? And ...
Use it as a return value for a lambda?

Related

Guidewire : Refresh List view when the button is clicked

The Listview(partial page) is not getting refreshed when I click the button. It keeps on adding the rows whenever the buttons are clicked.
Below are the functions for adding the drivers.
function getDriversFromPolicy_CA7() : CA7CommAutoDriver[] {
var drivers = this.Policy.LatestPeriod.CA7Line.Drivers // **this** Contingency Entity
var excludeDrivers = this.ExcludeDrivers_CA7.toList() // Contingency entity has a ExcludeDrivers_CA7 array
if(excludeDrivers.Empty) {
drivers?.each(\driver -> this.addToExcludeDrivers_CA7(driver) )
} else {
drivers.each(\driver -> {
if (excludeDrivers.where(\elt -> elt.LicenseNumber == driver.LicenseNumber).toList().Count == 0) {
this.addToExcludeDrivers_CA7(driver)
}
})
}
return this.ExcludeDrivers_CA7
}
function getDriversFromTransaction_CA7() : CA7CommAutoDriver[] {
var drivers = this.PolicyPeriod.CA7Line.Drivers.toList()
var excludeDrivers = this.ExcludeDrivers_CA7.toList()
if(this.ExcludeDrivers_CA7.IsEmpty) {
drivers?.each(\driver -> this.addToExcludeDrivers_CA7(driver) )
} else {
// this.ExcludeDrivers_CA7.toList().retainAll(drivers.toList())
drivers.each(\driver -> {
if (excludeDrivers.where(\elt -> elt.LicenseNumber == driver.LicenseNumber).toList().Count == 0) {
this.addToExcludeDrivers_CA7(driver)
}
})
}
return this.ExcludeDrivers_CA7
}
function removeDrivers_CA7(driver : CA7CommAutoDriver) {
this.removeFromExcludeDrivers_CA7(driver)
}
pcf screenshot for reference
UI screenshot for reference

Could haxe macro be used to detect when object is dirty (any property has been changed)

Let say we have an object:
#:checkDirty
class Test {
var a:Int;
var b(default, default):String;
var c(get, set):Array<Int>;
public function new() {
...
}
public function get_c() {
...
}
public function set_c(n) {
...
}
}
Could we write a macro checkDirty so that any change to field/properties would set property dirty to true. Macro would generate dirty field as Bool and clearDirty function to set it to false.
var test = new Test();
trace(test.dirty); // false
test.a = 12;
trace(test.dirty); // true
test.clearDirty();
trace(test.dirty); //false
test.b = "test"
trace(test.dirty); //true
test.clearDirty();
test.c = [1,2,3];
trace(test.dirty); //true
Just to note - whenever you consider proxying access to an object, in my experience, there are always hidden costs / added complexity. :)
That said, you have a few approaches:
First, if you want it to be pure Haxe, then either a macro or an abstract can get the job done. Either way, you're effectively transforming every property access into a function call that sets the value and also sets dirty.
For example, an abstract using the #:resolve getter and setter can be found in the NME source code, replicated here for convenience:
#:forward(decode,toString)
abstract URLVariables(URLVariablesBase)
{
public function new(?inEncoded:String)
{
this = new URLVariablesBase(inEncoded);
}
#:resolve
public function set(name:String, value:String) : String
{
return this.set(name,value);
}
#:resolve
public function get(name:String):String
{
return this.get(name);
}
}
This may be an older syntax, I'm not sure... also look at the operator overloading examples on the Haxe manual:
#:op(a.b) public function fieldRead(name:String)
return this.indexOf(name);
#:op(a.b) public function fieldWrite(name:String, value:String)
return this.split(name).join(value);
Second, I'd just point out that if the underlying language / runtime supports some kind of Proxy object (e.g. JavaScript Proxy), and macro / abstract isn't working as expected, then you could build your functionality on top of that.
I wrote a post (archive) about doing this kind of thing (except for emitting events) before - you can use a #:build macro to modify class members, be it appending an extra assignment into setter or replacing the field with a property.
So a modified version might look like so:
class Macro {
public static macro function build():Array<Field> {
var fields = Context.getBuildFields();
for (field in fields.copy()) { // (copy fields so that we don't go over freshly added ones)
switch (field.kind) {
case FVar(fieldType, fieldExpr), FProp("default", "default", fieldType, fieldExpr):
var fieldName = field.name;
if (fieldName == "dirty") continue;
var setterName = "set_" + fieldName;
var tmp_class = macro class {
public var $fieldName(default, set):$fieldType = $fieldExpr;
public function $setterName(v:$fieldType):$fieldType {
$i{fieldName} = v;
this.dirty = true;
return v;
}
};
for (mcf in tmp_class.fields) fields.push(mcf);
fields.remove(field);
case FProp(_, "set", t, e):
var setter = Lambda.find(fields, (f) -> f.name == "set_" + field.name);
if (setter == null) continue;
switch (setter.kind) {
case FFun(f):
f.expr = macro { dirty = true; ${f.expr}; };
default:
}
default:
}
}
if (Lambda.find(fields, (f) -> f.name == "dirty") == null) fields.push((macro class {
public var dirty:Bool = false;
}).fields[0]);
return fields;
}
}
which, if used as
#:build(Macro.build())
#:keep class Some {
public function new() {}
public var one:Int;
public var two(default, set):String;
function set_two(v:String):String {
two = v;
return v;
}
}
Would emit the following JS:
var Some = function() {
this.dirty = false;
};
Some.prototype = {
set_two: function(v) {
this.dirty = true;
this.two = v;
return v;
}
,set_one: function(v) {
this.one = v;
this.dirty = true;
return v;
}
};

MQL4 Drawing a Dynamic Rectangle_Label with a Text in It

I am trying to draw a Rectangle Label with a text in it every tick.. I want a text to fit exactly in to a Rectangle_Label.. As a text i am using Label.. But cant get it to work exactly.. It is not correctly situated..
In Fact i would like to create a class that would do it all in one... Just like a rectangle with text in it that would be always having same co ordinance and size etc..
Any help would be greatly appreciated...
bool createRectangleLabel(long chart_ID,string name,string labelName,int shift,double price,string text,double xSize,double ySize,double xOffSet,double yOffSet,double xDistance,double yDistance)
{
if(ObjectCreate(chart_ID,labelName,OBJ_RECTANGLE_LABEL,0,TimeCurrent()-shift,price))
{
Print(xDistance+" "+yDistance);
ObjectSetInteger(chart_ID,labelName,OBJPROP_BGCOLOR,clrBlack);
ObjectSetInteger(chart_ID,labelName,OBJPROP_XDISTANCE,xDistance);
ObjectSetInteger(chart_ID,labelName,OBJPROP_YDISTANCE,yDistance);
ObjectSetInteger(chart_ID,labelName,OBJPROP_YSIZE,ySize);
ObjectSetInteger(chart_ID,labelName,OBJPROP_XSIZE,xSize);
ObjectSetString(chart_ID,labelName,OBJPROP_TEXT,text);
ObjectSetInteger(chart_ID,name,OBJPROP_ANCHOR,ANCHOR_CENTER);
return true;
}
else
{
Print("createRectangleLabel return error code: ",GetLastError());
Print("+--------------------------------------------------------------+");
return false;
}
}
bool createLineText(long chart_ID,string name,string labelName,int shift,double price,string text)
{
int xDistance=0;
int yDistance=0;
int xSize,xOffSet;
int ySize,yOffSet;
bool i=ChartTimePriceToXY(chart_ID,0,TimeCurrent(),price,xDistance,yDistance);
if(ObjectCreate(chart_ID,name,OBJ_LABEL,0,TimeCurrent()-shift,price))
{
ObjectSetInteger(chart_ID,name,OBJPROP_BGCOLOR,clrWhite);
ObjectSetInteger(chart_ID,name,OBJPROP_XDISTANCE,xDistance);
ObjectSetInteger(chart_ID,name,OBJPROP_YDISTANCE,yDistance);
ObjectSetString(chart_ID,name,OBJPROP_TEXT,text);
ObjectSetInteger(chart_ID,name,OBJPROP_ANCHOR,ANCHOR_CENTER);
ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clrWhite);
ObjectSetInteger(chart_ID,name,OBJPROP_FONTSIZE,10);
xSize = ObjectGet(name,OBJPROP_XSIZE);
ySize = ObjectGet(name,OBJPROP_YSIZE);
xOffSet = ObjectGet(name,OBJPROP_XOFFSET);
yOffSet = ObjectGet(name,OBJPROP_YOFFSET);
TextGetSize(name,xSize,ySize);
createRectangleLabel(chart_ID,name,labelName,shift,price,text,xSize,ySize,xOffSet,yOffSet,xDistance,yDistance);
return true;
}
else
{
Print("createLineText return error code: ",GetLastError());
Print("+--------------------------------------------------------------+");
return false;
}
}
You cannot call ObjectCreate() every tick - it would return an error 4200.
If you check the object exists before creating, that would help. Alternative approach would be to try to create the object and assign it with some necessary properties (e.g., color of the object, anchor etc) in one block, and move it in another.
if(ObjectFind(chart_id,labelName)<0){
if(ObjectCreate(chart_ID,labelName,OBJ_RECTANGLE_LABEL,0,TimeCurrent()-shift,price)){
ObjectSetInteger(chart_ID,labelName,OBJPROP_BGCOLOR,clrBlack);//etc.
}
ObjectSetInteger(chart_ID,labelName,OBJPROP_XDISTANCE,xDistance);
ObjectSetInteger(chart_ID,labelName,OBJPROP_YDISTANCE,yDistance);//if you need to move the object or take other steps each tick, e.g. update text - do it here
}
You're thinking along the right lines when you say that you'd like to create a class. Fortunately for you, the standard library already includes all the classes you need to make chart objects. Documentation
Example Indicator:
#property strict
#property indicator_chart_window
#include <ChartObjects\ChartObjectsTxtControls.mqh>
class MyRectLabel : public CChartObjectRectLabel
{
CChartObjectLabel m_label;
public:
bool Create(long chart, const string name, const int window,
const int X, const int Y, const int sizeX, const int sizeY)
{
if(!CChartObjectRectLabel::Create(chart,name,window,X,Y,sizeX,sizeY))
return false;
return m_label.Create(chart, name + "_", window, X + 8, Y + 12);
}
bool Color(const color clr){
return m_label.Color(clr);
}
bool Description(const string text){
return m_label.Description(text);
}
bool FontSize(const int size){
return m_label.FontSize(size);
}
bool ToolTip(const string text){
return (this.ToolTip(text) && m_label.Tooltip(text));
}
};
//+------------------------------------------------------------------+
MyRectLabel rect_label;
//+------------------------------------------------------------------+
int OnInit()
{
if(!rect_label.Create(0, "rlabel", 0, 5, 25, 100, 50)
|| !rect_label.BackColor(clrWhiteSmoke)
|| !rect_label.Description("LABEL!")
|| !rect_label.Tooltip("I am a rectangle label")
|| !rect_label.Color(clrBlack)
|| !rect_label.FontSize(18)
)
return INIT_FAILED;
return INIT_SUCCEEDED;
}
//+------------------------------------------------------------------+
int start()
{
static double last_price = 0.;
rect_label.Description(DoubleToString(Bid, _Digits));
if(Bid > last_price)
rect_label.Color(clrLimeGreen);
else
rect_label.Color(clrRed);
last_price = Bid;
return 0;
}

SubclassDlgItem() debug assertion failed

I have created a dailog box with custom control. I am using ultimate grid in my application. (https://www.codeproject.com/Articles/20183/The-Ultimate-Grid-Home-Page).
I am having an error (Debug Assertion Failed) when I run my project.
BOOL CCustomControlDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// 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)
{
BOOL bNameValid;
CString strAboutMenu;
bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
ASSERT(bNameValid);
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
// Add "About..." menu item to system menu.
m_grid.AttachGrid(this, IDC_CUSTOM1);// ERROR LINE
return TRUE; // return TRUE unless you set the focus to a control
}
//Attach grid implementation
BOOL CUGCtrl::AttachGrid(CWnd * wnd,UINT ID){
if( SubclassDlgItem(IDC_CUSTOM1,wnd)) // ERROR LINE
{
long style = GetWindowLong(m_hWnd,GWL_STYLE);
style = style|WS_CLIPCHILDREN|WS_TABSTOP;
SetWindowLong(m_hWnd,GWL_STYLE,style);
// if the parent window is specified
if(wnd!= NULL)
{
LOGFONT logFont;
CFont *pTempFont = wnd->GetFont();
pTempFont->GetLogFont( &logFont );
// ceate a font object based on the font information retrieved from
// parent window. This font will be used as grid's default font.
int nIndex = AddFont( logFont.lfHeight, logFont.lfWidth, logFont.lfEscapement,
logFont.lfOrientation, logFont.lfWeight, logFont.lfItalic,
logFont.lfUnderline, logFont.lfStrikeOut, logFont.lfCharSet,
logFont.lfOutPrecision, logFont.lfClipPrecision,
logFont.lfQuality, logFont.lfPitchAndFamily, logFont.lfFaceName );
SetDefFont( nIndex );
// create a font that will be used for the heading cells. This object
// is almost identical to the grid's default font, except its weight
// was increased by 200.
nIndex = AddFont( logFont.lfHeight, logFont.lfWidth, logFont.lfEscapement,
logFont.lfOrientation, logFont.lfWeight + 200, logFont.lfItalic,
logFont.lfUnderline, logFont.lfStrikeOut, logFont.lfCharSet,
logFont.lfOutPrecision, logFont.lfClipPrecision,
logFont.lfQuality, logFont.lfPitchAndFamily, logFont.lfFaceName );
CUGCell cell;
GetHeadingDefault( &cell );
cell.SetFont( GetFont( nIndex ) );
SetHeadingDefault( &cell );
}
CreateChildWindows();
// When WS_EX_RTLREADING style was specified for the place holder
// window, then set the grid to be in RTL layout mode.
style = GetWindowLong( m_hWnd, GWL_EXSTYLE );
if ( style&WS_EX_RTLREADING )
SetGridLayout( 1 );
OnSetup();
OnSheetSetup(0);
// Allow drawing after the grid is initialized
m_GI->m_paintMode = TRUE;
// Adjust the grid's components to fit current setup
AdjustComponentSizes();
return TRUE;
}
return FALSE;
}
Anyone having any idea how to fix this??
// CAboutDlg dialog used for App About
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
// Dialog Data
#ifdef AFX_DESIGN_TIME
enum { IDD = IDD_ABOUTBOX };
#endif
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
// Implementation
protected:
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialog(IDD_ABOUTBOX)
{
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
}
void CCustomControlDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CCustomControlDlg)
// NOTE: the ClassWizard will add DDX and DDV calls here
DDX_Control(pDX, IDC_CUSTOM1, m_drawpad);
//}}AFX_DATA_MAP
}
The issue is, that you are attaching two different C++ objects to the same control (IDC_CUSTOM1). The entry in DoDataExchange() implicitly performs the subclassing by calling DDX_Control(pDX, IDC_CUSTOM1, m_drawpad);, while the code in OnInitDialog() is more explicit (m_grid.AttachGrid(this, IDC_CUSTOM1);), but essentially does the same thing.
To fix this, you have a number of options, depending on what you are after:
Remove the DDX_Control() call in DoDataExchange() if you don't need the m_drawpad object attached to IDC_CUSTOM1.
Remove the m_grid.AttachGrid() call inside OnInitDialog(), if you don't need the m_grid object attached to IDC_CUSTOM1.
Add an additional control placeholder to your dialog resource and use that for either of those objects, in case you need both.

Debug assertion error on printing

I have a simple text editor that I created in Visual Studio 2010 Professional Edition. Basically I modified the MFC MDI program automatically generated by the VS2010 wizard. The problem is that when i print, it gives me a debug assertion error in viewrich.cpp line 294. I have not modified anything in the code to do with printing, though it could be something wrong with how i used Rich Edit. This is all the information I have. Thanks in advance.
Viewrich.cpp
BOOL CRichEditView::PaginateTo(CDC* pDC, CPrintInfo* pInfo)
// attempts pagination to pInfo->m_nCurPage, TRUE == success
{
ASSERT_VALID(this);
ASSERT_VALID(pDC);
CRect rectSave = pInfo->m_rectDraw;
UINT nPageSave = pInfo->m_nCurPage;
ASSERT(nPageSave > 1); // LINE 294
ASSERT(nPageSave >= (UINT)m_aPageStart.GetSize());
VERIFY(pDC->SaveDC() != 0);
pDC->IntersectClipRect(0, 0, 0, 0);
pInfo->m_nCurPage = (int)m_aPageStart.GetSize();
while (pInfo->m_nCurPage < nPageSave)
{
ASSERT(pInfo->m_nCurPage == (UINT)m_aPageStart.GetSize());
OnPrepareDC(pDC, pInfo);
ASSERT(pInfo->m_bContinuePrinting);
pInfo->m_rectDraw.SetRect(0, 0,
pDC->GetDeviceCaps(HORZRES), pDC->GetDeviceCaps(VERTRES));
pDC->DPtoLP(&pInfo->m_rectDraw);
OnPrint(pDC, pInfo);
if (pInfo->m_nCurPage == (UINT)m_aPageStart.GetSize())
break;
++pInfo->m_nCurPage;
}
BOOL bResult = pInfo->m_nCurPage == nPageSave;
pDC->RestoreDC(-1);
pInfo->m_nCurPage = nPageSave;
pInfo->m_rectDraw = rectSave;
ASSERT_VALID(this);
return bResult;
}
EmergenceView.cpp
IMPLEMENT_DYNCREATE(CEmergenceView, CRichEditView)
BEGIN_MESSAGE_MAP(CEmergenceView, CRichEditView)
// Standard printing commands
ON_COMMAND(ID_FILE_PRINT, &CRichEditView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_DIRECT, &CRichEditView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_PREVIEW, &CEmergenceView::OnFilePrintPreview)
ON_WM_CONTEXTMENU()
ON_WM_RBUTTONUP()
ON_COMMAND(ID_MUTATE_GROUP, &CEmergenceView::OnMutateGroup)
ON_UPDATE_COMMAND_UI(ID_MUTATE_GROUP, &CEmergenceView::OnUpdateMutateGroup)
ON_COMMAND(ID_MUTATE_RANDOMISE, &CEmergenceView::OnMutateRandomise)
ON_UPDATE_COMMAND_UI(ID_MUTATE_RANDOMISE, &CEmergenceView::OnUpdateMutateRandomise)
ON_COMMAND(ID_HELP_STATISTICS, &CEmergenceView::OnHelpStatistics)
ON_UPDATE_COMMAND_UI(ID_HELP_STATISTICS, &CEmergenceView::OnUpdateHelpStatistics)
ON_COMMAND(ID_MUTATE_POETRIZE, &CEmergenceView::OnMutatePoetrize)
ON_COMMAND(ID_EDIT_SELECTALL, &CEmergenceView::OnEditSelectall)
END_MESSAGE_MAP()
// CEmergenceView construction/destruction
CEmergenceView::CEmergenceView()
{
// TODO: add construction code here
}
CEmergenceView::~CEmergenceView()
{
}
BOOL CEmergenceView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
return CRichEditView::PreCreateWindow(cs);
}
// CEmergenceView drawing
void CEmergenceView::OnDraw(CDC* /*pDC*/)
{
CEmergenceDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;
// TODO: add draw code for native data here
}
// CEmergenceView printing
void CEmergenceView::OnFilePrintPreview()
{
#ifndef SHARED_HANDLERS
AFXPrintPreview(this);
#endif
}
BOOL CEmergenceView::OnPreparePrinting(CPrintInfo* pInfo)
{
// default preparation
return DoPreparePrinting(pInfo);
}
void CEmergenceView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add extra initialization before printing
}
void CEmergenceView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add cleanup after printing
}
The ASSERT says it all:
UINT nPageSave = pInfo->m_nCurPage;
ASSERT(nPageSave > 1);
This is a value for the current page to print/paginate. It is set to 1 in CPrintInfo's constructor. But something changed it and made it 0 or negative. Usually this value is completely controlled by the RTF printout. So you must done something that manipulates it.
You have to set the Minimum page and the Maximum page value (SetMinPage and SetMaxPage) in CPrintInfo.

Resources