Changeset 496 for trunk/src/comctl32/updown.c
- Timestamp:
- Aug 14, 1999, 6:13:16 PM (26 years ago)
- 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:51cbratschi Exp $ */1 /* $Id: updown.c,v 1.7 1999-08-14 16:13:16 cbratschi Exp $ */ 2 2 /* 3 3 * Updown control … … 8 8 * 9 9 * TODO: 10 * - subclass the buddy window (in UPDOWN_SetBuddyHandle) to process the11 * arrow keys12 10 * - I am not sure about the default values for the Min, Max, Pos 13 11 * (in the UPDOWN_INFO the fields: MinVal, MaxVal, CurVal) … … 56 54 #define DEFAULT_ADDTOP 0 /* amount to extend above the buddy window */ 57 55 #define DEFAULT_ADDBOT 0 /* amount to extend below the buddy window */ 56 #define DEFAULT_BUDDYBORDER 2 /* Width/height of the buddy border */ 58 57 59 58 … … 67 66 #define TIMERID1 1 68 67 #define TIMERID2 2 68 #define BUDDY_UPDOWN_HWND "buddyUpDownHWND" 69 #define BUDDY_SUPERCLASS_WNDPROC "buddySupperClassWndProc" 69 70 70 71 static int accelIndex = -1; … … 77 78 #define UPDOWN_GetInfoPtr(hwnd) ((UPDOWN_INFO *)GetWindowLongA(hwnd,0)) 78 79 80 static LRESULT CALLBACK 81 UPDOWN_Buddy_SubclassProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); 79 82 80 83 /*********************************************************************** … … 119 122 120 123 /*********************************************************************** 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 */ 129 static 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 /*********************************************************************** 121 140 * UPDOWN_GetArrowRect 122 141 * wndPtr - pointer to the up-down wnd … … 128 147 static void UPDOWN_GetArrowRect (HWND hwnd, RECT *rect, BOOL incr) 129 148 { 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 */ 131 151 132 152 GetClientRect (hwnd, rect); 133 153 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)) 135 159 { 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; 144 186 } 145 187 } … … 277 319 278 320 /*********************************************************************** 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 */ 326 static 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 /*********************************************************************** 279 340 * UPDOWN_Draw [Internal] 280 341 * … … 287 348 BOOL prssed; 288 349 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); 289 356 290 357 /* Draw the incr button */ … … 332 399 * Calls UPDOWN_Draw. 333 400 */ 334 static void UPDOWN_Paint (HWND hwnd )401 static void UPDOWN_Paint (HWND hwnd, HDC passedDC) 335 402 { 336 403 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 340 409 UPDOWN_Draw (hwnd, hdc); 341 EndPaint (hwnd, &ps); 410 411 if (passedDC == 0) 412 EndPaint (hwnd, &ps); 342 413 } 343 414 344 415 /*********************************************************************** 345 416 * UPDOWN_SetBuddyHandle 417 * CB: UPDOWN_SetBuddy == message handler 346 418 * Tests if 'hwndBud' is a valid window handle. If not, returns FALSE. 347 419 * Else, sets it as a new Buddy. … … 354 426 static BOOL UPDOWN_SetBuddyHandle (HWND hwnd, HWND hwndBud) 355 427 { 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? */ 364 434 if(!IsWindow(hwndBud)) 365 435 return FALSE; 366 436 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 */ 368 442 infoPtr->Buddy = hwndBud; 369 443 444 /* keep upDown ctrl hwnd in a buddy property */ 445 SetPropA( hwndBud, BUDDY_UPDOWN_HWND, hwnd); 446 370 447 /* 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); 372 450 373 451 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); 375 469 } 376 470 … … 379 473 return TRUE; 380 474 381 infoPtr->Buddy = hwndBud;382 383 475 /* Get the rect of the buddy relative to its parent */ 384 476 GetWindowRect(infoPtr->Buddy, &budRect); 385 477 MapWindowPoints(HWND_DESKTOP, GetParent(infoPtr->Buddy), 386 478 (POINT *)(&budRect.left), 2); 387 479 388 480 /* now do the positioning */ … … 398 490 /* first adjust the buddy to accomodate the up/down */ 399 491 SetWindowPos(infoPtr->Buddy, 0, budRect.left, budRect.top, 400 401 492 budRect.right - budRect.left, budRect.bottom - budRect.top, 493 SWP_NOACTIVATE|SWP_NOZORDER); 402 494 403 495 /* now position the up/down */ 404 496 /* Since the UDS_ALIGN* flags were used, */ 405 497 /* 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); 410 517 411 518 return TRUE; 412 } 519 } 413 520 414 521 /*********************************************************************** … … 640 747 if(infoPtr->AccelVect) COMCTL32_Free(infoPtr->AccelVect); 641 748 749 if ( IsWindow(infoPtr->Buddy) ) /* Cleanup */ 750 RemovePropA(infoPtr->Buddy, BUDDY_UPDOWN_HWND); 751 642 752 COMCTL32_Free (infoPtr); 643 753 … … 652 762 653 763 if (dwStyle & WS_DISABLED) UPDOWN_CancelMode(hwnd); 654 UPDOWN_Paint(hwnd); 764 765 UPDOWN_Refresh(hwnd); 655 766 656 767 return 0; … … 811 922 if (lParam) UNKNOWN_PARAM(UDM_SETBUDDY,wParam,lParam); 812 923 temp = infoPtr->Buddy; 813 infoPtr->Buddy = wParam;814 924 UPDOWN_SetBuddyHandle(hwnd,wParam); 815 925 // TRACE(updown, "UpDown Ctrl new buddy(%04x), hwnd=%04x\n", … … 901 1011 * UpDownWndProc 902 1012 */ 903 LRESULT WINAPI UpDownWindowProc(HWND hwnd, UINT message, WPARAM wParam,1013 static LRESULT WINAPI UpDownWindowProc(HWND hwnd, UINT message, WPARAM wParam, 904 1014 LPARAM lParam) 905 1015 { … … 942 1052 943 1053 case WM_PAINT: 944 UPDOWN_Paint(hwnd );1054 UPDOWN_Paint(hwnd,(HDC)wParam); 945 1055 break; 946 1056 … … 991 1101 } 992 1102 1103 /*********************************************************************** 1104 * UPDOWN_Buddy_SubclassProc used to handle messages sent to the buddy 1105 * control. 1106 */ 1107 LRESULT CALLBACK 1108 UPDOWN_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 } 993 1150 994 1151 /***********************************************************************
Note:
See TracChangeset
for help on using the changeset viewer.