home *** CD-ROM | disk | FTP | other *** search
/ Media Share 13 / mediashare_13.zip / mediashare_13 / ZIPPED / PROGRAM / TBIWIN12.ZIP / TBIWIN.CPP < prev    next >
C/C++ Source or Header  |  1992-12-15  |  13KB  |  508 lines

  1. //----------------------------------------------------
  2. // TBIWINDOW.CPP
  3. //----------------------------------------------------
  4. // TBIWindow Ver. 1.2 (c) Copyright Casper Pedersen  1992
  5. // This source must be used, but not changed is it is
  6. // distributed to other people
  7. // If any questions write to
  8. // Casper Pedersen
  9. // P. Knudsensvej 14, 3, V. 11.
  10. // DK-8900  Randers
  11. // Denmark
  12. //
  13. // NOTE
  14. // The TBIWindow will might not work under Win30, that
  15. // is because I use WM_WINDOWPOSCHANGED, which first
  16. // was implemented in Win31.
  17. //----------------------------------------------------
  18. #include "tbiwin.h"
  19. //----------------------------------------------------
  20. // Function to display bitmaps
  21. //----------------------------------------------------
  22. extern "C" void _DisplayCaptionBitmap(HDC hdc, POINT pt, POINT pts, HBITMAP hBit)
  23. {
  24.   BITMAP    bm;
  25.   HDC        hdcMem;
  26.   POINT        ptOrg, ptSize;
  27.  
  28.   hdcMem = CreateCompatibleDC(hdc);
  29.   if ( hdcMem == NULL ) return;
  30.  
  31.   SelectObject(hdcMem, hBit);
  32.   SetMapMode(hdcMem, GetMapMode(hdc));
  33.  
  34.   GetObject(hBit, sizeof(BITMAP), (LPSTR)&bm);
  35.   ptSize.x = bm.bmWidth;
  36.   ptSize.y = bm.bmHeight;
  37.   ptOrg.x = 0;
  38.   ptOrg.y = 0;
  39.   DPtoLP(hdcMem, &ptOrg, 1);
  40.  
  41.   StretchBlt(hdc, pt.x, pt.y, pts.x, pts.y, hdcMem, 0, 0, ptSize.x, ptSize.y, SRCCOPY);
  42.  
  43.   DeleteDC(hdcMem);
  44. }
  45.  
  46. //----------------------------------------------------
  47. // Defines
  48. //----------------------------------------------------
  49. // macro that returns TRUE if the pt(p) is in the rect(r)
  50. #define ISPTINRECT(p, r) ( p.x >= r.left && p.x <= r.right && p.y >= r.top && p.y <= r.bottom )
  51.  
  52. // they are difined in the win30.h
  53. // but if compiles withe the WIN31 keyword
  54. // the win30.h is not included
  55. #ifndef OBM_CLOSE
  56. #define OBM_CLOSE 32754
  57. #endif
  58. #ifndef OBM_RESTORE
  59. #define OBM_RESTORE 32747
  60. #endif
  61.  
  62. //----------------------------------------------------
  63. // the constructor
  64. //----------------------------------------------------
  65. TBIWindow::TBIWindow(PTWindowsObject AParent, LPSTR ATitle, LEFTRIGHT LR, PTModule AModule) : TWindow(AParent, ATitle, AModule)
  66. {
  67.   WinName = ATitle;
  68.   _LR = LR;
  69.   ButtonDown = FALSE;
  70.   ButtonActive = 0;
  71.   ActivatedButton = 0;
  72.  
  73.   WinActive = FALSE;
  74.  
  75.   NoButtonsIn = 0;
  76.   head = new TBIList;
  77.   tail = new TBIList;
  78.   head->next = tail;
  79.   head->prev = NULL;
  80.   tail->next = NULL;
  81.   tail->prev = head;
  82.  
  83.   XStart = XEnd = 0;
  84. }
  85.  
  86. //----------------------------------------------------
  87. // the destructor
  88. //----------------------------------------------------
  89. TBIWindow::~TBIWindow()
  90. {
  91.   PTBIList tmp = head->next;
  92.   while(tmp != tail)
  93.   {
  94.     PTBIList del = tmp;
  95.     tmp = tmp->next;
  96.     del->prev->next = tmp;
  97.     tmp->prev = del->prev;
  98.  
  99.     DeleteObject(del->ButtonDeactive);
  100.     DeleteObject(del->ButtonActive);
  101.     delete del;
  102.   }
  103.  
  104.   delete head;
  105.   delete tail;
  106. }
  107.  
  108. //----------------------------------------------------
  109. void TBIWindow::GetWindowClass(WNDCLASS _FAR &AWndClass)
  110. {
  111.   TWindow::GetWindowClass(AWndClass);
  112.   // For Borland C++ users see in help, under CS_BYTEALIGNWINDOW
  113.   AWndClass.style |= CS_BYTEALIGNWINDOW;
  114. }
  115.  
  116. //----------------------------------------------------
  117. BOOL TBIWindow::IsInList(UINT ResId)
  118. {
  119.   // We will not have two of the same buttons
  120.   // in the list
  121.   PTBIList tmp = head->next;
  122.   while(tmp != tail)
  123.   {
  124.     if ( tmp->ButtonNo == ResId )
  125.       return(TRUE);
  126.     tmp = tmp->next;
  127.   }
  128.  
  129.   return(FALSE);
  130. }
  131.  
  132. //----------------------------------------------------
  133. BOOL TBIWindow::AddButton(UINT ResourceID)
  134. {
  135.   // no duplets are allowed
  136.   if ( IsInList(ResourceID) ) return(FALSE);
  137.  
  138.   PTBIList tmp = new TBIList;
  139.   if ( tmp == NULL ) return (FALSE);
  140.  
  141.   tmp->ButtonNo = ResourceID;
  142.  
  143.   HBITMAP hBit = LoadBitmap(GetApplication()->hInstance, MAKEINTRESOURCE(ResourceID + 10000));
  144.   if ( hBit == NULL )
  145.   {
  146.     delete tmp;
  147.     return (FALSE);
  148.   }
  149.  
  150.   tmp->ButtonDeactive = hBit;
  151.  
  152.   hBit = LoadBitmap(GetApplication()->hInstance, MAKEINTRESOURCE(ResourceID + 30000));
  153.   if ( hBit == NULL )
  154.   {
  155.     DeleteObject(tmp->ButtonDeactive);
  156.     delete tmp;
  157.     return (FALSE);
  158.   }
  159.  
  160.   tmp->ButtonActive = hBit;
  161.  
  162.   tmp->prev = tail->prev;
  163.   tail->prev->next = tmp;
  164.   tmp->next = tail;
  165.   tail->prev = tmp;
  166.  
  167.   NoButtonsIn++;
  168.  
  169.   return (TRUE);
  170. }
  171.  
  172. //----------------------------------------------------
  173. void TBIWindow::ButtonActivated(void)
  174. {
  175.   // To be overloaded
  176. }
  177.  
  178. //----------------------------------------------------
  179. void TBIWindow::WMSize(RTMessage Msg)
  180. {
  181.   TWindow::WMSize(Msg);
  182.  
  183.   // We cannot have that the buttons are drawn outside the
  184.   // window
  185.   // if the window is smaller than our buttons and
  186.   // the systemmenu + minimize- and maximizebuttons
  187.   // then we resizes the window
  188.   int x = (Attr.Style & WS_SYSMENU) ? CloseSize() : 0;
  189.   if ( Msg.LP.Lo < ( ((NoButtonsIn + 1) * CloseSize()) + ButtonSize() + x ) )
  190.   {
  191.     RECT rc;
  192.     GetWindowRect(HWindow, &rc);
  193.     MoveWindow(HWindow, rc.left, rc.top, ((NoButtonsIn + 1) * CloseSize()) + ButtonSize() + x, rc.bottom - rc.top, TRUE);
  194.   }
  195.  
  196.   UpdateCaption();
  197. }
  198.  
  199. //----------------------------------------------------
  200. void TBIWindow::WMNCLButtonDBLCLK(RTMessage Msg)
  201. {
  202.    if ( Msg.WParam == HTCAPTION && LOWORD(Msg.LParam) > XStart && LOWORD(Msg.LParam) < XEnd )
  203.      return;
  204.  
  205.    TWindow::DefWndProc(Msg);
  206. }
  207.  
  208. //----------------------------------------------------
  209. void TBIWindow::WMNCLButtonDown(RTMessage Msg)
  210. {
  211.   if ( Msg.WParam == HTCAPTION && LOWORD(Msg.LParam) < XEnd && LOWORD(Msg.LParam) > XStart && WinActive )
  212.   {
  213.      AKTBut = MAKEPOINT(Msg.LParam);
  214.      if ( CalcRect(AKTBut) )
  215.        HighLiteButton();
  216.      return;
  217.   }
  218.  
  219.   TWindow::DefWndProc(Msg);
  220. }
  221.  
  222. //----------------------------------------------------
  223. void TBIWindow::WMNCLButtonUp(RTMessage Msg)
  224. {
  225.   if ( ButtonDown )
  226.     HighLiteButton();
  227.  
  228.   // Must react just like MicroSoft buttons
  229.   // they do not sendmessages before the button is
  230.   // deactivated, and the mousepointer is in the
  231.   // button rect.
  232.   if ( ISPTINRECT(MAKEPOINT(Msg.LParam), AKTRect) )
  233.     SendMessage(HWindow, WM_COMMAND, ButtonActive, 0l);
  234.  
  235.   SetRectEmpty(&AKTRect);
  236.   TWindow::DefWndProc(Msg);
  237. }
  238.  
  239. //----------------------------------------------------
  240. void TBIWindow::WMLButtonUp(RTMessage Msg)
  241. {
  242.   SetRectEmpty(&AKTRect);
  243.   TWindow::DefWndProc(Msg);
  244. }
  245.  
  246. //----------------------------------------------------
  247. void TBIWindow::WMNCMouseMove(RTMessage Msg)
  248. {
  249.   POINT pt = MAKEPOINT(Msg.LParam);
  250.   if ( !ISPTINRECT(pt, AKTRect) && ButtonDown )
  251.     HighLiteButton();
  252.   else
  253.   if ( ISPTINRECT(pt, AKTRect) && !ButtonDown )
  254.     HighLiteButton();
  255.  
  256.   TWindow::DefWndProc(Msg);
  257. }
  258.  
  259. //----------------------------------------------------
  260. void TBIWindow::WMMouseMove(RTMessage Msg)
  261. {
  262.   if ( ButtonDown )
  263.     HighLiteButton();
  264.  
  265.   TWindow::DefWndProc(Msg);
  266. }
  267.  
  268. //----------------------------------------------------
  269. void TBIWindow::WMActivate(RTMessage Msg)
  270. {
  271.    TWindow::WMActivate(Msg);
  272.  
  273.    // if the window is been activated, either by call, or
  274.    // click with the mouse
  275.    if (Msg.WParam == WA_CLICKACTIVE || Msg.WParam == WA_ACTIVE )
  276.    {
  277.      UpdateCaption();
  278.      WinActive = TRUE;
  279.    }
  280.    else
  281.    {
  282.      // if not active set caption
  283.      WinActive = FALSE;
  284.      SetCaption(WinName);
  285.    }
  286. }
  287.  
  288. //----------------------------------------------------
  289. void TBIWindow::WMWindowPosChanged(RTMessage Msg)
  290. {
  291.   TWindow::DefWndProc(Msg);
  292.  
  293.   if ( IsIconic(HWindow) )
  294.     return;
  295.  
  296.   // to be sure that the buttons not are drawn
  297.   // when the window is nonactive, and
  298.   // when the window is to be closed
  299.   LPWINDOWPOS pwp = (WINDOWPOS FAR*) Msg.LParam;
  300.  
  301.   if ( pwp->flags & SWP_HIDEWINDOW )
  302.     WinHidden = TRUE;
  303.   else
  304.   if ( pwp->flags & SWP_SHOWWINDOW )
  305.     WinHidden = FALSE;
  306.  
  307.   if ( pwp->flags & SWP_NOACTIVATE )
  308.     return;
  309.  
  310.   // Even though Borland, in the help file says that WINDOWPOS.flags
  311.   // only can be one of the SWP_... values, it only works when
  312.   // I use & (and).
  313.  
  314.   DisplayButton();
  315. }
  316.  
  317. //----------------------------------------------------
  318. void TBIWindow::UpdateCaption(void)
  319. {
  320.   // if not, it look silly when minimized
  321.   if ( IsIconic(HWindow) )
  322.     return;
  323.  
  324.   DisplayButton();
  325. }
  326.  
  327. //----------------------------------------------------
  328. void TBIWindow::DisplayButton(void)
  329. {
  330.   if ( WinHidden ) return;
  331.   if ( head->next == tail ) return;
  332.  
  333.   RECT  rc; GetWindowRect(HWindow, &rc);
  334.   POINT pt; pt.x = 0; pt.y = 0;
  335.  
  336.   // we must not overwrite the sysmenu
  337.   if ( (Attr.Style & WS_SYSMENU) && (_LR != RIGHT) )
  338.      pt.x = CloseSize();
  339.  
  340.   // there are more than one FRAME style
  341.   if ( (Attr.Style & WS_DLGFRAME) || (Attr.Style & WS_THICKFRAME) )
  342.   {
  343.     pt.x += GetSystemMetrics(SM_CXDLGFRAME);
  344.     pt.y += GetSystemMetrics(SM_CYDLGFRAME);
  345.   }
  346.   else
  347.   {
  348.     pt.x += GetSystemMetrics(SM_CXBORDER);
  349.     pt.y += GetSystemMetrics(SM_CYBORDER);
  350.   }
  351.  
  352.   // the hight of the caption bar, whith small fonts
  353.   // it is 19 pixels high
  354.   POINT pts; pts.x = pts.y = GetSystemMetrics(SM_CYCAPTION) - 1;
  355.  
  356.   if ( _LR == LEFT )
  357.     pt.x += rc.left;
  358.   else
  359.   if ( _LR == RIGHT )
  360.     pt.x = rc.right - ( ButtonSize() + (pts.x * NoButtonsIn) + pt.x );
  361.  
  362.   pt.y += rc.top;
  363.   pts.y -= 1;
  364.  
  365.   XStart = pt.x;
  366.  
  367.   HDC hdc = CreateDC("DISPLAY", NULL, NULL, NULL);
  368.   if ( hdc == NULL ) return;
  369.  
  370.   PTBIList tmp = head->next;
  371.   while(tmp != tail)
  372.   {
  373.     _DisplayCaptionBitmap(hdc, pt, pts, tmp->ButtonDeactive);
  374.     pt.x += pts.x;
  375.     tmp = tmp->next;
  376.   }
  377.  
  378.   XEnd = pt.x;
  379.  
  380.   DeleteDC(hdc);
  381. }
  382.  
  383. //----------------------------------------------------
  384. void TBIWindow::HighLiteButton(void)
  385. {
  386.   if ( ActivatedButton == -1 )
  387.     return;
  388.  
  389.   HDC hdc = CreateDC("DISPLAY", NULL, NULL, NULL);
  390.   if ( hdc == NULL ) return;
  391.  
  392.   POINT pt, pts;
  393.   pt.x = AKTRect.left;
  394.   pt.y = AKTRect.top;
  395.   pts.x = AKTRect.right - pt.x;
  396.   pts.y = AKTRect.bottom - pt.y - 1;
  397.  
  398.   // we must find the actual button, in the list
  399.   PTBIList tmp = head->next;
  400.   while (tmp != tail && tmp->ButtonNo != ButtonActive)
  401.   { tmp = tmp->next; }
  402.  
  403.   if (tmp == tail) return;
  404.  
  405.   if ( !ButtonDown )
  406.   {
  407.     _DisplayCaptionBitmap(hdc, pt, pts, tmp->ButtonActive);
  408.   }
  409.   else
  410.   {
  411.     _DisplayCaptionBitmap(hdc, pt, pts, tmp->ButtonDeactive);
  412.   }
  413.  
  414.   pt.x += pts.x;
  415.   ButtonDown = !ButtonDown;
  416.  
  417.   DeleteDC(hdc);
  418. }
  419.  
  420. //----------------------------------------------------
  421. BOOL TBIWindow::CalcRect(POINT pt)
  422. {
  423.   // not much to explain, we find the
  424.   // button no, and the size of it
  425.   if ( pt.x >= XStart && pt.x <= XEnd )
  426.   {
  427.     UINT width = GetSystemMetrics(SM_CYCAPTION) - 1;
  428.  
  429.     RECT rect; GetWindowRect(HWindow, &rect);
  430.     rect.top += GetSystemMetrics(SM_CYDLGFRAME);
  431.  
  432.     UINT no = (pt.x - XStart) / width;
  433.  
  434.     AKTRect.top = rect.top;
  435.     AKTRect.left = (no * width) + XStart;
  436.     AKTRect.bottom = AKTRect.top + width;
  437.     AKTRect.right = AKTRect.left + width;
  438.  
  439.     PTBIList tmp = head->next;
  440.     for(UINT i = 0; i < no && tmp != tail; i++, tmp = tmp->next );
  441.  
  442.     ButtonActive = tmp->ButtonNo;
  443.     ActivatedButton = no;
  444.  
  445.     // call the possible overloaded function
  446.     ButtonActivated();
  447.  
  448.     return (TRUE);
  449.   }
  450.  
  451.   ActivatedButton = -1;
  452.   return (FALSE);
  453. }
  454.  
  455. //----------------------------------------------------
  456. UINT TBIWindow::CloseSize(void)
  457. {
  458.   // Calculates the size of the SystemMenu bitmap
  459.   HBITMAP hBit = LoadBitmap(NULL,MAKEINTRESOURCE(OBM_CLOSE));
  460.   BITMAP bm;
  461.   GetObject(hBit, sizeof(BITMAP), &bm);
  462.   UINT width = bm.bmWidth/2;
  463.   DeleteObject(hBit);
  464.   return(width);
  465. }
  466.  
  467. //----------------------------------------------------
  468. UINT TBIWindow::ButtonSize(void)
  469. {
  470.   // Calculates the size of the MAXIMIZE and MINIMIZE bitmaps
  471.   // if they are there.
  472.   HBITMAP hBit = LoadBitmap(NULL,MAKEINTRESOURCE(OBM_RESTORE));
  473.   BITMAP bm;
  474.   GetObject(hBit, sizeof(BITMAP), &bm);
  475.   UINT    width = 0;
  476.  
  477.   if ( Attr.Style & WS_MAXIMIZEBOX )
  478.     width += bm.bmWidth;
  479.  
  480.   if ( Attr.Style & WS_MINIMIZEBOX )
  481.     width += bm.bmWidth;
  482.  
  483.   DeleteObject(hBit);
  484.  
  485.   return(width);
  486. }
  487.  
  488. //----------------------------------------------------
  489. #ifdef USEBWCC
  490.  #include <bwcc.h>
  491. #endif
  492. //----------------------------------------------------
  493. void TBIWindow::AboutTBIWindow(void)
  494. {
  495.    char str[100];
  496.    wsprintf((LPSTR)str, "TBIWindow ver. %x.%x\n(c) Casper Pedersen\nCompiled: %s\nProvided As FreeWare", HIWORD(TBIGetVersion()), LOWORD(TBIGetVersion()), __DATE__ );
  497. #ifdef USEBWCC
  498.    BWCCMessageBox(
  499. #else
  500.    MessageBox(
  501. #endif
  502.    HWindow, str, "About TBIWindow", MB_ICONINFORMATION | MB_OK);
  503. }
  504.  
  505. //----------------------------------------------------
  506. // END
  507. //----------------------------------------------------
  508.