home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c083 / 20.ddi / BMPVIEW.PAK / BMPVIEW.CPP next >
Encoding:
C/C++ Source or Header  |  1993-12-02  |  16.7 KB  |  645 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 = 0;
  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. #endif
  246.   delete Dib;
  247.   Dib = newDib;
  248.  
  249.   delete Palette;
  250.   Palette = newPal ? newPal : new TPalette(*newDib);
  251.   Palette->GetObject(Colors);
  252.  
  253.   PixelWidth  = Dib->Width();
  254.   PixelHeight = Dib->Height();
  255.   AdjustScroller();
  256.   SetCaption("(Clipboard)");
  257.   
  258.   clipboard.CloseClipboard();
  259.  
  260. //  Parent->SetIcon(0, 0);  // we'll paint the icon from the bitmap
  261. }
  262.  
  263. void
  264. TBmpViewWindow::CePaste(TCommandEnabler& ce)
  265. {
  266.   TClipboard& clipboard = OpenClipboard();
  267.   ce.Enable(
  268.     clipboard && (
  269.       clipboard.IsClipboardFormatAvailable(CF_METAFILEPICT) ||
  270.       clipboard.IsClipboardFormatAvailable(CF_DIB) ||
  271.       clipboard.IsClipboardFormatAvailable(CF_BITMAP)
  272.     )
  273.   );
  274.   clipboard.CloseClipboard();
  275. }
  276.  
  277. //
  278. // If either of the "Read bitmap" menu items is selected, then we read
  279. // the bitmap resource with the ID of the menu item...
  280. //
  281. void
  282. TBmpViewWindow::CmRead1()
  283. {
  284.   if (LoadBitmapResource(CM_READ1))
  285.     SetCaption("(Bitmap resource 1)");
  286. }
  287.  
  288. void
  289. TBmpViewWindow::CmRead2()
  290. {
  291.   if (LoadBitmapResource(CM_READ2))
  292.     SetCaption("(Bitmap resource 2)");
  293. }
  294.  
  295. void
  296. TBmpViewWindow::CmReadBad()
  297. {
  298.   LoadBitmapFile("");   // force a failure for kicks
  299. }
  300.  
  301. //
  302. // Toggle Fit member variable & adjust scroller as needed
  303. //
  304. void
  305. TBmpViewWindow::CmFit()
  306. {
  307.   Fit = !Fit;
  308.   AdjustScroller();
  309. }
  310.  
  311. //
  312. // The fit menu item is checked if the Fit member is true
  313. //
  314. void
  315. TBmpViewWindow::CeFit(TCommandEnabler& ce)
  316. {
  317.   ce.SetCheck(Fit ? TCommandEnabler::Checked : TCommandEnabler::Unchecked);
  318. }
  319.  
  320. //
  321. // Toggle AutoAutoClipView member variable
  322. //
  323. void
  324. TBmpViewWindow::CmAutoClipView()
  325. {
  326.   AutoClipView = !AutoClipView;
  327. }
  328.  
  329. //
  330. // Check AutoClipView according to flag
  331. //
  332. void
  333. TBmpViewWindow::CeAutoClipView(TCommandEnabler& ce)
  334. {
  335.   ce.SetCheck(AutoClipView ? TCommandEnabler::Checked : TCommandEnabler::Unchecked);
  336. }
  337.  
  338. //
  339. // If the the "Open..." menu item is selected, then we prompt the user
  340. // for a new bitmap file.  If the user selects one and it is one that
  341. // we can read, we display it in the window and change the window's
  342. // caption to reflect the new bitmap file.
  343. //
  344. void
  345. TBmpViewWindow::CmFileOpen()
  346. {
  347.   static TOpenSaveDialog::TData data (
  348.     OFN_HIDEREADONLY|OFN_FILEMUSTEXIST|OFN_NOREADONLYRETURN,
  349.     "Bitmap Files (*.BMP)|*.bmp|",
  350.     0,
  351.     "",
  352.     "BMP"
  353.   );
  354.   if (TFileOpenDialog(this, data).Execute() == IDOK) {
  355.     char fileTitle[MAXPATH];
  356.     TOpenSaveDialog::GetFileTitle(data.FileName, fileTitle, MAXPATH);
  357.     LoadBitmapFile(fileTitle);
  358.     SetCaption(strlwr(fileTitle));
  359.   }
  360. }
  361.  
  362. //
  363. // Adjust the Scroller range so that the the origin is the
  364. // upper-most scrollable point and the corner is the
  365. // bottom-most.
  366. //
  367. void
  368. TBmpViewWindow::AdjustScroller() 
  369. {
  370.   TRect  clientRect = GetClientRect();
  371.  
  372.   // only show scrollbars when image is larger than
  373.   // the client area and we are not stretching to fit.
  374.   //
  375.   if (Fit)
  376.     Scroller->SetRange(0, 0);
  377.  
  378.   else {
  379.     TPoint Range(Max(PixelWidth-clientRect.Width(), 0),
  380.                  Max(PixelHeight-clientRect.Height(), 0));
  381.     Scroller->SetRange(Range.x, Range.y);
  382.   }
  383.   Scroller->ScrollTo(0, 0);
  384.   if (!GetUpdateRect(clientRect, FALSE))
  385.     Invalidate(FALSE);
  386. }
  387.  
  388. //
  389. // Reset scroller range.
  390. //
  391. void
  392. TBmpViewWindow::EvSize(UINT SizeType, TSize& Size)
  393. {
  394.   TWindow::EvSize(SizeType, Size);
  395.   if (SizeType != SIZEICONIC) {
  396.     AdjustScroller();
  397.     Invalidate(FALSE);
  398.   }
  399. }
  400.  
  401. //
  402. // Somebody changed the palette. If its not us, then we need to update.
  403. //
  404. void
  405. TBmpViewWindow::EvPaletteChanged(HWND hWndPalChg)
  406. {
  407.   if (hWndPalChg != HWindow)
  408.     UpdatePalette(TRUE);    // pass FALSE to UpdateColors() instead of repaint
  409. }
  410.  
  411. //
  412. // We need to re-realize the logical palette each time
  413. // we regain the input focus
  414. //
  415. BOOL
  416. TBmpViewWindow::EvQueryNewPalette()
  417. {
  418.   return UpdatePalette(TRUE);
  419. }
  420.  
  421. //
  422. // Use this message temporarily until the palette msgs get routed to us
  423. //
  424. void
  425. TBmpViewWindow::EvSetFocus(HWND)
  426. {
  427.   UpdatePalette(TRUE);
  428. }
  429.  
  430. void
  431. TBmpViewWindow::EvDrawClipboard()
  432. {
  433.   if (TClipboardViewer::DoDrawClipboard() == esComplete)
  434.     return;
  435.   if (AutoClipView)
  436.     CmPaste();
  437. }
  438.  
  439. void
  440. TBmpViewWindow::EvDestroy()
  441. {
  442.   if (TClipboardViewer::DoDestroy() == esComplete)
  443.     return;
  444.   TWindow::EvDestroy();
  445. }
  446.  
  447. BOOL
  448. TBmpViewWindow::UpdatePalette(BOOL alwaysRepaint)
  449. {
  450.   TRACEX(BmpView, 2, "Enter UpdatePalette()");
  451.   if (Palette) {
  452.     TClientDC clientDC(*this);
  453.     #if !defined(__WIN32__)
  454.       Palette->UnrealizeObject();
  455.     #endif
  456.     TRACEX(BmpView, 2, "UpdatePalette::Palette: " << hex << (UINT)(HPALETTE)*Palette);
  457.     clientDC.SelectObject(*Palette, FALSE);
  458.     if (clientDC.RealizePalette() > 0)
  459.       if (alwaysRepaint)
  460.         Invalidate(FALSE);
  461.       else
  462.         clientDC.UpdateColors();
  463.     TRACEX(BmpView, 2, "Leave UpdatePalette(TRUE)");
  464.     return TRUE;
  465.   }
  466.   TRACEX(BmpView, 2, "Leave UpdatePalette(FALSE)");
  467.   return FALSE;
  468. }
  469.  
  470. //
  471. // Responds to an incoming Paint message by redrawing the bitmap.
  472. // The Scroller's BeginView method, which sets the viewport origin
  473. // relative to the present scroll position, has been called by TWindow's
  474. // EvPaint
  475. // Note that we Invalidate() ourselves with false to avoid the background 
  476. // paint flicker. Thats why we use 
  477. //
  478. // The code can use either the Bitmap member with Stretch- and Bit- Blts,
  479. // or use the Dib member with Stretch- and Set- DIBits... 
  480. //
  481. void
  482. TBmpViewWindow::Paint(TDC& dc, BOOL, TRect&)
  483. {
  484.   TRACEX(BmpView, 2, "Enter Paint()");
  485.   TRect clientRect = GetClientRect();
  486.   TRACEX(BmpView, 2, "Paint::BkBrush: " << hex << (UINT)(HBRUSH)*BkgndBrush);
  487.   dc.SelectObject(*BkgndBrush);
  488.  
  489. #if defined(USE_DDB)
  490.   if (Bitmap) {
  491.     TMemoryDC memoryDC(dc);
  492.     TRACEX(BmpView, 2, "Paint::Bitmap: " << hex << (UINT)(HBITMAP)*Bitmap);
  493.     memoryDC.SelectObject(*Bitmap);
  494.     dc.SetStretchBltMode(COLORONCOLOR);
  495.     if (Palette) {
  496.       TRACEX(BmpView, 2, "Paint::Palette: " << hex << (UINT)(HPALETTE)*Palette);
  497.       dc.SelectObject(*Palette, FALSE);
  498.       dc.RealizePalette();
  499.       memoryDC.SelectObject(*Palette, FALSE);
  500.     }
  501.     if (Rop == SRCCOPY) {
  502.       if (Colors == 2) {
  503.         if (Palette) {
  504.           PALETTEENTRY pe;
  505.           Palette->GetPaletteEntry(0, pe);
  506.           dc.SetTextColor(TColor(pe));
  507.           Palette->GetPaletteEntry(1, pe);
  508.           dc.SetBkColor(TColor(pe));
  509.         } else {
  510.           dc.SetBkColor(TColor(0,0,0));
  511.           dc.SetTextColor(TColor(255,255,255));
  512.         }
  513.       }
  514.     }
  515. #else
  516.   if (Dib) {
  517. #endif
  518.  
  519.     TRect imageRect(0,0, PixelWidth, PixelHeight);
  520.     if (Parent->IsIconic()) {
  521.       #if defined(USE_DDB)
  522.         dc.StretchBlt(Parent->GetClientRect(), memoryDC, imageRect, Rop);
  523.       #else
  524.         dc.StretchDIBits(Parent->GetClientRect(), imageRect, *Dib, Rop);
  525.       #endif
  526.  
  527.     } else {
  528.       clientRect += TPoint((int)Scroller->XPos, (int)Scroller->YPos);
  529.       if (Fit) {
  530.         #if defined(USE_DDB)
  531.           dc.StretchBlt(clientRect, memoryDC, imageRect, Rop);
  532.         #else
  533.           dc.StretchDIBits(clientRect, imageRect, *Dib);
  534.         #endif
  535.  
  536.       } else {
  537.         #if defined(USE_DDB)
  538.           dc.BitBlt(imageRect, memoryDC, TPoint(0,0), Rop);
  539.         #else
  540.           dc.SetDIBitsToDevice(imageRect, TPoint(0,0), *Dib);
  541.         #endif
  542.             
  543.         // Clear borders here for no flicker
  544.         //
  545.         dc.PatBlt(TRect(TPoint(PixelWidth,0), clientRect.BottomRight()));
  546.         dc.PatBlt(TRect(TPoint(0,PixelHeight), clientRect.BottomRight()));
  547.       }
  548.     }
  549.   } else
  550.     dc.PatBlt(clientRect, PATCOPY);
  551.   TRACEX(BmpView, 2, "Leave Paint()" << endl);
  552. }
  553.  
  554. void
  555. TBmpViewWindow::SetupFromDib(TDib* dib)
  556. {
  557.   TRACEX(BmpView, 1, "Enter SetupFromDib()");
  558.   TRACEX(BmpView, 1, "SetupFromDib::Dib: " << hex << (UINT)(HANDLE)*dib);
  559.   delete Dib;
  560.   Dib = dib;
  561.   delete Palette;
  562.   Palette = new TPalette(*dib);
  563.   TRACEX(BmpView, 1, "SetupFromDib::Palette: " << hex << (UINT)(HPALETTE)*Palette);
  564.  
  565. #if defined(USE_DDB)
  566.   delete Bitmap;
  567.   Bitmap = new TBitmap(*Dib, Palette);
  568.   TRACEX(BmpView, 1, "SetupFromDib::Bitmap: " << hex << (UINT)(HBITMAP)*Bitmap);
  569. #endif
  570.  
  571.   PixelWidth  = Dib->Width();
  572.   PixelHeight = Dib->Height();
  573.   UpdatePalette(TRUE);
  574.   AdjustScroller();
  575. #if defined(PAINT_ICON)
  576.   Parent->SetIcon(0, 0);  // enable to paint the icon from the bitmap
  577. #endif
  578.   TRACEX(BmpView, 1, "Leave SetupFromDib()");
  579. }
  580.  
  581. //
  582. // Test if the passed resource is a Windows 3.0 (or PM 1.x) DI bitmap
  583. // and if so read it.
  584. // Report errors if unable to do so. Adjust the Scroller to the new
  585. // bitmap dimensions.
  586. //
  587. BOOL
  588. TBmpViewWindow::LoadBitmapResource(WORD resId)
  589. {
  590.   TDib* newDib;
  591.   try {
  592.     newDib = new TDib(*GetModule(), resId);
  593.   }
  594.   catch (TGdiBase::TXGdi) {
  595.     MessageBox("Cannot access bitmap resource", GetApplication()->GetName(),
  596.                MB_OK);
  597.     return FALSE;
  598.   }
  599.   SetupFromDib(newDib);
  600.   return TRUE;
  601. }
  602.  
  603. //
  604. // Test if the passed file is a Windows 3.0 DI (or PM 1.x) bitmap
  605. // and if so read it.
  606. // Report errors if unable to do so. Adjust the Scroller to the new
  607. // bitmap dimensions.
  608. //
  609. BOOL
  610. TBmpViewWindow::LoadBitmapFile(const char* name)
  611. {
  612.   TDib* newDib = 0;
  613.   try {
  614.     newDib = new TDib(name);
  615.   }
  616.   catch (TGdiBase::TXGdi) {
  617.     MessageBox("Cannot open bitmap file", GetApplication()->GetName(), MB_OK);
  618.     return FALSE;
  619.   }
  620.   SetupFromDib(newDib);
  621.   return TRUE;
  622. }
  623.  
  624.  
  625.  
  626. //----------------------------------------------------------------------------
  627.  
  628. class TBmpViewApp : public TApplication {
  629.   public:
  630.     TBmpViewApp(const char far* name) : TApplication(name) {}
  631.     void InitMainWindow() {
  632.       MainWindow = new TFrameWindow(0, Name, new TBmpViewWindow);
  633.       MainWindow->AssignMenu(Name);
  634.       MainWindow->SetIcon(this, Name);
  635.     }
  636. };
  637.  
  638. //----------------------------------------------------------------------------
  639.  
  640. int
  641. OwlMain(int /*argc*/, char* /*argv*/ [])
  642. {
  643.   return TBmpViewApp(AppName).Run();
  644. }
  645.