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