|
|||||||
Uncommon Knowledge - Window_Common% in Paint - Part IApologies in advance to those of you who are not yet using V3.0 - some of this article will not be relevant, but hopefully there should be something here of use to any version. I for one was especially sad to see the recent end of the Uncommon Knowledge series, (mainly because it took up a few pages per issue and saved me having to write any more product reviews), but recent events have convinced me to resurrect it one last time, with one small change - this time around, I'd like to consider the uses of the Window_Common% block in PAINT. The 2.12/3.0 upgrade seminars which Sprezzatura recently ran provoked a host of wide-ranging questions, but a few of them surprised me. One delegate, impressed by the ability to sort the options in a menu wondered about the easiest way to achieve the same effect with window softkeys; another (obviously employed by an impecunious Government department) lamented the fact that he didn't have a mouse and therefore saw only limited advantage to the new Paint processor. And, coincidentally, my own current task of rewriting the much loved Skeleton program from Utility Disk 1 meant that account had to be taken of the new ability in Paint to select multiple prompts simultaneously. (Why a new routine? Well, Andrew's old version of Skeleton worked, but elegantly and efficiently and from within Paint? - NOT !) I'd always assumed that everyone knew that the Window_Common% area was used extensively in Paint, but a straw poll quickly convinced me otherwise. This is a great shame because all manner of clever tricks can be carried out by changing common variables dynamically during a Paint session. Any subroutine which is called from Paint needs only a simple $Insert statement (just as in a window commuter program) to access them. The subroutines themselves can be called by a macro keystroke, in which case the subroutine must check to see whether it has actually been called from Paint (see RevMedia passim for rigorous methods including checks on the number of common variables used), but be aware that a simple If @Tutor = 'PAINT' Then... will normally suffice! Perhaps the most elegant solution though, is simply to create a new menu (to be stored in SYSMENUS) which is called directly from the PAINT_MAIN menu. This allows a series of utilities to be available across your entire development environment. (Make sure in this case that the object code for your routines is copied to SYSOBJ.) On then to the common area itself. As stated previously, most variables are available in an identical format to that of the window processor, but there are some significant changes. The most obvious is that the WC_W% dimensioned array is not used in Paint. The number of prompts in the window can go up and down during a Paint session (WC_W_Cnt% is still used as normal), so a dimensioned array is not appropriate. A consequence of this is that WC_Si% is not available either. Another area where functionality is largely absent is in the use of the flag type variables e.g. WC_Valid% and WC_Display_Action%. In the main, these have little or no effect on Paint processing. Students of Uncommon Knowledge will also be relieved to learn that WC_Reset% is not widely used, in stark contrast to its illogical overuse everywhere in the window processor. And so finally to some source code covering the questions raised above by way of example. Admittedly, softkeys could be sorted by an ordinary window process from within the SOFTKEYS window (the technique used by menus), but this would mean chopping up @Record, sorting, and then reassembling it. Direct access to the WC_Soft_Data% variable makes life much simpler. Witness the following, noting the direct use of the select type 'S' popup. Note also that there is no need to reorder the WC_Soft_Keys% array of scancodes - Paint takes care of this automatically! 0001 Subroutine SkSort 0002 Declare Function Pop.Up 0003 Declare Subroutine Msg 0004 If @Tutor = 'PAINT' Then 0005 $Insert SysInclude,Window_Common% 0006 If WC_Soft_Data% Then 0007 Format = 1:5:C::Key\2:30:L::Function\3:4:C::Code\4:20:L::Command' Select = 'S':@Fm:1 Title = '|Order softkeys as required|' WC_Soft_Data% = Pop.Up(1,2,'', WC_Soft_Data%, Format, 'R', Select, Title, '', '', '', '') End Else Msg('|No softkeys defined yet !|') End End Return' The next issue is not quite so clear cut in that there is no definitive answer to the problem in the program. If you don't have a mouse then obviously you're not going to get the full benefit of Paint in V3.x. However, there are a few techniques which you can use to aid in resizing/moving which are illustrated in the example below. The program shrinks the window by 2 rows and 4 columns from the left every time it is called. It is a simple matter using the same variables to move it as well. 0001 Declare Subroutine Video.RW 0002 If @Tutor = 'PAINT' Then 0003 $Insert SysInclude,Window_Common% 0004 WC_WindXY%<3> = WC_WindXY%<3> - 4 0005 WC_WindXY%<4> = WC_WindXY%<4> - 2 0006 WC_WRX% -= 4 0007 WC_WRY% -= 2 0008 WC_XMax% -= 4 0009 WC_YMax% -= 2 0010 VideoImage = WC_VPrev%[ 26, @CrtHigh * @CrtWide * 2] 0011 Video.RW( 0, 0, @CrtWide-1, @CrtHigh- 1, 'W', VideoImage) 0012 @Data = \00640064\ ; * {CTRL-F7} x 2 0013 End The last few lines bear further explanation - since the window is being made smaller, old border shadows will not be cleared down. The use of Video.RW to redisplay the pre- paint image ensures that the display is not corrupted. The first 25 characters of WC_VPrev% are ignored because these contain information specific to VSpace. Since we are not referencing VSpace ourselves, and since Paint does not recognise flags such as WC_Reset%, the last action of the program is to stuff a few Ctrl-F7's into the keyboard buffer - the window thinks it has been resized normally, and redisplays our changes! Finally, a brief discussion of the new usage in version 3.x is in order. Since there can now be more than one prompt selected at a time, it is not sufficient to check WC_Wi% to find out which are active. True, if only one prompt is selected then WC_Wi% will contain its prompt number, but on multiple selects (and these can include labels too, remember) WC_Wi% is set to one greater than the number of prompts in the window (i.e. to WC_W_Cnt% + 1).Highlighting details are held instead in a field mark delimited array in the WC_REDISPLAY_LIST% variable where each field has two values. The first value is a code representing the area which is highlighted. These codes are : 1 For a prompt label 2 For a prompt entry 3 For a display label The second value is the offset into the relevant order table. E.g. 10 is the 10th prompt, while 2 is the second label. The fields are stored in the order in which they were highlighted. The prompt details can then be picked up from the WC_PROMPTS% variable, which has its usual two dimensional dynamic array structure. The following code segment illustrates the parsing techniques involved. 0001 PromptNumbers = '' 0002 If WC_Redisplay_List% Then 0003 NumberInList = Count(WC_Redisplay_List%, @Fm) + 1 0004 For I = 1 To NumberInList 0005 If WC_Redisplay_List%<I,1> < 3 Then 0006 * 1 or 2 :- part of a prompt. 0007 PromptNumber = WC_Redisplay_List%<I,2> 0008 * Both parts might be highlighted, so check before append. 0009 Locate PromptNumber In PromptNumbers Using @Fm Setting Pos Else 0010 PromptNumbers<-1> = PromptNumber 0011 End 0012 End 0013 If PromptNumbers Else 0014 Msg('Only Labels are selected !') 0015 End 0016 Next 0017 End I could go on like this all day, but space is limited. The potential applications, however, are limited only by your imaginations, and if anyone out there comes up with their own useful technique or utility we'd be only too delighted if you shared it with us. (We're already half way through volume 4 now, and Utility Disk # 5 is already on our minds.) (Volume 4, Issue 7, Pages 9-12) |
|||||||
| |||||||