home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c082_144 / 6.ddi / OWLDEMOS.ZIP / BSCRLAPP.CPP next >
Encoding:
C/C++ Source or Header  |  1992-06-10  |  9.4 KB  |  325 lines

  1. // ObjectWindows - (C) Copyright 1992 by Borland International
  2.  
  3. #include <owl.h>
  4. #include <filedial.h>
  5. #include <string.h>
  6. #include <dir.h>
  7. #include <dos.h>
  8.  
  9. #define BSA_NAME "BitmapScroll"
  10.  
  11.  
  12. /* TBitScrollApp, a TApplication descendant */
  13.  
  14. class TBitScrollApp : public TApplication {
  15. public:
  16.     TBitScrollApp(LPSTR AName, HINSTANCE hInstance,
  17.           HINSTANCE hPrevInstance, LPSTR lpCmd,
  18.           int nCmdShow)
  19.             : TApplication(AName, hInstance,
  20.                    hPrevInstance, lpCmd, nCmdShow) {};
  21.     virtual void InitMainWindow();
  22. };
  23.  
  24. /* TBMPFileDialog, a TFileDialog descendant which uses .bmp as its
  25.     default extension. */
  26. class TBMPFileDialog : public TFileDialog {
  27. public:
  28.     TBMPFileDialog(PTWindowsObject AParent, int ResourceId,
  29.                    LPSTR AFilePath, PTModule AModule = NULL)
  30.      : TFileDialog(AParent, ResourceId, AFilePath, AModule)
  31.        { strcpy(Extension, ".bmp"); }
  32. };
  33.  
  34. /* TBitScrollWindow, a TWindow descendant */
  35.  
  36. class TBitScrollWindow : public TWindow {
  37. public:
  38.     char FileName[MAXPATH];
  39.     HBITMAP BitmapHandle;
  40.     WORD PixelHeight , PixelWidth;
  41.     long Mode;
  42.  
  43.     TBitScrollWindow(LPSTR);
  44.     virtual ~TBitScrollWindow();
  45.     virtual LPSTR GetClassName();
  46.     virtual void GetWindowClass(WNDCLASS&);
  47.     virtual void Paint(HDC, PAINTSTRUCT&);
  48.     virtual void CMFileOpen(TMessage&) = [CM_FIRST + CM_FILEOPEN];
  49.     virtual void WMSize(TMessage&) = [WM_FIRST + WM_SIZE];
  50.     void AdjustScroller();
  51.     BOOL LoadBitmapFile(LPSTR);
  52.     BOOL OpenDIB(int TheFile);
  53.     void GetBitmapData(int TheFile, HANDLE, long);
  54. };
  55.  
  56. /* __ahIncr, ordinal 114, is a 'magic' function. Defining this
  57.   function causes Windows to patch the value into the passed
  58.   reference.  This makes it a type of global variable. To use
  59.   the value of AHIncr, use FP_OFF(AHIncr). */
  60.  
  61. extern "C" {
  62. void FAR PASCAL  __ahIncr();
  63. }
  64.  
  65. /* Construct the TBitScrollApp's MainWindow of type TBitScrollWindow */
  66.  
  67. void TBitScrollApp::InitMainWindow()
  68. {
  69.   MainWindow = new TBitScrollWindow(BSA_NAME);
  70. }
  71.  
  72. /* Constructor for a TBitScrollWindow, sets scroll styles and constructs
  73.   the Scroller object.  Also sets the Mode based on whether the display
  74.   is monochrome (two-color) or polychrome. */
  75.  
  76. TBitScrollWindow::TBitScrollWindow(LPSTR ATitle)
  77.                  :TWindow(NULL, ATitle)
  78. {
  79.   HDC DCHandle;
  80.  
  81.   Attr.Style |= WS_VSCROLL | WS_HSCROLL;
  82.   AssignMenu(BSA_NAME);
  83.   BitmapHandle = 0;
  84.   Scroller = new TScroller(this, 1, 1, 200, 200);
  85.   DCHandle = CreateDC("Display", NULL, NULL, NULL);
  86.   if ( GetDeviceCaps(DCHandle, NUMCOLORS) < 3 )
  87.     Mode = NOTSRCCOPY;
  88.   else
  89.     Mode = SRCCOPY;
  90.   DeleteDC(DCHandle);
  91. }
  92.  
  93. /* Change the class name to the application name. */
  94.  
  95. LPSTR TBitScrollWindow::GetClassName()
  96. {
  97.   return BSA_NAME;
  98. }
  99.  
  100. /* Allow the iconic picture to be drawn from the client area. */
  101.  
  102. void TBitScrollWindow::GetWindowClass(WNDCLASS& WndClass)
  103. {
  104.   TWindow::GetWindowClass(WndClass);
  105.   WndClass.hIcon = 0; /* Client area will be painted by the app. */
  106. }
  107.  
  108. TBitScrollWindow::~TBitScrollWindow()
  109. {
  110.   if ( BitmapHandle )
  111.     DeleteObject(BitmapHandle);
  112. }
  113.  
  114. /* If the the "Open..." menu item is selected, then we prompt the user
  115.    for a new bitmap file.  If the user selects one and it is one that
  116.    we can read, we display it in the window and change the window's
  117.    caption to reflect the new bitmap file. */
  118.  
  119. void TBitScrollWindow::CMFileOpen(TMessage&)
  120. {
  121.   char TempName [MAXPATH];
  122.   char CaptionBuffer [MAXPATH+ 12 /*BSA_NAME*/ + 2 /*" "*/ + 1 /*'\0'*/ ];
  123.  
  124.   if (GetApplication()->ExecDialog( new TBMPFileDialog
  125.     (this, SD_FILEOPEN, strcpy(TempName, "*.bmp"))) == IDOK )
  126.     if ( LoadBitmapFile(TempName) )
  127.     {
  128.       strcpy(FileName, TempName);
  129.       strcpy(CaptionBuffer, BSA_NAME);
  130.       strcat(CaptionBuffer, ": ");
  131.       strcat(CaptionBuffer, strlwr(FileName));
  132.       SetWindowText(HWindow, CaptionBuffer);
  133.     }
  134. }
  135.  
  136. /* Adjust the Scroller range so that the the origin is the
  137.   upper-most scrollable point and the corner is the
  138.   bottom-most. */
  139.  
  140. void TBitScrollWindow::AdjustScroller()
  141. {
  142.   RECT ClientRect;
  143.  
  144.   GetClientRect(HWindow, &ClientRect);
  145.   Scroller->SetRange(PixelWidth - (ClientRect.right - ClientRect.left),
  146.       PixelHeight - (ClientRect.bottom - ClientRect.top));
  147.   Scroller->ScrollTo(0, 0);
  148.   InvalidateRect(HWindow, NULL, TRUE);
  149. }
  150.  
  151. /* Reset scroller range. */
  152.  
  153. void TBitScrollWindow::WMSize(TMessage& Msg)
  154. {
  155.   TWindow::WMSize(Msg);
  156.   if ( (Msg.WParam != SIZEICONIC) )
  157.     AdjustScroller();
  158. }
  159.  
  160. /* Copys the bitmap bit data from the file into memory. Since
  161.   copying cannot cross a segment (64K) boundary, we are forced
  162.   to do segment arithmetic to compute the next segment.  Created
  163.   a LongType type to simplify the process. */
  164.  
  165. void TBitScrollWindow::GetBitmapData(int TheFile, HANDLE BitsHandle,long BitsByteSize)
  166. {
  167.   long Count;
  168.   long Start, ToAddr, Bits;
  169.  
  170.   Start = 0L;
  171.   Bits = (long)GlobalLock(BitsHandle);
  172.   Count = BitsByteSize - Start;
  173.   while ( Count > 0 )
  174.   {
  175.     ToAddr = MAKELONG(LOWORD(Start),
  176.                       HIWORD(Bits) + (HIWORD(Start) * FP_OFF(__ahIncr)));
  177.     if ( Count > 0x4000 )
  178.       Count = 0x4000;
  179.     _lread(TheFile, (LPSTR)ToAddr, (WORD)Count);
  180.     Start = Start + Count;
  181.     Count = BitsByteSize - Start;
  182.   }
  183.   GlobalUnlock(BitsHandle);
  184. }
  185.  
  186. /* Attempt to open a Windows 3.0 device independent bitmap. */
  187.  
  188. BOOL TBitScrollWindow::OpenDIB(int TheFile)
  189. {
  190.     WORD bitCount;
  191.     WORD size;
  192.     long longWidth;
  193.     HDC DCHandle;
  194.     LPSTR BitsPtr;
  195.     BITMAPINFO *BitmapInfo;
  196.     HBITMAP BitsHandle , NewBitmapHandle;
  197.     DWORD NewPixelWidth , NewPixelHeight;
  198.     BOOL retval;
  199.  
  200.   retval= TRUE;
  201.   _llseek(TheFile, 28, 0);
  202.   _lread(TheFile, (LPSTR)&bitCount, sizeof(bitCount));
  203.   if ( bitCount <= 8 )
  204.   {
  205.     size = sizeof(BITMAPINFOHEADER) + ((1 << bitCount) * sizeof(RGBQUAD));
  206.     BitmapInfo = (BITMAPINFO *)new char[size];
  207.     _llseek(TheFile, sizeof(BITMAPFILEHEADER), 0);
  208.     _lread(TheFile, (LPSTR)BitmapInfo, size);
  209.     NewPixelWidth = BitmapInfo->bmiHeader.biWidth;
  210.     NewPixelHeight = BitmapInfo->bmiHeader.biHeight;
  211.     longWidth = (((NewPixelWidth * bitCount) + 31)/32) * 4;
  212.     BitmapInfo->bmiHeader.biSizeImage = longWidth * NewPixelHeight;
  213.     GlobalCompact(-1);
  214.     BitsHandle = (HBITMAP)GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT,
  215.       BitmapInfo->bmiHeader.biSizeImage);
  216.     GetBitmapData(TheFile, BitsHandle, BitmapInfo->bmiHeader.biSizeImage);
  217.     DCHandle = CreateDC("Display", NULL, NULL, NULL);
  218.     BitsPtr = (LPSTR)GlobalLock((HGLOBAL)BitsHandle);
  219.     NewBitmapHandle =
  220.       CreateDIBitmap(DCHandle, &(BitmapInfo->bmiHeader), CBM_INIT, BitsPtr,
  221.       BitmapInfo, 0);
  222.     DeleteDC(DCHandle);
  223.     GlobalUnlock(BitsHandle);
  224.     GlobalFree(BitsHandle);
  225.     delete BitmapInfo;
  226.     if ( NewBitmapHandle )
  227.     {
  228.       if ( BitmapHandle )
  229.         DeleteObject(BitmapHandle);
  230.       BitmapHandle = NewBitmapHandle;
  231.       PixelWidth = (WORD)NewPixelWidth;
  232.       PixelHeight = (WORD)NewPixelHeight;
  233.     }
  234.     else
  235.       retval = FALSE;
  236.   }
  237.   else
  238.     retval = FALSE;
  239. return retval;
  240. }
  241.  
  242. /* Test if the passed file is a Windows 3.0 DI bitmap and if so read it.
  243.   Report errors if unable to do so. Adjust the Scroller to the new
  244.   bitmap dimensions. */
  245.  
  246. BOOL TBitScrollWindow::LoadBitmapFile(LPSTR Name)
  247. {
  248.     int TheFile;
  249.     long TestWin30Bitmap;
  250.     char ErrorMsg[50] = "";
  251.     BOOL retval;
  252.  
  253.   TheFile = _lopen(Name, OF_READ);
  254.   if ( TheFile != -1 )
  255.   {
  256.     _llseek(TheFile, 14, 0);
  257.     _lread(TheFile, (LPSTR)&TestWin30Bitmap, sizeof(TestWin30Bitmap));
  258.     if ( TestWin30Bitmap == 40 )
  259.       if ( OpenDIB(TheFile) )
  260.       AdjustScroller();
  261.       else
  262.       strcpy(ErrorMsg,
  263.                     "Unable to create Windows 3.0 bitmap from file");
  264.     else
  265.       strcpy(ErrorMsg, "Not a Windows 3.0 bitmap file");
  266.     _lclose(TheFile);
  267.   }
  268.   else
  269.     strcpy(ErrorMsg, "Cannot open bitmap file");
  270.   if ( ErrorMsg[0] == '\0' )
  271.     retval= TRUE;
  272.   else
  273.   {
  274.     MessageBox(HWindow, ErrorMsg, BSA_NAME, MB_OK);
  275.     retval= FALSE;
  276.   }
  277.   return retval;
  278. }
  279.  
  280. /* Responds to an incoming "paint" message by redrawing the bitmap.
  281.    (The Scroller's BeginView method, which sets the viewport origin
  282.    relative to the present scroll position, has already been called.)  */
  283.  
  284. void TBitScrollWindow::Paint(HDC, PAINTSTRUCT& PaintInfo)
  285. {
  286.   HDC MemoryDC;
  287.   HANDLE OldBitmapHandle;
  288.   RECT ClientRect;
  289.  
  290.   if ( BitmapHandle )
  291.   {
  292.     MemoryDC = CreateCompatibleDC(PaintInfo.hdc);
  293.     OldBitmapHandle = SelectObject(MemoryDC, BitmapHandle);
  294.     if ( Mode == SRCCOPY )
  295.     {
  296.       SetBkColor(PaintInfo.hdc, GetNearestColor(PaintInfo.hdc, 0x800000L));
  297.       SetTextColor(PaintInfo.hdc, 0xFFFFFFL);
  298.     }
  299.     if ( IsIconic(HWindow) )
  300.     {
  301.       GetClientRect(HWindow, &ClientRect);
  302.       StretchBlt(PaintInfo.hdc, 0, 0,
  303.                  ClientRect.right - ClientRect.left,
  304.                  ClientRect.bottom - ClientRect.top,
  305.                  MemoryDC, 0, 0, PixelWidth, PixelHeight, Mode);
  306.     }
  307.     else
  308.       BitBlt(PaintInfo.hdc, 0, 0, PixelWidth, PixelHeight,
  309.              MemoryDC, 0, 0, Mode);
  310.     SelectObject(MemoryDC, OldBitmapHandle);
  311.     DeleteDC(MemoryDC);
  312.   }
  313. }
  314.  
  315.  
  316. /* Run the BitScrollApp */
  317. int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
  318.            LPSTR lpCmd, int nCmdShow)
  319. {
  320.   TBitScrollApp ScrollApp(BSA_NAME, hInstance, hPrevInstance,
  321.         lpCmd, nCmdShow);
  322.   ScrollApp.Run();
  323.   return ScrollApp.Status;
  324. }
  325.