Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations IamaSherpa on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Controls "outside" the Form 2

Status
Not open for further replies.

Scott24x7

Programmer
Jul 12, 2001
2,825
JP
So there are a number of discussions we've been having here, that seem to all be starting to tie together.
First, the elimination of PUBLIC (which I totally get is a good thing, and I'm committed to doing that).
Second the ability to print RTF in report form (Using Mike Gagnon's approach) or Office Automation (using Tamar's approach).
Which brings me to the third part -- building out the RTF capability, given the "RIBBON" bar that I've created within the MAIN form.

I was looking at the VFP Samples where they have an example of RTF, and example that I built from some other app years ago, where I stopped because I couldn't print it.
But both of these examples have the controls embedded in the form, and I want to be able to use them globally. (So any form open, will use the same controls when editing RTF editbox).

So when it's in the form, it's easy... the control and the ole box both see each other, and using the .ActiveControl property of the form, it's easy enough to get the ole field to respond to change in the RTF tools.

But, now my main form contains the "Ribbon Bar" that I've built. That bar is a pageframe inside the MAIN form as well. When I open a new window inside it, I can't reference Main.Pageframe1.basepage2.rtfControls.rtfFontSelect... To my OLE control in window CLIENTS which then has a pageframe within it, and pages, and ... down until I get to the RTF control (in one case, there is a pageframe on the page of another pagefram).

So all this deep traversing between forms which don't really see each other... to have a common set of controls like RTF font control, what is the best way to tackle this?


Best Regards,
Scott
MIET, MASHRAE, CDCP, CDCS, CDCE, CTDC, CTIA, ATS

"Everything should be made as simple as possible, and no simpler."[hammer]
 
Once I see it working, I think it will help a lot.
You mention it works for RTF and any field, but the RTF every character could be different (I know it won't be, but it's not out of the realm of possibility to have 2 - 3 fonts and maybe 2 - 3 sizes for each font within a long RTF box). So that is dependent upon SelText or SelStart if I understand correctly. Maybe I'm thinking about it too hard, but I thought it would need to cover those cases, versus the whole text box being applied with one font and size.

I had major dental work today, and I'm still foggy from the medication... maybe I should resume this tomorrow.

Best Regards,
Scott
MIET, MASHRAE, CDCP, CDCS, CDCE, CTDC, CTIA, ATS

"Everything should be made as simple as possible, and no simpler."[hammer]
 
Yes, you can have many sections with different fonts and sizes in word too, and the word font related Ribbon control will reflect that two-way, depending on where you put your cursor. But it doesn't have to be this way. It surely is not the concern of the fontsize picker of the ribbon to know the current font size, this is with the RTF code. You don't have to be as interactive as Word documents are, also only set the font and font size of the active selection in the moment of the change of the font or font size. But if you want to, of course you could act on RTF control events to set goApp.nFontsize to the fontsize at cursor position and then you have that two-way, too.

You also have a wrong idea what I meant with different fields. I was talking about binding totally independent and separate features of the ribbon with different controls, you don't just have the ribbon page or section for fonts, do you? Each and every section and control on the ribbon should just influence a data object it is bound to and whatever forms or controls need that info subscribing to changes via BindEvent. They don't subscribe to ribbon control value property but to properties of the data object connecting this. Why did I talk about goApp.oSettings or goApp.oSetup so many times already, not only here? goAppp is the host of many things, including many features and their settings. Anything that is of interest in more than one or two objects has to go there or into any other third thing like database tables are. goApp is your place for many quasi-static things like the application name (if you ever think of changing it you only want it to be defined in one place, not in 100s of MessageBox() calls third parameter value, don't you?) and goApp is your place of current application state like active language and also hosts active components like a form handler, database handler...

Simply look back to all I suggested about goApp already in your thread about public variables. So far you just picked out a few things and you do so in a way, that will need refactoring later, as you don't go the full monty right away.

Bye, Olaf.


 
Olaf,
Ok, I like this idea:
The idea about status and information and binding to their change is more valuable in this kind of involvement with the ribbon. Neither the ribbon should need to know what it influences nor should a control on any form - child form or main form - know the ribbon structure to pick out an information. Both ribbon and form should act on the so-called model. Data, properties, state, information. That's what you share.

The necessity to know references comes, if you want to interact with more than just the necessary information.

So if I understand it correctly, there is an object "outside" two other objects that is acting as a mediator. In this case, let's call it goAPP.oRibbon which was created in the pageframe init with goAPP.Ribbon = This (and I'm not clear here, should I have the whole form as a reference, instead making goAPP.oRibbon in the Form's Init?)

So now my goAPP.oRibbon has an object reference to the pageframe/form (depending on where created), that has pointers to all the same property and method names in the Ribbon?

Is this correct so far?

I look at it in the debugger, and I can see the object goAPP.oRibbon and it looks like it's the pageframe and all its contents, which for this purpose is fine, but I think you're suggesting if I put it at the form INIT instead, then I'll have access to all the objects at MAIN form, which has other things besides the ribbon I may want access to? Is that right?



Best Regards,
Scott
MIET, MASHRAE, CDCP, CDCS, CDCE, CTDC, CTIA, ATS

"Everything should be made as simple as possible, and no simpler."[hammer]
 
Ok, so now I progresses:

I look at it in the debugger, and I can see the object goAPP.oRibbon and it looks like it's the pageframe and all its contents, which for this purpose is fine, but I think you're suggesting if I put it at the form INIT instead, then I'll have access to all the objects at MAIN form, which has other things besides the ribbon I may want access to? Is that right?

So in the ribbon where the fontsize listbox is, I added in its Init:

Code:
_screen.AddObject("txtFontsize","Textbox")
WITH _screen.txtFontsize
    .controlsource = "goApp.nFontsize"
    .visible = .t.
ENDWITH

Since "EventSink" you say represents the form, then I assume I need to put the:

BINDEVENT(goApp,"nFontsize",This,"FontSizeChange",1+4)

In the form that's using the RTFedit box INIT?

So now I added the method FontSizeChange to RTF control.

This.SelFontSize = goAPP.nFontSize

Ah... note this is edited: It's working. I changed the _screen.txtFontsize as your example (I see that now) to WITH This ... ENDWITH within it's init code, and it worked.

Now, the one oddity I have, would be helpful is, the selected text in my RTF control in the form as soon as I go to the Ribbon and click the text size drop down, the selected text reverts to non-selected. I change the size, then the text that was selected changes its size, when I click back on the child form. the text is selected again. Is there some way to keep the selected text showing throughout? It's just a little "glitchy" behaviour compared to other editing interfaces. I tired setting ThisForm.LockScreen = .T. in the Form's LostFocus and back to .F. in GotFocus, but this didn't change the behavior.

Best Regards,
Scott
MIET, MASHRAE, CDCP, CDCS, CDCE, CTDC, CTIA, ATS

"Everything should be made as simple as possible, and no simpler."[hammer]
 
Just when I thought I had it...

I was tempted to start another thread, because this one is so long, and this issue is related, but kind of separate.

So after I got the fontsize change to work, I got all ambitious and thought I'd add fontname next.

So what I did was in the INIT of the RTF control Added in a second BINDEVENTS:

BINDEVENT(goApp,"nFontSize",This,"FontStateChange",1+4)
BINDEVENT(goAPP,"cFontName",This,"FontStateChange",1+4)

I decided to make a single method in the OLERTFcontrol to "FontStateChange" since there are a bunch of attributes I'll be tracking, and maybe more than one change at a time, so instead of a string of calls to different functions, though I'd just apply all the changes at once with:

WITH This
.SelFontSize = goAPP.nFontSize
.SelFontName = goAPP.cFontName
ENDWITH

The problem though is, now, as soon as I try to select any text in the OLE control, it blows up.
With Error # 1429
Error Message:
OLE IDispatch exception code 0 from RichTextControl: Invalid Property Value

Now, I commented each out (so just font or just size) was enabled, and singularly they work... so can you not have more than one BINDEVENT in a control? Or is there some other way I should do this? Am I confusing the OLE control with too many parameters?
*
Or do I have to keep each one in its own method?



Best Regards,
Scott
MIET, MASHRAE, CDCP, CDCS, CDCE, CTDC, CTIA, ATS

"Everything should be made as simple as possible, and no simpler."[hammer]
 
Well, lesson learned.
You have to make them separate, which is fine. Thought combining them would be elegant, but the OLE control doesn't like it. :)

So that's solved, sorry for the rambling.

Though my issue with selection not showing while away from the form remains, so if anyone has a solution to that, I would be really grateful.


Best Regards,
Scott
MIET, MASHRAE, CDCP, CDCS, CDCE, CTDC, CTIA, ATS

"Everything should be made as simple as possible, and no simpler."[hammer]
 
BTW Olaf, I'm just starting to scratch the surface on understanding how this actually works, (but it was still easier than images in a grid! :)
Thanks for taking me through this. I have to say the whole thing is very non-intuitive, I don't think in 100 years I'd have ever figured this out on my own.
Greatly appreciate it.
Now this is something that suddenly makes our application extremely modern and vibrant. I can't wait to apply it to all of our edit regions, and then start to work with printing the RTFs that Mike G and others have mentioned.
In my industry, this is going to be such a competitive advantage.
Many thanks.


Best Regards,
Scott
MIET, MASHRAE, CDCP, CDCS, CDCE, CTDC, CTIA, ATS

"Everything should be made as simple as possible, and no simpler."[hammer]
 
Let me try to catch up.

>So if I understand it correctly, there is an object "outside" two other objects that is acting as a mediator. In this case, let's call it goAPP.oRibbon which was created in the pageframe init with goAPP.Ribbon = This

No, this outside mediator object is goApp, or goApp.oSettings or other sub-objects. It is NOT goApp.oRibbon. That was the solution you wanted, but that is making the ribbon form a known reference to everything and that will mean, that a control needing an information now knows a reference to the ribbon, but will need to "know the ribbon structure to pick out an information". And that is unfortunate. When you want to allow customers to reorganize the ribbon in any way or when you reorganize your ribbon years from now, then all code accessing ribbon objects will need to change.

This idea you only got half is just like the normal sharing of data. You have forms bound to tables, if you need access to customers, you address the customer table and not the controls of the customer form bound to these tables, don't you? The goApp.oSettings will not be a reference to a table, but to objects and properties having loaded config data or default values or just the current values set by ribbon controls. But what is important is, the structure of the oSettings is merely giving the settings a reasonable name that can stay this way forever, no matter how the ribbon changes.

This is also not the first time I say this. What are you doing? Are you skipping each second sentence, are you speed reading this and only picking up 50% of it?

Further answers separately. Later.

Bye, Olaf.
 
Hi Olaf,
Ah, I see yes. The goAPP already existed, and I created it very high in the process before any forms exist. Then we make a reference to some other existing object, in this case the ribbon pageframe (Though it seems it would be better if I reference the whole form instead? I'm not sure why, but when I get bit by it some time in the future it will make me go "OH, THAT's what Olaf ment".
As for other stuff, not speed reading, but maybe not far off in that I'm comprehending about 1/2 what you are saying hence the feeling of 50%, and still very fuzzy on some other areas. I'm sure it is obvious to you, but for me, for some reason, some mental block, and I only understand once I can explain it back, and I'm not there yet (which is why I was trying to explain it in my post... if I say it out loud, maybe it makes sense to me... I have a very weird learning method, but I'm stuck with it).
I would say just know I do understand about 1/2 of what's happening. On the plus side, once I get a working example of something, I tend to be very quick to replicate it. I had some stumbling block initially with some of my other controls because they are (oddly) simpler than the drop down boxes. They don't need control source, so I wasn't sure how to manage it, then I just assign the goAPP.<value> = <some value> directly, and the BINDEVENTS took care of it (like Font Color, I have button that is just like Word color button... when you pick a color, it changes the bar under the A in the button to that color, and that color is passed to the OLE.SelFontColor via goAPP.nFontColor property... That was COOL.)
So I think I have the way now for the ribbon to talk to the control. Since this is all about RTF editing, I don't really see this part change in the future. OLE box won't change, Font picking and attribute setting won't change... if it does, the OLE control can't manage it anyway (like superscript and subscript... can't do those already). So I'm not too worried in this case about the years from now change of this, though I get I should be worried about that overall for something more dynamic.
At least for now it is working, and I can mature it later, as I come to terms with understanding WHY and HOW it works, than I am able to grasp for now.
I'm happy being the C student.


Best Regards,
Scott
MIET, MASHRAE, CDCP, CDCS, CDCE, CTDC, CTIA, ATS

"Everything should be made as simple as possible, and no simpler."[hammer]
 
>OH, THAT's what Olaf ment

I switch from suggestion to reacting to your rejections, that's why there are multiple ideas. So you have separate the ideal suggestions I made from reactions to your rejections of ideas and to make compromises. Having goApp.oRibbon at all is such a compromise. In my ideal practice suggestions it will not exist. The ribbon should be self-contained and encapsulated in itself, forms should be self-contained and encapsulated each in itself. Their interaction and share of information is via goApp.oSettings, or whatever else you imagine a better name for an information interchange object. A third object.

Bye, Olaf.
 
Hi Olaf,
I guess I am not understanding. Where would goAPP.oSetting be established?
Since it's just a reference, isn't oRibbon really irrelevant, it's just a name, though it gets assigned at INIT of the Pageframe, can move that to the form or before the form right?

I like this idea actually, but I thought it wouldn't work for my case for some reason. I think you think my grasp of OO is better than it is. I wish that were so, and I'm getting better but some of this is like speaking Japanese...
My analogy here is this. I live in Japan. If I say something in Japanese to someone like "How much is that" (Kode wa ikurda deska), they suddently think I'm fluent in Japanese... so when they answer me back, in something other then exactly the cost of what ever I pointed at, I have NO idea what they are saying.
I think our communication is sometimes like that. I appreciate that you think I understand this, but really... I don't. Parts I get very solid. The DB side, NO problem (how often you see me ask a question about database manipulation?) The OOP and interface side, very complicated for me. Still trying to get my head around it, and worse after having been "off" for so many years. And so many things I was "told" were the way to do it back in VFP 3, 5 and 6, now everyone says "don't do it that way..." It's very confusing to me sometimes. I know that the only reason I get anywhere in this stuff is just pure tenacity. I keep grinding away until I find a solution. I'm sure sometimes my solution isn't the best one. So I always try to make it better later, if for now, it's the best I can do.



Best Regards,
Scott
MIET, MASHRAE, CDCP, CDCS, CDCE, CTDC, CTIA, ATS

"Everything should be made as simple as possible, and no simpler."[hammer]
 
The idea is, that you don't act on ribbon controls from outside the ribbon, but act on the pure informations in the form of object properties of oSettings. This is the whole nature of the suggestion, to AVOID acting on ribbon controls. oSettings is the third object aside of the ribbon form/controls and the child forms the tools should influence. The interacton goes through oSettings via diferent bindings. The ribbons binds to oSettings properties as controlsource of its tools, the forms bind to their changes via bindevent.

Bye, Olaf.
 
Well, I'm interested in doing it right. I'm sorry I deviated the conversation, I thought it was going the preferred method.
So if I create goAPP.oSettings at the startup.prg is that the suggested approach?


Best Regards,
Scott
MIET, MASHRAE, CDCP, CDCS, CDCE, CTDC, CTIA, ATS

"Everything should be made as simple as possible, and no simpler."[hammer]
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top