As far as I am aware this actually works, so it might be a red herring. But ...
I have this definition:
static UINT BASED_CODE indicators[] =
{
ID_INDICATOR_DATE,
ID_INDICATOR_ZOOM,
ID_INDICATOR_CALENDARS,
ID_INDICATOR_MEETING_TYPE
};
Note that the value of ID_INDICATOR_DATE is 33604.
At the appropriate moment during my dialog's create I set the indicators for my status bar:
m_StatusBar.SetIndicators(&indicators[0], to_underlying(StatusBarPane::Count)); //Set the number of panes
I noticed in debug mode:
12d:\a01_work\20\s\src\vctools\VC7Libs\Ship\ATLMFC\Src\MFC\barstat.cpp(128) : AppMsg - Warning: failed to load indicator string 0x8344.
I determined that 0x8344 is hexadecimal for 33604.
I realised that SetIndicators returns a BOOL so I tested the result and it was 0. Since the official documentation does not say how to proceed from here - what to do? My panes appear to be operational.
The indicators array is defined at the top of the CPP file. And the statusbar is created in OnInitDialog.
Related
What I am Doing
I am trying to create a Sudoku solver and generator in Vue. Right now, I have the solving algorithm set up, and just need to generate new problems. I am generating problems by creating a completed Sudoku problem (complete with no bugs), then I have to remove nodes so that there is still only 1 solution to the problem.
The Problem
When I try to access a node from the multi-dimensional array that represents the board, and change it to null (what I am using to display a blank node), the board does not update that value. I am changing it with the following code: newGrid[pos[0]][pos[1]] = null; (where pos[0] is the row, pos[1] is the column , and newGrid is grid we want to mutate). Note that the array is an array with 9 arrays inside, and each of those arrays has 9 numbers (or null) which represent the values for that position in the grid. To elaborate on the bug, if I put a console.log(newGrid), there are normal looking values, and no null.
What I Know and Have Tried
I know it has to do with this specific line, and the fact that I am setting the value equal to null because changing null to another value (i.e. newGrid[pos[0]][pos[1]] = 0;) works and changes the array. The reason I don't just use a value other than null is: null renders and nothing and other values (0) render as something (null nodes should be blank), null is simple to understand in this situation (the logic is node has null, node has nothing, node is blank), and null is already implemented throughout my codebase.
Additionally, if I use console.log(newGrid[pos[0]][pos[1]]), null (the correct output) is outputted, even though console.log(newGrid) shows a number there, not null. Also, oddly enough, this works for one specific node. In row 1 (indexing starts at 0), column 8, null is set. Even though the input (completed) grid is always different, this node is always set to null. Edit: this bug had to do with the input grid already having null here, so it actually doesn't let any nulls be set.
To summarize: I expect an array with a null in a few positions I update, but I get a number instead. Also, there are no errors when the Typescript compiles to Javascript or during runtime.
Code
Given that I am not exactly sure where the problem may be (i.e. maybe I create the array wrong) I am including the minimum code with a pastebin link to the whole file (this is the full code). To restate, the goal of this function is to remove nodes from the list (by replacing them with null) in order to create a Sudoku puzzle with one solution. The code on Stack Overflow only includes some of the whole file, and the pastebin link includes the rest.
//global.d.ts
type Nullable<T> = T | null;
type Grid = Array<Array<number | null>>;
import { Solver } from './Solve';
// Inside the function that does the main work
const rowLen: number = grid.length;
const colLen: number = grid[0].length;
let newGrid: Grid = grid; // Grid is a argument for this function
let fullNodes = GetFirstFull(grid, colLen, rowLen);
let fullNodesLen: number = fullNodes.length;
// Some stuff that figures out how many solutions there are (we only want 1) is excluded
if (solutions != 1) {
fullNodesLen++;
rounds--;
} else {
newGrid[pos[0]][pos[1]] = null;
}
Note that if anything seems confusing check out the pastebin or ask. Thank you so much for taking the time to look at my problem!
Also, it isn't just 0 that works, undefined also makes it set correctly. So, this problem seems to be something with the null keyword...
EDIT:
Given that no one has responded yet, I assume: my problem is a bit hard, there isn't enough information, my post isn't good quality, or not enough people have seen it. To control the problem of not enough information, I would like to include the function that calls this function (just to see if that might be related).
generate(context: ActionContext<State, any>) {
let emptyArray = new Array(9);
for (let i = 0; i < 9; ++i)
emptyArray[i] = [null, null, null, null, null, null, null, null, null];
const fullGrid = Solver(emptyArray);
const puzzle = fullGrid ? Remover(fullGrid, 6) : state.gridLayout;
context.commit('resetBoard', puzzle);
},
Note: If you aren't familiar with Vuex, what context.commit does is changes the state (except it is changing a global state rather than a component state). Given that this function isn't refactored or very easy to read code in the first place, if you have any questions, please ask.
To solve other potential problems: I have been working on this, I have tried a lot of console.log()ing, changing the reference (newGrid) to a deepcopy, moving stuff out of the if statements, verifying code execution, and changing the way the point on the newGrid is set (i.e. by using newgrid.map() with logic to return that point as null). If you have any questions or I can help at all, please ask.
My SwiftUI segmented control picker uses plain Int ".tag(1)" etc values for its selection.
CoreData only has Int16, Int32 & Int64 options to choose from, and with any of those options it seems my picker selection and CoreData refuse to talk to each other.
How is this (??simple??) task achieved please?
I've tried every numeric based option within CoreData including Int16-64, doubles and floats, all of them break my code or simply just don't work.
Picker(selection: $addDogVM.gender, label: Text("Gender?")) {
Text("Boy ♂").tag(1)
Text("?").tag(2)
Text("Girl ♀").tag(3)
}
I expected any of the 3 CoreData Int options to work out of the box, and to be compatible with the (standard) Int used by the picker.
Each element of a segmented control is represented by an index of type Int, and this index therefore commences at 0.
So using your example of a segmented control with three segments (for example: Boy ♂, ?, Girl ♀), each segment is represented by three indexes 0, 1 & 2.
If the user selects the segmented control that represents Girl ♀, then...
segmentedControl.selectedSegmentIndex = 2
When storing a value using Core Data framework, that is to be represented as a segmented control index in the UI, I therefore always commence with 0.
Everything you read from this point onwards is programmer preference - that is and to be clear - there are a number of ways to achieve the same outcome and you should choose one that best suits you and your coding style. Note also that this can be confusing for a newcomer, so I would encourage patience. My only advice, keep things as simple as possible until you've tested and debugged and tested enough to understand the differences.
So to continue:
The Apple Documentation states that...
...on 64-bit platforms, Int is the same size as Int64.
So in the Core Data model editor (.xcdatamodeld file), I choose to apply an Integer 64 attribute type for any value that will be used as an Int in my code.
Also, somewhere, some time ago, I read that if there is no reason to use Integer 16 or Integer 32, then default to the use of Integer 64 in object model graph. (I assume Integer 16 or Integer 32 are kept for backward compatibility.) If I find that reference I'll link it here.
I could write about the use of scalar attribute types here and manually writing your managed object subclass/es by selecting in the attribute inspector Class Codegen = Manual/None, but honestly I have decided such added detail will only complicate matters.
So your "automatically generated by Core Data" managed object subclass/es (NSManagedObject) will use the optional NSNumber? wrapper...
You will therefore need to convert your persisted/saved data in your code.
I do this in two places... when I access the data and when I persist the data.
(Noting I assume your entity is of type Dog and an instance exists of dog i.e. let dog = Dog())
// access
tempGender = dog.gender as? Int
// save
dog.gender = tempGender as NSNumber?
In between, I use a "temp" var property of type Int to work with the segmented control.
// temporary property to use with segmented control
private var tempGender: Int?
UPDATE
I do the last part a little differently now...
Rather than convert the data in code, I made a simple extension to my managed object subclass to execute the conversion. So rather than accessing the Core Data attribute directly and manipulating the data in code, now I instead use this convenience var.
extension Dog {
var genderAsInt: Int {
get {
guard let gender = self.gender else { return 0 }
return Int(truncating: gender)
}
set {
self.gender = NSNumber(value: newValue)
}
}
}
Your picker code...
Picker(selection: $addDogVM.genderAsInt, label: Text("Gender?")) {
Text("Boy ♂").tag(0)
Text("?").tag(1)
Text("Girl ♀").tag(2)
}
Any questions, ask in the comments.
I am using Visual Studio 2013 and making MFC Dialog based application. I am running into strange issue with Kill Focus of Edit Control.
Please see below:
==========================================================================
In my application, I have two Edit Controls on Dialog Box.
1st Edit Control -> IDC_EDIT_QUALITY1
2nd Edit Control -> IDC_EDIT_QUALITY2
I have handled both's EN_KILLFOCUS event to validate the value.
BEGIN_MESSAGE_MAP(CTestDlg, CDialog)
ON_EN_KILLFOCUS(IDC_EDIT_QUALITY1, &CTestDlg::OnQuality1EditKillFocus)
ON_EN_KILLFOCUS(IDC_EDIT_QUALITY2, &CTestDlg::OnQuality2EditKillFocus)
END_MESSAGE_MAP()
void CTestDlg::OnQuality1EditKillFocus()
{
ValidateQualityParams(IDC_EDIT_QUALITY1);
}
void CTestDlg::OnQuality2EditKillFocus()
{
ValidateQualityParams(IDC_EDIT_QUALITY2);
}
#define MIN_QUALITY_VALUE 1
#define MAX_QUALITY_VALUE 100
void CTestDlg::ValidateQualityParams(int qualityParamID)
{
CString strQuality1;
if (IDC_EDIT_QUALITY1 == qualityParamID)
{
m_ctrlQuality1.GetWindowText(strQuality1);
if ((_ttoi(strQuality1) < MIN_QUALITY_VALUE) || (_ttoi(strQuality1) > MAX_QUALITY_VALUE))
{
CString strMessage;
strMessage.Format(_T("Quality1 value must be between %d to %d."), MIN_QUALITY_VALUE, MAX_QUALITY_VALUE);
**AfxMessageBox(strMessage);**
m_ctrlQuality1.SetSel(0, -1);
m_ctrlQuality1.SetFocus();
return;
}
}
CString strQuality2;
if (IDC_EDIT_QUALITY2 == qualityParamID)
{
m_ctrlQuality2.GetWindowText(strQuality2);
if ((_ttoi(strQuality2) < MIN_QUALITY_VALUE) || (_ttoi(strQuality2) > MAX_QUALITY_VALUE))
{
CString strMessage;
strMessage.Format(_T("Quality2 value must be between %d to %d."), MIN_QUALITY_VALUE, MAX_QUALITY_VALUE);
AfxMessageBox(strMessage);
m_ctrlQuality2.SetSel(0, -1);
m_ctrlQuality2.SetFocus();
return;
}
}
}
Now, the issue happens when, after changing the value in 1st Edit Control (IDC_EDIT_QUALITY1), say entering 0 in it and pressing TAB key, the flow goes as below:
void CTestDlg::OnQuality1EditKillFocus() is called.
It calls ValidateQualityParams(IDC_EDIT_QUALITY1)
Inside ValidateQualityParams, it goes to if (IDC_EDIT_QUALITY1 == qualityParamID) condition.
As the value I entered is less than MIN_QUALITY_VALUE, so it shows the Message by calling AfxMessageBox.
- Now, even from the callstack of AfxMessageBox, it hits void CTestDlg::OnQuality2EditKillFocus() internally.
Although callstack of OnQuality1EditKillFocus is NOT finished yet, OnQuality2EditKillFocus gets called from the callstack of AfxMessageBox.
I don't understand the cause of this issue. Has anyone encountered such issue before?
In my resource.h, I have two distinct values for IDC_EDIT_QUALITY1 and IDC_EDIT_QUALITY2
#define IDC_EDIT_QUALITY1 1018
#define IDC_EDIT_QUALITY2 1020
Please help on this issue.
I believe the EN_KILLFOCUS notification for the IDC_EDIT_QUALITY2 control you are receiving is caused not by the m_ctrlQuality1.SetFocus() call, but instead by the AfxMessageBox() call.
When you press the [Tab] key IDC_EDIT_QUALITY1 loses the focus, and IDC_EDIT_QUALITY2 gets the focus. Then you receive the EN_KILLFOCUS notification for IDC_EDIT_QUALITY1. You display the error-message, which causes the application to "yield" (start processing messages again), while the message-box is displayed. The m_ctrlQuality1.SetFocus() call won't take place before the AfxMessageBox() returns, ie before you close the message-box, and therefore the EN_KILLFOCUS notification for IDC_EDIT_QUALITY2 can't be the result of that call. I guess it's the result of displaying the message-box (IDC_EDIT_QUALITY2 has got the focus, but the message-box makes it lose it).
You may work around it by adding a memeber variable, as Staytuned123 suggested, but in a different setting: name it, say m_bKillFocusProcessing, and set it to TRUE while you are processing ANY EN_KILLFOCUS notification (AfxMessageBox() plus SetFocus()), and to FALSE when you are done processing it; if it's already TRUE exit without doing anything. That is, only one EN_KILLFOCUS notification may be processed at a time.
However, such a user-interface (displaying a message-box on exiting a field) is rather weird. And why reinvent the wheel and not instead use the DDX/DDV feature, which MFC already offers? You can define member variables associated with controls, and perform various checks, including range-check. Call UpdateData(TRUE) to perform the checks (for all controls on the dialog) and transfer the data to the member variables. Or you can put some error-displaying controls (usually in red color), activated when an error is found, like in .net or the web.
When you pressed TAB key, IDC_EDIT_QUALITY2 got focus. But because value entered was out of bound, the program called m_ctrlQuality1.SetFocus(), which in turn caused OnQuality2EditKillFocus() to get called.
Add a member variable says m_bQuality1OutOfBound and set it to true right before calling m_ctrlQuality1.SetFocus(). In OnQuality2EditKillFocus(), when m_bQuality1OutOfBound is true, set it to false and don't call ValidateQualityParams(IDC_EDIT_QUALITY2).
Chapter 3 of the AngularDart tutorial defines a rating #NgComponent (see excerpt below), that is used in index.html like this:
<rating max-rating="5" rating="ctrl.selectedRecipe.rating"></rating>
In that chapter it is also suggested that that the max-rating #NgAttr can be set via a {{...}} like this:
<rating max-rating="{{ctrl.max}}" rating="ctrl.selectedRecipe.rating"></rating>
In the RecipeController I have simply declared:
int max = 5;
If I add print("maxRating('$value')") at the top of the component's maxRating() setter body (see below), then in running the app I get the following output:
maxRating('') // printed 7 times
maxRating('5') // printed 7 times
Questions: Why is the value initially empty? I assume that it is because the interpolation has not been done yet, but then why is the setter called at all before the value is "ready"?
Excerpt of RatingComponent class definition:
#NgComponent(
selector: 'rating', ...
publishAs: 'cmp'
)
class RatingComponent {
...
#NgTwoWay('rating')
int rating;
#NgAttr('max-rating')
set maxRating(String value) {
var count = value == null ? 5 : int.parse(value);
stars = new List.generate(count, (i) => i+1);
}
As far as I know, angular dart is very eager in applying values. As soon as angular is running it starts applying values, I guess to provide a feel of responsiveness.
I've been bitten by this too and had to write more than one workaround for not yet initialized values.
The setter and getters are called by the binding mechanism to stabilize the values, as some values may depend on each other and the mechanism "brute forces" this by just setting and getting values multiple times (7 by default, IIRC).
Using infragistics UltraNumericEditor, if I set the .MaxValue to 50, the control will allow me to enter decimals larger than the limit (for example, 50.99)
I see the same behavior if I set the .MaxValue property to 50.01 (can set values larger)
I can obviously resolve this in code but resetting the value, but it seems like the control should do this on its own.
Is there something I'm missing in how to use these properties correctly?
I suppose you are using the UltraNumericEditor with the property Style set to Decimal (or Double).
In this case the control allows you to insert digits that render the input invalid with respect to the property MaxValue. However, by default, you are not able to exit the control until the value is correct.
If you want, you can use the event ValidationError that gives your the ValidationErrorEventArgs parameter. This parameter contains the LastValidValue property to reset the wrong value, the RetainFocus to let your user exit from the editor (or, if you prefer, display an error message)
private void ultraNumericEditor1_ValidationError(object sender, ValidationErrorEventArgs e)
{
// Reset the content to the last valid value and allow the exit from the editor
ultraNumericEditor1.Value = e.LastValidValue;
e.RetainFocus = false;
// In alternative display a message, but leave the wrong value to be reedited
// DisplayValidationMessage("The max value allowed is 50.00");
}
The problem was a result of the IEditorDataFilter for percentage values.
Infragistics recommends, and I had implemented, an IEditorDataFilter which converts decimal percentages (.5 = 50%) into percentages for display.
This filter is applied before the validation for the control takes place. Therefore, setting the MaxValue to "50" allowed me to enter "50.99" but not "51"... normally this would have caused a validation error as per Steve's answer. However, because of the IEditorDataFilter applied to this control, the value was automatically converted to .5099 and this new value does not violate the constraint.
The solution I implemented was to check the value in the Validated event to see if it was larger than the MaxValue / 100, and if so to set it equal to the same.