home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1998 May / Pcwk5b98.iso / Borland / Cplus45 / BC45 / BMPVIEW.PAK / BMPVIEW.CPP next >
C/C++ Source or Header  |  1995-08-29  |  17KB  |  656 lines

  1. //----------------------------------------------------------------------------
  2. // ObjectWindows - (C) Copyright 1991, 1993 by Borland International
  3. //   Example program that shows Dibs, Bitmaps and Palettes in a scrolling
  4. //   Window. Also uses diagnostics to trace thru some routines
  5. //----------------------------------------------------------------------------
  6. #include <owl\owlpch.h>
  7. #include <owl\applicat.h>
  8. #include <owl\dc.h>
  9. #include <owl\menu.h>
  10. #include <owl\framewin.h>
  11. #include <owl\scroller.h>
  12. #include <owl\opensave.h>
  13. #include <owl\clipview.h>
  14. #include <string.h>
  15. #include <dir.h>
  16. #include "bmpview.h"
  17.  
  18. DIAG_DEFINE_GROUP_INIT(OWL_INI, BmpView, 1, 0);
  19.  
  20. #define USE_DDB     // Use a DDB, else blts the DIB directly to the screen
  21. //#define PAINT_ICON  // define to paint the icon from the bitmap
  22.  
  23. #define MAXAPPNAME  20
  24. static const char AppName[] = "BitmapView";
  25.  
  26. //
  27. // TBmpViewWindow, a Bitmap displaying window derived from TClipboardViewer to
  28. // facilitate receiving of clipboard change notifications. Could mix it in if
  29. // an additional base was desired.
  30. //
  31. class TBmpViewWindow : virtual public TWindow, public TClipboardViewer {
  32.   public:
  33.     char      FileName[MAXPATH];
  34.     TDib*     Dib;
  35. #if defined(USE_DDB)
  36.     TBitmap*  Bitmap;
  37. #endif
  38.     TPalette* Palette;
  39.     TBrush*   BkgndBrush;
  40.     long      Rop;
  41.     int       PixelWidth;
  42.     int       PixelHeight;
  43.     WORD      Colors;
  44.     BOOL      Fit;
  45.     BOOL      AutoClipView;
  46.  
  47.     TBmpViewWindow();
  48.    ~TBmpViewWindow();
  49.  
  50.   protected:
  51.     void      CmFileOpen();
  52.     void      CmRead1();
  53.     void      CmRead2();
  54.     void      CmReadBad();
  55.     void      CmCopy();
  56.     void      CmPaste();
  57.     void      CmFit();
  58.     void      CmAutoClipView();
  59.     void      CeCopy(TCommandEnabler& ce);
  60.     void      CePaste(TCommandEnabler& ce);
  61.     void      CeFit(TCommandEnabler& ce);
  62.     void      CeAutoClipView(TCommandEnabler& ce);
  63.  
  64.     void      Paint(TDC&, BOOL erase, TRect&);
  65.     void      EvSize(UINT sizeType, TSize&);
  66.  
  67.     void      EvPaletteChanged(HWND hWndPalChg);
  68.     BOOL      EvQueryNewPalette();
  69.     void      EvSetFocus(HWND); // should use above when working
  70.     void      EvDrawClipboard();
  71.     void      EvDestroy();
  72.  
  73.     BOOL      UpdatePalette(BOOL alwaysRepaint);
  74.     void      AdjustScroller();
  75.     void      SetCaption(const char*);
  76.     void      SetupFromDib(TDib* dib);
  77.     BOOL      LoadBitmapFile(const char*);
  78.     BOOL      LoadBitmapResource(WORD ResId);
  79.  
  80.   DECLARE_RESPONSE_TABLE(TBmpViewWindow);
  81. };
  82.  
  83. DEFINE_RESPONSE_TABLE2(TBmpViewWindow, TClipboardViewer, TWindow)
  84.   EV_COMMAND(CM_FILEOPEN, CmFileOpen),
  85.   EV_COMMAND(CM_READ1, CmRead1),
  86.   EV_COMMAND(CM_READ2, CmRead2),
  87.   EV_COMMAND(CM_READBAD, CmReadBad),
  88.   EV_COMMAND(CM_EDITCOPY, CmCopy),
  89.   EV_COMMAND(CM_EDITPASTE, CmPaste),
  90.   EV_COMMAND(CM_FIT, CmFit),
  91.   EV_COMMAND(CM_AUTOCLIPVIEW, CmAutoClipView),
  92.   EV_COMMAND_ENABLE(CM_EDITCOPY, CeCopy),
  93.   EV_COMMAND_ENABLE(CM_EDITPASTE, CePaste),
  94.   EV_COMMAND_ENABLE(CM_FIT, CeFit),
  95.   EV_COMMAND_ENABLE(CM_AUTOCLIPVIEW, CeAutoClipView),
  96.   EV_WM_SIZE,
  97.   EV_WM_PALETTECHANGED,
  98.   EV_WM_QUERYNEWPALETTE,
  99.   EV_WM_SETFOCUS,
  100.   EV_WM_DRAWCLIPBOARD,
  101.   EV_WM_DESTROY,
  102. END_RESPONSE_TABLE;
  103.  
  104. //
  105. // Constructor for a TBmpViewWindow, sets scroll styles and constructs
  106. // the Scroller object.  Also sets the Rop based on whether the display
  107. // is monochrome (two-color) or polychrome.
  108. //
  109. TBmpViewWindow::TBmpViewWindow()
  110.   : TWindow(0, 0, 0), TClipboardViewer()
  111. {
  112.   // Init TWindow since TClipboardViewer is usually a mixin and doesn't do it
  113.   //
  114. //  Init(0, 0, 0);
  115.  
  116.   Attr.Style |= WS_VSCROLL | WS_HSCROLL;
  117.   Dib = 0;
  118. #if defined(USE_DDB)
  119.   Bitmap = 0;
  120. #endif
  121.   Palette = 0;
  122.   BkgndBrush = new TBrush(::GetSysColor(COLOR_WINDOW));
  123.   Scroller = new TScroller(this, 1, 1, 200, 200);
  124.   Fit = FALSE;
  125.   AutoClipView = FALSE;
  126.  
  127.   TScreenDC screenDC;
  128.   if (screenDC.GetDeviceCaps(NUMCOLORS) < 3 )
  129.     Rop = NOTSRCCOPY;
  130.   else
  131.     Rop = SRCCOPY;
  132.   
  133.   SetCaption(0);
  134. }
  135.  
  136. TBmpViewWindow::~TBmpViewWindow()
  137. {
  138. #if defined(USE_DDB)
  139.   delete Bitmap;
  140. #endif
  141.   delete Palette;
  142.   delete Dib;
  143.   delete BkgndBrush;
  144. }
  145.  
  146. //
  147. // Build up a caption based on a filename, and set it into the title.
  148. //
  149. void
  150. TBmpViewWindow::SetCaption(const char* name) 
  151. {
  152.   char caption[MAXPATH + MAXAPPNAME + 2 + 1];
  153.   strcpy(FileName, name ? name : "(Untitled)");
  154.   strcpy(caption, GetApplication()->GetName());
  155.   strcat(caption, " - ");
  156.   strcat(caption, FileName);
  157.   if (Parent)
  158.     Parent->SetCaption(caption);
  159. }
  160.  
  161. //
  162. // Make a metafile & put it on the clipboard.
  163. // Make a copy of each of the objects & place the copies on the clipboard
  164. //
  165. void
  166. TBmpViewWindow::CmCopy()
  167. {
  168.   TClipboard& clipboard = OpenClipboard();
  169.   if (clipboard.EmptyClipboard()) {
  170.     TMetaFileDC mfDC;
  171.     mfDC.SetWindowExt(Dib->Size());
  172.     mfDC.SetWindowOrg(0, 0);
  173.     mfDC.SetDIBitsToDevice(TRect(0,0, PixelWidth, PixelHeight), TPoint(0,0), *Dib);
  174.     TMetaFilePict mf(mfDC.Close(), AutoDelete);
  175.     mf.ToClipboard(clipboard, MM_TEXT, TSize(PixelWidth, PixelHeight));
  176.  
  177.     TPalette(*Palette).ToClipboard(clipboard);
  178.     TDib(*Dib).ToClipboard(clipboard);
  179. #if defined(USE_DDB)
  180.     TBitmap(*Bitmap).ToClipboard(clipboard);
  181. #endif
  182.  
  183.     clipboard.CloseClipboard();
  184.   }
  185. }
  186.  
  187. void
  188. TBmpViewWindow::CeCopy(TCommandEnabler& ce)
  189. {
  190.   ce.Enable(Dib != 0);
  191. }
  192.  
  193. //
  194. // When a user selects edit.paste, get the data from the clipboard. This
  195. // routine prefers CF_META over CF_DIB over CF_BITMAP
  196. //
  197. void
  198. TBmpViewWindow::CmPaste()
  199. {
  200.   TClipboard& clipboard = OpenClipboard();
  201.   if (!clipboard)
  202.     return;
  203.  
  204.   TPalette* newPal = 0;
  205.   TDib*     newDib = 0;
  206.   TBitmap*  newBitmap;
  207.  
  208.   // If there is a palette on the clipboard, get it & realize it
  209.   //
  210.   if (clipboard.IsClipboardFormatAvailable(CF_PALETTE)) {
  211.     newPal = new TPalette(TPalette(clipboard));  // make a copy
  212.     UpdatePalette(TRUE);
  213.   }
  214.  
  215.   // try DIB format 1st
  216.   //
  217.   if (clipboard.IsClipboardFormatAvailable(CF_DIB)) {
  218.     newDib = new TDib(TDib(clipboard));        // make a copy
  219.     newBitmap = new TBitmap(*newDib, newPal);  // newPal==0 is OK
  220.  
  221.   // try metafile 2nd
  222.   //
  223.   } else if (clipboard.IsClipboardFormatAvailable(CF_METAFILEPICT)) {
  224.     if (!newPal)
  225.       newPal = new TPalette((HPALETTE)GetStockObject(DEFAULT_PALETTE));
  226.     newBitmap = new TBitmap(TMetaFilePict(clipboard), *newPal,
  227.                             GetClientRect().Size());
  228.  
  229. #if defined(USE_DDB)
  230.   // try bitmap (DDB) format 3rd
  231.   //
  232.   } else if (clipboard.IsClipboardFormatAvailable(CF_BITMAP))
  233.     newBitmap = new TBitmap(TBitmap(clipboard));     // make a copy
  234.  
  235.   else
  236.     return;  // Should never happen--this command is enabled by above tests
  237.  
  238.   // Got a bitmap & maybe more. Now keep it & setup things.
  239.   //
  240.   delete Bitmap;
  241.   Bitmap = newBitmap;
  242.  
  243.   if (!newDib)
  244.     newDib = new TDib(*newBitmap, newPal);
  245. #else
  246.   }
  247. #endif
  248.   delete Dib;
  249.   Dib = newDib;
  250.  
  251.   delete Palette;
  252.   Palette = newPal ? newPal : new TPalette(*newDib);
  253.   Palette->GetObject(Colors);
  254.  
  255.   PixelWidth  = Dib->Width();
  256.   PixelHeight = Dib->Height();
  257.   AdjustScroller();
  258.   SetCaption("(Clipboard)");
  259.   
  260.   clipboard.CloseClipboard();
  261.  
  262. //  Parent->SetIcon(0, 0);  // we'll paint the icon from the bitmap
  263. }
  264.  
  265. void
  266. TBmpViewWindow::CePaste(TCommandEnabler& ce)
  267. {
  268.   TClipboard& clipboard = OpenClipboard();
  269.   ce.Enable(
  270.     clipboard && (
  271.       clipboard.IsClipboardFormatAvailable(CF_METAFILEPICT) ||
  272.       clipboard.IsClipboardFormatAvailable(CF_DIB) ||
  273.       clipboard.IsClipboardFormatAvailable(CF_BITMAP)
  274.     )
  275.   );
  276.   clipboard.CloseClipboard();
  277. }
  278.  
  279. //
  280. // If either of the "Read bitmap" menu items is selected, then we read
  281. // the bitmap resource with the ID of the menu item...
  282. //
  283. void
  284. TBmpViewWindow::CmRead1()
  285. {
  286.   if (LoadBitmapResource(CM_READ1))
  287.     SetCaption("(Bitmap resource 1)");
  288. }
  289.  
  290. void
  291. TBmpViewWindow::CmRead2()
  292. {
  293.   if (LoadBitmapResource(CM_READ2))
  294.     SetCaption("(Bitmap resource 2)");
  295. }
  296.  
  297. void
  298. TBmpViewWindow::CmReadBad()
  299. {
  300.   LoadBitmapFile("");   // force a failure for kicks
  301. }
  302.  
  303. //
  304. // Toggle Fit member variable & adjust scroller as needed
  305. //
  306. void
  307. TBmpViewWindow::CmFit()
  308. {
  309.   Fit = !Fit;
  310.   AdjustScroller();
  311. }
  312.  
  313. //
  314. // The fit menu item is checked if the Fit member is true
  315. //
  316. void
  317. TBmpViewWindow::CeFit(TCommandEnabler& ce)
  318. {
  319.   ce.SetCheck(Fit ? TCommandEnabler::Checked : TCommandEnabler::Unchecked);
  320. }
  321.  
  322. //
  323. // Toggle AutoAutoClipView member variable
  324. //
  325. void
  326. TBmpViewWindow::CmAutoClipView()
  327. {
  328.   AutoClipView = !AutoClipView;
  329. }
  330.  
  331. //
  332. // Check AutoClipView according to flag
  333. //
  334. void
  335. TBmpViewWindow::CeAutoClipView(TCommandEnabler& ce)
  336. {
  337.   ce.SetCheck(AutoClipView ? TCommandEnabler::Checked : TCommandEnabler::Unchecked);
  338. }
  339.  
  340. //
  341. // If the the "Open..." menu item is selected, then we prompt the user
  342. // for a new bitmap file.  If the user selects one and it is one that
  343. // we can read, we display it in the window and change the window's
  344. // caption to reflect the new bitmap file.
  345. //
  346. void
  347. TBmpViewWindow::CmFileOpen()
  348. {
  349.   static TOpenSaveDialog::TData data (
  350.     OFN_HIDEREADONLY|OFN_FILEMUSTEXIST|OFN_NOREADONLYRETURN,
  351.     "Bitmap Files (*.BMP)|*.bmp|",
  352.     0,
  353.     "",
  354.     "BMP"
  355.   );
  356.   if (TFileOpenDialog(this, data).Execute() == IDOK) {
  357.     char fileTitle[MAXPATH];
  358.     TOpenSaveDialog::GetFileTitle(data.FileName, fileTitle, MAXPATH);
  359.     LoadBitmapFile(fileTitle);
  360.     SetCaption(strlwr(fileTitle));
  361.   }
  362. }
  363.  
  364. //
  365. // Adjust the Scroller range so that the the origin is the
  366. // upper-most scrollable point and the corner is the
  367. // bottom-most.
  368. //
  369. void
  370. TBmpViewWindow::AdjustScroller() 
  371. {
  372.   TRect  clientRect = GetClientRect();
  373.  
  374.   // only show scrollbars when image is larger than
  375.   // the client area and we are not stretching to fit.
  376.   //
  377.   if (Fit)
  378.     Scroller->SetRange(0, 0);
  379.  
  380.   else {
  381.     TPoint Range(Max(PixelWidth-clientRect.Width(), 0),
  382.                  Max(PixelHeight-clientRect.Height(), 0));
  383.     Scroller->SetRange(Range.x, Range.y);
  384.   }
  385.   Scroller->ScrollTo(0, 0);
  386.   if (!GetUpdateRect(clientRect, FALSE))
  387.     Invalidate(FALSE);
  388. }
  389.  
  390. //
  391. // Reset scroller range.
  392. //
  393. void
  394. TBmpViewWindow::EvSize(UINT SizeType, TSize& Size)
  395. {
  396.   TWindow::EvSize(SizeType, Size);
  397.   if (SizeType != SIZEICONIC) {
  398.     AdjustScroller();
  399.     Invalidate(FALSE);
  400.   }
  401. }
  402.  
  403. //
  404. // Somebody changed the palette. If its not us, then we need to update.
  405. //
  406. void
  407. TBmpViewWindow::EvPaletteChanged(HWND hWndPalChg)
  408. {
  409.   if (hWndPalChg != HWindow)
  410.     UpdatePalette(TRUE);    // pass FALSE to UpdateColors() instead of repaint
  411. }
  412.  
  413. //
  414. // We need to re-realize the logical palette each time
  415. // we regain the input focus
  416. //
  417. BOOL
  418. TBmpViewWindow::EvQueryNewPalette()
  419. {
  420.   return UpdatePalette(TRUE);
  421. }
  422.  
  423. //
  424. // Use this message temporarily until the palette msgs get routed to us
  425. //
  426. void
  427. TBmpViewWindow::EvSetFocus(HWND)
  428. {
  429.   UpdatePalette(TRUE);
  430. }
  431.  
  432. void
  433. TBmpViewWindow::EvDrawClipboard()
  434. {
  435.   if (TClipboardViewer::DoDrawClipboard() == esComplete)
  436.     return;
  437.   if (AutoClipView)
  438.     CmPaste();
  439. }
  440.  
  441. void
  442. TBmpViewWindow::EvDestroy()
  443. {
  444.   if (TClipboardViewer::DoDestroy() == esComplete)
  445.     return;
  446.   TWindow::EvDestroy();
  447. }
  448.  
  449. BOOL
  450. TBmpViewWindow::UpdatePalette(BOOL alwaysRepaint)
  451. {
  452.   TRACEX(BmpView, 2, "Enter UpdatePalette()");
  453.   if (Palette) {
  454.     TClientDC clientDC(*this);
  455.     #if !defined(__WIN32__)
  456.       Palette->UnrealizeObject();
  457.     #endif
  458.     TRACEX(BmpView, 2, "UpdatePalette::Palette: " << hex << (UINT)(HPALETTE)*Palette);
  459.     clientDC.SelectObject(*Palette, FALSE);
  460.     if (clientDC.RealizePalette() > 0)
  461.       if (alwaysRepaint)
  462.         Invalidate(FALSE);
  463.       else
  464.         clientDC.UpdateColors();
  465.     TRACEX(BmpView, 2, "Leave UpdatePalette(TRUE)");
  466.     return TRUE;
  467.   }
  468.   TRACEX(BmpView, 2, "Leave UpdatePalette(FALSE)");
  469.   return FALSE;
  470. }
  471.  
  472. //
  473. // Responds to an incoming Paint message by redrawing the bitmap.
  474. // The Scroller's BeginView method, which sets the viewport origin
  475. // relative to the present scroll position, has been called by TWindow's
  476. // EvPaint
  477. // Note that we Invalidate() ourselves with false to avoid the background 
  478. // paint flicker. Thats why we use 
  479. //
  480. // The code can use either the Bitmap member with Stretch- and Bit- Blts,
  481. // or use the Dib member with Stretch- and Set- DIBits... 
  482. //
  483. void
  484. TBmpViewWindow::Paint(TDC& dc, BOOL, TRect&)
  485. {
  486.   TRACEX(BmpView, 2, "Enter Paint()");
  487.   TRect clientRect = GetClientRect();
  488.   TRACEX(BmpView, 2, "Paint::BkBrush: " << hex << (UINT)(HBRUSH)*BkgndBrush);
  489.   dc.SelectObject(*BkgndBrush);
  490.  
  491. #if defined(USE_DDB)
  492.   if (Bitmap) {
  493.     TMemoryDC memoryDC(dc);
  494.     TRACEX(BmpView, 2, "Paint::Bitmap: " << hex << (UINT)(HBITMAP)*Bitmap);
  495.     memoryDC.SelectObject(*Bitmap);
  496.     dc.SetStretchBltMode(COLORONCOLOR);
  497.     if (Palette) {
  498.       TRACEX(BmpView, 2, "Paint::Palette: " << hex << (UINT)(HPALETTE)*Palette);
  499.       dc.SelectObject(*Palette, FALSE);
  500.       dc.RealizePalette();
  501.       memoryDC.SelectObject(*Palette, FALSE);
  502.     }
  503.     if (Rop == SRCCOPY) {
  504.       if (Colors == 2) {
  505.         if (Palette) {
  506.           PALETTEENTRY pe;
  507.           Palette->GetPaletteEntry(0, pe);
  508.           dc.SetTextColor(TColor(pe));
  509.           Palette->GetPaletteEntry(1, pe);
  510.           dc.SetBkColor(TColor(pe));
  511.         } else {
  512.           dc.SetBkColor(TColor(0,0,0));
  513.           dc.SetTextColor(TColor(255,255,255));
  514.         }
  515.       }
  516.     }
  517. #else
  518.   if (Dib) {
  519. #endif
  520.  
  521.     TRect imageRect(0,0, PixelWidth, PixelHeight);
  522.     if (Parent->IsIconic()) {
  523.       #if defined(USE_DDB)
  524.         dc.StretchBlt(Parent->GetClientRect(), memoryDC, imageRect, Rop);
  525.       #else
  526.         dc.StretchDIBits(Parent->GetClientRect(), imageRect, *Dib, Rop);
  527.       #endif
  528.  
  529.     } else {
  530.       clientRect += TPoint((int)Scroller->XPos, (int)Scroller->YPos);
  531.       if (Fit) {
  532.         #if defined(USE_DDB)
  533.           dc.StretchBlt(clientRect, memoryDC, imageRect, Rop);
  534.         #else
  535.           dc.StretchDIBits(clientRect, imageRect, *Dib);
  536.         #endif
  537.  
  538.       } else {
  539.         #if defined(USE_DDB)
  540.           dc.BitBlt(imageRect, memoryDC, TPoint(0,0), Rop);
  541.         #else
  542.           dc.SetDIBitsToDevice(imageRect, TPoint(0,0), *Dib);
  543.         #endif
  544.             
  545.         // Clear borders here for no flicker
  546.         //
  547.         dc.PatBlt(TRect(TPoint(PixelWidth,0), clientRect.BottomRight()));
  548.         dc.PatBlt(TRect(TPoint(0,PixelHeight), clientRect.BottomRight()));
  549.       }
  550.     }
  551.   } else
  552.     dc.PatBlt(clientRect, PATCOPY);
  553.   TRACEX(BmpView, 2, "Leave Paint()" << endl);
  554. }
  555.  
  556. void
  557. TBmpViewWindow::SetupFromDib(TDib* dib)
  558. {
  559.   TRACEX(BmpView, 1, "Enter SetupFromDib()");
  560.   TRACEX(BmpView, 1, "SetupFromDib::Dib: " << hex << (UINT)(HANDLE)*dib);
  561.   delete Dib;
  562.   Dib = dib;
  563.   delete Palette;
  564.   Palette = 0;
  565.   try {
  566.     Palette = new TPalette(*dib);
  567.   }
  568.   catch (...) {
  569.     MessageBox("Dib has no color table, using default palette",
  570.                GetApplication()->GetName(), MB_OK);
  571.     Palette = new TPalette((HPALETTE)::GetStockObject(DEFAULT_PALETTE));
  572.   }
  573.  
  574.   TRACEX(BmpView, 1, "SetupFromDib::Palette: " << hex << (UINT)(HPALETTE)*Palette);
  575.  
  576. #if defined(USE_DDB)
  577.   delete Bitmap;
  578.   Bitmap = new TBitmap(*Dib, Palette);
  579.   TRACEX(BmpView, 1, "SetupFromDib::Bitmap: " << hex << (UINT)(HBITMAP)*Bitmap);
  580. #endif
  581.  
  582.   PixelWidth  = Dib->Width();
  583.   PixelHeight = Dib->Height();
  584.   UpdatePalette(TRUE);
  585.   AdjustScroller();
  586. #if defined(PAINT_ICON)
  587.   Parent->SetIcon(0, 0);  // enable to paint the icon from the bitmap
  588. #endif
  589.   TRACEX(BmpView, 1, "Leave SetupFromDib()");
  590. }
  591.  
  592. //
  593. // Test if the passed resource is a Windows 3.0 (or PM 1.x) DI bitmap
  594. // and if so read it.
  595. // Report errors if unable to do so. Adjust the Scroller to the new
  596. // bitmap dimensions.
  597. //
  598. BOOL
  599. TBmpViewWindow::LoadBitmapResource(WORD resId)
  600. {
  601.   TDib* newDib;
  602.   try {
  603.     newDib = new TDib(*GetModule(), resId);
  604.   }
  605.   catch (TGdiBase::TXGdi) {
  606.     MessageBox("Cannot access bitmap resource", GetApplication()->GetName(),
  607.                MB_OK);
  608.     return FALSE;
  609.   }
  610.   SetupFromDib(newDib);
  611.   return TRUE;
  612. }
  613.  
  614. //
  615. // Test if the passed file is a Windows 3.0 DI (or PM 1.x) bitmap
  616. // and if so read it.
  617. // Report errors if unable to do so. Adjust the Scroller to the new
  618. // bitmap dimensions.
  619. //
  620. BOOL
  621. TBmpViewWindow::LoadBitmapFile(const char* name)
  622. {
  623.   TDib* newDib;
  624.   try {
  625.     newDib = new TDib(name);
  626.   }
  627.   catch (TGdiBase::TXGdi) {
  628.     MessageBox("Cannot open bitmap file", GetApplication()->GetName(), MB_OK);
  629.     return FALSE;
  630.   }
  631.   SetupFromDib(newDib);
  632.   return TRUE;
  633. }
  634.  
  635.  
  636.  
  637. //----------------------------------------------------------------------------
  638.  
  639. class TBmpViewApp : public TApplication {
  640.   public:
  641.     TBmpViewApp(const char far* name) : TApplication(name) {}
  642.     void InitMainWindow() {
  643.       MainWindow = new TFrameWindow(0, Name, new TBmpViewWindow);
  644.       MainWindow->AssignMenu(Name);
  645.       MainWindow->SetIcon(this, Name);
  646.     }
  647. };
  648.  
  649. //----------------------------------------------------------------------------
  650.  
  651. int
  652. OwlMain(int /*argc*/, char* /*argv*/ [])
  653. {
  654.   return TBmpViewApp(AppName).Run();
  655. }
  656.