1 /******************************************************************************
2 *
3 * Copyright (C) 2004-2007, The Gentee Group. All rights reserved.
4 * This file is part of the Gentee open source project - http://www.gentee.com.
5 *
6 * THIS FILE IS PROVIDED UNDER THE TERMS OF THE GENTEE LICENSE ("AGREEMENT").
7 * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS FILE CONSTITUTES RECIPIENTS
8 * ACCEPTANCE OF THE AGREEMENT.
9 *
10 * ID: vis.combobox 30.07.07 0.0.A.
11 *
12 * Author: Alexander Krivonogov ( gentee )
13 *
14 ******************************************************************************/
15
16 include {
17 "ctrl.g"
18 }
19
20 /* Компонента vComboBox, порождена от vCtrl
21 События
22 */
23 type vComboBoxItem
24 {
25 uint pIndex
26 uint pComboBox
27 }
28
29 type fordatacombobox <inherit=fordata>
30 {
31 vComboBoxItem item
32 }
33
34 type vComboBox <index=vComboBoxItem inherit=vCtrl>
35 {
36 //Hidden Fields
37 uint fNewText //Признак программного изменения текста
38 //uint fUpdate
39 //uint pChanged //
40
41 uint pCBStyle
42 uint pSorted
43 uint pDropDownLen
44
45
46 arr pArrLabels of locustr
47 arrustr pArrKeys
48 arr pArrVals of uint
49 uint flgPosChanged
50
51 //uint itemcounts
52 //Events
53 evValUstr OnSelect
54 evEvent oncloseup
55
56 }
57
58
59
60 define <export> {
61 //Стили комбобокса
62 cbsDropDown = 0
63 cbsDropDownList= 1
64 cbsSimple = 2
65 }
66
67 extern {
68 operator uint * ( vComboBox combobox )
69 property vComboBox.DropDownLen ( uint val )
70 property uint vComboBox.DropDownLen ( )
71 method vComboBoxItem vComboBox.GetItem( uint index, vComboBoxItem item )
72 method vComboBox.Sel( uint start, uint len )
73 method vComboBox.SelAll()
74 property uint vComboBox.CurIndex()
75 property vComboBox.CurIndex ( uint val )
76 }
77
78 /*------------------------------------------------------------------------------
79 Internal Methods
80 */
81 /*Метод iUpdate
82 Обновить данные в окне
83 */
84 method vComboBox.iUpdateHeight
85 {
86 if /*!.fUpdate &&*/ .pCBStyle != $cbsSimple
87 {
88 // .fUpdate = 1
89 MoveWindow( this.hwnd, .loc.left, .loc.top, .loc.width, .loc.height + 4 + .WinMsg( $CB_GETITEMHEIGHT )*.pDropDownLen, 1 )
90 //this.Height = this.Height + 4 + .WinMsg( $CB_GETITEMHEIGHT )*.pDropDownLen
91 // .fUpdate = 0
92 }
93 }
94
95 method vComboBox.iUpdate
96 {
97 uint i
98 uint curindex = .CurIndex
99 .WinMsg( $CB_RESETCONTENT )
100 fornum i=0, *.pArrLabels
101 {
102 uint cbi = .WinMsg( $CB_ADDSTRING, 0, .pArrLabels[i].Text(this).ptr() )
103 .WinMsg( $CB_SETITEMDATA, cbi, i )
104 }
105 .iUpdateHeight()
106 .CurIndex = curindex
107 //.DropDownLen = .DropDownLen
108 }
109
110 method uint vComboBox.eof( fordatacombobox fd )
111 {
112 return ?( fd.icur < *this, 0, 1 )
113 }
114
115 method vComboBoxItem vComboBox.first( fordatacombobox fd )
116 {
117 return this.GetItem(0, fd.item )//fd.icur = 0 )
118 }
119
120 method vComboBoxItem vComboBox.next( fordatacombobox fd )
121 {
122 //return this.index( ++fd.icur )
123 return this.GetItem( ++fd.icur, fd.item )
124 }
125
126
127 /*------------------------------------------------------------------------------
128 Properties
129 */
130
131 operator uint * ( vComboBox combobox )
132 {
133 return *combobox.pArrLabels
134 }
135
136 /*Свойство ustr Text - Get Set
137 Получить, установить редактируемый текст
138 */
139 property ustr vComboBox.Text <result>
140 {
141 uint res = GetWindowTextLength( this.hwnd )
142 result.reserve( res + 1 )
143 GetWindowText( this.hwnd, result.ptr(), res + 1 )
144 result.setlen( res )
145 }
146
147 property vComboBox.Text( ustr val )
148 {
149 this.fNewText = 1
150 SetWindowText( this.hwnd, val.ptr() )
151 this.fNewText = 0
152 }
153
154 /*Свойство ustr MaxLen - Get Set
155 Получить, установить максимальную длину текста в символах
156 */
157 property uint vComboBox.MaxLen
158 {
159 return this.WinMsg( $EM_GETLIMITTEXT )
160 }
161
162 property vComboBox.MaxLen( uint val )
163 {
164 this.WinMsg( $EM_LIMITTEXT, val )
165 }
166
167 /*Свойство ustr SelStart - Get Set
168 Получить, установить начало выделенного текста
169 */
170 property uint vComboBox.SelStart
171 {
172 uint start
173 this.WinMsg( $EM_GETSEL, &start, 0 )
174 return start
175 }
176
177 property vComboBox.SelStart( uint val )
178 {
179 this.Sel( val, 0 )
180 }
181
182 /*Свойство ustr SelLen - Get Set
183 Получить, установить длину выделенного текста
184 */
185 property uint vComboBox.SelLen
186 {
187 uint start, end
188 this.WinMsg( $EM_GETSEL, &start, &end )
189 return end - start
190 }
191
192 property vComboBox.SelLen( uint val )
193 {
194 this.Sel( this.SelStart, val )
195 }
196
197 /*Свойство ustr SelStart - Get
198 Получить выделенный текст
199 */
200 property ustr vComboBox.SelText<result>
201 {
202 uint start, end
203 this.WinMsg( $EM_GETSEL, &start, &end )
204 result.substr( this.Text, start, end-start )
205 }
206
207 //CBStyle, Sorted, MaxLength, CurIndex, Items, DownDowncount, AutoComplete, AutoDropDown
208 /*Свойство ustr CBStyle - Get Set
209 Получить, установить стиль комбобокса
210 */
211 property uint vComboBox.CBStyle ()
212 {
213 return .pCBStyle
214 }
215
216 property vComboBox.CBStyle ( uint val )
217 {
218 if .pCBStyle != val
219 {
220 .pCBStyle = val
221 //.ReCreateWin()
222 .Virtual( $mReCreateWin )
223 }
224 }
225
226 /*Свойство ustr CurIndex - Get Set
227 Получить, установить текущий элемент
228 */
229 property uint vComboBox.CurIndex()
230 {
231 uint windex = .WinMsg( $CB_GETCURSEL )
232 if windex == -1 : return -1
233 return .WinMsg( $CB_GETITEMDATA, windex )
234 }
235
236 property vComboBox.CurIndex ( uint val )
237 {
238 if .CurIndex != val
239 {
240 if val > *.pArrLabels : val = -1
241 if val != -1
242 {
243 uint i
244 fornum i, *.pArrLabels
245 {
246 if val == .WinMsg( $CB_GETITEMDATA, i )
247 {
248 val = i
249 break
250 }
251 }
252 }
253 .WinMsg( $CB_SETCURSEL, val )
254 }
255 }
256
257 /*Свойство ustr Sorted - Get Set
258 Получить, установить стиль комбобокса
259 */
260 property uint vComboBox.Sorted ()
261 {
262 return .pSorted
263 }
264
265 property vComboBox.Sorted ( uint val )
266 {
267 if .pSorted != val
268 {
269 .pSorted = val
270 //.ReCreateWin()
271 .Virtual( $mReCreateWin )
272 }
273 }
274
275 /*Свойство ustr DropDownLen - Get Set
276 Получить, установить количество элементов отображаемых в выпадающем списке
277 */
278 property uint vComboBox.DropDownLen ()
279 {
280 return .pDropDownLen
281 }
282
283 property vComboBox.DropDownLen ( uint val )
284 {
285 if .pDropDownLen != val
286 {
287 .pDropDownLen = val
288 .iUpdateHeight()
289 }
290
291 }
292
293 property vComboBoxItem.Label( ustr val )
294 {
295 uint combobox as .pComboBox->vComboBox
296
297 if .pIndex < *combobox
298 {
299 combobox.pArrLabels[.pIndex].Value = val
300 combobox.iUpdate()
301 }
302 }
303
304 property ustr vComboBoxItem.Label<result>()
305 {
306 uint combobox as .pComboBox->vComboBox
307 if .pIndex < *combobox
308 {
309 result = combobox.pArrLabels[.pIndex].Value
310 }
311 // return 0->ustr
312 }
313
314 property vComboBoxItem.Key( ustr val )
315 {
316 uint combobox as .pComboBox->vComboBox
317 if .pIndex < *combobox
318 {
319 combobox.pArrKeys[.pIndex] = val
320 combobox.iUpdate()
321 }
322 }
323
324 property ustr vComboBoxItem.Key()
325 {
326 uint combobox as .pComboBox->vComboBox
327 if .pIndex < *combobox
328 {
329 return combobox.pArrKeys[.pIndex]
330 }
331 return 0->ustr
332 }
333
334 property vComboBoxItem.Val( uint val )
335 {
336 uint combobox as .pComboBox->vComboBox
337 if .pIndex < *combobox
338 {
339 combobox.pArrVals[.pIndex] = val
340 combobox.iUpdate()
341 }
342 }
343
344 property uint vComboBoxItem.Val()
345 {
346 uint combobox as .pComboBox->vComboBox
347 if .pIndex < *combobox
348 {
349 return combobox.pArrVals[.pIndex]
350 }
351 return 0
352 }
353
354
355 /*Метод Sel( uint start, uint len )
356 Выделить часть текста
357 start - позизия начала выделения
358 len - длина выделения в символах
359 */
360 method vComboBox.Sel( uint start, uint len )
361 {
362 this.WinMsg( $EM_SETSEL, start, start + len )
363 }
364
365 /*Метод SelAll()
366 Выделить весь текст
367 */
368 method vComboBox.SelAll()
369 {
370 this.Sel( 0, -1 )
371 }
372
373 method vComboBox.AddItem( ustr slabel, ustr key, uint val )
374 {
375 uint i = .pArrLabels.expand( 1 )
376 .pArrKeys.expand( 1 )
377 .pArrVals.expand( 1 )
378 .pArrLabels[i].Value = slabel
379 if &key: .pArrKeys[i] = key
380 .pArrVals[i] = val
381
382 uint cbi = .WinMsg( $CB_ADDSTRING, 0, .pArrLabels[i].Text(this).ptr() )
383 .WinMsg( $CB_SETITEMDATA, cbi, i )
384 }
385
386 method vComboBox.InsertItem( uint pos, ustr slabel, ustr key, uint val )
387 {
388 pos = min( pos, *.pArrLabels )
389 .pArrLabels.insert( pos )
390 .pArrKeys.insert( pos )
391 .pArrVals.insert( pos )
392 .pArrLabels[pos].Value = slabel
393 if &key: .pArrKeys[pos] = key
394 .pArrVals[pos] = val
395 .iUpdate()
396 }
397
398 method vComboBox.RemoveItem( uint pos )
399 {
400 if pos < *.pArrLabels - 1
401 {
402 .pArrLabels.del( pos )
403 .pArrKeys.del( pos )
404 .pArrVals.del( pos )
405 .iUpdate()
406 }
407 }
408
409 method uint vComboBox.FindItem( ustr slabel )
410 {
411 uint i
412 fornum i, *.pArrLabels
413 {
414 if .pArrLabels[i].Value == slabel : return i
415 }
416 return -1
417 }
418
419 method uint vComboBox.FindItemKey( ustr key )
420 {
421 uint i
422 fornum i, *.pArrKeys
423 {
424 if .pArrKeys[i] == key : return i
425 }
426 return -1
427 }
428
429
430 method uint vComboBox.FindItemVal( uint val )
431 {
432 uint i
433 fornum i, *.pArrVals
434 {
435 if .pArrVals[i] == val : return i
436 }
437 return -1
438 }
439
440
441
442 method vComboBox.AddLines( ustr list )
443 {
444 arrustr arrnames
445 ustr sname, skey
446 uint name, i
447 list.lines( arrnames )
448
449 fornum i, *arrnames
450 {
451
452 name as arrnames[i]
453 uint eq = name.findch('=')
454 if eq < *name
455 {
456 sname.substr( name, 0, eq )
457 skey.substr( name, eq + 1, *name - eq - 1 )
458 }
459 else
460 {
461 sname = name
462 skey.clear()
463 }
464 .AddItem( sname, skey, int( skey.str()))
465 }
466 }
467
468 method vComboBox.Clear()
469 {
470 .pArrLabels.clear()
471 .pArrKeys.clear()
472 .pArrVals.clear()
473 .iUpdate()
474 }
475
476 method uint vComboBox.DropDown()
477 {
478
479 SetFocus( .hwnd )
480 return .WinMsg( $CB_SHOWDROPDOWN, 1,0 )
481 }
482
483 method vComboBoxItem vComboBox.index <result>( uint index )
484 {
485 .GetItem( index, result )
486 }
487
488 /*
489 property uint vComboBox.count( )
490 {
491 return SendMessage( this.hwnd, $CB_GETCOUNT, 0, 0 )
492 }
493
494 property uint vComboBox.itemheight()
495 {
496 return SendMessage( this.hwnd, $CB_GETITEMHEIGHT, 0, 0 )
497 }
498
499 property uint vComboBox.itemindex()
500 {
501 return SendMessage( this.hwnd, $CB_GETCURSEL, 0, 0 )
502 }
503
504 property str vComboBox.getitemtext<result>( uint i )
505 {
506 result.reserve( SendMessage( this.hwnd, $CB_GETLBTEXTLEN, i, 0 ) + 1 )
507 SendMessage( this.hwnd, $CB_GETLBTEXT, i, result.ptr() )
508 result.setlenptr()
509 }
510
511 method vComboBox.loadfromarr( arrstr ar )
512 {
513 uint i
514 SendMessage( this.hwnd, $CB_RESETCONTENT, 0, ar[i].ptr() )
515 fornum i, *ar
516 {
517 SendMessage( this.hwnd, $CB_ADDSTRING, 0, ar[i].ptr() )
518 }
519 }
520
521 */
522
523 method uint vComboBox.mWinCmd <alias=vComboBox_mWinCmd>( uint cmd, uint id )
524 {
525 switch cmd
526 {
527 case $CBN_SELENDOK
528 {
529 evparValUstr es
530 es.val = this[.CurIndex].Label
531 .OnSelect.Run( es, this )
532 }
533 case $CBN_CLOSEUP
534 {
535 .oncloseup.run()
536 }
537 }
538 return 0
539 }
540
541 /*method vComboBox.mPosChanged <alias=vComboBox_mPosChanged>( evparValUint ev )
542 {
543 this->vCtrl.mPosChanged( ev )
544 if !.fUpdate
545 {
546
547
548 if ev.val = 1
549 {
550 .iUpdateHeight()
551 }
552 }
553 }*/
554
555 method vComboBoxItem vComboBox.GetItem( uint index, vComboBoxItem item )
556 {
557 //print( "set \(&this) \(index)\n" )
558 item.pComboBox = &this
559 if index < *.pArrLabels
560 {
561 item.pIndex = index
562 }
563 else
564 {
565 item.pIndex = -1
566 }
567 return item
568 }
569
570
571
572 /*------------------------------------------------------------------------------
573 Virtual Methods
574 */
575
576 method vComboBox vComboBox.mCreateWin <alias=vComboBox_mCreateWin>()
577 {
578 uint CBStyle
579 switch .pCBStyle
580 {
581 case $cbsDropDown: CBStyle = $CBS_DROPDOWN
582 case $cbsDropDownList: CBStyle = $CBS_DROPDOWNLIST
583 default : CBStyle = $CBS_SIMPLE
584 }
585 if .pSorted
586 {
587 CBStyle |= $CBS_SORT
588 }
589 this.CreateWin( "combobox".ustr(), 0,
590 CBStyle | $WS_VSCROLL |//| 0x242 |
591 $WS_CHILD | $WS_CLIPSIBLINGS )
592 this->vCtrl.mCreateWin()
593 this.WinMsg( $WM_SETFONT, GetStockObject( $DEFAULT_GUI_FONT ) )
594 .iUpdate()
595 return this
596 }
597
598
599 /*Виртуальный метод uint vComboBox.mLangChanged - Изменение текущего языка
600 */
601 method vComboBox.mLangChanged <alias=vComboBox_mLangChanged>()
602 {
603 .iUpdate()
604 this->vCtrl.mLangChanged()
605 }
606
607 method uint vComboBox.wmwindowposchanged <alias=vComboBox_wmwindowposchanged >( winmsg wmsg )
608 {
609 .flgPosChanged++
610 //print( "pchanged0 \n" )//\(&this) \(wmsg.lpar->WINDOWPOS.flags) \(wmsg.lpar->WINDOWPOS.cy) \(.Name) \(.fUpdate) \(this.Height)\n")
611 this->vCtrl.wmwindowposchanged ( wmsg )
612 if .flgPosChanged == 1
613 {
614 RECT r
615 .WinMsg( $CB_GETDROPPEDCONTROLRECT, 0, &r )
616 if r.bottom - r.top != .loc.height + 4 + .WinMsg( $CB_GETITEMHEIGHT )*.pDropDownLen
617 {
618 // print( "update \(r.bottom - r.top)\n" )
619 .iUpdateHeight()
620 eventpos evp
621 evp.move = 1
622 evp.loc = this.loc
623 .Virtual( $mPosChanging, evp )
624 }
625 }
626 .flgPosChanged--
627 //print( "pchanged1 \(.fUpdate) \(this.Height)\n")
628 return 0
629 }
630
631 method vComboBox.mPreDel <alias=vComboBox_mPreDel>()
632 {
633 // .flgPosChanged++
634 this->vCtrl.mPreDel()
635 }
636 /*------------------------------------------------------------------------------
637 Registration
638 */
639 /*method vComboBox.getprops( uint typeid, compMan cm )
640 {
641 this->vCtrl.getprops( typeid, cm)
642 }*/
643
644 method vComboBox vComboBox.init( )
645 {
646 this.loc.width = 200
647 this.loc.height = 200
648 this.pTypeId = vComboBox
649 this.pTabStop = 1
650 this.pCanFocus = 1
651 this.pDropDownLen = 5
652 return this
653 }
654
655 func init_vComboBox <entry>()
656 {
657 regcomp( vComboBox, "vComboBox", vCtrl, $vCtrl_last,
658 %{ %{$mCreateWin, vComboBox_mCreateWin},
659 %{$mWinCmd, vComboBox_mWinCmd},
660 //%{$mPosChanged, vComboBox_mPosChanged},
661 %{$mLangChanged, vComboBox_mLangChanged},
662 %{$mPreDel, vComboBox_mPreDel}
663 },
664 %{ %{$WM_WINDOWPOSCHANGED, vComboBox_wmwindowposchanged } } )
665 ifdef $DESIGNING {
666 cm.AddComp( vComboBox, 1, "Windows", "combobox" )
667
668 cm.AddProps( vComboBox, %{
669 //"TabOrder", uint, 0,
670 "CBStyle", uint, 0,
671 "Sorted", uint, 0,
672 "DropDownLen", uint, 0
673 })
674
675 cm.AddPropVals( vComboBox, "CBStyle", %{
676 "cbsDropDown" , $cbsDropDown,
677 "cbsDropDownList", $cbsDropDownList,
678 "cbsSimple" , $cbsSimple
679 })
680
681 cm.AddEvents( vComboBox, %{
682 "OnSelect" , "evparValUstr"
683 })
684 }
685 }
686
687
688