home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c480 / 18.ddi / SAMPLES / FONTEST / FONTEST.C_ / FONTEST.C
Encoding:
C/C++ Source or Header  |  1993-02-08  |  17.4 KB  |  608 lines

  1. //Order of includes matter for compile time ... /YX ...
  2.  
  3. #include <windows.h>
  4. #include "print.h"
  5.  
  6. #include <commdlg.h>
  7. #include <drivinit.h>
  8. #include <stdio.h>
  9. #include "fontest.h"
  10.  
  11. char    szAppName[] = "TM";
  12.  
  13. long FAR PASCAL __export MainWndProc(HWND, UINT, WPARAM, LPARAM);
  14.  
  15. void FAR PASCAL PaintMetrics(HDC hdc, PLOGFONT plf, int height);
  16. void FAR PASCAL DrawMetrics(HDC hdc, int x, int y, HFONT hFont, TEXTMETRIC *tm, char *pch);
  17. void FAR PASCAL ChangeOrient(HWND hWnd);
  18. BOOL ShowLogFont(HWND hWnd, LOGFONT *plf);
  19.  
  20. HANDLE hInst;
  21. char szFaceName[100] = "Times New Roman";
  22. int iPoints = 10;
  23. LOGFONT lf;
  24. BOOL bPrinter = FALSE;
  25. BOOL bScreen = TRUE;
  26. BOOL bEffects = TRUE;
  27. BOOL bAnsiOnly = FALSE;
  28. BOOL bExistingFonts = FALSE;
  29. BOOL bLimitSizes = FALSE;
  30. BOOL bFixedOnly = FALSE;
  31. BOOL bNoSimulations = FALSE;
  32. BOOL bTTOnly = FALSE;
  33. BOOL bNoWhirl = FALSE;
  34.  
  35. char szStyle[LF_FACESIZE];
  36.  
  37.  
  38.  
  39. #define PT_TO_PIXELS(hdc, pt)        MulDiv(-(pt), GetDeviceCaps(hdc, LOGPIXELSY), 72)
  40. #define POINT_SIZE    72
  41.  
  42.  
  43. int PASCAL WinMain(HANDLE hInstance, HANDLE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow)
  44. {
  45.     MSG        msg;
  46.     WNDCLASS    wndclass;
  47.     HWND        hwndMain;
  48.  
  49.     hInst = hInstance;
  50.  
  51.     if (!hPrevInstance) {
  52.         wndclass.style = CS_HREDRAW | CS_VREDRAW;
  53.         wndclass.lpfnWndProc = MainWndProc;
  54.         wndclass.cbClsExtra = 0;
  55.         wndclass.cbWndExtra = 0;
  56.         wndclass.hInstance = hInstance;
  57.         wndclass.hIcon = LoadIcon(hInst, MAKEINTRESOURCE(FONTICON));
  58.         wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
  59.         wndclass.hbrBackground = COLOR_WINDOW+1;
  60.         wndclass.lpszMenuName = szAppName;
  61.         wndclass.lpszClassName = szAppName;
  62.  
  63.         if (!RegisterClass(&wndclass))
  64.             return FALSE;
  65.     }
  66.  
  67.     if (lpszCmdLine) {
  68.         lstrcpy(lf.lfFaceName, lpszCmdLine);
  69.     }
  70.  
  71.     hwndMain = CreateWindow(szAppName, "Text Metrics",
  72.             WS_OVERLAPPEDWINDOW | WS_SYSMENU,
  73.         CW_USEDEFAULT, 0, CW_USEDEFAULT, 0,
  74.         NULL, NULL, hInstance, NULL);
  75.  
  76.     ShowWindow(hwndMain, nCmdShow);
  77.     UpdateWindow(hwndMain);
  78.  
  79.     while (GetMessage(&msg, NULL, 0, 0)) {
  80.         TranslateMessage(&msg);
  81.         DispatchMessage(&msg);
  82.     }
  83.  
  84.     return msg.wParam;
  85. }
  86.  
  87.  
  88. #define CommandMenu(id, bool)     case id: bool = !bool; break;
  89.  
  90. #define CheckMenu(id, bool)    CheckMenuItem(wParam, id, bool ? MF_BYCOMMAND | MF_CHECKED : MF_BYCOMMAND | MF_UNCHECKED)
  91.  
  92.  
  93.  
  94. long FAR PASCAL __export MainWndProc(HWND hwnd, UINT iMessage, WPARAM wParam, LPARAM lParam)
  95. {
  96.     HDC hdc;
  97.     HDC hdcDevice;
  98.     PAINTSTRUCT ps;
  99.  
  100.     switch (iMessage) {
  101.  
  102.     case WM_PAINT:
  103.         hdc = BeginPaint(hwnd, &ps);
  104.         PaintMetrics(hdc, &lf, PT_TO_PIXELS(hdc, iPoints));
  105.         EndPaint(hwnd, &ps);
  106.         break;
  107.  
  108.     case WM_INITMENUPOPUP:
  109.         CheckMenu(MENU_SCREEN, bScreen);
  110.         CheckMenu(MENU_PRINTER, bPrinter);
  111.         CheckMenu(MENU_EFFECTS, bEffects);
  112.         CheckMenu(MENU_ANSIONLY, bAnsiOnly);
  113.         CheckMenu(MENU_LIMITSIZE, bLimitSizes);
  114.         CheckMenu(MENU_EXISTINGFONTS, bExistingFonts);
  115.         CheckMenu(MENU_TTONLY, bTTOnly);
  116.         CheckMenu(MENU_NOSIMS, bNoSimulations);
  117.         CheckMenu(MENU_FIXEDONLY, bFixedOnly);
  118.         CheckMenu(MENU_NOWHIRL, bNoWhirl);
  119.  
  120.         break;
  121.  
  122.     case WM_COMMAND:
  123.  
  124.         switch (wParam) {
  125.         CommandMenu(MENU_SCREEN, bScreen);
  126.         CommandMenu(MENU_PRINTER, bPrinter);
  127.         CommandMenu(MENU_ANSIONLY, bAnsiOnly);
  128.         CommandMenu(MENU_EFFECTS, bEffects);
  129.         CommandMenu(MENU_EXISTINGFONTS, bExistingFonts);
  130.         CommandMenu(MENU_LIMITSIZE, bLimitSizes);
  131.         CommandMenu(MENU_FIXEDONLY, bFixedOnly);
  132.         CommandMenu(MENU_NOSIMS, bNoSimulations);
  133.         CommandMenu(MENU_TTONLY, bTTOnly);
  134.         CommandMenu(MENU_NOWHIRL, bNoWhirl);
  135.  
  136.         case MENU_PRINT:
  137.  
  138.             if (hdcDevice = GetPrinterDC()) {
  139.  
  140.                 if (InitPrinting(hdcDevice, hwnd, szAppName)) {
  141.  
  142.                 PaintMetrics(hdcDevice, &lf, PT_TO_PIXELS(hdcDevice, iPoints));
  143.                 Escape(hdcDevice, NEWFRAME, 0, NULL, NULL);
  144.  
  145.                 TermPrinting(hdcDevice, hwnd);
  146.                 }
  147.                 DeleteDC(hdcDevice);
  148.             }
  149.             break;
  150.  
  151.         case MENU_FONT: {
  152.             CHOOSEFONT cf;
  153.  
  154.             cf.lStructSize = sizeof(cf);
  155.             cf.hwndOwner = hwnd;
  156.             cf.lpLogFont = &lf;
  157.             cf.lpszStyle = szStyle;
  158.             cf.Flags = CF_INITTOLOGFONTSTRUCT; // | CF_USESTYLE;
  159.             if (bScreen)
  160.                 cf.Flags |= CF_SCREENFONTS;
  161.             if (bPrinter) {
  162.                 cf.hDC = GetPrinterDC();
  163.                 // cf.hDC = CreateCompatibleDC(NULL);
  164.                 cf.Flags |= CF_PRINTERFONTS;
  165.             }
  166.             if (bEffects)
  167.                 cf.Flags |= CF_EFFECTS;
  168.  
  169.             if (bAnsiOnly)
  170.                 cf.Flags |= CF_ANSIONLY;
  171.  
  172.             if (bExistingFonts)
  173.                 cf.Flags |= CF_FORCEFONTEXIST;
  174.  
  175.             if (bLimitSizes) {
  176.                 cf.Flags |= CF_LIMITSIZE;
  177.                 cf.nSizeMin = 10;
  178.                 cf.nSizeMax = 60;
  179.             }
  180.  
  181.             if (bFixedOnly)
  182.                 cf.Flags |= CF_FIXEDPITCHONLY;
  183.  
  184.             if (bNoSimulations)
  185.                 cf.Flags |= CF_NOSIMULATIONS;
  186.  
  187.             if (bTTOnly)
  188.                 cf.Flags |= CF_WYSIWYG;
  189.  
  190.             if (ChooseFont(&cf)) {
  191.                 InvalidateRect(hwnd, NULL, TRUE);
  192.                 iPoints = cf.iPointSize / 10;
  193.             }
  194.  
  195.             if (bPrinter && cf.hDC)
  196.                 DeleteDC(cf.hDC);
  197.             break;
  198.                         }
  199.  
  200.  
  201.                 case  MENU_LOGFONT:
  202.                         if (ShowLogFont (hwnd, &lf))
  203.                           InvalidateRect(hwnd, NULL, TRUE);
  204.                         break;
  205.         }
  206.         break;
  207.  
  208.  
  209.     case WM_DESTROY:
  210.         PostQuitMessage(0);
  211.         break;
  212.  
  213.     default:
  214.         return DefWindowProc(hwnd, iMessage, wParam, lParam);
  215.     }
  216.  
  217.     return 0L;
  218. }
  219.  
  220.  
  221. BOOL FAR PASCAL __export ShowLogFontProc(HWND hDlg, unsigned message, WORD wParam, LONG lParam)
  222. {
  223.   static LOGFONT  lfCurrent, FAR *plfSave;
  224.   BOOL            bTrans;
  225.  
  226.   switch (message)
  227.   {
  228.     case WM_INITDIALOG:             /* message: initialize dialog box */
  229.       plfSave = (LOGFONT FAR *) lParam;
  230.       lfCurrent = * (LOGFONT FAR *) lParam;
  231.       SetDlgItemInt (hDlg,ID_LOGHEIGHT      , lfCurrent.lfHeight, TRUE);
  232.       SetDlgItemInt (hDlg,ID_LOGWIDTH       , lfCurrent.lfWidth, TRUE);
  233.       SetDlgItemInt (hDlg,ID_LOGESCAPEMENT  , lfCurrent.lfEscapement, TRUE);
  234.       SetDlgItemInt (hDlg,ID_LOGORIENTATION , lfCurrent.lfOrientation, TRUE);
  235.       SetDlgItemInt (hDlg,ID_LOGWEIGHT      , lfCurrent.lfWeight, TRUE);
  236.       SetDlgItemInt (hDlg,ID_UNDERLINE      , lfCurrent.lfItalic, TRUE);
  237.       SetDlgItemInt (hDlg,ID_ITALIC         , lfCurrent.lfUnderline, TRUE);
  238.       SetDlgItemInt (hDlg,ID_STRIKEOUT      , lfCurrent.lfStrikeOut, TRUE);
  239.       SetDlgItemInt (hDlg,ID_CHARSET        , lfCurrent.lfCharSet, TRUE);
  240.       SetDlgItemInt (hDlg,ID_PRECISION      , lfCurrent.lfOutPrecision, TRUE);
  241.       SetDlgItemInt (hDlg,ID_CLIPPRECISION  , lfCurrent.lfClipPrecision, TRUE);
  242.       SetDlgItemInt (hDlg,ID_QUALITY        , lfCurrent.lfQuality, TRUE);
  243.       SetDlgItemInt (hDlg,ID_PITCH          , lfCurrent.lfPitchAndFamily, TRUE);
  244.       SetDlgItemText(hDlg,ID_FACE           , lfCurrent.lfFaceName);
  245.       return (TRUE);
  246.  
  247.     case WM_COMMAND:        /* message: received a command */
  248.       switch (wParam)
  249.       {
  250.         case IDOK:
  251.         lfCurrent.lfHeight         = GetDlgItemInt (hDlg,ID_LOGHEIGHT      , &bTrans, TRUE);
  252.         lfCurrent.lfWidth          = GetDlgItemInt (hDlg,ID_LOGWIDTH       , &bTrans, TRUE);
  253.         lfCurrent.lfEscapement     = GetDlgItemInt (hDlg,ID_LOGESCAPEMENT  , &bTrans, TRUE);
  254.         lfCurrent.lfOrientation    = GetDlgItemInt (hDlg,ID_LOGORIENTATION , &bTrans, TRUE);
  255.         lfCurrent.lfWeight         = GetDlgItemInt (hDlg,ID_LOGWEIGHT      , &bTrans, TRUE);
  256.         lfCurrent.lfItalic         = (BYTE) GetDlgItemInt (hDlg,ID_UNDERLINE      , &bTrans, TRUE);
  257.         lfCurrent.lfUnderline      = (BYTE) GetDlgItemInt (hDlg,ID_ITALIC         , &bTrans, TRUE);
  258.         lfCurrent.lfStrikeOut      = (BYTE) GetDlgItemInt (hDlg,ID_STRIKEOUT      , &bTrans, TRUE);
  259.         lfCurrent.lfCharSet        = (BYTE) GetDlgItemInt (hDlg,ID_CHARSET        , &bTrans, TRUE);
  260.         lfCurrent.lfOutPrecision   = (BYTE) GetDlgItemInt (hDlg,ID_PRECISION      , &bTrans, TRUE);
  261.         lfCurrent.lfClipPrecision  = (BYTE) GetDlgItemInt (hDlg,ID_CLIPPRECISION  , &bTrans, TRUE);
  262.         lfCurrent.lfQuality        = (BYTE) GetDlgItemInt (hDlg,ID_QUALITY        , &bTrans, TRUE);
  263.         lfCurrent.lfPitchAndFamily = (BYTE) GetDlgItemInt (hDlg,ID_PITCH          , &bTrans, TRUE);
  264.         GetDlgItemText(hDlg, ID_FACE, lfCurrent.lfFaceName, sizeof (lfCurrent.lfFaceName));
  265.         *plfSave = lfCurrent;
  266.  
  267.         case IDCANCEL:
  268.           EndDialog(hDlg, wParam == IDOK);  /* Exits the dialog box */
  269.           break;
  270.       }
  271.       break;
  272.     default:
  273.       return FALSE;
  274.   }
  275.   return TRUE;         /* Didn't process a message */
  276. }
  277.  
  278.  
  279. BOOL ShowLogFont (HWND hwnd, LOGFONT *plf)
  280. {
  281.   FARPROC lpShowLogFontProc;
  282.   BOOL    bRet;
  283.  
  284.   lpShowLogFontProc = MakeProcInstance (ShowLogFontProc, hInst);
  285.   bRet = (BOOL) DialogBoxParam(hInst, "LOGFONT", hwnd, lpShowLogFontProc, (LONG) (LOGFONT FAR *) plf);
  286.   FreeProcInstance (lpShowLogFontProc);
  287.   return bRet;
  288. }
  289.  
  290. void NEAR cdecl printat(HDC hdc, int x, int y, LPSTR fmt, ...)
  291. {
  292.     char    buf[80];
  293.  
  294.     wvsprintf(buf, fmt, (LPSTR)(&fmt + 1));
  295.     TextOut(hdc, x, y, buf, lstrlen(buf));
  296. }
  297.  
  298. void printWidth (HDC hdc, int *pWidth, int x, int y, int dx, int dy)
  299. {
  300.   int line, col;
  301.   char ach [10];
  302.  
  303.   for (line = 0; line < 16; line++)
  304.     for (col = 0; col < 16; col++)
  305.     {
  306.       sprintf (ach, "%d", *(pWidth + line * 16 + col));
  307.       TextOut(hdc, x + dx * col, y + line * dy, ach, lstrlen(ach));
  308.     }
  309.  
  310. }
  311.  
  312. void NEAR PASCAL SpinFont(HDC hdc, int x, int y, PLOGFONT plf)
  313. {
  314.     LOGFONT lf;
  315.     HFONT hFont, hOld;
  316.     int modeOld;
  317.     int theta;
  318.  
  319.     lf = *plf;
  320.     lf.lfWidth = 0;
  321.  
  322.     modeOld = SetBkMode(hdc, TRANSPARENT);
  323.     SetTextColor(hdc, 0x00000000);
  324.  
  325.     for (theta = 0; theta < 3600; theta += 200) {
  326.  
  327.  
  328.         lf.lfOrientation = lf.lfEscapement = theta;
  329.  
  330.         hFont = CreateFontIndirect(&lf);
  331.  
  332.         if (hFont) {
  333.             hOld = SelectObject(hdc, hFont);
  334.  
  335.             printat(hdc, x, y, "Wheee...");
  336.  
  337.             SelectObject(hdc, hOld);
  338.  
  339.             DeleteObject(hFont);
  340.         }
  341.  
  342.     }
  343.     SetBkMode(hdc, modeOld);
  344. }
  345.  
  346.  
  347.  
  348.  
  349. void FAR PASCAL PaintMetrics(HDC hdc, PLOGFONT plf, int height)
  350. {
  351.     char face_name[80];
  352.         TEXTMETRIC tm, tmView;
  353.         HFONT hFont, hOld, hFontView;
  354.         int     x, y, dy, yMax;
  355.         static LOGFONT lf = { 0, 0, 0, 0, 400, 0, 0, 0, 0, 1, 2, 1, 26, "Arial"};
  356.         static int aWidths [256];
  357.  
  358.         lf.lfHeight = PT_TO_PIXELS(hdc, 8);
  359.         hFontView = CreateFontIndirect(&lf);
  360.  
  361.     // plf->lfHeight = height;
  362.     hFont = CreateFontIndirect(plf);
  363.  
  364.     if (hFont)
  365.         hOld = SelectObject(hdc, hFont);
  366.  
  367.     GetTextMetrics(hdc, &tm);
  368.     GetTextFace(hdc, sizeof(face_name), face_name);
  369.         GetCharWidth(hdc, 0, 0xff, aWidths);
  370.  
  371.     if (hOld)
  372.         SelectObject(hdc, hOld);
  373.  
  374.         hOld = SelectObject(hdc, hFontView);
  375.  
  376.         GetTextMetrics(hdc, &tmView);
  377.  
  378.     y = 0;
  379.         x = GetDeviceCaps(hdc, LOGPIXELSX) / 4;
  380.         dy = tmView.tmHeight - 2;
  381.  
  382.     printat(hdc, x, y += dy, "tmHeight %d", tm.tmHeight);
  383.         printat(hdc, x, y += dy, "Ascent, Descent %d, %d", tm.tmAscent, tm.tmDescent);
  384.     printat(hdc, x, y += dy, "tmInternalLeading %d", tm.tmInternalLeading);
  385.     printat(hdc, x, y += dy, "tmExternalLeading %d", tm.tmExternalLeading);
  386.     printat(hdc, x, y += dy, "tmAveCharWidth %d", tm.tmAveCharWidth);
  387.     printat(hdc, x, y += dy, "tmMaxCharWidth %d", tm.tmMaxCharWidth);
  388.     printat(hdc, x, y += dy, "tmWeight %d", tm.tmWeight);
  389.         printat(hdc, x, y += dy, "Italic, Under, Strike %d, %d, %d", tm.tmItalic, tm.tmUnderlined, tm.tmStruckOut);
  390.         printat(hdc, x, y += dy, "tmFirst, tmlast: %x - %x", tm.tmFirstChar, tm.tmLastChar);
  391.     printat(hdc, x, y += dy, "tmDefaultChar %d", tm.tmDefaultChar);
  392.     printat(hdc, x, y += dy, "tmBreakChar %d", tm.tmBreakChar);
  393.     printat(hdc, x, y += dy, "tmPitchAndFamily %x", tm.tmPitchAndFamily);
  394.     printat(hdc, x, y += dy, "tmCharSet %d", tm.tmCharSet);
  395.     printat(hdc, x, y += dy, "tmOverhang %d", tm.tmOverhang);
  396.         printat(hdc, x, y += dy, "Digitized Aspect X, Y: %d, %d", tm.tmDigitizedAspectX, tm.tmDigitizedAspectY);
  397.         printat(hdc, x, y += dy, "Face Name: %s", (LPSTR)face_name);
  398.         yMax = y + dy + dy;
  399.  
  400.     y = 0;
  401.     x = 2 * GetDeviceCaps(hdc, LOGPIXELSX);
  402.     printat(hdc, x, y += dy, "lfHeight %d", plf->lfHeight);
  403.     printat(hdc, x, y += dy, "lfWidth %d", plf->lfWidth);
  404.     printat(hdc, x, y += dy, "lfEscapement %d", plf->lfEscapement);
  405.     printat(hdc, x, y += dy, "lfOrientation %d", plf->lfOrientation);
  406.     printat(hdc, x, y += dy, "lfWeight %d", plf->lfWeight);
  407.     printat(hdc, x, y += dy, "lfItalic %d", plf->lfItalic);
  408.     printat(hdc, x, y += dy, "lfUnderline %d", plf->lfUnderline);
  409.     printat(hdc, x, y += dy, "lfStrikeOut %d", plf->lfStrikeOut);
  410.     printat(hdc, x, y += dy, "lfCharSet %d", plf->lfCharSet);
  411.     printat(hdc, x, y += dy, "lfOutPrecision %x", plf->lfOutPrecision);
  412.     printat(hdc, x, y += dy, "lfClipPrecision %x", plf->lfClipPrecision);
  413.     printat(hdc, x, y += dy, "lfQuality %x", plf->lfQuality);
  414.     printat(hdc, x, y += dy, "lfPitchAndFamily %x", plf->lfPitchAndFamily);
  415.     printat(hdc, x, y += dy, "lfFaceName %s", (LPSTR)plf->lfFaceName);
  416.  
  417.         printWidth(hdc, aWidths, GetDeviceCaps(hdc, LOGPIXELSX) / 4, yMax, tmView.tmAveCharWidth * 4, dy);
  418.  
  419.     DrawMetrics(hdc, 4 * GetDeviceCaps(hdc, LOGPIXELSX), 1 * GetDeviceCaps(hdc, LOGPIXELSY), hFont, &tm, "Agm");
  420.  
  421.     if (!bNoWhirl)
  422.         SpinFont(hdc, 4 * GetDeviceCaps(hdc, LOGPIXELSX), 4 * GetDeviceCaps(hdc, LOGPIXELSY), plf);
  423.  
  424.         if (hOld)
  425.         SelectObject(hdc, hOld);
  426.  
  427.     if (hFont)
  428.         DeleteObject(hFont);
  429.  
  430.     if (hFontView)
  431.             DeleteObject(hFontView);
  432.  
  433. }
  434.  
  435.  
  436. void FAR PASCAL DrawMetrics(HDC hdc, int x, int y, HFONT hFont, TEXTMETRIC *tm, char *pch)
  437. {
  438.     RECT rc;
  439.     HFONT hOld;
  440.     int    modeOld;
  441.  
  442.     rc.top = y;
  443.     rc.left = x;
  444.  
  445.     rc.right = x + tm->tmMaxCharWidth;
  446.  
  447.  
  448.     rc.bottom = y + tm->tmHeight;
  449.  
  450.     FrameRect(hdc, &rc, GetStockObject(BLACK_BRUSH));
  451.  
  452.     rc.bottom = y + tm->tmAscent;
  453.  
  454.     FrameRect(hdc, &rc, GetStockObject(BLACK_BRUSH));
  455.  
  456.     rc.bottom = y + tm->tmInternalLeading;
  457.  
  458.     FrameRect(hdc, &rc, GetStockObject(BLACK_BRUSH));
  459.  
  460.     hOld = SelectObject(hdc, hFont);
  461.     modeOld = SetBkMode(hdc, TRANSPARENT);
  462.  
  463.     SetTextColor(hdc, 0x00FF0000);
  464.     SetBkColor(hdc, 0x0000FF00);
  465.  
  466.     while (*pch) {
  467.         TextOut(hdc, x, y, pch, 1);
  468.         pch++;
  469.     }
  470.     SetBkMode(hdc, modeOld);
  471.     SelectObject(hdc, hOld);
  472. }
  473.  
  474.  
  475.  
  476.  
  477. #if 1
  478. static char driver[] = {"PSCRIPT"};
  479. static char printer[] = {"Apple LaserWriter Plus"};
  480. static char port[] = {"output.prn"};
  481. #else
  482. static char driver[] = {"HPPCL"};
  483. static char printer[] = {"PCL / HP LaserJet"};
  484. static char port[] = {"LPT1"};
  485. #endif
  486.  
  487. /**[r******************************************************************
  488.  * ChangeOrient
  489.  **[r******************************************************************/
  490. void FAR PASCAL ChangeOrient(HWND hWnd)
  491.   {
  492.   LPDEVMODE lpDMOut;
  493.   LPDEVMODE lpDMIn;
  494.   LPFNDEVMODE lpfnDM;
  495.   HDC hDC;
  496.   HANDLE hMod;
  497.   HANDLE hData;
  498.   HFONT hFont;
  499.   WORD wSize;
  500.   char *pData;
  501.  
  502.   #define _EXTDEVICEMODE(a,b,c,d,e,f,g,h) \
  503.     (*lpfnDM)((HWND)(a),(HANDLE)(b),(LPDEVMODE)(c),(LPSTR)(d), \
  504.     (LPSTR)(e),(LPDEVMODE)(f),(LPSTR)(g),(WORD)(h))
  505.  
  506.   #define DM_SIZE 0
  507.  
  508.   if (hDC=CreateDC(driver,printer,port,(LPSTR)NULL))
  509.     {
  510.     if (!(hMod=GetModuleHandle(driver)))
  511.       goto backout0;
  512.  
  513.     if (!(lpfnDM=(LPFNDEVMODE)GetProcAddress(hMod,PROC_EXTDEVICEMODE)))
  514.       goto backout0;
  515.  
  516.     if (!(wSize=_EXTDEVICEMODE(hWnd, hMod, NULL,
  517.       printer, port, NULL, NULL, DM_SIZE)))
  518.       {
  519.       goto backout0;
  520.       }
  521.  
  522.     if (!(hData=LocalAlloc(LMEM_ZEROINIT,wSize * 2)))
  523.       goto backout0;
  524.  
  525.     if (!(pData=LocalLock(hData)))
  526.       goto backout1;
  527.  
  528.     lpDMIn = (LPDEVMODE)pData;
  529.     lpDMOut = (LPDEVMODE)&pData[wSize];
  530.  
  531.     if (_EXTDEVICEMODE(hWnd, hMod, lpDMOut, printer,
  532.       port, lpDMIn, NULL, DM_COPY) != IDOK)
  533.       {
  534.       goto backout2;
  535.       }
  536.  
  537.     if (lpDMOut->dmFields & DM_ORIENTATION)
  538.       {
  539.       // dmcopy(lpDMIn, lpDMOut, wSize)
  540.       *lpDMIn = *lpDMOut;    // doesn't copy the device dependant part!
  541.  
  542.       if (lpDMIn->dmOrientation == DMORIENT_PORTRAIT)
  543.         lpDMIn->dmOrientation = DMORIENT_LANDSCAPE;
  544.       else
  545.         lpDMIn->dmOrientation = DMORIENT_PORTRAIT;
  546.  
  547. #if 0
  548.       /* If you leave dmFields == the value returned from the
  549.        * PostScript driver, then the call to ExtDeviceMode()
  550.        * with (DM_MODIFY | DM_UPDATE) crashes the driver.
  551.        */
  552.       lpDMIn->dmFields = DM_ORIENTATION;
  553. #endif
  554.  
  555. #if 1
  556.       /* It appears that the DM_UPDATE flag has no effect.
  557.        */
  558.       _EXTDEVICEMODE(hWnd, hMod, lpDMOut,
  559.         printer, port, lpDMIn,
  560.         NULL, (DM_MODIFY | DM_UPDATE | DM_COPY));
  561. #else
  562.       /* This call succeeds, but the orientation is not changed
  563.        * on the printed output.
  564.        */
  565.       _EXTDEVICEMODE(hWnd, hMod, lpDMOut,
  566.         printer, port, lpDMIn,
  567.         NULL, DM_MODIFY);
  568. #endif
  569.  
  570. #if 1
  571.       /* If you use DM_UPDATE, the CreateDC() returns zero.
  572.        * If you don't use it, then you can't print with
  573.        * a different DC because the orientation change was
  574.        * not permanent.
  575.        */
  576.       DeleteDC(hDC);
  577.       hDC = 0;
  578.  
  579.       if (!(hDC=CreateDC(driver,printer,port,(LPSTR)NULL)))
  580.         goto backout2;
  581. #endif
  582.  
  583.       Escape(hDC, STARTDOC, 10, "Test Bench", NULL);
  584.  
  585.       if ((hFont=CreateFont(-300, 0, 0, 0, FW_NORMAL, 0, 0, 0,
  586.         ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
  587.         DEFAULT_QUALITY, (VARIABLE_PITCH | FF_ROMAN),
  588.         (LPSTR)"Tms Rmn")) && SelectObject(hDC,hFont))
  589.         {
  590.         ExtTextOut(hDC, 100, 100, 0, 0L, printer, sizeof(printer)-1, NULL);
  591.         }
  592.  
  593.       Escape(hDC, NEWFRAME, NULL, NULL, NULL);
  594.       Escape(hDC, ENDDOC, NULL, NULL, NULL);
  595.       }
  596.  
  597. backout2:
  598.     LocalUnlock(hData);
  599.     pData = NULL;
  600. backout1:
  601.     LocalFree(hData);
  602.     hData = 0;
  603. backout0:
  604.     if (hDC)
  605.       DeleteDC(hDC);
  606.     }
  607.   }
  608.