home *** CD-ROM | disk | FTP | other *** search
/ Programming Tool Box / SIMS_2.iso / vb_code1 / 3d_tabs / tabs.bas < prev    next >
BASIC Source File  |  1994-05-31  |  16KB  |  531 lines

  1. Option Explicit
  2.  
  3. ' used only by demo
  4. Global tabsup%
  5.  
  6. 'constants
  7. Global Const SRCCOPY = &HCC0020
  8. 'flags for painting
  9. Dim loading%, resizing%
  10. 'general purpose
  11. Dim i%, r%
  12.  
  13. Type POINTAPI
  14.     x As Integer
  15.     y As Integer
  16. End Type
  17.  
  18. Type RECT
  19.     left As Integer
  20.     top As Integer
  21.     right As Integer
  22.     bottom As Integer
  23. End Type
  24.  
  25. Type boxsize
  26.     width As Integer
  27.     height As Integer
  28. End Type
  29.  
  30. Type twipdata
  31.     'scaling constants for each instance
  32.     x As Integer            'twips/per/pixelx - depends on parent's scale mode
  33.     y As Integer            'twips/per/pixely
  34.     bx As Integer           'width of nonclient in twips
  35.     by As Integer           'height of nonclient
  36. End Type
  37.  
  38. '===========structure to hold the size data===========
  39.  
  40. Type TabData
  41.     'control 'properties' - set by caller
  42.     num As Integer          'num of Page()'s
  43.     active As Integer       'active Page()
  44.     orient As Integer       'up = 0, down = 1
  45.     cols As Integer         'horz# of tabs
  46.     left As Integer         'control left in twips
  47.     top As Integer          'control top in twips
  48.     offset As Integer       'tab angle
  49.     'optional 'properties' - set by caller for sizable windows
  50.     minwidth As Integer     'based on size of captions
  51.     minheight As Integer    'user-defined
  52.     width As Integer        'width of whole control
  53.     height As Integer       'height of whole control
  54.     'optional properties for 'nonaligned' controls
  55.     insetx  As Integer
  56.     insety As Integer
  57.     'calculated by DefineControl()
  58.     rows As Integer         '# of tabs horiz
  59.     box As boxsize          'tabbox in pixels
  60.     tab As boxsize          'invbox in pixels
  61.     'twips or pixels,depending on scalemode of parent:
  62.     twp As twipdata
  63. End Type
  64.  
  65. Declare Function BitBlt% Lib "GDI" (ByVal hDestDC%, ByVal x%, ByVal y%, ByVal nWidth%, ByVal nHeight%, ByVal hSrcDC%, ByVal XSrc%, ByVal YSrc%, ByVal dwRop&)
  66. Declare Sub GetClientRect Lib "User" (ByVal hWnd%, lpRect As RECT)
  67. Declare Function GetParent% Lib "User" (ByVal hWnd%)
  68. Declare Sub GetWindowRect Lib "User" (ByVal hWnd%, lpRect As RECT)
  69.  
  70. Sub DefineControl (F As Form, tbox As Control, ibox As Control, page() As Control, tb As TabData)
  71. Dim pageleft%, pagetop%, pageheight%, pagewidth%
  72. Dim tabtop%, aligned%, w%, h%
  73. Dim theight%, pheight%
  74. '
  75. loading = -1
  76. 'Debug.Print "=========new run================"
  77. zGetScaleData F, tbox, tb
  78.  
  79. 'note:if any of these values have been set by the caller, then
  80. 'the control will be sized to fit them all!
  81. 'otherwise the tab and the Form will be fitted to Page(0)
  82. If tb.left = 0 And tb.top = 0 And tb.Width = 0 And tb.Height = 0 Then aligned = -1
  83.  
  84. '===initialize structure with size of the control======
  85.     If tb.cols = 0 Then tb.cols = tb.num + 1
  86.     If tb.num = 0 Then tb.num = UBound(page)
  87.     If tb.offset = 0 Then tb.offset = 4
  88.     If tb.insetx = 0 Then tb.insetx = 8 * tb.twp.x
  89.     If tb.insety = 0 Then tb.insety = 8 * tb.twp.y
  90.     '
  91.     tb.rows = tb.num \ tb.cols + 1
  92.  
  93. '---set height of invbox & tabbox based on textsize
  94.     tb.tab.Height = (tbox.TextHeight("X") + tb.offset)
  95.     tb.box.Height = tb.tab.Height * tb.rows
  96.     ' add 2 pixels to boxheight for 'focus' lines
  97.     theight% = (tb.box.Height + 2) * tb.twp.x
  98.  
  99. '---set an integral pixel width for invbox & tabbox
  100.     If aligned Then
  101.     pagewidth = page(0).Width \ tb.twp.x
  102.     tb.tab.Width = (pagewidth + (2 * tb.insetx \ tb.twp.x)) \ tb.cols
  103.     tb.box.Width = tb.tab.Width * tb.cols
  104.     tb.Width = tb.box.Width * tb.twp.x
  105.     Else
  106.     'for 'nonaligned', use tbox.width by default
  107.     If tb.Width = 0 Then
  108.         tb.tab.Width = (tbox.Width \ tb.cols) \ tb.twp.x
  109.         tb.Width = tbox.Width
  110.     Else
  111.     'adjust the value set by the user
  112.         tb.tab.Width = (tb.Width \ tb.cols) \ tb.twp.x
  113.     End If
  114.     tb.box.Width = tb.tab.Width * tb.cols
  115.     pagewidth = tb.box.Width - 2 * tb.insetx \ tb.twp.x
  116.     End If
  117.  
  118. '--- Calculate size of Page() height & inset---------------
  119.     If aligned Then
  120.     'use page(0) to set control and form height
  121.     pageheight = page(0).Height \ tb.twp.y
  122.     tb.insetx = (tb.Width - page(0).Width) \ 2
  123.     pheight% = page(0).Height + 2 * tb.insety
  124.     Else
  125.     If tb.Height = 0 Then
  126.         'if it wasn't specified, there's no way
  127.         'to set it
  128.         MsgBox "Must specify a control height: tb.Height = (some value)"
  129.     Else
  130.     pageheight = (tb.Height - theight%) \ tb.twp.y - 2 * tb.insety \ tb.twp.y
  131.     'pheight% = pageheight * tb.twp.y + 2 * tb.insety
  132.     pheight% = (tb.Height - theight)
  133.        End If
  134.     End If
  135.  
  136. '----height of entire control-----
  137.     If aligned Then
  138.     tb.Height = theight% + pheight%
  139.     End If
  140. 'all fields show now be initialized (except minwidth)
  141.  
  142. '===position it all according to the align paramater=======
  143. pageleft = tb.left + tb.insetx
  144. If tb.orient Then 'tabs down
  145.     pagetop = tb.top + tb.insety
  146.     tabtop = tb.top + pheight%
  147. Else ' tabs up
  148.     pagetop = tb.top + tb.insety + theight%
  149.     tabtop = tb.top
  150. End If
  151. '---size all the pages to fit Page(0)
  152. For i = 0 To tb.num
  153.     page(i).Move pageleft, pagetop, pagewidth * tb.twp.x, pageheight * tb.twp.y
  154. Next
  155. tbox.Move tb.left, tabtop, tb.Width, theight%
  156.  
  157. '----Draw the constant elements-----
  158. DrawTabs ibox, tbox, tb
  159. '----now resize the form
  160. w = tb.Width + tb.twp.bx
  161. h = tb.Height + tb.twp.by
  162. If tb.twp.x = 1 Then
  163.     w = w * screen.TwipsPerPixelX
  164.     h = h * screen.TwipsPerPixelY
  165. End If
  166. If aligned Then
  167.     F.Move F.Left, F.Top, tb.Width + tb.twp.bx, tb.Height + tb.twp.by
  168. End If
  169. page(tb.active).ZOrder
  170. End Sub
  171.  
  172. Sub DrawTabs (ibox As Control, tbox As Control, tb As TabData)
  173. Debug.Print "Entering DrawTabs------------"
  174. 'called by DefineControl
  175. 'called by TabResize for sizable windows
  176. Dim n%                  'line color (shadow/hilite)
  177. Dim box As RECT
  178. Dim yoff%, xoff%        'inset for angled line
  179. Dim top2%               'hilite/shadow line
  180. Dim invert%             '+/- multiplier
  181. Dim x%, y%, res%
  182. Dim n1%, n2%
  183.  
  184. ibox.Cls
  185. ibox.Move 0, 0, tb.tab.Width, tb.tab.Height
  186. 'set color and scale
  187. box.left = 0: box.right = ibox.ScaleWidth - 1
  188. xoff = 4
  189. If tb.orient Then 'tabs down
  190.     n = 8 'darkgrey
  191.     'tbox.Scale (0, tbox.ScaleHeight - 1)-(tbox.ScaleWidth, -1)
  192.     box.bottom = -1
  193.     box.top = ibox.ScaleHeight - 1
  194.     top2 = box.top - 1
  195.     yoff = box.top - 4
  196.     invert = -1
  197. Else
  198.     n = 15 'white
  199.     box.top = 0: box.bottom = ibox.ScaleHeight
  200.     top2 = 1
  201.     yoff = 4
  202.     invert = 1
  203. End If
  204.  
  205. ' Draw black lines
  206. ibox.Line (box.left, yoff)-(xoff, box.top)                 'angle
  207. ibox.Line -(box.right - xoff - 1, box.top)                'box.top
  208. ibox.Line (box.right - xoff - 1, box.top)-(box.right, yoff + 1 * invert)  'angle
  209. ibox.Line (box.right, box.top)-(box.right, box.bottom)                       'box.right
  210. ' Draw white/grey lines
  211. ibox.Line (box.left, box.bottom)-(box.left, yoff + 1 * invert), QBColor(15)   'box.left
  212. ibox.Line -(xoff, top2), QBColor(15)            'angle
  213. ibox.Line -(box.right - xoff - 1, top2), QBColor(n)   'top
  214. ibox.Line -(box.right - 1, yoff + 1 * invert), QBColor(8)      'angle
  215. ibox.Line -(box.right - 1, box.bottom), QBColor(8)               'right
  216. ibox.Line (box.left, box.top)-(box.left, yoff), QBColor(15)
  217. ibox.Line (box.right, box.top)-(box.right, yoff)
  218. ibox.Line (box.right - 1, box.top)-(box.right - 1, yoff), QBColor(8)
  219.  
  220. 'blit to all the lower rows
  221. tbox.Visible = 0
  222. tbox.AutoRedraw = -1
  223. If tb.rows > 1 Then
  224.     If tb.orient Then
  225.     n1 = 0: n2 = tb.rows - 2
  226.     Else
  227.     n1 = 1: n2 = tb.rows - 1
  228.     End If
  229.     For y = n1 To n2
  230.     For x = 0 To tb.cols - 1
  231.     If tb.orient Then
  232.     res = BitBlt(tbox.hDC, x * tb.tab.Width, y * tb.tab.Height + 2, tb.tab.Width, tb.tab.Height + 2, ibox.hDC, 0, 0, SRCCOPY)
  233.     Else
  234.     res = BitBlt(tbox.hDC, x * tb.tab.Width, y * tb.tab.Height, tb.tab.Width, tb.tab.Height, ibox.hDC, 0, 0, SRCCOPY)
  235.     End If
  236.     Next: Next
  237. End If
  238.  
  239. 'add some grey for the background
  240. ibox.Line (0, box.top)-(0, yoff), QBColor(8)
  241. ibox.Line (1, box.top)-(1, yoff - 1 * invert), QBColor(8)
  242. ibox.Line (2, box.top)-(2, yoff - 2 * invert), QBColor(8)
  243. ibox.Line (box.right, box.top)-(box.right, yoff + 1 * invert), QBColor(8)
  244. ibox.Line (box.right - 1, box.top)-(box.right - 1, yoff), QBColor(8)
  245. ibox.Line (box.right - 2, box.top)-(box.right - 2, yoff - 1 * invert), QBColor(8)
  246. ibox.Line (box.right - 3, box.top)-(box.right - 3, yoff - 2 * invert), QBColor(8)
  247. ibox.PSet (3, box.top), QBColor(8)
  248. ibox.PSet (box.right - 4, box.top), QBColor(8)
  249. 'now blit the top row
  250. If tb.orient Then
  251.     y = tb.rows - 1
  252. Else
  253.     y = 0
  254. End If
  255. For x = 0 To tb.cols - 1
  256.     If tb.orient Then
  257.     res = BitBlt(tbox.hDC, x * tb.tab.Width, y * tb.tab.Height + 2, tb.tab.Width, tb.tab.Height + 2, ibox.hDC, 0, 0, SRCCOPY)
  258.     Else
  259.     res = BitBlt(tbox.hDC, x * tb.tab.Width, y * tb.tab.Height, tb.tab.Width, tb.tab.Height, ibox.hDC, 0, 0, SRCCOPY)
  260.     End If'blit
  261. Next
  262. tbox.Visible = -1
  263. tbox.AutoRedraw = 0
  264.  
  265. End Sub
  266.  
  267. Sub DrawText (tbox As Control, page() As Control, tb As TabData)
  268. 'called by tbox_paint
  269. 'draws tab captions and focus line
  270. Dim activerow%
  271. Dim txtw%, y1%, y2%
  272. Dim x%, y%, inner%, outer%, theight%, cell%
  273. '
  274. Debug.Print "Entering DrawText---------"
  275. If resizing Then Debug.Print "aborting": Exit Sub
  276. '
  277. tbox.Cls
  278.  
  279. 'get row containing active tab
  280. 'this row will be drawn on bottom
  281. 'values : 0,1,2....
  282. activerow = tb.active \ tb.cols
  283. 'get first tab in active row
  284. cell = activerow * tb.cols
  285. 'set y pos
  286. If tb.orient Then  'tabsdown
  287.     inner = 0
  288.     outer = (tb.rows - 1) * tb.tab.Height
  289.     theight = tb.tab.Height
  290. Else                'tabsup
  291.     inner = tb.box.Height - tb.tab.Height
  292.     outer = 0
  293.     theight = -tb.tab.Height
  294. End If
  295. 'set x pos
  296.  
  297. For y = inner To outer Step theight%
  298. For x = 0 To (tb.cols - 1) * tb.tab.Width Step tb.tab.Width
  299.     '
  300.     If cell > tb.num Then
  301.     'blank tabs
  302.     cell = 0:
  303.     If x <> 0 Then Exit For
  304.     End If
  305.     If cell = tb.active Then tbox.FontBold = -1 Else tbox.FontBold = 0
  306.     txtw = tbox.TextWidth(page(cell).Tag)
  307.     'do something here if the caption is too large
  308.     'if txtw >tb.tab.width then
  309.     'end if
  310.     tbox.CurrentX = x + (tb.tab.Width - txtw) \ 2
  311.     tbox.CurrentY = y + tb.offset \ 2
  312.     tbox.Print page(cell).Tag
  313.     cell = cell + 1
  314.     'If n > tb.num Then n = 0
  315. Next
  316. Next
  317.  
  318. ' draw a blank line underneath the selected tab
  319. If tb.orient Then
  320.     inner = 8
  321.     y2 = 0: y1 = 1
  322. Else
  323.     inner = 15
  324.     y1 = tbox.ScaleHeight - 1: y2 = tbox.ScaleHeight - 2
  325. End If
  326. 'solid line
  327. tbox.Line (0, y1)-(tbox.ScaleWidth, y1), QBColor(inner)
  328. tbox.Line (0, y2)-(tbox.ScaleWidth, y2)
  329. 'focus line
  330. x = (tb.active Mod tb.cols) * tb.tab.Width
  331. tbox.Line (x + 1, y1)-(x + tb.tab.Width - 2, y1), tbox.BackColor
  332. tbox.Line (x + 1, y2)-(x + tb.tab.Width - 1, y2), tbox.BackColor
  333. tbox.PSet (x, y1), QBColor(15)
  334. tbox.PSet (x, y2), QBColor(15)
  335. tbox.ZOrder 0
  336. End Sub
  337.  
  338. Sub NextPage (tbox As Control, page() As Control, tb As TabData)
  339. Dim n%
  340. n% = ((tb.active + 1) Mod (tb.num + 1))
  341. tb.active = n
  342. page(n).ZOrder
  343. DrawText tbox, page(), tb
  344. End Sub
  345.  
  346. Sub PrevPage (tbox As Control, page() As Control, tb As TabData)
  347. Dim n%
  348. If tb.active = 0 Then n = tb.num Else n = tb.active - 1
  349. tb.active = n
  350. page(n).ZOrder
  351. DrawText tbox, page(), tb
  352. End Sub
  353.  
  354. Sub TabClick (Button%, x As Single, y As Single, tbox As Control, page() As Control, tb As TabData)
  355. 'called by tbox_MouseUp
  356. Dim hpos%, vpos%
  357. Dim activerow%, thisrow%, row%, n%
  358.  
  359. activerow = tb.active \ tb.cols '0,1,2...
  360. '
  361. hpos = x \ tb.tab.Width  '=0,1,2...
  362. vpos = y \ tb.tab.Height
  363. If tb.orient = 0 Then
  364.     vpos = tb.rows - vpos - 1
  365. End If
  366. '
  367. vpos = vpos + activerow
  368. If vpos >= tb.rows Then
  369.     vpos = vpos - (tb.rows)
  370. End If
  371. n = (vpos * tb.cols) + hpos
  372.  
  373. 'blank tabs:
  374. If n < 0 Or n > tb.num Then Exit Sub
  375.  
  376. tb.active = n
  377. page(n).ZOrder
  378. DrawText tbox, page(), tb
  379.  
  380. End Sub
  381.  
  382. Sub TabResize (F As Form, x%, y%, tbox As Control, ibox As Control, page() As Control, tb As TabData)
  383. 'called by form_resize for resizable windows
  384. Dim tw%             'tabwidth
  385. Dim l%, t%, w%, h%
  386. Dim mintabwidth%, minwinheight%
  387. Static here%, tightening%
  388. Dim theight%, pheight%
  389. Dim win As RECT, client As RECT
  390. '---ignore resize events during form_load-------
  391. If loading Then
  392.     here = here + 1: If here < 2 Then Exit Sub
  393.     If here = 2 Then here = 0: loading = 0: Exit Sub
  394. End If
  395. '---exit if resize was triggered by this routine
  396. If tightening% Then Exit Sub
  397.  
  398. resizing = -1: Debug.Print "Entering TabResize----------"
  399.  
  400. 'get width needed to display text
  401. 'note: this can be declared static if calculated only
  402. 'the first time if tab captions do not change:
  403. 'if mintabwidth = 0 then
  404. mintabwidth = zGetMaxTextWidth(tbox, page(), tb)
  405. 'end if
  406. tw = mintabwidth * tb.cols
  407.  
  408. 'if the caller set minwidth then use it
  409. If tb.minwidth <> 0 Then
  410.     If tb.minwidth \ tb.twp.x > tw Then
  411.     tw = tb.minwidth \ tb.twp.x
  412.     mintabwidth = tw \ tb.cols
  413.     End If
  414. End If
  415.  
  416. 'get a minheight
  417. minwinheight = tb.tab.Height + 20 'some arbitrary size
  418. If tb.minheight <> 0 Then
  419.     If tb.minheight \ tb.twp.y > minwinheight Then
  420.     minwinheight = tb.minheight \ tb.twp.y
  421.     End If
  422. End If
  423. '
  424. GetClientRect F.hWnd, client
  425. '---set an integral width for the control
  426.     If client.right < tw Then
  427.     tb.tab.Width = mintabwidth
  428.     Else
  429.     tb.tab.Width = client.right \ tb.cols
  430.     End If
  431.     tb.box.Width = tb.tab.Width * tb.cols
  432.     'reset the form size
  433.     tb.Width = tb.box.Width * tb.twp.x
  434. '---check the new height
  435.     If client.bottom < minwinheight Then
  436.     tb.Height = minwinheight * tb.twp.y
  437.     Else
  438.     tb.Height = client.bottom * tb.twp.y
  439.     End If
  440.     theight% = tb.box.Height * tb.twp.x
  441.     pheight = tb.Height - theight%
  442.  
  443. '------ready to draw------------------:
  444. tbox.Visible = 0
  445. For i = 0 To tb.num: page(i).Visible = 0: Next
  446.  
  447. '---fit the tbox to the window
  448. l = tb.insetx
  449. w = tb.Width - 2 * tb.insetx
  450. h = pheight - 2 * tb.insety
  451. '
  452. If tb.orient Then 'tabs down
  453.     t = tb.top + l
  454.     tbox.Move 0, tb.top + pheight, tb.Width, theight
  455. Else ' tabs up
  456.     t = tb.top + theight + l
  457.     tbox.Move tb.left, tb.top, tb.Width, theight
  458. End If
  459. ' fit the pages to the window
  460. For i = 0 To tb.num: page(i).Move l, t, w, h: Next
  461. '
  462. 'this triggers more calls to this routine:
  463. If F.WindowState = 0 Then
  464.     tightening = -1
  465.     'adjust window to integral tabwidth
  466.     F.Move F.Left, F.Top, tb.Width + tb.twp.bx, tb.Height + tb.twp.by
  467.     'this isn't the proper way to do this!
  468.     'need to find if the menu will wrap and make this
  469.     'adjustment before the above line
  470.     'adjust for wrapped menu items:
  471.     GetWindowRect F.hWnd, win
  472.     GetClientRect F.hWnd, client
  473.    If (win.bottom - win.top - client.bottom) * tb.twp.y <> tb.twp.by Then
  474.     tb.twp.by = (win.bottom - win.top - client.bottom) * tb.twp.y
  475.     F.Move F.Left, F.Top, tb.Width + tb.twp.bx, tb.Height + tb.twp.by
  476.    End If
  477. End If
  478. '
  479. DrawTabs ibox, tbox, tb
  480. '
  481. tightening = 0: resizing = 0
  482. DrawText tbox, page(), tb
  483. '
  484. 'finished, show it
  485. tbox.Visible = -1
  486. For i = 0 To tb.num: page(i).Visible = -1: Next
  487. '
  488. End Sub
  489.  
  490. Private Function zGetMaxTextWidth% (tbox As Control, page() As Control, tb As TabData)
  491. 'called by TabResize
  492. Dim i%, w%, max%
  493. For i = 0 To tb.num
  494. w = tbox.TextWidth(page(i).Tag)
  495. If w > max Then max = w
  496. Next
  497. zGetMaxTextWidth = max + 2 * tb.offset
  498. End Function
  499.  
  500. Private Sub zGetScaleData (F As Form, tbox As Control, tb As TabData)
  501. 'called by DefineControl
  502. Dim containerhwnd%
  503. Dim win As RECT, client As RECT
  504. 'adjustment for scalemode of the form
  505. tb.twp.x = screen.TwipsPerPixelX
  506. tb.twp.y = screen.TwipsPerPixelY
  507. '
  508. containerhwnd% = GetParent(tbox.hWnd)
  509. If containerhwnd% = F.hWnd Then
  510.     If F.ScaleMode = 3 Then tb.twp.x = 1: tb.twp.y = 1
  511. Else
  512. For i = 0 To F.Controls.Count - 1
  513.     On Error Resume Next
  514.     If F.Controls(i).hWnd = containerhwnd Then
  515.     If F.Controls(i).ScaleMode = 3 Then
  516.         If Err Then Exit For
  517.         tb.twp.x = 1: tb.twp.y = 1
  518.     End If
  519.     Exit For
  520.     End If
  521. Next
  522. End If
  523.  
  524. 'subtract client area from window for border sizes
  525. GetWindowRect F.hWnd, win
  526. GetClientRect F.hWnd, client
  527. tb.twp.bx = (win.right - win.left - client.right) * tb.twp.x
  528. tb.twp.by = (win.bottom - win.top - client.bottom) * tb.twp.y
  529. End Sub
  530.  
  531.