How can identify Mouse Click event in PreTranslateMessage? - visual-c++

I want identify all mouse click event in PreTranslateMessage, but when I use WM_LBUTTONDOWN than WM_LBUTTONDBLCLK portion never called. Please tell me how can I identify all events separately.

This code will get the mouse click events in PreTranslateMessage
BOOL CSampleDlg::PreTranslateMessage(MSG* pMsg)
{
if(pMsg->message == WM_LBUTTONDOWN)
{
//add ur customized code here...
return false;
}
return CDHtmlDialog::preTranslateMessage(pMsg);
}

Related

Scroll after view becomes visible

I am trying to scroll to the bottom of my scrollView after a view becomes visible with button click. The problem is the scrollTo function is applied before the view is actually visible. I know this because when the button is pressed twice, it scrolls to the bottom on the second click.
So, is there a way to scroll after the view becomes visible?
button.setOnClickListener(v -> {
constraintLayout.setVisibility(View.VISIBLE);
scrollView.smoothScrollTo(0, constraintLayout.getBottom());
}
button.setOnClickListener(v -> {
constraintLayout.setVisibility(View.VISIBLE);
Handler handler = new Handler();
handler.postDelayed(() -> {
scrollView.smoothScrollTo(0, constraintLayout.getBottom());
}, 100);
}
I just figured out this works, but I was hoping to not use a delay.
Another option is to use a listener.
ViewTreeObserver.OnPreDrawListener viewVisibilityChanged = new ViewTreeObserver.OnPreDrawListener() {
#Override
public boolean onPreDraw() {
if (my_view.getVisibility() == View.VISIBLE) {
scroll_view.smoothScrollTo(0, scroll_view.getHeight());
}
return true;
}
};
You can add it to your view this way :
my_view.getViewTreeObserver().addOnPreDrawListener(viewVisibilityChanged);

Cannot trigger cancel button action after processing results returned

Within the Acumatica 19.201.0070 framework I have created a custom processing page that utilizes PXFilteredProcessing with the old style processing UI public override bool IsProcessing => false; I have defined a cancel button (below) that will clear the graph and set some values of the processing filter.
public PXCancel<NPMasterSubGeneratorFilter> Cancel;
[PXCancelButton()]
protected virtual IEnumerable cancel(PXAdapter adapter)
{
NPMasterSubGeneratorFilter row = Filter.Current;
if (row != null)
{
this.Clear();
Filter.SetValueExt<NPMasterSubGeneratorFilter.segmentID>(Filter.Current, row.SegmentID);
if (!(row.NewSegment ?? false)) Filter.SetValueExt<NPMasterSubGeneratorFilter.segmentValue>(Filter.Current, row.SegmentValue);
}
return adapter.Get();
}
This works perfectly fine except for a single use case, after processing results are shown if the user then presses the cancel button the corresponding action is never hit. ( My fellow office devs state that core Acumatica processing pages seem to operate the same. )
Setting of the processing delegate is within the filter RowSelected event.
GeneratedSubs.SetProcessDelegate(list => CreateSubaccounts(list, row));
I have implemented a few iterations of my processing method but the current is below.
protected virtual void CreateSubaccounts(List<NPGeneratedSub> subs, NPMasterSubGeneratorFilter filter)
{
if (filter.NewSegment ?? false)
{
try
{
SegmentMaint segGraph = PXGraph.CreateInstance<SegmentMaint>();
segGraph.Segment.Update(segGraph.Segment.Search<Segment.dimensionID, Segment.segmentID>(AADimension.Subaccount, filter.SegmentID.Value));
SegmentValue value = segGraph.Values.Insert(new SegmentValue() { Value = filter.SegmentValue, Descr = filter.Description });
segGraph.Actions.PressSave();
}
catch
{
throw new PXOperationCompletedSingleErrorException(NonProfitPlusMessages.SegmentValueCannotCreate);
}
}
SubAccountMaint subGraph = PXGraph.CreateInstance<SubAccountMaint>();
NPSubAccountMaintExtension subGraphExt = subGraph.GetExtension<NPSubAccountMaintExtension>();
subGraphExt.save.ConfirmSaving = false;
Sub newSub;
bool errored = false;
foreach (NPGeneratedSub sub in subs)
{
PXProcessing<NPGeneratedSub>.SetCurrentItem(sub);
try
{
newSub = subGraph.SubRecords.Insert(new Sub() { SubCD = sub.SubCD, Description = sub.Description });
subGraph.Save.Press();
subGraph.Clear();
PXProcessing<NPGeneratedSub>.SetProcessed();
}
catch (Exception e)
{
PXProcessing<NPGeneratedSub>.SetError(e);
errored = true;
}
}
if (errored)
{
throw new PXOperationCompletedWithErrorException();
}
}
What needs to be adjusted to allow the buttons action to be triggered on press after processing results have been returned?
After stepping through the javascript I discovered that it wasn't sending a request to the server when you click the cancel button on this screen after processing. The reason is because SuppressActions is getting set to true on the Cancel PXToolBarButton. I compared what I was seeing on this screen to what was happening on screens that work correctly and realized that Acumatica is supposed to set SuppressActions to true on the Schedule drop down PXToolBarButton but for some reason, on this screen, it is incorrectly setting it to true on whatever button is after the Schedule drop down button.
I looked through the code in PX.Web.UI and it looks like they set SuppressActions to true when a drop down button is disabled and PXProcessing adds a FieldSelecting event to the Schedule button which disables the button after you click process. However, I didn't notice any obvious issues as to why the code would be setting it on the wrong PXToolBarButton so someone will likely need to debug the code and see what's going on (we are unable to debug code in PX.Web.UI.dll).
I tried commenting out the other grids in the aspx file that aren't related to the PXProcessing view and this resolved the issue. So my guess would be that having multiple grids on the PXProcessing screen somehow causes a bug where it sets SuppressActions on the wrong PXToolBarButton. However, since the multiple grids are a business requirement, removing them is not a solution. Instead, I would suggest moving all buttons that are after the schedule button to be before the schedule button. To do this, just declare the PXActions before the PXFilteredProcessing view in the graph.
Please try this
Override IsDirty property
Use PXAction instead of PXCancel
Add PXUIField attribute with enable rights
action name should start from lowercase letter
delegate name should start from uppercase letter
see code below
public override bool IsDirty => false;
public override bool IsProcessing
{
get { return false;}
set { }
}
public PXAction<NPMasterSubGeneratorFilter> cancel;
[PXUIField(MapEnableRights = PXCacheRights.Select)]
[PXCancelButton]
protected virtual IEnumerable Cancel(PXAdapter adapter)
{
NPMasterSubGeneratorFilter row = Filter.Current;
if (row != null)
{
this.Clear();
Filter.SetValueExt<NPMasterSubGeneratorFilter.segmentID>(Filter.Current, row.SegmentID);
if (!(row.NewSegment ?? false)) Filter.SetValueExt<NPMasterSubGeneratorFilter.segmentValue>(Filter.Current, row.SegmentValue);
}
return adapter.Get();
}

Stop users going from one page to another page

I want to stop users going from one frame/page back to the main previous page.
For example, when the user successfully logs in they are to go to the users list page.
If a user presses the hardware back button from the users list page, then they shouldn't go back to the login screen. If they do, the program should either prompt with two buttons, yes to logout and go back to the login screen, or no and stay on the current screen.
private void HardwareButtons_BackPressed(object sender, Windows.Phone.UI.Input.BackPressedEventArgs e)
{
Frame frame = Window.Current.Content as Frame;
if (frame == null) return;
//the current frame is UserList
if (frame.Content is UserList)
{
messageBox("yes");
e.Handled = true;
}
else if (frame.CanGoBack)
{
frame.GoBack();
e.Handled = true;
}
}
In theory, if the current frame is the user list page, then do not go back.
How can I stop a user from going back a page?
First you need to attach the event to HardwareButtons back button which is available in Windows.UI.Xaml.Input namespace. Add this below InitializeComponent call in page constructor.
HardwareButtons.BackPressed += HardwareButtons_BackPressed;
If you just handle the event it is enough to prevent user from going back with hardware back button.
private void HardwareButtons_BackPressed(object sender, BackPressedEventArgs e)
{
e.Handled = true;
}
If you don't want to allow the user to go back if the previous page is Login page you can try this.
private void HardwareButtons_BackPressed(object sender, BackPressedEventArgs e)
{
e.Handled = true;
if (Frame.BackStack.Last().SourcePageType.Equals(typeof(LoginPage)))
{
//TODO: handle prompt
} else {
Frame.GoBack();
}
}
ps: if you handle e you should provide Frame.GoBack(); manually otherwise users will be stuck in that page.

Disable Dialog closing after ENTER button pressed in ControlsFX

I have extended org.controlsfx.dialog.Dialog and added some TextField to it, which is supposed to act when ENTER button is pressed (if TextField has focus). However when I press ENTER, my dialog takes over of steering, and act like on OK button was pressed.
Is there any method which I can override in order to change this behavior (to intercept Enter action)?
Thanks in advance
I have received some workaround to this problem at ControlsFX mailing list which is good for me. To disable Dialog closing after Enter button is pressed in TextField we must consume event in EventHandler attached to this TextField
textField.addEventFilter(new EventHandler() {
public void handle(KeyEvent evt) {
.......
evt.consume();
}
});
For me works this:
dialog.getDialogPane().addEventHandler(KeyEvent.KEY_PRESSED, event -> {
if (event.getCode() == KeyCode.ENTER) {
event.consume();
}
});

Blocking action of CDialog's maximize/minimize button

I am using mfc CDialog. I need to show the close and minimize/maximize button, but they should not close or maximize the dialog. I have overriden OnClose method and kept the dialog open even if close button is clicked. But I am unable to block maximize and minimize of the dialog as there doesn't seem to be a OnMaximize method. Is there an alternative way?
You need to handle the WM_SYSCOMMAND message, watching for wParam == SC_MAXIMIZE.
If you catch the SC_MINIMIZE, you can do what you want and not pass it on to Windows.
msdn
Found this snippet here.
const int WM_SYSCOMMAND= 0x0112;
const int SC_MAXIMIZE= 0xF030;
protected override void WndProc(ref Message m)
{
if(m.Msg==WM_SYSCOMMAND)
{
if((int)m.WParam==SC_MAXIMIZE)
{
MessageBox.Show("Maximized!!");
return; // swallow the message
}
}
base.WndProc (ref m);
}
You can not show at all the minimise/maximise icons i your dialog. You can do that by going to Dialog properties (right vlick on your Dialog Contorol --> Properties), Select Styles pain and unselect 'Minimise Box', 'Maximise Box'.

Resources