Changeset 145 for trunk/src


Ignore:
Timestamp:
Jun 21, 1999, 5:28:44 PM (26 years ago)
Author:
cbratschi
Message:

Trackbar optimized

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/comctl32/trackbar.c

    r110 r145  
    1 /* $Id: trackbar.c,v 1.5 1999-06-16 20:25:44 cbratschi Exp $ */
     1/* $Id: trackbar.c,v 1.6 1999-06-21 15:28:44 cbratschi Exp $ */
    22/*
    33 * Trackbar control
     
    1010 *
    1111 * TODO:
    12  *   - Some messages.
    13  *   - more display code.
    14  *   - handle dragging slider better
    15  *   - better tic handling.
     12 *
    1613 *   - more notifications.
    17  *   - implement TRACKBAR_Draw with inUpdate
    18  *
     14 *   - Fix Odin32/WINE DrawEdge() bugs
    1915 */
    20 
    21 /* known bugs:
    22 
    23    -TBM_SETRANGEMAX & TBM_SETRANGEMIN should only change the view of the
    24    trackbar, not the actual amount of tics in the list.
    25    -TBM_GETTIC & TBM_GETTICPOS shouldn't rely on infoPtr->tics being sorted.
    26    - Make drawing code exact match of w95 drawing.
    27 */
    28 
    29 
    3016
    3117#include "winbase.h"
     
    3824
    3925
    40 /* Used by TRACKBAR_Refresh to find out which parts of the control
     26/* Used by TRACKBAR_Draw to find out which parts of the control
    4127   need to be recalculated */
    4228
     
    4733#define TB_DRAG_MODE            16     /* we're dragging the slider */
    4834#define TB_DRAGPOSVALID         32     /* current Position is in dragPos */
    49 #define TB_SHOW_TOOLTIP         64     /* tooltip-style enabled and tooltip on */
     35#define TB_SCROLL_MODE          64     /* WM_TIMER scroll mode */
     36#define TB_SHOW_TOOLTIP         128    /* tooltip-style enabled and tooltip on */
    5037
    5138/* helper defines for TRACKBAR_DrawTic */
     
    5744#define TIC_SELECTIONMARK       (TIC_SELECTIONMARKMAX | TIC_SELECTIONMARKMIN)
    5845
     46/* size calculation */
     47
     48#define BORDER_SIZE 2
     49
     50#define SCALE_SIZE  4
     51#define SCALE_SPACE 1
     52
     53#define THUMB_LEN    23
     54#define THUMB_MINLEN 4
     55
     56#define CHANNEL_NOSEL_HEIGHT 4
     57#define CHANNEL_MIN_HEIGHT   4
     58#define CHANNEL_THUMB_DIFF   8
     59#define CHANNEL_SPACE        8
     60#define CHANNEL_SCALE_SPACE  CHANNEL_THUMB_DIFF/2+SCALE_SIZE+SCALE_SPACE+BORDER_SIZE
     61#define CHANNEL_THUMB_SPACE  CHANNEL_THUMB_DIFF+BORDER_SIZE
     62
     63/* scroll mode */
     64
     65#define SCROLL_TIME     500 //ms
     66#define SCROLL_TIMER_ID 1
     67
    5968static BOOL TRACKBAR_SendNotify (HWND hwnd, UINT code);
    6069
    61 void TRACKBAR_RecalculateTics (TRACKBAR_INFO *infoPtr)
    62 {
    63     int i,tic,nrTics;
    64 
    65     if (infoPtr->uTicFreq && infoPtr->nRangeMax >= infoPtr->nRangeMin)
    66         nrTics=(infoPtr->nRangeMax - infoPtr->nRangeMin)/infoPtr->uTicFreq;
    67     else {
    68         nrTics=0;
    69         COMCTL32_Free (infoPtr->tics);
    70         infoPtr->tics=NULL;
    71         infoPtr->uNumTics=0;
    72         return;
    73     }
    74 
    75     if (nrTics!=infoPtr->uNumTics) {
    76         infoPtr->tics=COMCTL32_ReAlloc (infoPtr->tics,
    77                                         (nrTics+1)*sizeof (DWORD));
    78         infoPtr->uNumTics=nrTics;
    79     }
    80     infoPtr->uNumTics=nrTics;
    81     tic=infoPtr->nRangeMin+infoPtr->uTicFreq;
    82     for (i=0; i<nrTics; i++,tic+=infoPtr->uTicFreq)
    83         infoPtr->tics[i]=tic;
     70void TRACKBAR_RecalculateTics (HWND hwnd,TRACKBAR_INFO *infoPtr,BOOL restoreOld)
     71{
     72    INT i,tic,nrTics;
     73    DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
     74
     75    if (dwStyle & TBS_NOTICKS) //no ticks
     76    {
     77      COMCTL32_Free(infoPtr->tics);
     78      infoPtr->tics = NULL;
     79      infoPtr->uNumTics = 0;
     80      return;
     81    }
     82
     83    if (restoreOld && !(dwStyle & TBS_AUTOTICKS) && infoPtr->tics != NULL)
     84    { //check old ticks
     85      LPLONG oldTics = COMCTL32_Alloc(infoPtr->uNumTics*sizeof(DWORD));
     86      INT count = 0;
     87
     88      for (i = 0;i < infoPtr->uNumTics;i++)
     89      {
     90        if (infoPtr->tics[i] >= infoPtr->nRangeMin && infoPtr->tics[i] <= infoPtr->nRangeMax)
     91        {
     92          oldTics[count] = infoPtr->tics[i];
     93          count++;
     94        }
     95      }
     96
     97      COMCTL32_Free(infoPtr->tics);
     98      infoPtr->tics = COMCTL32_ReAlloc(oldTics,count*sizeof(DWORD));
     99      infoPtr->uNumTics = count;
     100
     101      return;
     102    }
     103
     104    if (!(dwStyle & TBS_AUTOTICKS)) return;
     105
     106    if (infoPtr->uTicFreq == 0)
     107    {
     108      COMCTL32_Free(infoPtr->tics);
     109      infoPtr->tics = NULL;
     110      infoPtr->uNumTics = 0;
     111      return;
     112    }
     113
     114    if (infoPtr->uTicFreq && infoPtr->nRangeMax > infoPtr->nRangeMin && (dwStyle & TBS_AUTOTICKS))
     115    {
     116      //Tics without start and end tic
     117      nrTics = (infoPtr->nRangeMax-infoPtr->nRangeMin)/infoPtr->uTicFreq-1;
     118    } else
     119    {
     120      COMCTL32_Free(infoPtr->tics);
     121      infoPtr->tics = NULL;
     122      infoPtr->uNumTics = 0;
     123      return;
     124    }
     125
     126    if (nrTics != infoPtr->uNumTics)
     127    {
     128      COMCTL32_Free(infoPtr->tics);
     129      infoPtr->tics = COMCTL32_Alloc(nrTics*sizeof(DWORD));
     130      infoPtr->uNumTics = nrTics;
     131    }
     132
     133    tic = infoPtr->nRangeMin+infoPtr->uTicFreq; //start not included
     134    for (i = 0;i < nrTics;i++)
     135    {
     136      infoPtr->tics[i] = tic;
     137      tic += infoPtr->uTicFreq;
     138    }
    84139}
    85140
     
    89144
    90145static DOUBLE
    91 TRACKBAR_ConvertPlaceToPosition (TRACKBAR_INFO *infoPtr, int place,
    92                                  int vertical)
     146TRACKBAR_ConvertPlaceToPosition(TRACKBAR_INFO *infoPtr,int place,int vertical)
    93147{
    94148    double range,width,pos;
    95149
    96     range=infoPtr->nRangeMax - infoPtr->nRangeMin;
    97     if (vertical) {
    98         width=infoPtr->rcChannel.bottom - infoPtr->rcChannel.top;
    99         pos=(range*(place - infoPtr->rcChannel.top)) / width;
    100     } else {
    101         width=infoPtr->rcChannel.right - infoPtr->rcChannel.left;
    102         pos=(range*(place - infoPtr->rcChannel.left)) / width;
    103     }
    104 
    105     if (pos > infoPtr->nRangeMax)
    106         pos = infoPtr->nRangeMax;
    107     else if (pos < infoPtr->nRangeMin)
    108         pos = infoPtr->nRangeMin;
     150    range = infoPtr->nRangeMax-infoPtr->nRangeMin;
     151    if (vertical)
     152    {
     153      width = infoPtr->rcChannel.bottom-infoPtr->rcChannel.top;
     154      pos = infoPtr->nRangeMin+(range*(place-infoPtr->rcChannel.top))/width;
     155    } else
     156    {
     157      width = infoPtr->rcChannel.right-infoPtr->rcChannel.left;
     158      pos = infoPtr->nRangeMin+(range*(place-infoPtr->rcChannel.left))/width;
     159    }
     160
     161    if (pos > infoPtr->nRangeMax) pos = infoPtr->nRangeMax;
     162    else if (pos < infoPtr->nRangeMin) pos = infoPtr->nRangeMin;
    109163
    110164//    TRACE (trackbar,"%.2f\n",pos);
     
    114168
    115169static VOID
    116 TRACKBAR_CalcChannel (HWND hwnd, TRACKBAR_INFO *infoPtr)
    117 {
    118     DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
    119     INT cyChannel;
    120     RECT lpRect,*channel = & infoPtr->rcChannel;
    121 
    122     GetClientRect (hwnd, &lpRect);
    123 
    124     if (dwStyle & TBS_ENABLESELRANGE)
    125         cyChannel = MAX(infoPtr->uThumbLen - 8, 4);
    126     else
    127         cyChannel = 4;
    128 
    129     if (dwStyle & TBS_VERT) {
    130         channel->top    = lpRect.top + 8;
    131         channel->bottom = lpRect.bottom - 8;
    132 
    133         if (dwStyle & TBS_BOTH) {
    134             channel->left  = (lpRect.right - cyChannel) / 2;
    135             channel->right = (lpRect.right + cyChannel) / 2;
    136         }
    137         else if (dwStyle & TBS_LEFT) {
    138             channel->left  = lpRect.left + 10;
    139             channel->right = channel->left + cyChannel;
    140         }
    141         else { /* TBS_RIGHT */
    142             channel->right = lpRect.right - 10;
    143             channel->left  = channel->right - cyChannel;
    144         }
    145     }
    146     else {
    147         channel->left = lpRect.left + 8;
    148         channel->right = lpRect.right - 8;
    149         if (dwStyle & TBS_BOTH) {
    150             channel->top                = (lpRect.bottom - cyChannel) / 2;
    151             channel->bottom     = (lpRect.bottom + cyChannel) / 2;
    152         }
    153         else if (dwStyle & TBS_TOP) {
    154             channel->top    = lpRect.top + 10;
    155             channel->bottom = channel->top + cyChannel;
    156         }
    157         else { /* TBS_BOTTOM */
    158             channel->bottom = lpRect.bottom - 10;
    159             channel->top    = channel->bottom - cyChannel;
    160         }
    161     }
    162 }
     170TRACKBAR_CalcChannel (HWND hwnd,TRACKBAR_INFO *infoPtr)
     171{
     172    DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
     173    INT channelSize;
     174    RECT lpRect,*channel = &infoPtr->rcChannel;
     175
     176    GetClientRect(hwnd,&lpRect);
     177
     178    if (dwStyle & TBS_ENABLESELRANGE) channelSize = MAX(infoPtr->uThumbLen-CHANNEL_THUMB_DIFF,CHANNEL_MIN_HEIGHT);
     179    else channelSize = CHANNEL_NOSEL_HEIGHT;
     180
     181    if (dwStyle & TBS_VERT)
     182    {
     183      channel->top    = lpRect.top+CHANNEL_SPACE;
     184      channel->bottom = lpRect.bottom-CHANNEL_SPACE;
     185
     186      if (dwStyle & TBS_BOTH)
     187      { //center
     188        channel->left  = (lpRect.right-channelSize)/2;
     189        channel->right = (lpRect.right+channelSize)/2;
     190      } else if (dwStyle & TBS_LEFT)
     191      {
     192        channel->left  = lpRect.left+CHANNEL_SCALE_SPACE;
     193        channel->right = channel->left+channelSize;
     194      } else
     195      { //Right, align left
     196        channel->left = lpRect.left+CHANNEL_THUMB_SPACE;
     197        channel->right = channel->left+channelSize;
     198      }
     199    } else
     200    {
     201      channel->left = lpRect.left+CHANNEL_SPACE;
     202      channel->right = lpRect.right-CHANNEL_SPACE;
     203      if (dwStyle & TBS_BOTH)
     204      { //center
     205        channel->top    = (lpRect.bottom-channelSize)/2;
     206        channel->bottom = (lpRect.bottom+channelSize)/2;
     207      } else if (dwStyle & TBS_TOP)
     208      {
     209        channel->top    = lpRect.top+CHANNEL_SCALE_SPACE;
     210        channel->bottom = channel->top+channelSize;
     211      } else
     212      { //Bottom, align top
     213        channel->top    = lpRect.top+CHANNEL_THUMB_SPACE;
     214        channel->bottom = channel->top+channelSize;
     215      }
     216    }
     217}
     218
     219//Calculate thumb size
    163220
    164221static VOID
    165 TRACKBAR_CalcThumb (HWND hwnd, TRACKBAR_INFO *infoPtr)
     222TRACKBAR_CalcThumb(HWND hwnd,TRACKBAR_INFO *infoPtr)
    166223{
    167224    RECT *thumb;
     225    RECT *fullThumb;
    168226    int range, width;
    169 
    170     thumb=&infoPtr->rcThumb;
    171     range=infoPtr->nRangeMax - infoPtr->nRangeMin;
    172     if (GetWindowLongA (hwnd, GWL_STYLE) & TBS_VERT) {
    173         width=infoPtr->rcChannel.bottom - infoPtr->rcChannel.top;
    174         thumb->left  = infoPtr->rcChannel.left - 1;
    175         thumb->right  = infoPtr->rcChannel.left + infoPtr->uThumbLen - 8;
    176         thumb->top       = infoPtr->rcChannel.top +
    177             (width*infoPtr->nPos)/range - 5;
    178         thumb->bottom = thumb->top + infoPtr->uThumbLen/3;
    179 
    180     } else {
    181         width=infoPtr->rcChannel.right - infoPtr->rcChannel.left;
    182         thumb->left   = infoPtr->rcChannel.left +
    183             (width*infoPtr->nPos)/range - 5;
    184         thumb->right  = thumb->left + infoPtr->uThumbLen/3;
    185         thumb->top        = infoPtr->rcChannel.top - 1;
    186         thumb->bottom = infoPtr->rcChannel.top + infoPtr->uThumbLen - 8;
     227    int x,y;
     228    DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
     229    int thumbFactor = 2;
     230
     231    thumb = &infoPtr->rcThumb;
     232    fullThumb = &infoPtr->rcFullThumb;
     233    range = infoPtr->nRangeMax-infoPtr->nRangeMin;
     234    if (dwStyle & TBS_VERT)
     235    {
     236      width = infoPtr->rcChannel.bottom-infoPtr->rcChannel.top;
     237      y = infoPtr->uThumbLen/thumbFactor; //thumb height
     238      if (y%2 == 1) y++; //for real arrow
     239      thumb->top    = infoPtr->rcChannel.top+(width*(infoPtr->nPos-infoPtr->nRangeMin))/range-y/2; //centered
     240      thumb->bottom = thumb->top+y;
     241      //centered, no arrows
     242      thumb->left  = infoPtr->rcChannel.left-(infoPtr->uThumbLen-(infoPtr->rcChannel.right-infoPtr->rcChannel.left))/2;
     243      thumb->right = thumb->left+infoPtr->uThumbLen;
     244      CopyRect(fullThumb,thumb);
     245      if (dwStyle & TBS_BOTH) return;
     246      x = y/2; //arrow width
     247      if (dwStyle & TBS_LEFT) thumb->left += x; else thumb->right -= x;
     248    } else
     249    {
     250      width = infoPtr->rcChannel.right-infoPtr->rcChannel.left;
     251      x = infoPtr->uThumbLen/thumbFactor; //thumb width
     252      if (x%2 == 1) x++; //for real arrow
     253      thumb->left   = infoPtr->rcChannel.left+(width*(infoPtr->nPos-infoPtr->nRangeMin))/range-x/2; //centered
     254      thumb->right  = thumb->left+x;
     255      //centered, no arrows
     256      thumb->top  = infoPtr->rcChannel.top-(infoPtr->uThumbLen-(infoPtr->rcChannel.bottom-infoPtr->rcChannel.top))/2;
     257      thumb->bottom = thumb->top+infoPtr->uThumbLen;
     258      CopyRect(fullThumb,thumb);
     259      if (dwStyle & TBS_BOTH) return;
     260      y = x/2; //arrow height
     261      if (dwStyle & TBS_TOP) thumb->top += y; else thumb->bottom -= y;
    187262    }
    188263}
     
    192267{
    193268    RECT *selection;
    194     int range, width;
    195 
    196     selection= & infoPtr->rcSelection;
    197     range=infoPtr->nRangeMax - infoPtr->nRangeMin;
    198     width=infoPtr->rcChannel.right - infoPtr->rcChannel.left;
    199 
    200     if (range <= 0)
    201         SetRectEmpty (selection);
     269    int range,width,height;
     270    int selMin = infoPtr->nSelMin-infoPtr->nRangeMin; //relative to nRangeMin
     271    int selMax = infoPtr->nSelMax-infoPtr->nRangeMin; //dito
     272
     273    selection = &infoPtr->rcSelection;
     274    range = infoPtr->nRangeMax-infoPtr->nRangeMin;
     275
     276    if (range <= 0 || selMin == selMax) SetRectEmpty(selection);
    202277    else
    203         if (GetWindowLongA (hwnd, GWL_STYLE) & TBS_VERT) {
    204             selection->left   = infoPtr->rcChannel.left +
    205                 (width*infoPtr->nSelMin)/range;
    206             selection->right  = infoPtr->rcChannel.left +
    207                 (width*infoPtr->nSelMax)/range;
    208             selection->top    = infoPtr->rcChannel.top + 2;
    209             selection->bottom = infoPtr->rcChannel.bottom - 2;
    210         } else {
    211             selection->top    = infoPtr->rcChannel.top +
    212                 (width*infoPtr->nSelMin)/range;
    213             selection->bottom = infoPtr->rcChannel.top +
    214                 (width*infoPtr->nSelMax)/range;
    215             selection->left   = infoPtr->rcChannel.left + 2;
    216             selection->right  = infoPtr->rcChannel.right - 2;
     278        if (!(GetWindowLongA(hwnd, GWL_STYLE) & TBS_VERT))
     279        {   //Horizontal
     280            width = infoPtr->rcChannel.right-infoPtr->rcChannel.left;
     281            selection->left = infoPtr->rcChannel.left+(width*selMin)/range;
     282            selection->right  = infoPtr->rcChannel.left+(width*selMax)/range;
     283            selection->top    = infoPtr->rcChannel.top+2;
     284            selection->bottom = infoPtr->rcChannel.bottom-2;
     285        } else
     286        {   //Vertical
     287            height = infoPtr->rcChannel.bottom-infoPtr->rcChannel.top;
     288            selection->top    = infoPtr->rcChannel.top+(height*selMin)/range;
     289            selection->bottom = infoPtr->rcChannel.top+(height*selMax)/range;
     290            selection->left   = infoPtr->rcChannel.left+2;
     291            selection->right  = infoPtr->rcChannel.right-2;
    217292        }
    218293}
    219294
    220 /* Trackbar drawing code. I like my spaghetti done milanese. */
     295/* Trackbar drawing code */
    221296
    222297/* ticPos is in tic-units, not in pixels */
     
    226301                       int flags, COLORREF clrTic)
    227302{
    228     RECT rcChannel=infoPtr->rcChannel;
     303    RECT rcChannel = infoPtr->rcChannel;
    229304    int x,y,width,range,side;
    230305
    231     range=infoPtr->nRangeMax - infoPtr->nRangeMin;
    232     width=rcChannel.right - rcChannel.left;
    233 
    234     if (flags & TBS_TOP) {
    235         y=rcChannel.top-2;
    236         side=-1;
    237     } else {
    238         y=rcChannel.bottom+2;
    239         side=1;
    240     }
    241 
    242     if (flags & TIC_SELECTIONMARK) {
    243         if (flags & TIC_SELECTIONMARKMIN)
    244             x=rcChannel.left + (width*ticPos)/range - 1;
    245         else
    246             x=rcChannel.left + (width*ticPos)/range + 1;
    247 
    248         SetPixel (hdc, x,y+6*side, clrTic);
    249         SetPixel (hdc, x,y+7*side, clrTic);
    250         return;
    251     }
    252 
    253     if ((ticPos>infoPtr->nRangeMin) && (ticPos<infoPtr->nRangeMax)) {
    254         x=rcChannel.left + (width*ticPos)/range;
    255         SetPixel (hdc, x,y+5*side, clrTic);
    256         SetPixel (hdc, x,y+6*side, clrTic);
    257         SetPixel (hdc, x,y+7*side, clrTic);
    258     }
    259 
    260     if (flags & TIC_EDGE) {
    261         if (flags & TIC_LEFTEDGE)
    262             x=rcChannel.left;
    263         else
    264             x=rcChannel.right;
    265 
    266         SetPixel (hdc, x,y+5*side, clrTic);
    267         SetPixel (hdc, x,y+6*side, clrTic);
    268         SetPixel (hdc, x,y+7*side, clrTic);
    269         SetPixel (hdc, x,y+8*side, clrTic);
    270     }
    271 
     306    range = infoPtr->nRangeMax-infoPtr->nRangeMin;
     307    width = rcChannel.right-rcChannel.left;
     308
     309    if (flags & TBS_TOP)
     310    {
     311      y = infoPtr->rcFullThumb.top-SCALE_SPACE-1;
     312      side = -1;
     313    } else
     314    {
     315      y = infoPtr->rcFullThumb.bottom+SCALE_SPACE+1;
     316      side = 1;
     317    }
     318    if (flags & TIC_SELECTIONMARK)
     319    {
     320      ticPos -= infoPtr->nRangeMin; //relative to nRangeMin
     321      if (flags & TIC_SELECTIONMARKMIN) x = rcChannel.left+(width*ticPos)/range - 1;
     322      else x = rcChannel.left+(width*ticPos)/range+1;
     323
     324      //first line
     325      SetPixel(hdc,x,y+1*side,clrTic);
     326      SetPixel(hdc,x,y+2*side,clrTic);
     327      //point
     328      if (flags & TIC_SELECTIONMARKMIN) x--; else x++;
     329      SetPixel(hdc,x,y+2*side,clrTic);
     330
     331      return;
     332    }
     333
     334    if ((ticPos > infoPtr->nRangeMin) && (ticPos < infoPtr->nRangeMax))
     335    {
     336      ticPos -= infoPtr->nRangeMin; //relative to nRangeMin
     337      x = rcChannel.left+(width*ticPos)/range;
     338      SetPixel(hdc,x,y,clrTic); //base
     339      SetPixel(hdc,x,y+1*side,clrTic);
     340      SetPixel(hdc,x,y+2*side,clrTic);
     341    }
     342
     343    if (flags & TIC_EDGE)
     344    {
     345      if (flags & TIC_LEFTEDGE) x = rcChannel.left;
     346      else x = rcChannel.right;
     347
     348      SetPixel(hdc,x,y,clrTic); //base
     349      SetPixel(hdc,x,y+1*side,clrTic);
     350      SetPixel(hdc,x,y+2*side,clrTic);
     351      SetPixel(hdc,x,y+3*side,clrTic);
     352    }
    272353}
    273354
     
    276357                      int flags, COLORREF clrTic)
    277358{
    278     RECT rcChannel=infoPtr->rcChannel;
     359    RECT rcChannel = infoPtr->rcChannel;
    279360    int x,y,width,range,side;
    280361
    281     range=infoPtr->nRangeMax - infoPtr->nRangeMin;
    282     width=rcChannel.bottom - rcChannel.top;
    283 
    284     if (flags & TBS_TOP) {
    285         x=rcChannel.right-2;
    286         side=-1;
    287     } else {
    288         x=rcChannel.left+2;
    289         side=1;
    290     }
    291 
    292 
    293     if (flags & TIC_SELECTIONMARK) {
    294         if (flags & TIC_SELECTIONMARKMIN)
    295             y=rcChannel.top + (width*ticPos)/range - 1;
    296         else
    297             y=rcChannel.top + (width*ticPos)/range + 1;
    298 
    299         SetPixel (hdc, x+6*side, y, clrTic);
    300         SetPixel (hdc, x+7*side, y, clrTic);
    301         return;
    302     }
    303 
    304     if ((ticPos>infoPtr->nRangeMin) && (ticPos<infoPtr->nRangeMax)) {
    305         y=rcChannel.top + (width*ticPos)/range;
    306         SetPixel (hdc, x+5*side, y, clrTic);
    307         SetPixel (hdc, x+6*side, y, clrTic);
    308         SetPixel (hdc, x+7*side, y, clrTic);
    309     }
    310 
    311     if (flags & TIC_EDGE) {
    312         if (flags & TIC_LEFTEDGE)
    313             y=rcChannel.top;
    314         else
    315             y=rcChannel.bottom;
    316 
    317         SetPixel (hdc, x+5*side, y, clrTic);
    318         SetPixel (hdc, x+6*side, y, clrTic);
    319         SetPixel (hdc, x+7*side, y, clrTic);
    320         SetPixel (hdc, x+8*side, y, clrTic);
    321     }
    322 
     362    range = infoPtr->nRangeMax-infoPtr->nRangeMin;
     363    width = rcChannel.bottom-rcChannel.top;
     364
     365    if (flags & TBS_LEFT)
     366    {
     367      x = infoPtr->rcFullThumb.left-SCALE_SPACE-1;
     368      side = -1;
     369    } else
     370    {
     371      x = infoPtr->rcFullThumb.right+SCALE_SPACE+1;
     372      side = 1;
     373    }
     374
     375
     376    if (flags & TIC_SELECTIONMARK)
     377    {
     378      ticPos -= infoPtr->nRangeMin;
     379      if (flags & TIC_SELECTIONMARKMIN) y = rcChannel.top+(width*ticPos)/range-1;
     380      else y = rcChannel.top+(width*ticPos)/range+1;
     381
     382      //first line
     383      SetPixel(hdc,x+1*side,y,clrTic);
     384      SetPixel(hdc,x+2*side,y,clrTic);
     385      //point
     386      if (flags & TIC_SELECTIONMARKMIN) y--; else y++;
     387      SetPixel(hdc,x+2*side,y,clrTic);
     388
     389      return;
     390    }
     391
     392    if ((ticPos>infoPtr->nRangeMin) && (ticPos<infoPtr->nRangeMax))
     393    {
     394      ticPos -= infoPtr->nRangeMin;
     395      y = rcChannel.top+(width*ticPos)/range;
     396      SetPixel (hdc,x, y,clrTic); //base
     397      SetPixel (hdc,x+1*side,y,clrTic);
     398      SetPixel (hdc,x+2*side,y,clrTic);
     399    }
     400
     401    if (flags & TIC_EDGE)
     402    {
     403      if (flags & TIC_LEFTEDGE) y = rcChannel.top;
     404      else y = rcChannel.bottom;
     405
     406      SetPixel (hdc,x,y,clrTic); //base
     407      SetPixel (hdc,x+1*side,y,clrTic);
     408      SetPixel (hdc,x+2*side,y,clrTic);
     409      SetPixel (hdc,x+3*side,y,clrTic);
     410    }
    323411}
    324412
     
    328416                   int flags, COLORREF clrTic)
    329417{
    330 
    331     if (flags & TBS_VERT) {
    332         if ((flags & TBS_TOP) || (flags & TBS_BOTH))
    333             TRACKBAR_DrawVertTic (infoPtr, hdc, ticPos,
    334                                   flags | TBS_TOP , clrTic);
    335         if (!(flags & TBS_TOP) || (flags & TBS_BOTH))
    336             TRACKBAR_DrawVertTic (infoPtr, hdc, ticPos, flags, clrTic);
    337         return;
    338     }
    339 
    340     if ((flags & TBS_TOP) || (flags & TBS_BOTH))
    341         TRACKBAR_DrawHorizTic (infoPtr, hdc, ticPos, flags | TBS_TOP , clrTic);
    342 
    343     if (!(flags & TBS_TOP) || (flags & TBS_BOTH))
    344         TRACKBAR_DrawHorizTic (infoPtr, hdc, ticPos, flags, clrTic);
    345 
     418    if (flags & TBS_VERT)
     419    {
     420        if ((flags & TBS_LEFT) || (flags & TBS_BOTH))
     421            TRACKBAR_DrawVertTic (infoPtr,hdc,ticPos,flags | TBS_LEFT ,clrTic);
     422        //TBS_RIGHT == default
     423        if (!(flags & TBS_LEFT) || (flags & TBS_BOTH))
     424            TRACKBAR_DrawVertTic(infoPtr,hdc,ticPos,flags & ~TBS_LEFT,clrTic);
     425    } else
     426    {
     427      if ((flags & TBS_TOP) || (flags & TBS_BOTH))
     428        TRACKBAR_DrawHorizTic(infoPtr,hdc,ticPos,flags | TBS_TOP,clrTic);
     429      //TBS_BOTTOM == default
     430      if (!(flags & TBS_TOP) || (flags & TBS_BOTH))
     431        TRACKBAR_DrawHorizTic(infoPtr,hdc,ticPos,flags & ~TBS_TOP,clrTic);
     432    }
     433}
     434
     435//draw thumb, call only from draw!
     436
     437static VOID TRACKBAR_DrawThumb(TRACKBAR_INFO *infoPtr,HDC hdc,DWORD dwStyle)
     438{
     439    if (!(dwStyle & TBS_NOTHUMB))
     440    {
     441
     442      HBRUSH hbr,hbrOld;
     443      RECT thumb = infoPtr->rcThumb;
     444
     445      if (infoPtr->flags & TB_DRAG_MODE) hbr = CreateSolidBrush(GetSysColor(COLOR_3DHILIGHT));
     446      else hbr = CreateSolidBrush(GetSysColor(COLOR_3DFACE));
     447      hbrOld = SelectObject(hdc,hbr);
     448
     449      if (dwStyle & TBS_BOTH)
     450      {
     451        DrawEdge (hdc,&thumb,EDGE_RAISED,BF_RECT | BF_ADJUST);
     452        FillRect (hdc,&thumb,hbr);
     453      } else
     454      {
     455
     456        POINT points[6];
     457        RECT triangle;  /* for correct shadows of thumb */
     458
     459        if (dwStyle & TBS_VERT)
     460        { //Vertical
     461
     462          if (dwStyle & TBS_LEFT)
     463          {
     464            //Outline
     465
     466            SetPolyFillMode(hdc,WINDING);
     467            points[0].x = thumb.left;
     468            points[0].y = thumb.top;
     469            points[1].x = thumb.left-(thumb.bottom-thumb.top)/2;
     470            points[1].y = thumb.top+(thumb.bottom-thumb.top)/2;
     471            points[2].x = thumb.left;
     472            points[2].y = thumb.bottom;
     473            points[3].x = thumb.right;
     474            points[3].y = thumb.bottom;
     475            points[4].x = thumb.right;
     476            points[4].y = thumb.top;
     477            points[5].x = points[0].x;
     478            points[5].y = points[0].y;
     479            Polygon (hdc,points,6);
     480
     481            //Edge
     482
     483            thumb.bottom++;
     484            thumb.right++;
     485            DrawEdge(hdc,&thumb,EDGE_RAISED,BF_BOTTOM | BF_TOP | BF_RIGHT);
     486
     487            //Draw notch
     488
     489            triangle.right = points[0].x-1;
     490            triangle.top = points[0].y+1+1;
     491            triangle.left = points[1].x;
     492            triangle.bottom = points[1].y+1; //Odin32 fix
     493            DrawEdge(hdc,&triangle,EDGE_SUNKEN,BF_DIAGONAL | BF_DIAGONAL_ENDBOTTOMLEFT);
     494            triangle.right = points[2].x;
     495            triangle.bottom = points[2].y;
     496            triangle.left = points[1].x;
     497            triangle.top = points[1].y; //Odin32 bug: wrong lines
     498            DrawEdge(hdc,&triangle,EDGE_SUNKEN,BF_DIAGONAL | BF_DIAGONAL_ENDTOPLEFT);
     499
     500
     501          } else //Right
     502          {
     503            //Outline
     504
     505            SetPolyFillMode(hdc,WINDING);
     506            points[0].x = thumb.left;
     507            points[0].y = thumb.top;
     508            points[1].x = thumb.left;
     509            points[1].y = thumb.bottom;
     510            points[2].x = thumb.right;
     511            points[2].y = thumb.bottom;
     512            points[3].x = thumb.right+(thumb.bottom-thumb.top)/2;
     513            points[3].y = thumb.bottom-(thumb.bottom-thumb.top)/2;
     514            points[4].x = thumb.right;
     515            points[4].y = thumb.top;
     516            points[5].x = points[0].x;
     517            points[5].y = points[0].y;
     518            Polygon (hdc,points,6);
     519
     520            //Edge
     521
     522            thumb.bottom++;
     523            DrawEdge(hdc,&thumb,EDGE_RAISED,BF_BOTTOM | BF_TOP | BF_LEFT);
     524
     525            //Draw notch
     526
     527            triangle.left = points[4].x;
     528            triangle.top = points[4].y;
     529            triangle.right = points[3].x;
     530            triangle.bottom = points[3].y;
     531            DrawEdge(hdc,&triangle,EDGE_SUNKEN,BF_DIAGONAL | BF_DIAGONAL_ENDBOTTOMRIGHT);
     532            triangle.left = points[2].x;
     533            triangle.bottom = points[2].y;
     534            triangle.right = points[3].x;
     535            triangle.top = points[3].y; //Odin32: pixel bug
     536            DrawEdge(hdc,&triangle,EDGE_SUNKEN,BF_DIAGONAL | BF_DIAGONAL_ENDTOPRIGHT);
     537          }
     538        } else
     539        { //Horizontal
     540
     541          if (dwStyle & TBS_TOP)
     542          {
     543            //Outline
     544
     545            SetPolyFillMode(hdc,WINDING);
     546            points[0].x = thumb.left;
     547            points[0].y = thumb.top;
     548            points[1].x = thumb.left+(thumb.right-thumb.left)/2;
     549            points[1].y = thumb.top-(thumb.right-thumb.left)/2;
     550            points[2].x = thumb.right;
     551            points[2].y = thumb.top;
     552            points[3].x = thumb.right;
     553            points[3].y = thumb.bottom;
     554            points[4].x = thumb.left;
     555            points[4].y = thumb.bottom;
     556            points[5].x = points[0].x;
     557            points[5].y = points[0].y;
     558            Polygon (hdc,points,6);
     559
     560            //Edge
     561
     562            thumb.right++;
     563            thumb.bottom++;
     564            DrawEdge(hdc,&thumb,EDGE_RAISED,BF_BOTTOM | BF_LEFT | BF_RIGHT);
     565
     566            //Draw notch
     567
     568            triangle.left = points[0].x;
     569            triangle.bottom = points[0].y;
     570            triangle.right = points[1].x;
     571            triangle.top = points[1].y;
     572            DrawEdge(hdc,&triangle,EDGE_RAISED,BF_DIAGONAL | BF_DIAGONAL_ENDTOPRIGHT);
     573            triangle.right = points[1].x;
     574            triangle.bottom = points[1].y;
     575            triangle.left = points[2].x-1;
     576            triangle.top = points[2].y-1;
     577            DrawEdge(hdc,&triangle,EDGE_SUNKEN,BF_DIAGONAL | BF_DIAGONAL_ENDTOPLEFT);
     578
     579          } else //Bottom
     580          {
     581
     582            //Outline
     583
     584            SetPolyFillMode(hdc,WINDING);
     585            points[0].x = thumb.left;
     586            points[0].y = thumb.top;
     587            points[1].x = thumb.right;
     588            points[1].y = thumb.top;
     589            points[2].x = thumb.right;
     590            points[2].y = thumb.bottom;
     591            points[3].x = thumb.right-(thumb.right-thumb.left)/2;
     592            points[3].y = thumb.bottom+(thumb.right-thumb.left)/2;
     593            points[4].x = thumb.left;
     594            points[4].y = thumb.bottom;
     595            points[5].x = points[0].x;
     596            points[5].y = points[0].y;
     597            Polygon (hdc,points,6);
     598
     599            //Edge
     600
     601            thumb.right++;
     602            thumb.bottom++;
     603            DrawEdge(hdc,&thumb,EDGE_RAISED,BF_TOP | BF_LEFT | BF_RIGHT);
     604
     605            //Draw notch
     606
     607            triangle.left = points[4].x;
     608            triangle.top = points[4].y; //Odin32: wrong pixel at .y-1!
     609            triangle.right = points[3].x;
     610            triangle.bottom = points[3].y;
     611            DrawEdge(hdc,&triangle,EDGE_SUNKEN,BF_DIAGONAL | BF_DIAGONAL_ENDBOTTOMRIGHT);
     612            triangle.left = points[3].x-1; //Odin32: wrong pixel at .x-2!
     613            triangle.bottom = points[3].y+1;
     614            triangle.right = points[2].x-1;
     615            triangle.top = points[2].y+1;
     616            DrawEdge(hdc,&triangle,EDGE_SUNKEN,BF_DIAGONAL | BF_DIAGONAL_ENDTOPRIGHT);
     617
     618          }
     619        }
     620      }
     621      SelectObject(hdc,hbrOld);
     622      DeleteObject(hbr);
     623    }
    346624}
    347625
    348626//draw the trackbar
    349627
    350 static VOID TRACKBAR_Draw(HWND hwnd,HDC hdc,INT lastPos,BOOL inUpdate)
     628static VOID TRACKBAR_Draw(HWND hwnd,HDC hdc)
    351629{
    352630    TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
     
    357635
    358636    GetClientRect (hwnd, &rcClient);
    359     if (!inUpdate)
    360     {
    361       hBrush = CreateSolidBrush (infoPtr->clrBk);
    362       FillRect (hdc, &rcClient, hBrush);
    363       DeleteObject (hBrush);
    364     }
    365 
    366     if (infoPtr->flags & TB_DRAGPOSVALID)  {
    367         infoPtr->nPos=infoPtr->dragPos;
    368         infoPtr->flags |= TB_THUMBPOSCHANGED;
    369     }
    370 
    371     if (infoPtr->flags & TB_THUMBCHANGED) {
    372         TRACKBAR_CalcThumb      (hwnd, infoPtr);
    373         if (infoPtr->flags & TB_THUMBSIZECHANGED)
    374             TRACKBAR_CalcChannel (hwnd, infoPtr);
    375     }
    376     if (infoPtr->flags & TB_SELECTIONCHANGED)
    377         TRACKBAR_CalcSelection (hwnd, infoPtr);
    378     infoPtr->flags &= ~ (TB_THUMBCHANGED | TB_SELECTIONCHANGED |
    379                          TB_DRAGPOSVALID);
     637
     638    //Background
     639    hBrush = CreateSolidBrush(infoPtr->clrBk);
     640    FillRect(hdc,&rcClient,hBrush);
     641    DeleteObject(hBrush);
     642
     643    if (infoPtr->flags & TB_DRAGPOSVALID)
     644    {
     645      infoPtr->nPos = infoPtr->dragPos;
     646      infoPtr->flags |= TB_THUMBPOSCHANGED;
     647    }
     648
     649    if (infoPtr->flags & TB_THUMBCHANGED)
     650    {
     651      TRACKBAR_CalcThumb(hwnd,infoPtr);
     652      if (infoPtr->flags & TB_THUMBSIZECHANGED) TRACKBAR_CalcChannel(hwnd,infoPtr);
     653    }
     654    if (infoPtr->flags & TB_SELECTIONCHANGED) TRACKBAR_CalcSelection(hwnd,infoPtr);
     655    infoPtr->flags &= ~ (TB_THUMBCHANGED | TB_SELECTIONCHANGED | TB_DRAGPOSVALID);
    380656
    381657    /* draw channel */
    382658
    383659    rcChannel = infoPtr->rcChannel;
    384     rcSelection= infoPtr->rcSelection;
    385     DrawEdge (hdc, &rcChannel, EDGE_SUNKEN, BF_RECT | BF_ADJUST);
    386 
    387     if (dwStyle & TBS_ENABLESELRANGE) {          /* fill the channel */
    388         HBRUSH hbr = CreateSolidBrush (RGB(255,255,255));
    389         FillRect (hdc, &rcChannel, hbr);
    390         if (((dwStyle & TBS_VERT) &&
    391              (rcSelection.left!=rcSelection.right)) ||
    392             ((!(dwStyle & TBS_VERT)) &&
    393              (rcSelection.left!=rcSelection.right))) {
    394             hbr=CreateSolidBrush (COLOR_HIGHLIGHT);
    395             FillRect (hdc, &rcSelection, hbr);
    396         }
    397         DeleteObject (hbr);
    398     }
    399 
     660    rcSelection = infoPtr->rcSelection;
     661    DrawEdge (hdc,&rcChannel,EDGE_SUNKEN,BF_RECT | BF_ADJUST);
     662
     663    if (dwStyle & TBS_ENABLESELRANGE)           /* fill the channel */
     664    {
     665      HBRUSH hbr = CreateSolidBrush(RGB(255,255,255));
     666      FillRect(hdc,&rcChannel,hbr);
     667      DeleteObject(hbr);
     668      if (((dwStyle & TBS_VERT) && (rcSelection.top != rcSelection.bottom)) ||
     669         ((!(dwStyle & TBS_VERT)) && (rcSelection.left != rcSelection.right)))
     670         {
     671           hbr = CreateSolidBrush (COLOR_HIGHLIGHT);
     672           FillRect (hdc,&rcSelection,hbr);
     673           DeleteObject(hbr);
     674         }
     675    }
    400676
    401677    /* draw tics */
    402678
    403     if (!(dwStyle & TBS_NOTICKS)) {
    404         int ticFlags = dwStyle & 0x0f;
    405         COLORREF clrTic=GetSysColor (COLOR_3DDKSHADOW);
    406 
    407         for (i=0; i<infoPtr->uNumTics; i++)
    408             TRACKBAR_DrawTics (infoPtr, hdc, infoPtr->tics[i],
    409                                ticFlags, clrTic);
    410 
    411         TRACKBAR_DrawTics (infoPtr, hdc, 0, ticFlags | TIC_LEFTEDGE, clrTic);
    412         TRACKBAR_DrawTics (infoPtr, hdc, 0, ticFlags | TIC_RIGHTEDGE, clrTic);
    413 
    414         if ((dwStyle & TBS_ENABLESELRANGE) &&
    415             (rcSelection.left!=rcSelection.right)) {
    416             TRACKBAR_DrawTics (infoPtr, hdc, infoPtr->nSelMin,
    417                                ticFlags | TIC_SELECTIONMARKMIN, clrTic);
    418             TRACKBAR_DrawTics (infoPtr, hdc, infoPtr->nSelMax,
    419                                ticFlags | TIC_SELECTIONMARKMAX, clrTic);
    420         }
     679    if (!(dwStyle & TBS_NOTICKS))
     680    {
     681      int ticFlags = dwStyle & 0x0f;
     682      COLORREF clrTic = GetSysColor(COLOR_3DDKSHADOW);
     683
     684      for (i = 0;i < infoPtr->uNumTics;i++)
     685          TRACKBAR_DrawTics(infoPtr,hdc,infoPtr->tics[i],ticFlags,clrTic);
     686
     687      TRACKBAR_DrawTics(infoPtr,hdc,0,ticFlags | TIC_LEFTEDGE,clrTic);
     688      TRACKBAR_DrawTics(infoPtr,hdc,0,ticFlags | TIC_RIGHTEDGE,clrTic);
     689
     690      if ((dwStyle & TBS_ENABLESELRANGE) &&
     691            ((dwStyle & TBS_VERT && rcSelection.bottom != rcSelection.top) ||
     692            (!(dwStyle & TBS_VERT) && rcSelection.left != rcSelection.right)))
     693            {
     694              TRACKBAR_DrawTics(infoPtr,hdc,infoPtr->nSelMin,ticFlags | TIC_SELECTIONMARKMIN,clrTic);
     695              TRACKBAR_DrawTics(infoPtr,hdc,infoPtr->nSelMax,ticFlags | TIC_SELECTIONMARKMAX,clrTic);
     696            }
    421697    }
    422698
    423699    /* draw thumb */
    424700
    425     if (!(dwStyle & TBS_NOTHUMB)) {
    426 
    427         HBRUSH hbr = CreateSolidBrush (COLOR_BACKGROUND);
    428         RECT thumb = infoPtr->rcThumb;
    429 
    430         SelectObject (hdc, hbr);
    431 
    432         if (dwStyle & TBS_BOTH) {
    433             FillRect (hdc, &thumb, hbr);
    434             DrawEdge (hdc, &thumb, EDGE_RAISED, BF_TOPLEFT);
    435         } else {
    436 
    437             POINT points[6];
    438 
    439             /* first, fill the thumb */
    440             /* FIXME: revamp. check for TBS_VERT */
    441 
    442             SetPolyFillMode (hdc,WINDING);
    443             points[0].x=thumb.left;
    444             points[0].y=thumb.top;
    445             points[1].x=thumb.right - 1;
    446             points[1].y=thumb.top;
    447             points[2].x=thumb.right - 1;
    448             points[2].y=thumb.bottom -2;
    449             points[3].x=(thumb.right + thumb.left-1)/2;
    450             points[3].y=thumb.bottom+4;
    451             points[4].x=thumb.left;
    452             points[4].y=thumb.bottom -2;
    453             points[5].x=points[0].x;
    454             points[5].y=points[0].y;
    455             Polygon (hdc, points, 6);
    456 
    457             if (dwStyle & TBS_VERT) {
    458                 /*   draw edge  */
    459             } else {
    460                 RECT triangle;  /* for correct shadows of thumb */
    461                 DrawEdge (hdc, &thumb, EDGE_RAISED, BF_TOPLEFT);
    462 
    463                 /* draw notch */
    464 
    465                 triangle.right = thumb.right+5;
    466                 triangle.left  = points[3].x+5;
    467                 triangle.top   = thumb.bottom +5;
    468                 triangle.bottom= thumb.bottom +1;
    469                 DrawEdge (hdc, &triangle, EDGE_SUNKEN,
    470                           BF_DIAGONAL | BF_TOP | BF_RIGHT);
    471                 triangle.left  = thumb.left+6;
    472                 triangle.right = points[3].x+6;
    473                 DrawEdge (hdc, &triangle, EDGE_RAISED,
    474                           BF_DIAGONAL | BF_TOP | BF_LEFT);
    475             }
    476         }
    477         DeleteObject (hbr);
    478     }
    479 
    480     if (infoPtr->bFocus)
    481         DrawFocusRect (hdc, &rcClient);
    482 }
    483 
    484 //update display
    485 
    486 static VOID TRACKBAR_Update(HWND hwnd,INT lastPos)
    487 {
     701    TRACKBAR_DrawThumb(infoPtr,hdc,dwStyle);
     702
     703    if (infoPtr->bFocus) DrawFocusRect(hdc,&rcClient);
     704}
     705
     706//update thumb position
     707
     708static VOID TRACKBAR_UpdateThumbPosition(HWND hwnd,INT lastPos)
     709{
     710   HDC hdc;
     711   TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(hwnd);
     712   DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
     713   RECT lastRect,newRect;
     714   HRGN hrgn,hrgnLast,hrgnNew;
     715
     716   if (dwStyle & TBS_NOTHUMB) return;
     717
     718   //last
     719   lastRect = infoPtr->rcFullThumb;
     720
     721   //new
     722   if (infoPtr->flags & TB_DRAGPOSVALID) infoPtr->nPos = infoPtr->dragPos;
     723   if (infoPtr->nPos == lastPos) return;
     724
     725   TRACKBAR_CalcThumb(hwnd,infoPtr);
     726   infoPtr->flags &= ~TB_THUMBCHANGED;
     727   newRect = infoPtr->rcFullThumb;
     728
     729
     730   //3D frame adjustation
     731   lastRect.right++;
     732   lastRect.bottom++;
     733   newRect.right++;
     734   newRect.bottom++;
     735   //Odin32 pixel bugs
     736   lastRect.top--;
     737   lastRect.left--;
     738   newRect.top--;
     739   newRect.left--;
     740
     741   hdc = GetDC(hwnd);
     742   hrgnLast = CreateRectRgnIndirect(&lastRect);
     743   hrgnNew = CreateRectRgnIndirect(&newRect);
     744   hrgn = CreateRectRgn(0,0,0,0);
     745   CombineRgn(hrgn,hrgnLast,hrgnNew,RGN_OR);
     746   SelectClipRgn(hdc,hrgn);
     747   TRACKBAR_Draw(hwnd,hdc);
     748   SelectClipRgn(hdc,0);
     749   DeleteObject(hrgnLast);
     750   DeleteObject(hrgnNew);
     751   DeleteObject(hrgn);
     752   ReleaseDC(hwnd,hdc);
     753}
     754
     755//redraw thumb at same position
     756
     757static VOID TRACKBAR_UpdateThumb(HWND hwnd)
     758{
     759   HDC hdc;
    488760   TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
     761   DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
     762   HRGN hrgn;
     763
     764   if (dwStyle & TBS_NOTHUMB) return;
     765
     766   hdc = GetDC(hwnd);
     767   hrgn = CreateRectRgnIndirect(&infoPtr->rcFullThumb);
     768   SelectClipRgn(hdc,hrgn);
     769   TRACKBAR_Draw(hwnd,hdc);
     770   SelectClipRgn(hdc,0);
     771   DeleteObject(hrgn);
     772   ReleaseDC(hwnd,hdc);
     773}
     774
     775//redraw everything
     776
     777static VOID TRACKBAR_Refresh (HWND hwnd)
     778{
    489779   HDC hdc;
    490780
    491    if (infoPtr->flags & TB_DRAGPOSVALID && lastPos == infoPtr->dragPos) return;
    492    if (!infoPtr->flags & TB_DRAGPOSVALID && lastPos == infoPtr->nPos) return;
    493    hdc = GetDC(hwnd);
    494    TRACKBAR_Draw(hwnd,hdc,lastPos,TRUE);
    495    ReleaseDC(hwnd,hdc);
    496 }
    497 
    498 //redraw everything
    499 
    500 static VOID TRACKBAR_Refresh (HWND hwnd)
    501 {
    502    HDC hdc;
    503 
    504781   hdc = GetDC (hwnd);
    505    TRACKBAR_Draw(hwnd,hdc,0,FALSE);
     782   TRACKBAR_Draw(hwnd,hdc);
    506783   ReleaseDC(hwnd,hdc);
    507784}
     
    565842    TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
    566843
    567     infoPtr->nSelMin = 0;
    568     infoPtr->nSelMax = 0;
    569     infoPtr->flags |= TB_SELECTIONCHANGED;
    570 
    571     if ((BOOL)wParam) TRACKBAR_Refresh(hwnd);
     844    if (infoPtr->nSelMin != infoPtr->nSelMax)
     845    {
     846      infoPtr->nSelMin = 0;
     847      infoPtr->nSelMax = 0;
     848      infoPtr->flags |= TB_SELECTIONCHANGED;
     849
     850      if ((BOOL)wParam) TRACKBAR_Refresh(hwnd);
     851    }
    572852
    573853    return 0;
     
    580860    TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
    581861
    582     if (infoPtr->tics) {
    583         COMCTL32_Free (infoPtr->tics);
    584         infoPtr->tics = NULL;
    585         infoPtr->uNumTics = 0;
    586     }
    587 
    588     if (wParam) TRACKBAR_Refresh(hwnd);
     862    if (!(GetWindowLongA(hwnd, GWL_STYLE) & (TBS_AUTOTICKS | TBS_NOTICKS))) return 0;
     863
     864    if (infoPtr->tics)
     865    {
     866      COMCTL32_Free(infoPtr->tics);
     867      infoPtr->tics = NULL;
     868      infoPtr->uNumTics = 0;
     869
     870      if (wParam) TRACKBAR_Refresh(hwnd);
     871    }
    589872
    590873    return 0;
     
    611894    LPRECT lprc = (LPRECT)lParam;
    612895
    613     if (lprc == NULL)
    614         return 0;
    615 
    616     lprc->left   = infoPtr->rcChannel.left;
    617     lprc->right  = infoPtr->rcChannel.right;
    618     lprc->bottom = infoPtr->rcChannel.bottom;
    619     lprc->top    = infoPtr->rcChannel.top;
     896    if (lprc == NULL) return 0;
     897
     898    CopyRect(lprc,&infoPtr->rcChannel);
    620899
    621900    return 0;
     
    637916    TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
    638917
    639     if (GetWindowLongA (hwnd, GWL_STYLE) & TBS_NOTICKS)
    640         return 0;
    641 
    642     return infoPtr->uNumTics+2;
     918    if (GetWindowLongA(hwnd, GWL_STYLE) & TBS_NOTICKS) return 0;
     919
     920    return infoPtr->uNumTics+2; //includes last and first tick
    643921}
    644922
     
    711989    TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
    712990
    713     return (LRESULT) infoPtr->tics;
     991    return (LRESULT)infoPtr->tics;
    714992}
    715993
     
    720998    LPRECT lprc = (LPRECT)lParam;
    721999
    722     if (lprc == NULL)
    723         return 0;
    724 
    725     lprc->left   = infoPtr->rcThumb.left;
    726     lprc->right  = infoPtr->rcThumb.right;
    727     lprc->bottom = infoPtr->rcThumb.bottom;
    728     lprc->top    = infoPtr->rcThumb.top;
     1000    if (lprc == NULL) return 0;
     1001
     1002    CopyRect(lprc,&infoPtr->rcFullThumb);
    7291003
    7301004    return 0;
     
    7381012    INT iTic;
    7391013
    740     iTic=(INT) wParam;
    741     if ((iTic<0) || (iTic>infoPtr->uNumTics))
    742         return -1;
    743 
    744     return (LRESULT) infoPtr->tics[iTic];
     1014    iTic = (INT)wParam;
     1015    if ((iTic < 0) || (iTic > infoPtr->uNumTics)) return -1;
     1016
     1017    return (LRESULT)infoPtr->tics[iTic];
    7451018
    7461019}
     
    7541027
    7551028
    756     iTic=(INT ) wParam;
    757     if ((iTic<0) || (iTic>infoPtr->uNumTics))
    758         return -1;
    759 
    760     range=infoPtr->nRangeMax - infoPtr->nRangeMin;
    761     width=infoPtr->rcChannel.right - infoPtr->rcChannel.left;
    762     pos=infoPtr->rcChannel.left + (width * infoPtr->tics[iTic]) / range;
    763 
     1029    iTic = (INT)wParam;
     1030    if ((iTic < 0) || (iTic > infoPtr->uNumTics)) return -1;
     1031
     1032    range = infoPtr->nRangeMax-infoPtr->nRangeMin;
     1033    width = infoPtr->rcChannel.right-infoPtr->rcChannel.left;
     1034    pos = infoPtr->rcChannel.left+(width*(infoPtr->tics[iTic]-infoPtr->nRangeMin))/range;
    7641035
    7651036    return (LRESULT) pos;
     
    8361107{
    8371108    TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
    838 
    8391109    INT lastPos = infoPtr->nPos;
     1110
    8401111    infoPtr->nPos = (INT)LOWORD(lParam);
     1112
     1113    if (lastPos == infoPtr->nPos) return 0; //nothing changed
    8411114
    8421115    if (infoPtr->nPos < infoPtr->nRangeMin)
     
    8471120    infoPtr->flags |= TB_THUMBPOSCHANGED;
    8481121
    849     if (wParam) TRACKBAR_Update(hwnd,lastPos);
     1122    if (wParam) TRACKBAR_UpdateThumbPosition(hwnd,lastPos);
    8501123
    8511124    return 0;
     
    8571130{
    8581131    TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
    859     infoPtr->nRangeMin = (INT)LOWORD(lParam);
    860     infoPtr->nRangeMax = (INT)HIWORD(lParam);
    861 
    862     if (infoPtr->nPos < infoPtr->nRangeMin) {
     1132    int newMin,newMax;
     1133    newMin = (INT)LOWORD(lParam);
     1134    newMax = (INT)HIWORD(lParam);
     1135
     1136    if (newMin == infoPtr->nRangeMin && newMax == infoPtr->nRangeMax) return 0;
     1137
     1138    infoPtr->nRangeMin = newMin;
     1139    infoPtr->nRangeMax = newMax;
     1140
     1141    if (infoPtr->nPos < infoPtr->nRangeMin)
     1142    {
     1143        infoPtr->nPos = infoPtr->nRangeMin;
     1144        infoPtr->flags |= TB_THUMBPOSCHANGED;
     1145    }
     1146
     1147    if (infoPtr->nPos > infoPtr->nRangeMax)
     1148    {
     1149        infoPtr->nPos = infoPtr->nRangeMax;
     1150        infoPtr->flags |= TB_THUMBPOSCHANGED;
     1151    }
     1152
     1153    infoPtr->nPageSize = (infoPtr->nRangeMax-infoPtr->nRangeMin)/5;
     1154    if (infoPtr->nPageSize == 0) infoPtr->nPageSize = 1;
     1155    TRACKBAR_RecalculateTics(hwnd,infoPtr,TRUE);
     1156
     1157    if (wParam) TRACKBAR_Refresh(hwnd);
     1158
     1159    return 0;
     1160}
     1161
     1162
     1163static LRESULT
     1164TRACKBAR_SetRangeMax (HWND hwnd, WPARAM wParam, LPARAM lParam)
     1165{
     1166    TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
     1167
     1168    if (infoPtr->nRangeMax == (INT)lParam) return 0;
     1169
     1170    infoPtr->nRangeMax = (INT)lParam;
     1171    if (infoPtr->nPos > infoPtr->nRangeMax)
     1172    {
     1173        infoPtr->nPos = infoPtr->nRangeMax;
     1174        infoPtr->flags |=TB_THUMBPOSCHANGED;
     1175    }
     1176
     1177    infoPtr->nPageSize = (infoPtr->nRangeMax-infoPtr->nRangeMin)/5;
     1178    if (infoPtr->nPageSize == 0) infoPtr->nPageSize = 1;
     1179    TRACKBAR_RecalculateTics(hwnd,infoPtr,TRUE);
     1180
     1181    if (wParam) TRACKBAR_Refresh(hwnd);
     1182
     1183    return 0;
     1184}
     1185
     1186
     1187static LRESULT
     1188TRACKBAR_SetRangeMin (HWND hwnd, WPARAM wParam, LPARAM lParam)
     1189{
     1190    TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
     1191
     1192    if (infoPtr->nRangeMin == (INT)lParam) return 0;
     1193
     1194    infoPtr->nRangeMin = (INT)lParam;
     1195    if (infoPtr->nPos < infoPtr->nRangeMin)
     1196    {
    8631197        infoPtr->nPos = infoPtr->nRangeMin;
    8641198        infoPtr->flags |=TB_THUMBPOSCHANGED;
    8651199    }
    8661200
    867     if (infoPtr->nPos > infoPtr->nRangeMax) {
    868         infoPtr->nPos = infoPtr->nRangeMax;
    869         infoPtr->flags |=TB_THUMBPOSCHANGED;
    870     }
    871 
    872     infoPtr->nPageSize=(infoPtr->nRangeMax -  infoPtr->nRangeMin)/5;
    873     if (infoPtr->nPageSize == 0)
    874         infoPtr->nPageSize = 1;
    875     TRACKBAR_RecalculateTics (infoPtr);
     1201    infoPtr->nPageSize = (infoPtr->nRangeMax-infoPtr->nRangeMin)/5;
     1202    if (infoPtr->nPageSize == 0) infoPtr->nPageSize = 1;
     1203    TRACKBAR_RecalculateTics(hwnd,infoPtr,TRUE);
    8761204
    8771205    if (wParam) TRACKBAR_Refresh(hwnd);
     
    8821210
    8831211static LRESULT
    884 TRACKBAR_SetRangeMax (HWND hwnd, WPARAM wParam, LPARAM lParam)
    885 {
    886     TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
    887 
    888     infoPtr->nRangeMax = (INT)lParam;
    889     if (infoPtr->nPos > infoPtr->nRangeMax) {
    890         infoPtr->nPos = infoPtr->nRangeMax;
    891         infoPtr->flags |=TB_THUMBPOSCHANGED;
    892     }
    893 
    894     infoPtr->nPageSize=(infoPtr->nRangeMax -  infoPtr->nRangeMin)/5;
    895     if (infoPtr->nPageSize == 0)
    896         infoPtr->nPageSize = 1;
    897     TRACKBAR_RecalculateTics (infoPtr);
    898 
    899     if (wParam) TRACKBAR_Refresh(hwnd);
    900 
    901     return 0;
    902 }
    903 
    904 
    905 static LRESULT
    906 TRACKBAR_SetRangeMin (HWND hwnd, WPARAM wParam, LPARAM lParam)
    907 {
    908     TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
    909 
    910     infoPtr->nRangeMin = (INT)lParam;
    911     if (infoPtr->nPos < infoPtr->nRangeMin) {
    912         infoPtr->nPos = infoPtr->nRangeMin;
    913         infoPtr->flags |=TB_THUMBPOSCHANGED;
    914     }
    915 
    916     infoPtr->nPageSize=(infoPtr->nRangeMax -  infoPtr->nRangeMin)/5;
    917     if (infoPtr->nPageSize == 0)
    918         infoPtr->nPageSize = 1;
    919     TRACKBAR_RecalculateTics (infoPtr);
    920 
    921     if (wParam) TRACKBAR_Refresh(hwnd);
    922 
    923     return 0;
    924 }
    925 
    926 
    927 static LRESULT
    9281212TRACKBAR_SetTicFreq (HWND hwnd, WPARAM wParam)
    9291213{
    9301214    TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
    9311215
    932     if (GetWindowLongA (hwnd, GWL_STYLE) & TBS_AUTOTICKS)
    933         infoPtr->uTicFreq=(UINT) wParam;
    934 
    935     TRACKBAR_RecalculateTics (infoPtr);
    936 
    937     TRACKBAR_Refresh(hwnd); //CB: necessary?
     1216    if (infoPtr->uTicFreq == (UINT)wParam) return 0;
     1217
     1218    if (!(GetWindowLongA (hwnd, GWL_STYLE) & TBS_AUTOTICKS)) return 0;
     1219
     1220    infoPtr->uTicFreq = (UINT)wParam;
     1221
     1222    TRACKBAR_RecalculateTics(hwnd,infoPtr,FALSE);
     1223
     1224    TRACKBAR_Refresh(hwnd);
    9381225
    9391226    return 0;
     
    9451232{
    9461233    TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
    947 
    948     infoPtr->nSelMin = (INT)LOWORD(lParam);
    949     infoPtr->nSelMax = (INT)HIWORD(lParam);
     1234    INT newMin,newMax;
     1235
     1236    newMin = (INT)LOWORD(lParam);
     1237    newMax = (INT)HIWORD(lParam);
     1238
     1239    if (infoPtr->nSelMin == newMin && infoPtr->nSelMax == newMax) return 0;
     1240    infoPtr->nSelMin = newMin;
     1241    infoPtr->nSelMax = newMax;
     1242
    9501243    infoPtr->flags |=TB_SELECTIONCHANGED;
    9511244
     
    9601253    if (wParam) TRACKBAR_Refresh(hwnd);
    9611254
    962 
    9631255    return 0;
    9641256}
     
    9691261{
    9701262    TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
     1263
     1264    if (infoPtr->nSelMax == (INT)lParam) return 0;
    9711265
    9721266    if (!GetWindowLongA (hwnd, GWL_STYLE) & TBS_ENABLESELRANGE)
     
    9901284    TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
    9911285
     1286    if (infoPtr->nSelMin == (INT)lParam) return 0;
     1287
    9921288    if (!GetWindowLongA (hwnd, GWL_STYLE) & TBS_ENABLESELRANGE)
    9931289        return 0;
    9941290
    9951291    infoPtr->nSelMin = (INT)lParam;
    996     infoPtr->flags  |=TB_SELECTIONCHANGED;
     1292    infoPtr->flags |= TB_SELECTIONCHANGED;
    9971293
    9981294    if (infoPtr->nSelMin < infoPtr->nRangeMin)
     
    10101306    TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
    10111307
    1012     if (GetWindowLongA (hwnd, GWL_STYLE) & TBS_FIXEDLENGTH)
    1013         infoPtr->uThumbLen = (UINT)wParam;
    1014 
     1308    if (infoPtr->uThumbLen == (UINT)wParam) return 0;
     1309
     1310    if (!(GetWindowLongA (hwnd, GWL_STYLE) & TBS_FIXEDLENGTH)) return 0;
     1311
     1312    infoPtr->uThumbLen = (UINT)wParam;
    10151313    infoPtr->flags |= TB_THUMBSIZECHANGED;
    10161314
     
    10201318}
    10211319
     1320static void TRACKBAR_QuickSort(LPLONG list,INT lo,INT hi)
     1321{
     1322  INT i,j,x,y;
     1323
     1324  i = lo;
     1325  j = hi;
     1326  x = list[(lo+hi)/2];
     1327  while (i <= j)
     1328  {
     1329    while (list[i] < x) i++;
     1330    while (x < list[j]) j--;
     1331    if (i <= j)
     1332    {
     1333      y = list[i];
     1334      list[i] = list[j];
     1335      list[j] = y;
     1336      i++;
     1337      j--;
     1338    }
     1339  }
     1340  if (lo < j) TRACKBAR_QuickSort(list,lo,j);
     1341  if (i < hi) TRACKBAR_QuickSort(list,i,hi);
     1342}
    10221343
    10231344static LRESULT
     
    10261347    TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
    10271348    INT nPos = (INT)lParam;
    1028 
    1029     if ((nPos < infoPtr->nRangeMin) || (nPos> infoPtr->nRangeMax))
    1030         return FALSE;
     1349    INT x;
     1350
     1351    if (!(GetWindowLongA(hwnd, GWL_STYLE) & (TBS_AUTOTICKS | TBS_NOTICKS))) return 0;
     1352
     1353    if ((nPos < infoPtr->nRangeMin) || (nPos > infoPtr->nRangeMax)) return FALSE;
     1354
     1355    //Check if tick exists
     1356    for (x = 0;x < infoPtr->uNumTics;x++)
     1357    {
     1358      if (infoPtr->tics[x] == nPos) return TRUE; //value is ok
     1359    }
    10311360
    10321361    infoPtr->uNumTics++;
    1033     infoPtr->tics=COMCTL32_ReAlloc( infoPtr->tics,
    1034                                     (infoPtr->uNumTics)*sizeof (DWORD));
    1035     infoPtr->tics[infoPtr->uNumTics-1]=nPos;
     1362    infoPtr->tics = COMCTL32_ReAlloc(infoPtr->tics,infoPtr->uNumTics*sizeof(DWORD));
     1363    infoPtr->tics[infoPtr->uNumTics-1] = nPos;
     1364
     1365    //Quicksort the list
     1366    TRACKBAR_QuickSort(infoPtr->tics,0,infoPtr->uNumTics-1);
    10361367
    10371368    TRACKBAR_Refresh(hwnd);
     
    10711402{
    10721403    TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
    1073 
    1074     infoPtr->uThumbLen = 23;   /* initial thumb length */
    1075 
    1076     TRACKBAR_CalcChannel (hwnd,infoPtr);
    1077     TRACKBAR_CalcThumb (hwnd, infoPtr);
     1404    RECT clientRect;
     1405    DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
     1406    INT scaleSize;
     1407
     1408    GetWindowRect(hwnd,&clientRect);
     1409    infoPtr->uThumbLen = THUMB_LEN;   /* initial thumb length */
     1410
     1411    scaleSize = 2*BORDER_SIZE;
     1412    if (dwStyle & TBS_NOTICKS) scaleSize += 0;
     1413    else if (dwStyle & TBS_BOTH) scaleSize += 2*(SCALE_SIZE+SCALE_SPACE);
     1414    else scaleSize += SCALE_SIZE+SCALE_SPACE;
     1415
     1416    if (dwStyle & TBS_VERT)
     1417    {
     1418      INT width = clientRect.right-clientRect.left;
     1419
     1420      if (infoPtr->uThumbLen+scaleSize > width) infoPtr->uThumbLen = MAX(width-scaleSize,THUMB_MINLEN);
     1421    } else
     1422    {
     1423      INT height = clientRect.bottom-clientRect.top;
     1424
     1425      if (infoPtr->uThumbLen+scaleSize > height) infoPtr->uThumbLen = MAX(height-scaleSize,THUMB_MINLEN);
     1426    }
     1427
     1428    TRACKBAR_CalcChannel(hwnd,infoPtr);
     1429    TRACKBAR_CalcThumb(hwnd,infoPtr);
     1430
    10781431    infoPtr->flags &= ~TB_SELECTIONCHANGED;
    10791432
     
    10911444
    10921445    /* set default values */
    1093     infoPtr->nRangeMin = 0;
    1094     infoPtr->nRangeMax = 100;
    1095     infoPtr->nLineSize = 1;
    1096     infoPtr->nPageSize = 20;
    1097     infoPtr->nSelMin   = 0;
    1098     infoPtr->nSelMax   = 0;
    1099     infoPtr->nPos      = 0;
    1100 
    1101     infoPtr->uNumTics  = 0;    /* start and end tic are not included in count*/
    1102     infoPtr->uTicFreq  = 1;
    1103     infoPtr->tics          = NULL;
    1104     infoPtr->clrBk         = GetSysColor (COLOR_BACKGROUND);
     1446    infoPtr->nRangeMin  = 0;
     1447    infoPtr->nRangeMax  = 100;
     1448    infoPtr->nLineSize  = 1;
     1449    infoPtr->nPageSize  = 20;
     1450    infoPtr->nSelMin    = 0;
     1451    infoPtr->nSelMax    = 0;
     1452    infoPtr->nPos       = 0;
     1453
     1454    infoPtr->uNumTics   = 0;    /* start and end tic are not included in count*/
     1455    infoPtr->uTicFreq   = 1;
     1456    infoPtr->tics       = NULL;
     1457    infoPtr->clrBk      = GetSysColor (COLOR_3DFACE);
    11051458    infoPtr->hwndNotify = GetParent (hwnd);
    11061459
     
    11581511}
    11591512
    1160 
    1161 static LRESULT
    1162 TRACKBAR_KillFocus (HWND hwnd, WPARAM wParam, LPARAM lParam)
    1163 {
    1164     TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
    1165 
    1166 //    TRACE (trackbar,"\n");
    1167 
    1168     infoPtr->bFocus = FALSE;
    1169     infoPtr->flags &= ~TB_DRAG_MODE;
    1170 
    1171     TRACKBAR_Refresh(hwnd); //CB: make changes here
    1172 
    1173     return 0;
    1174 }
    1175 
    1176 
    11771513static LRESULT
    11781514TRACKBAR_LButtonDown (HWND hwnd, WPARAM wParam, LPARAM lParam)
     
    11821518    int clickPlace,prevPos,vertical;
    11831519    DOUBLE clickPos;
     1520    RECT thumb;
     1521    POINT clickPoint;
    11841522
    11851523    SetFocus (hwnd);
    11861524
    11871525    vertical = dwStyle & TBS_VERT;
    1188     if (vertical)
    1189         clickPlace=(INT)HIWORD(lParam);
    1190     else
    1191         clickPlace=(INT)LOWORD(lParam);
    1192 
     1526    clickPoint.x = (INT)LOWORD(lParam);
     1527    clickPoint.y = (INT)HIWORD(lParam);
     1528
     1529
     1530    if (vertical) clickPlace = clickPoint.y;
     1531    else clickPlace = clickPoint.x;
     1532
     1533    //Button down on thumb?
     1534    thumb = infoPtr->rcFullThumb; //approzimative
    11931535    if ((vertical &&
    1194          (clickPlace>infoPtr->rcThumb.top) &&
    1195          (clickPlace<infoPtr->rcThumb.bottom))   ||
     1536         (clickPoint.y >= thumb.top) &&
     1537         (clickPoint.y <= thumb.bottom) &&
     1538         (clickPoint.x >= thumb.left) &&
     1539         (clickPoint.x <= thumb.right))   ||
    11961540        (!vertical &&
    1197          (clickPlace>infoPtr->rcThumb.left) &&
    1198          (clickPlace<infoPtr->rcThumb.right))) {
    1199         infoPtr->flags |= TB_DRAG_MODE;
    1200         if (dwStyle & TBS_TOOLTIPS) {  /* enable tooltip */
    1201             TTTOOLINFOA ti;
    1202             POINT pt;
    1203 
    1204             GetCursorPos (&pt);
    1205             SendMessageA (infoPtr->hwndToolTip, TTM_TRACKPOSITION, 0,
    1206                           (LPARAM)MAKELPARAM(pt.x, pt.y));
    1207 
    1208             ti.cbSize   = sizeof(TTTOOLINFOA);
    1209             ti.uId      = 0;
    1210             ti.hwnd     = (UINT)hwnd;
    1211 
    1212             infoPtr->flags |= TB_SHOW_TOOLTIP;
    1213             SetCapture (hwnd);
    1214             SendMessageA (infoPtr->hwndToolTip, TTM_TRACKACTIVATE,
    1215                           (WPARAM)TRUE, (LPARAM)&ti);
    1216         }
    1217         return 0;
    1218     }
    1219 
    1220     clickPos = TRACKBAR_ConvertPlaceToPosition (infoPtr, clickPlace, vertical);
     1541         (clickPoint.x >= thumb.left) &&
     1542         (clickPoint.x <= thumb.right) &&
     1543         (clickPoint.y >= thumb.top) &&
     1544         (clickPoint.y <= thumb.bottom)))
     1545       {
     1546         infoPtr->flags |= TB_DRAG_MODE;
     1547         if (dwStyle & TBS_TOOLTIPS)
     1548         {  /* enable tooltip */
     1549           TTTOOLINFOA ti;
     1550           POINT pt;
     1551
     1552           GetCursorPos (&pt);
     1553           SendMessageA (infoPtr->hwndToolTip, TTM_TRACKPOSITION, 0,
     1554                         (LPARAM)MAKELPARAM(pt.x, pt.y));
     1555
     1556           ti.cbSize   = sizeof(TTTOOLINFOA);
     1557           ti.uId      = 0;
     1558           ti.hwnd     = (UINT)hwnd;
     1559
     1560           infoPtr->flags |= TB_SHOW_TOOLTIP;
     1561           SetCapture (hwnd);
     1562           SendMessageA (infoPtr->hwndToolTip, TTM_TRACKACTIVATE,
     1563                         (WPARAM)TRUE, (LPARAM)&ti);
     1564         }
     1565         SetCapture(hwnd);
     1566         TRACKBAR_UpdateThumb(hwnd); //change arrow color
     1567         return 0;
     1568       }
     1569    else if ((vertical &&
     1570              (clickPoint.y >= thumb.top) &&
     1571              (clickPoint.y <= thumb.bottom))   ||
     1572             (!vertical &&
     1573              (clickPoint.x >= thumb.left) &&
     1574              (clickPoint.x <= thumb.right)))
     1575            {
     1576              //ScrollMode
     1577              infoPtr->flags |= TB_SCROLL_MODE;
     1578              SetCapture(hwnd);
     1579              SetTimer(hwnd,SCROLL_TIMER_ID,SCROLL_TIME,NULL);
     1580
     1581              return 0;
     1582            }
     1583
     1584    clickPos = TRACKBAR_ConvertPlaceToPosition(infoPtr,clickPlace,vertical);
    12211585    prevPos = infoPtr->nPos;
    12221586
    1223     if (clickPos > prevPos) {  /* similar to VK_NEXT */
    1224         infoPtr->nPos += infoPtr->nPageSize;
    1225         if (infoPtr->nPos > infoPtr->nRangeMax)
    1226             infoPtr->nPos = infoPtr->nRangeMax;
    1227         TRACKBAR_SendNotify (hwnd, TB_PAGEUP);
    1228     } else {
    1229         infoPtr->nPos -= infoPtr->nPageSize;  /* similar to VK_PRIOR */
    1230         if (infoPtr->nPos < infoPtr->nRangeMin)
    1231             infoPtr->nPos = infoPtr->nRangeMin;
    1232         TRACKBAR_SendNotify (hwnd, TB_PAGEDOWN);
    1233     }
    1234 
    1235     if (prevPos!=infoPtr->nPos) {
    1236         infoPtr->flags |= TB_THUMBPOSCHANGED;
    1237         TRACKBAR_Update(hwnd,prevPos);
    1238     }
     1587    if (clickPos > prevPos)
     1588    {  /* similar to VK_NEXT */
     1589      infoPtr->nPos += infoPtr->nPageSize;
     1590      if (infoPtr->nPos > infoPtr->nRangeMax) infoPtr->nPos = infoPtr->nRangeMax;
     1591      if (prevPos != infoPtr->nPos) TRACKBAR_SendNotify(hwnd,TB_PAGEUP);
     1592    } else
     1593    {  /* similar to VK_PRIOR */
     1594      infoPtr->nPos -= infoPtr->nPageSize;
     1595      if (infoPtr->nPos < infoPtr->nRangeMin) infoPtr->nPos = infoPtr->nRangeMin;
     1596      if (prevPos != infoPtr->nPos) TRACKBAR_SendNotify(hwnd,TB_PAGEDOWN);
     1597    }
     1598
     1599    if (prevPos != infoPtr->nPos)
     1600    {
     1601      infoPtr->flags |= TB_THUMBPOSCHANGED;
     1602      TRACKBAR_UpdateThumbPosition(hwnd,prevPos);
     1603    }
     1604
     1605    //ScrollMode
     1606    infoPtr->flags |= TB_SCROLL_MODE;
     1607    SetCapture(hwnd);
     1608    SetTimer(hwnd,SCROLL_TIMER_ID,SCROLL_TIME,NULL);
    12391609
    12401610    return 0;
     
    12471617    TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
    12481618
    1249     TRACKBAR_SendNotify (hwnd, TB_ENDTRACK);
    1250 
    12511619    if (infoPtr->flags & TB_DRAG_MODE)
    12521620    {
    1253         infoPtr->flags &= ~TB_DRAG_MODE;
    1254         ReleaseCapture ();
    1255     }
    1256 
    1257     if (GetWindowLongA (hwnd, GWL_STYLE) & TBS_TOOLTIPS) {  /* disable tooltip */
     1621      TRACKBAR_SendNotify(hwnd,TB_ENDTRACK);
     1622
     1623      infoPtr->flags &= ~TB_DRAG_MODE;
     1624      ReleaseCapture();
     1625      TRACKBAR_UpdateThumb(hwnd); //change arrow color
     1626    }
     1627
     1628    if (infoPtr->flags & TB_SCROLL_MODE)
     1629    {
     1630      infoPtr->flags &= ~TB_SCROLL_MODE;
     1631      ReleaseCapture();
     1632      KillTimer(hwnd,SCROLL_TIMER_ID);
     1633    }
     1634
     1635    if (GetWindowLongA (hwnd, GWL_STYLE) & TBS_TOOLTIPS)
     1636    {  /* disable tooltip */
    12581637        TTTOOLINFOA ti;
    12591638
     
    12671646    }
    12681647
    1269     //TRACKBAR_Refresh(hwnd); //CB: nothing changed
    1270 
    1271     return 0;
    1272 }
    1273 
     1648    return 0;
     1649}
     1650
     1651
     1652static LRESULT TRACKBAR_Timer(HWND hwnd,WPARAM wParam,LPARAM lParam)
     1653{
     1654  TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(hwnd);
     1655  DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
     1656  POINT mousePoint;
     1657  INT mousePlace,prevPos,newPos,vertical;
     1658  DOUBLE mousePos;
     1659
     1660  GetCursorPos(&mousePoint);
     1661  ScreenToClient(hwnd,&mousePoint);
     1662
     1663  vertical = dwStyle & TBS_VERT;
     1664  if (vertical) mousePlace = mousePoint.y;
     1665  else mousePlace = mousePoint.x;
     1666
     1667  mousePos = TRACKBAR_ConvertPlaceToPosition(infoPtr,mousePlace,vertical);
     1668  prevPos = infoPtr->nPos;
     1669
     1670  if (mousePos > (INT)mousePos+0.5) newPos = mousePos+1;
     1671  else newPos = mousePos;
     1672  if (newPos == prevPos) return 0;
     1673
     1674  if (newPos > prevPos)
     1675  {  /* similar to VK_NEXT */
     1676      infoPtr->nPos += infoPtr->nPageSize;
     1677      if (infoPtr->nPos > infoPtr->nRangeMax) infoPtr->nPos = infoPtr->nRangeMax;
     1678      if (prevPos != infoPtr->nPos) TRACKBAR_SendNotify(hwnd,TB_PAGEUP);
     1679    } else
     1680    {  /* similar to VK_PRIOR */
     1681      infoPtr->nPos -= infoPtr->nPageSize;
     1682      if (infoPtr->nPos < infoPtr->nRangeMin) infoPtr->nPos = infoPtr->nRangeMin;
     1683      if (prevPos != infoPtr->nPos) TRACKBAR_SendNotify(hwnd,TB_PAGEDOWN);
     1684    }
     1685
     1686    if (prevPos != infoPtr->nPos)
     1687    {
     1688      infoPtr->flags |= TB_THUMBPOSCHANGED;
     1689      TRACKBAR_UpdateThumbPosition(hwnd,prevPos);
     1690    }
     1691
     1692  return 0;
     1693}
    12741694
    12751695static LRESULT
     
    12781698    TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
    12791699
    1280     if (infoPtr->flags & TB_DRAGPOSVALID) {
    1281         int lastPos = infoPtr->nPos;
    1282         infoPtr->nPos=infoPtr->dragPos;
    1283         TRACKBAR_Update(hwnd,lastPos);
     1700    if (infoPtr->flags & TB_DRAGPOSVALID)
     1701    {
     1702      int lastPos = infoPtr->nPos;
     1703      infoPtr->nPos = infoPtr->dragPos;
     1704      if (lastPos != infoPtr->nPos) TRACKBAR_UpdateThumbPosition(hwnd,lastPos);
    12841705    }
    12851706
    12861707    infoPtr->flags &= ~ TB_DRAGPOSVALID;
    12871708
    1288     TRACKBAR_SendNotify (hwnd, TB_ENDTRACK);
     1709    if (infoPtr->flags & TB_SCROLL_MODE)
     1710    {
     1711      infoPtr->flags &= ~TB_SCROLL_MODE;
     1712      KillTimer(hwnd,SCROLL_TIMER_ID);
     1713    }
     1714
     1715    TRACKBAR_SendNotify(hwnd,TB_ENDTRACK);
    12891716    return 0;
    12901717}
     
    12981725
    12991726    hdc = wParam==0 ? BeginPaint (hwnd, &ps) : (HDC)wParam;
    1300     TRACKBAR_Draw(hwnd,hdc,0,FALSE);
    1301     if(!wParam)
    1302         EndPaint (hwnd, &ps);
     1727    TRACKBAR_Draw(hwnd,hdc);
     1728    if (!wParam) EndPaint (hwnd, &ps);
    13031729    return 0;
    13041730}
     
    13091735{
    13101736    TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
     1737    HDC hdc;
     1738    RECT rcClient;
    13111739
    13121740//    TRACE (trackbar,"\n");
    1313     infoPtr->bFocus = TRUE;
    1314 
    1315     TRACKBAR_Refresh(hwnd); //CB: make changes here
    1316 
    1317     return 0;
    1318 }
    1319 
     1741    if (!infoPtr->bFocus)
     1742    {
     1743      infoPtr->bFocus = TRUE;
     1744
     1745      GetClientRect (hwnd,&rcClient);
     1746      hdc = GetDC (hwnd);
     1747      DrawFocusRect (hdc,&rcClient);
     1748      ReleaseDC(hwnd,hdc);
     1749
     1750    }
     1751    return 0;
     1752}
     1753
     1754static LRESULT
     1755TRACKBAR_KillFocus (HWND hwnd, WPARAM wParam, LPARAM lParam)
     1756{
     1757    TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
     1758    HDC hdc;
     1759    RECT rcClient;
     1760
     1761//    TRACE (trackbar,"\n");
     1762
     1763    infoPtr->flags &= ~TB_DRAG_MODE;
     1764    if (infoPtr->bFocus)
     1765    {
     1766      infoPtr->bFocus = FALSE;
     1767
     1768      GetClientRect(hwnd,&rcClient);
     1769      hdc = GetDC (hwnd);
     1770      DrawFocusRect(hdc,&rcClient); //XOR removes
     1771      ReleaseDC(hwnd,hdc);
     1772    }
     1773
     1774    return 0;
     1775}
    13201776
    13211777static LRESULT
     
    13571813//    TRACE (trackbar, "%x\n",wParam);
    13581814
    1359     if (dwStyle & TBS_VERT)
    1360         clickPlace=(SHORT)HIWORD(lParam);
    1361     else
    1362         clickPlace=(SHORT)LOWORD(lParam);
    1363 
    1364     if (!(infoPtr->flags & TB_DRAG_MODE))
    1365         return TRUE;
    1366 
    1367     SetCapture (hwnd);
     1815    if (dwStyle & TBS_VERT) clickPlace=(SHORT)HIWORD(lParam);
     1816    else clickPlace=(SHORT)LOWORD(lParam);
     1817
     1818    if (!(infoPtr->flags & TB_DRAG_MODE)) return TRUE;
     1819
    13681820    lastDragPos = infoPtr->dragPos;
    13691821    dragPos = TRACKBAR_ConvertPlaceToPosition (infoPtr, clickPlace,
    13701822                                               dwStyle & TBS_VERT);
    1371     if (dragPos > ((INT)dragPos) + 0.5)
    1372         infoPtr->dragPos = dragPos + 1;
    1373     else
    1374         infoPtr->dragPos = dragPos;
     1823    if (dragPos > ((INT)dragPos)+0.5) infoPtr->dragPos = dragPos + 1;
     1824    else infoPtr->dragPos = dragPos;
     1825
     1826    if (lastDragPos == infoPtr->dragPos) return TRUE; //nothing changed
    13751827
    13761828    infoPtr->flags |= TB_DRAGPOSVALID;
    13771829    TRACKBAR_SendNotify (hwnd, TB_THUMBTRACK | (infoPtr->nPos>>16));
    13781830
    1379     if (infoPtr->flags & TB_SHOW_TOOLTIP) {
     1831    if (infoPtr->flags & TB_SHOW_TOOLTIP)
     1832    {
    13801833        POINT pt;
    13811834        TTTOOLINFOA ti;
     
    14001853    }
    14011854
    1402     TRACKBAR_Update(hwnd,lastDragPos);
    1403     UpdateWindow (hwnd);
     1855    TRACKBAR_UpdateThumbPosition(hwnd,lastDragPos);
    14041856
    14051857    return TRUE;
     
    14231875        if (infoPtr->nPos < infoPtr->nRangeMin)
    14241876            infoPtr->nPos = infoPtr->nRangeMin;
    1425         TRACKBAR_SendNotify (hwnd, TB_LINEUP);
     1877        TRACKBAR_SendNotify(hwnd,TB_LINEUP);
    14261878        break;
    14271879    case VK_RIGHT:
     
    14591911    }
    14601912
    1461     if (pos!=infoPtr->nPos) {
    1462         infoPtr->flags |=TB_THUMBPOSCHANGED;
    1463         TRACKBAR_Update(hwnd,pos);
     1913    if (pos != infoPtr->nPos)
     1914    {
     1915      infoPtr->flags |= TB_THUMBPOSCHANGED;
     1916      TRACKBAR_UpdateThumbPosition(hwnd,pos);
    14641917    }
    14651918
     
    16182071        return TRACKBAR_KeyUp (hwnd, wParam);
    16192072
     2073    case WM_LBUTTONDOWN:
     2074        return TRACKBAR_LButtonDown (hwnd, wParam, lParam);
     2075
     2076    case WM_LBUTTONUP:
     2077        return TRACKBAR_LButtonUp (hwnd, wParam, lParam);
     2078
     2079    case WM_TIMER:
     2080        return TRACKBAR_Timer(hwnd,wParam,lParam);
     2081
     2082    case WM_MOUSEMOVE:
     2083        return TRACKBAR_MouseMove (hwnd, wParam, lParam);
     2084
     2085    case WM_PAINT:
     2086        return TRACKBAR_Paint (hwnd, wParam);
     2087
     2088    case WM_SETFOCUS:
     2089        return TRACKBAR_SetFocus (hwnd, wParam, lParam);
     2090
    16202091    case WM_KILLFOCUS:
    16212092        return TRACKBAR_KillFocus (hwnd, wParam, lParam);
    1622 
    1623     case WM_LBUTTONDOWN:
    1624         return TRACKBAR_LButtonDown (hwnd, wParam, lParam);
    1625 
    1626     case WM_LBUTTONUP:
    1627         return TRACKBAR_LButtonUp (hwnd, wParam, lParam);
    1628 
    1629     case WM_MOUSEMOVE:
    1630         return TRACKBAR_MouseMove (hwnd, wParam, lParam);
    1631 
    1632     case WM_PAINT:
    1633         return TRACKBAR_Paint (hwnd, wParam);
    1634 
    1635     case WM_SETFOCUS:
    1636         return TRACKBAR_SetFocus (hwnd, wParam, lParam);
    16372093
    16382094    case WM_SIZE:
Note: See TracChangeset for help on using the changeset viewer.