00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include <string.h>
00018 #include <os2win.h>
00019 #include "controls.h"
00020 #include "combo.h"
00021 #include "initterm.h"
00022
00023 #ifdef DEBUG
00024 char *GetMsgText(int Msg);
00025 #endif
00026
00027 #define DBG_LOCALLOG DBG_combo
00028 #include "dbglocal.h"
00029
00030
00031 #define KEYDATA_ALT 0x2000
00032 #define KEYDATA_PREVSTATE 0x4000
00033
00034
00035
00036
00037
00038 #define CB_NOTIFY( lphc, code ) \
00039 (SendMessageA( (lphc)->owner, WM_COMMAND, \
00040 MAKEWPARAM(GetWindowLongA((lphc)->hwndself,GWL_ID), (code)), (lphc)->hwndself))
00041 #define CB_GETEDITTEXTLENGTH( lphc ) \
00042 (SendMessageA( (lphc)->hWndEdit, WM_GETTEXTLENGTH, 0, 0 ))
00043
00044
00045
00046
00047 #define COMBO_YBORDERGAP 5
00048 #define COMBO_XBORDERSIZE() ( 2 )
00049 #define COMBO_YBORDERSIZE() ( 2 )
00050 #define COMBO_EDITBUTTONSPACE() ( 0 )
00051 #define EDIT_CONTROL_PADDING() ( 1 )
00052
00053
00054
00055
00056 static LRESULT COMBO_NCCreate(HWND hwnd,WPARAM wParam,LPARAM lParam)
00057 {
00058 LPHEADCOMBO lphc;
00059
00060 if ( hwnd &&
00061 (lphc = (LPHEADCOMBO)HeapAlloc(GetProcessHeap(), 0, sizeof(HEADCOMBO))) )
00062 {
00063 LPCREATESTRUCTA lpcs = (CREATESTRUCTA*)lParam;
00064 DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
00065 DWORD dwExStyle = GetWindowLongA(hwnd,GWL_EXSTYLE);
00066
00067 memset( lphc, 0, sizeof(HEADCOMBO) );
00068 SetInfoPtr(hwnd,(DWORD)lphc);
00069
00070
00071
00072 lphc->dwStyle = (lpcs->style & ~(WS_BORDER | WS_HSCROLL | WS_VSCROLL));
00073 dwStyle &= ~(WS_BORDER | WS_HSCROLL | WS_VSCROLL);
00074 SetWindowLongA(hwnd,GWL_STYLE,dwStyle);
00075
00076
00077
00078
00079
00080 dwExStyle &= ~(WS_EX_CLIENTEDGE);
00081 SetWindowLongA(hwnd,GWL_EXSTYLE,dwExStyle);
00082
00083 if( !(lpcs->style & (CBS_OWNERDRAWFIXED | CBS_OWNERDRAWVARIABLE)) )
00084 lphc->dwStyle |= CBS_HASSTRINGS;
00085 if( !(dwExStyle & WS_EX_NOPARENTNOTIFY) )
00086 lphc->wState |= CBF_NOTIFY;
00087
00088
00089
00090
00091 return TRUE;
00092 }
00093 return FALSE;
00094 }
00095
00096
00097
00098
00099 static LRESULT COMBO_NCDestroy(HWND hwnd,WPARAM wParam,LPARAM lParam)
00100 {
00101 LPHEADCOMBO lphc = (LPHEADCOMBO)GetInfoPtr(hwnd);
00102
00103 if( lphc )
00104 {
00105
00106
00107 if( (CB_GETTYPE(lphc) != CBS_SIMPLE) && lphc->hWndLBox )
00108 DestroyWindow( lphc->hWndLBox );
00109
00110 HeapFree( GetProcessHeap(), 0, lphc );
00111 SetInfoPtr(hwnd,0);
00112 }
00113
00114 return DefWindowProcA(hwnd,WM_NCDESTROY,wParam,lParam);
00115 }
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128 static INT CBGetTextAreaHeight(
00129 HWND hwnd,
00130 LPHEADCOMBO lphc)
00131 {
00132 INT iTextItemHeight;
00133
00134 if( lphc->editHeight )
00135 {
00136 iTextItemHeight = lphc->editHeight;
00137 }
00138 else
00139 {
00140 TEXTMETRICA tm;
00141 HDC hDC = GetDC(hwnd);
00142 HFONT hPrevFont = 0;
00143 INT baseUnitY;
00144
00145 if (lphc->hFont)
00146 hPrevFont = SelectObject( hDC, lphc->hFont );
00147
00148 GetTextMetricsA(hDC, &tm);
00149
00150 baseUnitY = tm.tmHeight;
00151
00152 if( hPrevFont )
00153 SelectObject( hDC, hPrevFont );
00154
00155 ReleaseDC(hwnd, hDC);
00156
00157 iTextItemHeight = ((13 * baseUnitY) / 8);
00158
00159
00160
00161
00162
00163
00164 iTextItemHeight -= 2*COMBO_YBORDERSIZE();
00165 }
00166
00167
00168
00169
00170
00171 if ( CB_OWNERDRAWN(lphc) &&
00172 (lphc->wState & CBF_MEASUREITEM) )
00173 {
00174 MEASUREITEMSTRUCT measureItem;
00175 RECT clientRect;
00176 INT originalItemHeight = iTextItemHeight;
00177
00178
00179
00180
00181 GetClientRect(hwnd, &clientRect);
00182
00183 lphc->wState &= ~CBF_MEASUREITEM;
00184
00185
00186
00187
00188 measureItem.CtlType = ODT_COMBOBOX;
00189 measureItem.CtlID = GetWindowLongA(lphc->hwndself,GWL_ID);
00190 measureItem.itemID = -1;
00191 measureItem.itemWidth = clientRect.right;
00192 measureItem.itemHeight = iTextItemHeight - 6;
00193 measureItem.itemData = 0;
00194 SendMessageA(lphc->owner, WM_MEASUREITEM,
00195 (WPARAM)measureItem.CtlID, (LPARAM)&measureItem);
00196 iTextItemHeight = 6 + measureItem.itemHeight;
00197
00198
00199
00200
00201
00202 if (lphc->dwStyle & CBS_OWNERDRAWFIXED)
00203 {
00204 measureItem.CtlType = ODT_COMBOBOX;
00205 measureItem.CtlID = GetWindowLongA(lphc->hwndself,GWL_ID);
00206 measureItem.itemID = 0;
00207 measureItem.itemWidth = clientRect.right;
00208 measureItem.itemHeight = originalItemHeight;
00209 measureItem.itemData = 0;
00210 SendMessageA(lphc->owner, WM_MEASUREITEM,
00211 (WPARAM)measureItem.CtlID, (LPARAM)&measureItem);
00212 lphc->fixedOwnerDrawHeight = measureItem.itemHeight;
00213 }
00214
00215
00216
00217
00218 lphc->editHeight = iTextItemHeight;
00219 }
00220
00221 return iTextItemHeight;
00222 }
00223
00224
00225
00226
00227
00228
00229
00230
00231 static void CBForceDummyResize(
00232 LPHEADCOMBO lphc)
00233 {
00234 RECT windowRect;
00235 int newComboHeight;
00236
00237 newComboHeight = CBGetTextAreaHeight(CB_HWND(lphc),lphc) + 2*COMBO_YBORDERSIZE();
00238
00239 GetWindowRect(CB_HWND(lphc), &windowRect);
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249 SetWindowPos( CB_HWND(lphc),
00250 (HWND)0,
00251 0, 0,
00252 windowRect.right - windowRect.left,
00253 newComboHeight,
00254 SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE );
00255 }
00256
00257
00258
00259
00260
00261
00262 static void CBCalcPlacement(
00263 HWND hwnd,
00264 LPHEADCOMBO lphc,
00265 LPRECT lprEdit,
00266 LPRECT lprButton,
00267 LPRECT lprLB)
00268 {
00269 #if 1
00270
00271
00272
00273 GetClientRect(hwnd, lprEdit);
00274
00275
00276
00277
00278 InflateRect(lprEdit, -COMBO_XBORDERSIZE(), -COMBO_YBORDERSIZE());
00279
00280
00281
00282
00283 lprEdit->bottom = lprEdit->top + CBGetTextAreaHeight(hwnd, lphc);
00284
00285
00286
00287
00288 CopyRect(lprButton, lprEdit);
00289
00290
00291
00292
00293 if( CB_GETTYPE(lphc) == CBS_SIMPLE )
00294 lprButton->left = lprButton->right = lprButton->bottom = 0;
00295 else
00296 {
00297
00298
00299
00300
00301
00302 lprButton->left = lprButton->right - GetSystemMetrics(SM_CXVSCROLL);
00303 lprEdit->right = lprButton->left;
00304 }
00305
00306
00307
00308
00309
00310 if( CB_GETTYPE(lphc) == CBS_DROPDOWN )
00311 {
00312 lprEdit->right -= COMBO_EDITBUTTONSPACE();
00313 }
00314
00315
00316
00317
00318 if (CB_GETTYPE(lphc) != CBS_DROPDOWNLIST)
00319 {
00320 InflateRect(lprEdit, -EDIT_CONTROL_PADDING(), -EDIT_CONTROL_PADDING());
00321 }
00322
00323
00324
00325
00326 if( CB_GETTYPE(lphc) == CBS_SIMPLE )
00327 {
00328
00329
00330
00331 GetClientRect(hwnd, lprLB);
00332
00333
00334
00335
00336 lprLB->top = lprEdit->bottom + COMBO_YBORDERSIZE();
00337 }
00338 else
00339 {
00340
00341
00342
00343 if (lphc->droppedWidth < (lprButton->right + COMBO_XBORDERSIZE()))
00344 {
00345 lprLB->right = lprLB->left + (lprButton->right + COMBO_XBORDERSIZE());
00346
00347
00348
00349
00350
00351
00352 if( CB_GETTYPE(lphc) == CBS_DROPDOWN )
00353 lprLB->right -= COMBO_EDITBUTTONSPACE();
00354 }
00355 else
00356 lprLB->right = lprLB->left + lphc->droppedWidth;
00357 }
00358 #else
00359
00360
00361
00362 GetClientRect(hwnd, lprEdit);
00363
00364
00365
00366
00367 InflateRect(lprEdit, -COMBO_XBORDERSIZE(), -COMBO_YBORDERSIZE());
00368
00369
00370
00371
00372 lprEdit->bottom = lprEdit->top + CBGetTextAreaHeight(hwnd, lphc);
00373
00374
00375
00376
00377 CopyRect(lprButton, lprEdit);
00378
00379
00380
00381
00382 if( CB_GETTYPE(lphc) == CBS_SIMPLE )
00383 lprButton->left = lprButton->right = lprButton->bottom = 0;
00384 else
00385 {
00386
00387
00388
00389
00390
00391 lprButton->left = lprButton->right - GetSystemMetrics(SM_CXVSCROLL);
00392 lprEdit->right = lprButton->left;
00393 }
00394
00395
00396
00397
00398
00399 if( CB_GETTYPE(lphc) == CBS_DROPDOWN )
00400 {
00401 lprEdit->right -= COMBO_EDITBUTTONSPACE();
00402 }
00403
00404
00405
00406
00407 if (CB_GETTYPE(lphc) != CBS_DROPDOWNLIST)
00408 {
00409 InflateRect(lprEdit, -EDIT_CONTROL_PADDING(), -EDIT_CONTROL_PADDING());
00410 }
00411
00412
00413
00414
00415 if( CB_GETTYPE(lphc) == CBS_SIMPLE )
00416 {
00417
00418
00419
00420 GetClientRect(hwnd, lprLB);
00421
00422
00423
00424
00425 lprLB->top = lprEdit->bottom + COMBO_YBORDERSIZE();
00426 }
00427 else
00428 {
00429
00430 if(lphc->hWndLBox)
00431 GetWindowRect(lphc->hWndLBox, lprLB);
00432
00433
00434
00435
00436 if (lphc->droppedWidth < (lprButton->right + COMBO_XBORDERSIZE()))
00437 {
00438 lprLB->right = lprLB->left + (lprButton->right + COMBO_XBORDERSIZE());
00439
00440
00441
00442
00443
00444
00445 if( CB_GETTYPE(lphc) == CBS_DROPDOWN )
00446 lprLB->right -= COMBO_EDITBUTTONSPACE();
00447 }
00448 else
00449 lprLB->right = lprLB->left + lphc->droppedWidth;
00450 }
00451 #endif
00452
00453
00454
00455
00456
00457
00458
00459
00460 }
00461
00462
00463
00464
00465 static void CBGetDroppedControlRect( LPHEADCOMBO lphc, LPRECT lpRect)
00466 {
00467
00468
00469
00470 GetWindowRect(lphc->hwndself, lpRect);
00471
00472 lpRect->right = lpRect->left + lphc->droppedRect.right - lphc->droppedRect.left;
00473 lpRect->bottom = lpRect->top + lphc->droppedRect.bottom - lphc->droppedRect.top;
00474
00475 }
00476
00477
00478
00479
00480 static LRESULT COMBO_WindowPosChanging(HWND hwnd,WPARAM wParam,LPARAM lParam)
00481 {
00482 LPHEADCOMBO lphc = (LPHEADCOMBO)GetInfoPtr(hwnd);
00483 WINDOWPOS *posChanging = (WINDOWPOS*)lParam;
00484
00485 dprintf(("COMBO_WindowPosChanging"));
00486
00487
00488
00489
00490
00491
00492
00493 if ( ( CB_GETTYPE(lphc) != CBS_SIMPLE ) &&
00494 ((posChanging->flags & SWP_NOSIZE) == 0) )
00495 {
00496 int newComboHeight;
00497
00498 newComboHeight = CBGetTextAreaHeight(hwnd,lphc) +
00499 2*COMBO_YBORDERSIZE();
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509 if (posChanging->cy != newComboHeight)
00510 {
00511 if (posChanging->cy > newComboHeight)
00512 lphc->droppedRect.bottom = lphc->droppedRect.top + posChanging->cy - newComboHeight;
00513 posChanging->cy = newComboHeight;
00514 }
00515 }
00516
00517 return 0;
00518 }
00519
00520
00521
00522
00523 static LRESULT COMBO_Create(HWND hwnd,WPARAM wParam,LPARAM lParam)
00524 {
00525 static char clbName[] = "ComboLBox";
00526 static char editName[] = "Edit";
00527 LPHEADCOMBO lphc = (LPHEADCOMBO)GetInfoPtr(hwnd);
00528
00529 LPCREATESTRUCTA lpcs = (CREATESTRUCTA*)lParam;
00530
00531 if( !CB_GETTYPE(lphc) ) lphc->dwStyle |= CBS_SIMPLE;
00532 if( CB_GETTYPE(lphc) != CBS_DROPDOWNLIST ) lphc->wState |= CBF_EDIT;
00533
00534 lphc->hwndself = hwnd;
00535 lphc->owner = lpcs->hwndParent;
00536
00537
00538
00539
00540
00541 lphc->droppedWidth = lphc->editHeight = 0;
00542
00543
00544
00545
00546 lphc->wState |= CBF_MEASUREITEM;
00547
00548
00549
00550 if( lphc->owner || !(lpcs->style & WS_VISIBLE) )
00551 {
00552 UINT lbeStyle = 0;
00553 UINT lbeExStyle = 0;
00554
00555
00556
00557
00558
00559
00560 GetClientRect( hwnd, &lphc->droppedRect );
00561
00562 CBCalcPlacement(hwnd,
00563 lphc,
00564 &lphc->textRect,
00565 &lphc->buttonRect,
00566 &lphc->droppedRect );
00567
00568
00569
00570
00571 if ( CB_GETTYPE(lphc) != CBS_SIMPLE )
00572 {
00573 lphc->droppedRect.top = lphc->textRect.bottom + COMBO_YBORDERSIZE();
00574
00575
00576
00577
00578 if( CB_GETTYPE(lphc) == CBS_DROPDOWN )
00579 lphc->droppedRect.left += COMBO_EDITBUTTONSPACE();
00580
00581 ClientToScreen(hwnd, (LPPOINT)&lphc->droppedRect);
00582 ClientToScreen(hwnd, (LPPOINT)&lphc->droppedRect.right);
00583 }
00584
00585
00586
00587 lbeStyle = (LBS_NOTIFY | WS_BORDER | WS_CLIPSIBLINGS | WS_CHILD) |
00588 (lpcs->style & (WS_VSCROLL | CBS_OWNERDRAWFIXED | CBS_OWNERDRAWVARIABLE));
00589
00590 if( lphc->dwStyle & CBS_SORT )
00591 lbeStyle |= LBS_SORT;
00592 if( lphc->dwStyle & CBS_HASSTRINGS )
00593 lbeStyle |= LBS_HASSTRINGS;
00594 if( lphc->dwStyle & CBS_NOINTEGRALHEIGHT )
00595 lbeStyle |= LBS_NOINTEGRALHEIGHT;
00596 if( lphc->dwStyle & CBS_DISABLENOSCROLL )
00597 lbeStyle |= LBS_DISABLENOSCROLL;
00598
00599 if( CB_GETTYPE(lphc) == CBS_SIMPLE )
00600 {
00601 lbeStyle |= WS_VISIBLE;
00602
00603
00604
00605
00606
00607 lbeStyle &= ~WS_BORDER;
00608 lbeExStyle |= WS_EX_CLIENTEDGE;
00609 }
00610
00611 lphc->hWndLBox = CreateWindowExA(lbeExStyle,
00612 clbName,
00613 NULL,
00614 lbeStyle,
00615 lphc->droppedRect.left,
00616 lphc->droppedRect.top,
00617 lphc->droppedRect.right - lphc->droppedRect.left,
00618 lphc->droppedRect.bottom - lphc->droppedRect.top,
00619 lphc->hwndself,
00620 (HMENU)ID_CB_LISTBOX,
00621 GetWindowLongA(lphc->hwndself,GWL_HINSTANCE),
00622 (LPVOID)lphc );
00623
00624 if( lphc->hWndLBox )
00625 {
00626 BOOL bEdit = TRUE;
00627 lbeStyle = WS_CHILD | WS_VISIBLE | ES_NOHIDESEL | ES_LEFT | ES_COMBO;
00628
00629
00630
00631
00632
00633 if( lphc->wState & CBF_EDIT )
00634 {
00635 if( lphc->dwStyle & CBS_OEMCONVERT )
00636 lbeStyle |= ES_OEMCONVERT;
00637 if( lphc->dwStyle & CBS_AUTOHSCROLL )
00638 lbeStyle |= ES_AUTOHSCROLL;
00639 if( lphc->dwStyle & CBS_LOWERCASE )
00640 lbeStyle |= ES_LOWERCASE;
00641 else if( lphc->dwStyle & CBS_UPPERCASE )
00642 lbeStyle |= ES_UPPERCASE;
00643
00644 lphc->hWndEdit = CreateWindowExA(0,
00645 editName,
00646 NULL,
00647 lbeStyle,
00648 lphc->textRect.left, lphc->textRect.top,
00649 lphc->textRect.right - lphc->textRect.left,
00650 lphc->textRect.bottom - lphc->textRect.top,
00651 lphc->hwndself,
00652 (HMENU)ID_CB_EDIT,
00653 GetWindowLongA(lphc->hwndself,GWL_HINSTANCE),
00654 NULL );
00655
00656 if( !lphc->hWndEdit )
00657 bEdit = FALSE;
00658 }
00659
00660 if( bEdit )
00661 {
00662 if( CB_GETTYPE(lphc) != CBS_SIMPLE )
00663 {
00664
00665 SetParent(lphc->hWndLBox, HWND_DESKTOP);
00666
00667
00668
00669
00670
00671
00672
00673
00674 CBForceDummyResize(lphc);
00675 }
00676
00677
00678 return hwnd;
00679 }
00680
00681 }
00682 }
00683
00684
00685
00686 return -1;
00687 }
00688
00689
00690
00691
00692
00693
00694 static void CBPaintButton(
00695 LPHEADCOMBO lphc,
00696 HDC hdc,
00697 RECT rectButton)
00698 {
00699 if( lphc->wState & CBF_NOREDRAW )
00700 return;
00701
00702
00703 UINT buttonState = DFCS_SCROLLCOMBOBOX;
00704
00705 if (lphc->wState & CBF_BUTTONDOWN)
00706 {
00707 buttonState |= DFCS_PUSHED;
00708 }
00709
00710 if (CB_DISABLED(lphc))
00711 {
00712 buttonState |= DFCS_INACTIVE;
00713 }
00714
00715 DrawFrameControl(hdc,&rectButton,DFC_SCROLL,buttonState);
00716 }
00717
00718
00719
00720
00721
00722
00723 static void CBPaintText(
00724 LPHEADCOMBO lphc,
00725 HDC hdc,
00726 RECT rectEdit)
00727 {
00728 INT id, size = 0;
00729 LPSTR pText = NULL;
00730
00731 if( lphc->wState & CBF_NOREDRAW ) return;
00732
00733
00734
00735
00736 if( (id = SendMessageA(lphc->hWndLBox, LB_GETCURSEL, 0, 0) ) != LB_ERR )
00737 {
00738 size = SendMessageA( lphc->hWndLBox, LB_GETTEXTLEN, id, 0);
00739 if( (pText = (char*)HeapAlloc( GetProcessHeap(), 0, size + 1)) != NULL )
00740 {
00741 SendMessageA( lphc->hWndLBox, LB_GETTEXT, (WPARAM)id, (LPARAM)pText );
00742 pText[size] = '\0';
00743 } else return;
00744 }
00745
00746 if( lphc->wState & CBF_EDIT )
00747 {
00748 if( CB_HASSTRINGS(lphc) ) SetWindowTextA( lphc->hWndEdit, pText ? pText : "" );
00749 if( lphc->wState & CBF_FOCUSED )
00750 SendMessageA( lphc->hWndEdit, EM_SETSEL, 0, (LPARAM)(-1));
00751 }
00752 else
00753 {
00754 UINT itemState;
00755 HFONT hPrevFont = (lphc->hFont) ? SelectObject(hdc, lphc->hFont) : 0;
00756
00757
00758
00759
00760 InflateRect( &rectEdit, -1, -1 );
00761
00762 if ( (lphc->wState & CBF_FOCUSED) &&
00763 !(lphc->wState & CBF_DROPPED) )
00764 {
00765
00766
00767 FillRect( hdc, &rectEdit, GetSysColorBrush(COLOR_HIGHLIGHT) );
00768 SetBkColor( hdc, GetSysColor( COLOR_HIGHLIGHT ) );
00769 SetTextColor( hdc, GetSysColor( COLOR_HIGHLIGHTTEXT ) );
00770 itemState = ODS_SELECTED | ODS_FOCUS;
00771 }
00772 else
00773 itemState = 0;
00774
00775 if( CB_OWNERDRAWN(lphc) )
00776 {
00777 DRAWITEMSTRUCT dis;
00778 HRGN clipRegion;
00779 DWORD dwStyle = GetWindowLongA(lphc->hwndself,GWL_STYLE);
00780
00781
00782
00783
00784
00785
00786 clipRegion = CreateRectRgnIndirect(&rectEdit);
00787
00788 if (GetClipRgn(hdc, clipRegion)!=1)
00789 {
00790 DeleteObject(clipRegion);
00791 clipRegion=(HRGN)NULL;
00792 }
00793
00794 if ( dwStyle & WS_DISABLED )
00795 itemState |= ODS_DISABLED;
00796
00797 dis.CtlType = ODT_COMBOBOX;
00798 dis.CtlID = GetWindowLongA(lphc->hwndself,GWL_ID);
00799 dis.hwndItem = lphc->hwndself;
00800 dis.itemAction = ODA_DRAWENTIRE;
00801 dis.itemID = id;
00802 dis.itemState = itemState | ODS_COMBOBOXEDIT;
00803 dis.hDC = hdc;
00804 dis.rcItem = rectEdit;
00805 dis.itemData = SendMessageA( lphc->hWndLBox, LB_GETITEMDATA,
00806 (WPARAM)id, 0 );
00807
00808
00809
00810
00811 IntersectClipRect(hdc,
00812 rectEdit.left, rectEdit.top,
00813 rectEdit.right, rectEdit.bottom);
00814
00815 SendMessageA(lphc->owner, WM_DRAWITEM,
00816 GetWindowLongA(lphc->hwndself,GWL_ID), (LPARAM)&dis );
00817
00818
00819
00820
00821 SelectClipRgn(hdc, clipRegion);
00822 }
00823 else
00824 {
00825 ExtTextOutA( hdc,
00826 rectEdit.left + 1,
00827 rectEdit.top + 1,
00828 ETO_OPAQUE | ETO_CLIPPED,
00829 &rectEdit,
00830 pText ? pText : "" , size, NULL );
00831
00832 if(lphc->wState & CBF_FOCUSED && !(lphc->wState & CBF_DROPPED))
00833 DrawFocusRect( hdc, &rectEdit );
00834 }
00835
00836 if( hPrevFont )
00837 SelectObject(hdc, hPrevFont );
00838 }
00839 if (pText)
00840 HeapFree( GetProcessHeap(), 0, pText );
00841 }
00842
00843
00844
00845
00846 static void CBPaintBorder(
00847 HWND hwnd,
00848 LPHEADCOMBO lphc,
00849 HDC hdc)
00850 {
00851 RECT clientRect;
00852
00853 if (CB_GETTYPE(lphc) != CBS_SIMPLE)
00854 {
00855 GetClientRect(hwnd, &clientRect);
00856 }
00857 else
00858 {
00859 CopyRect(&clientRect, &lphc->textRect);
00860
00861 InflateRect(&clientRect, EDIT_CONTROL_PADDING(), EDIT_CONTROL_PADDING());
00862 InflateRect(&clientRect, COMBO_XBORDERSIZE(), COMBO_YBORDERSIZE());
00863 }
00864
00865 DrawEdge(hdc, &clientRect, EDGE_SUNKEN, BF_RECT);
00866 }
00867
00868
00869
00870
00871
00872
00873
00874
00875
00876 static HBRUSH COMBO_PrepareColors(
00877 HWND hwnd,
00878 LPHEADCOMBO lphc,
00879 HDC hDC)
00880 {
00881 HBRUSH hBkgBrush;
00882
00883
00884
00885
00886 if (CB_DISABLED(lphc))
00887 {
00888 hBkgBrush = SendMessageA( lphc->owner, WM_CTLCOLORSTATIC,
00889 hDC, lphc->hwndself );
00890
00891
00892
00893
00894
00895
00896 SetTextColor(hDC, GetSysColor(COLOR_GRAYTEXT));
00897 }
00898 else
00899 {
00900 if (lphc->wState & CBF_EDIT)
00901 {
00902 hBkgBrush = SendMessageA( lphc->owner, WM_CTLCOLOREDIT,
00903 hDC, lphc->hwndself );
00904 }
00905 else
00906 {
00907 hBkgBrush = SendMessageA( lphc->owner, WM_CTLCOLORLISTBOX,
00908 hDC, lphc->hwndself );
00909 }
00910 }
00911
00912
00913
00914
00915 if( !hBkgBrush )
00916 hBkgBrush = GetSysColorBrush(COLOR_WINDOW);
00917
00918 return hBkgBrush;
00919 }
00920
00921
00922
00923
00924 static LRESULT COMBO_EraseBackground(HWND hwnd,WPARAM wParam,LPARAM lParam)
00925 {
00926 LPHEADCOMBO lphc = (LPHEADCOMBO)GetInfoPtr(hwnd);
00927 HBRUSH hBkgBrush;
00928 RECT clientRect;
00929 HDC hDC;
00930
00931 hDC = (wParam) ? (HDC)wParam:GetDC(hwnd);
00932
00933
00934
00935
00936 if (CB_GETTYPE(lphc) != CBS_SIMPLE)
00937 {
00938 GetClientRect(hwnd, &clientRect);
00939 }
00940 else
00941 {
00942 CopyRect(&clientRect, &lphc->textRect);
00943
00944 InflateRect(&clientRect, COMBO_XBORDERSIZE(), COMBO_YBORDERSIZE());
00945 }
00946
00947
00948
00949
00950 hBkgBrush = COMBO_PrepareColors(hwnd, lphc, hDC);
00951
00952 FillRect(hDC, &clientRect, hBkgBrush);
00953
00954 if (!wParam)
00955 ReleaseDC(hwnd, hDC);
00956
00957 return TRUE;
00958 }
00959
00960 static LRESULT COMBO_GetDlgCode(HWND hwnd,WPARAM wParam,LPARAM lParam)
00961 {
00962 LPHEADCOMBO lphc = (LPHEADCOMBO)GetInfoPtr(hwnd);
00963 LRESULT result = DLGC_WANTARROWS | DLGC_WANTCHARS;
00964
00965 if (lParam && (((LPMSG)lParam)->message == WM_KEYDOWN))
00966 {
00967 int vk = (int)((LPMSG)lParam)->wParam;
00968
00969 if ((vk == VK_RETURN || vk == VK_ESCAPE) && (lphc->wState & CBF_DROPPED))
00970 result |= DLGC_WANTMESSAGE;
00971 }
00972 return result;
00973 }
00974
00975
00976
00977
00978 static LRESULT COMBO_Paint(HWND hwnd,WPARAM wParam,LPARAM lParam)
00979 {
00980 LPHEADCOMBO lphc = (LPHEADCOMBO)GetInfoPtr(hwnd);
00981 PAINTSTRUCT ps;
00982 HDC hDC;
00983
00984 hDC = (wParam) ? (HDC)wParam:BeginPaint(hwnd,&ps);
00985
00986
00987 if( hDC && !(lphc->wState & CBF_NOREDRAW) )
00988 {
00989 HBRUSH hPrevBrush, hBkgBrush;
00990
00991
00992
00993
00994
00995 hBkgBrush = COMBO_PrepareColors(hwnd,lphc,hDC);
00996
00997 hPrevBrush = SelectObject( hDC, hBkgBrush );
00998
00999
01000
01001
01002 CBPaintBorder(CB_HWND(lphc), lphc, hDC);
01003
01004 if( !IsRectEmpty(&lphc->buttonRect) )
01005 {
01006 CBPaintButton(lphc, hDC, lphc->buttonRect);
01007 }
01008
01009 if( !(lphc->wState & CBF_EDIT) )
01010 {
01011
01012
01013
01014
01015 CBPaintText( lphc, hDC, lphc->textRect);
01016 }
01017
01018 if( hPrevBrush )
01019 SelectObject( hDC, hPrevBrush );
01020 }
01021
01022 if(!wParam) EndPaint(hwnd,&ps);
01023
01024 return 0;
01025 }
01026
01027 static LRESULT COMBO_PrintClient(HWND hwnd,WPARAM wParam,LPARAM lParam)
01028 {
01029 if (lParam & PRF_ERASEBKGND) COMBO_EraseBackground(hwnd,wParam,lParam);
01030
01031 return COMBO_Paint(hwnd,wParam,lParam);
01032 }
01033
01034
01035
01036
01037
01038
01039 static INT CBUpdateLBox( LPHEADCOMBO lphc, BOOL bSelect )
01040 {
01041 INT length, idx;
01042 LPSTR pText = NULL;
01043
01044 idx = LB_ERR;
01045 length = CB_GETEDITTEXTLENGTH( lphc );
01046
01047 if( length > 0 )
01048 pText = (LPSTR) HeapAlloc( GetProcessHeap(), 0, length + 1);
01049
01050
01051
01052 if( pText )
01053 {
01054 if( length ) GetWindowTextA( lphc->hWndEdit, pText, length + 1);
01055 else pText[0] = '\0';
01056 idx = SendMessageA( lphc->hWndLBox, LB_FINDSTRING,
01057 (WPARAM)(-1), (LPARAM)pText );
01058 HeapFree( GetProcessHeap(), 0, pText );
01059 }
01060
01061 SendMessageA( lphc->hWndLBox, LB_SETCURSEL, (WPARAM)(bSelect ? idx : -1), 0 );
01062
01063
01064
01065
01066 SendMessageA( lphc->hWndLBox, LB_SETCARETINDEX, (WPARAM)(idx < 0 ? 0 : idx), 0 );
01067 SendMessageA( lphc->hWndLBox, LB_SETTOPINDEX, (WPARAM)(idx < 0 ? 0 : idx), 0 );
01068
01069 return idx;
01070 }
01071
01072
01073
01074
01075
01076
01077 static void CBUpdateEdit( LPHEADCOMBO lphc , INT index )
01078 {
01079 INT length;
01080 LPSTR pText = NULL;
01081
01082
01083
01084 if( index >= 0 )
01085 {
01086 length = SendMessageA( lphc->hWndLBox, LB_GETTEXTLEN, (WPARAM)index, 0);
01087 if( length )
01088 {
01089 pText = (LPSTR) HeapAlloc( GetProcessHeap(), 0, length + 1);
01090 if(pText)
01091 {
01092 SendMessageA( lphc->hWndLBox, LB_GETTEXT,
01093 (WPARAM)index, (LPARAM)pText );
01094 }
01095 }
01096 }
01097 lphc->wState |= CBF_NOEDITNOTIFY;
01098
01099 SendMessageA( lphc->hWndEdit, WM_SETTEXT, 0, pText ? (LPARAM)pText : (LPARAM)"" );
01100
01101 lphc->wState &= ~CBF_NOEDITNOTIFY;
01102
01103 if( lphc->wState & CBF_FOCUSED )
01104 SendMessageA( lphc->hWndEdit, EM_SETSEL, 0, (LPARAM)(-1) );
01105
01106
01107 if( pText )
01108 HeapFree( GetProcessHeap(), 0, pText );
01109 }
01110
01111
01112
01113
01114
01115
01116 static void CBDropDown( LPHEADCOMBO lphc )
01117 {
01118 RECT rect;
01119 int nItems = 0;
01120 int nDroppedHeight;
01121
01122 HWND hWnd = 0;
01123 RECT DesktopRect;
01124
01125
01126
01127 CB_NOTIFY( lphc, CBN_DROPDOWN );
01128
01129
01130
01131 lphc->wState |= CBF_DROPPED;
01132 if( CB_GETTYPE(lphc) == CBS_DROPDOWN )
01133 {
01134 lphc->droppedIndex = CBUpdateLBox( lphc,TRUE );
01135
01136 if( !(lphc->wState & CBF_CAPTURE) )
01137 CBUpdateEdit( lphc, lphc->droppedIndex );
01138 }
01139 else
01140 {
01141 lphc->droppedIndex = SendMessageA( lphc->hWndLBox, LB_GETCURSEL, 0, 0 );
01142
01143 if( lphc->droppedIndex == LB_ERR )
01144 lphc->droppedIndex = 0;
01145
01146 SendMessageA( lphc->hWndLBox, LB_SETTOPINDEX,
01147 (WPARAM)(lphc->droppedIndex == LB_ERR ? 0 : lphc->droppedIndex), 0 );
01148 SendMessageA( lphc->hWndLBox, LB_CARETON, 0, 0 );
01149 }
01150
01151
01152 GetWindowRect( lphc->hwndself, &rect );
01153
01154
01155
01156
01157 if( CB_GETTYPE(lphc) == CBS_DROPDOWN )
01158 rect.left += COMBO_EDITBUTTONSPACE();
01159
01160
01161
01162
01163
01164
01165 nDroppedHeight = lphc->droppedRect.bottom - lphc->droppedRect.top;
01166 nItems = (int)SendMessageA (lphc->hWndLBox, LB_GETCOUNT, 0, 0);
01167
01168 if (nItems > 0)
01169 {
01170 int nHeight;
01171
01172 nHeight = (int)SendMessageA (lphc->hWndLBox, LB_GETITEMHEIGHT, 0, 0);
01173 nHeight *= nItems;
01174
01175 if (nHeight < nDroppedHeight - COMBO_YBORDERSIZE())
01176 nDroppedHeight = nHeight + COMBO_YBORDERSIZE();
01177 }
01178
01179
01180 hWnd = GetDesktopWindow();
01181
01182 if( hWnd )
01183 {
01184 GetClientRect( hWnd, &DesktopRect );
01185 }
01186
01187
01188
01189 if((rect.bottom + nDroppedHeight) >= DesktopRect.bottom)
01190 rect.bottom = rect.top - nDroppedHeight;
01191
01192 SetWindowPos( lphc->hWndLBox, HWND_TOP, rect.left, rect.bottom,
01193 lphc->droppedRect.right - lphc->droppedRect.left,
01194 nDroppedHeight,
01195 SWP_NOACTIVATE | SWP_SHOWWINDOW);
01196
01197
01198 if( !(lphc->wState & CBF_NOREDRAW) )
01199 RedrawWindow( lphc->hwndself, NULL, 0, RDW_INVALIDATE |
01200 RDW_ERASE | RDW_UPDATENOW | RDW_NOCHILDREN );
01201
01202 EnableWindow( lphc->hWndLBox, TRUE );
01203 if (GetCapture() != lphc->hwndself)
01204 SetCapture(lphc->hWndLBox);
01205 }
01206
01207
01208
01209
01210
01211
01212 static void CBRollUp( LPHEADCOMBO lphc, BOOL ok, BOOL bButton )
01213 {
01214 HWND hWnd = lphc->hwndself;
01215
01216 CB_NOTIFY( lphc, (ok) ? CBN_SELENDOK : CBN_SELENDCANCEL );
01217
01218 if( IsWindow( hWnd ) && CB_GETTYPE(lphc) != CBS_SIMPLE )
01219 {
01220
01221
01222
01223 if( lphc->wState & CBF_DROPPED )
01224 {
01225 RECT rect;
01226
01227 lphc->wState &= ~CBF_DROPPED;
01228
01229
01230 ShowWindow( lphc->hWndLBox, SW_HIDE );
01231
01232 if( CB_GETTYPE(lphc) == CBS_DROPDOWN )
01233 {
01234 rect = lphc->buttonRect;
01235 }
01236 else
01237 {
01238 if( bButton )
01239 {
01240 UnionRect( &rect,
01241 &lphc->buttonRect,
01242 &lphc->textRect);
01243 }
01244 else
01245 rect = lphc->textRect;
01246
01247 bButton = TRUE;
01248 }
01249
01250 if( bButton && !(lphc->wState & CBF_NOREDRAW) )
01251 RedrawWindow( hWnd, &rect, 0, RDW_INVALIDATE |
01252 RDW_ERASE | RDW_UPDATENOW | RDW_NOCHILDREN );
01253 CB_NOTIFY( lphc, CBN_CLOSEUP );
01254 }
01255 }
01256 }
01257
01258
01259
01260
01261
01262
01263 BOOL COMBO_FlipListbox( LPHEADCOMBO lphc, BOOL ok, BOOL bRedrawButton )
01264 {
01265 if( lphc->wState & CBF_DROPPED )
01266 {
01267 CBRollUp( lphc, ok, bRedrawButton );
01268 return FALSE;
01269 }
01270
01271 CBDropDown( lphc );
01272 return TRUE;
01273 }
01274
01275
01276
01277
01278 static void CBRepaintButton( LPHEADCOMBO lphc )
01279 {
01280 InvalidateRect(CB_HWND(lphc), &lphc->buttonRect, TRUE);
01281 UpdateWindow(CB_HWND(lphc));
01282 }
01283
01284 static VOID COMBO_EditSetFocus(LPHEADCOMBO lphc)
01285 {
01286 if(!(lphc->wState & CBF_FOCUSED))
01287 {
01288 if( CB_GETTYPE(lphc) == CBS_DROPDOWNLIST )
01289 SendMessageA( lphc->hWndLBox, LB_CARETON, 0, 0 );
01290
01291 lphc->wState |= CBF_FOCUSED;
01292
01293 if( !(lphc->wState & CBF_EDIT) )
01294 InvalidateRect(CB_HWND(lphc), &lphc->textRect, TRUE);
01295
01296 CB_NOTIFY( lphc, CBN_SETFOCUS );
01297 }
01298 }
01299
01300
01301
01302
01303 static LRESULT COMBO_SetFocus(HWND hwnd,WPARAM wParam,LPARAM lParam)
01304 {
01305 LPHEADCOMBO lphc = (LPHEADCOMBO)GetInfoPtr(hwnd);
01306
01307
01308
01309
01310
01311
01312
01313
01314
01315
01316
01317 COMBO_EditSetFocus(lphc);
01318
01319 return 0;
01320 }
01321
01322 static VOID COMBO_EditKillFocus(LPHEADCOMBO lphc)
01323 {
01324 if( lphc->wState & CBF_FOCUSED )
01325 {
01326 CBRollUp( lphc, FALSE, TRUE );
01327 if( IsWindow( lphc->hwndself ) )
01328 {
01329 if( CB_GETTYPE(lphc) == CBS_DROPDOWNLIST )
01330 SendMessageA( lphc->hWndLBox, LB_CARETOFF, 0, 0 );
01331
01332 lphc->wState &= ~CBF_FOCUSED;
01333
01334
01335 if( !(lphc->wState & CBF_EDIT) )
01336 InvalidateRect(CB_HWND(lphc), &lphc->textRect, TRUE);
01337
01338 CB_NOTIFY( lphc, CBN_KILLFOCUS );
01339 }
01340 }
01341 }
01342
01343
01344
01345
01346 static LRESULT COMBO_KillFocus(HWND hwnd,WPARAM wParam,LPARAM lParam)
01347 {
01348 LPHEADCOMBO lphc = (LPHEADCOMBO)GetInfoPtr(hwnd);
01349
01350 if(!wParam || (wParam != lphc->hWndEdit && wParam != lphc->hWndLBox ))
01351 {
01352 COMBO_EditKillFocus(lphc);
01353 }
01354
01355 return 0;
01356 }
01357
01358
01359
01360
01361 static LRESULT COMBO_Command(HWND hwnd,WPARAM wParam,LPARAM lParam)
01362 {
01363 LPHEADCOMBO lphc = (LPHEADCOMBO)GetInfoPtr(hwnd);
01364
01365 if ( lphc->wState & CBF_EDIT && lphc->hWndEdit == lParam )
01366 {
01367
01368
01369 switch( HIWORD(wParam) >> 8 )
01370 {
01371 case (EN_SETFOCUS >> 8):
01372
01373
01374
01375
01376 COMBO_EditSetFocus(lphc);
01377 break;
01378
01379 case (EN_KILLFOCUS >> 8):
01380
01381
01382
01383
01384
01385
01386
01387
01388
01389
01390 COMBO_EditKillFocus(lphc);
01391 break;
01392
01393
01394 case (EN_CHANGE >> 8):
01395
01396
01397
01398
01399
01400
01401
01402 if (lphc->wState & CBF_NOEDITNOTIFY)
01403 {
01404 lphc->wState &= ~CBF_NOEDITNOTIFY;
01405 }
01406 else
01407 {
01408 CB_NOTIFY( lphc, CBN_EDITCHANGE );
01409 }
01410
01411 if (lphc->wState & CBF_NOLBSELECT)
01412 {
01413 lphc->wState &= ~CBF_NOLBSELECT;
01414 }
01415 else
01416 {
01417 CBUpdateLBox( lphc, lphc->wState & CBF_DROPPED );
01418 }
01419 break;
01420
01421 case (EN_UPDATE >> 8):
01422
01423
01424
01425
01426
01427
01428
01429
01430
01431 if (lphc->wState & CBF_NOEDITNOTIFY)
01432 {
01433 lphc->wState &= ~CBF_NOEDITNOTIFY;
01434 }
01435 else
01436 {
01437 CB_NOTIFY( lphc, CBN_EDITUPDATE );
01438 }
01439 break;
01440
01441 case (EN_ERRSPACE >> 8):
01442 CB_NOTIFY( lphc, CBN_ERRSPACE );
01443 }
01444 }
01445 else if( lphc->hWndLBox == lParam )
01446 {
01447 switch( HIWORD(wParam) )
01448 {
01449 case LBN_ERRSPACE:
01450 CB_NOTIFY( lphc, CBN_ERRSPACE );
01451 break;
01452
01453 case LBN_DBLCLK:
01454 CB_NOTIFY( lphc, CBN_DBLCLK );
01455 break;
01456
01457 case LBN_SELCHANGE:
01458 case LBN_SELCANCEL:
01459
01460
01461
01462
01463
01464
01465
01466 if( (CB_GETTYPE(lphc) == CBS_SIMPLE) ||
01467 ((lphc->wState & CBF_DROPPED) && !(lphc->wState & CBF_NOROLLUP)) )
01468 {
01469 CBRollUp( lphc, (HIWORD(wParam) == LBN_SELCHANGE), TRUE );
01470 }
01471 else lphc->wState &= ~CBF_NOROLLUP;
01472
01473 CB_NOTIFY( lphc, CBN_SELCHANGE );
01474
01475 if( HIWORD(wParam) == LBN_SELCHANGE)
01476 {
01477 if( lphc->wState & CBF_EDIT )
01478 {
01479 INT index = SendMessageA(lphc->hWndLBox, LB_GETCURSEL, 0, 0);
01480
01481 lphc->wState |= CBF_NOLBSELECT;
01482 CBUpdateEdit( lphc, index );
01483
01484 SendMessageA( lphc->hWndEdit, EM_SETSEL, 0, (LPARAM)(-1) );
01485 }
01486 else
01487 InvalidateRect(CB_HWND(lphc), &lphc->textRect, TRUE);
01488 }
01489
01490
01491
01492 case LBN_SETFOCUS:
01493 case LBN_KILLFOCUS:
01494
01495
01496 break;
01497 }
01498 }
01499 return 0;
01500 }
01501
01502
01503
01504
01505
01506
01507 static LRESULT COMBO_HandleItem(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
01508 {
01509 LPHEADCOMBO lphc = (LPHEADCOMBO)GetInfoPtr(hwnd);
01510
01511
01512
01513 #define lpIS ((LPDELETEITEMSTRUCT)lParam)
01514
01515
01516 lpIS->CtlType = ODT_COMBOBOX;
01517 lpIS->CtlID = GetWindowLongA(hwnd,GWL_ID);
01518
01519 switch( msg )
01520 {
01521 case WM_DELETEITEM:
01522 lpIS->hwndItem = hwnd;
01523 #undef lpIS
01524 break;
01525 case WM_DRAWITEM:
01526 #define lpIS ((LPDRAWITEMSTRUCT)lParam)
01527 lpIS->hwndItem = hwnd;
01528 #undef lpIS
01529 break;
01530 case WM_COMPAREITEM:
01531 #define lpIS ((LPCOMPAREITEMSTRUCT)lParam)
01532 lpIS->hwndItem = hwnd;
01533 #undef lpIS
01534 break;
01535 }
01536 return SendMessageA( GetParent(hwnd), msg, GetWindowLongA(hwnd,GWL_ID), lParam );
01537 }
01538
01539
01540
01541
01542 static LRESULT COMBO_GetText(HWND hwnd,WPARAM wParam,LPARAM lParam)
01543 {
01544 LPHEADCOMBO lphc = (LPHEADCOMBO)GetInfoPtr(hwnd);
01545
01546 if( lphc->wState & CBF_EDIT )
01547 return SendMessageA( lphc->hWndEdit, WM_GETTEXT,
01548 wParam,lParam);
01549
01550
01551
01552 if( lphc->hWndLBox )
01553 {
01554 INT idx = SendMessageA( lphc->hWndLBox, LB_GETCURSEL, 0, 0 );
01555 if( idx != LB_ERR )
01556 {
01557 LPSTR lpBuffer;
01558 INT length = SendMessageA( lphc->hWndLBox, LB_GETTEXTLEN,
01559 (WPARAM)idx, 0 );
01560
01561
01562 if( length >= (UINT)wParam )
01563 lpBuffer = (LPSTR) HeapAlloc( GetProcessHeap(), 0, length + 1 );
01564 else
01565 lpBuffer = (LPSTR)lParam;
01566
01567 if( lpBuffer )
01568 {
01569 INT n = SendMessageA( lphc->hWndLBox, LB_GETTEXT,
01570 (WPARAM)idx, (LPARAM)lpBuffer );
01571
01572
01573
01574 if( length >= (UINT)wParam )
01575 {
01576 if ((UINT)wParam && lParam) {
01577 if( n != LB_ERR ) memcpy( (LPSTR)lParam, lpBuffer, ((UINT)wParam>n) ? n+1 : (UINT)wParam-1 );
01578 ((LPSTR)lParam)[(UINT)wParam - 1] = '\0';
01579 }
01580 HeapFree( GetProcessHeap(), 0, lpBuffer );
01581 }
01582 return (LRESULT)n;
01583 }
01584 }
01585 }
01586 return 0;
01587 }
01588
01589 static LRESULT COMBO_GetTextLength(HWND hwnd,WPARAM wParam,LPARAM lParam)
01590 {
01591 LPHEADCOMBO lphc = (LPHEADCOMBO)GetInfoPtr(hwnd);
01592
01593 if (!(lphc->wState & CBF_EDIT))
01594 {
01595 int idx = SendMessageA( lphc->hWndLBox, LB_GETCURSEL, 0, 0 );
01596
01597 if (idx == -1) return 0;
01598 return SendMessageA( lphc->hWndLBox, LB_GETTEXTLEN, idx, 0 );
01599 } else if (lphc->wState & CBF_EDIT)
01600 {
01601
01602 return SendMessageA( lphc->hWndEdit, WM_GETTEXTLENGTH, wParam, lParam );
01603 } else return CB_ERR;
01604 }
01605
01606 static LRESULT COMBO_HandleText(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
01607 {
01608 LPHEADCOMBO lphc = (LPHEADCOMBO)GetInfoPtr(hwnd);
01609
01610 if (lphc == NULL)
01611 {
01612 dprintf(("COMBO_HandleText Info Pointer NULL!\n"));
01613 return CB_ERR;
01614 }
01615
01616 if (lphc->wState & CBF_EDIT)
01617 {
01618 LRESULT res;
01619
01620 lphc->wState |= CBF_NOEDITNOTIFY;
01621 res = SendMessageA( lphc->hWndEdit, message, wParam, lParam );
01622 lphc->wState &= ~CBF_NOEDITNOTIFY;
01623 return res;
01624 } else return CB_ERR;
01625 }
01626
01627
01628
01629
01630
01631
01632
01633 static void CBResetPos(
01634 LPHEADCOMBO lphc,
01635 LPRECT rectEdit,
01636 LPRECT rectLB,
01637 BOOL bRedraw)
01638 {
01639 BOOL bDrop = (CB_GETTYPE(lphc) != CBS_SIMPLE);
01640
01641
01642
01643
01644 if( lphc->wState & CBF_EDIT )
01645 SetWindowPos( lphc->hWndEdit, 0,
01646 rectEdit->left, rectEdit->top,
01647 rectEdit->right - rectEdit->left,
01648 rectEdit->bottom - rectEdit->top,
01649 SWP_NOZORDER | SWP_NOACTIVATE | ((bDrop) ? SWP_NOREDRAW : 0) );
01650
01651 SetWindowPos( lphc->hWndLBox, 0,
01652 rectLB->left, rectLB->top,
01653 rectLB->right - rectLB->left,
01654 rectLB->bottom - rectLB->top,
01655 SWP_NOACTIVATE | SWP_NOZORDER | ((bDrop) ? SWP_NOREDRAW : 0) );
01656
01657 if( bDrop )
01658 {
01659 if( lphc->wState & CBF_DROPPED )
01660 {
01661 lphc->wState &= ~CBF_DROPPED;
01662 ShowWindow( lphc->hWndLBox, SW_HIDE );
01663 }
01664
01665 if( bRedraw && !(lphc->wState & CBF_NOREDRAW) )
01666 RedrawWindow( lphc->hwndself, NULL, 0,
01667 RDW_INVALIDATE | RDW_ERASE | RDW_UPDATENOW );
01668 }
01669 }
01670
01671
01672
01673
01674
01675 static LRESULT COMBO_Size(HWND hwnd,WPARAM wParam,LPARAM lParam)
01676 {
01677 LPHEADCOMBO lphc = (LPHEADCOMBO)GetInfoPtr(hwnd);
01678
01679 dprintf(("COMBO_Size"));
01680
01681 if(lphc->hWndLBox && !(lphc->wState & CBF_NORESIZE))
01682 {
01683 CBCalcPlacement(hwnd,
01684 lphc,
01685 &lphc->textRect,
01686 &lphc->buttonRect,
01687 &lphc->droppedRect);
01688
01689 CBResetPos( lphc, &lphc->textRect, &lphc->droppedRect, TRUE );
01690 }
01691
01692 return 0;
01693 }
01694
01695
01696
01697
01698
01699 static LRESULT COMBO_SetFont(HWND hwnd,WPARAM wParam,LPARAM lParam)
01700 {
01701 LPHEADCOMBO lphc = (LPHEADCOMBO)GetInfoPtr(hwnd);
01702
01703
01704
01705
01706 lphc->hFont = wParam;
01707
01708
01709
01710
01711 if( lphc->wState & CBF_EDIT )
01712 SendMessageA(lphc->hWndEdit,WM_SETFONT,wParam,lParam);
01713 SendMessageA(lphc->hWndLBox,WM_SETFONT,wParam,lParam);
01714
01715
01716
01717
01718 if ( CB_GETTYPE(lphc) == CBS_SIMPLE)
01719 {
01720 CBCalcPlacement(hwnd,
01721 lphc,
01722 &lphc->textRect,
01723 &lphc->buttonRect,
01724 &lphc->droppedRect);
01725
01726 CBResetPos( lphc, &lphc->textRect, &lphc->droppedRect, TRUE );
01727 }
01728 else
01729 {
01730 CBForceDummyResize(lphc);
01731 }
01732
01733 return 0;
01734 }
01735
01736 static LRESULT COMBO_GetFont(HWND hwnd,WPARAM wParam,LPARAM lParam)
01737 {
01738 LPHEADCOMBO lphc = (LPHEADCOMBO)GetInfoPtr(hwnd);
01739
01740 return lphc->hFont;
01741 }
01742
01743
01744
01745
01746
01747 static LRESULT COMBO_LButtonDown(HWND hwnd,WPARAM wParam,LPARAM lParam)
01748 {
01749 LPHEADCOMBO lphc = (LPHEADCOMBO)GetInfoPtr(hwnd);
01750 POINT pt;
01751 BOOL bButton;
01752
01753 if(!(lphc->wState & CBF_FOCUSED)) SetFocus(hwnd);
01754 if(!(lphc->wState & CBF_FOCUSED)) return 0;
01755
01756 pt.x = LOWORD(lParam);
01757 pt.y = HIWORD(lParam);
01758 bButton = PtInRect(&lphc->buttonRect, pt);
01759
01760 if( (CB_GETTYPE(lphc) == CBS_DROPDOWNLIST) ||
01761 (bButton && (CB_GETTYPE(lphc) == CBS_DROPDOWN)) )
01762 {
01763 lphc->wState |= CBF_BUTTONDOWN;
01764 if( lphc->wState & CBF_DROPPED )
01765 {
01766
01767
01768 lphc->wState &= ~CBF_BUTTONDOWN;
01769 CBRollUp( lphc, TRUE, FALSE );
01770 if( !IsWindow( hwnd ) ) return 0;
01771
01772 if( lphc->wState & CBF_CAPTURE )
01773 {
01774 lphc->wState &= ~CBF_CAPTURE;
01775 ReleaseCapture();
01776 }
01777 }
01778 else
01779 {
01780
01781
01782 lphc->wState |= CBF_CAPTURE;
01783 SetCapture( hwnd );
01784 CBDropDown( lphc );
01785 }
01786 if( bButton ) CBRepaintButton( lphc );
01787 }
01788
01789 return 0;
01790 }
01791
01792
01793
01794
01795
01796
01797 static LRESULT COMBO_LButtonUp(HWND hwnd,WPARAM wParam,LPARAM lParam)
01798 {
01799 LPHEADCOMBO lphc = (LPHEADCOMBO)GetInfoPtr(hwnd);
01800
01801 if( lphc->wState & CBF_CAPTURE )
01802 {
01803 lphc->wState &= ~CBF_CAPTURE;
01804 if( CB_GETTYPE(lphc) == CBS_DROPDOWN )
01805 {
01806 INT index = CBUpdateLBox( lphc, TRUE );
01807
01808 lphc->wState |= CBF_NOLBSELECT;
01809 CBUpdateEdit( lphc, index );
01810 lphc->wState &= ~CBF_NOLBSELECT;
01811 }
01812 SetCapture(lphc->hWndLBox);
01813 }
01814
01815 if( lphc->wState & CBF_BUTTONDOWN )
01816 {
01817 lphc->wState &= ~CBF_BUTTONDOWN;
01818 CBRepaintButton( lphc );
01819 }
01820
01821 return 0;
01822 }
01823
01824
01825
01826
01827
01828
01829
01830 static LRESULT COMBO_MouseMove(HWND hwnd,WPARAM wParam,LPARAM lParam)
01831 {
01832 LPHEADCOMBO lphc = (LPHEADCOMBO)GetInfoPtr(hwnd);
01833 POINT pt;
01834 RECT lbRect;
01835
01836 if(!(lphc->wState & CBF_CAPTURE)) return 0;
01837
01838 pt.x = LOWORD(lParam);
01839 pt.y = HIWORD(lParam);
01840
01841 if( lphc->wState & CBF_BUTTONDOWN )
01842 {
01843 BOOL bButton;
01844
01845 bButton = PtInRect(&lphc->buttonRect, pt);
01846
01847 if( !bButton )
01848 {
01849 lphc->wState &= ~CBF_BUTTONDOWN;
01850 CBRepaintButton( lphc );
01851 }
01852 }
01853
01854 GetClientRect( lphc->hWndLBox, &lbRect );
01855 MapWindowPoints(hwnd, lphc->hWndLBox, &pt, 1 );
01856 if( PtInRect(&lbRect, pt) )
01857 {
01858 lphc->wState &= ~CBF_CAPTURE;
01859 ReleaseCapture();
01860 if( CB_GETTYPE(lphc) == CBS_DROPDOWN ) CBUpdateLBox( lphc,TRUE );
01861
01862
01863 SendMessageA( lphc->hWndLBox, WM_LBUTTONDOWN, wParam, lParam );
01864 }
01865
01866 return 0;
01867 }
01868
01869 static LRESULT COMBO_MouseWheel(HWND hwnd,WPARAM wParam,LPARAM lParam)
01870 {
01871 if (wParam & (MK_SHIFT | MK_CONTROL))
01872 return DefWindowProcA(hwnd,WM_MOUSEWHEEL,wParam,lParam);
01873
01874 if ((short) HIWORD(wParam) > 0) return SendMessageA(hwnd,WM_KEYDOWN,VK_UP,0);
01875 if ((short) HIWORD(wParam) < 0) return SendMessageA(hwnd,WM_KEYDOWN,VK_DOWN,0);
01876
01877 return TRUE;
01878 }
01879
01880 static LRESULT COMBO_Enable(HWND hwnd,WPARAM wParam,LPARAM lParam)
01881 {
01882 LPHEADCOMBO lphc = (LPHEADCOMBO)GetInfoPtr(hwnd);
01883
01884 if( lphc->wState & CBF_EDIT )
01885 EnableWindow( lphc->hWndEdit, (BOOL)wParam );
01886 EnableWindow( lphc->hWndLBox, (BOOL)wParam );
01887
01888
01889 InvalidateRect(CB_HWND(lphc), NULL, TRUE);
01890
01891 return 0;
01892 }
01893
01894 static LRESULT COMBO_SetRedraw(HWND hwnd,WPARAM wParam,LPARAM lParam)
01895 {
01896 LPHEADCOMBO lphc = (LPHEADCOMBO)GetInfoPtr(hwnd);
01897
01898 if( wParam )
01899 lphc->wState &= ~CBF_NOREDRAW;
01900 else
01901 lphc->wState |= CBF_NOREDRAW;
01902
01903 if( lphc->wState & CBF_EDIT )
01904 SendMessageA( lphc->hWndEdit, WM_SETREDRAW, wParam, lParam );
01905 SendMessageA( lphc->hWndLBox, WM_SETREDRAW, wParam, lParam );
01906
01907 return 0;
01908 }
01909
01910 static LRESULT COMBO_SysKeyDown(HWND hwnd,WPARAM wParam,LPARAM lParam)
01911 {
01912 LPHEADCOMBO lphc = (LPHEADCOMBO)GetInfoPtr(hwnd);
01913
01914 if( KEYDATA_ALT & HIWORD(lParam) )
01915 if( wParam == VK_UP || wParam == VK_DOWN )
01916 COMBO_FlipListbox( lphc,FALSE,FALSE );
01917
01918 return 0;
01919 }
01920
01921 static LRESULT COMBO_HandleKey(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
01922 {
01923 LPHEADCOMBO lphc = (LPHEADCOMBO)GetInfoPtr(hwnd);
01924
01925 if (((CHAR)wParam == VK_RETURN || (CHAR)wParam == VK_ESCAPE) && (lphc->wState & CBF_DROPPED))
01926 {
01927 CBRollUp( lphc, (CHAR)wParam == VK_RETURN, FALSE );
01928 return TRUE;
01929 }
01930
01931 if( lphc->wState & CBF_EDIT )
01932 return SendMessageA( lphc->hWndEdit, message, wParam, lParam );
01933 else
01934 return SendMessageA( lphc->hWndLBox, message, wParam, lParam );
01935 }
01936
01937
01938
01939 static LRESULT COMBO_AddString(HWND hwnd,WPARAM wParam,LPARAM lParam)
01940 {
01941 LPHEADCOMBO lphc = (LPHEADCOMBO)GetInfoPtr(hwnd);
01942
01943 return SendMessageA(lphc->hWndLBox,LB_ADDSTRING,0,lParam);
01944 }
01945
01946 static LRESULT COMBO_InsertString(HWND hwnd,WPARAM wParam,LPARAM lParam)
01947 {
01948 LPHEADCOMBO lphc = (LPHEADCOMBO)GetInfoPtr(hwnd);
01949
01950 return SendMessageA(lphc->hWndLBox,LB_INSERTSTRING,wParam,lParam);
01951 }
01952
01953 static LRESULT COMBO_DeleteString(HWND hwnd,WPARAM wParam,LPARAM lParam)
01954 {
01955 LPHEADCOMBO lphc = (LPHEADCOMBO)GetInfoPtr(hwnd);
01956
01957 return SendMessageA(lphc->hWndLBox,LB_DELETESTRING,wParam,0);
01958 }
01959
01960
01961
01962
01963 static LRESULT COMBO_SelectString(HWND hwnd,WPARAM wParam,LPARAM lParam)
01964 {
01965 LPHEADCOMBO lphc = (LPHEADCOMBO)GetInfoPtr(hwnd);
01966 INT CurSel = SendMessageA( lphc->hWndLBox, LB_GETCURSEL, 0, 0 );
01967 INT index = SendMessageA(lphc->hWndLBox,LB_SELECTSTRING,wParam,lParam);
01968
01969 if( index >= 0 )
01970 {
01971 if( lphc->wState & CBF_EDIT )
01972 {
01973 if (CurSel != index)
01974 CBUpdateEdit( lphc, index );
01975 } else
01976 InvalidateRect(CB_HWND(lphc), &lphc->textRect, TRUE);
01977 }
01978
01979 return (LRESULT)index;
01980 }
01981
01982 static LRESULT COMBO_FindString(HWND hwnd,WPARAM wParam,LPARAM lParam)
01983 {
01984 LPHEADCOMBO lphc = (LPHEADCOMBO)GetInfoPtr(hwnd);
01985
01986 return SendMessageA(lphc->hWndLBox,LB_FINDSTRING,wParam,lParam);
01987 }
01988
01989 static LRESULT COMBO_FindStringExact(HWND hwnd,WPARAM wParam,LPARAM lParam)
01990 {
01991 LPHEADCOMBO lphc = (LPHEADCOMBO)GetInfoPtr(hwnd);
01992
01993 return SendMessageA(lphc->hWndLBox,LB_FINDSTRINGEXACT,wParam,lParam);
01994 }
01995
01996
01997
01998
01999 static LRESULT COMBO_SetItemHeight(HWND hwnd,WPARAM wParam,LPARAM lParam)
02000 {
02001 LPHEADCOMBO lphc = (LPHEADCOMBO)GetInfoPtr(hwnd);
02002 LRESULT lRet = CB_ERR;
02003
02004 if( wParam == -1 )
02005 {
02006 if( lParam < 32768 )
02007 {
02008 lphc->editHeight = lParam;
02009
02010
02011
02012
02013 if ( CB_GETTYPE(lphc) == CBS_SIMPLE)
02014 {
02015 CBCalcPlacement(hwnd,
02016 lphc,
02017 &lphc->textRect,
02018 &lphc->buttonRect,
02019 &lphc->droppedRect);
02020
02021 CBResetPos( lphc, &lphc->textRect, &lphc->droppedRect, TRUE );
02022 }
02023 else
02024 {
02025 CBForceDummyResize(lphc);
02026 }
02027
02028 lRet = lParam;
02029 }
02030 }
02031 else if ( CB_OWNERDRAWN(lphc) )
02032 lRet = SendMessageA( lphc->hWndLBox, LB_SETITEMHEIGHT,
02033 wParam,lParam);
02034 return lRet;
02035 }
02036
02037 static LRESULT COMBO_GetItemHeight(HWND hwnd,WPARAM wParam,LPARAM lParam)
02038 {
02039 LPHEADCOMBO lphc = (LPHEADCOMBO)GetInfoPtr(hwnd);
02040
02041 if( (INT)wParam >= 0 )
02042 return SendMessageA( lphc->hWndLBox, LB_GETITEMHEIGHT, wParam, 0);
02043
02044 return CBGetTextAreaHeight(hwnd, lphc);
02045 }
02046
02047 static LRESULT COMBO_ResetContent(HWND hwnd,WPARAM wParam,LPARAM lParam)
02048 {
02049 LPHEADCOMBO lphc = (LPHEADCOMBO)GetInfoPtr(hwnd);
02050
02051 SendMessageA( lphc->hWndLBox, LB_RESETCONTENT, 0, 0 );
02052 InvalidateRect(CB_HWND(lphc), NULL, TRUE);
02053
02054 return TRUE;
02055 }
02056
02057 static LRESULT COMBO_InitStorage(HWND hwnd,WPARAM wParam,LPARAM lParam)
02058 {
02059 LPHEADCOMBO lphc = (LPHEADCOMBO)GetInfoPtr(hwnd);
02060
02061 return SendMessageA( lphc->hWndLBox, LB_INITSTORAGE, wParam, lParam);
02062 }
02063
02064 static LRESULT COMBO_GetHorizontalExtent(HWND hwnd,WPARAM wParam,LPARAM lParam)
02065 {
02066 LPHEADCOMBO lphc = (LPHEADCOMBO)GetInfoPtr(hwnd);
02067
02068 return SendMessageA( lphc->hWndLBox, LB_GETHORIZONTALEXTENT, 0, 0);
02069 }
02070
02071 static LRESULT COMBO_SetHorizontalExtent(HWND hwnd,WPARAM wParam,LPARAM lParam)
02072 {
02073 LPHEADCOMBO lphc = (LPHEADCOMBO)GetInfoPtr(hwnd);
02074
02075 return SendMessageA( lphc->hWndLBox, LB_SETHORIZONTALEXTENT, wParam, 0);
02076 }
02077
02078 static LRESULT COMBO_GetTopIndex(HWND hwnd,WPARAM wParam,LPARAM lParam)
02079 {
02080 LPHEADCOMBO lphc = (LPHEADCOMBO)GetInfoPtr(hwnd);
02081
02082 return SendMessageA( lphc->hWndLBox, LB_GETTOPINDEX, 0, 0);
02083 }
02084
02085 static LRESULT COMBO_GetLocale(HWND hwnd,WPARAM wParam,LPARAM lParam)
02086 {
02087 LPHEADCOMBO lphc = (LPHEADCOMBO)GetInfoPtr(hwnd);
02088
02089 return SendMessageA( lphc->hWndLBox, LB_GETLOCALE, 0, 0);
02090 }
02091
02092 static LRESULT COMBO_SetLocale(HWND hwnd,WPARAM wParam,LPARAM lParam)
02093 {
02094 LPHEADCOMBO lphc = (LPHEADCOMBO)GetInfoPtr(hwnd);
02095
02096 return SendMessageA( lphc->hWndLBox, LB_SETLOCALE, wParam, 0);
02097 }
02098
02099 static LRESULT COMBO_GetDroppedWidth(HWND hwnd,WPARAM wParam,LPARAM lParam)
02100 {
02101 LPHEADCOMBO lphc = (LPHEADCOMBO)GetInfoPtr(hwnd);
02102
02103 if( lphc->droppedWidth )
02104 return lphc->droppedWidth;
02105
02106 return lphc->droppedRect.right - lphc->droppedRect.left;
02107 }
02108
02109 static LRESULT COMBO_SetDroppedWidth(HWND hwnd,WPARAM wParam,LPARAM lParam)
02110 {
02111 LPHEADCOMBO lphc = (LPHEADCOMBO)GetInfoPtr(hwnd);
02112
02113 if( (CB_GETTYPE(lphc) != CBS_SIMPLE) &&
02114 (INT)wParam < 32768 ) lphc->droppedWidth = (INT)wParam;
02115
02116 return CB_ERR;
02117 }
02118
02119 static LRESULT COMBO_GetDroppedControlRect(HWND hwnd,WPARAM wParam,LPARAM lParam)
02120 {
02121 LPHEADCOMBO lphc = (LPHEADCOMBO)GetInfoPtr(hwnd);
02122
02123 if( lParam ) CBGetDroppedControlRect(lphc, (LPRECT)lParam );
02124
02125 return CB_OKAY;
02126 }
02127
02128 static LRESULT COMBO_GetDroppedState(HWND hwnd,WPARAM wParam,LPARAM lParam)
02129 {
02130 LPHEADCOMBO lphc = (LPHEADCOMBO)GetInfoPtr(hwnd);
02131
02132 return (lphc->wState & CBF_DROPPED) ? TRUE : FALSE;
02133 }
02134
02135 static LRESULT COMBO_Dir(HWND hwnd,WPARAM wParam,LPARAM lParam)
02136 {
02137 LPHEADCOMBO lphc = (LPHEADCOMBO)GetInfoPtr(hwnd);
02138
02139 return COMBO_Directory( lphc, (UINT)wParam,
02140 (LPSTR)lParam,TRUE);
02141 }
02142
02143 static LRESULT COMBO_ShowDropDown(HWND hwnd,WPARAM wParam,LPARAM lParam)
02144 {
02145 LPHEADCOMBO lphc = (LPHEADCOMBO)GetInfoPtr(hwnd);
02146
02147 if( CB_GETTYPE(lphc) != CBS_SIMPLE )
02148 {
02149 if( wParam )
02150 {
02151 if( !(lphc->wState & CBF_DROPPED) )
02152 CBDropDown( lphc );
02153 }
02154 else
02155 if( lphc->wState & CBF_DROPPED )
02156 CBRollUp( lphc, FALSE, TRUE );
02157 }
02158
02159 return TRUE;
02160 }
02161
02162 static LRESULT COMBO_GetCount(HWND hwnd,WPARAM wParam,LPARAM lParam)
02163 {
02164 LPHEADCOMBO lphc = (LPHEADCOMBO)GetInfoPtr(hwnd);
02165
02166 return SendMessageA( lphc->hWndLBox, LB_GETCOUNT, 0, 0);
02167 }
02168
02169 static LRESULT COMBO_GetCurSel(HWND hwnd,WPARAM wParam,LPARAM lParam)
02170 {
02171 LPHEADCOMBO lphc = (LPHEADCOMBO)GetInfoPtr(hwnd);
02172
02173 return SendMessageA( lphc->hWndLBox, LB_GETCURSEL, 0, 0);
02174 }
02175
02176 static LRESULT COMBO_SetCurSel(HWND hwnd,WPARAM wParam,LPARAM lParam)
02177 {
02178 LPHEADCOMBO lphc = (LPHEADCOMBO)GetInfoPtr(hwnd);
02179
02180 lParam = SendMessageA( lphc->hWndLBox, LB_SETCURSEL, wParam, 0);
02181 if( lParam >= 0 )
02182 SendMessageA( lphc->hWndLBox, LB_SETTOPINDEX, wParam, 0);
02183 if( lphc->wState & CBF_SELCHANGE )
02184 {
02185
02186
02187 lphc->wState &= ~CBF_SELCHANGE;
02188
02189
02190 if( lphc->wState & CBF_EDIT )
02191 CBUpdateEdit( lphc, (INT)wParam );
02192 else
02193 InvalidateRect(CB_HWND(lphc), &lphc->textRect, TRUE);
02194 }
02195
02196 return lParam;
02197 }
02198
02199 static LRESULT COMBO_GetLBText(HWND hwnd,WPARAM wParam,LPARAM lParam)
02200 {
02201 LPHEADCOMBO lphc = (LPHEADCOMBO)GetInfoPtr(hwnd);
02202
02203 return SendMessageA( lphc->hWndLBox, LB_GETTEXT, wParam, lParam);
02204 }
02205
02206 static LRESULT COMBO_GetLBTextLen(HWND hwnd,WPARAM wParam,LPARAM lParam)
02207 {
02208 LPHEADCOMBO lphc = (LPHEADCOMBO)GetInfoPtr(hwnd);
02209
02210 return SendMessageA( lphc->hWndLBox, LB_GETTEXTLEN, wParam, 0);
02211 }
02212
02213 static LRESULT COMBO_GetItemData(HWND hwnd,WPARAM wParam,LPARAM lParam)
02214 {
02215 LPHEADCOMBO lphc = (LPHEADCOMBO)GetInfoPtr(hwnd);
02216
02217 return SendMessageA( lphc->hWndLBox, LB_GETITEMDATA, wParam, 0);
02218 }
02219
02220 static LRESULT COMBO_SetItemData(HWND hwnd,WPARAM wParam,LPARAM lParam)
02221 {
02222 LPHEADCOMBO lphc = (LPHEADCOMBO)GetInfoPtr(hwnd);
02223
02224 return SendMessageA( lphc->hWndLBox, LB_SETITEMDATA, wParam, lParam);
02225 }
02226
02227 static LRESULT COMBO_GetEditSel(HWND hwnd,WPARAM wParam,LPARAM lParam)
02228 {
02229 LPHEADCOMBO lphc = (LPHEADCOMBO)GetInfoPtr(hwnd);
02230
02231 if( lphc->wState & CBF_EDIT )
02232 {
02233 INT a, b;
02234
02235 return SendMessageA( lphc->hWndEdit, EM_GETSEL,
02236 (wParam) ? wParam : (WPARAM)&a,
02237 (lParam) ? lParam : (LPARAM)&b );
02238 }
02239
02240 return CB_ERR;
02241 }
02242
02243 static LRESULT COMBO_SetEditSel(HWND hwnd,WPARAM wParam,LPARAM lParam)
02244 {
02245 LPHEADCOMBO lphc = (LPHEADCOMBO)GetInfoPtr(hwnd);
02246
02247 if( lphc->wState & CBF_EDIT )
02248 return SendMessageA( lphc->hWndEdit, EM_SETSEL,
02249 (INT)(INT16)LOWORD(lParam), (INT)(INT16)HIWORD(lParam) );
02250
02251 return CB_ERR;
02252 }
02253
02254 static LRESULT COMBO_SetExtendedUI(HWND hwnd,WPARAM wParam,LPARAM lParam)
02255 {
02256 LPHEADCOMBO lphc = (LPHEADCOMBO)GetInfoPtr(hwnd);
02257
02258 if( CB_GETTYPE(lphc) == CBS_SIMPLE )
02259 return CB_ERR;
02260 if( wParam )
02261 lphc->wState |= CBF_EUI;
02262 else lphc->wState &= ~CBF_EUI;
02263 return CB_OKAY;
02264 }
02265
02266 static LRESULT COMBO_GetExtendedUI(HWND hwnd,WPARAM wParam,LPARAM lParam)
02267 {
02268 LPHEADCOMBO lphc = (LPHEADCOMBO)GetInfoPtr(hwnd);
02269
02270 return (lphc->wState & CBF_EUI) ? TRUE : FALSE;
02271 }
02272
02273
02274
02275
02276
02277
02278 LRESULT WINAPI ComboWndProc( HWND hwnd, UINT message,
02279 WPARAM wParam, LPARAM lParam )
02280 {
02281
02282
02283
02284 switch(message)
02285 {
02286
02287
02288
02289 case WM_NCCREATE:
02290 return COMBO_NCCreate(hwnd,wParam,lParam);
02291
02292 case WM_NCDESTROY:
02293 return COMBO_NCDestroy(hwnd,wParam,lParam);
02294
02295 case WM_CREATE:
02296 return COMBO_Create(hwnd,wParam,lParam);
02297
02298 case WM_PRINTCLIENT:
02299 return COMBO_PrintClient(hwnd,wParam,lParam);
02300
02301 case WM_PAINT:
02302 return COMBO_Paint(hwnd,wParam,lParam);
02303
02304 case WM_ERASEBKGND:
02305 return COMBO_EraseBackground(hwnd,wParam,lParam);
02306
02307 case WM_GETDLGCODE:
02308 return COMBO_GetDlgCode(hwnd,wParam,lParam);
02309
02310 case WM_WINDOWPOSCHANGING:
02311 return COMBO_WindowPosChanging(hwnd,wParam,lParam);
02312
02313 case WM_SIZE:
02314 return COMBO_Size(hwnd,wParam,lParam);
02315
02316 case WM_SETFONT:
02317 return COMBO_SetFont(hwnd,wParam,lParam);
02318
02319 case WM_GETFONT:
02320 return COMBO_GetFont(hwnd,wParam,lParam);
02321
02322 case WM_SETFOCUS:
02323 return COMBO_SetFocus(hwnd,wParam,lParam);
02324
02325 case WM_KILLFOCUS:
02326 return COMBO_KillFocus(hwnd,wParam,lParam);
02327
02328 case WM_COMMAND:
02329 return COMBO_Command(hwnd,wParam,lParam);
02330
02331 case WM_GETTEXT:
02332 return COMBO_GetText(hwnd,wParam,lParam);
02333
02334 case WM_GETTEXTLENGTH:
02335 return COMBO_GetTextLength(hwnd,wParam,lParam);
02336
02337 case WM_SETTEXT:
02338 case WM_CLEAR:
02339 case WM_CUT:
02340 case WM_PASTE:
02341 case WM_COPY:
02342 return COMBO_HandleText(hwnd,message,wParam,lParam);
02343
02344 case WM_DRAWITEM:
02345 case WM_DELETEITEM:
02346 case WM_COMPAREITEM:
02347 case WM_MEASUREITEM:
02348 return COMBO_HandleItem(hwnd,message,wParam,lParam);
02349
02350 case WM_ENABLE:
02351 return COMBO_Enable(hwnd,wParam,lParam);
02352
02353 case WM_SETREDRAW:
02354 return COMBO_SetRedraw(hwnd,wParam,lParam);
02355
02356 case WM_SYSKEYDOWN:
02357 return COMBO_SysKeyDown(hwnd,wParam,lParam);
02358
02359 case WM_CHAR:
02360 case WM_KEYDOWN:
02361 return COMBO_HandleKey(hwnd,message,wParam,lParam);
02362
02363 case WM_LBUTTONDOWN:
02364 return COMBO_LButtonDown(hwnd,wParam,lParam);
02365
02366 case WM_LBUTTONUP:
02367 return COMBO_LButtonUp(hwnd,wParam,lParam);
02368
02369 case WM_MOUSEMOVE:
02370 return COMBO_MouseMove(hwnd,wParam,lParam);
02371
02372 case WM_MOUSEWHEEL:
02373 return COMBO_MouseWheel(hwnd,wParam,lParam);
02374
02375
02376
02377 case CB_ADDSTRING:
02378 return COMBO_AddString(hwnd,wParam,lParam);
02379
02380 case CB_INSERTSTRING:
02381 return COMBO_InsertString(hwnd,wParam,lParam);
02382
02383 case CB_DELETESTRING:
02384 return COMBO_DeleteString(hwnd,wParam,lParam);
02385
02386 case CB_SELECTSTRING:
02387 return COMBO_SelectString(hwnd,wParam,lParam);
02388
02389 case CB_FINDSTRING:
02390 return COMBO_FindString(hwnd,wParam,lParam);
02391
02392 case CB_FINDSTRINGEXACT:
02393 return COMBO_FindStringExact(hwnd,wParam,lParam);
02394
02395 case CB_SETITEMHEIGHT:
02396 return COMBO_SetItemHeight(hwnd,wParam,lParam);
02397
02398 case CB_GETITEMHEIGHT:
02399 return COMBO_GetItemHeight(hwnd,wParam,lParam);
02400
02401 case CB_RESETCONTENT:
02402 return COMBO_ResetContent(hwnd,wParam,lParam);
02403
02404 case CB_INITSTORAGE:
02405 return COMBO_InitStorage(hwnd,wParam,lParam);
02406
02407 case CB_GETHORIZONTALEXTENT:
02408 return COMBO_GetHorizontalExtent(hwnd,wParam,lParam);
02409
02410 case CB_SETHORIZONTALEXTENT:
02411 return COMBO_SetHorizontalExtent(hwnd,wParam,lParam);
02412
02413 case CB_GETTOPINDEX:
02414 return COMBO_GetTopIndex(hwnd,wParam,lParam);
02415
02416 case CB_GETLOCALE:
02417 return COMBO_GetLocale(hwnd,wParam,lParam);
02418
02419 case CB_SETLOCALE:
02420 return COMBO_SetLocale(hwnd,wParam,lParam);
02421
02422 case CB_GETDROPPEDWIDTH:
02423 return COMBO_GetDroppedWidth(hwnd,wParam,lParam);
02424
02425 case CB_SETDROPPEDWIDTH:
02426 return COMBO_SetDroppedWidth(hwnd,wParam,lParam);
02427
02428 case CB_GETDROPPEDCONTROLRECT:
02429 return COMBO_GetDroppedControlRect(hwnd,wParam,lParam);
02430
02431 case CB_GETDROPPEDSTATE:
02432 return COMBO_GetDroppedState(hwnd,wParam,lParam);
02433
02434 case CB_DIR:
02435 return COMBO_Dir(hwnd,wParam,lParam);
02436
02437 case CB_SHOWDROPDOWN:
02438 return COMBO_ShowDropDown(hwnd,wParam,lParam);
02439
02440 case CB_GETCOUNT:
02441 return COMBO_GetCount(hwnd,wParam,lParam);
02442
02443 case CB_GETCURSEL:
02444 return COMBO_GetCurSel(hwnd,wParam,lParam);
02445
02446 case CB_SETCURSEL:
02447 return COMBO_SetCurSel(hwnd,wParam,lParam);
02448
02449 case CB_GETLBTEXT:
02450 return COMBO_GetLBText(hwnd,wParam,lParam);
02451
02452 case CB_GETLBTEXTLEN:
02453 return COMBO_GetLBTextLen(hwnd,wParam,lParam);
02454
02455 case CB_GETITEMDATA:
02456 return COMBO_GetItemData(hwnd,wParam,lParam);
02457
02458 case CB_SETITEMDATA:
02459 return COMBO_SetItemData(hwnd,wParam,lParam);
02460
02461 case CB_GETEDITSEL:
02462 return COMBO_GetEditSel(hwnd,wParam,lParam);
02463
02464 case CB_SETEDITSEL:
02465 return COMBO_SetEditSel(hwnd,wParam,lParam);
02466
02467 case CB_SETEXTENDEDUI:
02468 return COMBO_SetExtendedUI(hwnd,wParam,lParam);
02469
02470 case CB_GETEXTENDEDUI:
02471 return COMBO_GetExtendedUI(hwnd,wParam,lParam);
02472
02473
02474
02475 }
02476 return DefWindowProcA(hwnd, message, wParam, lParam);
02477 }
02478
02479 BOOL COMBOBOX_Register()
02480 {
02481 WNDCLASSA wndClass;
02482
02483
02484
02485
02486 ZeroMemory(&wndClass,sizeof(WNDCLASSA));
02487 wndClass.style = CS_GLOBALCLASS | CS_PARENTDC;
02488 wndClass.lpfnWndProc = (WNDPROC)ComboWndProc;
02489 wndClass.cbClsExtra = 0;
02490 wndClass.cbWndExtra = sizeof(VOID*);
02491 wndClass.hCursor = LoadCursorA(0,IDC_ARROWA);
02492 wndClass.hbrBackground = (HBRUSH)0;
02493 wndClass.lpszClassName = COMBOBOXCLASSNAME;
02494
02495 return RegisterClassA(&wndClass);
02496 }
02497
02498 BOOL COMBOBOX_Unregister()
02499 {
02500 if (GlobalFindAtomA(COMBOBOXCLASSNAME))
02501 return UnregisterClassA(COMBOBOXCLASSNAME,(HINSTANCE)NULL);
02502 else return FALSE;
02503 }
02504