|
|
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.