ActiveX Controls don't treat Focus the same

If a RichText control on a form doesn’t have focus yet, it responds to being clicked on by calling the IOleControlSite::OnFocus method inside VFP. The VFP code says Aha!: there is a focus change happening, so it fires the LOSTFOCUS event for the control losing focus and the GOTFOCUS event for the control getting focus. The code also keeps track of which control has focus. This is all fine and dandy and everybody’s happy.

The DHTML Editing and Web Browser controls do not call that method. So VFP can’t fire the focus events and loses track of which control has focus: The ActiveX control is marked as still having focus, and when you try to interact with the textbox, the ActiveX control is sent the events. You can see this behavior by running the code below. Click between the textbox and the ActiveX control, type a few characters. Try the Web control or the RichEdit controls by uncommenting those lines, and they work fine.

You say “That can’t be. The Task Pane, the Class Browser, the Object Browser each use the Web Browser control and they don’t seem to have this problem.” Pat yourself on the back: you’re right!

Almost 8 years ago, for VFP6, I put in a workaround for this behavior specifically for the Web Browser control. Here’s my comment for the code checkin: “workaround for IE3,IE4 bug: The weboc doesn't call OnFocus, so we fake it in OnUIActive”. The workaround is in the code that handles IOleInPlaceSite::OnUIActivate. The workaround code says if the control is the Web Browser control, fire the events for focus change manually. If I do the same workaround for the DHTML control, it works fine. The RichText control fires both the IOleInPlaceSite::OnUIActivate and the IOleControlSite::OnFocus, so it doesn’t need the workaround.

Should the control fire the IOleControlSite::OnFocus method when it gets clicked and gets focus? Or should it be content in firing the IOleInPlaceSite::OnUIActivate ? Today’s documentation doesn’t specify, and the documentation when the VFP code was written over 10 years ago was probably different. Perhaps the DHTML and Web Browser controls have similar architectures, originating from the same team, and thus interpreted the documentation the same way. The RichText control seems to have interpreted the documentation a different way. Or perhaps the Web Browser and the DHTML controls are *so* rich in functionality that they are hardly ever used on a form where they need to co-exist with other controls.

BTW, the DHTML editing control is kinda cool. Uncomment the LoadURL code below to preload it with some HTML and run the code. The DHTML control allows you to drill into HTML objects, so to type text or drag/drop items, you may need to click a few times. Try dragging/dropping things around or typing new content. Be sure to save the file and overwrite the MSN website content!<g>

PUBLIC ox as Form

ox = CREATEOBJECT("fform")

ox.Show()

DEFINE CLASS fform as Form

      height=600

      width=500

      allowoutput=0

      left=200

      ADD OBJECT ot as textbox WITH left=10, width=200 ,top=5

      ADD OBJECT oc as myolecontrol WITH left=10,width =400, height =500, top=30,anchor=15

      PROCEDURE init

            TRY

                  this.oc.navigate2("https://www.msn.com") &&web browser control

            CATCH

            ENDTRY

            TRY

* this.oc.loadurl("https://www.msn.com") && DHTML Edit Uncomment to load with content

            CATCH

            ENDTRY

ENDDEFINE

DEFINE CLASS myolecontrol as OleControl

      oleclass="DHTMLEDit.dhtmledit.1" && DHTML Edit

* oleclass="shell.explorer.2" && Web Browser

* oleclass="RICHTEXT.RichtextCtrl.1" && Rich Text

      PROCEDURE init

            thisform.caption=this.oleclass

      PROCEDURE Lostfocus

            ?PROGRAM()

      PROCEDURE Gotfocus

            ?PROGRAM()

      PROCEDURE refresh

            nodefault && for web browser control

ENDDEFINE