root/trunk/txlib/txwind.c

Revision 14, 61.7 kB (checked in by jvw, 2 years ago)

HEX/ASCII (sector) editor control added

Line 
1//
2//                     TxWin, Textmode Windowing Library
3//
4//   Original code Copyright (c) 1995-2005 Fsys Software and Jan van Wijk
5//
6// ==========================================================================
7//
8// This file contains Original Code and/or Modifications of Original Code as
9// defined in and that are subject to the GNU Lesser General Public License.
10// You may not use this file except in compliance with the License.
11// BY USING THIS FILE YOU AGREE TO ALL TERMS AND CONDITIONS OF THE LICENSE.
12// A copy of the License is provided with the Original Code and Modifications,
13// and is also available at http://www.dfsee.com/txwin/lgpl.htm
14//
15// This library is free software; you can redistribute it and/or modify
16// it under the terms of the GNU Lesser General Public License as published
17// by the Free Software Foundation; either version 2.1 of the License,
18// or (at your option) any later version.
19//
20// This library is distributed in the hope that it will be useful,
21// but WITHOUT ANY WARRANTY; without even the implied warranty of
22// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
23// See the GNU Lesser General Public License for more details.
24//
25// You should have received a copy of the GNU Lesser General Public License
26// along with this library; (lgpl.htm) if not, write to the Free Software
27// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28//
29// Questions on TxWin licensing can be directed to: txwin@fsys.nl
30//
31// ==========================================================================
32//
33// TX Windowed text handling
34//
35// Author: J. van Wijk
36//
37// JvW  29-08-2001   Added dialog windows
38// JvW  20-08-2001   Added window movement and cleaned up
39// JvW  16-05-1999   Added window USHORT/ULONG query/set functions
40// JvW  25-07-1998   Split off drawing and default window proc
41// JvW  07-07-1998   Initial version
42
43#include <txlib.h>                              // public interface
44#include <txwpriv.h>                            // private window interface
45
46
47
48// Recursive set position and size (relative) for child windows
49static void txwSetChildPos
50(
51   TXWHANDLE           hwnd,                    // IN    window handle or 0
52   TXRECT             *move                     // IN    relative move/size
53);
54
55static BYTE  StaticVbuf[512];                   // possible VIO bug avoider
56       BYTE *txVbuf = StaticVbuf;
57
58/*****************************************************************************/
59// Initialize TX window manager and create the desktop window
60/*****************************************************************************/
61TXWHANDLE txwInitializeDesktop                  // RET   Desktop handle
62(
63   TXWINDOW           *custom,                  // IN    custom desktop style
64   TXWINPROC           winproc                  // IN    custom desktop proc
65)
66{
67   TXWHANDLE           desktop;
68   TXWINDOW            deskwin;
69   TXWINDOW           *window  = custom;
70   char               *csname;                  // color scheme name
71   int                 attempt = 0;
72
73   ENTER();
74
75   #ifndef WIN32                                // ALWAYS check on Windows :-)
76   if (TxaExeSwitchSet('W'))                    // or explicitly specified
77   #endif
78   {
79      txwa->rsmaxlines = TxaExeSwitchNum( 'W', NULL, 0);
80      if (txwa->rsmaxlines == 0)                // -W or -W:0
81      {
82         //- slightly smaller than screen (on WIN, fixed to 38 for others :-)
83         txwa->rsmaxlines = txwScrVisibleLines();
84      }
85   }
86   if (TxaExeSwitchSet(TXA_O_SCHEME))           // WIN color scheme
87   {
88      csname = TxaExeSwitchStr( TXA_O_SCHEME, "", "");
89      txwColorScheme( csname[0], NULL);
90   }
91   if (TxaExeSwitchSet(TXA_O_STYLE))            // WIN linestyle
92   {
93      txwcs->linestyle = TxaExeSwitchNum( TXA_O_STYLE, "", 0);
94   }
95
96   while ((txwa->desktop == NULL) &&            // desktop not present yet
97          (attempt++     <  2   )  )            // and no more than 2 tries
98   {
99      desktop = TXHWND_NULL;
100
101      txwa->screen.right  = TxScreenCols() -1;
102      txwa->screen.bottom = TxScreenRows() -1;
103      txwa->cursorRow     = TxCursorRow();
104      txwa->cursorCol     = TxCursorCol();
105      txwa->autoid        = 0;
106
107      if (window == NULL)                       // create default desktop style
108      {
109         window = &deskwin;
110         txwSetupWindowData( 0, 0,              // upper left corner
111                             TxScreenRows(),    // vertical size
112                             TxScreenCols(),    // horizontal size
113                             TXWS_CANVAS, 0,    // style and help
114                             ' ', ' ',
115                             cSchemeColor,    cSchemeColor,
116                             cDskTitleStand,  cDskTitleFocus,
117                             cDskFooterStand, cDskFooterFocus,
118                             "",  "",
119                             window);
120      }
121      desktop = txwCreateWindow( 0,             // parent window
122                                 TXW_FRAME,     // class of this window
123                                 0,             // owner window
124                                 0,             // insert after ...
125                                 window,        // window setup data
126                                 winproc);      // window procedure
127
128
129      txwa->focus         = (TXWINBASE *) desktop;
130      txwSendMsg( desktop, TXWM_SETFOCUS, TRUE, 0);
131
132      txwInitStandardDialogs();                 // needed for messageboxes etc
133
134      txwSetAccelerator( TXWACCEL_SYSTEM, TXk_F1,  TXWACCEL_MHELP);
135
136      #if   defined (DEV32)
137      {
138         COUNTRYCODE     ccode = {0};           // 0 = default codepage
139         COUNTRYINFO     cinfo;
140         ULONG           csize;                 // returned size in cinfo
141
142         DosGetCtryInfo( sizeof(cinfo), &ccode, &cinfo, &csize);
143
144         txwa->codepage = (ULONG) cinfo.codepage;
145      }
146      #elif defined (LINUX)
147         txwa->codepage = 0;                    // assume no 437 for now
148      #else
149         //- codepage / 437 compatibility to be refined for DOS/WIN etc
150      #endif
151
152      if (attempt < 2)                          // first resize ?
153      {
154         if ((TxaExeSwitch('b') == FALSE) && (txwa->rsmaxlines != 0) &&
155             (TxScreenRows()    > (USHORT)   (txwa->rsmaxlines)    )  )
156         {
157            if (TxConfirm( TXWD_HELPSMSG + TXWD_WINSCREEN,
158               "The number of lines in your text window is quite large, and\n"
159               "might need vertical scrollbars when running in a GUI window.\n"
160               "This does NOT work very well with this programs windowing!\n\n"
161               "If you are seeing vertical scrollbars you should resize, you\n"
162               "can do that now, or use the 'mode cols,lines' command later.\n\n"
163               "(Use the Arrow- and <Enter> keys, mouse is not supported)\n\n"
164               "Do you want to resize the window to %hu lines now ? [Y/N] : ",
165                txwa->rsmaxlines))
166            {
167               TXTM       command;
168               short      delta = TxScreenRows(); // current nr of rows
169
170               sprintf( command, "mode %hu,%hu", TxScreenCols(), txwa->rsmaxlines);
171
172               TxExternalCommand( command);     // set mode, will cls too
173               txwTerminateDesktop();           // quit current desktop
174
175               delta -= TxScreenRows();
176               window->border.bottom -= delta;  // recalculate sizes
177               window->client.bottom -= delta;
178            }
179         }
180      }
181      else                                      // resize failed!
182      {
183         TxPrint( "Screen resize failed, 'mode' command missing from PATH ?\n");
184      }
185   }
186   if (desktop != NULL)
187   {
188      TxInputDesktopInit();                     // start keyboard reader
189   }
190   RETURN( desktop);
191}                                               // end 'txwInitializeDesktop'
192/*---------------------------------------------------------------------------*/
193
194
195/*****************************************************************************/
196// Terminate TX window manager including the desktop and other windows
197/*****************************************************************************/
198void txwTerminateDesktop                        // RET   Desktop handle
199(
200   void
201)
202{
203   ENTER();
204
205   txwTermStandardDialogs();                    // messageboxes etc
206
207   txwa->sbview  = NULL;                        // SBVIEW for debug status
208   while (txwa->last != NULL)                   // destroy all windows
209   {
210      txwDestroyWindow((TXWHANDLE) txwa->last);
211   }
212   txwa->desktop = NULL;
213   TxFreeMem( txwa->acceltable);
214
215   TxSetCursorPos( txwa->cursorRow, txwa->cursorCol);
216   TxSetCursorStyle( TRUE, txwa->insert);
217
218   VRETURN();
219}                                               // end 'txwTerminateDesktop'
220/*---------------------------------------------------------------------------*/
221
222
223/*****************************************************************************/
224// Determine if specified handle is an existing window
225/*****************************************************************************/
226BOOL txwIsWindow
227(
228   TXWHANDLE           hwnd                     // IN    window handle
229)
230{
231   return (txwValidateHandle( hwnd, NULL) != NULL);
232}                                               // end 'txwIsWindow'
233/*---------------------------------------------------------------------------*/
234
235
236/*****************************************************************************/
237// Query window-handles related to the specified one
238/*****************************************************************************/
239TXWHANDLE txwQueryWindow
240(
241   TXWHANDLE           hwnd,                    // IN    window handle
242   ULONG               relation                 // IN    window relation
243)
244{
245   TXWINBASE          *wnd;
246
247   ENTER();
248
249   if ((wnd = txwValidateHandle( hwnd, NULL)) != NULL)
250   {
251      TRCLAS( "Query", hwnd);
252      switch (relation)
253      {
254         case TXQW_NEXT   : wnd = wnd->next;      break;
255         case TXQW_PREV   : wnd = wnd->prev;      break;
256         case TXQW_TOP    : wnd = txwa->last;     break;
257         case TXQW_BOTTOM : wnd = txwa->desktop;  break;
258         case TXQW_OWNER  : wnd = wnd->owner;     break;
259         case TXQW_PARENT : wnd = wnd->parent;    break;
260         default:           wnd = TXHWND_NULL;    break;
261      }
262   }
263   else
264   {
265      wnd = TXHWND_NULL;
266   }
267   RETURN ((TXWHANDLE) wnd);
268}                                               // end 'txwQueryWindow'
269/*---------------------------------------------------------------------------*/
270
271
272/*****************************************************************************/
273// Get a pointer to the TXWINDOW data from window-handle
274/*****************************************************************************/
275TXWINDOW *txwWindowData                         // RET   valid window pointer
276(
277   TXWHANDLE           hwnd                     // IN    window handle
278)
279{
280   TXWINDOW           *win;
281
282   txwValidateHandle( hwnd, &win);
283   return( win);
284}                                               // end 'txwWindowData'
285/*---------------------------------------------------------------------------*/
286
287/*****************************************************************************/
288// Initialize a setup window structure for Create
289/*****************************************************************************/
290void txwSetupWindowData
291(
292   short               row,                     // IN    top-left row (border)
293   short               col,                     // IN    top-left column
294   short               rows,                    // IN    nr of rows incl border
295   short               cols,                    // IN    nr of cols incl border
296   ULONG               style,                   // IN    window & border style
297   ULONG               helpid,                  // IN    compound helpid
298   BYTE                winchar,                 // IN    default window char
299   BYTE                borchar,                 // IN    default border char
300   BYTE                wincolor,                // IN    default window color
301   BYTE                borcolor,                // IN    default border color
302   BYTE                titlecolor,              // IN    default title color
303   BYTE                titlefocus,              // IN    default t-focus color
304   BYTE                footercolor,             // IN    default footer color
305   BYTE                footerfocus,             // IN    default f-focus color
306   char               *title,                   // IN    title text string
307   char               *footertxt,               // IN    footer text string
308   TXWINDOW           *win                      // OUT   window structure
309)
310{
311   ENTER();
312
313   TRACES(( "row:%hd  col:%hd  rows:%hd  cols:%hd\n", row, col, rows, cols));
314   TRACES(( "style:%8.8lx  helpid:%lu  title:'%s'\n", style, helpid, title));
315
316   memset( win, 0, sizeof(TXWINDOW));           // all unitialized fields zero
317
318   win->style          = style;
319   win->helpid         = helpid;
320   win->clientclear.ch = winchar;
321   win->clientclear.at = wincolor;
322   win->borderclear.ch = borchar;
323   win->borderclear.at = borcolor;
324   win->titlecolor     = titlecolor;
325   win->titlefocus     = titlefocus;
326   win->title          = title;
327   win->footercolor    = footercolor;
328   win->footerfocus    = footerfocus;
329   win->footer         = footertxt;
330
331   win->border.top     = row;
332   win->border.left    = col;
333   win->border.bottom  = row + rows -1;
334   win->border.right   = col + cols -1;
335
336   win->client = win->border;                   // start with same size
337
338   if (style & TXWS_TITLEBORDER) win->client.top++;
339   if (style & TXWS_FOOTRBORDER) win->client.bottom--;
340   if (style & TXWS_SIDEBORDERS)
341   {
342      win->client.left++;
343      win->client.right--;
344   }
345   TRHEXS(200,win,sizeof(TXWINDOW),"TXWINDOW Setup");
346
347   TRECTA("border", (&win->border));
348   TRECTA("client", (&win->client));
349   VRETURN();
350}                                               // end 'txwSetupWindowData'
351/*---------------------------------------------------------------------------*/
352
353#if defined (NEVER)
354/*****************************************************************************/
355// Initialize the client and border rectangle structures in a Window
356/*****************************************************************************/
357void txwSetupWindowRect
358(
359   short               row,                     // IN    top-left row (border)
360   short               col,                     // IN    top-left column
361   short               rows,                    // IN    nr of rows incl border
362   short               cols,                    // IN    nr of cols incl border
363   ULONG               style,                   // IN    window & border style
364   TXWINDOW           *win                      // INOUT window structure
365)
366{
367   ENTER();
368   TRACES(( "row:%hd  col:%hd  rows:%hd  cols:%hd\n", row, col, rows, cols));
369
370   win->style          = style;
371   win->border.top     = row;
372   win->border.left    = col;
373   win->border.bottom  = row + rows -1;
374   win->border.right   = col + cols -1;
375
376   win->client = win->border;                   // start with same size
377
378   if (style & TXWS_TITLEBORDER) win->client.top++;
379   if (style & TXWS_FOOTRBORDER) win->client.bottom--;
380   if (style & TXWS_SIDEBORDERS)
381   {
382      win->client.left++;
383      win->client.right--;
384   }
385   TRHEXS(200,win,sizeof(TXWINDOW),"TXWINDOW Setup");
386
387   TRECTA("border", (&win->border));
388   TRECTA("client", (&win->client));
389   VRETURN();
390}                                               // end 'txwSetupWindowRect'
391/*---------------------------------------------------------------------------*/
392#endif
393
394
395/*****************************************************************************/
396// Create a new base window element and initialize its window-data
397/*****************************************************************************/
398TXWHANDLE txwCreateWindow
399(
400   TXWHANDLE           parent,                  // IN    parent window
401   TXWCLASS            class,                   // IN    class of this window
402   TXWHANDLE           owner,                   // IN    owner window
403   TXWHANDLE           after,                   // IN    insert after ...
404   TXWINDOW           *setup,                   // IN    window setup data
405   TXWINPROC           winproc                  // IN    window procedure
406)
407{
408   TXWINBASE          *aft = txwValidateHandle( after, NULL);
409   TXWINBASE          *wnd = NULL;
410   TXWINDOW           *win = NULL;
411
412   ENTER();
413   TRHEXS(200,setup,sizeof(TXWINDOW),"TXWINDOW Create");
414
415   if ((win = TxAlloc(1, sizeof(TXWINDOW)))  != NULL)
416   {
417      if ((wnd = TxAlloc(1, sizeof(TXWINBASE))) != NULL)
418      {
419         TXWINBASE    *vwnd;                    // validated winbase
420         TXWINDOW     *vwin;                    // validated window
421
422         if ((vwnd = txwValidateHandle( owner, NULL)) != NULL)
423         {
424            wnd->owner     = vwnd;
425         }
426         else
427         {
428            wnd->owner     = txwa->desktop;
429         }
430         wnd->window       = win;
431         wnd->winproc      = winproc;
432         wnd->cursor.x     = 0;
433         wnd->cursor.y     = 0;
434         wnd->us[TXQWS_ID] = (txwa->autoid)--;  // assign next automatic id
435         wnd->oldFocus     = (TXWHANDLE) txwa->focus;
436         wnd->oldFooter    = setup->footer;
437
438         *win = *setup;                         // (shallow) copy setup info
439         win->class        = class;
440
441         switch (class)
442         {
443            case TXW_SBVIEW:
444               win->sb.status = TxAlloc( 1, TXMAXLN);
445
446               if (TxaExeSwitchSet(TXA_O_COLOR)) // SB color scheme
447               {
448                  win->sb.altcol = TxaExeSwitchNum( TXA_O_COLOR, "", 1);
449               }
450               else                             // use SB colors for scheme
451               {
452                  win->sb.altcol = txwcs->sbcolors;
453               }
454               txwa->sbview = wnd;              // SBVIEW for debug status
455               break;
456
457            case TXW_ENTRYFIELD:
458            case TXW_HEXEDIT:
459               wnd->curvisible = TRUE;
460               break;
461
462            case TXW_BUTTON:
463               switch (win->style & TXBS_PRIMARYSTYLES)
464               {
465                  case TXBS_RADIOBUTTON:
466                  case TXBS_AUTORADIO:
467                  case TXBS_CHECKBOX:
468                  case TXBS_AUTOCHECK:
469                     wnd->curvisible = TRUE;
470                     wnd->cursor.x   = 1;
471                     wnd->cursor.y   = (win->client.bottom - win->client.top) /2;
472                     break;
473
474                  default:
475                     wnd->curvisible = FALSE;
476                     break;
477               }
478               break;
479
480            default:
481               wnd->curvisible = FALSE;
482               break;
483         }
484
485         if ((vwnd = txwValidateHandle( parent, &vwin)) != NULL)
486         {
487            wnd->parent = vwnd;
488                                                // make position absolute
489            win->client.top    += vwin->client.top;
490            win->client.bottom += vwin->client.top;
491            win->border.top    += vwin->client.top;
492            win->border.bottom += vwin->client.top;
493            win->client.left   += vwin->client.left;
494            win->client.right  += vwin->client.left;
495            win->border.left   += vwin->client.left;
496            win->border.right  += vwin->client.left;
497         }
498         else
499         {
500            wnd->parent = txwa->desktop;
501         }
502         wnd->restore = win->border;            // initial restore size/pos
503
504         if (win->style & TXWS_SAVEBITS)
505         {
506            txwSaveWindowContent( wnd);
507         }
508
509         if (aft == NULL)                       // no position specified
510         {
511            aft = txwa->last;
512         }
513         TRACES(( "new window after: %8.8lx, txwa: %8.8lx\n", aft, txwa));
514         if (aft == NULL)                       // first window (desktop)
515         {
516            txwa->last    = wnd;
517            txwa->desktop = wnd;
518         }
519         else                                   // attach after ...
520         {
521            wnd->next     = aft->next;          // new forward link
522            if (aft->next != NULL)
523            {
524               aft->next->prev = wnd;           // rerouted backward link
525            }
526            aft->next     = wnd;                // rerouted forward link
527            wnd->prev     = aft;                // new backward link
528            if (txwa->last == aft)              // new last element ?
529            {
530               txwa->last = wnd;
531            }
532         }
533         txwa->windows++;                       // update window count
534         TRCLAS("Creating", (TXWHANDLE) wnd);
535
536         if (winproc != NULL)                   // dialogs created without ...
537         {
538            //- to be refined, pass cData pointer as param
539            //- cData to be added as param for CreateWindow
540            txwPostMsg( (TXWHANDLE) wnd, TXWM_CREATE, 0, 0);
541         }
542
543         TRACES(("size of TXWINBASE : %d bytes\n", sizeof(TXWINBASE)));
544         TRACES(("size of TXWINDOW  : %d bytes\n", sizeof(TXWINDOW)));
545         TRACES(("size of TXRECT    : %d bytes\n", sizeof(TXRECT)));
546         TRACES(("border: top:%hd left:%hd bot:%hd right:%hd\n", win->border.top,
547                           win->border.left, win->border.bottom, win->border.right));
548         TRACES(("client: top:%hd left:%hd bot:%hd right:%hd\n", win->client.top,
549                           win->client.left, win->client.bottom, win->client.right));
550
551         TRSTYL("window", (TXWHANDLE) wnd);
552         TRECTA("border", (&win->border));
553         TRECTA("client", (&win->client));
554         TRACES(("parent:%8.8lx after:%8.8lx helpid:%8.8lx=%lu  #windows: %s%ld%s\n",
555                  wnd->parent, wnd->prev,
556                  win->helpid, win->helpid, CBY, txwa->windows, CNN));
557      }
558      else
559      {
560         TxFreeMem( win);
561      }
562   }
563   RETURN( (TXWHANDLE) wnd);
564}                                               // end 'txwCreateWindow'
565/*---------------------------------------------------------------------------*/
566
567/*****************************************************************************/
568// Destroy a base window element and remove it from the list
569/*****************************************************************************/
570ULONG txwDestroyWindow                          // RET   result
571(
572   TXWHANDLE           hwnd                     // IN    window handle
573)
574{
575   ULONG               rc  = NO_ERROR;
576   TXWINBASE          *wnd;
577   TXWINDOW           *win;
578
579   ENTER();
580
581   if (((wnd  = txwValidateHandle( hwnd, &win)) != NULL) && // valid, desktop
582       ((wnd != txwa->desktop) ||  (wnd->next   == NULL)) ) // only when last
583   {
584      TXWHENUM         henum;
585      TXWHANDLE        child;
586
587      if ((win->class == TXW_SBVIEW) && (txwa->sbview == wnd))
588      {
589         txwa->sbview  = NULL;                  // SBVIEW for debug status
590         TxFreeMem( win->sb.status);            // status string buffer
591      }
592
593      if (hwnd == txwa->modality)               // just in case ...
594      {
595         txwa->modality = TXHWND_DESKTOP;       // reset to desktop
596      }
597      if (txwIsDescendant((TXWHANDLE) txwa->focus, hwnd)) // we had focus
598      {
599         if (txwSetFocus(wnd->oldFocus) != NO_ERROR)
600         {
601            txwSetFocus( txwFindPrevFocus( hwnd, FALSE));
602         }
603      }
604
605      TRACES(("Destroy children for window:%8.8lx\n", hwnd));
606      if ((henum = txwBeginEnumWindows( hwnd)) != 0)
607      {
608         while ((child = txwGetNextWindow( henum)) != 0)
609         {
610            txwDestroyWindow( child);           // recurse over children
611         }
612         txwEndEnumWindows( henum);
613      }
614
615      TRACES(("wnd:%8.8lx win:%8.8lx id:%4.4hu\n", wnd, win, wnd->us[TXQWS_ID]));
616      TRCLAS( "Destroy", hwnd);
617
618      txwSendMsg( hwnd, TXWM_DESTROY, 0,  0);   // signal window-procedure
619      txwDestroyMessages( hwnd);                // destroy pending messages
620                                                // in the MsgQueue
621      if (wnd->prev == NULL)
622      {
623         txwa->desktop   = wnd->next;           // destroying current desktop!
624      }
625      else
626      {
627         wnd->prev->next = wnd->next;
628      }
629      if (wnd->next == NULL)
630      {
631         txwa->last = wnd->prev;
632      }
633      else
634      {
635         wnd->next->prev = wnd->prev;
636      }
637
638      if (wnd->oldContent != NULL)              // something to restore ?
639      {
640         txwRestoreWindowContent( wnd, NULL, NULL);
641         TxFreeMem( wnd->oldContent);           // saved image
642      }
643      TxFreeMem( win);                          // window data
644      TxFreeMem( wnd->acceltable);              // accelerator table
645      TxFreeMem( wnd);
646
647      txwa->windows--;                          // update window count
648
649      TRACES(("Total number of windows remaining in the list is now: %s%ld%s\n",
650               (txwa->windows > 0) ? CBG : CBR, txwa->windows, CNN));
651   }
652   else
653   {
654      rc = TX_INVALID_HANDLE;
655   }
656   RETURN( rc);
657}                                               // end 'txwDestroyWindow'
658/*---------------------------------------------------------------------------*/
659
660
661/*****************************************************************************/
662// Set focus to specified window, notify old and new focus-windows
663/*****************************************************************************/
664ULONG txwSetFocus
665(
666   TXWHANDLE           hwnd                     // IN    destination window
667)
668{
669   ULONG               rc  = NO_ERROR;
670   TXWINBASE          *wnd;                     // window gaining focus
671   TXWINDOW           *win;
672   TXWINBASE          *losingFocus;             // window losing focus
673
674   ENTER();
675
676   if ((wnd = txwValidateHandle( hwnd, &win)) != NULL)
677   {
678      TRCLAS( "Current win", (TXWHANDLE) txwa->focus);
679      TRCLAS( "SetFocus to", hwnd);
680      if (txwa->focus != wnd)                   // no focus already ?
681      {
682         if (txwIsDescendant( hwnd, txwa->modality)) // and inside modality
683         {
684            losingFocus   = txwa->focus;
685            txwa->focus   = wnd;
686
687            TRACES(("Focus from %8.8lx to %8.8lx\n", losingFocus, wnd));
688
689            txwSendMsg((TXWHANDLE) losingFocus, TXWM_SETFOCUS, FALSE, 0);
690
691            txwSendMsg((TXWHANDLE) txwa->focus, TXWM_SETFOCUS, TRUE,  0);
692
693            txwSetCursorPos( hwnd, wnd->cursor.y, wnd->cursor.x);
694         }
695         else
696         {
697            rc = TX_FAILED;
698            TRACES(("Focus NOT changed, target NOT in current MODAL area\n"));
699         }
700      }
701      else
702      {
703         TRACES(("Focus NOT changed, was already at target window\n"));
704         //- Send FOCUS message, to trigger 'on-focus' behaviour (mouse click)
705         txwSendMsg((TXWHANDLE) txwa->focus, TXWM_SETFOCUS, TRUE,  0);
706      }
707   }
708   else
709   {
710      rc = TX_INVALID_HANDLE;
711   }
712   RETURN( rc);
713}                                               // end 'txwSetFocus'
714/*---------------------------------------------------------------------------*/
715
716/*****************************************************************************/
717// Enable or disable specified window
718/*****************************************************************************/
719ULONG txwEnableWindow
720(
721   TXWHANDLE           hwnd,                    // IN    destination window
722   BOOL                enable                   // IN    enable flag
723)
724{
725   ULONG               rc  = NO_ERROR;
726   TXWINBASE          *wnd;
727   TXWINDOW           *win;
728
729   ENTER();
730
731   if ((wnd = txwValidateHandle( hwnd, &win)) != NULL)
732   {
733      TRACES(("enable: %lu <= %lu\n", enable, !(win->style & TXWS_DISABLED)));
734      if (enable == (BOOL) (win->style & TXWS_DISABLED)) // status change ?
735      {
736         if (enable)
737         {
738            win->style &= ~TXWS_DISABLED;       // not disabled
739         }
740         else
741         {
742            win->style |=  TXWS_DISABLED;
743         }
744         txwSendMsg( hwnd, TXWM_ENABLE, enable