home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / graphics / directx / dxview / dxprint.c < prev    next >
C/C++ Source or Header  |  1997-07-14  |  22KB  |  812 lines

  1. /*
  2. **-----------------------------------------------------------------------------
  3. ** Name:    dxprint.c
  4. ** Purpose: print's DX Tree View info to selected printer
  5. ** Notes:
  6. **-----------------------------------------------------------------------------
  7. */
  8.  
  9. /*
  10. **-----------------------------------------------------------------------------
  11. ** Includes
  12. **-----------------------------------------------------------------------------
  13. */
  14. #include <windows.h>
  15. #include <windowsx.h>
  16. #include <mmsystem.h>
  17. #include <commctrl.h>
  18. #include <commdlg.h>        // Common Print Dialog
  19. #include <tchar.h>          // Unicode string functions and types
  20.  
  21. #include <ddraw.h>
  22. #include <dsound.h>
  23. #include <dplay.h>
  24. #include <d3d.h>
  25. #include "dxview.h"
  26.  
  27.  
  28. /*
  29. **-----------------------------------------------------------------------------
  30. ** Local Variables
  31. **-----------------------------------------------------------------------------
  32. */
  33.  
  34. BOOL g_fAbortPrint      = FALSE;       // Did User Abort Print operation ?!?
  35. HWND g_hAbortPrintDlg   = NULL;        // Print Abort Dialog handle
  36. BOOL g_PrintToFile      = FALSE;       // Don't print to printer print to dxview.log
  37. HANDLE g_FileHandle     = NULL;        // Handle to log file
  38.                                         
  39. /*
  40. **-----------------------------------------------------------------------------
  41. ** Local Prototypes
  42. **-----------------------------------------------------------------------------
  43. */
  44.  
  45. BOOL CALLBACK PrintTreeStats(
  46.     HINSTANCE   hInstance,
  47.     HWND        hWindow,
  48.     HWND        hTreeWnd,
  49.     HTREEITEM   hRoot);
  50.  
  51. void DoMessage (DWORD dwTitle, DWORD dwMsg);
  52.  
  53.  
  54. /*
  55. **-----------------------------------------------------------------------------
  56. ** Functions
  57. **-----------------------------------------------------------------------------
  58. */
  59.  
  60. /*
  61. **-----------------------------------------------------------------------------
  62. ** Name:    DXView_OnPrint
  63. ** Purpose: Print user defined stuff
  64. **-----------------------------------------------------------------------------
  65. */
  66.  
  67. BOOL DXView_OnPrint (
  68.     HWND hWindow, 
  69.     HWND hTreeWnd,
  70.     BOOL fPrintAll)
  71. {
  72.     HINSTANCE hInstance;
  73.     HTREEITEM hRoot;
  74.  
  75.     // Check Parameters
  76.     if ((! hWindow) || (! hTreeWnd))
  77.     {
  78.         // Invalid parameters
  79.         return FALSE;
  80.     }
  81.  
  82.     // Get hInstance
  83.     hInstance = (HINSTANCE)GetWindowLong (hWindow, GWL_HINSTANCE);
  84.     if (! hInstance)
  85.         return FALSE;
  86.  
  87.     if (fPrintAll)
  88.     {
  89.         hRoot = NULL;
  90.     }
  91.     else
  92.     {
  93.         hRoot = TreeView_GetSelection (hTreeWnd);
  94.         if (! hRoot)
  95.         {
  96.             DoMessage (IDS_PRINT_WARNING, IDS_PRINT_NEEDSELECT);
  97.         }
  98.     }
  99.     g_PrintToFile = FALSE;
  100.     // Do actual printing
  101.     return PrintTreeStats (hInstance, hWindow, hTreeWnd, hRoot);
  102.  
  103. } // End DXView_OnPrint
  104.  
  105. BOOL DXView_OnFile (
  106.     HWND hWindow, 
  107.     HWND hTreeWnd,
  108.     BOOL fPrintAll)
  109. {
  110.     HINSTANCE hInstance;
  111.     HTREEITEM hRoot;
  112.  
  113.     // Check Parameters
  114.     if ((! hWindow) || (! hTreeWnd))
  115.     {
  116.         // Invalid parameters
  117.         return FALSE;
  118.     }
  119.  
  120.     // Get hInstance
  121.     hInstance = (HINSTANCE)GetWindowLong (hWindow, GWL_HINSTANCE);
  122.     if (! hInstance)
  123.         return FALSE;
  124.  
  125.     if (fPrintAll)
  126.     {
  127.         hRoot = NULL;
  128.     }
  129.     else
  130.     {
  131.         hRoot = TreeView_GetSelection (hTreeWnd);
  132.         if (! hRoot)
  133.         {
  134.             DoMessage (IDS_PRINT_WARNING, IDS_PRINT_NEEDSELECT);
  135.         }
  136.     }
  137.     g_PrintToFile = TRUE;
  138.     // Do actual printing
  139.     return PrintTreeStats (hInstance, hWindow, hTreeWnd, hRoot);
  140.  
  141. } // End DXView_OnPrint
  142.  
  143.  
  144.  
  145. /*
  146. **-----------------------------------------------------------------------------
  147. ** Name:    PrintDialogProc
  148. ** Purpose: Dialog procedure for printing
  149. **-----------------------------------------------------------------------------
  150. */
  151.  
  152. BOOL CALLBACK PrintDialogProc (
  153.     HWND    hDialog,
  154.     UINT    uiMsg,
  155.     WPARAM  wParam,
  156.     LPARAM  lParam)
  157. {
  158.     switch (uiMsg)
  159.     {
  160.     case WM_INITDIALOG:
  161.         {
  162.         // Disable system menu on dialog
  163.         HMENU hSysMenu = GetSystemMenu (hDialog, FALSE);
  164.         EnableMenuItem (hSysMenu, SC_CLOSE, MF_GRAYED);
  165.         }
  166.         return TRUE;
  167.  
  168.     case WM_COMMAND:
  169.         {
  170.         // User is aborting print operation
  171.         g_fAbortPrint = TRUE;
  172.         EnableWindow (GetParent (hDialog), TRUE);
  173.         DestroyWindow (hDialog);
  174.         g_hAbortPrintDlg = NULL;
  175.         }
  176.         return TRUE;
  177.     } // End switch
  178.  
  179.     return FALSE;
  180. } // End PrintDialogProc
  181.  
  182.  
  183.  
  184. /*
  185. **-----------------------------------------------------------------------------
  186. ** Name:    AbortProc
  187. ** Purpose: Abort procedure for printing
  188. **-----------------------------------------------------------------------------
  189. */
  190.  
  191. BOOL CALLBACK AbortProc (HDC hPrinterDC, int iCode)
  192. {
  193.     MSG msg;
  194.  
  195.     while (! g_fAbortPrint && PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
  196.     {
  197.         if ((! g_hAbortPrintDlg) || ! IsDialogMessage (g_hAbortPrintDlg, &msg))
  198.         {
  199.             TranslateMessage (&msg);
  200.             DispatchMessage (&msg);
  201.         }
  202.     }
  203.  
  204.     return !g_fAbortPrint;
  205. } // End AbortProc
  206.  
  207.  
  208. /*
  209. **-----------------------------------------------------------------------------
  210. ** Name:    PrintStats
  211. ** Purpose: Print user defined stuff
  212. **-----------------------------------------------------------------------------
  213. */
  214.  
  215. BOOL CALLBACK PrintTreeStats(
  216.     HINSTANCE   hInstance,
  217.     HWND        hWindow,
  218.     HWND        hTreeWnd,
  219.     HTREEITEM   hRoot)
  220. {
  221.     static DOCINFO  di;
  222.     static PRINTDLG pd;
  223.  
  224.     BOOL        fDone           = FALSE;
  225.     BOOL        fFindNext       = FALSE;
  226.     BOOL        fResult         = FALSE;
  227.     BOOL        fStartDoc       = FALSE;
  228.     BOOL        fDisableWindow  = FALSE;
  229.     LPTSTR      pstrTitle       = NULL;
  230.     LPTSTR      pstrBuff        = NULL;
  231.     TEXTMETRIC  tm;
  232.     DWORD       dwCurrCopy;
  233.     HANDLE      hHeap;
  234.     DWORD       cbSize;
  235.     DWORD       cchLen;
  236.     TV_ITEM     tvi;
  237.     HTREEITEM   hStartTree, hTempTree;
  238.     PRINTCBINFO pci;
  239.  
  240.     // Check Parameters
  241.     if ((! hInstance) || (! hWindow) || (! hTreeWnd))
  242.     {
  243.         // Error, invalid parameters
  244.         return FALSE;
  245.     }
  246.  
  247.     // Get Starting point for tree
  248.     if (hRoot)
  249.         hStartTree = hRoot;
  250.     else
  251.         hStartTree = TreeView_GetRoot (hTreeWnd);
  252.     if (! hStartTree)
  253.     {
  254.         // Error, invalid tree
  255.         return FALSE;
  256.     }
  257.     
  258.     // Initialize Print Dialog structure
  259.     pd.lStructSize          = sizeof (PRINTDLG);
  260.     pd.hwndOwner            = hWindow;
  261.     pd.hDevMode             = NULL;
  262.     pd.hDevNames            = NULL;
  263.     pd.hDC                  = NULL;
  264.     pd.Flags                = PD_ALLPAGES | PD_RETURNDC;
  265.     pd.nFromPage            = 0;
  266.     pd.nToPage              = 0;
  267.     pd.nMinPage             = 0;
  268.     pd.nMaxPage             = 0;
  269.     pd.nCopies              = 1;
  270.     pd.hInstance            = NULL;
  271.     pd.lCustData            = 0L;
  272.     pd.lpfnPrintHook        = NULL;
  273.     pd.lpfnSetupHook        = NULL;
  274.     pd.lpPrintTemplateName  = NULL;
  275.     pd.lpSetupTemplateName  = NULL;
  276.     pd.hPrintTemplate       = NULL;
  277.     pd.hSetupTemplate       = NULL;
  278.  
  279.     if(g_PrintToFile)
  280.     {
  281.         pci.hdcPrint = NULL;
  282.     }else
  283.     {
  284.         // Call Common Print Dialog to get printer DC
  285.         if ((! PrintDlg (&pd)) || (! pd.hDC))
  286.         {
  287.             // Error, Print Dialog failed or user canceled
  288.             return TRUE;
  289.         }
  290.         pci.hdcPrint = pd.hDC;
  291.         // Get Text metrics for printing
  292.         if (! GetTextMetrics (pci.hdcPrint, &tm))
  293.         {
  294.             // Error, TextMetrics failed
  295.             goto lblCLEANUP;
  296.         }
  297.     }
  298.     if(g_PrintToFile)
  299.     {
  300.         pci.dwLineHeight   = 1;
  301.         pci.dwCharWidth    = 1;
  302.         pci.dwCharsPerLine = 80;
  303.         pci.dwLinesPerPage = 66;
  304.     }else
  305.     {
  306.         pci.dwLineHeight   = tm.tmHeight + tm.tmExternalLeading;
  307.         pci.dwCharWidth    = tm.tmAveCharWidth;
  308.         pci.dwCharsPerLine = GetDeviceCaps (pci.hdcPrint, HORZRES) / pci.dwCharWidth;
  309.         pci.dwLinesPerPage = GetDeviceCaps (pci.hdcPrint, VERTRES) / pci.dwLineHeight;
  310.     }
  311.  
  312.     // Get Heap
  313.     hHeap = GetProcessHeap ();
  314.     if (! hHeap)
  315.     {
  316.         // Error, no heap associated with this process
  317.         goto lblCLEANUP;
  318.     }
  319.  
  320.     // Create line buffer
  321.     cbSize = (pci.dwCharsPerLine + 1) * sizeof(TCHAR);
  322.     pstrBuff = (LPTSTR) HeapAlloc (hHeap, HEAP_NO_SERIALIZE, cbSize);
  323.     if (! pstrBuff)
  324.     {
  325.         // Error, not enough memory 
  326.         goto lblCLEANUP;
  327.     }
  328.  
  329.     // Disable Parent window
  330.     EnableWindow (hWindow, FALSE);
  331.     fDisableWindow = TRUE;
  332.  
  333.     // Start Printer Abort Dialog
  334.     g_fAbortPrint = FALSE;
  335.     g_hAbortPrintDlg = CreateDialog (hInstance, MAKEINTRESOURCE (IDD_ABORTPRINTDLG),
  336.                                      hWindow, (DLGPROC)PrintDialogProc);
  337.     if (! g_hAbortPrintDlg)
  338.     {
  339.         // Error, unable to create abort dialog
  340.         goto lblCLEANUP;
  341.     }
  342.  
  343.     //
  344.     // Set Document title to Root string
  345.     //
  346.     tvi.mask            = TVIF_CHILDREN | TVIF_TEXT;
  347.     tvi.hItem           = hStartTree;
  348.     tvi.pszText         = pstrBuff;
  349.     tvi.cchTextMax      = pci.dwCharsPerLine;
  350.     if (TreeView_GetItem (hTreeWnd, &tvi))
  351.     {
  352.         SetWindowText (g_hAbortPrintDlg, pstrBuff);
  353.         SetAbortProc (pd.hDC, AbortProc);
  354.         cchLen = _tcsclen (pstrBuff);
  355.         cbSize = (cchLen + 1) * sizeof(TCHAR);
  356.         pstrTitle = (LPTSTR) HeapAlloc (hHeap, HEAP_NO_SERIALIZE, cbSize);
  357.         if (! pstrTitle)
  358.         {
  359.             // Error, not enough memory 
  360.             goto lblCLEANUP;
  361.         }
  362.  
  363.         _tcsncpy (pstrTitle, pstrBuff, cchLen);
  364.         pstrTitle[cchLen] = 0;
  365.     }
  366.     else
  367.     {
  368.         SetWindowText (g_hAbortPrintDlg, TEXT("Unknown"));
  369.         SetAbortProc (pd.hDC, AbortProc);
  370.         cchLen = _tcsclen (TEXT("Unknown"));
  371.         cbSize = (cchLen + 1) * sizeof(TCHAR);
  372.         pstrTitle = (LPTSTR) HeapAlloc (hHeap, HEAP_NO_SERIALIZE, cbSize);
  373.         if (! pstrTitle)
  374.         {
  375.             // Error, not enough memory 
  376.             goto lblCLEANUP;
  377.         }
  378.  
  379.         _tcsncpy (pstrTitle, TEXT("Unknown"), cchLen);
  380.         pstrTitle[cchLen] = 0;
  381.     }
  382.  
  383.     // Initialize Document Structure
  384.     di.cbSize       = sizeof(DOCINFO);
  385.     di.lpszDocName  = pstrTitle; 
  386.     di.lpszOutput   = NULL; 
  387.     di.lpszDatatype = NULL;
  388.     di.fwType       = 0;
  389.  
  390.     // Start document
  391.     if(g_PrintToFile)
  392.     {
  393.         g_FileHandle = CreateFile("dxview.log",GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
  394.     } else
  395.     if (StartDoc (pd.hDC, &di) < 0)
  396.     {
  397.         // Error, StartDoc failed
  398.         goto lblCLEANUP;
  399.     }
  400.     fStartDoc = TRUE;
  401.  
  402.     // Print requested number of copies
  403.     fResult = FALSE;
  404.     for (dwCurrCopy = 0; dwCurrCopy < (DWORD)pd.nCopies; dwCurrCopy++)
  405.     {
  406.  
  407.         pci.hCurrTree       = hStartTree;
  408.         pci.fStartPage      = TRUE;
  409.         pci.dwCurrIndent    = 0;
  410.  
  411.  
  412.         // Note:  We are basically doing an pre-order traversal
  413.         //        of the Tree.  Printing the current node
  414.         //        before moving on to it's children or siblings
  415.  
  416.         fDone               = FALSE;
  417.         while (! fDone)
  418.         {
  419.             // Check if we need to start a new page
  420.             if (! PrintStartPage (&pci))
  421.             {
  422.                 goto lblCLEANUP;
  423.             }
  424.  
  425.             //
  426.             // Get Current Item in Tree 
  427.             // and print it's text info and associated Node caps
  428.             //
  429.  
  430.             tvi.mask            = TVIF_CHILDREN | TVIF_TEXT | TVIF_PARAM;
  431.             tvi.hItem           = pci.hCurrTree;
  432.             tvi.pszText         = pstrBuff;
  433.             tvi.lParam          = 0;
  434.             tvi.cchTextMax      = pci.dwCharsPerLine;
  435.             if (TreeView_GetItem (hTreeWnd, &tvi))
  436.             {
  437.                 cchLen = _tcslen (pstrBuff);
  438.                 if (cchLen > 0)
  439.                 {
  440.                     int xOffset = (int)(pci.dwCurrIndent * DEF_TAB_SIZE * pci.dwCharWidth);
  441.                     int yOffset = (int)(pci.dwLineHeight * pci.dwCurrLine);
  442.  
  443.                     // Print this line
  444.                     if (! PrintLine (xOffset, yOffset, pstrBuff, cchLen, &pci))
  445.                     {
  446.                         goto lblCLEANUP;
  447.                     }
  448.     
  449.                     // Advance to next line in page
  450.                     if (! PrintNextLine (&pci))
  451.                     {
  452.                         goto lblCLEANUP;
  453.                     }
  454.  
  455.                     // Check if there is any additional node info 
  456.                     // that needs to be printed
  457.                     if (tvi.lParam != 0)
  458.                     {
  459.                         NODEINFO * pni = (NODEINFO*)tvi.lParam;
  460.                     
  461.                         if (pni && pni->printCallback)
  462.                         {                            
  463.                             // Force indent to offset node info from tree info
  464.                             pci.dwCurrIndent += 2;
  465.  
  466.                             if (! pni->printCallback(pni->lParam1, pni->lParam2, &pci))
  467.                             {
  468.                                 // Error, callback failed
  469.                                 goto lblCLEANUP;
  470.                             }
  471.  
  472.                             // Recover indent
  473.                             pci.dwCurrIndent -= 2;
  474.                         }
  475.                     }
  476.                 }
  477.             } // End if TreeView_GetItem()
  478.  
  479.             
  480.             
  481.             // 
  482.             // Get Next Item in tree
  483.             //
  484.  
  485.             // Get first child, if any
  486.             if (tvi.cChildren)
  487.             {
  488.                 // Get First child
  489.                 hTempTree = TreeView_GetChild (hTreeWnd, pci.hCurrTree);
  490.                 if (hTempTree)
  491.                 {
  492.                     // Increase Indentation
  493.                     pci.dwCurrIndent++;
  494.  
  495.                     pci.hCurrTree = hTempTree;
  496.                     continue;
  497.                 }
  498.             }
  499.             
  500.             // Exit, if we are the root
  501.             if (pci.hCurrTree == hRoot)
  502.             {
  503.                 // We have reached the root, so stop
  504.                 PrintEndPage (&pci);
  505.                 fDone = TRUE;
  506.                 continue;
  507.             }
  508.  
  509.             // Get next sibling in the chain
  510.             hTempTree = TreeView_GetNextSibling (hTreeWnd, pci.hCurrTree);
  511.             if (hTempTree)
  512.             {
  513.                 pci.hCurrTree = hTempTree;
  514.                 continue;
  515.             }
  516.  
  517.             // Get next Ancestor yet to be processed
  518.             // (uncle, granduncle, etc)
  519.             fFindNext = FALSE;
  520.             while (! fFindNext)
  521.             {
  522.                 hTempTree = TreeView_GetParent (hTreeWnd, pci.hCurrTree);
  523.                 if ((! hTempTree) || (hTempTree == hRoot))
  524.                 {
  525.                     // We have reached the root, so stop
  526.                     PrintEndPage (&pci);
  527.                     fDone       = TRUE;
  528.                     fFindNext   = TRUE;
  529.                 }
  530.                 else
  531.                 {
  532.                     // Move up to the parent
  533.                     pci.hCurrTree = hTempTree;
  534.  
  535.                     // Decrease Indentation
  536.                     pci.dwCurrIndent--;
  537.  
  538.                     // Since we have already processed the parent 
  539.                     // we want to get the uncle/aunt node
  540.                     hTempTree = TreeView_GetNextSibling (hTreeWnd, pci.hCurrTree);
  541.                     if (hTempTree)
  542.                     {
  543.                         // Found a non-processed node
  544.                         pci.hCurrTree = hTempTree;
  545.                         fFindNext = TRUE;
  546.                     }
  547.                 }
  548.             }
  549.         } // End While (! fDone)
  550.     } // End for num copies
  551.  
  552.     // Success
  553.     fResult = TRUE;
  554.  
  555. lblCLEANUP:    
  556.     // End Document
  557.     if (fStartDoc)
  558.     {
  559.         if(g_PrintToFile)
  560.         {
  561.             CloseHandle(g_FileHandle);
  562.         } else
  563.         EndDoc (pd.hDC);
  564.         fStartDoc = FALSE;
  565.     }
  566.  
  567.     // Re-enable main window
  568.     // Note:  Do this before destroying abort dialog
  569.     //        otherwise the main window loses focus
  570.     if (fDisableWindow)
  571.     {
  572.         EnableWindow (hWindow, TRUE);
  573.         fDisableWindow = FALSE;
  574.     }
  575.  
  576.     // Destroy Abort Dialog
  577.     if (g_hAbortPrintDlg)
  578.     {
  579.         DestroyWindow (g_hAbortPrintDlg);
  580.         g_hAbortPrintDlg = NULL;
  581.     }
  582.  
  583.     // Free title memory
  584.     if (pstrTitle)
  585.     {
  586.         HeapFree (hHeap, 0, (LPVOID)pstrTitle);
  587.         pstrTitle       = NULL;
  588.         di.lpszDocName  = NULL; 
  589.     }
  590.  
  591.     // Free buffer memory
  592.     if (pstrBuff)
  593.     {
  594.         HeapFree (hHeap, 0, (LPVOID)pstrBuff);
  595.         pstrBuff = NULL;
  596.     }
  597.  
  598.     // Cleanup printer DC
  599.     if (pd.hDC)
  600.     {
  601.         DeleteDC (pd.hDC);
  602.         pd.hDC = NULL;
  603.     }
  604.  
  605.     // Return success/failure
  606.     return fResult;
  607. } // End PrintTreeStats
  608.  
  609.  
  610.  
  611. /*
  612. **-----------------------------------------------------------------------------
  613. ** Name:    PrintStartPage
  614. ** Purpose: check if we need to start a new page
  615. **-----------------------------------------------------------------------------
  616. */
  617.  
  618. BOOL PrintStartPage (PRINTCBINFO * pci)
  619. {
  620.     if(g_PrintToFile)
  621.         return TRUE;
  622.     if (! pci)
  623.         return FALSE;
  624.  
  625.     // Check if we need to start a new page
  626.     if (pci->fStartPage)
  627.     {
  628.         // Check for user abort
  629.         if (g_fAbortPrint)
  630.         {
  631.             // Error, user canceled printing job
  632.             return FALSE;
  633.         } 
  634.  
  635.         // Start new page
  636.         if (StartPage (pci->hdcPrint) < 0)
  637.         {
  638.             // Error, StartPage failed
  639.             return FALSE;
  640.         }
  641.  
  642.         // Reset line count
  643.         pci->fStartPage = FALSE;
  644.         pci->dwCurrLine = 0;
  645.     }
  646.  
  647.     // Success
  648.     return TRUE;
  649. } // End PrintStartPage
  650.  
  651.  
  652.   
  653. /*
  654. **-----------------------------------------------------------------------------
  655. ** Name:    PrintEndPage
  656. ** Purpose: check if we need to start a new page
  657. **-----------------------------------------------------------------------------
  658. */
  659.  
  660. BOOL PrintEndPage (PRINTCBINFO * pci)
  661. {
  662.     if(g_PrintToFile)
  663.         return TRUE;
  664.     if (! pci)
  665.         return FALSE;
  666.  
  667.     // Check if we need to end this page
  668.     if (! pci->fStartPage)
  669.     {
  670.         // End page
  671.         if (EndPage (pci->hdcPrint) < 0)
  672.         {
  673.             // Error, end page failed
  674.             return FALSE;
  675.         }
  676.         pci->fStartPage = TRUE;
  677.  
  678.         // Check for user abort
  679.         if (g_fAbortPrint)
  680.         {
  681.             // Error, user canceled printing job
  682.             return FALSE;
  683.         } 
  684.     }
  685.  
  686.     // Success
  687.     return TRUE;
  688. } // End PrintEndPage
  689.  
  690.  
  691.   
  692. /*
  693. **-----------------------------------------------------------------------------
  694. ** Name:    PrintLine
  695. ** Purpose: Prints text to page at specified location
  696. **-----------------------------------------------------------------------------
  697. */
  698. static DWORD iLastXPos;
  699.  
  700. BOOL PrintLine (
  701.     int xOffset,
  702.     int yOffset,
  703.     LPCTSTR pszBuff,
  704.     DWORD  cchBuff,
  705.     PRINTCBINFO * pci)
  706. {
  707.     if (! pci)
  708.     {
  709.         // Programming error
  710.         return FALSE;
  711.     }
  712.  
  713.     // Check if we need to start a new page
  714.     if (! PrintStartPage (pci))
  715.         return FALSE;
  716.  
  717.     if ((! pszBuff) || (! cchBuff))
  718.     {
  719.         // Nothing to print
  720.         // assume it's OK and just keep printing
  721.         return TRUE;
  722.     }
  723.  
  724.     // Print text out to buffer current line
  725.     if(g_PrintToFile)
  726.     {
  727.         DWORD Foobar;
  728.         TCHAR Temp[80];
  729.  
  730.         if(((xOffset-iLastXPos)/pci->dwCharWidth)>80)
  731.             return TRUE;
  732.         memset(Temp,' ',sizeof(TCHAR)*79);
  733.         Temp[(xOffset-iLastXPos)/pci->dwCharWidth]=0;
  734.         WriteFile(g_FileHandle,Temp,(xOffset-iLastXPos)/pci->dwCharWidth,&Foobar,NULL);
  735.         iLastXPos = (xOffset-iLastXPos)+(pci->dwCharWidth * cchBuff);
  736.             
  737.         WriteFile(g_FileHandle,pszBuff,cchBuff,&Foobar,NULL);
  738.     }else
  739.     {
  740.         TextOut (pci->hdcPrint, xOffset, yOffset, pszBuff, cchBuff);
  741.     };
  742.  
  743.     return TRUE;
  744. } // End PrintLine
  745.     
  746.  
  747.  
  748. /*
  749. **-----------------------------------------------------------------------------
  750. ** Name:    PrintNextLine
  751. ** Purpose: advance to next line on page
  752. **-----------------------------------------------------------------------------
  753. */
  754.  
  755. BOOL PrintNextLine (PRINTCBINFO * pci)
  756. {
  757.  
  758.     if(g_PrintToFile)
  759.     {
  760.         DWORD Foobar;
  761.  
  762.         WriteFile(g_FileHandle,"\r\n",2,&Foobar,NULL);
  763.         iLastXPos = 0;
  764.         return TRUE;
  765.     };
  766.     if (! pci)
  767.         return FALSE;
  768.  
  769.     pci->dwCurrLine++;
  770.  
  771.     // Check if we need to end the page
  772.     if (pci->dwCurrLine >= pci->dwLinesPerPage)
  773.     {
  774.         return PrintEndPage (pci);
  775.     }
  776.  
  777.     // Success
  778.     return TRUE;
  779. } // End PrintNextLine
  780.  
  781.  
  782.  
  783. /*
  784. **-----------------------------------------------------------------------------
  785. ** Name:    DoMessage
  786. ** Purpose: display warning message to user
  787. **-----------------------------------------------------------------------------
  788. */
  789.  
  790. #define MAX_TITLE   64
  791. #define MAX_MESSAGE 256
  792.  
  793. void DoMessage (DWORD dwTitle, DWORD dwMsg)
  794. {
  795.     TCHAR szTitle[MAX_TITLE];
  796.     TCHAR szMsg[MAX_MESSAGE];
  797.     HMODULE hModule;
  798.  
  799.     hModule = GetModuleHandle (NULL);
  800.  
  801.     LoadString (hModule, dwTitle, szTitle, MAX_TITLE);
  802.     LoadString (hModule, dwMsg, szMsg, MAX_MESSAGE);
  803.     MessageBox (NULL, szMsg, szTitle, MB_OK);
  804. } // End DoMessage
  805.   
  806.  
  807. /*
  808. **-----------------------------------------------------------------------------
  809. ** End of File
  810. **-----------------------------------------------------------------------------
  811. */
  812.