Welcome to the SRP Forum! Please refer to the SRP Forum FAQ post if you have any questions regarding how the forum works.


I am tring to call Form_Services.SetWindowReadOnly.

The problem I am having is with EditLines that have been subclassed.

The section in question is
Equate WM_SETREADONLY$ to 207 Case Type EQ "EDITBOX" OR Type EQ "EDITFIELD" hwndEdit = Get_Property(Control, "HANDLE") Send_Message(hwndEdit, WM_SETREADONLY$, Yes$, 0)

Options are still able to be selected and the user can then save the record when prompted at exit so not exactly a Read Only.
Turning off the Subclassing altogether in the form's Create to test and then just do a straight Set_Property(Control, "ENABLED", Yes$) in SetWindowReadOnly is more the behavior I was after.

So I thought I would be smart and unsubclass it programatically and then try the straight disable but with no luck (it didnt seem to unsubclass)
Equate SubClass$ to @Window:".OLE_SUBCLASS" Send_Message(SubClass$, "OLE.Unsubclass", Control) Set_Property(Control, "ENABLED", No$)

What am I doing wrong?


  • The timing of this question if amusing. I have another client that just reported the exact same issue. You will need to amend the code to set the OptionEnabled property.
  • @DonBakke

    Maybe the Universe was just waiting to nudge me ;-)

    I must be doing something wrong. I have tried to both disable the option as you noted, as well as removing the button alogether.

    Equate SubClass$ to @Window:".OLE_SUBCLASS" Convert "." to ";" in Control Set_Property(SubClass$, "OLE.OptionButton[":Control:"]", No$) Set_Property(SubClass$, "OLE.OptionEnabled[":Control:"]", No$)

    So I tested with disabling the field alogether
    Set_Property(Control, "ENABLED", No$)

    However, this works (just not wanted)
    Set_Property(Control, "VISIBLE", No$)

    Not sure if it matters but I am using the latest Controls but a super old FrameWork.
  • edited May 2023
    Since Frameworks is going to have to be updated to include this, I was looking at this today using a test window setting multiple option buttons and then both manually setting the OptionEnabled and then using the Form Services to set read only. These are the things I would confirm:
    1. Your subclass control is actually named "OLE_SUBCLASS" on your form. I'm guessing since you can see the option button, this is probably ok, but just in case. If you are using Form Services SetOptionButton to put the button in the field, it is going to find the subclass control on it's own, but if the form has some other name, it's going to go looking for OLE_SUBCLASS on the frame.
    2. The SetWindowReadOnly section is actually getting called. I threw a debug in the editfield section just to make sure.
    3. The field in question is NOT a key control or part of a multi-part key. SetWindowReadOnly does not disable the key control so users could still view different records in a read-only state. If you needed to lock that down, you'd have to do that manually / in your window's code after the appropriate event.
    This is the code I've added to the editfield section of SetWindowReadOnly, which is working how I would expect it to (locks down all fields' option buttons, except for the key):
    Subclass = Form_Services("FindSubclassControl", @Window) Convert "." to ";" in Control Set_Property(Subclass<1>, "OLE.OptionEnabled[":Control:"]", No$)
  • @FrankTomeo

    After I started to respond with negative results and scrrenshotsI actually took a second and re-read your post and actually consider what it meant. I am glad I did because you were spot on!

    The SubClass control at this point thanks to the Equate is "FW_MAIN.OLE_SUBCLASS".
    Setting a variable to WINDOW:".OLE_SUBCLASS" for my call made all the difference. I started to see some expected results.

    I will note, however, that the OptionEnabled documentation notes "Normally, option buttons take on the enabled state of the EDITLINE control.". I took this to mean if the Control was disabled then the Option was disabled by default. I have not found that to be the case but then again, maybe that is why @DonBakke pointed me to OptionEnabled. Even when I disabled the Control the Option Buttons were still active so doing both gets the result I was after.

    Now all I have to do is work out how I can get this to work for multi-instance forms since the WINDOW variable does not have the Instance ID and, as noted, @WINDOW is FW_MAIN at this point.

  • I will note, however, that the OptionEnabled documentation notes "Normally, option buttons take on the enabled state of the EDITLINE control."

    That does seem ambiguous, but I took it to mean that this is the normal desired behavior but sometimes a developer might want the edit line to be set differently than the option button. Hence, the need for this property. Perhaps Kevin (the engineer for this feature) meant it differently and we have a feature that doesn't work fully as expected.
    Now all I have to do is work out how I can get this to work for multi-instance forms since the WINDOW variable does not have the Instance ID and, as noted, @WINDOW is FW_MAIN at this point.

    This has me confused. Do you not put subclass controls on the individual forms?
  • It may work as expected, just not as I interpreted ;-P

    I absolultey have the Subclass on the individual Form.
    I debugged at the same point in Form_Services as Frank and at that stage my @Window is FW_MAIN and the Window variable is the Form Name (excluding the InstanceID). I was hoping for something like DBW_FORMNAME*2

    I havent yet had a chance to look upstream from that to see how it is getting to that point.

  • edited May 2023
    Not sure how / when you are calling Form Services, but for comparison, I'm calling it at the end of the window's promoted create event. (The window is being launched from the ribbon control in Frameworks):
    Form_Services("SetWindowReadOnly", @Window) If I launch multiple instances of the window, it works out fine, as @Window being passed in has the instance id. Form Services will also try to figure out the window if the passed in window parameter is blank. So, somewhere is either passing in a non-instanced window variable, or a null is being passed in and Form Services is taking its best guess.
  • @FrankTomeo

    Thanks for that feedback. It gave me a thought...
    We are also launching from the Ribbon so I did a bit of a trace.
    It appears we are using Command_Services.Execute as a core of our security integration.

    After launching the MDIChild the service does this check:
    // [SRPFW-211] Read Only If ExecuteProcedure _eqc "Child Window" or ExecuteProcedure _eqc "Window" then If CommandAccess _eqc "Read Only" then Form_Services("SetWindowReadOnly", ExecuteParam) end end

    Unfortunately ExecuteParam was taken from this so has no instance ID:
    CommandRec = SRP_HashTable("Get", CommandsHandle@, Command)

    However, if I take the response from the Start_MDIChild, which contains the instanceID, to use as the ExcuteParam instead for a Child Window, it now behaves as expected!
Sign In or Register to comment.