Ignore:
Timestamp:
Aug 14, 1999, 6:13:16 PM (26 years ago)
Author:
cbratschi
Message:

wine-990731 update

File:
1 edited

Legend:

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

    r295 r496  
    1 /* $Id: updown.c,v 1.6 1999-07-12 15:58:51 cbratschi Exp $ */
     1/* $Id: updown.c,v 1.7 1999-08-14 16:13:16 cbratschi Exp $ */
    22/*
    33 * Updown control
     
    88 *
    99 * TODO:
    10  *   - subclass the buddy window (in UPDOWN_SetBuddyHandle) to process the
    11  *     arrow keys
    1210 *   - I am not sure about the default values for the Min, Max, Pos
    1311 *     (in the UPDOWN_INFO the fields: MinVal, MaxVal, CurVal)
     
    5654#define DEFAULT_ADDTOP    0  /* amount to extend above the buddy window */
    5755#define DEFAULT_ADDBOT    0  /* amount to extend below the buddy window */
     56#define DEFAULT_BUDDYBORDER  2  /* Width/height of the buddy border */
    5857
    5958
     
    6766#define TIMERID1         1
    6867#define TIMERID2         2
     68#define BUDDY_UPDOWN_HWND        "buddyUpDownHWND"
     69#define BUDDY_SUPERCLASS_WNDPROC "buddySupperClassWndProc"
    6970
    7071static int accelIndex = -1;
     
    7778#define UPDOWN_GetInfoPtr(hwnd) ((UPDOWN_INFO *)GetWindowLongA(hwnd,0))
    7879
     80static LRESULT CALLBACK
     81UPDOWN_Buddy_SubclassProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
    7982
    8083/***********************************************************************
     
    119122
    120123/***********************************************************************
     124 * UPDOWN_HasBuddyBorder [Internal]
     125 *
     126 * When we have a buddy set and that we are aligned on our buddy, we
     127 * want to draw a sunken edge to make like we are part of that control.
     128 */
     129static BOOL UPDOWN_HasBuddyBorder(HWND hwnd)
     130{
     131  UPDOWN_INFO* infoPtr = UPDOWN_GetInfoPtr (hwnd);
     132  DWORD        dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
     133
     134  return  ( ((dwStyle & (UDS_ALIGNLEFT | UDS_ALIGNRIGHT)) != 0) &&
     135            (SendMessageA(hwnd, UDM_GETBUDDY, 0, 0) != 0) &&
     136            (lstrcmpiA(infoPtr->szBuddyClass, "EDIT") == 0 ) );
     137}
     138
     139/***********************************************************************
    121140 *           UPDOWN_GetArrowRect
    122141 * wndPtr   - pointer to the up-down wnd
     
    128147static void UPDOWN_GetArrowRect (HWND hwnd, RECT *rect, BOOL incr)
    129148{
    130   int len; /* will hold the width or height */
     149  DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
     150  int   len; /* will hold the width or height */
    131151
    132152  GetClientRect (hwnd, rect);
    133153
    134   if (GetWindowLongA(hwnd, GWL_STYLE) & UDS_HORZ)
     154  /*
     155   * Make sure we calculate the rectangle to fit even if we draw the
     156   * border.
     157   */
     158  if (UPDOWN_HasBuddyBorder(hwnd))
    135159  {
    136     len = rect->right-rect->left; /* compute the width */
    137     if (incr) rect->left = len/2+1;
    138     else rect->right = len/2;
    139   } else
    140   {
    141     len = rect->bottom-rect->top; /* compute the height */
    142     if (incr) rect->bottom = len/2;
    143     else rect->top = len/2+1;
     160    if (dwStyle & UDS_ALIGNLEFT)
     161      rect->left+=DEFAULT_BUDDYBORDER;
     162    else
     163      rect->right-=DEFAULT_BUDDYBORDER;
     164
     165    InflateRect(rect, 0, -DEFAULT_BUDDYBORDER);
     166  }
     167
     168  /*
     169   * We're calculating the midpoint to figure-out where the
     170   * separation between the buttons will lay. We make sure that we
     171   * round the uneven numbers by adding 1.
     172   */
     173  if (dwStyle & UDS_HORZ) {
     174    len = rect->right - rect->left + 1; /* compute the width */
     175    if (incr)
     176      rect->left = rect->left + len/2;
     177    else
     178      rect->right =  rect->left + len/2;
     179  }
     180  else {
     181    len = rect->bottom - rect->top + 1; /* compute the height */
     182    if (incr)
     183      rect->bottom =  rect->top + len/2;
     184    else
     185      rect->top =  rect->top + len/2;
    144186  }
    145187}
     
    277319
    278320/***********************************************************************
     321 * UPDOWN_DrawBuddyBorder [Internal]
     322 *
     323 * When we have a buddy set and that we are aligned on our buddy, we
     324 * want to draw a sunken edge to make like we are part of that control.
     325 */
     326static void UPDOWN_DrawBuddyBorder (HWND hwnd, HDC hdc)
     327{
     328  DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
     329  RECT  clientRect;
     330
     331  GetClientRect(hwnd, &clientRect);
     332
     333  if (dwStyle & UDS_ALIGNLEFT)
     334    DrawEdge(hdc, &clientRect, EDGE_SUNKEN, BF_BOTTOM | BF_LEFT | BF_TOP);
     335  else
     336    DrawEdge(hdc, &clientRect, EDGE_SUNKEN, BF_BOTTOM | BF_RIGHT | BF_TOP);
     337}
     338
     339/***********************************************************************
    279340 * UPDOWN_Draw [Internal]
    280341 *
     
    287348  BOOL prssed;
    288349  RECT rect;
     350
     351  /*
     352   * Draw the common border between ourselves and our buddy.
     353   */
     354  if (UPDOWN_HasBuddyBorder(hwnd))
     355    UPDOWN_DrawBuddyBorder(hwnd, hdc);
    289356
    290357  /* Draw the incr button */
     
    332399 * Calls UPDOWN_Draw.
    333400 */
    334 static void UPDOWN_Paint (HWND hwnd)
     401static void UPDOWN_Paint (HWND hwnd, HDC passedDC)
    335402{
    336403    PAINTSTRUCT ps;
    337     HDC hdc;
    338 
    339     hdc = BeginPaint (hwnd, &ps);
     404    HDC         hdc = passedDC;
     405
     406    if (passedDC == 0)
     407      hdc = BeginPaint (hwnd, &ps);
     408
    340409    UPDOWN_Draw (hwnd, hdc);
    341     EndPaint (hwnd, &ps);
     410
     411    if (passedDC == 0)
     412      EndPaint (hwnd, &ps);
    342413}
    343414
    344415/***********************************************************************
    345416 *           UPDOWN_SetBuddyHandle
     417 * CB: UPDOWN_SetBuddy == message handler
    346418 * Tests if 'hwndBud' is a valid window handle. If not, returns FALSE.
    347419 * Else, sets it as a new Buddy.
     
    354426static BOOL UPDOWN_SetBuddyHandle (HWND hwnd, HWND hwndBud)
    355427{
    356   UPDOWN_INFO *infoPtr = UPDOWN_GetInfoPtr (hwnd);
    357   DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
    358   RECT budRect; /* new coord for the buddy */
    359   int x;          /* new x position and width for the up-down */
    360 
    361   *infoPtr->szBuddyClass = '\0';
    362 
    363   /* Is is a valid bud? */
     428  UPDOWN_INFO* infoPtr = UPDOWN_GetInfoPtr (hwnd);
     429  DWORD        dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
     430  RECT         budRect;  /* new coord for the buddy */
     431  int          x,width;  /* new x position and width for the up-down */
     432       
     433  /* Is it a valid bud? */
    364434  if(!IsWindow(hwndBud))
    365435    return FALSE;
    366436
    367   /* Store buddy wundow handle */
     437  /* there is already a body assigned */
     438  if ( infoPtr->Buddy )
     439    RemovePropA(infoPtr->Buddy, BUDDY_UPDOWN_HWND);
     440
     441  /* Store buddy window handle */
    368442  infoPtr->Buddy = hwndBud;
    369443
     444  /* keep upDown ctrl hwnd in a buddy property */
     445  SetPropA( hwndBud, BUDDY_UPDOWN_HWND, hwnd);
     446
    370447  /* Store buddy window clas name */
    371   GetClassNameA (hwndBud, infoPtr->szBuddyClass, 40);
     448  memset(infoPtr->szBuddyClass, 0, UPDOWN_BUDDYCLASSNAMELEN);
     449  GetClassNameA (hwndBud, infoPtr->szBuddyClass, UPDOWN_BUDDYCLASSNAMELEN-1);
    372450
    373451  if(dwStyle & UDS_ARROWKEYS){
    374 //    FIXME(updown, "we need to subclass the buddy to process the arrow keys.\n");
     452    /* Note that I don't clear the BUDDY_SUPERCLASS_WNDPROC property
     453       when we reset the upDown ctrl buddy to another buddy because it is not
     454       good to break the window proc chain. */
     455
     456    /* keep buddy supperclass wndproc in prop instead of in ptr struct
     457       to prevent accessing freed memory */
     458    SetPropA(
     459      hwndBud,
     460      BUDDY_SUPERCLASS_WNDPROC,
     461      (LONG)GetWindowLongA(hwndBud, GWL_WNDPROC) );
     462
     463    /* Assign the buddy wndproc to local wndproc in order to override
     464       keyboard's up and down arrow */
     465    SetWindowLongA(
     466      hwndBud,
     467      GWL_WNDPROC,
     468      (LONG)UPDOWN_Buddy_SubclassProc);
    375469  }
    376470
     
    379473    return TRUE;
    380474
    381   infoPtr->Buddy = hwndBud;
    382 
    383475  /* Get the rect of the buddy relative to its parent */
    384476  GetWindowRect(infoPtr->Buddy, &budRect);
    385477  MapWindowPoints(HWND_DESKTOP, GetParent(infoPtr->Buddy),
    386                   (POINT *)(&budRect.left), 2);
     478                  (POINT *)(&budRect.left), 2);
    387479
    388480  /* now do the positioning */
     
    398490  /* first adjust the buddy to accomodate the up/down */
    399491  SetWindowPos(infoPtr->Buddy, 0, budRect.left, budRect.top,
    400                budRect.right  - budRect.left, budRect.bottom - budRect.top,
    401                SWP_NOACTIVATE|SWP_NOZORDER);
     492               budRect.right  - budRect.left, budRect.bottom - budRect.top,
     493               SWP_NOACTIVATE|SWP_NOZORDER);
    402494
    403495  /* now position the up/down */
    404496  /* Since the UDS_ALIGN* flags were used, */
    405497  /* we will pick the position and size of the window. */
    406 
    407   SetWindowPos (hwnd, 0, x, budRect.top-DEFAULT_ADDTOP,DEFAULT_WIDTH,
    408                  (budRect.bottom-budRect.top)+DEFAULT_ADDTOP+DEFAULT_ADDBOT,
    409                  SWP_NOACTIVATE|SWP_NOZORDER);
     498  width = DEFAULT_WIDTH;
     499
     500  /*
     501   * If the updown has a buddy border, it has to overlap with the buddy
     502   * to look as if it is integrated with the buddy control.
     503   * We nudge the control or change it size to overlap.
     504   */
     505  if (UPDOWN_HasBuddyBorder(hwnd))
     506  {
     507    if(dwStyle & UDS_ALIGNRIGHT)
     508      x-=DEFAULT_BUDDYBORDER;
     509    else
     510      width+=DEFAULT_BUDDYBORDER;
     511  }
     512
     513  SetWindowPos (hwnd, infoPtr->Buddy,
     514                x, budRect.top-DEFAULT_ADDTOP,
     515                width, (budRect.bottom-budRect.top)+DEFAULT_ADDTOP+DEFAULT_ADDBOT,
     516                SWP_NOACTIVATE);
    410517
    411518  return TRUE;
    412 }
     519}       
    413520
    414521/***********************************************************************
     
    640747  if(infoPtr->AccelVect) COMCTL32_Free(infoPtr->AccelVect);
    641748
     749  if ( IsWindow(infoPtr->Buddy) ) /* Cleanup */
     750        RemovePropA(infoPtr->Buddy, BUDDY_UPDOWN_HWND);
     751
    642752  COMCTL32_Free (infoPtr);
    643753
     
    652762
    653763  if (dwStyle & WS_DISABLED) UPDOWN_CancelMode(hwnd);
    654   UPDOWN_Paint(hwnd);
     764
     765  UPDOWN_Refresh(hwnd);
    655766
    656767  return 0;
     
    811922  if (lParam) UNKNOWN_PARAM(UDM_SETBUDDY,wParam,lParam);
    812923  temp = infoPtr->Buddy;
    813   infoPtr->Buddy = wParam;
    814924  UPDOWN_SetBuddyHandle(hwnd,wParam);
    815925//      TRACE(updown, "UpDown Ctrl new buddy(%04x), hwnd=%04x\n",
     
    9011011 *           UpDownWndProc
    9021012 */
    903 LRESULT WINAPI UpDownWindowProc(HWND hwnd, UINT message, WPARAM wParam,
     1013static LRESULT WINAPI UpDownWindowProc(HWND hwnd, UINT message, WPARAM wParam,
    9041014                                LPARAM lParam)
    9051015{
     
    9421052
    9431053    case WM_PAINT:
    944       UPDOWN_Paint(hwnd);
     1054      UPDOWN_Paint(hwnd,(HDC)wParam);
    9451055      break;
    9461056
     
    9911101}
    9921102
     1103/***********************************************************************
     1104 * UPDOWN_Buddy_SubclassProc used to handle messages sent to the buddy
     1105 *                           control.
     1106 */
     1107LRESULT CALLBACK
     1108UPDOWN_Buddy_SubclassProc (
     1109  HWND   hwnd,
     1110  UINT   uMsg,
     1111  WPARAM wParam,
     1112  LPARAM lParam)
     1113{
     1114  LONG superClassWndProc = GetPropA(hwnd, BUDDY_SUPERCLASS_WNDPROC);
     1115  //TRACE("hwnd=%04x, wndProc=%d, uMsg=%04x, wParam=%d, lParam=%d\n",
     1116  // hwnd, (INT)superClassWndProc, uMsg, wParam, (UINT)lParam);
     1117
     1118  switch (uMsg)
     1119  {
     1120    case WM_KEYDOWN:
     1121    {
     1122      if ( ((int)wParam == VK_UP ) || ((int)wParam == VK_DOWN ) )
     1123      {
     1124        HWND upDownHwnd      = GetPropA(hwnd, BUDDY_UPDOWN_HWND);
     1125        UPDOWN_INFO *infoPtr = UPDOWN_GetInfoPtr(upDownHwnd);
     1126
     1127        if (!lstrcmpA (infoPtr->szBuddyClass, "ListBox"))
     1128        {
     1129          /* if the buddy is a list window, we must update curr index */
     1130          INT oldVal = SendMessageA(hwnd, LB_GETCURSEL, 0, 0);
     1131          SendMessageA(hwnd, LB_SETCURSEL, oldVal+1, 0);
     1132        }
     1133        else
     1134        {
     1135          UPDOWN_GetBuddyInt(upDownHwnd);
     1136          UPDOWN_DoAction(upDownHwnd, 1, wParam==VK_UP);
     1137        }
     1138
     1139        break;
     1140      }
     1141      /* else Fall Through */
     1142    }
     1143
     1144    default:
     1145      return CallWindowProcA( (WNDPROC)superClassWndProc, hwnd, uMsg, wParam, lParam);
     1146  }
     1147
     1148  return 0;
     1149}
    9931150
    9941151/***********************************************************************
Note: See TracChangeset for help on using the changeset viewer.