/[dtapublic]/projs/ets/trunk/src/c_tk_base_7_5_w_mods/tkwinscrlbr.c
ViewVC logotype

Diff of /projs/ets/trunk/src/c_tk_base_7_5_w_mods/tkwinscrlbr.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

projs/trunk/shared_source/c_tk_base_7_5_w_mods/tkwinscrlbr.c revision 69 by dashley, Sat Nov 5 10:54:17 2016 UTC projs/dtats/trunk/shared_source/c_tk_base_7_5_w_mods/tkwinscrlbr.c revision 98 by dashley, Sun Dec 18 00:57:31 2016 UTC
# Line 1  Line 1 
1  /* $Header$ */  /* $Header$ */
2    
3  /*  /*
4   * tkWinScrollbar.c --   * tkWinScrollbar.c --
5   *   *
6   *      This file implements the Windows specific portion of the scrollbar   *      This file implements the Windows specific portion of the scrollbar
7   *      widget.   *      widget.
8   *   *
9   * Copyright (c) 1996 by Sun Microsystems, Inc.   * Copyright (c) 1996 by Sun Microsystems, Inc.
10   *   *
11   * See the file "license.terms" for information on usage and redistribution   * See the file "license.terms" for information on usage and redistribution
12   * of this file, and for a DISCLAIMER OF ALL WARRANTIES.   * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
13   *   *
14   * RCS: @(#) $Id: tkwinscrlbr.c,v 1.1.1.1 2001/06/13 05:14:22 dtashley Exp $   * RCS: @(#) $Id: tkwinscrlbr.c,v 1.1.1.1 2001/06/13 05:14:22 dtashley Exp $
15   */   */
16    
17  #include "tkWinInt.h"  #include "tkWinInt.h"
18  #include "tkScrollbar.h"  #include "tkScrollbar.h"
19    
20    
21  /*  /*
22   * The following constant is used to specify the maximum scroll position.   * The following constant is used to specify the maximum scroll position.
23   * This value is limited by the Win32 API to either 16-bits or 32-bits,   * This value is limited by the Win32 API to either 16-bits or 32-bits,
24   * depending on the context.  For now we'll just use a value small   * depending on the context.  For now we'll just use a value small
25   * enough to fit in 16-bits, but which gives us 4-digits of precision.   * enough to fit in 16-bits, but which gives us 4-digits of precision.
26   */   */
27    
28  #define MAX_SCROLL 10000  #define MAX_SCROLL 10000
29    
30  /*  /*
31   * Declaration of Windows specific scrollbar structure.   * Declaration of Windows specific scrollbar structure.
32   */   */
33    
34  typedef struct WinScrollbar {  typedef struct WinScrollbar {
35      TkScrollbar info;           /* Generic scrollbar info. */      TkScrollbar info;           /* Generic scrollbar info. */
36      WNDPROC oldProc;            /* Old window procedure. */      WNDPROC oldProc;            /* Old window procedure. */
37      int lastVertical;           /* 1 if was vertical at last refresh. */      int lastVertical;           /* 1 if was vertical at last refresh. */
38      HWND hwnd;                  /* Current window handle. */      HWND hwnd;                  /* Current window handle. */
39      int winFlags;               /* Various flags; see below. */      int winFlags;               /* Various flags; see below. */
40  } WinScrollbar;  } WinScrollbar;
41    
42  /*  /*
43   * Flag bits for native scrollbars:   * Flag bits for native scrollbars:
44   *   *
45   * IN_MODAL_LOOP:               Non-zero means this scrollbar is in the middle   * IN_MODAL_LOOP:               Non-zero means this scrollbar is in the middle
46   *                              of a modal loop.   *                              of a modal loop.
47   * ALREADY_DEAD:                Non-zero means this scrollbar has been   * ALREADY_DEAD:                Non-zero means this scrollbar has been
48   *                              destroyed, but has not been cleaned up.   *                              destroyed, but has not been cleaned up.
49   */   */
50    
51  #define IN_MODAL_LOOP   1  #define IN_MODAL_LOOP   1
52  #define ALREADY_DEAD    2  #define ALREADY_DEAD    2
53    
54  /*  /*
55   * Cached system metrics used to determine scrollbar geometry.   * Cached system metrics used to determine scrollbar geometry.
56   */   */
57    
58  static int initialized = 0;  static int initialized = 0;
59  static int hArrowWidth, hThumb; /* Horizontal control metrics. */  static int hArrowWidth, hThumb; /* Horizontal control metrics. */
60  static int vArrowWidth, vArrowHeight, vThumb; /* Vertical control metrics. */  static int vArrowWidth, vArrowHeight, vThumb; /* Vertical control metrics. */
61    
62  TCL_DECLARE_MUTEX(winScrlbrMutex)  TCL_DECLARE_MUTEX(winScrlbrMutex)
63    
64  /*  /*
65   * This variable holds the default width for a scrollbar in string   * This variable holds the default width for a scrollbar in string
66   * form for use in a Tk_ConfigSpec.   * form for use in a Tk_ConfigSpec.
67   */   */
68    
69  static char defWidth[TCL_INTEGER_SPACE];  static char defWidth[TCL_INTEGER_SPACE];
70    
71  /*  /*
72   * Declarations for functions defined in this file.   * Declarations for functions defined in this file.
73   */   */
74    
75  static Window           CreateProc _ANSI_ARGS_((Tk_Window tkwin,  static Window           CreateProc _ANSI_ARGS_((Tk_Window tkwin,
76                              Window parent, ClientData instanceData));                              Window parent, ClientData instanceData));
77  static void             ModalLoopProc _ANSI_ARGS_((Tk_Window tkwin,  static void             ModalLoopProc _ANSI_ARGS_((Tk_Window tkwin,
78                              XEvent *eventPtr));                              XEvent *eventPtr));
79  static int              ScrollbarBindProc _ANSI_ARGS_((ClientData clientData,  static int              ScrollbarBindProc _ANSI_ARGS_((ClientData clientData,
80                              Tcl_Interp *interp, XEvent *eventPtr,                              Tcl_Interp *interp, XEvent *eventPtr,
81                              Tk_Window tkwin, KeySym keySym));                              Tk_Window tkwin, KeySym keySym));
82  static LRESULT CALLBACK ScrollbarProc _ANSI_ARGS_((HWND hwnd, UINT message,  static LRESULT CALLBACK ScrollbarProc _ANSI_ARGS_((HWND hwnd, UINT message,
83                              WPARAM wParam, LPARAM lParam));                              WPARAM wParam, LPARAM lParam));
84  static void             UpdateScrollbar _ANSI_ARGS_((  static void             UpdateScrollbar _ANSI_ARGS_((
85                              WinScrollbar *scrollPtr));                              WinScrollbar *scrollPtr));
86  static void             UpdateScrollbarMetrics _ANSI_ARGS_((void));  static void             UpdateScrollbarMetrics _ANSI_ARGS_((void));
87    
88  /*  /*
89   * The class procedure table for the scrollbar widget.   * The class procedure table for the scrollbar widget.
90   */   */
91    
92  TkClassProcs tkpScrollbarProcs = {  TkClassProcs tkpScrollbarProcs = {
93      CreateProc,                 /* createProc */      CreateProc,                 /* createProc */
94      NULL,                       /* geometryProc */      NULL,                       /* geometryProc */
95      ModalLoopProc,              /* modalProc */      ModalLoopProc,              /* modalProc */
96  };  };
97    
98    
99  /*  /*
100   *----------------------------------------------------------------------   *----------------------------------------------------------------------
101   *   *
102   * TkpCreateScrollbar --   * TkpCreateScrollbar --
103   *   *
104   *      Allocate a new TkScrollbar structure.   *      Allocate a new TkScrollbar structure.
105   *   *
106   * Results:   * Results:
107   *      Returns a newly allocated TkScrollbar structure.   *      Returns a newly allocated TkScrollbar structure.
108   *   *
109   * Side effects:   * Side effects:
110   *      Registers an event handler for the widget.   *      Registers an event handler for the widget.
111   *   *
112   *----------------------------------------------------------------------   *----------------------------------------------------------------------
113   */   */
114    
115  TkScrollbar *  TkScrollbar *
116  TkpCreateScrollbar(tkwin)  TkpCreateScrollbar(tkwin)
117      Tk_Window tkwin;      Tk_Window tkwin;
118  {  {
119      WinScrollbar *scrollPtr;      WinScrollbar *scrollPtr;
120      TkWindow *winPtr = (TkWindow *)tkwin;      TkWindow *winPtr = (TkWindow *)tkwin;
121            
122      if (!initialized) {      if (!initialized) {
123          Tcl_MutexLock(&winScrlbrMutex);          Tcl_MutexLock(&winScrlbrMutex);
124          UpdateScrollbarMetrics();          UpdateScrollbarMetrics();
125          initialized = 1;          initialized = 1;
126          Tcl_MutexUnlock(&winScrlbrMutex);          Tcl_MutexUnlock(&winScrlbrMutex);
127      }      }
128    
129      scrollPtr = (WinScrollbar *) ckalloc(sizeof(WinScrollbar));      scrollPtr = (WinScrollbar *) ckalloc(sizeof(WinScrollbar));
130      scrollPtr->winFlags = 0;      scrollPtr->winFlags = 0;
131      scrollPtr->hwnd = NULL;      scrollPtr->hwnd = NULL;
132    
133      Tk_CreateEventHandler(tkwin,      Tk_CreateEventHandler(tkwin,
134              ExposureMask|StructureNotifyMask|FocusChangeMask,              ExposureMask|StructureNotifyMask|FocusChangeMask,
135              TkScrollbarEventProc, (ClientData) scrollPtr);              TkScrollbarEventProc, (ClientData) scrollPtr);
136    
137      if (!Tcl_GetAssocData(winPtr->mainPtr->interp, "TkScrollbar", NULL)) {      if (!Tcl_GetAssocData(winPtr->mainPtr->interp, "TkScrollbar", NULL)) {
138          Tcl_SetAssocData(winPtr->mainPtr->interp, "TkScrollbar", NULL,          Tcl_SetAssocData(winPtr->mainPtr->interp, "TkScrollbar", NULL,
139                  (ClientData)1);                  (ClientData)1);
140          TkCreateBindingProcedure(winPtr->mainPtr->interp,          TkCreateBindingProcedure(winPtr->mainPtr->interp,
141                  winPtr->mainPtr->bindingTable,                  winPtr->mainPtr->bindingTable,
142                  (ClientData)Tk_GetUid("Scrollbar"), "<ButtonPress>",                  (ClientData)Tk_GetUid("Scrollbar"), "<ButtonPress>",
143                  ScrollbarBindProc, NULL, NULL);                  ScrollbarBindProc, NULL, NULL);
144      }      }
145    
146      return (TkScrollbar*) scrollPtr;      return (TkScrollbar*) scrollPtr;
147  }  }
148    
149  /*  /*
150   *----------------------------------------------------------------------   *----------------------------------------------------------------------
151   *   *
152   * UpdateScrollbar --   * UpdateScrollbar --
153   *   *
154   *      This function updates the position and size of the scrollbar   *      This function updates the position and size of the scrollbar
155   *      thumb based on the current settings.   *      thumb based on the current settings.
156   *   *
157   * Results:   * Results:
158   *      None.   *      None.
159   *   *
160   * Side effects:   * Side effects:
161   *      Moves the thumb.   *      Moves the thumb.
162   *   *
163   *----------------------------------------------------------------------   *----------------------------------------------------------------------
164   */   */
165    
166  static void  static void
167  UpdateScrollbar(scrollPtr)  UpdateScrollbar(scrollPtr)
168      WinScrollbar *scrollPtr;      WinScrollbar *scrollPtr;
169  {  {
170      SCROLLINFO scrollInfo;      SCROLLINFO scrollInfo;
171      double thumbSize;      double thumbSize;
172    
173      /*      /*
174       * Update the current scrollbar position and shape.       * Update the current scrollbar position and shape.
175       */       */
176    
177      scrollInfo.fMask = SIF_PAGE | SIF_POS | SIF_RANGE;      scrollInfo.fMask = SIF_PAGE | SIF_POS | SIF_RANGE;
178      scrollInfo.cbSize = sizeof(scrollInfo);      scrollInfo.cbSize = sizeof(scrollInfo);
179      scrollInfo.nMin = 0;      scrollInfo.nMin = 0;
180      scrollInfo.nMax = MAX_SCROLL;      scrollInfo.nMax = MAX_SCROLL;
181      thumbSize = (scrollPtr->info.lastFraction - scrollPtr->info.firstFraction);      thumbSize = (scrollPtr->info.lastFraction - scrollPtr->info.firstFraction);
182      scrollInfo.nPage = ((UINT) (thumbSize * (double) MAX_SCROLL)) + 1;      scrollInfo.nPage = ((UINT) (thumbSize * (double) MAX_SCROLL)) + 1;
183      if (thumbSize < 1.0) {      if (thumbSize < 1.0) {
184          scrollInfo.nPos = (int)          scrollInfo.nPos = (int)
185              ((scrollPtr->info.firstFraction / (1.0-thumbSize))              ((scrollPtr->info.firstFraction / (1.0-thumbSize))
186                      * (MAX_SCROLL - (scrollInfo.nPage - 1)));                      * (MAX_SCROLL - (scrollInfo.nPage - 1)));
187      } else {      } else {
188          scrollInfo.nPos = 0;          scrollInfo.nPos = 0;
189      }      }
190      SetScrollInfo(scrollPtr->hwnd, SB_CTL, &scrollInfo, TRUE);      SetScrollInfo(scrollPtr->hwnd, SB_CTL, &scrollInfo, TRUE);
191  }  }
192    
193  /*  /*
194   *----------------------------------------------------------------------   *----------------------------------------------------------------------
195   *   *
196   * CreateProc --   * CreateProc --
197   *   *
198   *      This function creates a new Scrollbar control, subclasses   *      This function creates a new Scrollbar control, subclasses
199   *      the instance, and generates a new Window object.   *      the instance, and generates a new Window object.
200   *   *
201   * Results:   * Results:
202   *      Returns the newly allocated Window object, or None on failure.   *      Returns the newly allocated Window object, or None on failure.
203   *   *
204   * Side effects:   * Side effects:
205   *      Causes a new Scrollbar control to come into existence.   *      Causes a new Scrollbar control to come into existence.
206   *   *
207   *----------------------------------------------------------------------   *----------------------------------------------------------------------
208   */   */
209    
210  static Window  static Window
211  CreateProc(tkwin, parentWin, instanceData)  CreateProc(tkwin, parentWin, instanceData)
212      Tk_Window tkwin;            /* Token for window. */      Tk_Window tkwin;            /* Token for window. */
213      Window parentWin;           /* Parent of new window. */      Window parentWin;           /* Parent of new window. */
214      ClientData instanceData;    /* Scrollbar instance data. */      ClientData instanceData;    /* Scrollbar instance data. */
215  {  {
216      DWORD style;      DWORD style;
217      Window window;      Window window;
218      HWND parent;      HWND parent;
219      TkWindow *winPtr;      TkWindow *winPtr;
220      WinScrollbar *scrollPtr = (WinScrollbar *)instanceData;      WinScrollbar *scrollPtr = (WinScrollbar *)instanceData;
221    
222      parent = Tk_GetHWND(parentWin);      parent = Tk_GetHWND(parentWin);
223    
224      if (scrollPtr->info.vertical) {      if (scrollPtr->info.vertical) {
225          style = WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS          style = WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS
226              | SBS_VERT | SBS_RIGHTALIGN;              | SBS_VERT | SBS_RIGHTALIGN;
227      } else {      } else {
228          style = WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS          style = WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS
229              | SBS_HORZ | SBS_BOTTOMALIGN;              | SBS_HORZ | SBS_BOTTOMALIGN;
230      }      }
231    
232      scrollPtr->hwnd = CreateWindow("SCROLLBAR", NULL, style,      scrollPtr->hwnd = CreateWindow("SCROLLBAR", NULL, style,
233              Tk_X(tkwin), Tk_Y(tkwin), Tk_Width(tkwin), Tk_Height(tkwin),              Tk_X(tkwin), Tk_Y(tkwin), Tk_Width(tkwin), Tk_Height(tkwin),
234              parent, NULL, Tk_GetHINSTANCE(), NULL);              parent, NULL, Tk_GetHINSTANCE(), NULL);
235    
236      /*      /*
237       * Ensure new window is inserted into the stacking order at the correct       * Ensure new window is inserted into the stacking order at the correct
238       * place.       * place.
239       */       */
240    
241      SetWindowPos(scrollPtr->hwnd, HWND_TOP, 0, 0, 0, 0,      SetWindowPos(scrollPtr->hwnd, HWND_TOP, 0, 0, 0, 0,
242                      SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);                      SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
243    
244      for (winPtr = ((TkWindow*)tkwin)->nextPtr; winPtr != NULL;      for (winPtr = ((TkWindow*)tkwin)->nextPtr; winPtr != NULL;
245           winPtr = winPtr->nextPtr) {           winPtr = winPtr->nextPtr) {
246          if ((winPtr->window != None) && !(winPtr->flags & TK_TOP_LEVEL)) {          if ((winPtr->window != None) && !(winPtr->flags & TK_TOP_LEVEL)) {
247              TkWinSetWindowPos(scrollPtr->hwnd, Tk_GetHWND(winPtr->window),              TkWinSetWindowPos(scrollPtr->hwnd, Tk_GetHWND(winPtr->window),
248                      Below);                      Below);
249              break;              break;
250          }          }
251      }      }
252    
253      scrollPtr->lastVertical = scrollPtr->info.vertical;      scrollPtr->lastVertical = scrollPtr->info.vertical;
254      scrollPtr->oldProc = (WNDPROC)SetWindowLong(scrollPtr->hwnd, GWL_WNDPROC,      scrollPtr->oldProc = (WNDPROC)SetWindowLong(scrollPtr->hwnd, GWL_WNDPROC,
255              (DWORD) ScrollbarProc);              (DWORD) ScrollbarProc);
256      window = Tk_AttachHWND(tkwin, scrollPtr->hwnd);      window = Tk_AttachHWND(tkwin, scrollPtr->hwnd);
257    
258      UpdateScrollbar(scrollPtr);      UpdateScrollbar(scrollPtr);
259      return window;      return window;
260  }  }
261    
262  /*  /*
263   *--------------------------------------------------------------   *--------------------------------------------------------------
264   *   *
265   * TkpDisplayScrollbar --   * TkpDisplayScrollbar --
266   *   *
267   *      This procedure redraws the contents of a scrollbar window.   *      This procedure redraws the contents of a scrollbar window.
268   *      It is invoked as a do-when-idle handler, so it only runs   *      It is invoked as a do-when-idle handler, so it only runs
269   *      when there's nothing else for the application to do.   *      when there's nothing else for the application to do.
270   *   *
271   * Results:   * Results:
272   *      None.   *      None.
273   *   *
274   * Side effects:   * Side effects:
275   *      Information appears on the screen.   *      Information appears on the screen.
276   *   *
277   *--------------------------------------------------------------   *--------------------------------------------------------------
278   */   */
279    
280  void  void
281  TkpDisplayScrollbar(clientData)  TkpDisplayScrollbar(clientData)
282      ClientData clientData;      /* Information about window. */      ClientData clientData;      /* Information about window. */
283  {  {
284      WinScrollbar *scrollPtr = (WinScrollbar *) clientData;      WinScrollbar *scrollPtr = (WinScrollbar *) clientData;
285      Tk_Window tkwin = scrollPtr->info.tkwin;      Tk_Window tkwin = scrollPtr->info.tkwin;
286    
287      scrollPtr->info.flags &= ~REDRAW_PENDING;      scrollPtr->info.flags &= ~REDRAW_PENDING;
288      if ((tkwin == NULL) || !Tk_IsMapped(tkwin)) {      if ((tkwin == NULL) || !Tk_IsMapped(tkwin)) {
289          return;          return;
290      }      }
291    
292      /*      /*
293       * Destroy and recreate the scrollbar control if the orientation       * Destroy and recreate the scrollbar control if the orientation
294       * has changed.       * has changed.
295       */       */
296    
297      if (scrollPtr->lastVertical != scrollPtr->info.vertical) {      if (scrollPtr->lastVertical != scrollPtr->info.vertical) {
298          HWND hwnd = Tk_GetHWND(Tk_WindowId(tkwin));          HWND hwnd = Tk_GetHWND(Tk_WindowId(tkwin));
299    
300          SetWindowLong(hwnd, GWL_WNDPROC, (DWORD) scrollPtr->oldProc);          SetWindowLong(hwnd, GWL_WNDPROC, (DWORD) scrollPtr->oldProc);
301          DestroyWindow(hwnd);          DestroyWindow(hwnd);
302    
303          CreateProc(tkwin, Tk_WindowId(Tk_Parent(tkwin)),          CreateProc(tkwin, Tk_WindowId(Tk_Parent(tkwin)),
304                  (ClientData) scrollPtr);                  (ClientData) scrollPtr);
305      } else {      } else {
306          UpdateScrollbar(scrollPtr);          UpdateScrollbar(scrollPtr);
307      }      }
308  }  }
309    
310  /*  /*
311   *----------------------------------------------------------------------   *----------------------------------------------------------------------
312   *   *
313   * TkpDestroyScrollbar --   * TkpDestroyScrollbar --
314   *   *
315   *      Free data structures associated with the scrollbar control.   *      Free data structures associated with the scrollbar control.
316   *   *
317   * Results:   * Results:
318   *      None.   *      None.
319   *   *
320   * Side effects:   * Side effects:
321   *      Restores the default control state.   *      Restores the default control state.
322   *   *
323   *----------------------------------------------------------------------   *----------------------------------------------------------------------
324   */   */
325    
326  void  void
327  TkpDestroyScrollbar(scrollPtr)  TkpDestroyScrollbar(scrollPtr)
328      TkScrollbar *scrollPtr;      TkScrollbar *scrollPtr;
329  {  {
330      WinScrollbar *winScrollPtr = (WinScrollbar *)scrollPtr;      WinScrollbar *winScrollPtr = (WinScrollbar *)scrollPtr;
331      HWND hwnd = winScrollPtr->hwnd;      HWND hwnd = winScrollPtr->hwnd;
332      if (hwnd) {      if (hwnd) {
333          SetWindowLong(hwnd, GWL_WNDPROC, (DWORD) winScrollPtr->oldProc);          SetWindowLong(hwnd, GWL_WNDPROC, (DWORD) winScrollPtr->oldProc);
334          if (winScrollPtr->winFlags & IN_MODAL_LOOP) {          if (winScrollPtr->winFlags & IN_MODAL_LOOP) {
335              ((TkWindow *)scrollPtr->tkwin)->flags |= TK_DONT_DESTROY_WINDOW;              ((TkWindow *)scrollPtr->tkwin)->flags |= TK_DONT_DESTROY_WINDOW;
336              SetParent(hwnd, NULL);              SetParent(hwnd, NULL);
337          }          }
338      }      }
339      winScrollPtr->winFlags |= ALREADY_DEAD;      winScrollPtr->winFlags |= ALREADY_DEAD;
340  }  }
341    
342  /*  /*
343   *----------------------------------------------------------------------   *----------------------------------------------------------------------
344   *   *
345   * UpdateScrollbarMetrics --   * UpdateScrollbarMetrics --
346   *   *
347   *      This function retrieves the current system metrics for a   *      This function retrieves the current system metrics for a
348   *      scrollbar.   *      scrollbar.
349   *   *
350   * Results:   * Results:
351   *      None.   *      None.
352   *   *
353   * Side effects:   * Side effects:
354   *      Updates the geometry cache info for all scrollbars.   *      Updates the geometry cache info for all scrollbars.
355   *   *
356   *----------------------------------------------------------------------   *----------------------------------------------------------------------
357   */   */
358    
359  void  void
360  UpdateScrollbarMetrics()  UpdateScrollbarMetrics()
361  {  {
362      Tk_ConfigSpec *specPtr;      Tk_ConfigSpec *specPtr;
363    
364      hArrowWidth = GetSystemMetrics(SM_CXHSCROLL);      hArrowWidth = GetSystemMetrics(SM_CXHSCROLL);
365      hThumb = GetSystemMetrics(SM_CXHTHUMB);      hThumb = GetSystemMetrics(SM_CXHTHUMB);
366      vArrowWidth = GetSystemMetrics(SM_CXVSCROLL);      vArrowWidth = GetSystemMetrics(SM_CXVSCROLL);
367      vArrowHeight = GetSystemMetrics(SM_CYVSCROLL);      vArrowHeight = GetSystemMetrics(SM_CYVSCROLL);
368      vThumb = GetSystemMetrics(SM_CYVTHUMB);      vThumb = GetSystemMetrics(SM_CYVTHUMB);
369    
370      sprintf(defWidth, "%d", vArrowWidth);      sprintf(defWidth, "%d", vArrowWidth);
371      for (specPtr = tkpScrollbarConfigSpecs; specPtr->type != TK_CONFIG_END;      for (specPtr = tkpScrollbarConfigSpecs; specPtr->type != TK_CONFIG_END;
372              specPtr++) {              specPtr++) {
373          if (specPtr->offset == Tk_Offset(TkScrollbar, width)) {          if (specPtr->offset == Tk_Offset(TkScrollbar, width)) {
374              specPtr->defValue = defWidth;              specPtr->defValue = defWidth;
375          }          }
376      }      }
377  }  }
378    
379  /*  /*
380   *----------------------------------------------------------------------   *----------------------------------------------------------------------
381   *   *
382   * TkpComputeScrollbarGeometry --   * TkpComputeScrollbarGeometry --
383   *   *
384   *      After changes in a scrollbar's size or configuration, this   *      After changes in a scrollbar's size or configuration, this
385   *      procedure recomputes various geometry information used in   *      procedure recomputes various geometry information used in
386   *      displaying the scrollbar.   *      displaying the scrollbar.
387   *   *
388   * Results:   * Results:
389   *      None.   *      None.
390   *   *
391   * Side effects:   * Side effects:
392   *      The scrollbar will be displayed differently.   *      The scrollbar will be displayed differently.
393   *   *
394   *----------------------------------------------------------------------   *----------------------------------------------------------------------
395   */   */
396    
397  void  void
398  TkpComputeScrollbarGeometry(scrollPtr)  TkpComputeScrollbarGeometry(scrollPtr)
399      register TkScrollbar *scrollPtr;    /* Scrollbar whose geometry may      register TkScrollbar *scrollPtr;    /* Scrollbar whose geometry may
400                                           * have changed. */                                           * have changed. */
401  {  {
402      int fieldLength, minThumbSize;      int fieldLength, minThumbSize;
403    
404      /*      /*
405       * Windows doesn't use focus rings on scrollbars, but we still       * Windows doesn't use focus rings on scrollbars, but we still
406       * perform basic sanity checks to appease backwards compatibility.       * perform basic sanity checks to appease backwards compatibility.
407       */       */
408    
409      if (scrollPtr->highlightWidth < 0) {      if (scrollPtr->highlightWidth < 0) {
410          scrollPtr->highlightWidth = 0;          scrollPtr->highlightWidth = 0;
411      }      }
412    
413      if (scrollPtr->vertical) {      if (scrollPtr->vertical) {
414          scrollPtr->arrowLength = vArrowHeight;          scrollPtr->arrowLength = vArrowHeight;
415          fieldLength = Tk_Height(scrollPtr->tkwin);          fieldLength = Tk_Height(scrollPtr->tkwin);
416          minThumbSize = vThumb;          minThumbSize = vThumb;
417      } else {      } else {
418          scrollPtr->arrowLength = hArrowWidth;          scrollPtr->arrowLength = hArrowWidth;
419          fieldLength = Tk_Width(scrollPtr->tkwin);          fieldLength = Tk_Width(scrollPtr->tkwin);
420          minThumbSize = hThumb;          minThumbSize = hThumb;
421      }      }
422      fieldLength -= 2*scrollPtr->arrowLength;      fieldLength -= 2*scrollPtr->arrowLength;
423      if (fieldLength < 0) {      if (fieldLength < 0) {
424          fieldLength = 0;          fieldLength = 0;
425      }      }
426      scrollPtr->sliderFirst = (int) ((double)fieldLength      scrollPtr->sliderFirst = (int) ((double)fieldLength
427              * scrollPtr->firstFraction);              * scrollPtr->firstFraction);
428      scrollPtr->sliderLast = (int) ((double)fieldLength      scrollPtr->sliderLast = (int) ((double)fieldLength
429              * scrollPtr->lastFraction);              * scrollPtr->lastFraction);
430    
431      /*      /*
432       * Adjust the slider so that some piece of it is always       * Adjust the slider so that some piece of it is always
433       * displayed in the scrollbar and so that it has at least       * displayed in the scrollbar and so that it has at least
434       * a minimal width (so it can be grabbed with the mouse).       * a minimal width (so it can be grabbed with the mouse).
435       */       */
436    
437      if (scrollPtr->sliderFirst > fieldLength) {      if (scrollPtr->sliderFirst > fieldLength) {
438          scrollPtr->sliderFirst = fieldLength;          scrollPtr->sliderFirst = fieldLength;
439      }      }
440      if (scrollPtr->sliderFirst < 0) {      if (scrollPtr->sliderFirst < 0) {
441          scrollPtr->sliderFirst = 0;          scrollPtr->sliderFirst = 0;
442      }      }
443      if (scrollPtr->sliderLast < (scrollPtr->sliderFirst      if (scrollPtr->sliderLast < (scrollPtr->sliderFirst
444              + minThumbSize)) {              + minThumbSize)) {
445          scrollPtr->sliderLast = scrollPtr->sliderFirst + minThumbSize;          scrollPtr->sliderLast = scrollPtr->sliderFirst + minThumbSize;
446      }      }
447      if (scrollPtr->sliderLast > fieldLength) {      if (scrollPtr->sliderLast > fieldLength) {
448          scrollPtr->sliderLast = fieldLength;          scrollPtr->sliderLast = fieldLength;
449      }      }
450      scrollPtr->sliderFirst += scrollPtr->arrowLength;      scrollPtr->sliderFirst += scrollPtr->arrowLength;
451      scrollPtr->sliderLast += scrollPtr->arrowLength;      scrollPtr->sliderLast += scrollPtr->arrowLength;
452    
453      /*      /*
454       * Register the desired geometry for the window (leave enough space       * Register the desired geometry for the window (leave enough space
455       * for the two arrows plus a minimum-size slider, plus border around       * for the two arrows plus a minimum-size slider, plus border around
456       * the whole window, if any).  Then arrange for the window to be       * the whole window, if any).  Then arrange for the window to be
457       * redisplayed.       * redisplayed.
458       */       */
459    
460      if (scrollPtr->vertical) {      if (scrollPtr->vertical) {
461          Tk_GeometryRequest(scrollPtr->tkwin,          Tk_GeometryRequest(scrollPtr->tkwin,
462                  scrollPtr->width, 2*scrollPtr->arrowLength + minThumbSize);                  scrollPtr->width, 2*scrollPtr->arrowLength + minThumbSize);
463      } else {      } else {
464          Tk_GeometryRequest(scrollPtr->tkwin,          Tk_GeometryRequest(scrollPtr->tkwin,
465                  2*scrollPtr->arrowLength + minThumbSize, scrollPtr->width);                  2*scrollPtr->arrowLength + minThumbSize, scrollPtr->width);
466      }      }
467      Tk_SetInternalBorder(scrollPtr->tkwin, 0);      Tk_SetInternalBorder(scrollPtr->tkwin, 0);
468  }  }
469    
470  /*  /*
471   *----------------------------------------------------------------------   *----------------------------------------------------------------------
472   *   *
473   * ScrollbarProc --   * ScrollbarProc --
474   *   *
475   *      This function is call by Windows whenever an event occurs on   *      This function is call by Windows whenever an event occurs on
476   *      a scrollbar control created by Tk.   *      a scrollbar control created by Tk.
477   *   *
478   * Results:   * Results:
479   *      Standard Windows return value.   *      Standard Windows return value.
480   *   *
481   * Side effects:   * Side effects:
482   *      May generate events.   *      May generate events.
483   *   *
484   *----------------------------------------------------------------------   *----------------------------------------------------------------------
485   */   */
486    
487  static LRESULT CALLBACK  static LRESULT CALLBACK
488  ScrollbarProc(hwnd, message, wParam, lParam)  ScrollbarProc(hwnd, message, wParam, lParam)
489      HWND hwnd;      HWND hwnd;
490      UINT message;      UINT message;
491      WPARAM wParam;      WPARAM wParam;
492      LPARAM lParam;      LPARAM lParam;
493  {  {
494      LRESULT result;      LRESULT result;
495      POINT point;      POINT point;
496      WinScrollbar *scrollPtr;      WinScrollbar *scrollPtr;
497      Tk_Window tkwin = Tk_HWNDToWindow(hwnd);      Tk_Window tkwin = Tk_HWNDToWindow(hwnd);
498    
499      if (tkwin == NULL) {      if (tkwin == NULL) {
500          panic("ScrollbarProc called on an invalid HWND");          panic("ScrollbarProc called on an invalid HWND");
501      }      }
502      scrollPtr = (WinScrollbar *)((TkWindow*)tkwin)->instanceData;      scrollPtr = (WinScrollbar *)((TkWindow*)tkwin)->instanceData;
503    
504      switch(message) {      switch(message) {
505          case WM_HSCROLL:          case WM_HSCROLL:
506          case WM_VSCROLL: {          case WM_VSCROLL: {
507              Tcl_Interp *interp;              Tcl_Interp *interp;
508              Tcl_DString cmdString;              Tcl_DString cmdString;
509              int command = LOWORD(wParam);              int command = LOWORD(wParam);
510              int code;              int code;
511    
512              GetCursorPos(&point);              GetCursorPos(&point);
513              Tk_TranslateWinEvent(NULL, WM_MOUSEMOVE, 0,              Tk_TranslateWinEvent(NULL, WM_MOUSEMOVE, 0,
514                      MAKELPARAM(point.x, point.y), &result);                      MAKELPARAM(point.x, point.y), &result);
515    
516              if (command == SB_ENDSCROLL) {              if (command == SB_ENDSCROLL) {
517                  return 0;                  return 0;
518              }              }
519    
520              /*              /*
521               * Bail out immediately if there isn't a command to invoke.               * Bail out immediately if there isn't a command to invoke.
522               */               */
523    
524              if (scrollPtr->info.commandSize == 0) {              if (scrollPtr->info.commandSize == 0) {
525                  Tcl_ServiceAll();                  Tcl_ServiceAll();
526                  return 0;                  return 0;
527              }              }
528                                    
529              Tcl_DStringInit(&cmdString);              Tcl_DStringInit(&cmdString);
530              Tcl_DStringAppend(&cmdString, scrollPtr->info.command,              Tcl_DStringAppend(&cmdString, scrollPtr->info.command,
531                      scrollPtr->info.commandSize);                      scrollPtr->info.commandSize);
532                                    
533              if (command == SB_LINELEFT || command == SB_LINERIGHT) {              if (command == SB_LINELEFT || command == SB_LINERIGHT) {
534                  Tcl_DStringAppendElement(&cmdString, "scroll");                  Tcl_DStringAppendElement(&cmdString, "scroll");
535                  Tcl_DStringAppendElement(&cmdString,                  Tcl_DStringAppendElement(&cmdString,
536                          (command == SB_LINELEFT ) ? "-1" : "1");                          (command == SB_LINELEFT ) ? "-1" : "1");
537                  Tcl_DStringAppendElement(&cmdString, "units");                  Tcl_DStringAppendElement(&cmdString, "units");
538              } else if (command == SB_PAGELEFT || command == SB_PAGERIGHT) {              } else if (command == SB_PAGELEFT || command == SB_PAGERIGHT) {
539                  Tcl_DStringAppendElement(&cmdString, "scroll");                  Tcl_DStringAppendElement(&cmdString, "scroll");
540                  Tcl_DStringAppendElement(&cmdString,                  Tcl_DStringAppendElement(&cmdString,
541                          (command == SB_PAGELEFT ) ? "-1" : "1");                          (command == SB_PAGELEFT ) ? "-1" : "1");
542                  Tcl_DStringAppendElement(&cmdString, "pages");                  Tcl_DStringAppendElement(&cmdString, "pages");
543              } else {              } else {
544                  char valueString[TCL_DOUBLE_SPACE];                  char valueString[TCL_DOUBLE_SPACE];
545                  double pos = 0.0;                  double pos = 0.0;
546                  switch (command) {                  switch (command) {
547                      case SB_THUMBPOSITION:                      case SB_THUMBPOSITION:
548                          pos = ((double)HIWORD(wParam)) / MAX_SCROLL;                          pos = ((double)HIWORD(wParam)) / MAX_SCROLL;
549                          break;                          break;
550    
551                      case SB_THUMBTRACK:                      case SB_THUMBTRACK:
552                          pos = ((double)HIWORD(wParam)) / MAX_SCROLL;                          pos = ((double)HIWORD(wParam)) / MAX_SCROLL;
553                          break;                          break;
554    
555                      case SB_TOP:                      case SB_TOP:
556                          pos = 0.0;                          pos = 0.0;
557                          break;                          break;
558    
559                      case SB_BOTTOM:                      case SB_BOTTOM:
560                          pos = 1.0;                          pos = 1.0;
561                          break;                          break;
562                  }                  }
563                  sprintf(valueString, "%g", pos);                  sprintf(valueString, "%g", pos);
564                  Tcl_DStringAppendElement(&cmdString, "moveto");                  Tcl_DStringAppendElement(&cmdString, "moveto");
565                  Tcl_DStringAppendElement(&cmdString, valueString);                  Tcl_DStringAppendElement(&cmdString, valueString);
566              }              }
567    
568              interp = scrollPtr->info.interp;              interp = scrollPtr->info.interp;
569              code = Tcl_GlobalEval(interp, cmdString.string);              code = Tcl_GlobalEval(interp, cmdString.string);
570              if (code != TCL_OK && code != TCL_CONTINUE && code != TCL_BREAK) {              if (code != TCL_OK && code != TCL_CONTINUE && code != TCL_BREAK) {
571                  Tcl_AddErrorInfo(interp, "\n    (scrollbar command)");                  Tcl_AddErrorInfo(interp, "\n    (scrollbar command)");
572                  Tcl_BackgroundError(interp);                  Tcl_BackgroundError(interp);
573              }                        }          
574              Tcl_DStringFree(&cmdString);                              Tcl_DStringFree(&cmdString);                
575    
576              Tcl_ServiceAll();              Tcl_ServiceAll();
577              return 0;              return 0;
578          }          }
579    
580          default:          default:
581              if (Tk_TranslateWinEvent(hwnd, message, wParam, lParam, &result)) {              if (Tk_TranslateWinEvent(hwnd, message, wParam, lParam, &result)) {
582                  return result;                  return result;
583              }              }
584      }      }
585      return CallWindowProc(scrollPtr->oldProc, hwnd, message, wParam, lParam);      return CallWindowProc(scrollPtr->oldProc, hwnd, message, wParam, lParam);
586  }  }
587    
588  /*  /*
589   *----------------------------------------------------------------------   *----------------------------------------------------------------------
590   *   *
591   * TkpConfigureScrollbar --   * TkpConfigureScrollbar --
592   *   *
593   *      This procedure is called after the generic code has finished   *      This procedure is called after the generic code has finished
594   *      processing configuration options, in order to configure   *      processing configuration options, in order to configure
595   *      platform specific options.   *      platform specific options.
596   *   *
597   * Results:   * Results:
598   *      None.   *      None.
599   *   *
600   * Side effects:   * Side effects:
601   *      None.   *      None.
602   *   *
603   *----------------------------------------------------------------------   *----------------------------------------------------------------------
604   */   */
605    
606  void  void
607  TkpConfigureScrollbar(scrollPtr)  TkpConfigureScrollbar(scrollPtr)
608      register TkScrollbar *scrollPtr;    /* Information about widget;  may or      register TkScrollbar *scrollPtr;    /* Information about widget;  may or
609                                           * may not already have values for                                           * may not already have values for
610                                           * some fields. */                                           * some fields. */
611  {  {
612  }  }
613    
614  /*  /*
615   *--------------------------------------------------------------   *--------------------------------------------------------------
616   *   *
617   * ScrollbarBindProc --   * ScrollbarBindProc --
618   *   *
619   *      This procedure is invoked when the default <ButtonPress>   *      This procedure is invoked when the default <ButtonPress>
620   *      binding on the Scrollbar bind tag fires.   *      binding on the Scrollbar bind tag fires.
621   *   *
622   * Results:   * Results:
623   *      None.   *      None.
624   *   *
625   * Side effects:   * Side effects:
626   *      The event enters a modal loop.   *      The event enters a modal loop.
627   *   *
628   *--------------------------------------------------------------   *--------------------------------------------------------------
629   */   */
630    
631  static int  static int
632  ScrollbarBindProc(clientData, interp, eventPtr, tkwin, keySym)  ScrollbarBindProc(clientData, interp, eventPtr, tkwin, keySym)
633      ClientData clientData;      ClientData clientData;
634      Tcl_Interp *interp;      Tcl_Interp *interp;
635      XEvent *eventPtr;      XEvent *eventPtr;
636      Tk_Window tkwin;      Tk_Window tkwin;
637      KeySym keySym;      KeySym keySym;
638  {  {
639      TkWindow *winPtr = (TkWindow*)tkwin;      TkWindow *winPtr = (TkWindow*)tkwin;
640      if (eventPtr->type == ButtonPress) {      if (eventPtr->type == ButtonPress) {
641          winPtr->flags |= TK_DEFER_MODAL;          winPtr->flags |= TK_DEFER_MODAL;
642      }      }
643      return TCL_OK;      return TCL_OK;
644  }  }
645    
646  /*  /*
647   *----------------------------------------------------------------------   *----------------------------------------------------------------------
648   *   *
649   * ModalLoopProc --   * ModalLoopProc --
650   *   *
651   *      This function is invoked at the end of the event processing   *      This function is invoked at the end of the event processing
652   *      whenever the ScrollbarBindProc has been invoked for a ButtonPress   *      whenever the ScrollbarBindProc has been invoked for a ButtonPress
653   *      event.   *      event.
654   *   *
655   * Results:   * Results:
656   *      None.   *      None.
657   *   *
658   * Side effects:   * Side effects:
659   *      Enters a modal loop.   *      Enters a modal loop.
660   *   *
661   *----------------------------------------------------------------------   *----------------------------------------------------------------------
662   */   */
663    
664  static void  static void
665  ModalLoopProc(tkwin, eventPtr)  ModalLoopProc(tkwin, eventPtr)
666      Tk_Window tkwin;      Tk_Window tkwin;
667      XEvent *eventPtr;      XEvent *eventPtr;
668  {  {
669      TkWindow *winPtr = (TkWindow*)tkwin;      TkWindow *winPtr = (TkWindow*)tkwin;
670      WinScrollbar *scrollPtr = (WinScrollbar *) winPtr->instanceData;      WinScrollbar *scrollPtr = (WinScrollbar *) winPtr->instanceData;
671      int oldMode;      int oldMode;
672    
673      if (scrollPtr->hwnd) {      if (scrollPtr->hwnd) {
674          Tcl_Preserve((ClientData)scrollPtr);          Tcl_Preserve((ClientData)scrollPtr);
675          scrollPtr->winFlags |= IN_MODAL_LOOP;          scrollPtr->winFlags |= IN_MODAL_LOOP;
676          oldMode = Tcl_SetServiceMode(TCL_SERVICE_ALL);          oldMode = Tcl_SetServiceMode(TCL_SERVICE_ALL);
677          TkWinResendEvent(scrollPtr->oldProc, scrollPtr->hwnd, eventPtr);          TkWinResendEvent(scrollPtr->oldProc, scrollPtr->hwnd, eventPtr);
678          (void) Tcl_SetServiceMode(oldMode);          (void) Tcl_SetServiceMode(oldMode);
679          scrollPtr->winFlags &= ~IN_MODAL_LOOP;          scrollPtr->winFlags &= ~IN_MODAL_LOOP;
680          if (scrollPtr->hwnd && scrollPtr->winFlags & ALREADY_DEAD) {          if (scrollPtr->hwnd && scrollPtr->winFlags & ALREADY_DEAD) {
681              DestroyWindow(scrollPtr->hwnd);              DestroyWindow(scrollPtr->hwnd);
682          }          }
683          Tcl_Release((ClientData)scrollPtr);          Tcl_Release((ClientData)scrollPtr);
684      }      }
685  }  }
686    
687  /*  /*
688   *--------------------------------------------------------------   *--------------------------------------------------------------
689   *   *
690   * TkpScrollbarPosition --   * TkpScrollbarPosition --
691   *   *
692   *      Determine the scrollbar element corresponding to a   *      Determine the scrollbar element corresponding to a
693   *      given position.   *      given position.
694   *   *
695   * Results:   * Results:
696   *      One of TOP_ARROW, TOP_GAP, etc., indicating which element   *      One of TOP_ARROW, TOP_GAP, etc., indicating which element
697   *      of the scrollbar covers the position given by (x, y).  If   *      of the scrollbar covers the position given by (x, y).  If
698   *      (x,y) is outside the scrollbar entirely, then OUTSIDE is   *      (x,y) is outside the scrollbar entirely, then OUTSIDE is
699   *      returned.   *      returned.
700   *   *
701   * Side effects:   * Side effects:
702   *      None.   *      None.
703   *   *
704   *--------------------------------------------------------------   *--------------------------------------------------------------
705   */   */
706    
707  int  int
708  TkpScrollbarPosition(scrollPtr, x, y)  TkpScrollbarPosition(scrollPtr, x, y)
709      register TkScrollbar *scrollPtr;    /* Scrollbar widget record. */      register TkScrollbar *scrollPtr;    /* Scrollbar widget record. */
710      int x, y;                           /* Coordinates within scrollPtr's      int x, y;                           /* Coordinates within scrollPtr's
711                                           * window. */                                           * window. */
712  {  {
713      int length, width, tmp;      int length, width, tmp;
714    
715      if (scrollPtr->vertical) {      if (scrollPtr->vertical) {
716          length = Tk_Height(scrollPtr->tkwin);          length = Tk_Height(scrollPtr->tkwin);
717          width = Tk_Width(scrollPtr->tkwin);          width = Tk_Width(scrollPtr->tkwin);
718      } else {      } else {
719          tmp = x;          tmp = x;
720          x = y;          x = y;
721          y = tmp;          y = tmp;
722          length = Tk_Width(scrollPtr->tkwin);          length = Tk_Width(scrollPtr->tkwin);
723          width = Tk_Height(scrollPtr->tkwin);          width = Tk_Height(scrollPtr->tkwin);
724      }      }
725    
726      if ((x < scrollPtr->inset) || (x >= (width - scrollPtr->inset))      if ((x < scrollPtr->inset) || (x >= (width - scrollPtr->inset))
727              || (y < scrollPtr->inset) || (y >= (length - scrollPtr->inset))) {              || (y < scrollPtr->inset) || (y >= (length - scrollPtr->inset))) {
728          return OUTSIDE;          return OUTSIDE;
729      }      }
730    
731      /*      /*
732       * All of the calculations in this procedure mirror those in       * All of the calculations in this procedure mirror those in
733       * TkpDisplayScrollbar.  Be sure to keep the two consistent.       * TkpDisplayScrollbar.  Be sure to keep the two consistent.
734       */       */
735    
736      if (y < (scrollPtr->inset + scrollPtr->arrowLength)) {      if (y < (scrollPtr->inset + scrollPtr->arrowLength)) {
737          return TOP_ARROW;          return TOP_ARROW;
738      }      }
739      if (y < scrollPtr->sliderFirst) {      if (y < scrollPtr->sliderFirst) {
740          return TOP_GAP;          return TOP_GAP;
741      }      }
742      if (y < scrollPtr->sliderLast) {      if (y < scrollPtr->sliderLast) {
743          return SLIDER;          return SLIDER;
744      }      }
745      if (y >= (length - (scrollPtr->arrowLength + scrollPtr->inset))) {      if (y >= (length - (scrollPtr->arrowLength + scrollPtr->inset))) {
746          return BOTTOM_ARROW;          return BOTTOM_ARROW;
747      }      }
748      return BOTTOM_GAP;      return BOTTOM_GAP;
749  }  }
750    
751  /* End of tkwinscrlbr.c */  /* End of tkwinscrlbr.c */

Legend:
Removed from v.69  
changed lines
  Added in v.98

dashley@gmail.com
ViewVC Help
Powered by ViewVC 1.1.25