How can I disable TRadioButtons on a panel without changing their appearance? - radio-button

The scenario
I have a reasonably complex form that is used for either data entry or for viewing with no editing allowed, depending upon a state variable (the colour and headings on the form change depending upon the state). It contains many panels containing data entry type components. When in the viewing (non editing) state these panels are set to disabled, so preventing any of the components they contain from being changed.
One panel contains four TRadioButtons and a memo box with scroll bars.
Because of the amount of text in the memo I still want to be able to scroll the memo box when in view mode in order to read it all. However I do not want either the memo text or the radio buttons to be changed.
What I have tried
Instead of disabling the whole panel I leave it enabled and just make the memo box read only. This allows scrolling but not editing of the memobox as desired.
However as the panel is enabled it means the radiobuttons are also enabled and can be changed.
If I set the enabled property of each radiobutton to false I can prevent them being changed as desired but this also changes their appearance and greys them out.
Question
How can I prevent a user from changing the radiobuttons on this panel whilst keeping their appearance unchanged as if they are enabled i.e. without them greying out?
Minimal reproducible example
procedure TFrmMember.ShowMemberForm(MemberDisplayMode: TMemberDisplayType);
begin
case FormDisplayMode of
<other stuff in a big case statement depending upon MemberDisplayMode>
ShowNoEdit: begin
SetFormDisplay(ShowNoEdit); //set colours and titles etc
DisableAllControls; //disable all panels on the form
//now enable scrolling of the comment memo content but don't allow edits
PanelComment.Enabled := True; //enable the panel containing the memo and 4 radiobuttons
MemoComment.ReadOnly := True; //don't allow editing of the memo
//now disable the radio buttons -THIS CHANGES APPEARANCE ??
RadioButtonCircEmail.Enabled := False;
RadioButtonCircPost.Enabled := False;
RadioButtonCircBoth.Enabled := False;
RadioButtonCircNone.Enabled := False;
<other stuff>
end;
<other stuff in a big case statement depending upon MemberDisplayMode>
end; //case
end; //procedure ShowMemberForm

Place a TPanel on the existing Panel and move the RadioButtons to this new Panel. Or, use a single TRadioGroup instead of placing individual buttons on a Panel.
Then you can disable just the new Panel/Group, while keeping the parent Panel enabled and setting the TMemo to read-only.

Related

Control Source of a text boxes set to DCount function - Refresh issue

I'm setting the control source of text fields to return the value of a function (multiple fields with different filtering conditions). The form has a combo box with a list of years: when the user selects a specific year, the on change event triggers a refresh of all the fields.
My problem is the fields don't show any values unless after combo box's On Change events. I have to click on the form/fields before the values start showing up.
I tried to do form refresh & field's requery but doesn't work.
The text field's Control Source is set to:
=SummaryReport("Projects","G","1",[Forms]![frmSUMMARY_REPORT]![cmbYEARS])
What I'm trying to do is when the user selects a year from a drop down, the fields values are updated & displayed by the On Change event - currently they seem to be updated but are not showing unless I click on the screen and that's when values start showing up in each field.
The method to update calculated fields is Me.Recalc (or myForm.Recalc):
https://learn.microsoft.com/en-us/office/vba/api/access.form.recalc
Try this instead of .Refresh.
Also I think the better event to use is After Update instead of On Change for a combo box.

combobox properties to allow user to type text in it and let it filter by text entered

I have a combobox where I'll need to allow user to search by text and be able to select that value from the list. So what I'm currently doing is, on CBO_KeyPress, I open the drop down.
Me.cboNames.DroppedDown = True
I set the property of the cbo...
AutoCompleteMode=SuggestAppend
DropDownStyle = DropDown
AutoCompleteSource=ListItems
Everything works beautifully except for one issue. As it stands, i have items in the drop down where the width is significantly wider than the combobox - I have a function that adjusts the DropDownWith to longest string in the list of items. My concern is that while this helps user search for correct item, it's width is only as wide as the combobox. Is there a way to adjust this?
My only other option is to not use AutoCompleteSource=ListItems and instead simply open the dropDown programmatically on KeyPress or something. In this case, it doesn't do as good of a job of filtering the items. AutoCompleteSource does it beautifully but the width issue does not make it look right.
EDIT : Plutonix - here's what I did. I changed AutoCompleteSource=None. On CboName_KeyPress I open dropdown programmatically. Now I type in text, see image below....
It doesn't find text 100% of the time as you can see. AutoCompleteSource narrows it down and only shows you the items that begin with the same text as typed by user but the width is the issue. It actually looks much better with AutoCompleteSource because if they type in text that's not in the list of items then it shows nothing - and user known it's not in the list.
Users tab into the filed and start typing text. They don't open it. That's why they want this to be updated like that. I want them to see the items as they type in.

wxPropertyGrid::EditorValidate() always returns true

A user is editing a value in a property grid, then he clicks a button outside the property grid which executes code to read the property values. Sometimes the OLD value of the property is read, rather than the new value which was being edited. I have to tell the users that they must complete the editing, by hitting return or clicking on another property before clicking any buttons outside the grid. They forget, and report a bug.
I would like to make this foolproof. Perhaps by forcing the current edit to complete when the mouse leaves the property grid.
I know how to handle the mouse leaving event. I do not know how to force the property grid to accept any partial edits.
I have tried, as a hint to the user,
pg = new wxPropertyGrid( ...
....
if( ! pg->EditorValidate() )
{
SetStatusText("Please complete editing");
return;
}
but EditorValidate() always returns true
Found it!
wxPropertyGrid::CommitChangesFromEditor()
http://docs.wxwidgets.org/trunk/classwx_property_grid.html#a6e06d92a622237457fea00372df1eaae

Dynamically manipulate a menu to create an MRU in a Windows app in Progress

I have a Windows application written in Progress. I'm working with version 10.1C. I would like to add MRU functionality to the menu, i.e. I want to add, remove and modify menu items in the application's File menu, to show the user's most recent files in the order in which they were used. I've done this often enough in a number of other languages, it's a pretty common feature and very easy to do.
But how would one do this in Progress? In another language I could have created 10 menu items and simply made the unused ones invisible, but you can't do that in Progress. I can't imagine why.
Alternatively, I should be able to dynamically create menu items as needed and add them to the end of the MRU list in the File menu, but I can't seem do that either: Firstly, I can't specify where in the File menu the item must be added, it always adds it to the bottom, and secondly, I can't add dynamic menus to static menus, so I can't add my MRU menus to the existing File menu. I can do it if I make the whole File menu dynamic (which I really don't want to do), but then I can't add the dynamic File menu to the static menu bar. This leaves me with the unacceptable option of making the entire menu structure dynamic.
Does anybody have any ideas?
Using Ade's answer below, here is a brief example of how I achieved it. Changing the labels and values of the MRU items doesn't require any fiddling, just set the appropriate attributes, but in order to add new MRU items, I have to remove and recreate the Exit menu item:
/* Remove the RULE and Exit menu items */
IF VALID-HANDLE(ghMenuRule) THEN DELETE OBJECT ghMenuRule.
IF VALID-HANDLE(ghMenuExit) THEN DELETE OBJECT ghMenuExit.
/*
...
Coding to add MRU items.
...
*/
/* Create the RULE and Exit menu items */
CREATE MENU-ITEM ghMenuRule
ASSIGN
SUBTYPE = "RULE"
PARENT = MENU m_File:HANDLE IN MENU MENU-BAR-C-Win.
CREATE MENU-ITEM ghMenuExit
ASSIGN
PARENT = MENU m_File:HANDLE IN MENU MENU-BAR-C-Win
LABEL = "E&xit"
TRIGGERS:
ON CHOOSE PERSISTENT RUN ExitApp IN THIS-PROCEDURE.
END TRIGGERS.
The actual MRU items are created just like the Exit menu is created here, except that I store the handles in a temp-table.
The result is a menu like this:
File
New
Open
--------
Print Setup
Print
--------
1 Mru item
2 Mru Item
3 Mru Item
--------
Exit
create a static menu MENU-BAR-C-Win.
add static sub-menu "File" m_file.
add static menu-item (use ">>") "Exit" (m_Exit) to m_file.
define....
DEFINE VARIABLE hMRU#1 AS HANDLE NO-UNDO.
create a button to dynamically...
CREATE MENU-ITEM hMRU#1
ASSIGN
PARENT = MENU m_File:HANDLE IN MENU MENU-BAR-C-Win
LABEL = "MRU#1"
TRIGGERS:
ON CHOOSE PERSISTENT RUN SomeThing IN THIS-PROCEDURE.
END TRIGGERS.
you'll want to keep track of your handles (temp-table?) some how.

Gray out a form row's (detail's) button conditionally with VBA code

I have a standard form in MS-Access which lists a bunch of orders, and each row contains order no, customer, etc fields + a button to view notes and attached document files.
On request from our customer we should gray out the button btnAnm (or check or uncheck a checkbox) depending on a calculation from two queries to two other tables (a SELECT COUNT WHERE and a check if a text field is empty).
I've tried btnAnm_BeforeUpdate(...) and btnAnm_BeforeRender(...) and put breakpoints in the subs, but none of them trigger. The same if I use the control Ordernr instead of btnAnm.
I'd like a function in the Detail VBA code to be triggered for each "Me." (row) so to speak, and set the row's control's properties in that sub.
What do I do? I've looked at the help file and searched here.
*Edit: So I want to do something that "isn't made to work that way"? Ie. events are not triggered in Details.
As an alternative, could I base the value of a checkbox on each line on a query based on the 'Ordernr' field of the current row and the result of a SELECT COUNT from another table and empty field check?
Do I do this in the query the list is based on, or can I bind the extra checkbox field to a query?
A description of how to do this (combine a COUNT and a WHERE "not empty" to yes/no checkbox value) would be perfectly acceptable, I think! :)*
You cannot do much with an unbound control in a continuous form, anything you do will only apply to the current record. You can use a bound control with a click event so that it acts like a button.
Presumably the related documents have a reference to the order number that appears on your form, which means that you can create a control, let us call it CountOrders, with a ControlSource like so:
=DCount("OrderID","QueryName","OrderID=" & [OrderID])
The control can be hidden, or you can set it up to return true or False for use with a textbox, you can also use it for Conditional Formatting, but sadly, not for command buttons.
Expression Is [CountOrders]>0
You can also hide the contents and add a click event so that is acts in place of the command button. Conditional Formatting will allow you to enable or disable a textbox.
As I understand your question, you have a continuous form with as command button that appears on each row - and you'd like to enable/disable the button conditionally depending on the contents of the row.
Unfortunately you can't do that. It seems that you can't reference the individual command buttons separately.
Having wanted to do something similar in the past I came up with two alternate ways of setting up my interface.
Put a trap into the onClick code for the Button. Which is icky, because it is counter intuitive to the user. But it gets you that functionality now.
Move the command button (and editable fields) up into the form header, and make the rows read only. Your users then interact with the record only in the header, and select the record they want work with in the list below. As I recall this is known a Master-Detail interface.