|
|
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];
1.1.1.5 ! root 956: va_list args;
! 957:
! 958: va_start(args, sz);
1.1 root 959:
1.1.1.5 ! root 960: wvsprintf (ach, sz, args); /* Format the string */
1.1 root 961: MessageBox (NULL, ach, NULL, MB_OK|MB_ICONEXCLAMATION|MB_APPLMODAL);
962: return FALSE;
963: }
964:
965: /****************************************************************************
1.1.1.4 root 966: * *
967: * FUNCTION : fDialog(int id,HWND hwnd,FARPROC fpfn) *
968: * *
969: * PURPOSE : This function displays a dialog box *
970: * *
971: * RETURNS : The exit code. *
972: * *
1.1 root 973: ****************************************************************************/
974: BOOL fDialog (
975: INT id,
976: HWND hwnd,
977: FARPROC fpfn)
978: {
1.1.1.4 root 979: BOOL f;
980: HANDLE hInst;
1.1 root 981:
982: hInst = (HANDLE)GetWindowLong (hwnd, GWL_HINSTANCE);
983: fpfn = MakeProcInstance (fpfn, hInst);
1.1.1.2 root 984: f = DialogBox (hInst, MAKEINTRESOURCE(id), hwnd, (DLGPROC)fpfn);
1.1 root 985: FreeProcInstance (fpfn);
986: return f;
987: }
988:
989: /****************************************************************************
1.1.1.4 root 990: * *
991: * FUNCTION : AppAbout( hDlg, uiMessage, wParam, lParam ) *
992: * *
993: * PURPOSE : Dialog function for the About... dialog box *
994: * *
1.1 root 995: ****************************************************************************/
996: BOOL APIENTRY AppAbout(
1.1.1.4 root 997: HWND hDlg,
998: UINT uiMessage,
999: UINT wParam,
1000: LONG lParam)
1.1 root 1001: {
1002: switch (uiMessage) {
1003: case WM_COMMAND:
1.1.1.4 root 1004: if (LOWORD(wParam) == IDOK)
1005: EndDialog (hDlg, TRUE);
1006: break;
1.1 root 1007:
1.1.1.4 root 1008: case WM_INITDIALOG:
1009: return TRUE;
1.1 root 1010: }
1011: return FALSE;
1.1.1.4 root 1012: UNREFERENCED_PARAMETER(lParam);
1.1 root 1013: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.