|
|
1.1 ! root 1: /******************************************************************************* ! 2: * * ! 3: * MODULE : DrawDIB.c * ! 4: * * ! 5: * PURPOSE : Handles most of the SHOWDIB's DIB drawing and clipboard * ! 6: * operations. * ! 7: * * ! 8: * FUNCTIONS : * ! 9: * PrintDIB() - Sets the current DIB bits to the * ! 10: * printer DC. * ! 11: * * ! 12: * AppPaint() - Sets the DIB/bitmap bits on the * ! 13: * screen or the given device. * ! 14: * * ! 15: * DrawSelect() - Draws selected clip rectangle on * ! 16: * the DC/screen. * ! 17: * * ! 18: * NormalizeRect() - Swaps reversed rectangle coords. * ! 19: * * ! 20: * TrackMouse() - Draws rubberbanding rectangle and * ! 21: * displays it's dimensions. * ! 22: * * ! 23: * BandDIB() - Outputs DIB in bands to device. * ! 24: * * ! 25: * SizeWindow() - Sizes app. window based on client * ! 26: * dimensions and style. * ! 27: * * ! 28: * GetRealClientRect() - Calculates client rectangle dimen- * ! 29: * sions if scrollbars are present. * ! 30: * * ! 31: * SetScrollRanges() - Sets global scroll ranges. * ! 32: * * ! 33: * CopyHandle() - Makes a copy of memory block. * ! 34: * * ! 35: * CopyPalette() - Makes a copy of the GDI logical * ! 36: * palette. * ! 37: * * ! 38: * CopyBitmap() - Copies given bitmap to another. * ! 39: * * ! 40: * CropBitmap() - Crops a bitmap to the given size. * ! 41: * * ! 42: * RenderFormat() - renders currently displayed DIB * ! 43: * in CF_BITMAP or CF_DIB format. * ! 44: * * ! 45: * RealizeDibFormat() - Realizes the DIB in given format. * ! 46: * * ! 47: * ErrMsg() - Pops an error message to user. * ! 48: * * ! 49: * fDialog() - Displays a dialog box. * ! 50: * * ! 51: * AppAbout() - Shows the About.. dialog box. * ! 52: * * ! 53: *******************************************************************************/ ! 54: #include <windows.h> ! 55: #include <io.h> ! 56: #include <stdio.h> ! 57: #include "showdib.h" ! 58: ! 59: MPOINT ptSize; /* Stores DIB dimensions */ ! 60: ! 61: /**************************************************************************** ! 62: * * ! 63: * FUNCTION : PrintDIB(HWND hWnd, HDC hDC, int x, int y, int dx, int dy)* ! 64: * * ! 65: * PURPOSE : Set the DIB bits to the printer DC. * ! 66: * * ! 67: ****************************************************************************/ ! 68: VOID PrintDIB ( ! 69: HWND hWnd, ! 70: HDC hDC, ! 71: INT x, ! 72: INT y, ! 73: INT dx, ! 74: INT dy) ! 75: ! 76: { ! 77: BITMAPINFOHEADER bi; ! 78: INT dibX, dibY; ! 79: INT dibDX, dibDY; ! 80: ! 81: if (!bLegitDraw) ! 82: return; ! 83: ! 84: DibInfo (hbiCurrent, &bi); ! 85: ! 86: if (IsRectEmpty (&rcClip)){ ! 87: dibX = 0; ! 88: dibY = 0; ! 89: dibDX = (INT)bi.biWidth; ! 90: dibDY = (INT)bi.biHeight; ! 91: } ! 92: else{ ! 93: dibX = rcClip.left; ! 94: dibY = (INT)bi.biHeight - 1 - rcClip.bottom; ! 95: dibDX = rcClip.right - rcClip.left; ! 96: dibDY = rcClip.bottom - rcClip.top; ! 97: } ! 98: ! 99: if (hdibCurrent){ ! 100: /* Stretch the DIB to printer DC */ ! 101: StretchDibBlt ( hDC, ! 102: x, ! 103: y, ! 104: dx, ! 105: dy, ! 106: hdibCurrent, ! 107: dibX, ! 108: dibY, ! 109: dibDX, ! 110: dibDY, ! 111: SRCCOPY); ! 112: } ! 113: else if (achFileName[0]) { ! 114: ! 115: SetMapMode (hDC, MM_ANISOTROPIC); ! 116: (VOID)SetViewportOrgEx (hDC, x, y, NULL); ! 117: (VOID)SetViewportExtEx (hDC, dx, dy, NULL); ! 118: ! 119: BandDIB (hWnd, hDC, 0, 0); ! 120: } ! 121: } ! 122: ! 123: /**************************************************************************** ! 124: * * ! 125: * FUNCTION : AppPaint(HWND hWnd, HDC hDC, int x, int y) * ! 126: * * ! 127: * PURPOSE : Sets the DIB/bitmap bits on the screen or the given device* ! 128: * * ! 129: ****************************************************************************/ ! 130: VOID AppPaint ( ! 131: HWND hWnd, ! 132: HDC hDC, ! 133: INT x, ! 134: INT y) ! 135: { ! 136: HPALETTE hpalT; ! 137: BITMAPINFOHEADER bi; ! 138: // LPBITMAPINFOHEADER lpbi; ! 139: ! 140: (VOID)SetWindowOrgEx (hDC, x, y, NULL); ! 141: SetBkMode (hDC, wTransparent); ! 142: ! 143: if (bLegitDraw) { ! 144: hpalT = SelectPalette (hDC, hpalCurrent, FALSE); ! 145: RealizePalette (hDC); ! 146: ! 147: if (hbmCurrent && !bDIBToDevice) { ! 148: DrawBitmap (hDC, 0, 0, hbmCurrent, SRCCOPY); ! 149: } ! 150: else if (hdibCurrent) { ! 151: DibInfo (hdibCurrent, &bi); ! 152: DibBlt (hDC, ! 153: 0, ! 154: 0, ! 155: (INT)bi.biWidth, ! 156: (INT)bi.biHeight, ! 157: hdibCurrent, ! 158: 0, ! 159: 0, ! 160: SRCCOPY); ! 161: } ! 162: else if (achFileName[0]) { ! 163: BandDIB (hWnd, hDC, 0, 0); ! 164: } ! 165: ! 166: SelectPalette(hDC,hpalT,FALSE); ! 167: } ! 168: ! 169: DrawSelect(hDC, TRUE); ! 170: } ! 171: ! 172: /**************************************************************************** ! 173: * * ! 174: * FUNCTION : DrawSelect(HDC hdc, BOOL fDraw) * ! 175: * * ! 176: * PURPOSE : Draws the selected clip rectangle with its dimensions on * ! 177: * the DC/screen * ! 178: * * ! 179: ****************************************************************************/ ! 180: VOID DrawSelect( ! 181: HDC hdc, ! 182: BOOL fDraw) ! 183: { ! 184: CHAR sz[80]; ! 185: INT x,y,len,dx,dy; ! 186: HDC hdcBits; ! 187: HBITMAP hbm; ! 188: ! 189: if (!IsRectEmpty (&rcClip)) { ! 190: ! 191: /* If a rectangular clip region has been selected, draw it */ ! 192: PatBlt(hdc, rcClip.left, rcClip.top, rcClip.right-rcClip.left, 1, DSTINVERT); ! 193: PatBlt(hdc, rcClip.left, rcClip.bottom, 1, -(rcClip.bottom-rcClip.top), DSTINVERT); ! 194: PatBlt(hdc, rcClip.right-1, rcClip.top, 1, rcClip.bottom-rcClip.top, DSTINVERT); ! 195: PatBlt(hdc, rcClip.right, rcClip.bottom-1, -(rcClip.right-rcClip.left), 1, DSTINVERT); ! 196: ! 197: /* Format the dimensions string ...*/ ! 198: sprintf( sz, ! 199: "%dx%d", ! 200: rcClip.right - rcClip.left, ! 201: rcClip.bottom - rcClip.top ); ! 202: len = lstrlen(sz); ! 203: ! 204: /* ... and center it in the rectangle */ ! 205: { SIZE size; ! 206: (VOID)GetTextExtentPoint(hdc, sz, len, &size); ! 207: dx = size.cx; dy = size.cy; ! 208: } ! 209: x = (rcClip.right + rcClip.left - dx) / 2; ! 210: y = (rcClip.bottom + rcClip.top - dy) / 2; ! 211: ! 212: hdcBits = CreateCompatibleDC (hdc); ! 213: SetTextColor (hdcBits, 0xFFFFFFL); ! 214: SetBkColor (hdcBits, 0x000000L); ! 215: ! 216: /* Output the text to the DC */ ! 217: /*if (hbm = +++CreateBitmap - Not Recommended(use CreateDIBitmap)+++ (dx, dy, 1, 1, NULL)){*/ ! 218: if (hbm = CreateBitmap(dx, dy, 1, 1, NULL)){ ! 219: hbm = SelectObject (hdcBits, hbm); ! 220: ExtTextOut (hdcBits, 0, 0, 0, NULL, sz, len, NULL); ! 221: BitBlt (hdc, x, y, dx, dy, hdcBits, 0, 0, SRCINVERT); ! 222: hbm = SelectObject (hdcBits, hbm); ! 223: DeleteObject (hbm); ! 224: } ! 225: DeleteDC (hdcBits); ! 226: UNREFERENCED_PARAMETER(fDraw); ! 227: } ! 228: } ! 229: /**************************************************************************** ! 230: * * ! 231: * FUNCTION : NormalizeRect(RECT *prc) * ! 232: * * ! 233: * PURPOSE : If the rectangle coordinates are reversed, swaps them * ! 234: * * ! 235: ****************************************************************************/ ! 236: VOID PASCAL NormalizeRect (RECT *prc) ! 237: { ! 238: if (prc->right < prc->left) ! 239: SWAP(prc->right,prc->left); ! 240: if (prc->bottom < prc->top) ! 241: SWAP(prc->bottom,prc->top); ! 242: } ! 243: ! 244: /**************************************************************************** ! 245: * * ! 246: * FUNCTION : TrackMouse(HWND hwnd, POINT pt) * ! 247: * * ! 248: * PURPOSE : Draws a rubberbanding rectangle and displays it's * ! 249: * dimensions till the mouse button is released * ! 250: * * ! 251: ****************************************************************************/ ! 252: VOID TrackMouse ( ! 253: HWND hwnd, ! 254: MPOINT pt) ! 255: { ! 256: // MPOINT ptBase; ! 257: HDC hdc; ! 258: MSG msg; ! 259: MPOINT ptOrigin; ! 260: RECT rcClient; ! 261: ! 262: hdc = GetDC(hwnd); ! 263: SetCapture(hwnd); ! 264: ! 265: GetClientRect(hwnd,&rcClient); ! 266: ! 267: /* Get mouse coordinates relative to origin of DIB */ ! 268: ptOrigin.x = (short int)GetScrollPos(hwnd,SB_HORZ); ! 269: ptOrigin.y = (short int)GetScrollPos(hwnd,SB_VERT); ! 270: ! 271: pt.x += ptOrigin.x; ! 272: pt.y += ptOrigin.y; ! 273: ! 274: /* Display the coordinates */ ! 275: (VOID)SetWindowOrgEx(hdc, ptOrigin.x, ptOrigin.y, NULL); ! 276: DrawSelect(hdc,FALSE); ! 277: ! 278: /* Initialize clip rectangle to the point */ ! 279: rcClip.left = pt.x; ! 280: rcClip.top = pt.y; ! 281: rcClip.right = pt.x; ! 282: rcClip.bottom = pt.y; ! 283: ! 284: /* Eat mouse messages until a WM_LBUTTONUP is encountered. Meanwhile ! 285: * continue to draw a rubberbanding rectangle and display it's dimensions ! 286: */ ! 287: for (;;){ ! 288: WaitMessage(); ! 289: if (PeekMessage(&msg,NULL,WM_MOUSEFIRST,WM_MOUSELAST,PM_REMOVE)){ ! 290: DrawSelect(hdc,FALSE); ! 291: ! 292: rcClip.left = pt.x; ! 293: rcClip.top = pt.y; ! 294: rcClip.right = LOWORD(msg.lParam) + ptOrigin.x; ! 295: rcClip.bottom = HIWORD(msg.lParam) + ptOrigin.y; ! 296: ! 297: NormalizeRect(&rcClip); ! 298: DrawSelect(hdc,TRUE); ! 299: ! 300: if (msg.message == WM_LBUTTONUP) ! 301: break; ! 302: } ! 303: else ! 304: continue; ! 305: } ! 306: ! 307: ReleaseCapture(); ! 308: ReleaseDC(hwnd,hdc); ! 309: } ! 310: ! 311: /**************************************************************************** ! 312: * * ! 313: * FUNCTION : BandDIB(HWND hWnd, HDC hDC, int x, int y) * ! 314: * * ! 315: * PURPOSE : Outputs the DIB in bands to a device or the screen, using * ! 316: * the maximum possible band size. * ! 317: * * ! 318: ****************************************************************************/ ! 319: VOID BandDIB ( ! 320: HWND hWnd, ! 321: HDC hDC, ! 322: INT x, ! 323: INT y) ! 324: { ! 325: HBITMAP hBitmap, hOld ; ! 326: HDC hMemDC ; ! 327: LPSTR pBuf; ! 328: LPBITMAPINFOHEADER lpbi; ! 329: WORD wRead, wActualPosition, wScansLeft ; ! 330: DWORD dwMapSize; ! 331: DWORD dwScans; ! 332: WORD wBitmapHeight; ! 333: RECT Rect; ! 334: HANDLE hBuf; ! 335: BOOL bSuccess = FALSE; ! 336: INT nBandSize; ! 337: HPALETTE hOldMemPal; ! 338: HPALETTE hOldPal; ! 339: HFILE fh; ! 340: OFSTRUCT of; ! 341: ! 342: /* Open the map file and get the information out */ ! 343: fh = OpenFile(achFileName, (LPOFSTRUCT)&of, (UINT)OF_READ); ! 344: ! 345: if (fh == -1) ! 346: return; ! 347: lpbi = (VOID FAR *)GlobalLock(hbiCurrent); ! 348: if (!lpbi){ ! 349: _lclose(fh); ! 350: return; ! 351: } ! 352: ! 353: /* Compute scan size in bytes */ ! 354: dwScans = WIDTHBYTES((DWORD)lpbi->biWidth * lpbi->biBitCount); ! 355: ! 356: wBitmapHeight = (WORD)lpbi->biHeight ; ! 357: wScansLeft = (WORD)lpbi->biHeight ; ! 358: ! 359: hMemDC = NULL; ! 360: for ( nBandSize = wScansLeft; ! 361: (WORD)nBandSize >= MINBAND || (WORD)nBandSize == wScansLeft; ! 362: nBandSize -= BANDINCREMENT) { ! 363: ! 364: /* Attempt to maximize band size by trying to allocate a buffer ! 365: * for the given band size. If allocation fails, try again with the ! 366: * smaller band size. ! 367: */ ! 368: hBuf = GlobalAlloc (GMEM_FIXED | GMEM_ZEROINIT, dwScans * nBandSize) ; ! 369: if (!hBuf) ! 370: continue; ! 371: ! 372: /* Show success and exit loop if we're going to set bits to device. */ ! 373: if (bDIBToDevice) { ! 374: (int)hMemDC = 1; ! 375: break; ! 376: } ! 377: else { ! 378: /* Create a device-dependent bitmap to hold the bits */ ! 379: hBitmap = CreateCompatibleBitmap (hDC, ! 380: (WORD)lpbi->biWidth, ! 381: nBandSize); ! 382: if (!hBitmap) { ! 383: /* Try again for the next smaller band size */ ! 384: GlobalFree (hBuf); ! 385: continue; ! 386: } ! 387: ! 388: /* Create a memory context for the bitmap */ ! 389: if (!(hMemDC = CreateCompatibleDC (hDC))) { ! 390: GlobalFree (hBuf); ! 391: DeleteObject (hBitmap); ! 392: continue; ! 393: } else ! 394: /* Success in creating a DC */ ! 395: break; ! 396: } ! 397: } ! 398: if (!hMemDC) { ! 399: ! 400: /* We failed allocation , so give error message and quit */ ! 401: if (GetFocus () == hWnd) { ! 402: ErrMsg ("No memory available!"); ! 403: ValidateRect (hWnd, (LPRECT) (NULL)); ! 404: } else ! 405: MessageBeep(0); ! 406: ! 407: GlobalUnlock(hbiCurrent); ! 408: _lclose(fh); ! 409: return; ! 410: } ! 411: pBuf = GlobalLock (hBuf); ! 412: ! 413: /* Calculate number of bytes to be transferred */ ! 414: dwMapSize = dwScans * nBandSize ; ! 415: ! 416: /* Manipulate palette appropriately */ ! 417: if (!bDIBToDevice) ! 418: hOldMemPal = SelectPalette (hMemDC, hpalCurrent, 0) ; ! 419: ! 420: /* Now get to the start of the map in the file */ ! 421: _llseek(fh, dwOffset, (UINT)SEEK_SET); ! 422: ! 423: /* we are now all set to start off */ ! 424: wActualPosition = wScansLeft ; ! 425: ! 426: Rect.left = 0; ! 427: Rect.right = (WORD)lpbi->biWidth; ! 428: ! 429: hOldPal = SelectPalette(hDC, hpalCurrent, 0); ! 430: RealizePalette(hDC); ! 431: ! 432: do { ! 433: /* Read in nBandSize scans or whatever is left */ ! 434: if (wScansLeft > (WORD)nBandSize) ! 435: wRead = (WORD)nBandSize ; ! 436: else ! 437: wRead = wScansLeft ; ! 438: ! 439: Rect.bottom = wActualPosition; ! 440: wActualPosition -= wRead ; ! 441: Rect.top = wActualPosition; ! 442: ! 443: dwMapSize = ((DWORD) wRead) * dwScans ; ! 444: ! 445: /* Now read in the map to the global buffer */ ! 446: if (RectVisible (hDC, &Rect)) { ! 447: lread(fh, (LPSTR)pBuf, dwMapSize); ! 448: ! 449: if (bDIBToDevice) { ! 450: if (wRead != (WORD)SetDIBitsToDevice (hDC, x, y, ! 451: (WORD)lpbi->biWidth, ! 452: wBitmapHeight, ! 453: 0, ! 454: 0, ! 455: wBitmapHeight - wScansLeft, ! 456: wRead, ! 457: pBuf, ! 458: (LPBITMAPINFO)lpbi, ! 459: fPalColors ? ! 460: DIB_PAL_COLORS : ! 461: DIB_RGB_COLORS)){ ! 462: ErrMsg ("Could not draw DIB scans to device!"); ! 463: GlobalUnlock (hBuf); ! 464: GlobalFree (hBuf); ! 465: GlobalUnlock(hbiCurrent); ! 466: _lclose(fh); ! 467: return; ! 468: } ! 469: } else { ! 470: lpbi->biHeight = wRead ; ! 471: ! 472: /* Set the DIB bits to a device-dependent format */ ! 473: if (lpbi->biHeight != (DWORD)SetDIBits (hMemDC, ! 474: hBitmap, ! 475: 0, ! 476: (WORD)lpbi->biHeight, ! 477: pBuf, ! 478: (LPBITMAPINFO)lpbi, ! 479: (DWORD) (fPalColors ? ! 480: DIB_PAL_COLORS : ! 481: DIB_RGB_COLORS))){ ! 482: ErrMsg ("Could not draw DIB scans!"); ! 483: GlobalUnlock (hBuf); ! 484: GlobalFree (hBuf); ! 485: GlobalUnlock(hbiCurrent); ! 486: _lclose(fh); ! 487: return; ! 488: } ! 489: ! 490: /* Blt own map onto the screen, remembering the point to start */ ! 491: hOld = SelectObject (hMemDC, hBitmap) ; ! 492: if (!BitBlt (hDC, 0, wActualPosition, ! 493: (WORD)lpbi->biWidth, ! 494: (WORD)lpbi->biHeight, ! 495: hMemDC, 0, 0, SRCCOPY)){ ! 496: ErrMsg ("Could not draw map to screen!"); ! 497: GlobalUnlock (hBuf); ! 498: GlobalFree (hBuf); ! 499: GlobalUnlock(hbiCurrent); ! 500: _lclose(fh); ! 501: return; ! 502: } ! 503: SelectObject (hMemDC, hOld) ; ! 504: ! 505: /* Restore the value of bitmap height */ ! 506: lpbi->biHeight = wBitmapHeight ; ! 507: } ! 508: } ! 509: else { ! 510: /* This chunk is not visible, seek over the data in the file */ ! 511: _llseek(fh, dwMapSize, (UINT)SEEK_CUR); ! 512: } ! 513: wScansLeft -= wRead ; ! 514: } while (wScansLeft > 0 ) ; ! 515: ! 516: /* Delete the objects just created above */ ! 517: GlobalUnlock (hBuf); ! 518: GlobalFree (hBuf); ! 519: SelectPalette (hDC, hOldPal, 0); ! 520: ! 521: /* Set success flag */ ! 522: bSuccess = TRUE; ! 523: ! 524: if (!bDIBToDevice) { ! 525: SelectPalette (hMemDC, hOldMemPal, 0); ! 526: DeleteDC (hMemDC) ; ! 527: DeleteObject (hBitmap) ; ! 528: } ! 529: GlobalUnlock(hbiCurrent); ! 530: ! 531: /* Close the file */ ! 532: _lclose(fh); ! 533: } ! 534: ! 535: /**************************************************************************** ! 536: * * ! 537: * FUNCTION : SizeWindow(HWND hWnd) * ! 538: * * ! 539: * PURPOSE : Sizes the app. window based on client dimensions (DIB * ! 540: * dimensions) and style. Sets the caption text. * ! 541: * * ! 542: ****************************************************************************/ ! 543: VOID SizeWindow (HWND hWnd) ! 544: { ! 545: CHAR *pstr; ! 546: CHAR Name[60]; ! 547: RECT Rectangle; ! 548: RECT rectClient; ! 549: // INT dx,dy; ! 550: // MPOINT pt; ! 551: BITMAPINFOHEADER bi; ! 552: ! 553: /* Get information about current DIB */ ! 554: DibInfo(hbiCurrent,&bi); ! 555: ! 556: /* Extract the filename from the full pathname */ ! 557: pstr = achFileName + lstrlen(achFileName) - 1; ! 558: while ((*pstr != '\\') && (*pstr != ':') && (pstr >= achFileName)) ! 559: pstr--; ! 560: pstr++; ! 561: ! 562: /* Format filename along with the DIB attributes */ ! 563: sprintf (Name, ! 564: "%s (%s %dx%dx%d%s)", ! 565: szAppName, ! 566: pstr, ! 567: (WORD)bi.biWidth, ! 568: (WORD)bi.biHeight, ! 569: (WORD)bi.biBitCount, ! 570: bi.biCompression == BI_RGB ? " RGB" : ! 571: bi.biCompression == BI_RLE8 ? " RLE8" : " RLE4" ); ! 572: ! 573: /* Show formatted text in the caption bar */ ! 574: SetWindowText (hWnd, Name); ! 575: ! 576: /* Store the size in ptSize, so the scroll bars will work. */ ! 577: ptSize.x = (WORD)bi.biWidth; ! 578: ptSize.y = (WORD)bi.biHeight; ! 579: ! 580: if (IsZoomed (hWnd)) ! 581: SetScrollRanges (hWnd); ! 582: else { ! 583: Rectangle.left = 0; ! 584: Rectangle.top = 0; ! 585: Rectangle.right = (WORD)bi.biWidth; ! 586: Rectangle.bottom = (WORD)bi.biHeight; ! 587: ! 588: /* Compute the size of the window rectangle based on the given ! 589: * client rectangle size and the window style, then size the ! 590: * window. ! 591: */ ! 592: AdjustWindowRect (&Rectangle, dwStyle, TRUE); ! 593: SetWindowPos (hWnd, (HWND)NULL, 0, 0, ! 594: Rectangle.right - Rectangle.left + 1, ! 595: Rectangle.bottom - Rectangle.top + 1, ! 596: SWP_NOMOVE | SWP_NOZORDER); ! 597: GetClientRect( hWnd, &rectClient ); ! 598: // Correct for small bitmap that causes multiline menu ! 599: if (rectClient.bottom < Rectangle.bottom) { ! 600: Rectangle.bottom += (Rectangle.bottom - rectClient.bottom); ! 601: SetWindowPos (hWnd, (HWND)NULL, 0, 0, ! 602: Rectangle.right - Rectangle.left + 1, ! 603: Rectangle.bottom - Rectangle.top + 1, ! 604: SWP_NOMOVE | SWP_NOZORDER); ! 605: } ! 606: } ! 607: ! 608: InvalidateRect(hWnd,NULL,TRUE); ! 609: } ! 610: ! 611: /**************************************************************************** ! 612: * * ! 613: * FUNCTION : GetRealClientRect(HWND hwnd, LPRECT lprc) * ! 614: * * ! 615: * PURPOSE : Calculates the client rectangle taking scrollbars into * ! 616: * consideration. * ! 617: * * ! 618: ****************************************************************************/ ! 619: VOID GetRealClientRect ( ! 620: HWND hwnd, ! 621: PRECT lprc) ! 622: { ! 623: DWORD dwStyle; ! 624: ! 625: dwStyle = GetWindowLong (hwnd, GWL_STYLE); ! 626: GetClientRect (hwnd,lprc); ! 627: ! 628: if (dwStyle & WS_HSCROLL) ! 629: lprc->bottom += GetSystemMetrics (SM_CYHSCROLL); ! 630: ! 631: if (dwStyle & WS_VSCROLL) ! 632: lprc->right += GetSystemMetrics (SM_CXVSCROLL); ! 633: } ! 634: ! 635: /**************************************************************************** ! 636: * * ! 637: * FUNCTION : SetScrollRanges(hwnd) * ! 638: * * ! 639: * PURPOSE : * ! 640: * * ! 641: ****************************************************************************/ ! 642: VOID SetScrollRanges(HWND hwnd) ! 643: { ! 644: RECT rc; ! 645: INT iRangeH, iRangeV, i; ! 646: static INT iSem = 0; ! 647: ! 648: if (!iSem){ ! 649: iSem++; ! 650: GetRealClientRect (hwnd, &rc); ! 651: ! 652: for (i = 0; i < 2; i++){ ! 653: iRangeV = ptSize.y - rc.bottom; ! 654: iRangeH = ptSize.x - rc.right; ! 655: ! 656: if (iRangeH < 0) iRangeH = 0; ! 657: if (iRangeV < 0) iRangeV = 0; ! 658: ! 659: if (GetScrollPos ( hwnd, ! 660: SB_VERT) > iRangeV || ! 661: GetScrollPos (hwnd, SB_HORZ) > iRangeH) ! 662: InvalidateRect (hwnd, NULL, TRUE); ! 663: ! 664: SetScrollRange (hwnd, SB_VERT, 0, iRangeV, TRUE); ! 665: SetScrollRange (hwnd, SB_HORZ, 0, iRangeH, TRUE); ! 666: ! 667: GetClientRect (hwnd, &rc); ! 668: } ! 669: iSem--; ! 670: } ! 671: } ! 672: ! 673: /*********** THE FOLLOWING FUNCTIONS ARE FOR CLIPBOARD SUPPORT **************/ ! 674: /**************************************************************************** ! 675: * * ! 676: * FUNCTION : CopyHandle (HANDLE h) * ! 677: * * ! 678: * PURPOSE : Makes a copy of the given global memory block. * ! 679: * * ! 680: * RETURNS : A handle to the new block. * ! 681: * * ! 682: ****************************************************************************/ ! 683: HANDLE CopyHandle (HANDLE h) ! 684: { ! 685: BYTE HUGE_T *lpCopy; ! 686: BYTE HUGE_T *lp; ! 687: HANDLE hCopy; ! 688: DWORD dwLen; ! 689: ! 690: dwLen = GlobalSize (h); ! 691: if (hCopy = GlobalAlloc (GHND, dwLen)) { ! 692: ! 693: lpCopy = (BYTE HUGE_T *)GlobalLock (hCopy); ! 694: lp = (BYTE HUGE_T *)GlobalLock (h); ! 695: while (dwLen--) *lpCopy++ = *lp++; ! 696: GlobalUnlock (hCopy); ! 697: GlobalUnlock (h); ! 698: } ! 699: return hCopy; ! 700: } ! 701: ! 702: /**************************************************************************** ! 703: * * ! 704: * FUNCTION : CopyPalette(HPALETTE hpal) * ! 705: * * ! 706: * PURPOSE : Makes a copy of a GDI logical palette * ! 707: * * ! 708: * RETURNS : A handle to the new palette. * ! 709: * * ! 710: ****************************************************************************/ ! 711: HPALETTE CopyPalette (HPALETTE hpal) ! 712: { ! 713: PLOGPALETTE ppal; ! 714: WORD nNumEntries; ! 715: ! 716: if (!hpal) ! 717: return NULL; ! 718: ! 719: GetObject(hpal,sizeof(INT),(LPSTR)&nNumEntries); ! 720: ! 721: if (nNumEntries == 0) ! 722: return NULL; ! 723: ! 724: ppal = (PLOGPALETTE)LocalAlloc(LPTR,sizeof(LOGPALETTE) + ! 725: nNumEntries * sizeof(PALETTEENTRY)); ! 726: ! 727: if (!ppal) ! 728: return NULL; ! 729: ! 730: ppal->palVersion = PALVERSION; ! 731: ppal->palNumEntries = nNumEntries; ! 732: ! 733: GetPaletteEntries(hpal,0,nNumEntries,(LPPALETTEENTRY)ppal->palPalEntry); ! 734: ! 735: hpal = CreatePalette(ppal); ! 736: ! 737: LocalFree((HANDLE)ppal); ! 738: return hpal; ! 739: } ! 740: /**************************************************************************** ! 741: * * ! 742: * FUNCTION : CopyBitmap (HBITMAP hbm) * ! 743: * * ! 744: * PURPOSE : Copies the given bitmap to another. * ! 745: * * ! 746: * RETURNS : A handle to the new bitmap. * ! 747: * * ! 748: ****************************************************************************/ ! 749: HBITMAP CopyBitmap (HBITMAP hbm) ! 750: { ! 751: BITMAP bm; ! 752: RECT rc; ! 753: ! 754: if (!hbm) ! 755: return NULL; ! 756: ! 757: GetObject (hbm, sizeof(BITMAP), (LPSTR)&bm); ! 758: rc.left = 0; ! 759: rc.top = 0; ! 760: rc.right = bm.bmWidth; ! 761: rc.bottom = bm.bmHeight; ! 762: ! 763: return CropBitmap (hbm, &rc); ! 764: } ! 765: /**************************************************************************** ! 766: * * ! 767: * FUNCTION : CropBitmap (hbm,lprect) * ! 768: * * ! 769: * PURPOSE : Crops a bitmap to a new size specified by the lprect * ! 770: * parameter. * ! 771: * * ! 772: * RETURNS : A handle to the new bitmap. * ! 773: * * ! 774: ****************************************************************************/ ! 775: HBITMAP CropBitmap ( ! 776: HBITMAP hbm, ! 777: PRECT prc) ! 778: { ! 779: HDC hMemDCsrc; ! 780: HDC hMemDCdst; ! 781: HDC hdc; ! 782: HBITMAP hNewBm; ! 783: BITMAP bm; ! 784: INT dx,dy; ! 785: ! 786: if (!hbm) ! 787: return NULL; ! 788: ! 789: hdc = GetDC (NULL); ! 790: hMemDCsrc = CreateCompatibleDC (hdc); ! 791: hMemDCdst = CreateCompatibleDC (hdc); ! 792: ! 793: GetObject (hbm, sizeof(BITMAP), (LPSTR)&bm); ! 794: dx = prc->right - prc->left; ! 795: dy = prc->bottom - prc->top; ! 796: ! 797: /*hNewBm = +++CreateBitmap - Not Recommended(use CreateDIBitmap)+++ (dx, dy, bm.bmPlanes, bm.bmBitsPixel, NULL);*/ ! 798: hNewBm = CreateBitmap(dx, dy, bm.bmPlanes, bm.bmBitsPixel, NULL); ! 799: if (hNewBm){ ! 800: SelectObject (hMemDCsrc, hbm); ! 801: SelectObject (hMemDCdst, hNewBm); ! 802: ! 803: BitBlt (hMemDCdst, ! 804: 0, ! 805: 0, ! 806: dx, ! 807: dy, ! 808: hMemDCsrc, ! 809: prc->left, ! 810: prc->top, ! 811: SRCCOPY); ! 812: } ! 813: ! 814: ReleaseDC (NULL,hdc); ! 815: DeleteDC (hMemDCsrc); ! 816: DeleteDC (hMemDCdst); ! 817: return hNewBm; ! 818: } ! 819: ! 820: /**************************************************************************** ! 821: * * ! 822: * FUNCTION : RenderFormat(int cf) * ! 823: * * ! 824: * PURPOSE : Renders the currently displayed DIB in CF_DIB or * ! 825: * CF_BITMAP format.The bitmap is clipped to the current * ! 826: * rcClip. * ! 827: * * ! 828: * RETURNS : A handle to the DIB * ! 829: * * ! 830: ****************************************************************************/ ! 831: HANDLE RenderFormat (INT cf) ! 832: { ! 833: HANDLE h = NULL; ! 834: HBITMAP hbm; ! 835: ! 836: if (!bLegitDraw) ! 837: return NULL; ! 838: ! 839: switch (cf){ ! 840: case CF_BITMAP: ! 841: if (hbmCurrent && !IsRectEmpty (&rcClip)) ! 842: h = CropBitmap (hbmCurrent, &rcClip); ! 843: else{ ! 844: if (hbmCurrent) ! 845: h = CopyBitmap (hbmCurrent); ! 846: else if (hdibCurrent) ! 847: h = BitmapFromDib (hdibCurrent, hpalCurrent); ! 848: else if (achFileName[0] && (hdibCurrent = OpenDIB (achFileName))) ! 849: h = BitmapFromDib (hdibCurrent, hpalCurrent); ! 850: else ! 851: h = NULL; ! 852: ! 853: if (h && !IsRectEmpty (&rcClip)){ ! 854: hbm = CropBitmap (h,&rcClip); ! 855: DeleteObject (h); ! 856: h = hbm; ! 857: } ! 858: } ! 859: break; ! 860: ! 861: case CF_DIB: ! 862: if (!IsRectEmpty (&rcClip)){ ! 863: if (hbm = RenderFormat (CF_BITMAP)){ ! 864: h = DibFromBitmap (hbm, BI_RGB, 0, hpalCurrent); ! 865: DeleteObject (hbm); ! 866: } ! 867: } ! 868: else{ ! 869: if (!hdibCurrent && hbmCurrent) ! 870: h = DibFromBitmap (hbmCurrent, BI_RGB, 0, hpalCurrent); ! 871: else if (hdibCurrent) ! 872: h = CopyHandle (hdibCurrent); ! 873: else if (achFileName[0]) ! 874: h = OpenDIB (achFileName); ! 875: else ! 876: h = NULL; ! 877: } ! 878: break; ! 879: ! 880: case CF_PALETTE: ! 881: if (hpalCurrent) ! 882: h = CopyPalette (hpalCurrent); ! 883: break; ! 884: } ! 885: return h; ! 886: } ! 887: /**************************************************************************** ! 888: * * ! 889: * FUNCTION : RealizeDibFormat(DWORD biStyle, WORD biBits) * ! 890: * * ! 891: * PURPOSE : Realize the current DIB in the specifed format * ! 892: * This function is used to get a specific format of CF_DIB * ! 893: * * ! 894: * biStyle DIB format RGB or RLE * ! 895: * biBits Bits per pixel 1,4,8,24 * ! 896: * * ! 897: * RETURNS : A handle to the created DIB. * ! 898: * * ! 899: ****************************************************************************/ ! 900: HANDLE RealizeDibFormat ( ! 901: DWORD biStyle, ! 902: WORD biBits) ! 903: { ! 904: BITMAPINFOHEADER bi; ! 905: ! 906: if (!bLegitDraw) ! 907: return NULL; ! 908: ! 909: DibInfo (hbiCurrent, &bi); ! 910: ! 911: /* Do we have the requested format already? */ ! 912: if (bi.biCompression == biStyle && bi.biBitCount == biBits){ ! 913: if (!hdibCurrent) ! 914: hdibCurrent = RenderFormat (CF_DIB); ! 915: } ! 916: else{ ! 917: if (!hbmCurrent) ! 918: hbmCurrent = RenderFormat (CF_BITMAP); ! 919: ! 920: if (hbmCurrent){ ! 921: if (hdibCurrent) ! 922: GlobalFree (hdibCurrent); ! 923: ! 924: hdibCurrent = DibFromBitmap (hbmCurrent, biStyle, biBits, hpalCurrent); ! 925: } ! 926: } ! 927: ! 928: return hdibCurrent; ! 929: } ! 930: /**************************************************************************** ! 931: * * ! 932: * FUNCTION : ErrMsg (PSTR sz,...) * ! 933: * * ! 934: * PURPOSE : Opens a Message box with a error message in it.The user can* ! 935: * select the OK button to continue * ! 936: * * ! 937: * RETURNS : FALSE to indicate an error has occured. * ! 938: * * ! 939: ****************************************************************************/ ! 940: INT ErrMsg (PSTR sz,...) ! 941: { ! 942: CHAR ach[128]; ! 943: ! 944: wvsprintf (ach, sz, (LPSTR)(&sz+1)); /* Format the string */ ! 945: MessageBox (NULL, ach, NULL, MB_OK|MB_ICONEXCLAMATION|MB_APPLMODAL); ! 946: return FALSE; ! 947: } ! 948: ! 949: /**************************************************************************** ! 950: * * ! 951: * FUNCTION : fDialog(int id,HWND hwnd,FARPROC fpfn) * ! 952: * * ! 953: * PURPOSE : This function displays a dialog box * ! 954: * * ! 955: * RETURNS : The exit code. * ! 956: * * ! 957: ****************************************************************************/ ! 958: BOOL fDialog ( ! 959: INT id, ! 960: HWND hwnd, ! 961: FARPROC fpfn) ! 962: { ! 963: BOOL f; ! 964: HANDLE hInst; ! 965: ! 966: hInst = (HANDLE)GetWindowLong (hwnd, GWL_HINSTANCE); ! 967: fpfn = MakeProcInstance (fpfn, hInst); ! 968: f = DialogBox (hInst, MAKEINTRESOURCE(id), hwnd, (WNDPROC)fpfn); ! 969: FreeProcInstance (fpfn); ! 970: return f; ! 971: } ! 972: ! 973: /**************************************************************************** ! 974: * * ! 975: * FUNCTION : AppAbout( hDlg, uiMessage, wParam, lParam ) * ! 976: * * ! 977: * PURPOSE : Dialog function for the About... dialog box * ! 978: * * ! 979: ****************************************************************************/ ! 980: BOOL APIENTRY AppAbout( ! 981: HWND hDlg, ! 982: UINT uiMessage, ! 983: UINT wParam, ! 984: LONG lParam) ! 985: { ! 986: switch (uiMessage) { ! 987: case WM_COMMAND: ! 988: if (LOWORD(wParam) == IDOK) ! 989: EndDialog (hDlg, TRUE); ! 990: break; ! 991: ! 992: case WM_INITDIALOG: ! 993: return TRUE; ! 994: } ! 995: return FALSE; ! 996: UNREFERENCED_PARAMETER(lParam); ! 997: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.