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.ctrl 17.07.07 0.0.A.
11 *
12 * Author: Alexander Krivonogov ( gentee )
13 *
14 ******************************************************************************/
15 /* Компонента vCtrl, порождена от vComp
16 События
17
18 */
19
20
21 include
22 {
23 "virtctrl.g"
24 //"addustr.g"
25 }
26
27 type winmsg <inherit=MSG>{
28 //uint hwnd
29 //uint msg
30 //uint wpar
31 //uint lpar
32 uint flags
33 }
34
35 type winmsgsh {
36 uint hwnd
37 uint msg
38 ushort wparlo
39 ushort wparhi
40 ushort lparlo
41 ushort lparhi
42 uint flags
43 }
44
45 type winmsgmouse{
46 uint hwnd
47 uint msg
48 uint wpar
49 ushort x
50 ushort y
51 uint flags
52 }
53
54 type winmsgcmd {
55 uint hwnd
56 uint msg
57 ushort id
58 ushort ntf
59 uint ctrlhwnd
60 uint flags
61 }
62
63 /*
64 operator vloc =( vloc l, r )
65 {
66 mcopy( &l, &r, sizeof(vloc) )
67 return l
68 }
69
70 operator uint ==( vloc l, r )
71 {
72 return l.left == r.left && l.top == r.top && l.width == r.width && l.height == r.height
73 }
74 */
75
76
77 type vCtrl <inherit = vVirtCtrl>
78 {
79 //Hidden Fields
80
81 uint prevwndproc
82 vloc clloc
83 uint hwnd
84
85
86 uint pCanContain
87 uint pCanFocus
88 uint pTabStop
89 uint pAlign
90 uint pRight
91 uint pBottom
92 uint pCtrls //Количество дочерних контролов
93 str pFont
94 //uint hFont
95 uint pPopupMenu
96 ustr pHelpTopic
97
98 str pStyle
99 uint aStyle
100
101 uint flgnoposchanged
102 uint flgXPStyle //Контрол должен поддерживать обработку фона для XP
103 uint flgRePaint //Принудительная перерисовка при изменении размеров нужна для STATIC
104 uint flgNoPosChanging //Запрет на перемещение и изменение размеров
105 //uint flgPosChanging
106
107 uint pMinWidth
108 uint pMinHeight
109 uint pMaxWidth
110 uint pMaxHeight
111 uint fMinMax
112
113 //Public Fields
114 // arr ctrls of uint
115
116 //Events
117 oneventpos onposchanging
118 evEvent OnPosChanged
119 evEvent onownersize
120 evMouse OnMouse
121 evKey OnKey
122
123 //oneventuint onfocus
124 evValUint OnFocus
125 //uint oncomnotify
126 }
127
128 define <export>{
129 mReCreateWin = $vVirtCtrl_last
130 mDestroyWin
131 mPosChanged
132 //mPosChanging
133 mWinCmd
134 mWinNtf
135 mWinDrawItem
136 mWinMeasureItem
137 mFocus
138 mKey
139 mMouse
140 mFontChanged
141
142 mDesChanging
143 mDesChanged
144
145 mGetHint
146
147 mClColor
148
149 vCtrl_last
150 }
151
152 extern {
153 func uint myproc( uint hwnd, uint msg, uint wpar, uint lpar )
154 property uint vCtrl.TabOrder
155 property vCtrl.TabOrder( uint newidx )
156 }
157
158
159 define {
160 TAB_INSERT = 1
161 TAB_REMOVE
162 TAB_MOVE
163 }
164
165
166 define <export>
167 {
168 alhLeft = 0x01
169 alhClient = 0x02
170 alhRight = 0x04
171 alhCenter = 0x08
172 alhLeftRight = 0x10
173 ALH_MASK = 0xFF
174
175 alvTop = 0x0100
176 alvClient = 0x0200
177 alvBottom = 0x0400
178 alvCenter = 0x0800
179 alvTopBottom = 0x1000
180 ALV_MASK = 0xFF00
181 }
182
183
184
185
186
187
188 func win_move( uint hwnd, int x y )
189 {
190 SetWindowPos( hwnd, 0, x, y, 0, 0, $SWP_NOACTIVATE | $SWP_NOZORDER | $SWP_NOSIZE )
191 }
192
193 func win_loc( uint hwnd, int x y width height )
194 {
195 MoveWindow( hwnd, x, y, width, height, 1 )
196 }
197
198
199
200 method vCtrl.ownerresize( vloc n )
201 {
202 if this.pOwner && this.pOwner != &App
203 {
204 int width, height
205
206 //n.left -= this.Owner->vCtrl.clloc.left
207 //n.top -= this.Owner->vCtrl.clloc.top
208
209
210 width = this.Owner->vCtrl.clloc.width
211 height = this.Owner->vCtrl.clloc.height
212
213 switch this.pAlign & $ALV_MASK
214 {
215 case $alvTop
216 {
217 //Привязать к позиции верхнего края
218 //Ничего делать не надо
219 }
220 case $alvClient
221 {
222 //Растянуть на всю высоту
223 n.top = 0
224 n.height = height
225 }
226 case $alvBottom
227 {
228 //Привязать к позиции нижнего края
229 n.top = height - n.height - this.pBottom
230 }
231 case $alvCenter
232 {
233 //Центрировать
234 n.top = (height - n.height )>>1
235 }
236 case $alvTopBottom
237 {
238 n.height = height - n.top - this.pBottom
239 }
240 }
241 switch this.pAlign & $ALH_MASK
242 {
243 case $alhLeft
244 {
245 //Привязать к позиции верхнего края
246 //Ничего делать не надо
247 }
248 case $alhClient
249 {
250 //Растянуть на всю высоту
251 n.left = 0
252 n.width = width
253 }
254 case $alhRight
255 {
256 //Привязать к позиции нижнего края
257 n.left = width - n.width - this.pRight
258 }
259 case $alhCenter
260 {
261 //Центрировать
262 n.left = (width - n.width )>>1
263 }
264 case $alhLeftRight
265 {
266 //Растягивать с отступами
267 n.width = width - this.pRight - n.left
268 }
269 }
270 if .fMinMax
271 {
272 if .pMinWidth
273 {
274 n.width = max( n.width, .pMinWidth )
275 }
276 if .pMaxWidth
277 {
278 n.width = min( n.width, .pMaxWidth )
279 }
280 if .pMinHeight
281 {
282 n.height = max( n.height, .pMinHeight )
283 }
284 if .pMaxHeight
285 {
286 n.height = min( n.height, .pMaxHeight )
287 }
288 }
289 }
290 }
291
292 method vCtrl.Invalidate()
293 {
294 if this.hwnd: InvalidateRect( this.hwnd, 0->RECT, 1 )
295 }
296
297 method vCtrl.CreateWin( ustr class, uint exstyle style )
298 {
299 if .pVisible : style |= $WS_VISIBLE
300 if !.pEnabled : style |= $WS_DISABLED
301 this.hwnd = CreateWindowEx( exstyle, class.ptr(), "".ustr().ptr(), style,
302 this.loc.left, this.loc.top, this.loc.width, this.loc.height, ?( this.pOwner && this.pOwner != &App, this.pOwner->vCtrl.hwnd, 0), 0, GetModuleHandle( 0 ), &this )
303
304 }
305
306 func vCtrl getctrl( uint hwnd )
307 {
308 uint ctrl = GetWindowLong( hwnd, $GWL_USERDATA )
309 while !ctrl && hwnd
310 {
311 hwnd = GetParent( hwnd )
312 ctrl = GetWindowLong( hwnd, $GWL_USERDATA )
313 }
314 return ctrl->vCtrl
315 }
316
317 method vCtrl.SetStyle( uint mask is )
318 {
319 if this.hwnd
320 {
321 uint style = GetWindowLong( this.hwnd, $GWL_STYLE )
322 if is : style |= mask
323 else : style &= ~mask
324 SetWindowLong( this.hwnd, $GWL_STYLE, style )
325 SetWindowPos( this.hwnd, 0, 0, 0, 0, 0,
326 $SWP_NOACTIVATE | $SWP_NOZORDER | $SWP_NOMOVE | $SWP_NOSIZE )
327 .Invalidate()
328 }
329 }
330 method uint vCtrl.GetStyle( uint mask )
331 {
332 return ?(GetWindowLong( this.hwnd, $GWL_STYLE ) & mask == mask, 1,0)
333 }
334
335
336 method uint vCtrl.WinMsg( uint message )
337 {
338 return SendMessage( this.hwnd, message, 0, 0 )
339 }
340
341 method uint vCtrl.WinMsg( uint message wpar )
342 {
343 return SendMessage( this.hwnd, message, wpar, 0 )
344 }
345
346 method uint vCtrl.WinMsg( uint message wpar lpar )
347 {
348 return SendMessage( this.hwnd, message, wpar, lpar )
349 }
350
351 method vCtrl.ChangeStyle( uint addstyle remstyle )
352 {
353 STYLESTRUCT stls
354 uint style = GetWindowLong( this.hwnd, $GWL_STYLE )
355 stls.styleOld = style
356 style &= ~remstyle
357 style |= addstyle
358 stls.styleNew = style
359 SetWindowLong( this.hwnd, $GWL_STYLE, style )
360
361 this.WinMsg( 0x7d, $GWL_STYLE, &stls)//$WM_STYLECHANGED )
362
363 }
364
365 /*method vCtrl.ReCreateWin()
366 {
367 .Virtual( $mDestroyWin )
368 .Virtual( $mCreateWin )
369 if .pOwner
370 {
371 SetWindowLong( .hwnd, $GWL_STYLE, GetWindowLong( .hwnd, $GWL_STYLE ) | $WS_CHILD )
372 SetParent( .hwnd, .pOwner->vCtrl.hwnd )
373 this.TabOrder = this.TabOrder
374 }
375 }*/
376
377
378
379 /*------------------------------------------------------------------------------
380 Propirties
381 */
382 /*
383 property int vCtrl.Left
384 {
385 //if this.Owner : return this.loc.left + this.Owner->vCtrl.clloc.left
386 return this.loc.left
387 }
388
389 property vCtrl.Left( int val )
390 {
391 //if val != this.loc.left
392 {
393 eventpos ep
394 this.loc.left = val
395 ep.loc = this.loc
396 ep.loc.left = val
397 ep.move = 1
398 ep.code = $e_poschanging
399 .Virtual( $mPosChanging, ep )
400 }
401 }
402
403 property int vCtrl.Top
404 {
405 //if this.Owner : return this.loc.top + this.Owner->vCtrl.clloc.top
406 return this.loc.top
407 }
408
409 property vCtrl.Top( int val )
410 {
411 //if val != this.loc.top
412 {
413 eventpos ep
414 this.loc.top = val
415 ep.loc = this.loc
416 ep.loc.top = val
417 ep.move = 1
418 ep.code = $e_poschanging
419 .Virtual( $mPosChanging, ep )
420 }
421 }
422
423 property int vCtrl.Width
424 {
425 return this.loc.width
426 }
427
428 property vCtrl.Width( int val )
429 {
430 if val < 0 : val = 0
431 if val != this.loc.width
432 {
433 eventpos ep
434 ep.loc = this.loc
435 ep.loc.width = val
436 ep.move = 1
437 ep.code = $e_poschanging
438 .Virtual( $mPosChanging, ep )
439 }
440 }
441
442 property int vCtrl.Height
443 {
444 return this.loc.height
445 }
446
447
448 property vCtrl.Height( int val )
449 {
450 if val < 0 : val = 0
451 if val != this.loc.height
452 {
453
454 eventpos ep
455 ep.loc = this.loc
456 ep.loc.height = val
457 ep.move = 1
458 ep.code = $e_poschanging
459 .Virtual( $mPosChanging, ep )
460 }
461 }
462 */
463 property int vCtrl.Right
464 {
465 return this.pRight
466 }
467
468 property vCtrl.Right( int val )
469 {
470 if val != this.pRight
471 {
472 this.pRight = val
473 if this.pAlign & ( $alhRight | $alhLeftRight )
474 {
475 eventpos ep
476 ep.loc = this.loc
477 ep.move = 1
478 ep.code = $e_poschanging
479 .Virtual( $mPosChanging, ep )
480 }
481 }
482 }
483
484 property int vCtrl.Bottom
485 {
486 return this.pBottom
487 }
488
489 property vCtrl.Bottom( int val )
490 {
491 if val != this.pBottom
492 {
493 this.pBottom = val
494 if this.pAlign & ( $alvBottom | $alvTopBottom )
495 {
496 eventpos ep
497 ep.loc = this.loc
498 ep.move = 1
499 ep.code = $e_poschanging
500 .Virtual( $mPosChanging, ep )
501 }
502 }
503 }
504 method vCtrl.iCheckMinMax()
505 {
506 if .pMinWidth || .pMaxWidth || .pMinHeight || .pMaxHeight
507 {
508 .fMinMax = 1
509 }
510 else : .fMinMax = 0
511 }
512
513 property uint vCtrl.MinWidth()
514 {
515 return .pMinWidth
516 }
517
518 property vCtrl.MinWidth( uint val )
519 {
520 .pMinWidth = val
521 .iCheckMinMax()
522 }
523
524 property uint vCtrl.MaxWidth()
525 {
526 return .pMaxWidth
527 }
528
529 property vCtrl.MaxWidth( uint val )
530 {
531 .pMaxWidth = val
532 .iCheckMinMax()
533 }
534
535 property uint vCtrl.MinHeight()
536 {
537 return .pMinHeight
538 }
539
540 property vCtrl.MinHeight( uint val )
541 {
542 .pMinHeight = val
543 .iCheckMinMax()
544 }
545
546 property uint vCtrl.MaxHeight()
547 {
548 return .pMaxHeight
549 }
550
551 property vCtrl.MaxHeight( uint val )
552 {
553 .pMaxHeight = val
554 .iCheckMinMax()
555 }
556 /*
557 property vCtrl.Visible( uint val )
558 {
559 if val != this.pVisible
560 {
561 this.pVisible = val
562 if !this.p_designing
563 {
564 .Virtual( $mUpdateVisible )
565 }
566 }
567 }
568
569 property uint vCtrl.Visible
570 {
571 return this.pVisible
572 }
573
574 property vCtrl.Enabled( uint val )
575 {
576 if val != this.pEnabled
577 {
578 .Virtual( $mSetEnabled, val )
579 }
580 }
581
582 property uint vCtrl.Enabled
583 {
584 return this.pEnabled
585 }
586 */
587 property uint vCtrl.TabStop
588 {
589 return this.pTabStop
590 }
591
592 property vCtrl.TabStop( uint val )
593 {
594 if val != this.pTabStop
595 {
596 this.pTabStop = val
597 }
598 }
599
600
601 property uint vCtrl.TabOrder
602 {
603 //return this.Index//.cidx
604 return this.pIndex//.cidx
605 }
606
607 property vCtrl.TabOrder( uint newidx )
608 {
609 this.CompIndex = newidx
610 /* this.Index = newidx
611 uint prevhwnd
612 if newidx > 0 : prevhwnd = ctrls[newidx-1]->vCtrl.hwnd
613 else : prevhwnd = 1
614 SetWindowPos( this.hwnd, prevhwnd, 0, 0, 0, 0, $SWP_NOACTIVATE | $SWP_NOSIZE | $SWP_NOMOVE )
615 */
616 /* if this.pOwner && this.pOwner->vComp.TypeIs( vCtrl )
617 {
618 uint ctrls as this.pOwner->vCtrl.Comps//ctrls
619 uint oldidx, i
620 uint prevhwnd
621 newidx = min( max( -0, int( newidx )), *ctrls - 1 )
622 if newidx != this.pIndex//cidx
623 {
624 oldidx = this.pIndex//cidx
625 if newidx > oldidx
626 {
627 fornum i = oldidx + 1, newidx + 1
628 {
629 ctrls[i]->vCtrl.pIndex--//cidx--
630 ctrls[i-1] = ctrls[i]
631 }
632 }
633 else
634 {
635 for i = oldidx - 1, int(i) >= newidx, i--
636 {
637 ctrls[i]->vCtrl.pIndex++//cidx++
638 ctrls[i+1] = ctrls[i]
639 }
640 }
641 ctrls[newidx] = &this
642 this.pIndex = newidx//cidx = newidx
643 //if newidx < .pCtrls-1 : prevhwnd = ctrls[newidx+1]->vCtrl.hwnd
644 if newidx > 0 : prevhwnd = ctrls[newidx-1]->vCtrl.hwnd
645 else : prevhwnd = 1
646 SetWindowPos( this.hwnd, prevhwnd, 0, 0, 0, 0, $SWP_NOACTIVATE | $SWP_NOSIZE | $SWP_NOMOVE )
647 }
648 }*/
649 }
650
651
652 property uint vCtrl.VertAlign
653 {
654 return this.pAlign & $ALV_MASK
655 }
656
657
658 property vCtrl.VertAlign( uint flg )
659 {
660 flg &= $ALV_MASK
661
662 this.pAlign = this.pAlign & $ALH_MASK | flg
663 if flg & ( $alvBottom | $alvTopBottom )
664 {
665 if this.p_designing && this.pOwner && this.pOwner != &App
666 {
667 this.pBottom = this.Owner->vCtrl.clloc.height - this.loc.top - this.loc.height
668
669 }
670 }
671 eventpos evp
672 evp.code = $e_poschanging
673 evp.loc = this.loc
674 evp.move = 1
675 .Virtual( $mPosChanging, evp )
676 }
677
678
679 property uint vCtrl.HorzAlign
680 {
681 return this.pAlign & $ALH_MASK
682 }
683
684 property vCtrl.HorzAlign( uint flg )
685 {
686 flg &= $ALH_MASK
687
688 this.pAlign = this.pAlign & $ALV_MASK | flg
689 if flg & ( $alhRight | $alhLeftRight )
690 {
691 if this.p_designing && this.pOwner && this.pOwner != &App
692 {
693 this.pRight = this.Owner->vCtrl.clloc.width - this.loc.left - this.loc.width
694 }
695 }
696 eventpos evp
697 evp.code = $e_poschanging
698 evp.loc = this.loc
699 evp.move = 1
700
701 .Virtual( $mPosChanging, evp )
702 }
703
704
705 /* Свойство str vCtrl.Font - Get Set
706 Усотанавливает или получает псевдоним( настройки шрифта контрола )
707 */
708 property str vCtrl.Font <result>
709 {
710 result = this.pFont
711 }
712
713 property vCtrl.Font( str val )
714 {
715 if val != this.pFont
716 {
717 //App.FntM.Default()
718 this.pFont = val
719 .Virtual( $mFontChanged )
720 }
721 }
722
723 property str vCtrl.Style <result>
724 {
725 result = this.pStyle
726 }
727
728 property vCtrl.Style( str val )
729 {
730 if val != this.pStyle
731 {
732 //App.FntM.Default()
733 this.pStyle = val
734 .Virtual( $mFontChanged )
735 }
736 }
737
738 /*------------------------------------------------------------------------------
739 Windows Mesages Methods
740 */
741
742
743 method uint vCtrl.wmmoving_sizing <alias=vCtrl_wmmoving_sizing>( winmsg wmsg )
744 {
745 uint lpar = wmsg.lpar
746 eventpos ev_p
747 ev_p.loc.left = lpar->RECT.left
748 ev_p.loc.top = lpar->RECT.top
749 ev_p.loc.width = lpar->RECT.right - lpar->RECT.left
750 ev_p.loc.height = lpar->RECT.bottom - lpar->RECT.top
751 ev_p.code = $e_poschanging
752 //this.event( ev_p )
753 this.Virtual( $mPosChanging, ev_p )
754 lpar->RECT.left = ev_p.loc.left
755 lpar->RECT.top = ev_p.loc.top
756 lpar->RECT.right = ev_p.loc.left + ev_p.loc.width
757 lpar->RECT.bottom = ev_p.loc.top + ev_p.loc.height
758 wmsg.flags = 1
759 return 1
760 }
761
762 method uint vCtrl.wmfocus <alias=vCtrl_wmfocus> ( winmsg wmsg )
763 {
764 evparValUint eu
765 eu.code = $e_focus
766 eu.val = ( wmsg.msg == $WM_SETFOCUS )
767 SendMessage (this.hwnd, 0x0128/*$WM_UPDATEUISTATE*/, (0x01/*$UISF_HIDEFOCUS*/<<16)|2/*$UIS_CLEAR*/, 0);
768 this.Virtual( $mFocus, eu )
769 /*if this.Virtual( $mFocus, eu )
770 {
771 wmsg.flags = 1
772 return 1
773 }*/
774 return 0
775 }
776
777 method uint vCtrl.wmkey <alias=vCtrl_wmkey> ( winmsg wmsg )
778 {
779 subfunc uint key( uint evktype )
780 {
781 evparKey ek
782 ek.evktype = evktype
783 ek.code = $e_key
784 ek.key = wmsg.wpar
785 if GetKeyState( $VK_MENU ) & 0x8000 : ek.mstate |= $mstAlt
786 if GetKeyState( $VK_CONTROL ) & 0x8000 : ek.mstate |= $mstCtrl
787 if GetKeyState( $VK_SHIFT ) & 0x8000 : ek.mstate |= $mstShift
788 if GetKeyState( $VK_RWIN ) & 0x8000 ||
789 GetKeyState( $VK_LWIN ) & 0x8000 : ek.mstate |= $mstWin
790 wmsg.flags = this.Virtual( $mKey, ek )
791 return 0
792 }
793
794 switch wmsg.msg
795 {
796 case $WM_KEYDOWN, $WM_SYSKEYDOWN
797 {
798 return key( $evkDown )
799 }
800 case $WM_KEYUP, $WM_SYSKEYUP
801 {
802 return key( $evkUp )
803 }
804 case $WM_CHAR, $WM_SYSCHAR
805 {
806 return key( $evkPress )
807 }
808 default : return 0
809 }
810 }
811
812
813 method uint vCtrl.mClColor <alias=vCtrl_mClColor>( winmsg wmsg )
814 {
815 uint hbrush
816 if .aStyle
817 {
818 hbrush = DefWindowProc( wmsg.hwnd, wmsg.msg, wmsg.wpar, wmsg.lpar )
819 SetBkMode( wmsg.wpar, $TRANSPARENT )
820 if .aStyle->Style.fTextColor
821 {
822 SetTextColor( wmsg.wpar, .aStyle->Style.pTextColor )
823 }
824 wmsg.flags = 1
825 if .aStyle->Style.hBrush
826 {
827 hbrush = .aStyle->Style.hBrush//GetStockObject(0)
828 }
829 //else : hbrush = GetStockObject(5)
830 //SelectObject( wmsg.wpar, hbrush )
831 return hbrush//GetStockObject(18)
832 }
833
834 if isThemed && .flgXPStyle
835 {
836 uint hfont = GetCurrentObject( wmsg.wpar, $OBJ_FONT )
837 SetBkMode( wmsg.wpar, $TRANSPARENT )
838 pDrawThemeParentBackground->stdcall( /*getctrl(wmsg.lpar)*/.hwnd, wmsg.wpar, 0 )
839 wmsg.flags = 1
840 SelectObject( wmsg.wpar, hfont )
841 if !hbrush: hbrush = GetStockObject(5)
842 }
843 //if wmsg.flags : return hbrush
844 return hbrush
845 }
846
847 method uint vCtrl.wmclcolorbtn <alias=vCtrl_wmclcolorbtn>(winmsg wmsg )
848 {
849 uint ctrl as getctrl(wmsg.lpar)
850 if &ctrl : return ctrl.Virtual( $mClColor, wmsg )
851 //return 5
852 return 0
853 /* if isThemed && .flgXPStyle
854 {
855 uint hfont = GetCurrentObject( wmsg.wpar, $OBJ_FONT )
856 SetBkMode( wmsg.wpar, $TRANSPARENT )
857 pDrawThemeParentBackground->stdcall( getctrl(wmsg.lpar).hwnd, wmsg.wpar, 0 )
858 wmsg.flags = 1
859 SelectObject( wmsg.wpar, hfont )
860 return GetStockObject(5)
861 }
862 return 0*/
863 }
864
865 method uint vCtrl.wmerasebkgnd <alias=vCtrl_wmerasebkgnd>( winmsg wmsg )
866 {
867 if isThemed && .flgXPStyle
868 {
869 RECT r
870 r.right = this.Width//.clloc.width
871 r.bottom = this.Height//.clloc.height
872 pDrawThemeParentBackground->stdcall( this.hwnd, wmsg.wpar, &r )
873 wmsg.flags = 1
874 return 1
875 }
876 /*uint hdc
877 PAINTSTRUCT lp
878 // hdc = BeginPaint( this.hwnd, lp )
879 RECT r
880 r.left = 0
881 r.top = 0
882 r.right = this.loc.width
883 r.bottom = this.loc.height
884 FillRect( wmsg.wpar, r, $COLOR_BTNFACE + 1 ) -*/
885 // EndPaint( this.hwnd, lp )
886 // InvalidateRect( this.hwnd, 0->RECT, 0 )
887 return 0
888 }
889 /*------------------------------------------------------------------------------
890 Virtual Methods
891 */
892
893
894 method vCtrl.mDestroyWin <alias=vCtrl_mDestroyWin> ()
895 {
896 if this.hwnd
897 {
898 DestroyWindow( this.hwnd )
899 this.hwnd = 0
900 }
901 }
902
903
904 method vCtrl.mPosChanging <alias=vCtrl_mPosChanging>( evparEvent ev )
905 {
906 if .flgNoPosChanging : return
907 uint evp as ev->eventpos
908 this.ownerresize( evp.loc )
909 if evp.move
910 {
911 ifdef $DESIGNING {
912 uint owner
913 owner as vCtrl
914 if this.p_designing && evp.loc != this.loc
915 {
916 owner as this
917 do
918 {
919 owner as ?( owner.pOwner && owner.pOwner != &App, owner.pOwner->vComp, 0->vComp )
920 }
921 while owner && owner.p_designing
922 if owner : owner as ?( owner.pOwner && owner.pOwner != &App, owner.pOwner->vComp, 0->vComp )
923 //if owner : owner as owner.Owner
924 if owner : owner.Virtual( $mDesChanging, &this )
925 }
926 }
927 //.flgPosChanging = 1
928 this.onposchanging.run( evp )
929 //SetWindowPos( this.hwnd, 0, evp.loc.left, evp.loc.top, evp.loc.width, evp.loc.height, $SWP_NOACTIVATE | $SWP_NOZORDER /*| $SWP_NOCOPYBITS*/ )
930 if this.hwnd : MoveWindow( this.hwnd, evp.loc.left, evp.loc.top, evp.loc.width, evp.loc.height, 1 )
931 else : this.loc = evp.loc
932
933 //SetWindowPos( this.hwnd, 0, evp.loc.left, evp.loc.top, evp.loc.width, evp.loc.height, $SWP_NOACTIVATE | $SWP_NOZORDER /*| $SWP_NOCOPYBITS*/ )
934 //.flgPosChanging = 0
935 /*UpdateWindow( 0 )
936 if this.Owner
937 {
938 UpdateWindow( this.Owner->vCtrl.hwnd )
939 } */
940 //RedrawWindow( this.hwnd, 0->RECT, 0, 0x507)
941 /*ifdef $DESIGNING {
942 if owner : owner.Virtual( $mDesChanged, &this )
943 } */
944 }
945
946 }
947
948 method vCtrl.mPosChanged <alias=vCtrl_mPosChanged>( evparEvent ev )
949 {
950 uint evu as ev->evparValUint
951 uint i
952 if evu.val
953 {
954 //foreach chctrl, this.ctrls
955 fornum i = 0, .pCtrls
956 {
957 uint chctrl as this.Comps[ i ]->vCtrl//vCtrl
958 eventpos ep
959 ep.loc = chctrl.loc
960 ep.move = 1
961 chctrl.Virtual( $mPosChanging, ep )
962 }
963 }
964 if this.pOwner && this.pOwner != &App
965 {
966 this.Owner->vCtrl.Virtual( $mChildPosChanged, this )
967 }
968 this.OnPosChanged.run( ev )
969 if .flgRePaint: .Invalidate()
970
971 ifdef $DESIGNING {
972 uint owner
973 owner as vCtrl
974 if this.p_designing
975 {
976 owner as this
977 do
978 {
979 owner as owner as ?( owner.pOwner && owner.pOwner != &App, owner.pOwner->vComp, 0->vComp )
980 }
981 while owner && owner.p_designing
982 if owner : owner as ?( owner.pOwner && owner.pOwner != &App, owner.pOwner->vComp, 0->vComp )
983 //if owner : owner as owner.Owner
984 if owner : owner.Virtual( $mDesChanged, &this )
985 }
986 }
987 }
988
989
990
991
992 method vCtrl.mRemove <alias=vCtrl_mRemove>( vComp remcomp )
993 {
994 if remcomp.TypeIs( vVirtCtrl )
995 {
996 uint ctrl as remcomp->vVirtCtrl
997 uint ar as this.Comps//ctrls
998 uint i
999 //this.childtaborder( ctrl, 0, $TAB_REMOVE )
1000 if ar[ctrl.pIndex] == &ctrl//cidx] == &ctrl
1001 {
1002
1003 ar.del(ctrl.pIndex,1)//cidx,1)
1004
1005 fornum i = ctrl.pIndex, *ar//cidx, *ar
1006 {
1007 //ar[i]->vCtrl.cidx--//cidx
1008 ar[i]->vComp.pIndex--
1009 }
1010
1011 this.pCtrls--
1012 }
1013 remcomp.Virtual( $mSetOwner, 0 )
1014 }
1015 else
1016 {
1017 this->vComp.mRemove( remcomp )
1018 }
1019 }
1020
1021
1022
1023 method vCtrl.mSetCaption <alias=vCtrl_mSetCaption>( ustr caption )
1024 {
1025 SetWindowText( this.hwnd, caption.ptr() )
1026 }
1027
1028
1029 method vCtrl.mFontChanged <alias=vCtrl_mFontChanged>( )
1030 {
1031 /*uint hFont as App.FntM.GetFont( .pFont )
1032 if &hFont
1033 {
1034 .hFont = hFont->Font.hFont
1035 }
1036 else
1037 {
1038 .hFont = GetStockObject( $DEFAULT_GUI_FONT )
1039 }
1040 this.WinMsg( $WM_SETFONT, .hFont )
1041 */
1042
1043 .aStyle = &App.StyleM.GetStyle( .pStyle )
1044 if .aStyle && .aStyle->Style.hFont
1045 {
1046 this.WinMsg( $WM_SETFONT, .aStyle->Style.hFont )
1047 }
1048 .Invalidate()
1049 }
1050
1051 method vVirtCtrl.mSetIndex <alias=vVirtCtrl_mSetIndex>( uint newidx )
1052 {
1053 if this.pOwner && this.pOwner->vComp.TypeIs( vCtrl )
1054 {
1055 this->vComp.mSetIndex( min( newidx, this.pOwner->vCtrl.pCtrls - 1 ) )
1056 }
1057 }
1058
1059 method vCtrl.mSetIndex <alias=vCtrl_mSetIndex>( uint newidx )
1060 {
1061 if this.pOwner && this.pOwner->vComp.TypeIs( vCtrl )
1062 {
1063 this->vVirtCtrl.mSetIndex( newidx )
1064 uint prevhwnd
1065 if .pIndex > 0 : prevhwnd = .pOwner->vCtrl.Comps[.pIndex-1]->vCtrl.hwnd
1066 else : prevhwnd = 1
1067 SetWindowPos( this.hwnd, prevhwnd, 0, 0, 0, 0, $SWP_NOACTIVATE | $SWP_NOSIZE | $SWP_NOMOVE )
1068 }
1069 }
1070
1071 /*------------------------------------------------------------------------------
1072 Registration
1073 */
1074
1075
1076 method vCtrl vCtrl.init()
1077 {
1078 this.pTypeId = vCtrl
1079
1080 //this.pVisible = 1
1081 //this.pEnabled = 1
1082 this.loc.width = 20
1083 this.loc.height = 20
1084 this.pAlign = $alvTop | $alhLeft
1085 return this
1086 }
1087
1088 /*method vCtrl.getevents( uint typeid, compMan cm )
1089 {
1090
1091 }
1092 */
1093 /*method vCtrl.v_focus <alias=vCtrl_focus>( eventuint ev )
1094 {
1095 if ev.val : this.form->vform.curtab = &this
1096 this.onfocus.run( ev )
1097 }
1098 */
1099
1100
1101 func uint myproc( uint hwnd, uint msg, uint wpar, uint lpar )
1102 {
1103 uint ctrl = GetWindowLong( hwnd, $GWL_USERDATA )
1104 if ctrl
1105 {
1106 uint res
1107 if ctrl->vCtrl.pTypeDef
1108 {
1109 //uint msgtbl = min( msg, $WM_USER )
1110 winmsg mymsg
1111 uint addr //= (&ctrl->vCtrl.curproctbl->proctbl.tbl[ msg << 2 ])->uint
1112 if msg < $WM_USER
1113 {
1114 addr = (ctrl->vCtrl.pTypeDef->tTypeDef.ProcTbl.data + ( msg << 2 ))->uint
1115 }
1116 else
1117 {
1118 uint i
1119 for i = 0, i < *ctrl->vCtrl.pTypeDef->tTypeDef.ProcUserTbl, i += 2
1120 {
1121 if ctrl->vCtrl.pTypeDef->tTypeDef.ProcUserTbl[i] == msg
1122 {
1123 addr = ctrl->vCtrl.pTypeDef->tTypeDef.ProcUserTbl[ i + 1 ]
1124 break
1125 }
1126 }
1127 }
1128 mymsg.flags = 0
1129 if addr
1130 {
1131 mymsg.msg = msg
1132 mymsg.hwnd = hwnd
1133 mymsg.wpar = wpar
1134 mymsg.lpar = lpar
1135 res = addr->func( ctrl, &mymsg )
1136 if mymsg.flags
1137 {
1138 return res
1139 }
1140 }
1141 }
1142
1143 if ctrl->vCtrl.prevwndproc
1144 {
1145 return CallWindowProc( ctrl->vCtrl.prevwndproc, hwnd, msg, wpar, lpar )
1146 }
1147
1148 /* if msg == $WM_DESTROY {
1149 PostQuitMessage( 0 )
1150 return 1
1151 }*/
1152
1153
1154 }
1155 return DefWindowProc( hwnd, msg, wpar, lpar );
1156 }
1157