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