![]() Delphi™ | C++Builder™ Technical Articles |
|
Delphi™ | C++Builder™ Technical Articles CALLING CLASS METHODS — A CLASS METHOD INTRODUCTION FOR APPLICATION DEVELOPERS PAGED, MULTIPLE WORKSPACE (PMW) APPLICATION DEVELOPMENT MODEL GOALS OF THE PAGED, MULTIPLE WORKSPACE (PMW) APPLICATION DEVELOPMENT MODEL HOW TO BUILD SUPERIOR PAGED, MULTIPLE WORKSPACE (PMW) APPLICATIONS ROOT CLASSES — OOP BASE CLASSES WE CAN WORK WITH VITAL FIXES FOR FUNDAMENTAL OWNERSHIP AND STREAMING PROBLEMS IN THE DELPHI™ IDE |
|
VITAL FIXES FOR FUNDAMENTAL OWNERSHIP AND STREAMING PROBLEMS IN THE DELPHI™ IDE |
|
Here too, in the years which have passed since we expressed our imperative need that Borland fix these issues, proper support for streaming/serialization has become a principal instrument of Microsoft .Net tools. Our current projects are just now testing whether Microsoft implementations meet the necessary standards to develop some of the more complex visual control implementations we have succeeded in, despite these critical flaws in Borland Delphi™ and C++Builder™. As to how "well" Borland tools might support .NET implementations which are essential to our own goals... we can only report that no committment to cooperate in rectifying these faults means we cannot continue to use Borland tools. An often repeated cycle first appears to observers, with a component Developer A reporting their component will not accept controls placed on it at design time. Because the documentation advertises that this behavior succeeds by inclusion of the csAcceptsControls flag, a Developer B reminds Developer A to include csAcceptsControls. Possibly to some embarrassment of Developer B, Developer A responds that they already have. The rest of us often lose interest at this point, expecting there is nothing to learn from this query. After all, csAcceptsControls "works" in TWinControl, TCustomPanel, TTabSheet and so forth; and so we ask ourselves how credible the reported dysfunctionality can be. Without a serious effort, we can only come up empty handed. But it is this presumptive thinking itself which is flawed, because, as it turns out, csAcceptsControls does not work at all but for the most simple possible cases of TWinControl, TCustomPanel, TTabSheet and so forth — and so, this often repeated pattern is actually prominent evidence that substantial issues exist in what we think carelessly is a proven system. In what amounts to the proverbial search for a needle in a hay stack, Developer A is no neophyte. They have already spent weeks exhausting every conceivable combination of csAcceptsControls with every further potentially relevant condition they can think of. They have looked everywhere for examples. They have scoured resources for further references. They find none of either. The nearest potential VCL example they have collected will take weeks of careful study and test code before they can realize how it does not model their problem. Those eventual weeks of work yet face steep odds they may never understand why. To discover so, they may write days of code that melt into weeks and months which ultimately "can never get there from here." After all of this, their efforts remain at inch one, with miles of problem ahead. Only hoping that Developer B has succeeded in such a design, and receiving no other useful answer, Developer A asks what else they might be doing wrong. But Developer B too only took the documentation at face value, and their expertise is no greater or more valid than the little they have merely read. It is Developer A who is closer to finding the truth. Both have assumed csAcceptsControls *works*, because it has in fact succeeded in only the most simple possible classes — TPanel, TWinControl, TCustomPanel, TTabSheet, etc. Actually, to call these challenges "steep" is to understate what is more an impassable mountain range. Actually, Developer A hasn't (necessarily) done anything wrong. But to understand that, we and Developer B have to conquer substantial problems that the very designers of the IDE never solved. If we or Developer B had ever succeeded to the end of that difficult road, we would instead answer the original post with an explanation,
Actually, to call these challenges "steep" is to understate what is more an impassable mountain range. Months pass. The answers are never found. Intended products are never completed. Each Developer A's issue disappears without a solution — or worse, with a retort that is not a solution at all, but appears (quite superficially) to close the issue. As the years go by, mountain after mountain of futile effort are wasted untold times in untold places as the csAcceptsControls issue recurs again and again. |
|
WHERE csAcceptsControls OUGHT TO BE FIXED |
|
Before we explain how what we shall call "composite parent controls" can accept controls from the present development environment, let us first be clear,
|
|
RAMIFICATIONS OF LACKING PROTECTION CAPABILITIES |
|
What are some of the undesirable consequences that you cannot provide well conceived protection against?
|
|
BASIC PROBLEM OF FIXING csAcceptsControls IN OUR CONTROLS |
|
Our basic problem is,
|
|
NEAREST PATTERN FOR SOLVING THE csAcceptsControls ISSUE |
|
The source for TPageControl provides your nearest model for dealing with csAcceptsControls issues. Yet only after very substantial study might you see that TPageControl cannot take you where you need to go, even as substantial program flow is introduced to deal with the coincidental capacity to select and delete pages (TTabSheets):
These are the matters that Developer A's study may never come to understand, and which can lead to tremendous futile programming — hoping to make the TPageControl model work for *integral* subcomponents which are not separable parts, and which cannot tolerate the unprotected capacity of the development environment to delete them. TPageControl however is no model at all for a greater reason: It paves no ground by which composite controls can accept controls in regions which are not (and should not be) subject to the circumstances that the root layers of TPageControl and TTabSheet are. This shall be clear in due course. |
|
HOW csAcceptsControls IS BROKEN |
|
As yet, your effort is aware of only one issue, this being that your *composite* control will not accept other controls placed on it at design time. If you conquer this first issue (and we will prescribe how to do so immediately), your reward will only be to discover the real quagmire. The fact your component does not accept controls is just the tip of the iceberg. You are the Titanic, confidently steaming into waters which are not RAD, and which will soon send your best work to the bottom of the sea. You are the Titanic, confidently steaming into waters which are not RAD, and which will soon send your best work to the bottom of the sea. To introduce the iceberg ahead, let us proceed directly to the solution of your perceived issue. You may try this immediately, and indeed, you will find your *subcomponent* will accept controls by the only means it is possible (under the present IDE design) to accept controls:
Hmmm. We have of course simply skipped across the vital learnings from which we develop this conclusion. But to get your composite control to accept further controls from the development environment, we need only pass a pointer to the form to the constructors of your interceding subcomponents. So, if our component will now accept controls from the development environment, how is csAcceptsControls (still) "broken?" |
|
HOW csAcceptsControls IS STILL BROKEN |
|
Backing up a step, we discover our clue how csAcceptsControls is indeed broken; and this clue indeed suggests that things may very well not be right with our only possible solution:
Having emphasized this, I expect many of you will certainly smell a rat. We have been forced to give ownership to something we should not. The IDE designers have broken an essential pattern; and, as yet, we can only anticipate what ramifications that broken pattern have. Note, most importantly, that we have not fixed csAcceptsControls:
How does this actually play out? |
|
HOW OUR FIXED csAcceptsControls PLAYS OUT |
|
Our problem soon reveals obstructions which indeed are as surprising and imposing to our project as the iceberg which suddenly loomed ahead of the Titanic. Only after complying with this *requisite of the streaming system* can we discover how far we are from even *finding* (much less solving) the problems which ensue. Our ship is just now grazing the iceberg. Our problem soon reveals obstructions which indeed are as surprising and imposing to our project as the iceberg which suddenly loomed ahead of the Titanic. Only after complying with this *requisite of the streaming system* can we discover how far we are from even *finding* (much less solving) the problems which ensue. Our ship is just now grazing the iceberg. To have the slightest idea of what we are getting into, we have to back up again to the vital learnings we have skipped:
Every further riddle hinges on this issue; and the answer to this question is simple. But while we trudge toward solution, let us test if having to deduce the vital answer will stop your project in its tracks. This is the only existing clue:
Hmmm, you muse. What does this have to do with anything? Think about it for a moment. If the streaming system has made the form the owner of our "component" (root layer), then if we have included the csAcceptsControls flag in every interceding layer and "our component" is still not accepting controls, this is our clue to find out whether ownership by the form must be an (unfortunate) obligation imposed by the streaming system:
Realizing the magnitude of our conquest, tears of joy flood our desk... Now that we are up to speed with the vital train of thought, we perform our suggested ownership experiment:
We can't believe it. With our jaw on the floor, we blink incredulously at the product of so incredibly much futile work. Realizing the magnitude of our conquest, tears of joy flood our desk. Deservedly, we close shop and head to the tavern to celebrate, and to renew spirits diminished by far too much expended energy over what should be (and is advertised to be) a very simple issue. |
|
CHAPTER 9 — STILL FIXING csAcceptsControls |
|
The next morning as we open our project, the hair rises on the back of our neck as we recall again what we have done and what we went through to get here. Buckets of tears flow across our desk again as we reflect on our rather incredible success. We have indeed built the Titanic. And now, halfway across the sea and with too few life boats, we have to fix "just a small crease" with a slight headache. If we're still using Delphi 7 or earlier, in only a second or two our project opens... OOOOOOOOOOOOOOPS! ACCESS VIOLATION CITY! What the @^$$$@#%????? We have indeed built the Titanic. And now, halfway across the sea and with too few life boats, we have to fix "just a small crease" with a slight headache. I will explain straight-away what has just happened:
Swallow, and believe me: It's now time to think how long you can stand the cold. If you could answer these questions to now, you are floating in frigid waters, your teeth are clicking out of control, and your ship is already headed to the bottom, even as the work you have in building her is very many times the possible lifetime of her one and only partial sailing. On the other hand we know that if our tool makers fail even to recognize such critical problems, they simply never will send the life boats until after we have met the fate of their work. The next phase of your wee little "RAD" problem, *merely* (!!!!!) to accept controls at design time, equates to worse than doing something inside out — fixing the streaming system *from the outside*, while its design further obstructs you from doing so. Here, you will lack a pattern or further help from this article, because our own costs were so great in conquering this issue we cannot disclose how we did it. But what's the sense, in any case? If Borland cannot build a more comprehensive streaming system and provide necessary related capabilities, we can code or whistle all we want. On the one hand we know that some day the advertised privilege will only mean so much work will be for naught. On the other hand we know that if our tool makers fail even to recognize such critical problems, they simply never will send the life boats until after we have met the fate of their work. |
|
MINIMAL RELATED CAPABILITIES FOR "COMPOSITE PARENT CONTROLS" |
|
If management determines that streaming behavior shall remain based on form ownership (which I say was the wrong concept from the very beginning), here are a few things that successful "composite parent" control designs (obviously) will still need:
Are these issues optional "for the rest of us?" Only if our tools (and the work we can do with them) are to preclude competing with tools which can do what so many of us have already intended to do — only to be doomed to failure. |
|
• PRECEDING
|
|
|