home *** CD-ROM | disk | FTP | other *** search
- // ObjectWindows - (C) Copyright 1992 by Borland International
-
- #include <owl.h>
- #include <filedial.h>
- #include <string.h>
- #include <dir.h>
- #include <dos.h>
-
- #define BSA_NAME "BitmapScroll"
-
-
- /* TBitScrollApp, a TApplication descendant */
-
- class TBitScrollApp : public TApplication {
- public:
- TBitScrollApp(LPSTR AName, HINSTANCE hInstance,
- HINSTANCE hPrevInstance, LPSTR lpCmd,
- int nCmdShow)
- : TApplication(AName, hInstance,
- hPrevInstance, lpCmd, nCmdShow) {};
- virtual void InitMainWindow();
- };
-
- /* TBMPFileDialog, a TFileDialog descendant which uses .bmp as its
- default extension. */
- class TBMPFileDialog : public TFileDialog {
- public:
- TBMPFileDialog(PTWindowsObject AParent, int ResourceId,
- LPSTR AFilePath, PTModule AModule = NULL)
- : TFileDialog(AParent, ResourceId, AFilePath, AModule)
- { strcpy(Extension, ".bmp"); }
- };
-
- /* TBitScrollWindow, a TWindow descendant */
-
- class TBitScrollWindow : public TWindow {
- public:
- char FileName[MAXPATH];
- HBITMAP BitmapHandle;
- WORD PixelHeight , PixelWidth;
- long Mode;
-
- TBitScrollWindow(LPSTR);
- virtual ~TBitScrollWindow();
- virtual LPSTR GetClassName();
- virtual void GetWindowClass(WNDCLASS&);
- virtual void Paint(HDC, PAINTSTRUCT&);
- virtual void CMFileOpen(TMessage&) = [CM_FIRST + CM_FILEOPEN];
- virtual void WMSize(TMessage&) = [WM_FIRST + WM_SIZE];
- void AdjustScroller();
- BOOL LoadBitmapFile(LPSTR);
- BOOL OpenDIB(int TheFile);
- void GetBitmapData(int TheFile, HANDLE, long);
- };
-
- /* __ahIncr, ordinal 114, is a 'magic' function. Defining this
- function causes Windows to patch the value into the passed
- reference. This makes it a type of global variable. To use
- the value of AHIncr, use FP_OFF(AHIncr). */
-
- extern "C" {
- void FAR PASCAL __ahIncr();
- }
-
- /* Construct the TBitScrollApp's MainWindow of type TBitScrollWindow */
-
- void TBitScrollApp::InitMainWindow()
- {
- MainWindow = new TBitScrollWindow(BSA_NAME);
- }
-
- /* Constructor for a TBitScrollWindow, sets scroll styles and constructs
- the Scroller object. Also sets the Mode based on whether the display
- is monochrome (two-color) or polychrome. */
-
- TBitScrollWindow::TBitScrollWindow(LPSTR ATitle)
- :TWindow(NULL, ATitle)
- {
- HDC DCHandle;
-
- Attr.Style |= WS_VSCROLL | WS_HSCROLL;
- AssignMenu(BSA_NAME);
- BitmapHandle = 0;
- Scroller = new TScroller(this, 1, 1, 200, 200);
- DCHandle = CreateDC("Display", NULL, NULL, NULL);
- if ( GetDeviceCaps(DCHandle, NUMCOLORS) < 3 )
- Mode = NOTSRCCOPY;
- else
- Mode = SRCCOPY;
- DeleteDC(DCHandle);
- }
-
- /* Change the class name to the application name. */
-
- LPSTR TBitScrollWindow::GetClassName()
- {
- return BSA_NAME;
- }
-
- /* Allow the iconic picture to be drawn from the client area. */
-
- void TBitScrollWindow::GetWindowClass(WNDCLASS& WndClass)
- {
- TWindow::GetWindowClass(WndClass);
- WndClass.hIcon = 0; /* Client area will be painted by the app. */
- }
-
- TBitScrollWindow::~TBitScrollWindow()
- {
- if ( BitmapHandle )
- DeleteObject(BitmapHandle);
- }
-
- /* If the the "Open..." menu item is selected, then we prompt the user
- for a new bitmap file. If the user selects one and it is one that
- we can read, we display it in the window and change the window's
- caption to reflect the new bitmap file. */
-
- void TBitScrollWindow::CMFileOpen(TMessage&)
- {
- char TempName [MAXPATH];
- char CaptionBuffer [MAXPATH+ 12 /*BSA_NAME*/ + 2 /*" "*/ + 1 /*'\0'*/ ];
-
- if (GetApplication()->ExecDialog( new TBMPFileDialog
- (this, SD_FILEOPEN, strcpy(TempName, "*.bmp"))) == IDOK )
- if ( LoadBitmapFile(TempName) )
- {
- strcpy(FileName, TempName);
- strcpy(CaptionBuffer, BSA_NAME);
- strcat(CaptionBuffer, ": ");
- strcat(CaptionBuffer, strlwr(FileName));
- SetWindowText(HWindow, CaptionBuffer);
- }
- }
-
- /* Adjust the Scroller range so that the the origin is the
- upper-most scrollable point and the corner is the
- bottom-most. */
-
- void TBitScrollWindow::AdjustScroller()
- {
- RECT ClientRect;
-
- GetClientRect(HWindow, &ClientRect);
- Scroller->SetRange(PixelWidth - (ClientRect.right - ClientRect.left),
- PixelHeight - (ClientRect.bottom - ClientRect.top));
- Scroller->ScrollTo(0, 0);
- InvalidateRect(HWindow, NULL, TRUE);
- }
-
- /* Reset scroller range. */
-
- void TBitScrollWindow::WMSize(TMessage& Msg)
- {
- TWindow::WMSize(Msg);
- if ( (Msg.WParam != SIZEICONIC) )
- AdjustScroller();
- }
-
- /* Copys the bitmap bit data from the file into memory. Since
- copying cannot cross a segment (64K) boundary, we are forced
- to do segment arithmetic to compute the next segment. Created
- a LongType type to simplify the process. */
-
- void TBitScrollWindow::GetBitmapData(int TheFile, HANDLE BitsHandle,long BitsByteSize)
- {
- long Count;
- long Start, ToAddr, Bits;
-
- Start = 0L;
- Bits = (long)GlobalLock(BitsHandle);
- Count = BitsByteSize - Start;
- while ( Count > 0 )
- {
- ToAddr = MAKELONG(LOWORD(Start),
- HIWORD(Bits) + (HIWORD(Start) * FP_OFF(__ahIncr)));
- if ( Count > 0x4000 )
- Count = 0x4000;
- _lread(TheFile, (LPSTR)ToAddr, (WORD)Count);
- Start = Start + Count;
- Count = BitsByteSize - Start;
- }
- GlobalUnlock(BitsHandle);
- }
-
- /* Attempt to open a Windows 3.0 device independent bitmap. */
-
- BOOL TBitScrollWindow::OpenDIB(int TheFile)
- {
- WORD bitCount;
- WORD size;
- long longWidth;
- HDC DCHandle;
- LPSTR BitsPtr;
- BITMAPINFO *BitmapInfo;
- HBITMAP BitsHandle , NewBitmapHandle;
- DWORD NewPixelWidth , NewPixelHeight;
- BOOL retval;
-
- retval= TRUE;
- _llseek(TheFile, 28, 0);
- _lread(TheFile, (LPSTR)&bitCount, sizeof(bitCount));
- if ( bitCount <= 8 )
- {
- size = sizeof(BITMAPINFOHEADER) + ((1 << bitCount) * sizeof(RGBQUAD));
- BitmapInfo = (BITMAPINFO *)new char[size];
- _llseek(TheFile, sizeof(BITMAPFILEHEADER), 0);
- _lread(TheFile, (LPSTR)BitmapInfo, size);
- NewPixelWidth = BitmapInfo->bmiHeader.biWidth;
- NewPixelHeight = BitmapInfo->bmiHeader.biHeight;
- longWidth = (((NewPixelWidth * bitCount) + 31)/32) * 4;
- BitmapInfo->bmiHeader.biSizeImage = longWidth * NewPixelHeight;
- GlobalCompact(-1);
- BitsHandle = (HBITMAP)GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT,
- BitmapInfo->bmiHeader.biSizeImage);
- GetBitmapData(TheFile, BitsHandle, BitmapInfo->bmiHeader.biSizeImage);
- DCHandle = CreateDC("Display", NULL, NULL, NULL);
- BitsPtr = (LPSTR)GlobalLock((HGLOBAL)BitsHandle);
- NewBitmapHandle =
- CreateDIBitmap(DCHandle, &(BitmapInfo->bmiHeader), CBM_INIT, BitsPtr,
- BitmapInfo, 0);
- DeleteDC(DCHandle);
- GlobalUnlock(BitsHandle);
- GlobalFree(BitsHandle);
- delete BitmapInfo;
- if ( NewBitmapHandle )
- {
- if ( BitmapHandle )
- DeleteObject(BitmapHandle);
- BitmapHandle = NewBitmapHandle;
- PixelWidth = (WORD)NewPixelWidth;
- PixelHeight = (WORD)NewPixelHeight;
- }
- else
- retval = FALSE;
- }
- else
- retval = FALSE;
- return retval;
- }
-
- /* Test if the passed file is a Windows 3.0 DI bitmap and if so read it.
- Report errors if unable to do so. Adjust the Scroller to the new
- bitmap dimensions. */
-
- BOOL TBitScrollWindow::LoadBitmapFile(LPSTR Name)
- {
- int TheFile;
- long TestWin30Bitmap;
- char ErrorMsg[50] = "";
- BOOL retval;
-
- TheFile = _lopen(Name, OF_READ);
- if ( TheFile != -1 )
- {
- _llseek(TheFile, 14, 0);
- _lread(TheFile, (LPSTR)&TestWin30Bitmap, sizeof(TestWin30Bitmap));
- if ( TestWin30Bitmap == 40 )
- if ( OpenDIB(TheFile) )
- AdjustScroller();
- else
- strcpy(ErrorMsg,
- "Unable to create Windows 3.0 bitmap from file");
- else
- strcpy(ErrorMsg, "Not a Windows 3.0 bitmap file");
- _lclose(TheFile);
- }
- else
- strcpy(ErrorMsg, "Cannot open bitmap file");
- if ( ErrorMsg[0] == '\0' )
- retval= TRUE;
- else
- {
- MessageBox(HWindow, ErrorMsg, BSA_NAME, MB_OK);
- retval= FALSE;
- }
- return retval;
- }
-
- /* Responds to an incoming "paint" message by redrawing the bitmap.
- (The Scroller's BeginView method, which sets the viewport origin
- relative to the present scroll position, has already been called.) */
-
- void TBitScrollWindow::Paint(HDC, PAINTSTRUCT& PaintInfo)
- {
- HDC MemoryDC;
- HANDLE OldBitmapHandle;
- RECT ClientRect;
-
- if ( BitmapHandle )
- {
- MemoryDC = CreateCompatibleDC(PaintInfo.hdc);
- OldBitmapHandle = SelectObject(MemoryDC, BitmapHandle);
- if ( Mode == SRCCOPY )
- {
- SetBkColor(PaintInfo.hdc, GetNearestColor(PaintInfo.hdc, 0x800000L));
- SetTextColor(PaintInfo.hdc, 0xFFFFFFL);
- }
- if ( IsIconic(HWindow) )
- {
- GetClientRect(HWindow, &ClientRect);
- StretchBlt(PaintInfo.hdc, 0, 0,
- ClientRect.right - ClientRect.left,
- ClientRect.bottom - ClientRect.top,
- MemoryDC, 0, 0, PixelWidth, PixelHeight, Mode);
- }
- else
- BitBlt(PaintInfo.hdc, 0, 0, PixelWidth, PixelHeight,
- MemoryDC, 0, 0, Mode);
- SelectObject(MemoryDC, OldBitmapHandle);
- DeleteDC(MemoryDC);
- }
- }
-
-
- /* Run the BitScrollApp */
- int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
- LPSTR lpCmd, int nCmdShow)
- {
- TBitScrollApp ScrollApp(BSA_NAME, hInstance, hPrevInstance,
- lpCmd, nCmdShow);
- ScrollApp.Run();
- return ScrollApp.Status;
- }