|
|
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 */
1.1.1.2 root 473: if (lpbi->biHeight != (int)SetDIBits (hMemDC,
1.1 root 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;
1.1.1.3 ! root 558: while ((*pstr != '\\') && (*pstr != ':') && (pstr > achFileName))
1.1 root 559: pstr--;
1.1.1.3 ! root 560:
! 561: if(pstr != achFileName)
! 562: pstr++;
1.1 root 563:
564: /* Format filename along with the DIB attributes */
565: sprintf (Name,
566: "%s (%s %dx%dx%d%s)",
567: szAppName,
568: pstr,
569: (WORD)bi.biWidth,
570: (WORD)bi.biHeight,
571: (WORD)bi.biBitCount,
572: bi.biCompression == BI_RGB ? " RGB" :
573: bi.biCompression == BI_RLE8 ? " RLE8" : " RLE4" );
574:
575: /* Show formatted text in the caption bar */
576: SetWindowText (hWnd, Name);
577:
578: /* Store the size in ptSize, so the scroll bars will work. */
579: ptSize.x = (WORD)bi.biWidth;
580: ptSize.y = (WORD)bi.biHeight;
581:
582: if (IsZoomed (hWnd))
583: SetScrollRanges (hWnd);
584: else {
585: Rectangle.left = 0;
586: Rectangle.top = 0;
587: Rectangle.right = (WORD)bi.biWidth;
588: Rectangle.bottom = (WORD)bi.biHeight;
589:
590: /* Compute the size of the window rectangle based on the given
591: * client rectangle size and the window style, then size the
592: * window.
593: */
594: AdjustWindowRect (&Rectangle, dwStyle, TRUE);
595: SetWindowPos (hWnd, (HWND)NULL, 0, 0,
596: Rectangle.right - Rectangle.left + 1,
597: Rectangle.bottom - Rectangle.top + 1,
598: SWP_NOMOVE | SWP_NOZORDER);
599: GetClientRect( hWnd, &rectClient );
600: // Correct for small bitmap that causes multiline menu
601: if (rectClient.bottom < Rectangle.bottom) {
602: Rectangle.bottom += (Rectangle.bottom - rectClient.bottom);
603: SetWindowPos (hWnd, (HWND)NULL, 0, 0,
604: Rectangle.right - Rectangle.left + 1,
605: Rectangle.bottom - Rectangle.top + 1,
606: SWP_NOMOVE | SWP_NOZORDER);
607: }
608: }
609:
610: InvalidateRect(hWnd,NULL,TRUE);
611: }
612:
613: /****************************************************************************
614: * *
615: * FUNCTION : GetRealClientRect(HWND hwnd, LPRECT lprc) *
616: * *
617: * PURPOSE : Calculates the client rectangle taking scrollbars into *
618: * consideration. *
619: * *
620: ****************************************************************************/
621: VOID GetRealClientRect (
622: HWND hwnd,
623: PRECT lprc)
624: {
625: DWORD dwStyle;
626:
627: dwStyle = GetWindowLong (hwnd, GWL_STYLE);
628: GetClientRect (hwnd,lprc);
629:
630: if (dwStyle & WS_HSCROLL)
631: lprc->bottom += GetSystemMetrics (SM_CYHSCROLL);
632:
633: if (dwStyle & WS_VSCROLL)
634: lprc->right += GetSystemMetrics (SM_CXVSCROLL);
635: }
636:
637: /****************************************************************************
638: * *
639: * FUNCTION : SetScrollRanges(hwnd) *
640: * *
641: * PURPOSE : *
642: * *
643: ****************************************************************************/
644: VOID SetScrollRanges(HWND hwnd)
645: {
646: RECT rc;
647: INT iRangeH, iRangeV, i;
648: static INT iSem = 0;
649:
650: if (!iSem){
651: iSem++;
652: GetRealClientRect (hwnd, &rc);
653:
654: for (i = 0; i < 2; i++){
655: iRangeV = ptSize.y - rc.bottom;
656: iRangeH = ptSize.x - rc.right;
657:
658: if (iRangeH < 0) iRangeH = 0;
659: if (iRangeV < 0) iRangeV = 0;
660:
661: if (GetScrollPos ( hwnd,
662: SB_VERT) > iRangeV ||
663: GetScrollPos (hwnd, SB_HORZ) > iRangeH)
664: InvalidateRect (hwnd, NULL, TRUE);
665:
666: SetScrollRange (hwnd, SB_VERT, 0, iRangeV, TRUE);
667: SetScrollRange (hwnd, SB_HORZ, 0, iRangeH, TRUE);
668:
669: GetClientRect (hwnd, &rc);
670: }
671: iSem--;
672: }
673: }
674:
675: /*********** THE FOLLOWING FUNCTIONS ARE FOR CLIPBOARD SUPPORT **************/
676: /****************************************************************************
677: * *
678: * FUNCTION : CopyHandle (HANDLE h) *
679: * *
680: * PURPOSE : Makes a copy of the given global memory block. *
681: * *
682: * RETURNS : A handle to the new block. *
683: * *
684: ****************************************************************************/
685: HANDLE CopyHandle (HANDLE h)
686: {
687: BYTE HUGE_T *lpCopy;
688: BYTE HUGE_T *lp;
689: HANDLE hCopy;
690: DWORD dwLen;
691:
692: dwLen = GlobalSize (h);
693: if (hCopy = GlobalAlloc (GHND, dwLen)) {
694:
695: lpCopy = (BYTE HUGE_T *)GlobalLock (hCopy);
696: lp = (BYTE HUGE_T *)GlobalLock (h);
697: while (dwLen--) *lpCopy++ = *lp++;
698: GlobalUnlock (hCopy);
699: GlobalUnlock (h);
700: }
701: return hCopy;
702: }
703:
704: /****************************************************************************
705: * *
706: * FUNCTION : CopyPalette(HPALETTE hpal) *
707: * *
708: * PURPOSE : Makes a copy of a GDI logical palette *
709: * *
710: * RETURNS : A handle to the new palette. *
711: * *
712: ****************************************************************************/
713: HPALETTE CopyPalette (HPALETTE hpal)
714: {
715: PLOGPALETTE ppal;
716: WORD nNumEntries;
717:
718: if (!hpal)
719: return NULL;
720:
721: GetObject(hpal,sizeof(INT),(LPSTR)&nNumEntries);
722:
723: if (nNumEntries == 0)
724: return NULL;
725:
726: ppal = (PLOGPALETTE)LocalAlloc(LPTR,sizeof(LOGPALETTE) +
727: nNumEntries * sizeof(PALETTEENTRY));
728:
729: if (!ppal)
730: return NULL;
731:
732: ppal->palVersion = PALVERSION;
733: ppal->palNumEntries = nNumEntries;
734:
735: GetPaletteEntries(hpal,0,nNumEntries,(LPPALETTEENTRY)ppal->palPalEntry);
736:
737: hpal = CreatePalette(ppal);
738:
739: LocalFree((HANDLE)ppal);
740: return hpal;
741: }
742: /****************************************************************************
743: * *
744: * FUNCTION : CopyBitmap (HBITMAP hbm) *
745: * *
746: * PURPOSE : Copies the given bitmap to another. *
747: * *
748: * RETURNS : A handle to the new bitmap. *
749: * *
750: ****************************************************************************/
751: HBITMAP CopyBitmap (HBITMAP hbm)
752: {
753: BITMAP bm;
754: RECT rc;
755:
756: if (!hbm)
757: return NULL;
758:
759: GetObject (hbm, sizeof(BITMAP), (LPSTR)&bm);
760: rc.left = 0;
761: rc.top = 0;
762: rc.right = bm.bmWidth;
763: rc.bottom = bm.bmHeight;
764:
765: return CropBitmap (hbm, &rc);
766: }
767: /****************************************************************************
768: * *
769: * FUNCTION : CropBitmap (hbm,lprect) *
770: * *
771: * PURPOSE : Crops a bitmap to a new size specified by the lprect *
772: * parameter. *
773: * *
774: * RETURNS : A handle to the new bitmap. *
775: * *
776: ****************************************************************************/
777: HBITMAP CropBitmap (
778: HBITMAP hbm,
779: PRECT prc)
780: {
781: HDC hMemDCsrc;
782: HDC hMemDCdst;
783: HDC hdc;
784: HBITMAP hNewBm;
785: BITMAP bm;
786: INT dx,dy;
787:
788: if (!hbm)
789: return NULL;
790:
791: hdc = GetDC (NULL);
792: hMemDCsrc = CreateCompatibleDC (hdc);
793: hMemDCdst = CreateCompatibleDC (hdc);
794:
795: GetObject (hbm, sizeof(BITMAP), (LPSTR)&bm);
796: dx = prc->right - prc->left;
797: dy = prc->bottom - prc->top;
798:
799: /*hNewBm = +++CreateBitmap - Not Recommended(use CreateDIBitmap)+++ (dx, dy, bm.bmPlanes, bm.bmBitsPixel, NULL);*/
800: hNewBm = CreateBitmap(dx, dy, bm.bmPlanes, bm.bmBitsPixel, NULL);
801: if (hNewBm){
802: SelectObject (hMemDCsrc, hbm);
803: SelectObject (hMemDCdst, hNewBm);
804:
805: BitBlt (hMemDCdst,
806: 0,
807: 0,
808: dx,
809: dy,
810: hMemDCsrc,
811: prc->left,
812: prc->top,
813: SRCCOPY);
814: }
815:
816: ReleaseDC (NULL,hdc);
817: DeleteDC (hMemDCsrc);
818: DeleteDC (hMemDCdst);
819: return hNewBm;
820: }
821:
822: /****************************************************************************
823: * *
824: * FUNCTION : RenderFormat(int cf) *
825: * *
826: * PURPOSE : Renders the currently displayed DIB in CF_DIB or *
827: * CF_BITMAP format.The bitmap is clipped to the current *
828: * rcClip. *
829: * *
830: * RETURNS : A handle to the DIB *
831: * *
832: ****************************************************************************/
833: HANDLE RenderFormat (INT cf)
834: {
835: HANDLE h = NULL;
836: HBITMAP hbm;
837:
838: if (!bLegitDraw)
839: return NULL;
840:
841: switch (cf){
842: case CF_BITMAP:
843: if (hbmCurrent && !IsRectEmpty (&rcClip))
844: h = CropBitmap (hbmCurrent, &rcClip);
845: else{
846: if (hbmCurrent)
847: h = CopyBitmap (hbmCurrent);
848: else if (hdibCurrent)
849: h = BitmapFromDib (hdibCurrent, hpalCurrent);
850: else if (achFileName[0] && (hdibCurrent = OpenDIB (achFileName)))
851: h = BitmapFromDib (hdibCurrent, hpalCurrent);
852: else
853: h = NULL;
854:
855: if (h && !IsRectEmpty (&rcClip)){
856: hbm = CropBitmap (h,&rcClip);
857: DeleteObject (h);
858: h = hbm;
859: }
860: }
861: break;
862:
863: case CF_DIB:
864: if (!IsRectEmpty (&rcClip)){
865: if (hbm = RenderFormat (CF_BITMAP)){
866: h = DibFromBitmap (hbm, BI_RGB, 0, hpalCurrent);
867: DeleteObject (hbm);
868: }
869: }
870: else{
871: if (!hdibCurrent && hbmCurrent)
872: h = DibFromBitmap (hbmCurrent, BI_RGB, 0, hpalCurrent);
873: else if (hdibCurrent)
874: h = CopyHandle (hdibCurrent);
875: else if (achFileName[0])
876: h = OpenDIB (achFileName);
877: else
878: h = NULL;
879: }
880: break;
881:
882: case CF_PALETTE:
883: if (hpalCurrent)
884: h = CopyPalette (hpalCurrent);
885: break;
886: }
887: return h;
888: }
889: /****************************************************************************
890: * *
891: * FUNCTION : RealizeDibFormat(DWORD biStyle, WORD biBits) *
892: * *
893: * PURPOSE : Realize the current DIB in the specifed format *
894: * This function is used to get a specific format of CF_DIB *
895: * *
896: * biStyle DIB format RGB or RLE *
897: * biBits Bits per pixel 1,4,8,24 *
898: * *
899: * RETURNS : A handle to the created DIB. *
900: * *
901: ****************************************************************************/
902: HANDLE RealizeDibFormat (
903: DWORD biStyle,
904: WORD biBits)
905: {
906: BITMAPINFOHEADER bi;
907:
908: if (!bLegitDraw)
909: return NULL;
910:
911: DibInfo (hbiCurrent, &bi);
912:
913: /* Do we have the requested format already? */
914: if (bi.biCompression == biStyle && bi.biBitCount == biBits){
915: if (!hdibCurrent)
916: hdibCurrent = RenderFormat (CF_DIB);
917: }
918: else{
919: if (!hbmCurrent)
920: hbmCurrent = RenderFormat (CF_BITMAP);
921:
922: if (hbmCurrent){
923: if (hdibCurrent)
924: GlobalFree (hdibCurrent);
925:
926: hdibCurrent = DibFromBitmap (hbmCurrent, biStyle, biBits, hpalCurrent);
927: }
928: }
929:
930: return hdibCurrent;
931: }
932: /****************************************************************************
933: * *
934: * FUNCTION : ErrMsg (PSTR sz,...) *
935: * *
936: * PURPOSE : Opens a Message box with a error message in it.The user can*
937: * select the OK button to continue *
938: * *
939: * RETURNS : FALSE to indicate an error has occured. *
940: * *
941: ****************************************************************************/
942: INT ErrMsg (PSTR sz,...)
943: {
944: CHAR ach[128];
945:
946: wvsprintf (ach, sz, (LPSTR)(&sz+1)); /* Format the string */
947: MessageBox (NULL, ach, NULL, MB_OK|MB_ICONEXCLAMATION|MB_APPLMODAL);
948: return FALSE;
949: }
950:
951: /****************************************************************************
952: * *
953: * FUNCTION : fDialog(int id,HWND hwnd,FARPROC fpfn) *
954: * *
955: * PURPOSE : This function displays a dialog box *
956: * *
957: * RETURNS : The exit code. *
958: * *
959: ****************************************************************************/
960: BOOL fDialog (
961: INT id,
962: HWND hwnd,
963: FARPROC fpfn)
964: {
965: BOOL f;
966: HANDLE hInst;
967:
968: hInst = (HANDLE)GetWindowLong (hwnd, GWL_HINSTANCE);
969: fpfn = MakeProcInstance (fpfn, hInst);
1.1.1.2 root 970: f = DialogBox (hInst, MAKEINTRESOURCE(id), hwnd, (DLGPROC)fpfn);
1.1 root 971: FreeProcInstance (fpfn);
972: return f;
973: }
974:
975: /****************************************************************************
976: * *
977: * FUNCTION : AppAbout( hDlg, uiMessage, wParam, lParam ) *
978: * *
979: * PURPOSE : Dialog function for the About... dialog box *
980: * *
981: ****************************************************************************/
982: BOOL APIENTRY AppAbout(
983: HWND hDlg,
984: UINT uiMessage,
985: UINT wParam,
986: LONG lParam)
987: {
988: switch (uiMessage) {
989: case WM_COMMAND:
990: if (LOWORD(wParam) == IDOK)
991: EndDialog (hDlg, TRUE);
992: break;
993:
994: case WM_INITDIALOG:
995: return TRUE;
996: }
997: return FALSE;
998: UNREFERENCED_PARAMETER(lParam);
999: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.